I have a simple fastApi demo app which achieve a function: get different response json by calling a post api named changeResponse. The changeResponse api just changed a global variable, another api return different response through the same global variable.On local env,it works correctly, but the response always changed after i just call changeResponse once when i build this on docker.The code is as follows:
from typing import Optional
from fastapi import FastAPI
from util import read_json
import enum
app = FastAPI()
type = "00"
@app.post("/changeResponse")
async def handle_change_download_response(param:Optional[str]):
global type
type = param
print("type is "+type)
return {"success":"true"}
@app.post("/download")
async def handle_download(param:Optional[str]):
print("get download param: "+param)
if legalDownload(param):
print("type is "+type)
return read_json.readDownloadSuccessRes(type)
else:
return read_json.readDownloadFailRes()
def legalDownload(data:str)->bool:
return True
the dockerfile is as follows:
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7
COPY ./app /app
what i except: call changeResponse param is 7, get response for 7, call changeResponse param is 8, get response for 8. what i get: call changeResponse param is 7,get reponse for 7,call changeReponse 8, sometime the response is 7, sometime is 8,impossible to predict
The reason global variables are bad is that they enable functions to have hidden (non-obvious, surprising, hard to detect, hard to diagnose) side effects, leading to an increase in complexity, potentially leading to Spaghetti code.
You can change the value of a Python global variable by simply assigning it a new value (redeclaring). To delete a variable, use the keyword del .
In Python, variables that are only referenced inside a function are implicitly global. If a variable is assigned a value anywhere within the function's body, it's assumed to be a local unless explicitly declared as global.
tiangolo/uvicorn-gunicorn-fastapi
is based on uvicorn-gunicorn-docker image, which by defaults creates multiple workers. Excerpt from gunicorn_conf.py:
default_web_concurrency = workers_per_core * cores
Thus, the described situation arises because the request is processed by different workers (processes). Each of which has its own copy of the global variable
Update: If you want to change the count of workers, use the following environment variables:
You can set it like:
docker run -d -p 80:80 -e WEB_CONCURRENCY="2" myimage
A more detailed description of these variables and examples here
If you want to share data between workers, pay attention to this topic.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With