[英]Python requests in Docker Compose containers
docker-compose.yml
文件。requests
package 來訪問 API。我可以使用與 Python package 中的代碼完全相同的代碼從外部訪問應用程序容器,並且它可以工作,但它在 ZEFE90A8E604A7C640E88D03AD67F 中不起作用。
docker-compose.yml
version: "3.8"
services:
read-api:
build:
context: ./read-api
depends_on:
- "toy-api"
networks:
- ds-net
toy-api:
build:
context: ./api
networks:
- ds-net
ports:
- "80:80"
networks:
ds-net:
requests
代碼from requests import Session
def post_to_api(session, raw_input, path):
print(f"The script is sending: {raw_input}")
print(f"The script is sending it to: {path}")
response = session.post(path, json={"payload": raw_input})
print(f"The script received: {response.text}")
def get_from_api(session, path):
print(f"The datalake script is trying to GET from: {path}")
response = session.get(path)
print(f"The datalake script received: {response.text}")
session = Session()
session.trust_env = False ### I got that from here: https://stackoverflow.com/a/50326101/534238
get_from_api(session, path="http://localhost/test")
post_to_api(session, "this is a test", path="http://localhost/raw")
如果我創建一個交互式 session 並在requests
代碼部分運行上面的那些確切命令,它可以工作:
>>> get_from_api(session, path="http://localhost/test")
The script is trying to GET from: http://localhost/test
The script received: {"payload":"Yes, you reached here..."}
>>> post_to_api(session, "this is a test", path="http://localhost/raw")
The script is sending: this is a test
The script is sending it to: http://localhost/raw
The script received: {"payload":"received `raw_input`: this is a test"}
需要明確的是:API 代碼仍在作為容器運行,並且該容器仍然是使用docker-compose.yml
文件創建的。 (換句話說,當從主機訪問時,API 容器工作正常。)
在容器中做同樣的事情,我得到以下(相當長的)錯誤:
read-api_1 | The script is trying to GET from: http://localhost/test
read-api_1 | Traceback (most recent call last):
read-api_1 | File "/usr/local/lib/python3.8/site-packages/urllib3/connection.py", line 159, in _new_conn
read-api_1 | conn = connection.create_connection(
read-api_1 | File "/usr/local/lib/python3.8/site-packages/urllib3/util/connection.py", line 84, in create_connection
read-api_1 | raise err
read-api_1 | File "/usr/local/lib/python3.8/site-packages/urllib3/util/connection.py", line 74, in create_connection
read-api_1 | sock.connect(sa)
read-api_1 | ConnectionRefusedError: [Errno 111] Connection refused
read-api_1 |
read-api_1 | During handling of the above exception, another exception occurred:
.
.
.
read-api_1 | Traceback (most recent call last):
read-api_1 | File "access_api.py", line 99, in <module>
read-api_1 | get_from_api(session, path="http://localhost/test")
read-api_1 | File "access_datalake.py", line 86, in get_from_api
read-api_1 | response = session.get(path)
read-api_1 | File "/usr/local/lib/python3.8/site-packages/requests/sessions.py", line 543, in get
read-api_1 | return self.request('GET', url, **kwargs)
read-api_1 | File "/usr/local/lib/python3.8/site-packages/requests/sessions.py", line 530, in request
read-api_1 | resp = self.send(prep, **send_kwargs)
read-api_1 | File "/usr/local/lib/python3.8/site-packages/requests/sessions.py", line 643, in send
read-api_1 | r = adapter.send(request, **kwargs)
read-api_1 | File "/usr/local/lib/python3.8/site-packages/requests/adapters.py", line 516, in send
read-api_1 | raise ConnectionError(e, request=request)
read-api_1 | requests.exceptions.ConnectionError: HTTPConnectionPool(host='localhost', port=80): Max retries exceeded with url: /test (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7ffa9c69b3a0>: Failed to establish a new connection: [Errno 111] Connection refused'))
ai_poc_work_read-api_1 exited with code 1
我認為這是主機如何在容器組中識別自己,或者是否可以訪問該來源,所以我已經嘗試更改以下內容,但沒有成功:
localhost
作為主機,而是使用了read-api
。
read-api
開始的,但運氣不好,但是一旦使用localhost
,我至少可以在主機上使用 REPL,如上所示。0.0.0.0
,沒有運氣。 (我沒想到會解決它。)ORIGINS
,包括嘗試讀取的容器的所有可能路徑,並且僅使用"*"
標記所有 CORS 來源。 沒運氣。 我究竟做錯了什么? 似乎問題一定出在容器上,或者可能是requests
如何與容器交互,但我不知道是什么。
以下是我找到的一些相關 GitHub 問題或 SO 答案,但沒有解決:
在 Docker 網絡中,必須使用docker-compose.yml
中定義的服務名稱訪問應用程序。
如果您嘗試訪問toy-api
服務,請使用
get_from_api(session, path="http://toy-api/test")
您可以在主機上通過http://localhost/test
訪問應用程序,因為 Docker 將應用程序暴露給主機。 但是,粗略地說,在 Docker 網絡中, localhost
不是指主機的localhost
,而只是指容器的localhost
。 而在read-api
服務的情況下,沒有應用程序監聽http://localhost/test
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.