Issue
I have two Flask apps (A and B). App A is running locally on port 5000 and makes a post request to app B running on port 5002 like such:
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)
and the response back is:
Max retries exceeded with url: /endpoint/ Failed to establish a new connection: [Errno 111] Connection refused
I opened my terminal and tried this curl request:
curl -X 'POST' 'http://localhost:5002/endpoint/' -H 'accept: application/json' -H 'Content-Type: application/json' -d '{"test_string": "test input string", "flatten": true}'
and it returns the correct response from app B
I figured maybe there was a problem with how I formatted the request on app A since curl was working and I tested the 3 lines I had on app A just using python from my terminal and it worked in my python terminal.
The only variable left is app A being a flask app running locally since that code snippet runs in python terminal. Is there some problem with calling app B from app A with both apps running locally on different ports?
UPDATE: Ok, I have narrowed down the the issue to something with docker-compose and Redis. Here is how to replicate it:
APP 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)
APP 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"]
requirements.txt
redis
Flask~=1.1.2
flask-restx
tenacity
requests
you can run app B the normal way, how I run app A: docker-compose up --build
You can curl app B from a terminal: curl -X 'POST' \ 'http://localhost:5002/parse/' \ -H 'accept: application/json' \ -H 'Content-Type: application/json' \ -d '{ "input_string": "string" }'
and you can also run the code instead app A from a python terminal:
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)
But app A CANNOT call app B
If you run app A by just running app.py it works fine, it only breaks using docker-compose + redis even though redis isnt even used in the example
Solution
Figured it out. Docker containers run on a different network so 'localhost' will not work. Dockerizing app B and deploying it to the same docker network as app A, and then changing 'localhost' to the container name of B on the network fixes it.
Answered By - user3831011
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.