python - 从本地另一个烧瓶应用程序调用烧瓶应用程序
问题描述
我有两个 Flask 应用程序(A 和 B)。应用程序 A 在本地端口 5000 上运行,并向运行在端口 5002 上的应用程序 B 发出 post 请求,如下所示:
headers = {
'accept': 'application/type',
'Content-Type': 'application/json'
}
data = '{"test_string": "test input string", "flatten": true}'
response = requests.post('http://localhost:5002/endpoint', headers=headers, data=data)
回复是:
Max retries exceeded with url: /endpoint/ Failed to establish a new connection: [Errno 111] Connection refused
我打开终端并尝试了这个 curl 请求:
curl -X 'POST' 'http://localhost:5002/endpoint/' -H 'accept: application/json' -H 'Content-Type: application/json' -d '{"test_string": "test input string", "flatten": true}'
它从应用 B 返回正确的响应
我想我在应用程序 A 上格式化请求的方式可能存在问题,因为 curl 正在工作,我只使用终端中的 python 测试了我在应用程序 A 上的 3 行,它在我的 python 终端中工作。
剩下的唯一变量是 app A 是在本地运行的烧瓶应用程序,因为该代码片段在 python 终端中运行。从应用程序 A 调用应用程序 B 并且两个应用程序在不同端口上本地运行是否存在一些问题?
更新:好的,我已将问题缩小到 docker-compose 和 Redis。以下是如何复制它:
应用程序 B:app.py
from flask import Flask, abort
from flask_restx import Api, Resource, fields
app = Flask(__name__)
api = Api(app, version='1.0', title='something',
description='something',
)
ns = api.namespace('parse', description='something')
parse_raw = api.model('parse', {
'input_string': fields.String(required=True, description='string')
})
@ns.route('/')
class Parser(Resource):
@ns.doc('parse')
@ns.expect(parse_raw)
def post(self):
'''Parse'''
try:
s = "yes"
except Exception:
abort(400, 'unsupported')
return s, 200
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=5002)
应用程序 A:app.py
from flask import Flask
from flask_restx import Api, Resource
import requests
app = Flask(__name__)
api = Api(app, version='1.0', title='something',
description='something',
)
ns = api.namespace('parse', description='something')
@ns.route('/')
class Parser(Resource):
@ns.doc('parse')
def get(self):
'''Parse'''
headers = {
'accept': 'application/json',
'Content-Type': 'application/json',
}
data = '{"input_string": "SELECT * FROM table1"}'
response = requests.post('http://0.0.0.0:5002/parse/', headers=headers, data=data)
return response.text, 200
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=5000)
docker-compose.yaml
version: '3'
services:
app:
build:
context: .
dockerfile: Dockerfile
ports:
- "5000:5000"
redis:
image: "redis:alpine"
Dockerfile
FROM python:3.6-alpine
WORKDIR /app
ENV PYTHONHASHSEED=1
RUN apk add --no-cache --update make
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
COPY . .
CMD ["python3", "app.py"]
要求.txt
redis
Flask~=1.1.2
flask-restx
tenacity
requests
您可以以正常方式运行应用程序 B,我如何运行应用程序 A:docker-compose up --build
您可以从终端 curl 应用程序 B:curl -X 'POST' \ 'http://localhost:5002/parse/' \ -H 'accept: application/json' \ -H 'Content-Type: application/json' \ -d '{ "input_string": "string" }'
您还可以从 python 终端运行代码而不是应用程序 A:
headers = {
'accept': 'application/json',
'Content-Type': 'application/json',
}
data = '{"input_string": "SELECT * FROM table1"}'
response = requests.post('http://0.0.0.0:5002/parse/', headers=headers, data=data)
但是应用 A 不能调用应用 B
如果您通过运行 app.py 来运行应用程序 A,它可以正常工作,它只会使用 docker-compose + redis 中断,即使示例中甚至没有使用 redis
解决方案
弄清楚了。Docker 容器在不同的网络上运行,因此“localhost”将不起作用。将应用程序 B Docker 化并将其部署到与应用程序 A 相同的 docker 网络,然后将“localhost”更改为网络上 B 的容器名称来修复它。
推荐阅读
- c++ - 如何将 ROS AudioData 消息写入 wav 文件?
- php - 执行 PHP 脚本来处理 Apache2 的 ErrorDocument 500
- mongodb - 如果我在重命名 MongoDB 集合时发送查询会发生什么?
- python - 如何在python的正则表达式模块中获取多个以字符串开头和以字符串结尾的字符串?
- python - 如何在早晚之间获得频繁的时间戳?
- python - 如何通过鼠标单击并拖动来选中或取消选中“PySide2 QStandardItemModel”中的 QStandrdItem 复选框?
- vuetify.js - Vuetify.js:当我关闭并再次打开时,v-dialog 不起作用
- python - 我无法正确地从 api 可视化 json 数据框
- python - 从折线图中识别峰
- python - 如何在 Python 中将不规则张量转换为张量?