I have a FastAPI server running locally. I launched it with uvicorn like so:
uvicorn app:app --port 5000
I am querying it frpm Python, like so:
response = requests.post(rf"http://127.0.0.1:5000/endpoint1/", json={"arg1": "somevalue})
When I am looking at my FastAPI logs, I see that every request comes from a different port and increments at every new one:
...
INFO: 127.0.0.1:59605 - "POST /endpoint1/ HTTP/1.1" 200 OK
INFO: 127.0.0.1:59606 - "POST /endpoint2/ HTTP/1.1" 200 OK
INFO: 127.0.0.1:59607 - "POST /endpoint1/ HTTP/1.1" 200 OK
INFO: 127.0.0.1:59608 - "POST /endpoint2/ HTTP/1.1" 200 OK
INFO: 127.0.0.1:59609 - "POST /endpoint1/ HTTP/1.1" 200 OK
INFO: 127.0.0.1:59610 - "POST /endpoint2/ HTTP/1.1" 200 OK
INFO: 127.0.0.1:59611 - "POST /endpoint1/ HTTP/1.1" 200 OK
INFO: 127.0.0.1:59612 - "POST /endpoint2/ HTTP/1.1" 200 OK
INFO: 127.0.0.1:59613 - "POST /endpoint1/ HTTP/1.1" 200 OK
INFO: 127.0.0.1:59614 - "POST /endpoint2/ HTTP/1.1" 200 OK
After a while this leads to issues because all ports are exhausted (I think; at port 65535). Specifically, this error:
requests.exceptions.ConnectionError: HTTPConnectionPool(host='127.0.0.1', port=5000): Max retries exceeded with url: /endpoint1/ (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x000001BC822DDC40>: Failed to establish a new connection: [WinError 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted'))
I am doing the requests sequentially (not in parallel!), so is there a way to ensure that the request is always send through the same port? Or another solution to avoid this issue?
So the explanation is that each request is being served on a new connection and is assigned a new port number. The requests came in so fast that it seems that the ports were not closed/reopened fast enough and that Python ran out of ports that it thought were available.
The solution is to do all the requests through a single requests.Session
. Note the session.post
below instead of requests.post
.
session = requests.Session()
response = session.post(rf"http://127.0.0.1:5000/endpoint1/", json={"arg1": "sometext"})
# ... other requests
session.close()