[英]Flask+requests API ConnectionRefusedError: [Errno 111] Connection refused
I'm trying to run a simple Flask API, but it's not working as expected.我正在尝试运行一个简单的 Flask API,但它没有按预期工作。 I'm not very experienced in Python, so found the error and solve it have been very challenging.
我在 Python 方面不是很有经验,所以发现错误并解决它非常具有挑战性。 I would appreciate a lot if someone could help.
如果有人可以提供帮助,我将不胜感激。
The system's settings are:系统设置如下:
And these are the requirements:这些是要求:
$ pip freeze
ansimarkup==1.4.0
asn1crypto==0.24.0
better-exceptions-fork==0.2.1.post6
certifi==2019.3.9
cffi==1.12.3
chardet==3.0.4
Click==7.0
colorama==0.4.1
cryptography==2.7
Flask==1.0.3
idna==2.8
itsdangerous==1.1.0
Jinja2==2.10.1
loguru==0.2.5
MarkupSafe==1.1.1
pycparser==2.19
Pygments==2.4.2
pyOpenSSL==19.0.0
PySocks==1.7.0
requests==2.22.0
six==1.12.0
urllib3==1.24.2
Werkzeug==0.15.4
My project structure is like this:我的项目结构是这样的:
├── statsapi
│ ├── data_store.py
├── app.py
├── client.py
├── requirements.txt
Here is the app.py code:这是 app.py 代码:
#!/usr/bin/env python
from flask import Flask, request, jsonify
from loguru import logger
from statsapi import data_store
app = Flask(__name__)
# Creating an endpoint
@app.route("/data", methods=["POST"])
def save_data():
# setting log for this action
logger.info(f"Saving data...")
# transform content requisition to json
content = request.get_json()
# save in a module just the "data" field
# The uuid of the data
uuid = data_store.save(content["data"])
# set log for las action
logger.info(f"Data saved with UUID `{uuid}` successfully")
# define information to be returned
return jsonify({"status": "success",
"message": "data saved successfully",
"uuid": uuid})
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
The data_store.py code: data_store.py 代码:
#!/usr/bin/env python
from uuid import uuid4
# Create a dictionary to keep things in memory
_in_memory_storage = dict()
# Save received data in memory giving an uuid
def save(data):
data_uuid = uuid4()
_in_memory_storage[data_uuid] = data
return data_uuid
And the client.py code:和 client.py 代码:
#!/usr/bin/env python
import requests
def send(data):
response = requests.post("http://localhost:5000/data", json={"data": data})
print(response.json())
def main():
send([1, 2, 3, 4])
if __name__ == "__main__":
main()
The client.py should send some data to API, but when called it returns this long error message: client.py 应该向 API 发送一些数据,但是在调用时它会返回以下长错误消息:
$ python client.py
Traceback (most recent call last):
File "/home/bruno/anaconda3/envs/statsapi/lib/python3.7/site-packages/urllib3/connection.py", line 159, in _new_conn
(self._dns_host, self.port), self.timeout, **extra_kw)
File "/home/bruno/anaconda3/envs/statsapi/lib/python3.7/site-packages/urllib3/util/connection.py", line 80, in create_connection
raise err
File "/home/bruno/anaconda3/envs/statsapi/lib/python3.7/site-packages/urllib3/util/connection.py", line 70, in create_connection
sock.connect(sa)
ConnectionRefusedError: [Errno 111] Connection refused
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/bruno/anaconda3/envs/statsapi/lib/python3.7/site-packages/urllib3/connectionpool.py", line 600, in urlopen
chunked=chunked)
File "/home/bruno/anaconda3/envs/statsapi/lib/python3.7/site-packages/urllib3/connectionpool.py", line 354, in _make_request
conn.request(method, url, **httplib_request_kw)
File "/home/bruno/anaconda3/envs/statsapi/lib/python3.7/http/client.py", line 1229, in request
self._send_request(method, url, body, headers, encode_chunked)
File "/home/bruno/anaconda3/envs/statsapi/lib/python3.7/http/client.py", line 1275, in _send_request
self.endheaders(body, encode_chunked=encode_chunked)
File "/home/bruno/anaconda3/envs/statsapi/lib/python3.7/http/client.py", line 1224, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File "/home/bruno/anaconda3/envs/statsapi/lib/python3.7/http/client.py", line 1016, in _send_output
self.send(msg)
File "/home/bruno/anaconda3/envs/statsapi/lib/python3.7/http/client.py", line 956, in send
self.connect()
File "/home/bruno/anaconda3/envs/statsapi/lib/python3.7/site-packages/urllib3/connection.py", line 181, in connect
conn = self._new_conn()
File "/home/bruno/anaconda3/envs/statsapi/lib/python3.7/site-packages/urllib3/connection.py", line 168, in _new_conn
self, "Failed to establish a new connection: %s" % e)
urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPConnection object at 0x7fd0c7a26a58>: Failed to establish a new connection: [Errno 111] Connection refused
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/bruno/anaconda3/envs/statsapi/lib/python3.7/site-packages/requests/adapters.py", line 449, in send
timeout=timeout
File "/home/bruno/anaconda3/envs/statsapi/lib/python3.7/site-packages/urllib3/connectionpool.py", line 638, in urlopen
_stacktrace=sys.exc_info()[2])
File "/home/bruno/anaconda3/envs/statsapi/lib/python3.7/site-packages/urllib3/util/retry.py", line 399, in increment
raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='localhost', port=5000): Max retries exceeded with url: /data (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7fd0c7a26a58>: Failed to establish a new connection: [Errno 111] Connection refused'))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "client.py", line 17, in <module>
main()
File "client.py", line 13, in main
send([1, 2, 3, 4])
File "client.py", line 7, in send
response = requests.post("http://localhost:5000/data", json={"data": data})
File "/home/bruno/anaconda3/envs/statsapi/lib/python3.7/site-packages/requests/api.py", line 116, in post
return request('post', url, data=data, json=json, **kwargs)
File "/home/bruno/anaconda3/envs/statsapi/lib/python3.7/site-packages/requests/api.py", line 60, in request
return session.request(method=method, url=url, **kwargs)
File "/home/bruno/anaconda3/envs/statsapi/lib/python3.7/site-packages/requests/sessions.py", line 533, in request
resp = self.send(prep, **send_kwargs)
File "/home/bruno/anaconda3/envs/statsapi/lib/python3.7/site-packages/requests/sessions.py", line 646, in send
r = adapter.send(request, **kwargs)
File "/home/bruno/anaconda3/envs/statsapi/lib/python3.7/site-packages/requests/adapters.py", line 516, in send
raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPConnectionPool(host='localhost', port=5000): Max retries exceeded with url: /data (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7fd0c7a26a58>: Failed to establish a new connection: [Errno 111] Connection refused'))
As I said, I'm far away from to be a python expert, so I will be many thankful for any help.正如我所说,我离成为一名 Python 专家还很遥远,所以我将非常感谢任何帮助。
i think this might be your port is already serve by another apps, try to change flask port.我认为这可能是您的端口已经由其他应用程序提供服务,请尝试更改烧瓶端口。
i used your code in local and successfully我在本地成功使用了你的代码
try something like this尝试这样的事情
main.py
import data_store
from flask import Flask, request, jsonify
app = Flask(__name__)
# Creating an endpoint
@app.route("/data", methods=["POST"])
def save_data():
# setting log for this action
print(f"Saving data...")
# transform content requisition to json
content = request.get_json()
# save in a module just the "data" field
# The uuid of the data
uuid = data_store.save(content["data"])
# set log for las action
print(f"Data saved with UUID `{uuid}` successfully")
# define information to be returned
return jsonify({"status": "success",
"message": "data saved successfully",
"uuid": uuid})
if __name__ == "__main__":
app.run(port=8000)
data_store.py
from uuid import uuid4
# Create a dictionary to keep things in memory
_in_memory_storage = dict()
# Save received data in memory giving an uuid
def save(data):
data_uuid = uuid4()
_in_memory_storage[data_uuid] = data
print(f"Cached value => {_in_memory_storage}")
return data_uuid
client.py
import requests
def send(data):
response = requests.post("http://localhost:8000/data", json={"data": data})
print(response.json())
def main():
send([1, 2, 3, 4])
if __name__ == "__main__":
main()
and when it test successfully like this当它像这样测试成功时
→ python client.py
{'message': 'data saved successfully', 'status': 'success', 'uuid': '050b02c2-e67e-44f7-b6c9-450106d8b40e'}
flask logger烧瓶记录器
→ python main.py
* Serving Flask app "main" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:8000/ (Press CTRL+C to quit)
Saving data...
Cached value => {UUID('050b02c2-e67e-44f7-b6c9-450106d8b40e'): [1, 2, 3, 4]}
Data saved with UUID `050b02c2-e67e-44f7-b6c9-450106d8b40e` successfully
127.0.0.1 - - [06/Jun/2021 12:51:35] "POST /data HTTP/1.1" 200 -
Might not exactly relate to the question, but it might help someone facing similar issue.可能与问题不完全相关,但它可能会帮助面临类似问题的人。
I had similar issue, but in my case it was because of docker containers.我有类似的问题,但就我而言,这是因为 docker 容器。 When container #1 is connecting to container #2 using requests api it was failing as both the containers are not in a single network.
当容器 #1 使用请求 api 连接到容器 #2 时,它失败了,因为两个容器都不在一个网络中。
So I modified my docker-compose file to所以我将我的 docker-compose 文件修改为
networks:
default:
external: true
name: <network_name>
Make sure to create the docker network in advance and modify the host to docker service name of the container #2 while connecting using requests.确保提前创建 docker 网络,并在使用请求连接时将主机修改为容器 #2 的 docker 服务名称。
So use http://<docker_service_name>:8000/api
instead of http://127.0.0.1:8000/api
所以使用
http://<docker_service_name>:8000/api
而不是http://127.0.0.1:8000/api
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.