enigmare/v2-crawler
1904
1{"id":"stack-60819376","source":"stackoverflow","questionId":60819376,"title":"FastAPI throws an error (Error loading ASGI app. Could not import module \"api\")","tags":["python","fastapi","uvicorn"],"text":"Title: FastAPI throws an error (Error loading ASGI app. Could not import module \"api\")\nTags: python, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI tried to run FastAPI using uvicorn webserver but it throws an error.\n\nI run this command,\n\n```\nuvicorn api:app --reload --host 0.0.0.0\n```\n\nbut there is an error in the terminal.\n\n```\nUvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)\nStarted reloader process [23445]\nError loading ASGI app. Could not import module \"api\".\nStopping reloader process [23445]\n```\n\n========================================\n\nTop Answer:\nOne reason this might be happening is that you are using:\n\n```\nuvicorn src/main:app --reload\n```\n\ninstead of the **correct syntax**:\n\n```\nuvicorn src.main:app --reload\n```\n\nNotice the **.** instead of the **/**\n\nCurrently auto-completion in the terminal suggests the wrong format.\n\nThat's assuming that:\n\n(1) your structure is something like this:\n\n```\nproject_folder/\n├── some_folder\n├── src\n│ └── main.py\n└── tests\n ├── test_xx.py\n └── test_yy.py\n```\n\n(2) your `FastAPI()` object is indeed assigned to an object named `app` in `main.py`:\n\n```\napp = FastAPI()\n```\n\n(3) you are running the uvicorn command from the `project_folder`, e.g.:\n\n```\n(venv) @:~/PycharmProjects/project_folder$ uvicorn src.main:app --reload\n```\n\n========================================\n\nCode:\n```text\nuvicorn api:app --reload --host 0.0.0.0\n```\n\n```text\nUvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)\nStarted reloader process [23445]\nError loading ASGI app. Could not import module \"api\".\nStopping reloader process [23445]\n```\n\n```py\nuvicorn src.main:app\n```\n\n```py\ncd src\nuvicorn main:app\n```\n\n```text\nmy_fastapi_app/\n├── app.yaml\n├── docker-compose.yml\n├── src\n│ └── main.py\n└── tests\n ├── test_xx.py\n └── test_yy.py\n\n$ pwd # Present Working Directory\n/home/yagiz/Desktop/my_fastapi_app\n```\n\n```text\n$ uvicorn main:app --reload\nINFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\nINFO: Started reloader process [40645] using statreload\nERROR: Error loading ASGI app. Could not import module \"main\".\n```\n\n```text\nuvicorn src.main:app --reload\n```\n\n```text\ncd src\n```\n\n```text\nsrc\n└── main.py\n```\n\n```text\n$ uvicorn main:app --reload\nINFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\nINFO: Started reloader process [40726] using statreload\nINFO: Started server process [40728]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\n```\n\n```text\ncd\n```\n\n```text\nuvicorn src.main:app --reload\n```\n\n```text\nmain.py\n```\n\n```text\napp.py\n```\n\n```text\nuvicorn main:app\n```\n\n```text\nmain\n```\n\n```text\nmain.py\n```\n\n```text\napp\n```\n\n```text\nmain.py\n```\n\n```text\napp = FastAPI()\n```\n\n```text\n--reload\n```\n\n```text\nuvicorn src/main:app --reload\n```\n\n```text\nuvicorn src.main:app --reload\n```\n\n```text\nproject_folder/\n├── some_folder\n├── src\n│ └── main.py\n└── tests\n ├── test_xx.py\n └── test_yy.py\n```\n\n```text\napp = FastAPI()\n```\n\n```text\n(venv) <username>@<pcname>:~/PycharmProjects/project_folder$ uvicorn src.main:app --reload\n```\n\n```text\nFastAPI()\n```\n\n```text\napp\n```\n\n```text\nmain.py\n```\n\n```text\nproject_folder\n```\n\n```text\n{\n // Use IntelliSense to learn about possible attributes.\n // Hover to view descriptions of existing attributes.\n // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387\n \"version\": \"0.2.0\",\n \"configurations\": [\n {\n \"name\": \"Python: FastAPI\",\n \"type\": \"python\",\n \"request\": \"launch\",\n \"module\": \"uvicorn\",\n \"args\": [\n \"main:app\"\n ],\n \"jinja\": true\n }\n ]\n}\n```\n\n```text\nfrom fastapi import FastAPI\napp = FastAPI(\n title=\"test\",\n description=\"test\",\n version=\"0.0.1\",\n)\nif __name__ == \"__main__\":\nimport uvicorn\n\nuvicorn.run(\n \"main:app\",\n host=\"0.0.0.0\",\n reload=True,\n port=3001,\n)\n```\n\n```py\nfrom tools import validator\n\n# ...\n\nclass GlobalException(Exception):\n # ...\n```\n\n```py\nfrom main import GlobalException\n```\n\n```text\nmain.py\n```\n\n```text\n/tools/validator.py\n```\n\n```text\ntest_app/main.py\n```\n\n```text\nuvicorn test_app.main:app --reload\n```\n\n```text\ntest_app.py\n```\n\n```text\n(virtual-env) shayon@shayon-X556UQK:~/Documents/python-fast-api$ ls\nmain.py __pycache__ README.md requirements.txt virtual-env\n```\n\n```text\n(virtual-env) shayon@shayon-X556UQK:~/Documents/python-fast-api$ pwd\n/home/shayon/Documents/python-fast-api\n```\n\n```text\n(virtual-env) shayon@shayon-X556UQK:~/Documents/python-fast-api$ cat main.py\n```\n\n```text\nfrom fastapi import FastAPI\napp = FastAPI()\n\n\n@app.get(\"/\")\ndef index():\n return {\"Hello\": \"World\"}\n```\n\n```text\nls\n```\n\n```text\npwd\n```\n\n```text\napp\n```\n\n```text\nuvicorn main:app --reload\n```\n\n```text\napp1\n```\n\n```text\nuvicorn main:app1 --reload\n```\n\n```text\nuvicorn main.py:app --reload\n```\n\n```text\nuvicorn main:app --reload\n```\n\n```text\nmy_app_name\n├── docker-compose.yml\n├── src\n│ └── main.py\n└── tests\n ├── test_file1.py\n └── test_file2.py\n```\n\n```text\ncd directory of code\nuvicorn fast-api:main --reload\n```\n\n```text\nimport uvicorn\n\napp = FastAPI()\n\n@app.get(\"/\")\ndef index():\n return {\"index\": \"root\"}\n\nif __name__ == '__main__':\n\n uvicorn.run(f\"{Path(__file__).stem}:app\", host=\"127.0.0.1\", port=8888, reload=True)\n```\n\n```text\nuvicorn main:app --reload\n```\n\n```text\n/home/my_user/project_folder/\n├── some_folder\n├── src\n│ └── main.py\n└── tests\n ├── test_xx.py\n └── test_yy.py\n```\n\n```text\n# Two ways to run it from outside of the project dir:\n/home> uvicorn --app-dir ./my_user/project_folder/src main:app --reload\n/home> uvicorn my_user.project_folder.src.main:app --reload\n\n# Two ways to run it from outside of the project dir:\n/home/my_user> uvicorn --app-dir ./project_folder/src main:app --reload\n/home/my_user> uvicorn project_folder.src.main:app --reload\n\n# Two ways to run it from the project root:\n/home/my_user/project_folder> uvicorn --app-dir ./src main:app --reload\n/home/my_user/project_folder> uvicorn src.main:app --reload\n\n# From the same level with you main.py file:\n/home/my_user/project_folder/src> uvicorn main:app --reload\n```\n\n```text\nfastapi <subcommand>\n```\n\n```text\nfastapi dev <file or package where your FastAPI app instance is>\n```\n\n```text\nfastapi run <file or package where your FastAPI app instance is>\n```\n\n```text\nmain.py\n```\n\n```text\nfastapi\n```\n\n```text\nuvicorn fastapi.main:app --reload\n```\n\n```text\ncd\n```\n\n```text\nfastapi\n```\n\n========================================\n\nComments:\n- what is the path of the python file which declares the `app` variable ?\n- in my case, my filename was `uvicorn.py` and `uvicorn uvicorn:app` throws error.\n- Does this answer your question? ERROR: Error loading ASGI app. Import string \"main\" must be in format \":\"\n- Well, I'm at the same folder as my main.py file but it doesn't want to run\n- Hi @Carlos3dx what is FastAPI instance's name is it called app? for example if you declare like `other_app = FastAPI()` you need to run as `main:other_app` , if it doesn't works either, i can help you from FastAPI's gitter\n- There was another file in the application importing main, the error message was related to that import, not the main I passed to uvicorn, but cause there was no stacktrace it looked like uvicorn cannot foun main module. Rearranged the code and now works perfect\n- another option, uvicorn has a path parameter: --app-dir src. running uvicorn --help, shows all options\n- I encountered this issue because I mistakenly added `.py` in the command like this `uvicorn main.py:app`. It should be `uvicorn main:app`.\n- Just FYI, I was running this from main, and could not get it to work until I added an `__init__.py` to the package directory, even with `pkg.module:app`. Python 3.10.4\n- What if I'm using docker and directory name is `/app` (not `app`)\n- Beware that this error also appears if you haven't saved the main.py file yet...\n- you can name it as you want as long as you reference it correctly.\n- holyyyy this actually worked, thanks a lot","metadata":{"transformedAt":"2026-08-18T18:32:29.081Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":65,"totalLines":455,"estimatedTokens":2022}}2{"id":"stack-55873174","source":"stackoverflow","questionId":55873174,"title":"How do I return an image in FastAPI?","tags":["python","fastapi"],"text":"Title: How do I return an image in FastAPI?\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nUsing the python module FastAPI, I can't figure out how to return an image. In flask I would do something like this:\n\n```\n@app.route(\"/vector_image\", methods=[\"POST\"])\ndef image_endpoint():\n # img = ... # Create the image here\n return Response(img, mimetype=\"image/png\")\n```\n\nwhat's the corresponding call in this module?\n\n========================================\n\nTop Answer:\nI had a similar issue but with a cv2 image. This may be useful for others. Uses the `StreamingResponse`.\n\n```\nimport io\nfrom starlette.responses import StreamingResponse\n\napp = FastAPI()\n\n@app.post(\"/vector_image\")\ndef image_endpoint(*, vector):\n # Returns a cv2 image array from the document vector\n cv2img = my_function(vector)\n res, im_png = cv2.imencode(\".png\", cv2img)\n return StreamingResponse(io.BytesIO(im_png.tobytes()), media_type=\"image/png\")\n```\n\n========================================\n\nCode:\n```text\n@app.route(\"/vector_image\", methods=[\"POST\"])\ndef image_endpoint():\n # img = ... # Create the image here\n return Response(img, mimetype=\"image/png\")\n```\n\n```py\n@app.get(\n \"/image\",\n\n # Set what the media type will be in the autogenerated OpenAPI specification.\n # fastapi.tiangolo.com/advanced/additional-responses/#additional-media-types-for-the-main-response\n responses = {\n 200: {\n \"content\": {\"image/png\": {}}\n }\n },\n\n # Prevent FastAPI from adding \"application/json\" as an additional\n # response media type in the autogenerated OpenAPI specification.\n # https://github.com/tiangolo/fastapi/issues/3258\n response_class=Response\n)\ndef get_image()\n image_bytes: bytes = generate_cat_picture()\n # media_type here sets the media type of the actual response sent to the client.\n return Response(content=image_bytes, media_type=\"image/png\")\n```\n\n```py\n@app.get(\"/image\")\ndef get_image()\n image_bytes: bytes = generate_cat_picture()\n # ❌ Don't do this.\n image_stream = io.BytesIO(image_bytes)\n return StreamingResponse(content=image_stream, media_type=\"image/png\")\n```\n\n```text\nfastapi.responses.Response\n```\n\n```text\ncontent\n```\n\n```text\nmedia_type\n```\n\n```text\nResponse\n```\n\n```text\nfastapi.responses.FileResponse\n```\n\n```text\nFileResponse\n```\n\n```text\nStreamingResponse\n```\n\n```text\nStreamingResponse\n```\n\n```text\nStreamingResponse\n```\n\n```text\nResponse\n```\n\n```text\nFileResponse\n```\n\n```text\nStreamingResponse(content=my_iterable)\n```\n\n```text\nmy_iterable\n```\n\n```text\nBytesIO\n```\n\n```text\n\\n\n```\n\n```text\nimage_bytes\n```\n\n```text\nbytes\n```\n\n```text\nResponse\n```\n\n```text\nStreamingResponse\n```\n\n```text\nFileResponse\n```\n\n```text\nStreamingResponse\n```\n\n```py\nfrom starlette.responses import FileResponse\nfrom starlette.middleware.cors import CORSMiddleware\nimport tempfile\n\napp = FastAPI()\napp.add_middleware(\n CORSMiddleware, allow_origins=[\"*\"], allow_methods=[\"*\"], allow_headers=[\"*\"]\n)\n\n@app.post(\"/vector_image\")\ndef image_endpoint(*, vector):\n # Returns a raw PNG from the document vector (define here)\n img = my_function(vector)\n\n with tempfile.NamedTemporaryFile(mode=\"w+b\", suffix=\".png\", delete=False) as FOUT:\n FOUT.write(img)\n return FileResponse(FOUT.name, media_type=\"image/png\")\n```\n\n```text\nFileResponse\n```\n\n```text\nimport io\nfrom starlette.responses import StreamingResponse\n\napp = FastAPI()\n\n@app.post(\"/vector_image\")\ndef image_endpoint(*, vector):\n # Returns a cv2 image array from the document vector\n cv2img = my_function(vector)\n res, im_png = cv2.imencode(\".png\", cv2img)\n return StreamingResponse(io.BytesIO(im_png.tobytes()), media_type=\"image/png\")\n```\n\n```text\nStreamingResponse\n```\n\n```py\n@app.get(\"/generate\")\ndef generate(data: str):\n img = generate_image(data)\n print('img=%s' % (img.shape,))\n buf = BytesIO()\n imsave(buf, img, format='JPEG', quality=100)\n buf.seek(0) # important here!\n return StreamingResponse(buf, media_type=\"image/jpeg\",\n headers={'Content-Disposition': 'inline; filename=\"%s.jpg\"' %(data,)})\n```\n\n```text\nBytesIO\n```\n\n```text\nimg.seek(0)\n```\n\n```text\nfrom fastapi.responses import FileResponse\n\n@app.get(\"/\")\nasync def main():\n return FileResponse(\"your_image.jpeg\")\n```\n\n```text\nfrom fastapi import FastAPI, Response\n\napp = FastAPI()\n\n@app.post(\"/vector_image/\")\nasync def image_endpoint():\n # img = ... # Create the image here\n return Response(content=img, media_type=\"image/png\")\n```\n\n```py\nimport os\n\nfrom fastapi import FastAPI \nfrom fastapi.responses import FileResponse\n\napp = FastAPI()\n\npath = \"/path/to/files\"\n\n@app.get(\"/\")\ndef index():\n return {\"Hello\": \"World\"}\n\n@app.get(\"/vector_image\", responses={200: {\"description\": \"A picture of a vector image.\", \"content\" : {\"image/jpeg\" : {\"example\" : \"No example available. Just imagine a picture of a vector image.\"}}}})\ndef image_endpoint():\n file_path = os.path.join(path, \"files/vector_image.jpg\")\n if os.path.exists(file_path):\n return FileResponse(file_path, media_type=\"image/jpeg\", filename=\"vector_image_for_you.jpg\")\n return {\"error\" : \"File not found!\"}\n```\n\n```text\nFileResponse\n```\n\n```text\npath\n```\n\n```text\nimport io\nfrom PIL import Image\nfrom fastapi.responses import StreamingResponse\n@app.get('/images/thumbnail/{filename}',\n response_description=\"Returns a thumbnail image from a larger image\",\n response_class=\"StreamingResponse\",\n responses= {200: {\"description\": \"an image\", \"content\": {\"image/jpeg\": {}}}})\ndef thumbnail_image (filename: str):\n # read the high-res image file\n image = Image.open(filename)\n # create a thumbnail image\n image.thumbnail((100, 100))\n imgio = io.BytesIO()\n image.save(imgio, 'JPEG')\n imgio.seek(0)\n return StreamingResponse(content=imgio, media_type=\"image/jpeg\")\n```\n\n```text\n<img src=\"http://localhost:8000/images/thumbnail/bigimage.jpg\">\n```\n\n```py\nbuffer = BytesIO(my_data)\n\n # Return file\n return Response(content=buffer, media_type=\"image/jpg\")\n```\n\n```text\nAttributeError: '_io.BytesIO' object has no attribute 'encode'\n```\n\n```py\nbuffer = BytesIO(my_data)\n\n # Return file\n return Response(content=buffer.getvalue(), media_type=\"image/jpg\")\n```\n\n```text\nResponse\n```\n\n```text\nrender\n```\n\n```text\nResponse\n```\n\n```text\nbytes\n```\n\n```text\nBytesIO != bytes\n```\n\n```text\nreturn FileResponse(file_path, media_type=media_type, filename=basename(file_path), content_disposition_type=\"inline\")\n```\n\n========================================\n\nComments:\n- Thanks for the response! I got it to work with your suggestion but it wasn't easy (and probably overkill!). See my solution below. Other than this issue, fastAPI was a pleasure to work with a very nicely documented, thanks for providing it!\n- could you be more specific please? like where is the file name? what is the Item, where is the route?\n- @PekoChan You're right, I was missing some parts. I was trying to adapt the code I actually used to a minimal example. I made it a bit too minimal, hopefully I've fixed it.\n- If you're using `BytesIO` especially with PIL/skimage, make sure to also do `img.seek(0)` before returning!\n- This also works very well for returning GridFS objects ex: `val = grid_fs_file.read()` `return StreamingResponse(io.BytesIO(val), media_type=\"application/pdf\")` Thank you very much!\n- Things might have changed since this answer was written, but the use of `StreamingResponse` in this answer seems wrong today. See my answer.\n- @HendyIrawan Why it's important to use img.seek(0)?\n- The example presented in the above answer already has the enitre image, i.e., `im_png`, loaded into memory. Thus, writing the image to a buffered stream, i.e., `BytesIO` and returning a `StreamingResponse` should not be the preferred choice. **Instead**, a custom `Response` should be returned directly, as explained in this answer, e.g., `return Response(im_png.tobytes(), media_type='image/png')`.\n- Wow!!! `buf.seek(0)` saved me\n- In the example above, it would be a good idea to call the `close()` method of the buffer in a background task, so that the buffer is discarded, once the response has been sent to the client (see the linked answer later on). Also, since the entire contents are already loaded into memory, one should instead use `buf.getvalue()`, in order to get the entire contents of the buffer, and return a custom `Response` directly. More details are given in this answer.\n- also you need to install `aiofiles` library for this\n- whats the type of image? create image how?\n- png image here, image create as per application requirement\n- this isn't clear, what types can the `content` be? IO? bytes? etc\n- Good answer, however with this, the OpenAPI document will still list `application/json` as a possible 200 response, in addition to `image/png`. It even lists this first, so it's the first possible response shown in the generated docs. Do you know how to make it only list `image/png`? See also my question about this in github.com/tiangolo/fastapi/issues/3258\n- @estan Good catch. It looks like you've already found a solution in that GitHub issue. I have an alternative approach; I've replied to that GitHub issue with it and added it to my answer here.\n- No StreamingResponse does not correspond to chunked encoding. FastAPI/starlette are not in control of this as per the WSGI specification (see \"Handling the Content-Length Header\"). Other response classes set the `Content-Length` header for you. The StreamingResponse doesn't. `StreamingResponse(content, headers={'Content-Length': str(content_length)})` is unlikely to be chunked. To the server (uvicorn), this would look the same as any other static response.\n- @PhilipCouling \"Corresponds\" is maybe the wrong word, yeah. Would something like \"`StreamingResponse()` is likely to be handled by the server with chunked transfer encoding\" be better?\n- @Maxpm no I would actually make it clear in the answer clear that you need to set the content-length header manually (or it will likely be chunked). That's the fundamental issue you're referencing. There's also another issue with the accepted answer. There's a pretty big trip hazard passing back a file object. The api doesn't close it. So it's fine with a BytesIO but not any real file objects.\n- Man, i faced this choice few days ago. First of all i did as in your example \"pointless StreamingResponse \". I noticed that TTFB is not good and i got some problems when trying to send files more than 50 MB - it was very slow. After that i came to Response variant. It works great couse my servece send files 50 - 200 KB. Your post gave me a lot of useful information. Thanks!\n- I faced this issue as well and your answer helped a lot, this worked for me `python image = np.ones((800, 800, 3)) encoded_jpg = cv2.imencode(\".jpg\", image)[1] return Response(encoded_jpg.tobytes(), media_type=\"image/jpeg\")`\n- @Maxpm I tried your solution to return an image. But it threw `AttributeError: '_io.BytesIO' object has no attribute 'encode'` But this was resolved by using StreamingResponse. Am I missing something?\n- @MSS It's because `Response` doesn't expect a file, it expects a discrete object. If you want to pass `BytesIO` directly, use `StreamingResponse`, if you want to use `Response` feed it `bytes_io_object.read1()`.\n- @PhilipCouling I am afraid that you are mistaken. Regardless of setting the `Content-Length` header or not, `StreamingResponse` would **still stream the data in chunks**. Not only that, but if you used a `StreamingResponse` with a *synchronous* iterator, Starlette would spawn a thread from its threadpool to run it, in order to avoid blocking the event loop. Thus, `Response` and `StreamingResponse` (with `Content-Length` header or not) are **not the same**. It is all explained in this answer, including links to the relevant implementation.\n- @Chris You have misunderstood my words. I suspect you are mixing up between the application (FastAPI/starlette) delivering the data to the WSGI webserver in chunks and the webserver itself choosing to use transfer-encoding: chunked over the wire to send the response to the web-client. I have not said that `Response` and `StreamingResponse` are the same. I have not commented on the application delivering data to the webserver. I've only commented on the HTTP transfer encoding.\n- return Response(content=your_content_bytes, media_type=\"image/jpg\")","metadata":{"transformedAt":"2026-08-18T18:32:29.082Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":47,"totalLines":366,"estimatedTokens":3094}}3{"id":"stack-71516140","source":"stackoverflow","questionId":71516140,"title":"FastAPI runs API calls in serial instead of parallel fashion","tags":["python","asynchronous","concurrency","python-asyncio","fastapi"],"text":"Title: FastAPI runs API calls in serial instead of parallel fashion\nTags: python, asynchronous, concurrency, python-asyncio, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have the following FastAPI application:\n\n```\nfrom fastapi import FastAPI, Request\nimport time\n \napp = FastAPI()\n\n@app.get(\"/ping\")\nasync def ping(request: Request):\n print(\"Hello\")\n time.sleep(5)\n print(\"bye\")\n return {\"ping\": \"pong!\"}\n```\n\nCalling the above endpoint on `localhost`—e.g., `http://localhost:8501/ping`—from different tabs of the same browser window, it returns the following:\n\n```\nHello\nbye\nHello\nbye\n```\n\ninstead of:\n\n```\nHello\nHello\nbye\nbye\n```\n\nI have read about using `httpx`, but, still, I cannot get true parallelization. What's the problem?\n\n========================================\n\nTop Answer:\nThe FastAPI documentation is explicit to say the framework uses in-process tasks ( as inherited from *Starlette* ).\n\nThat, by itself, means, that all such task compete to receive ( from time to time ) the Python Interpreter GIL-lock - being efficiently a MUTEX-terrorising Global Interpreter Lock, which in effect re-`[SERIAL]`-ises any and all amounts of Python Interpreter in-process threads\n to work as *one-and-**only-one-WORKS**-while-all-others-stay-waiting*...\n\nOn fine-grain scale, you see the result -- if spawning another handler for the second ( manually initiated from a second FireFox-tab ) arriving http-request actually takes longer than a sleep has taken, the result of GIL-lock interleaved `~ 100 [ms]` time-quanta round-robin ( all-wait-one-can-work `~ 100 [ms]` before each next round of GIL-lock release-acquire-roulette takes place ) Python Interpreter internal work does not show more details, you may use more details ( depending on O/S type or version ) from here to see more in-thread LoD, like this inside the async-decorated code being performed :\n\n```\nimport time\nimport threading\nfrom fastapi import FastAPI, Request\n\nTEMPLATE = \"INF[{0:_>20d}]: t_id( {1: >20d} ):: {2:}\"\n\nprint( TEMPLATE.format( time.perf_counter_ns(),\n threading.get_ident(),\n \"Python Interpreter __main__ was started ...\"\n )\n...\n@app.get(\"/ping\")\nasync def ping( request: Request ):\n \"\"\" __doc__\n [DOC-ME]\n ping( Request ): a mock-up AS-IS function to yield\n a CLI/GUI self-evidence of the order-of-execution\n RETURNS: a JSON-alike decorated dict\n\n [TEST-ME] ...\n \"\"\"\n print( TEMPLATE.format( time.perf_counter_ns(),\n threading.get_ident(),\n \"Hello...\"\n )\n #------------------------------------------------- actual blocking work\n time.sleep( 5 )\n #------------------------------------------------- actual blocking work\n print( TEMPLATE.format( time.perf_counter_ns(),\n threading.get_ident(),\n \"...bye\"\n )\n return { \"ping\": \"pong!\" }\n```\n\nLast, but not least, do not hesitate to read more about all other sharks threads-based code may suffer from ... or even cause ... behind the curtains ...\n\n### Ad Memorandum\n\nA mixture of GIL-lock, thread-based pools, asynchronous decorators, blocking and event-handling -- a sure mix to uncertainties & HWY2HELL ;o)\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI, Request\nimport time\n \napp = FastAPI()\n\n\n@app.get(\"/ping\")\nasync def ping(request: Request):\n print(\"Hello\")\n time.sleep(5)\n print(\"bye\")\n return {\"ping\": \"pong!\"}\n```\n\n```text\nHello\nbye\nHello\nbye\n```\n\n```text\nHello\nHello\nbye\nbye\n```\n\n```text\nlocalhost\n```\n\n```text\nhttp://localhost:8501/ping\n```\n\n```text\nhttpx\n```\n\n```py\n@app.get(\"/ping\")\ndef ping(request: Request):\n #print(request.client)\n print(\"Hello\")\n time.sleep(5)\n print(\"bye\")\n return \"pong\"\n```\n\n```py\nimport asyncio\n \n@app.get(\"/ping\")\nasync def ping(request: Request):\n #print(request.client)\n print(\"Hello\")\n await asyncio.sleep(5)\n print(\"bye\")\n return \"pong\"\n```\n\n```none\nHello\nHello\nbye\nbye\n```\n\n```py\nimport httpx\nimport asyncio\n\nURLS = ['http://127.0.0.1:8000/ping'] * 2\n\nasync def send(url, client):\n return await client.get(url, timeout=10)\n\nasync def main():\n async with httpx.AsyncClient() as client:\n tasks = [send(url, client) for url in URLS]\n responses = await asyncio.gather(*tasks)\n print(*[r.json() for r in responses], sep='\\n')\n\nasyncio.run(main())\n```\n\n```text\nasync def send(url, client):\n res = await client.get(url, timeout=10)\n print(res.json())\n return res\n```\n\n```py\nimport sys\n\nprint(sys.getswitchinterval()) # 0.005\n```\n\n```py\n@app.post(\"/ping\")\nasync def ping(file: UploadFile = File(...)):\n print(\"Hello\")\n try:\n contents = await file.read()\n res = cpu_bound_task(contents) # this would block the event loop\n finally:\n await file.close()\n print(\"bye\")\n return \"pong\"\n```\n\n```py\n@app.post(\"/ping\")\ndef ping(file: UploadFile = File(...)):\n print(\"Hello\")\n try:\n contents = file.file.read()\n res = cpu_bound_task(contents)\n finally:\n file.file.close()\n print(\"bye\")\n return \"pong\"\n```\n\n```py\nfrom fastapi.concurrency import run_in_threadpool\n\nres = await run_in_threadpool(cpu_bound_task, contents)\n```\n\n```py\nimport asyncio\n\nloop = asyncio.get_running_loop()\nres = await loop.run_in_executor(None, cpu_bound_task, contents)\n```\n\n```py\nimport asyncio\nfrom functools import partial\n\nloop = asyncio.get_running_loop()\nres = await loop.run_in_executor(None, partial(cpu_bound_task, some_arg=contents))\n```\n\n```text\nimport asyncio\n\nres = await asyncio.to_thread(cpu_bound_task, contents)\n```\n\n```py\nimport asyncio\nimport concurrent.futures\n\nloop = asyncio.get_running_loop()\nwith concurrent.futures.ThreadPoolExecutor() as pool:\n res = await loop.run_in_executor(pool, cpu_bound_task, contents)\n```\n\n```py\nimport concurrent.futures\n\nloop = asyncio.get_running_loop()\nwith concurrent.futures.ProcessPoolExecutor() as pool:\n res = await loop.run_in_executor(pool, cpu_bound_task, contents)\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\nawait\n```\n\n```text\nawait\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\ndef\n```\n\n```text\nevent loop\n```\n\n```text\nawait\n```\n\n```text\nasync def\n```\n\n```text\nevent loop\n```\n\n```text\nuvicorn.run()\n```\n\n```text\nawait\n```\n\n```text\nasync def\n```\n\n```text\nasync def\n```\n\n```text\nawait\n```\n\n```text\nasync def\n```\n\n```text\nevent loop\n```\n\n```text\nevent loop\n```\n\n```text\nevent loop\n```\n\n```text\nevent loop\n```\n\n```text\nasync def\n```\n\n```text\ntime.sleep()\n```\n\n```text\nHTMLResponse\n```\n\n```text\nFileResponse\n```\n\n```text\nawait anyio.open_file()\n```\n\n```text\nFileResponse\n```\n\n```text\nawait\n```\n\n```text\nevent loop\n```\n\n```text\nJSONResponse\n```\n\n```text\nORJSONResponse\n```\n\n```text\nUJSONResponse\n```\n\n```text\njson.dumps()\n```\n\n```text\norjson.dumps()\n```\n\n```text\nujson.dumps()\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\norjson.dumps()\n```\n\n```text\ndf.to_json()\n```\n\n```text\nStreamingResponse\n```\n\n```text\nStreamingResponse\n```\n\n```text\nBackground Tasks\n```\n\n```text\nBackgroundTask\n```\n\n```text\nDependencies\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\nevent loop\n```\n\n```text\nawait\n```\n\n```text\nrun_in_threadpool()\n```\n\n```text\nanyio.to_thread.run_sync()\n```\n\n```text\n40\n```\n\n```text\nStreamingResponse\n```\n\n```text\nBackgroundTask\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\nasync def\n```\n\n```text\nawait\n```\n\n```text\nawait\n```\n\n```text\nasync def\n```\n\n```text\nevent loop\n```\n\n```text\nevent loop\n```\n\n```text\nawait\n```\n\n```text\nasync def\n```\n\n```text\nawait\n```\n\n```text\nasync def\n```\n\n```text\ntime.sleep()\n```\n\n```text\nasync\n```\n\n```text\nUploadFile\n```\n\n```text\nawait file.read()\n```\n\n```text\nawait file.close()\n```\n\n```text\nrun_in_threadpool()\n```\n\n```text\nawait\n```\n\n```text\nevent loop\n```\n\n```text\nUploadFile\n```\n\n```text\nasync\n```\n\n```text\nasync\n```\n\n```text\nawait\n```\n\n```text\nawait\n```\n\n```text\nasync for\n```\n\n```text\nasync with\n```\n\n```text\nawait\n```\n\n```text\nasync def\n```\n\n```text\nevent loop\n```\n\n```text\ntime.sleep()\n```\n\n```text\nasync def\n```\n\n```text\nasync\n```\n\n```text\ndef\n```\n\n```text\nawait\n```\n\n```text\nasync\n```\n\n```text\nawait\n```\n\n```text\nasync def\n```\n\n```text\nasyncio.sleep()\n```\n\n```text\nevent loop\n```\n\n```text\nprint(request.client)\n```\n\n```text\nhostname\n```\n\n```text\nport\n```\n\n```text\nport\n```\n\n```text\nhttpx\n```\n\n```text\nasyncio.gather()\n```\n\n```text\nasyncio.gather()\n```\n\n```text\nsend()\n```\n\n```text\nsend()\n```\n\n```text\ntime.sleep()\n```\n\n```text\ndef\n```\n\n```text\ntime.sleep()\n```\n\n```text\nx\n```\n\n```text\n5ms\n```\n\n```text\nAsync\n```\n\n```text\nawait\n```\n\n```text\nasync\n```\n\n```text\nStreamingResponse\n```\n\n```text\nasync def\n```\n\n```text\nawait\n```\n\n```text\nevent loop\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\nawait\n```\n\n```text\nbytes\n```\n\n```text\ncontents: bytes = File()\n```\n\n```text\nbytes\n```\n\n```text\nasync def\n```\n\n```text\nawait file.read()\n```\n\n```text\ncontents: bytes = File()\n```\n\n```text\nFile\n```\n\n```text\nfile: UploadFile = File(...)\n```\n\n```text\n.read()\n```\n\n```text\nSpooledTemporaryFile\n```\n\n```text\n.file\n```\n\n```text\nUploadFile\n```\n\n```text\ndef\n```\n\n```text\nawait\n```\n\n```text\nFile\n```\n\n```text\nSpooledTemporaryFile\n```\n\n```text\nFile\n```\n\n```text\ndef\n```\n\n```text\nevent loop\n```\n\n```text\nawait\n```\n\n```text\nawait\n```\n\n```text\nasync\n```\n\n```text\ndef\n```\n\n```text\nrun_in_threadpool()\n```\n\n```text\nconcurrency\n```\n\n```text\nrun_in_threadpool()\n```\n\n```text\nawait\n```\n\n```text\nasyncio\n```\n\n```text\nloop.run_in_executor()\n```\n\n```text\nevent loop\n```\n\n```text\nasyncio.get_running_loop()\n```\n\n```text\nawait\n```\n\n```text\nNone\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nlambda\n```\n\n```text\nlambda: cpu_bound_task(some_arg=contents)\n```\n\n```text\nfunctools.partial()\n```\n\n```text\nloop.run_in_executor()\n```\n\n```text\nasyncio.to_thread()\n```\n\n```text\nawait loop.run_in_executor(None, func_call)\n```\n\n```text\nasyncio.to_thread()\n```\n\n```text\nto_thread()\n```\n\n```text\n*args\n```\n\n```text\n**kwargs\n```\n\n```text\nawait\n```\n\n```text\nNone\n```\n\n```text\nexecutor\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nawait loop.run_in_executor(None, ...)\n```\n\n```text\nmin(32, os.cpu_count() + 4)\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nrun_in_threadpool()\n```\n\n```text\nrun_in_executor()\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nevent loop\n```\n\n```text\nCPU-bound\n```\n\n```text\nProcessPoolExecutor\n```\n\n```text\nasyncio\n```\n\n```text\nawait\n```\n\n```text\nif __name__ == '__main__'\n```\n\n```text\nProcessPoolExecutor\n```\n\n```text\nasyncio.create_task()\n```\n\n```text\nasync def\n```\n\n```text\nawait\n```\n\n```text\nthreading\n```\n\n```text\nmultiprocessing\n```\n\n```text\nconcurrent.futures\n```\n\n```text\napscheduler\n```\n\n```text\nuvicorn main:app --workers 4\n```\n\n```text\nevent loop\n```\n\n```text\nevent loop\n```\n\n```text\nrun_in_threadpool\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nStreamingResponse\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\nUploadFile\n```\n\n```text\nglobal\n```\n\n```py\nimport time\nimport threading\nfrom fastapi import FastAPI, Request\n\nTEMPLATE = \"INF[{0:_>20d}]: t_id( {1: >20d} ):: {2:}\"\n\nprint( TEMPLATE.format( time.perf_counter_ns(),\n threading.get_ident(),\n \"Python Interpreter __main__ was started ...\"\n )\n...\n@app.get(\"/ping\")\nasync def ping( request: Request ):\n \"\"\" __doc__\n [DOC-ME]\n ping( Request ): a mock-up AS-IS function to yield\n a CLI/GUI self-evidence of the order-of-execution\n RETURNS: a JSON-alike decorated dict\n\n [TEST-ME] ...\n \"\"\"\n print( TEMPLATE.format( time.perf_counter_ns(),\n threading.get_ident(),\n \"Hello...\"\n )\n #------------------------------------------------- actual blocking work\n time.sleep( 5 )\n #------------------------------------------------- actual blocking work\n print( TEMPLATE.format( time.perf_counter_ns(),\n threading.get_ident(),\n \"...bye\"\n )\n return { \"ping\": \"pong!\" }\n```\n\n```text\n[SERIAL]\n```\n\n```text\n~ 100 [ms]\n```\n\n```text\n~ 100 [ms]\n```\n\n========================================\n\nComments:\n- Chrome at least, blocks concurrent GET reuqests on the same URL (probably to get a chance to use the chached versin on the next one?) Testing with one Chrome in Incognito should work, with \"def\" as well as with \"async def\".\n- In short, replace `time.sleep()` with `await asyncio.sleep()`, then you will get concurrency.\n- time.sleep() is a blocking function and blocks the event loop for 5s. If you use the await keyword along with asyncio.sleep per @Bruce, it will yield control to the event loop allowing it to do other things - like executing other invocations to your function.\n- This is a misleading and incorrect answer. Starlette **does not** say that in-process tasks are used; instead, it offers in-process background tasks to use whenever desired. FastAPI & Starlette are ASGI frameworks, meaning that requests are handled *asynchronously*. Each endpoint/background task defined with `async def` will run directly in the event loop of the main thread; each worker/process is single-threaded and has its own event loop. Additional threads would be spawned/reused, if you defined such functions with normal `def` instead (part 1/2).\n- Your example and assumptions are misleading as well, as in such cases, as in the example you provided, you should use a **non-blocking** sleep operation, e.g., `await asyncio.sleep(5)`, or other approaches described in the accepted answer. Even if using your example (which is missing closing parentheses), you would see that there is **only one thread** involved. Also, when testing this through a web browser, succeeding requests should be performed from **a tab that is isolated from the browser's main session** for the reasons outlined in the accepted answer above (part 2/2).\n- In fact this was a trial to check why another call was running serial. The other function calls \"UploadFile\" and does an \"await file.read()\" and also runs serial. Moreover, this is run inside an amazon server product, after an api gateway from amazon, and hence all of the requests come from the same IP, since the user connects to amazon, and amazon server calls my api. The problem is that the operation with file is long, and if I have this serialized at the end I have timeouts because of Amazon limitation. I guess I will have to go for the last link you provided!\n- After loading the file (an image) I do some hard processing of the image and I upload the image to AWS server (there are S3 handlers). However, there aren't any other explicit awaits in the code.\n- To load the image I have: def myfunc(image: bytes = File(...)): Image.open(BytesIO(image)).convert('RGB'), but this now fails. Before it was: async def myfunc(image: UploadFile = File(...)): Image.open(BytesIO(await image.read())).convert('RGB') How should it be without async and wait?\n- computation task means CPU-intensive load. In CPython, threads don't make noticeable boosts for CPU tasks because of GIL which allows only one thread to be active at the moment. Thus, neither the `def` route nor `run_in_threadpool` will help here.\n- @zhanymkanov Thanks for the comment. I am aware of Python's GIL, and thus, I am planning on extending the above answer soon to provide further solutions using `multiprocessing`. Option 1 mentioned above (i.e., increasing the number of `workers`) is already one solution to this problem. Regardless, running such tasks in an external threadpool that is then awaited, instead of being called directly - although not offering a true parallelism - is better than nothing, as such tasks would otherwise block the entire server.\n- @chris When await is used will the code error out if the next step needs output the awaited operation? What does python execute next to avoid blocking when it encounters await? is it the next line in the code?\n- @GeorgeOfTheRF I've just posted an answer to your recent question. Please have a look.\n- @Chris just for clarity to be sure. If I use more N workers, then async routes will have N event loops, which can be blocked, right? Another question, is ThreadPoolExecutor shared between multiple workers on each worker has it's own ThreadPoolExecutor for non-async route? Thanks for clarification!\n- It's a pitty that such a great answer cannot be found in the fastAPI official document, which does not describe these clearly. It would save a lot of time for a lot of people\n- @iwtu The answer above has been updated with the relevant details. Please have a look (under the section where the \"multiple workers\" option is discussed).\n- @Chris One thing that isn't really clear to me is, if there is a (noticeable) performance difference between the Options 1, 2 and 3. As far as I understood using normal def for endpoints (Option 1) creates new threads for every single request while Options 2 and 3 don't. Is one preferred over the other? While doing tests myself, I experienced that Option 3 (with a reusable thread pool) was the fastest, could that be?\n- @NickTheDev Please have a look at this answer (see the \"Final Notes\" section, if you 're in a hurry, but I would suggest having a look at the entire answer).\n- @Chris I have read both answers multiple times before and now after you asked me to (they are great, thanks). What I read was that it's best to use async and await as much as possible. So if I have non-blocking I/O and blocking I/O in one endpoint I should use Option 2/3 to be able to differentiate. Also I thought the threads would be reused and not recreated after it idle again.\n- @NickTheDev All three options you mentioned invlove and do reuse threads from their pool. As described in both answers, when you define an endpoint with normal `def`, it is run in an external threadpool that is then `await`ed. That is the very same threadpool used in Option 2 as well, i.e., when calling `await run_in_threadpool()`. That is also the reason the linked answer noted that the default number of worker threads of that external threadpool should be adjusted as required, depending on a number of variables (see the linked answer for more details).","metadata":{"transformedAt":"2026-08-18T18:32:29.082Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":222,"totalLines":1129,"estimatedTokens":4554}}4{"id":"stack-63169865","source":"stackoverflow","questionId":63169865,"title":"How to do multiprocessing in FastAPI","tags":["python","multiprocessing","python-asyncio","fastapi","uvicorn"],"text":"Title: How to do multiprocessing in FastAPI\nTags: python, multiprocessing, python-asyncio, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nWhile serving a FastAPI request, I have a CPU-bound task to do on every element of a list. I'd like to do this processing on multiple CPU cores.\n\nWhat's the proper way to do this within FastAPI? Can I use the standard `multiprocessing` module? All the tutorials/questions I found so far only cover I/O-bound tasks like web requests.\n\n========================================\n\nTop Answer:\nWe were also looking for the solution. And finally `aiomultiprocess` library helped us run mulitprocess in nonblocking way. We are using this pool instead of concurrent futures. It is able to run without blocking and no need to call inside background tasks.\n\nPlease check it out here: https://aiomultiprocess.omnilib.dev/en/stable/\n\n```\nimport asyncio\nfrom aiohttp import request\nfrom aiomultiprocess import Pool\n\nasync def get(url):\n async with request(\"GET\", url) as response:\n return await response.text(\"utf-8\")\n\nasync def main():\n urls = [\"https://jreese.sh\", ...]\n async with Pool() as pool:\n async for result in pool.map(get, urls):\n ... # process result\n\nif __name__ == '__main__':\n # Python 3.7\n asyncio.run(main())\n\n # Python 3.6\n # loop = asyncio.get_event_loop()\n # loop.run_until_complete(main())\n```\n\n========================================\n\nCode:\n```text\nmultiprocessing\n```\n\n```text\n@app.post(\"/async-endpoint\")\nasync def test_endpoint():\n loop = asyncio.get_event_loop()\n with concurrent.futures.ProcessPoolExecutor() as pool:\n result = await loop.run_in_executor(pool, cpu_bound_func) # wait result\n```\n\n```text\n@app.post(\"/def-endpoint\")\ndef test_endpoint():\n ...\n with multiprocessing.Pool(3) as p:\n result = p.map(f, [1, 2, 3])\n```\n\n```text\n@app.post(\"/def-endpoint/\")\ndef test_endpoint():\n ...\n with concurrent.futures.ProcessPoolExecutor(max_workers=3) as executor:\n results = executor.map(f, [1, 2, 3])\n```\n\n```text\nimport asyncio\nfrom concurrent.futures.process import ProcessPoolExecutor\nfrom contextlib import asynccontextmanager\nfrom fastapi import FastAPI\n\nfrom calc import cpu_bound_func\n\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI):\n app.state.executor = ProcessPoolExecutor()\n yield\n app.state.executor.shutdown()\n\n\napp = FastAPI(lifespan=lifespan)\n\n\nasync def run_in_process(fn, *args):\n loop = asyncio.get_event_loop()\n return await loop.run_in_executor(app.state.executor, fn, *args) # wait and return result\n\n\n@app.get(\"/{param}\")\nasync def handler(param: int):\n res = await run_in_process(cpu_bound_func, param)\n return {\"result\": res}\n```\n\n```text\nimport asyncio\nfrom concurrent.futures.process import ProcessPoolExecutor\nfrom contextlib import asynccontextmanager\nfrom http import HTTPStatus\n\nfrom fastapi import BackgroundTasks\nfrom typing import Dict\nfrom uuid import UUID, uuid4\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel, Field\n\nfrom calc import cpu_bound_func\n\n\nclass Job(BaseModel):\n uid: UUID = Field(default_factory=uuid4)\n status: str = \"in_progress\"\n result: int = None\n\n\napp = FastAPI()\njobs: Dict[UUID, Job] = {}\n\n\nasync def run_in_process(fn, *args):\n loop = asyncio.get_event_loop()\n return await loop.run_in_executor(app.state.executor, fn, *args) # wait and return result\n\n\nasync def start_cpu_bound_task(uid: UUID, param: int) -> None:\n jobs[uid].result = await run_in_process(cpu_bound_func, param)\n jobs[uid].status = \"complete\"\n\n\n@app.post(\"/new_cpu_bound_task/{param}\", status_code=HTTPStatus.ACCEPTED)\nasync def task_handler(param: int, background_tasks: BackgroundTasks):\n new_task = Job()\n jobs[new_task.uid] = new_task\n background_tasks.add_task(start_cpu_bound_task, new_task.uid, param)\n return new_task\n\n\n@app.get(\"/status/{uid}\")\nasync def status_handler(uid: UUID):\n return jobs[uid]\n\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI):\n app.state.executor = ProcessPoolExecutor()\n yield\n app.state.executor.shutdown()\n```\n\n```text\nasync def\n```\n\n```text\ndef\n```\n\n```text\ndef\n```\n\n```text\ndef\n```\n\n```text\nawait\n```\n\n```text\nProcessPoolExecutor\n```\n\n```text\nmax_workers\n```\n\n```text\nNone\n```\n\n```text\n\"Accepted\"\n```\n\n```text\nID\n```\n\n```text\nID\n```\n\n```text\nBackgroundTasks\n```\n\n```text\nRabbitMQ\n```\n\n```text\nKafka\n```\n\n```text\nNATS\n```\n\n```text\nimport asyncio\nfrom aiohttp import request\nfrom aiomultiprocess import Pool\n\nasync def get(url):\n async with request(\"GET\", url) as response:\n return await response.text(\"utf-8\")\n\nasync def main():\n urls = [\"https://jreese.sh\", ...]\n async with Pool() as pool:\n async for result in pool.map(get, urls):\n ... # process result\n\nif __name__ == '__main__':\n # Python 3.7\n asyncio.run(main())\n\n # Python 3.6\n # loop = asyncio.get_event_loop()\n # loop.run_until_complete(main())\n```\n\n```text\naiomultiprocess\n```\n\n========================================\n\nComments:\n- Future readers might find this answer and this answer helpful as well.\n- But this way I don't have access to the result of cpu_bound_func to return, right?\n- In case of background executing yes, but I modified the answer for returning example.\n- In my case, I wanted to update a global `dict` inside `cpu_bound_func` which did not work using the code above. Hence I ran the function directly inside of `start_cpu_bound_task` (without `await` and `async`) and it works. Is there any downside to my solution?\n- That's not a good idea to start cpu bound function in the context of async coroutine. The most preferable is to use some interprocess communication (or cache, database) to supply state updates to the web server from the working process. The example above is just a strong simplification.\n- I tried this and ended up getting `AssertionError: daemonic processes are not allowed to have children`\n- Yeah won't work on hypercorn/gunicorn and so on\n- I tried the above solution. However, the app crashes when the function in the process pool raises a custom Exception. This is undesirable. How to handle exceptions thrown by functions in the process pool?","metadata":{"transformedAt":"2026-08-18T18:32:29.082Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":23,"totalLines":255,"estimatedTokens":1538}}5{"id":"stack-63682956","source":"stackoverflow","questionId":63682956,"title":"FastAPI: Retrieve URL from view name ( route name )","tags":["python","python-3.x","fastapi"],"text":"Title: FastAPI: Retrieve URL from view name ( route name )\nTags: python, python-3.x, fastapi\nSource: Stack Overflow\n\nQuestion:\nSuppose I have following views,\n\n```\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get('/hello/')\ndef hello_world():\n return {\"msg\": \"Hello World\"}\n\n@app.get('/hello/{number}/')\ndef hello_world_number(number: int):\n return {\"msg\": \"Hello World Number\", \"number\": number}\n```\n\nI have been using these functions in Flask and Django\n\n- Flask: **`url_for(...)`**\n\n- Django: **`reverse(...)`**\n\nSo, how can I obtain/build the URLs of `hello_world` and `hello_world_number` in a similar way?\n\n========================================\n\nTop Answer:\n**Actually you don't need to reinvent the wheel. FastAPI supports this out-of-box** *(Actually Starlette)*, **and it works pretty well.**\n\n```\napp = FastAPI()\n\n@app.get(\"/hello/{number}/\")\ndef hello_world_number(number: int):\n return {\"msg\": \"Hello World Number\", \"number\": number}\n```\n\nIf you have an endpoint like this you can simply use\n\n```\nIn: app.url_path_for(\"hello_world_number\", number=3)\nIn: app.url_path_for(\"hello_world_number\", number=50)\n\nOut: /hello/3/\nOut: /hello/50/\n```\n\nIn **FastAPI**, **APIRouter** and **FastAPI(APIRoute)** inherits from **Router**(Starlette's) so, if you have an **APIRouter** like this, you can keep using this feature\n\n```\nrouter = APIRouter()\n\n@router.get(\"/hello\")\ndef hello_world():\n return {\"msg\": \"Hello World\"}\n\nIn: router.url_path_for(\"hello_world\")\nOut: /hello\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n\n@app.get('/hello/')\ndef hello_world():\n return {\"msg\": \"Hello World\"}\n\n\n@app.get('/hello/{number}/')\ndef hello_world_number(number: int):\n return {\"msg\": \"Hello World Number\", \"number\": number}\n```\n\n```text\nurl_for(...)\n```\n\n```text\nreverse(...)\n```\n\n```text\nhello_world\n```\n\n```text\nhello_world_number\n```\n\n```py\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n\n@app.get('/hello/')\ndef hello_world():\n return {\"msg\": \"Hello World\"}\n\n\n@app.get('/hello/{number}/')\ndef hello_world_number(number: int):\n return {\"msg\": \"Hello World Number\", \"number\": number}\n\n\nprint(app.url_path_for('hello_world'))\nprint(app.url_path_for('hello_world_number', number=1))\nprint(app.url_path_for('hello_world_number', number=2))\n\n# Results\n\n\"/hello/\"\n\"/hello/1/\"\n\"/hello/2/\"\n```\n\n```py\nfrom fastapi import FastAPI, Request\n\napp = FastAPI()\n\n\n@app.get('/hello/')\ndef hello_world():\n return {\"msg\": \"Hello World\"}\n\n\n@app.get('/hello/{number}/')\ndef hello_world_number(number: int):\n return {\"msg\": \"Hello World Number\", \"number\": number}\n\n\n@app.get('/')\ndef named_url_reveres(request: Request):\n return {\n \"URL for 'hello_world'\": request.url_for(\"hello_world\"),\n \"URL for 'hello_world_number' with number '1'\": request.url_for(\"hello_world_number\", number=1),\n \"URL for 'hello_world_number' with number '2''\": request.url_for(\"hello_world_number\", number=2})\n }\n\n# Result Response\n\n{\n \"URL for 'hello_world'\": \"http://0.0.0.0:6022/hello/\",\n \"URL for 'hello_world_number' with number '1'\": \"http://0.0.0.0:6022/hello/1/\",\n \"URL for 'hello_world_number' with number '2''\": \"http://0.0.0.0:6022/hello/2/\"\n}\n```\n\n```text\nRouter.url_path_for(...)\n```\n\n```text\nFastAPI\n```\n\n```text\nFastAPI\n```\n\n```text\nAPIRouter\n```\n\n```text\nrouter.url_path_for('hello_world')\n```\n\n```text\nrouter\n```\n\n```text\nFastAPI\n```\n\n```text\nFastAPI\n```\n\n```text\nRequest\n```\n\n```text\nRequest\n```\n\n```text\nrequest\n```\n\n```text\nurl_for\n```\n\n```text\napp = FastAPI()\n\n@app.get(\"/hello/{number}/\")\ndef hello_world_number(number: int):\n return {\"msg\": \"Hello World Number\", \"number\": number}\n```\n\n```text\nIn: app.url_path_for(\"hello_world_number\", number=3)\nIn: app.url_path_for(\"hello_world_number\", number=50)\n\nOut: /hello/3/\nOut: /hello/50/\n```\n\n```text\nrouter = APIRouter()\n\n@router.get(\"/hello\")\ndef hello_world():\n return {\"msg\": \"Hello World\"}\n\nIn: router.url_path_for(\"hello_world\")\nOut: /hello\n```\n\n```text\ndef url_of(request: Request, name: str, **path_params: dict):\n from fastapi.routing import APIRoute\n from starlette.routing import NoMatchFound\n tag, tid, fname = None, name.find('.'), name\n if tid > 0:\n tag = name[:tid]\n fname = name[tid + 1:]\n url_no_tag = None\n for route in request.app.router.routes:\n if not isinstance(route, APIRoute):\n continue\n if fname == route.name and (not tag or tag in route.tags):\n try:\n url_path = route.url_path_for(fname, **path_params)\n url_no_tag = url_path.make_absolute_url(base_url=request.base_url)\n if tag:\n return url_no_tag\n except NoMatchFound:\n pass\n if url_no_tag:\n return url_no_tag\n return request.url_for(name, **path_params)\n```\n\n```py\nrouter = APIRouter(prefix='/user', tags=['user'])\n@router.get('/')\ndef login():\n return 'login page'\n```\n\n```py\n@router2.get('/test')\ndef test(request: Request):\n return RedirectResponse(url_of(request, 'user.login') + '?a=1')\n```\n\n```text\nrequest.url_for\n```\n\n```text\nrouter.url_path_for\n```\n\n```text\n__init__.py\n```\n\n```text\nurl_as\n```\n\n```text\nurl_of\n```\n\n```text\nurl_for()\n```\n\n```text\nrequest\n```\n\n```text\nurl_for\n```\n\n```text\n{{ url_for('hello_world_number', number=42) }}\n```\n\n========================================\n\nComments:\n- Great answer! I'm using Method 2 with ViewModel. I've defined the base ViewModel class to pass the `request.url_for` as an argument called `url_for` (flask nostalgia) and thereby transparently have access to it in my jinja templates (as long as we pass request, which I was already doing)\n- What would you suggest as an approach when you have multiple router files, and want to get the `url_path_for` a route in a different file? My `main.py` does a bunch of `app.include_router` to get all the routes.Thanks!\n- @Shawn I used `return fastapi.responses.RedirectResponse(url=request.url_for(name=‌​'account'), status_code=status.HTTP_302_FOUND)` in my view function based view\n- your approach returns path, not URL. `flask.url_for()` returns absolute URL value\n- it's working fine.but you can only redirectResponse when parent and target method have same route .Eg if test is post method means you can only call a post method instead you can't call the get method using the post method request object.\n- This answer aims to solve the problem of building URL from function name proposed by 'jpg'. RedirectResponse is an example of how to use the built URL. RedirectResponse is returned with 307 as the default status code (a new request is initiated in the same way during redirection). If the 'test' needs to be POST and 'login' is GET, we can set the status_code parameter as 302: `RedirectResponse(url_as(request, 'user.login') + '?a=1', status_code=302)`. The `url_as` can also be used in other ways. In fact, I register the `url_as` as a global template method in jinja2 @NAGARAJS\n- If the `request` In `request.url_for` is an incoming request instance, you don't need to implement the function `url_of(...)`, because, the `request` object has all the route informations.\n- I didn't test the `request.url_for` adequately, `url_for` can indeed get all the urls of the app by the function name. But if the same function name is defined under multiple APIRouters, `url_for` would return the first matching function name (in the order of include_router). `url_of` provides a way to get the correct url with the tag of APIRouter when there is a function name conflict. The answer has been updated. Thanks @JPG\n- It was not mentioned that `url_for` is exported in the template context.","metadata":{"transformedAt":"2026-08-18T18:32:29.082Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":34,"totalLines":321,"estimatedTokens":1926}}6{"id":"stack-69670125","source":"stackoverflow","questionId":69670125,"title":"How to log raw HTTP request/response in FastAPI?","tags":["python","logging","fastapi","python-logging","starlette"],"text":"Title: How to log raw HTTP request/response in FastAPI?\nTags: python, logging, fastapi, python-logging, starlette\nSource: Stack Overflow\n\nQuestion:\nWe are writing a web service using FastAPI that is going to be hosted in Kubernetes. For auditing purposes, we need to save the raw JSON body of the `request`/`response` for **specific** routes. The body size of both `request` and `response` JSON is about **1MB**, and preferably, this should not impact the response time.\nHow can we do that?\n\n========================================\n\nTop Answer:\n### Option 1 - Using Middleware\n\nYou could use a `Middleware`. A `middleware` takes each request that comes to your application, and hence, allows you to handle the `request`, before it is processed by any endpoint, as well as handle the `response`, before it is returned to the client. To create a `middleware`, you could use the `@app.middleware(\"http\")` decorator on top of a function, as shown in the example below.\n\nAs you need to consume the request body from the stream inside the `middleware`—using either `request.body()` or `request.stream()`, as shown in this answer (behind the scenes, the former method actually calls the latter, see here)—then it won't be available when you later pass the `request` to the corresponding endpoint. Thus, you can the approach described in this post to make the request body available down the line (i.e., using the `set_body()` function below). **UPDATE:** This issue has now been fixed, and hence, there is no need to use that workaround, if you are using FastAPI 0.108.0 or later versions.\n\nAs for the `response` body, you can use the same approach as described in this answer to consume the body and then return the `response` to the client. Either option described in the aforementioned linked answer would work; the below, however, uses Option 2, which stores the body in a bytes object and returns a custom `Response` directly (along with the `status_code`, `headers` and `media_type` of the original `response`).\n\nTo log the data, you could use a `BackgroundTask`, as described in this answer, as well as this answer and this answer. A `BackgroundTask` will run only once the response has been sent (see Starlette documentation as well); thus, the client won't have to be waiting for the logging to complete before receiving the `response` (and hence, the response time won't be noticeably impacted).\n\n### Note\n\nIf you had a streaming `request` or `response` with a body that wouldn't fit into your server's RAM (for example, imagine a body of 100GB on a machine running 8GB RAM), it would become problematic, as you are storing the data to RAM, which wouldn't have enough space available to accommodate the accumulated data. Also, in case of a large `response` (e.g., a large `FileResponse` or `StreamingResponse`), you may be faced with `Timeout` errors on client side (or on reverse proxy side, if you are using one), as you would not be able to respond back to the client, until you have read the entire response body (as you are looping over `response.body_iterator`). You mentioned that *\"the body size of both request and response JSON is about 1MB\"*; hence, that should normally be fine (however, it is always a good practice to consider beforehand matters, such as how many requests your API is expected to be serving concurrently, what other applications might be using the RAM, etc., in order to rule whether this is an issue or not). If you needed to, you could limit the number of requests to your API endpoints using, for example, SlowAPI (as shown in this answer).\n\n### Limiting the usage of the `middleware` to specific routes only\n\nYou could limit the usage of the `middleware` to specific endpoints by:\n\nchecking the `request.url.path` inside the middleware against a\npre-defined list of routes for which you would like to log the\n`request` and `response`, as described in this answer (see the\n\"**Update**\" section),\nor using a sub application, as demonstrated in this\nanswer\nor using a custom `APIRoute` class, as demonstrated in **Option 2**\nbelow.\n\n### Working Example\n\n```\nfrom fastapi import FastAPI, APIRouter, Response, Request\nfrom starlette.background import BackgroundTask\nfrom fastapi.routing import APIRoute\nfrom starlette.types import Message\nfrom typing import Dict, Any\nimport logging\n\napp = FastAPI()\nlogging.basicConfig(filename='info.log', level=logging.DEBUG)\n\ndef log_info(req_body, res_body):\n logging.info(req_body)\n logging.info(res_body)\n\n# not needed when using FastAPI>=0.108.0.\n'''\nasync def set_body(request: Request, body: bytes):\n async def receive() -> Message:\n return {'type': 'http.request', 'body': body}\n request._receive = receive\n'''\n\n@app.middleware('http')\nasync def some_middleware(request: Request, call_next):\n req_body = await request.body()\n #await set_body(request, req_body) # not needed when using FastAPI>=0.108.0.\n response = await call_next(request)\n \n chunks = []\n async for chunk in response.body_iterator:\n chunks.append(chunk)\n res_body = b''.join(chunks)\n \n task = BackgroundTask(log_info, req_body, res_body)\n return Response(content=res_body, status_code=response.status_code, \n headers=dict(response.headers), media_type=response.media_type, background=task)\n\n@app.post('/')\ndef main(payload: Dict[Any, Any]):\n return payload\n```\n\nIn case you would like to perform some validation on the request body—for example, ensruing that the request body size is not exceeding a certain value—instead of using `request.body()`, you can process the body one chunk at a time using the `.stream()` method, as shown below (similar to this answer).\n\n```\n@app.middleware('http')\nasync def some_middleware(request: Request, call_next):\n chunks = []\n async for chunk in request.stream():\n chunks.append(chunk)\n req_body = b''.join(chunks)\n ...\n```\n\n### Option 2 - Using custom `APIRoute` class\n\nYou can alternatively use a custom `APIRoute` class—similar to here and here—which, among other things, would allow you to manipulate the `request` body before it is processed by your application, as well as the `response` body before it is returned to the client. This option also allows you to limit the usage of this class to the routes you wish, as only the endpoints under the `APIRouter` (i.e., `router` in the example below) will use the custom `APIRoute` class .\n\nIt should be noted that the same comments mentioned in **Option 1** above, under the \"**Note**\" section, apply to this option as well. For example, if your API returns a `StreamingResponse`—such as in `/video` route of the example below, which is streaming a video file from an online source (public videos to test this can be found here, and you can even use a longer video than the one used below to see the effect more clearly)—you may come across issues on server side, if your server's RAM can't handle it, as well as delays on client side (and reverse proxy server, if using one) due to the whole (streaming) response being read and stored in RAM, before it is returned to the client (as explained earlier). In such cases, you could exclude such endpoints that return a `StreamingResponse` from the custom `APIRoute` class and limit its usage only to the desired routes—especially, if it is a large video file, or even live video that wouldn't likely make much sense to have it stored in the logs—simply by not using the `@` decorator (i.e., `@router` in the example below) for such endpoints, but rather using the `@` decorator (i.e., `@app` in the example below), or some other `APIRouter` or sub application.\n\n### Working Example\n\n```\nfrom fastapi import FastAPI, APIRouter, Response, Request\nfrom starlette.background import BackgroundTask\nfrom starlette.responses import StreamingResponse\nfrom fastapi.routing import APIRoute\nfrom starlette.types import Message\nfrom typing import Callable, Dict, Any\nimport logging\nimport httpx\n\ndef log_info(req_body, res_body):\n logging.info(req_body)\n logging.info(res_body)\n\n \nclass LoggingRoute(APIRoute):\n def get_route_handler(self) -> Callable:\n original_route_handler = super().get_route_handler()\n\n async def custom_route_handler(request: Request) -> Response:\n req_body = await request.body()\n response = await original_route_handler(request)\n tasks = response.background\n \n if isinstance(response, StreamingResponse):\n chunks = []\n async for chunk in response.body_iterator:\n chunks.append(chunk)\n res_body = b''.join(chunks)\n \n task = BackgroundTask(log_info, req_body, res_body)\n response = Response(content=res_body, status_code=response.status_code, \n headers=dict(response.headers), media_type=response.media_type)\n else:\n task = BackgroundTask(log_info, req_body, response.body)\n \n # check if the original response had background tasks already attached to it\n if tasks:\n tasks.add_task(task) # add the new task to the tasks list\n response.background = tasks\n else:\n response.background = task\n \n return response\n \n return custom_route_handler\n\napp = FastAPI()\nrouter = APIRouter(route_class=LoggingRoute)\nlogging.basicConfig(filename='info.log', level=logging.DEBUG)\n\n@router.post('/')\ndef main(payload: Dict[Any, Any]):\n return payload\n\n@router.get('/video')\ndef get_video():\n url = 'https://storage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4'\n \n def gen():\n with httpx.stream('GET', url) as r:\n for chunk in r.iter_raw():\n yield chunk\n\n return StreamingResponse(gen(), media_type='video/mp4')\n\napp.include_router(router)\n```\n\n========================================\n\nCode:\n```text\nrequest\n```\n\n```text\nresponse\n```\n\n```text\nrequest\n```\n\n```text\nresponse\n```\n\n```py\nimport time\nfrom typing import Callable\n\nfrom fastapi import APIRouter, FastAPI, Request, Response\nfrom fastapi.routing import APIRoute\n\n\nclass TimedRoute(APIRoute):\n def get_route_handler(self) -> Callable:\n original_route_handler = super().get_route_handler()\n\n async def custom_route_handler(request: Request) -> Response:\n before = time.time()\n response: Response = await original_route_handler(request)\n duration = time.time() - before\n response.headers[\"X-Response-Time\"] = str(duration)\n print(f\"route duration: {duration}\")\n print(f\"route response: {response}\")\n print(f\"route response headers: {response.headers}\")\n return response\n\n return custom_route_handler\n\n\napp = FastAPI()\nrouter = APIRouter(route_class=TimedRoute)\n\n\n@app.get(\"/\")\nasync def not_timed():\n return {\"message\": \"Not timed\"}\n\n\n@router.get(\"/timed\")\nasync def timed():\n return {\"message\": \"It's the time of my life\"}\n\n\napp.include_router(router)\n```\n\n```text\nfrom json import JSONDecodeError\nimport json\nimport logging\nfrom typing import Callable, Awaitable, Tuple, Dict, List\n\nfrom starlette.middleware.base import BaseHTTPMiddleware\nfrom starlette.requests import Request\nfrom starlette.responses import Response, StreamingResponse\nfrom starlette.types import Scope, Message\n\n# Set up your custom logger here\nlogger = \"\"\n\nclass RequestWithBody(Request):\n \"\"\"Creation of new request with body\"\"\"\n def __init__(self, scope: Scope, body: bytes) -> None:\n super().__init__(scope, self._receive)\n self._body = body\n self._body_returned = False\n\n async def _receive(self) -> Message:\n if self._body_returned:\n return {\"type\": \"http.disconnect\"}\n else:\n self._body_returned = True\n return {\"type\": \"http.request\", \"body\": self._body, \"more_body\": False}\n\n\nclass CustomLoggingMiddleware(BaseHTTPMiddleware):\n \"\"\"\n Use of custom middleware since reading the request body and the response consumes the bytestream.\n Hence this approach to basically generate a new request/response when we read the attributes for logging.\n \"\"\"\n async def dispatch( # type: ignore\n self, request: Request, call_next: Callable[[Request], Awaitable[StreamingResponse]]\n ) -> Response:\n # Store request body in a variable and generate new request as it is consumed.\n request_body_bytes = await request.body()\n \n request_with_body = RequestWithBody(request.scope, request_body_bytes)\n\n # Store response body in a variable and generate new response as it is consumed.\n response = await call_next(request_with_body)\n response_content_bytes, response_headers, response_status = await self._get_response_params(response)\n\n # Logging\n\n # If there is no request body handle exception, otherwise convert bytes to JSON.\n try:\n req_body = json.loads(request_body_bytes)\n except JSONDecodeError:\n req_body = \"\"\n # Logging of relevant variables.\n logger.info(\n f\"{request.method} request to {request.url} metadata\\n\"\n f\"\\tStatus_code: {response.status_code}\\n\"\n f\"\\tRequest_Body: {req_body}\\n\"\n )\n # Finally, return the newly instantiated response values\n return Response(response_content_bytes, response_status, response_headers)\n\nasync def _get_response_params(self, response: StreamingResponse) -> Tuple[bytes, Dict[str, str], int]:\n \"\"\"Getting the response parameters of a response and create a new response.\"\"\"\n response_byte_chunks: List[bytes] = []\n response_status: List[int] = []\n response_headers: List[Dict[str, str]] = []\n\n async def send(message: Message) -> None:\n if message[\"type\"] == \"http.response.start\":\n response_status.append(message[\"status\"])\n response_headers.append({k.decode(\"utf8\"): v.decode(\"utf8\") for k, v in message[\"headers\"]})\n else:\n response_byte_chunks.append(message[\"body\"])\n\n await response.stream_response(send)\n content = b\"\".join(response_byte_chunks)\n return content, response_headers[0], response_status[0]\n```\n\n```py\nfrom fastapi import FastAPI, APIRouter, Response, Request\nfrom starlette.background import BackgroundTask\nfrom fastapi.routing import APIRoute\nfrom starlette.types import Message\nfrom typing import Dict, Any\nimport logging\n\n\napp = FastAPI()\nlogging.basicConfig(filename='info.log', level=logging.DEBUG)\n\n\ndef log_info(req_body, res_body):\n logging.info(req_body)\n logging.info(res_body)\n\n\n# not needed when using FastAPI>=0.108.0.\n'''\nasync def set_body(request: Request, body: bytes):\n async def receive() -> Message:\n return {'type': 'http.request', 'body': body}\n request._receive = receive\n'''\n\n@app.middleware('http')\nasync def some_middleware(request: Request, call_next):\n req_body = await request.body()\n #await set_body(request, req_body) # not needed when using FastAPI>=0.108.0.\n response = await call_next(request)\n \n chunks = []\n async for chunk in response.body_iterator:\n chunks.append(chunk)\n res_body = b''.join(chunks)\n \n task = BackgroundTask(log_info, req_body, res_body)\n return Response(content=res_body, status_code=response.status_code, \n headers=dict(response.headers), media_type=response.media_type, background=task)\n\n\n@app.post('/')\ndef main(payload: Dict[Any, Any]):\n return payload\n```\n\n```py\n@app.middleware('http')\nasync def some_middleware(request: Request, call_next):\n chunks = []\n async for chunk in request.stream():\n chunks.append(chunk)\n req_body = b''.join(chunks)\n ...\n```\n\n```py\nfrom fastapi import FastAPI, APIRouter, Response, Request\nfrom starlette.background import BackgroundTask\nfrom starlette.responses import StreamingResponse\nfrom fastapi.routing import APIRoute\nfrom starlette.types import Message\nfrom typing import Callable, Dict, Any\nimport logging\nimport httpx\n\n\ndef log_info(req_body, res_body):\n logging.info(req_body)\n logging.info(res_body)\n\n \nclass LoggingRoute(APIRoute):\n def get_route_handler(self) -> Callable:\n original_route_handler = super().get_route_handler()\n\n async def custom_route_handler(request: Request) -> Response:\n req_body = await request.body()\n response = await original_route_handler(request)\n tasks = response.background\n \n if isinstance(response, StreamingResponse):\n chunks = []\n async for chunk in response.body_iterator:\n chunks.append(chunk)\n res_body = b''.join(chunks)\n \n task = BackgroundTask(log_info, req_body, res_body)\n response = Response(content=res_body, status_code=response.status_code, \n headers=dict(response.headers), media_type=response.media_type)\n else:\n task = BackgroundTask(log_info, req_body, response.body)\n \n # check if the original response had background tasks already attached to it\n if tasks:\n tasks.add_task(task) # add the new task to the tasks list\n response.background = tasks\n else:\n response.background = task\n \n return response\n \n return custom_route_handler\n\n\napp = FastAPI()\nrouter = APIRouter(route_class=LoggingRoute)\nlogging.basicConfig(filename='info.log', level=logging.DEBUG)\n\n\n@router.post('/')\ndef main(payload: Dict[Any, Any]):\n return payload\n\n\n@router.get('/video')\ndef get_video():\n url = 'https://storage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4'\n \n def gen():\n with httpx.stream('GET', url) as r:\n for chunk in r.iter_raw():\n yield chunk\n\n return StreamingResponse(gen(), media_type='video/mp4')\n\n\napp.include_router(router)\n```\n\n```text\nMiddleware\n```\n\n```text\nmiddleware\n```\n\n```text\nrequest\n```\n\n```text\nresponse\n```\n\n```text\nmiddleware\n```\n\n```text\n@app.middleware(\"http\")\n```\n\n```text\nmiddleware\n```\n\n```text\nrequest.body()\n```\n\n```text\nrequest.stream()\n```\n\n```text\nrequest\n```\n\n```text\nset_body()\n```\n\n```text\nresponse\n```\n\n```text\nresponse\n```\n\n```text\nResponse\n```\n\n```text\nstatus_code\n```\n\n```text\nheaders\n```\n\n```text\nmedia_type\n```\n\n```text\nresponse\n```\n\n```text\nBackgroundTask\n```\n\n```text\nBackgroundTask\n```\n\n```text\nresponse\n```\n\n```text\nrequest\n```\n\n```text\nresponse\n```\n\n```text\nresponse\n```\n\n```text\nFileResponse\n```\n\n```text\nStreamingResponse\n```\n\n```text\nTimeout\n```\n\n```text\nresponse.body_iterator\n```\n\n```text\nmiddleware\n```\n\n```text\nmiddleware\n```\n\n```text\nrequest.url.path\n```\n\n```text\nrequest\n```\n\n```text\nresponse\n```\n\n```text\nAPIRoute\n```\n\n```text\nrequest.body()\n```\n\n```text\n.stream()\n```\n\n```text\nAPIRoute\n```\n\n```text\nAPIRoute\n```\n\n```text\nrequest\n```\n\n```text\nresponse\n```\n\n```text\nAPIRouter\n```\n\n```text\nrouter\n```\n\n```text\nAPIRoute\n```\n\n```text\nStreamingResponse\n```\n\n```text\n/video\n```\n\n```text\nStreamingResponse\n```\n\n```text\nAPIRoute\n```\n\n```text\n@<name_of_router>\n```\n\n```text\n@router\n```\n\n```text\n@<name_of_app>\n```\n\n```text\n@app\n```\n\n```text\nAPIRouter\n```\n\n========================================\n\nComments:\n- Related topic You could use middleware or apirouter and loguru logger with option `enqueue=True`. This will allow you not to affect response time.\n- As a note to this example, and the others - all sharing some similarities around recreating the original response: these all contain a bug where duplicate response headers (which are allowed per http spec, e.g. multiple set-cookie headers) will be removed, and only the last one will be kept. This happens due to the List[Tuple[bytes, bytes]] -> Dict[str, str] conversion.\n- yes there was a problem with my code. Thanks for taking a look. BTW, I have not found a way to quickly see which of the router's endpoint was triggered plus have a way to bubble up information from the endpoint. Currently I misuse the response headers to pass values upwards to the logger, but that seems like a dirty hack to me.\n- @576i You could use `request.url.path`, as shown here, to identify which endpoint was triggered. See this answer and this answer as well.\n- Thanks, I've tried that and it works. (but it seems not suitable for larger projects) In my real world code I have the routes in seperate files with are imported and attached like this `app.include_router(router=routes_status.router, prefix=\"/api\", tags=[\"My API\"])`. These routers has a few endpoints each. For me the obvious place to store the info if something should trigger the middleware is in that file close to the endpoint, so the should-I-log info should \"bubble up\". That's why I am passing the info up via headers, but am looking for a better way. I should make that a new question...\n- @576i You could store additional information on the `Request` object using `request.state`, as described here, as well as here and here. You might find this answer helpful as well.\n- thanks for those suggestions - that's very helpful.\n- If using `fastapi>0.106.0` then you no longer need the `set_body()` method described above in Option 1. If you try to use it, then you will get error `Unexpected message received: http.request`. This is because this 'quirk' of fastapi has been fixed, so you no longer need to restore the request body after reading it. See more at github.com/tiangolo/fastapi/discussions/…\n- @ZoltanFedor The answer has been updated with the relevant details. Couldn't reproduce the error you mentioned though - the example worked as expected even with using the `set_body()` method (in FastAPI 0.108.0). Regardless, since the issue has now been fixed, there is no longer need for calling the `set_body()` method.","metadata":{"transformedAt":"2026-08-18T18:32:29.083Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":61,"totalLines":664,"estimatedTokens":5375}}7{"id":"stack-62468402","source":"stackoverflow","questionId":62468402,"title":"Query parameters from pydantic model","tags":["python","fastapi","pydantic"],"text":"Title: Query parameters from pydantic model\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nIs there a way to convert a pydantic model to query parameters in fastapi? \n\nSome of my endpoints pass parameters via the body, but some others pass them directly in the query. All this endpoints the same data model, for example: \n\n```\nclass Model(BaseModel):\n x: str\n y: str\n```\n\nI would like to avoid duplicating my definition of this model in the definition of my \"query-parameters endpoints\", like for example `test_query` in this code:\n\n```\nclass Model(BaseModel):\n x: str\n y: str\n\n@app.post(\"/test-body\")\ndef test_body(model: Model): pass\n\n@app.post(\"/test-query-params\")\ndef test_query(x: str, y: str): pass\n```\n\nWhat's the cleanest way of doing this?\n\n========================================\n\nTop Answer:\nSpecial case that isn't mentioned in the documentation for Query Parameters Lists, for example with:\n\n```\n/members?member_ids=1&member_ids=2\n```\n\nThe answer provided by @cglacet will unfortunately ignore the array for such a model:\n\n```\nclass Model(BaseModel):\n member_ids: List[str]\n```\n\nYou need to modify your model like so:\n\n```\nclass Model(BaseModel):\n member_ids: List[str] = Field(Query([]))\n```\n\nAnswer from @fnep on GitHub here\n\n22nd of Jan. 2025:\nThis solution is still working as of Pydantic v2.8.2\n\n========================================\n\nCode:\n```py\nclass Model(BaseModel):\n x: str\n y: str\n```\n\n```py\nclass Model(BaseModel):\n x: str\n y: str\n\n@app.post(\"/test-body\")\ndef test_body(model: Model): pass\n\n@app.post(\"/test-query-params\")\ndef test_query(x: str, y: str): pass\n```\n\n```text\ntest_query\n```\n\n```py\nfrom fastapi import Depends\n\n@app.post(\"/test-query-params\")\ndef test_query(model: Model = Depends()): pass\n```\n\n```py\nfrom typing import Annotated\nfrom fastapi import Depends\n\n@app.post(\"/test-query-params\")\ndef test_query(model: Annotated[Model, Depends()]): pass\n```\n\n```text\n/test-query-params?x=1&y=2\n```\n\n```text\nDepends()\n```\n\n```text\nfrom fastapi import Depends, FastAPI, Query\n\napp = FastAPI()\n\n\nclass Model:\n def __init__(\n self,\n y: str,\n x: str = Query(\n default='default for X',\n title='Title for X',\n deprecated=True\n )\n\n ):\n self.x = x\n self.y = y\n\n\n@app.post(\"/test-body\")\ndef test_body(model: Model = Depends()):\n return model\n```\n\n```text\n/members?member_ids=1&member_ids=2\n```\n\n```text\nclass Model(BaseModel):\n member_ids: List[str]\n```\n\n```text\nclass Model(BaseModel):\n member_ids: List[str] = Field(Query([]))\n```\n\n```text\nimport inspect\n\nfrom fastapi import Query, FastAPI, Depends\nfrom pydantic import BaseModel, ValidationError\nfrom fastapi.exceptions import RequestValidationError\n\n\nclass QueryBaseModel(BaseModel):\n def __init_subclass__(cls, *args, **kwargs):\n field_default = Query(...)\n new_params = []\n for field in cls.__fields__.values():\n default = Query(field.default) if not field.required else field_default\n annotation = inspect.Parameter.empty\n\n new_params.append(\n inspect.Parameter(\n field.alias,\n inspect.Parameter.POSITIONAL_ONLY,\n default=default,\n annotation=annotation,\n )\n )\n\n async def _as_query(**data):\n try:\n return cls(**data)\n except ValidationError as e:\n raise RequestValidationError(e.raw_errors)\n\n sig = inspect.signature(_as_query)\n sig = sig.replace(parameters=new_params)\n _as_query.__signature__ = sig # type: ignore\n setattr(cls, \"as_query\", _as_query)\n\n @staticmethod\n def as_query(parameters: list) -> \"QueryBaseModel\":\n raise NotImplementedError\n\nclass ParamModel(QueryBaseModel):\n start_datetime: datetime\n \napp = FastAPI()\n\n@app.get(\"/api\")\ndef test(q_param: ParamModel: Depends(ParamModel.as_query))\n start_datetime = q_param.start_datetime\n ...\n return {}\n```\n\n```text\nfrom typing import Annotated\nfrom fastapi import Depends\nfrom pydantic import BaseModel, Field\n\nclass Model(BaseModel):\n query_param1: str = Field(...)\n query_param2: int | None = Field(None)\n\n\n@app.get(\"\")\nasync def _(query_params: Model = Depends()):\n ...\n```\n\n```text\nfrom dataclasses import dataclass\n\nfrom fastapi import Query\nfrom typing import List, Optional\n\n@dataclass\nclass QueryParametersDTO:\n projections: List[str] = Query(default=[], alias=\"projections\")\n includes: Optional[List[str]] = Query(default=[], alias=\"includes\")\n start: Optional[int] = Query(0)\n limit: Optional[int] = Query(10)\n```\n\n```text\nfrom typing import Annotated, Literal\n\nfrom fastapi import FastAPI, Query\nfrom pydantic import BaseModel, Field\n\napp = FastAPI()\n\n\nclass FilterParams(BaseModel):\n limit: int = Field(100, gt=0, le=100)\n offset: int = Field(0, ge=0)\n order_by: Literal[\"created_at\", \"updated_at\"] = \"created_at\"\n tags: list[str] = []\n\n\n@app.get(\"/items/\")\nasync def read_items(filter_query: Annotated[FilterParams, Query()]):\n return filter_query\n```\n\n========================================\n\nComments:\n- Please have a look at this answer, which provides a working example demonstrating how to use Pydantic models to define query parameters (including `List` query params), as well as how to validate the parameters and raise exceptions.\n- Wooow, thank you SO much! This has eluded me for months! It's unintuitive that `model: Model` is recognized as body params, but `model: Model = Depends()` is recognized as query params. The fastapi docs are nice and all, but sometimes they fail to highlight key things like this.\n- @mblakesley don't hesitate asking for help on the dedicated gitter, I think that's how I got this information (gitter.im/tiangolo/fastapi)\n- This is a very nice explanation. I just want to add that this goes only one level deep. If you have some_other_key: SomeOtherModel in your Model class it will be evaluated as a body parameter. So, when using this technique, only your model should inherit from parent classes, not your Model attributes.\n- Note that this does not work for models using \"advanced\" validators like `field_validator`. If validation fails in it, it will crash the call.\n- Seems to not work anymore with pydantic 2. The request fails asking for a body payload\n- @Finch_Powers I had the same issue attempting to add a model_validator to the model, but found that it worked if the validator raises an HTTPException when validation fails.\n- Are you aware you can also use `Query` definitions in pydantic models?\n- @h345k34cr Yes, I do. Unfortunately, it doesn't work for the ***linked SO post***\n- It is also worth to add a minimal example here as a new answer so that someone else can benefit from that. @h345k34cr\n- this is cool, but seem not working for pydantic v2\n- This works jsut fine, however, the OpenAPI documentation does not enable user to send multiple arguments for that field. Any way to fix that?\n- @MiradilZeynalli you can specify a custom path using openapi_extra in your app decorator, see fastapi.tiangolo.com/advanced/…. You shouldn't have to do that though, in my OpenAPI documentation at least the array[string] properly shows up and I have the possibility to add and remove strings, execution is properly formatted as well","metadata":{"transformedAt":"2026-08-18T18:32:29.083Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":15,"totalLines":265,"estimatedTokens":1858}}8{"id":"stack-57204499","source":"stackoverflow","questionId":57204499,"title":"Is there a FastAPI way to access current Request data globally?","tags":["fastapi"],"text":"Title: Is there a FastAPI way to access current Request data globally?\nTags: fastapi\nSource: Stack Overflow\n\nQuestion:\nWithin the FastAPI framework:\n\nWhile request data can certainly be passed around as an argument, I would like to know if it is possible for a function to access information about the current request without being passed an argument.\n\nDisclaimer: I do not think global access to Request data a good practice, and yet I have a use case where it would be very good to be able to do.\n\n========================================\n\nTop Answer:\nWanted to provide an updated answer here. My original comment is on a starlette issue, here.\n\nI am using FastAPI, and needed a way to access information on the request object outside of a view. I initially looked at using starlette-context but found the below solution to work for my needs.\n\nCredit to Marc (see starlette issue above) for the basis of this solution.\n\nAs noted by Colin Le Nost above, the authors warn against using `BaseHTTPMiddleware` -- the parent class Marc's middleware inherits from.\n\nInstead, the suggestion is to use a raw ASGI middleware. However, there isn't much documentation for this. I was able to use Starlette's AuthenticationMiddleware as a reference point, and develop what I needed in combination with Marc's wonderful solution of ContextVars.\n\n```\n# middleware.py\nfrom starlette.types import ASGIApp, Receive, Scope, Send\n\nREQUEST_ID_CTX_KEY = \"request_id\"\n\n_request_id_ctx_var: ContextVar[str] = ContextVar(REQUEST_ID_CTX_KEY, default=None)\n\ndef get_request_id() -> str:\n return _request_id_ctx_var.get()\n\nclass CustomRequestMiddleware:\n def __init__(\n self,\n app: ASGIApp,\n ) -> None:\n self.app = app\n\n async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:\n if scope[\"type\"] not in [\"http\", \"websocket\"]:\n await self.app(scope, receive, send)\n return\n\n request_id = _request_id_ctx_var.set(str(uuid4()))\n\n await self.app(scope, receive, send)\n\n _request_id_ctx_var.reset(request_id)\n```\n\nAnd then in the app setup:\n\n```\n# main.py\napp.add_middleware(CustomRequestMiddleware)\n```\n\nAnd finally, the non-view function:\n\n```\n# myfunc.py\nimport get_request_id\n\nrequest_id = get_request_id()\n```\n\nThis should enable you to use ContextVars as a way to get any info from the request object you need, and make it available outside of view function. Thanks again to everyone in this thread for all the help, and I hope the above is useful!\n\n========================================\n\nCode:\n```py\nimport uvicorn\nfrom fastapi import FastAPI\nfrom starlette.requests import Request\nfrom starlette.responses import JSONResponse\nfrom starlette.middleware import Middleware\n\nfrom starlette_context import context, plugins\nfrom starlette_context.middleware import RawContextMiddleware\n\nmiddleware = [\n Middleware(\n RawContextMiddleware,\n plugins=(\n plugins.RequestIdPlugin(),\n plugins.CorrelationIdPlugin()\n )\n )\n]\n\napp = FastAPI(debug=True, middleware=middleware)\n\n\n@app.route('/')\nasync def index(request: Request): # This argument is still needed here\n return JSONResponse(context.data) # Your context data\n\n\nuvicorn.run(app, host=\"0.0.0.0\")\n```\n\n```text\ncontext\n```\n\n```text\nstarlette-context==0.3.0\n```\n\n```text\nStarlette\n```\n\n```text\nBaseHTTPMiddleware\n```\n\n```text\nRawContextMiddleware\n```\n\n```text\nStarlette\n```\n\n```text\nasync def push(self, msg: str):\n await self.channel.default_exchange.publish(\n Message(msg.encode(\"ascii\")),\n routing_key=self.queue_name,\n )\n```\n\n```text\nasync def _notify(self, message: IncomingMessage):\n living_connections = []\n while len(self.connections) > 0:\n websocket = self.connections.pop()\n await websocket.send_text(f\"{message.body}\")\n living_connections.append(websocket)\n self.connections = living_connections\n```\n\n```text\n_notify\n```\n\n```text\nrequest.state\n```\n\n```py\nfrom starlette.requests import Request\nfrom fastapi import FastApi\n\napp = FastApi()\n@app.get('/')\ndef get(request:Request):\n requests_header = request.headers\n return \"Hi\"\n```\n\n```py\n# middleware.py\nfrom starlette.types import ASGIApp, Receive, Scope, Send\n\nREQUEST_ID_CTX_KEY = \"request_id\"\n\n_request_id_ctx_var: ContextVar[str] = ContextVar(REQUEST_ID_CTX_KEY, default=None)\n\ndef get_request_id() -> str:\n return _request_id_ctx_var.get()\n\nclass CustomRequestMiddleware:\n def __init__(\n self,\n app: ASGIApp,\n ) -> None:\n self.app = app\n\n async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:\n if scope[\"type\"] not in [\"http\", \"websocket\"]:\n await self.app(scope, receive, send)\n return\n\n request_id = _request_id_ctx_var.set(str(uuid4()))\n\n await self.app(scope, receive, send)\n\n _request_id_ctx_var.reset(request_id)\n```\n\n```py\n# main.py\napp.add_middleware(CustomRequestMiddleware)\n```\n\n```py\n# myfunc.py\nimport get_request_id\n\nrequest_id = get_request_id()\n```\n\n```text\nBaseHTTPMiddleware\n```\n\n========================================\n\nComments:\n- While it might be useful, this is not what OP was asking about.\n- More details and examples related on the approach above might be found here.\n- In this example we are getting the request object passed as an argument to our get callback. And we could pass it to other functions as an argument. However I was asking about being able to access whatever the current request was from another module without passing it as an argument. For example if we create a logging.Formatter that wants to include something from the request as a standard part of each log message, we need a way to access the request object without passing it to the format method.\n- Woops, sorry about that. I haven't found a good way, I was looking into this. You can use fastapi Dependencies (fastapi.tiangolo.com/tutorial/bigger-applications/#dependen‌​cies) but I've found the function is invoked every time. Another way I've heard about is using a MiddleWare. Some stuff I found on the web but haven't been able to get personally working. - github.com/tiangolo/fastapi/issues/633 - github.com/tiangolo/fastapi/issues/81 Sorry about that, I understand better now what you're interested in.\n- Hey, I wrote starlette-context! If you have questions don't hesitate to open a ticket on GH.\n- Hey @TomWojcik, I have an issue with starlette_context: I am working on a FastAPI app, and I had to add your package because I need to receive some data over a http header and put something in a context to be used laters. The application works perfectly, but I have a few test that fail because \"You didn't use ContextMiddleware or you're trying to access context object outside of the request-response cycle\". Now, I am using the same factory to generate the app object with all the correct middlewares, and the test call contains the header I need to test. I don't understand why the error occurs\n- Hey @bruno-ripa, please open a ticket on GH but chances are it's due to incorrect order of middlewares.\n- Very glad to find this thread, and also very glad to find this library. I'd suggest checking out the latest discussion on Github. In short: it looks like RawContextMiddleware has been established as the path forward. Thanks @TomWojcik for providing this library and pivoting to address this issue.\n- I have to write \"app.add_middleware(CustomRequestMiddleware)\" after other mount、include_router、middlewares to make this work.\n- What is the reason for this line `if scope[\"type\"] not in [\"http\", \"websocket\"]:`","metadata":{"transformedAt":"2026-08-18T18:32:29.083Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":16,"totalLines":226,"estimatedTokens":1891}}9{"id":"stack-71435960","source":"stackoverflow","questionId":71435960,"title":"What is the purpose of Uvicorn?","tags":["python-3.x","frameworks","fastapi","web-frameworks","uvicorn"],"text":"Title: What is the purpose of Uvicorn?\nTags: python-3.x, frameworks, fastapi, web-frameworks, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI supposed to work with FastAPI. I was taught that FastAPI is used with Uvicorn. What exactly is Uvicorn. I don't know what uvicorn is doing with FastAPI exactly. Can anyone explain?\n\n========================================\n\nTop Answer:\nIn short, **Uvicorn** is a lightning-fast ASGI (Asynchronous Server Gateway Interface) server implementation for Python.\n\nWhile frameworks like **FastAPI** (which I used in my project) define *how* your API handles requests (routing, validation, logic), they do not include a web server to actually listen for network requests and send responses. Uvicorn fills this gap by acting as the bridge between the outside world (HTTP) and your Python application.\n\n========================================\n\nComments:\n- Can uvicorn be used as a production server ?\n- @vipulb Usually you'll run gunicorn with the UvicornWorker in that case, as that allows you to properly spawn many workers and scale your deployment properly. This is also what's suggested in uvicorn's deployment guide: uvicorn.org/deployment\n- Is it the same as `http-server` in Node.js?\n- @MaulanaAdamSahid while I'm not deeply familiar with `http-server`, if my memory serves me correct, it only serves static files. The ASGI protocol is meant for dynamic web applications, not (only) static files.\n- is uvicorn the most popular web framework for asgi?\n- @mike01010 While not related to this question, uvicorn isn't really an application framework, it's more of a webserver or application server that is used by other frameworks (FastAPI, Starlette, etc. - anything compatible with ASGI).\n- @MatsLindh yeah, as im reading up on it i realized this. i looking to move to a faster ASGI framework from Flask. looks like Blacksheep and FastApi are possible good choices.\n- It's usually not the framework that is the limiting factor, but what you're doing inside the framework - Flask can be more than quick enough. But I'm happy with both Flask and FastAPI, and I do like how FastAPI allows for compositing dependencies required for endpoints. async is its own can of worms as it requires everything to be async compatible in your critical paths to have any real performance gain. You're also mostly going to use gunicorn with the uvicorn worker in production.","metadata":{"transformedAt":"2026-08-18T18:32:29.083Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":0,"totalLines":25,"estimatedTokens":598}}10{"id":"stack-65635346","source":"stackoverflow","questionId":65635346,"title":"How can I enable CORS in FastAPI?","tags":["python","cors","fastapi"],"text":"Title: How can I enable CORS in FastAPI?\nTags: python, cors, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm trying to enable CORS in this very basic FastAPI example, however it doesn't seem to be working.\n\n```\nfrom fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware\n\napp = FastAPI()\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=['*']\n)\n\n@app.get('/')\ndef read_main():\n return {'message': 'Hello World!'}\n```\n\nThis is the response I get:\n\n```\ncurl -v http://127.0.0.1:8000\n* Trying 127.0.0.1...\n* TCP_NODELAY set\n* Connected to 127.0.0.1 (127.0.0.1) port 8000 (#0)\n> GET / HTTP/1.1\n> Host: 127.0.0.1:8000\n> User-Agent: curl/7.64.1\n> Accept: */*\n>\n< HTTP/1.1 200 OK\n< date: Fri, 08 Jan 2021 19:27:37 GMT\n< server: uvicorn\n< content-length: 26\n< content-type: application/json\n<\n* Connection #0 to host 127.0.0.1 left intact\n{\"message\":\"Hello World!\"}*\n```\n\n========================================\n\nTop Answer:\nIn my case, CORS not works when pydantic or type problems occured.\n\n```\nfrom fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware\n\napp = FastAPI()\n\norigins = [\n \"http://localhost:3000\",\n]\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=origins,\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n\n# works well!\n@app.get(\"/list\")\nasync def main():\n return [\"hi\", \"hello\"]\n\n# error cases\nfrom typing import List\nfrom app.nosql.model import Book\n\n@app.get(\"/error\")\nasync def main():\n # case 1\n ret = mongo_db.engine.find(Book, limit=10) # keyword \"await\" missing\n return ret # CORS 500 error\n # case 2\n ret: List[Book] = await mongo_db.engine.find(Book, limit=10) # data was not fit with model Book\n return ret # CORS error\n # case 3\n return [\"hi\", \"hello\"] # works well...\n```\n\nWhats the server-side error says?\nIt might be error occurs in server.\nHow about test with new function. (has no error)\nIf server works well.. humm.. sry about that.\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware\n\napp = FastAPI()\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=['*']\n)\n\n@app.get('/')\ndef read_main():\n return {'message': 'Hello World!'}\n```\n\n```text\ncurl -v http://127.0.0.1:8000\n* Trying 127.0.0.1...\n* TCP_NODELAY set\n* Connected to 127.0.0.1 (127.0.0.1) port 8000 (#0)\n> GET / HTTP/1.1\n> Host: 127.0.0.1:8000\n> User-Agent: curl/7.64.1\n> Accept: */*\n>\n< HTTP/1.1 200 OK\n< date: Fri, 08 Jan 2021 19:27:37 GMT\n< server: uvicorn\n< content-length: 26\n< content-type: application/json\n<\n* Connection #0 to host 127.0.0.1 left intact\n{\"message\":\"Hello World!\"}*\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware\n\napp = FastAPI()\n\norigins = [\"*\"]\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=origins,\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n\n\n@app.get(\"/\")\nasync def main():\n return {\"message\": \"Hello World\"}\n```\n\n```sh\nuvicorn main:app --reload --host 0.0.0.0 --port 8000\n```\n\n```text\n<script>\n fetch(\"http://192.12.12.12:8000/\").then((Response) => {\n return Response.json()\n }).then((data) => {\n console.log(data);\n })\n </script>\n```\n\n```text\nmain.py\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware\n\napp = FastAPI()\n\norigins = [\n \"http://localhost:3000\",\n]\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=origins,\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n\n# works well!\n@app.get(\"/list\")\nasync def main():\n return [\"hi\", \"hello\"]\n\n# error cases\nfrom typing import List\nfrom app.nosql.model import Book\n\n@app.get(\"/error\")\nasync def main():\n # case 1\n ret = mongo_db.engine.find(Book, limit=10) # keyword \"await\" missing\n return ret # CORS 500 error\n # case 2\n ret: List[Book] = await mongo_db.engine.find(Book, limit=10) # data was not fit with model Book\n return ret # CORS error\n # case 3\n return [\"hi\", \"hello\"] # works well...\n```\n\n```text\napp = FastAPI()\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=['*']\n)\n\n... much later somewhere within lots of green code ...\napp = FastAPI()\n```\n\n```text\nexpose_headers=[\"*\"]\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware, Response\n\napp = FastAPI()\napp.add_middleware(\n CORSMiddleware, allow_origins=['null'],\n allow_credentials=True, allow_methods=['*'], allow_headers=['*'])\n\n@app.get('/')\ndef main():\n return Response('OK', status_code=200)\n```\n\n```text\n'null'\n```\n\n========================================\n\nComments:\n- It seems to be working. You are allowing requests from every origin\n- @Isabi I don't get *Access-Control-Allow-Origin: ** in my response though.\n- Have you tried with a browser or an app? My guess is that curl is not sending the `Origin` in the headers because it has no well defined origin, so it cannot return it in the headers\n- I tried with Chrome and Postman. The only headers I get in the response are: *content-length*, *content-type*, *date* and *server*.\n- That's strange. Have you tried with the full example? fastapi.tiangolo.com/tutorial/cors/?h=+cors#use-corsmiddlewa‌​re\n- I have tried that too. I've no idea what's going on unfortunately...\n- I tested the sample code of the official docs and it does not show the CORS when requested from the terminal, but it shows them from javascript running within the browser (Chromium `Version 87.0.4280.88 (Official Build) snap (64-bit)`)\n- If CORS is indeed enabled, should the *Access-Control-Allow-Origin: ** header not be sent with the response?\n- If it's in the browser in which `CORS` permissions are mandatory yes, but in the case of an API requests from different sources/domains will be performed, then no. `CORS` are mainly for security reasons (scripts that perform requests to external resources)\n- @lsabi of what use is this CORS if it cant restrict at all times? looks to me like a useless feature as it can be bypassed pretty easily and just does not work, also if behind web server proxy...wont work except if proxy is setup to use CORS also\n- @uberrebu I don't understand your question. Goal of CORS is to support direct access of javascript to third party APIs\n- or to restrict and only allow from certain origins/domains...yes or no?\n- @lsabi yes or no? CORS is to control access to endpoint based on origin/domain? yes or no?\n- @uberrebu No, CORS is for restricting access to the same domain. I want to be the only one accessing my API from the browser, thus I allow only my domain as origin (though direct API calls, not through browser, are allowed). This ensures more security for my users who navigate via browser\n- you said No and then agree with what am saying, contradicting there...you just said for restricting access...so if this CORS can be bypassed, then is that security of illusion of security?\n- as here is written: stackoverflow.com/questions/65191061/… The reponse is only generated if the sender includes origin in the header.\n- not working for me even restarted the server\n- @SunilGarg it shouldn't work. on the link given by yuanzz fastapi.tiangolo.com/tutorial/cors/…, it literally says \"allow_origins cannot be set to ['*'] for credentials to be allowed\"\n- You can't use [*] as allowed origins while with_credentials is set to true\n- Literal quote from the help page: *\"Also, allow_origins cannot be set to `[*]` for credentials to be allowed, origins must be specified.\"*\n- As others have said REMOVE `allow_methods=[\"*\"],` if the origin is a wildcard otherwise it WILL NOT WORK\n- As per the documentation, it is preferabe to explicitly specify the allowed origins, e.g., `origins = ['http://localhost:3000', 'http://127.0.0.1:3000']`, instead of using the `\"*\"` wildcard, which would allow **any** origin at the cost of excluding everything that involves credentials from the communication, such as cookies and Authorization headers. See here and here as well.\n- Please have a look at related answers here and here\n- The docs explicitly say: allow_credentials - Indicate that cookies should be supported for cross-origin requests. Defaults to False. Also, allow_origins cannot be set to ['*'] for credentials to be allowed, origins must be specified. I know FastAPI will quietly accept * origin and allow_credentials=True, but it will most likely not pass cookies.\n- This isn't an answer. It's better to add comments instead of answers if you've got a similar question. But even then this isn't a minimal working example. So it's not clear what you're trying to add to the conversation here.\n- CORS headers are **not** added when the request ends in an error. Please have a look at this answer for more details.\n- Where? As an argument to `add_middleware()`?\n- Yes, just like this: `app.add_middleware( CORSMiddleware, ..., expose_headers=[\"*\"] )` Also, you can be very specific about the headers you want to allow to avoid security risks!\n- where we should add this line??","metadata":{"transformedAt":"2026-08-18T18:32:29.083Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":11,"totalLines":278,"estimatedTokens":2273}}11{"id":"stack-64379089","source":"stackoverflow","questionId":64379089,"title":"How to read body as any valid json?","tags":["json","fastapi","pydantic"],"text":"Title: How to read body as any valid json?\nTags: json, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI haven't found the docs for that use case. How can I get the request body, ensure it's a valid JSON (**any valid JSON**, including numbers, string, booleans, and nulls, not only objects and arrays) and get the actual JSON.\nUsing Pydantic forces the JSON to have a specific structure.\n\n========================================\n\nTop Answer:\nThe accepted answer is valid as well, but FastAPI provides a built-in way to do that - check the Singular values in body section in docs.\n\nA parameter with the default `Body` gets all the payload that doesn't match passed Pydantic-typed parameters (the whole payload in our case) and converts it to the appropriate Python type. In case of invalid JSON, a standard validation error would be produced.\n\n```\nfrom typing import Any\nfrom fastapi import Body, FastAPI\n\napp = FastAPI()\n\n@app.post('/test')\nasync def update_item(\n payload: Any = Body(None)\n):\n return payload\n```\n\n**UPD:** Note on first Body positional argument (default) - None here makes request body optional, `...` (Ellipsis) - marks it as required (passing nothing will actually keep it required). Read more in the Required with Ellipsis docs section\n\nAlso, this solution works for JSON containing only `null`, `true`, `false`, any string, any number.\n\n========================================\n\nCode:\n```text\nfrom fastapi import Request, FastAPI\n\n@app.post(\"/dummypath\")\nasync def get_body(request: Request):\n return await request.json()\n```\n\n```text\nRequest\n```\n\n```text\nrequest.json()\n```\n\n```text\nrequest.body()\n```\n\n```text\nfrom fastapi import FastAPI\nfrom typing import Any, Dict, AnyStr, List, Union\n\napp = FastAPI()\n\nJSONObject = Dict[AnyStr, Any]\nJSONArray = List[Any]\nJSONStructure = Union[JSONArray, JSONObject]\n\n\n@app.post(\"/\")\nasync def root(arbitrary_json: JSONStructure = None):\n return {\"received_data\": arbitrary_json}\n```\n\n```text\ncurl -X POST \"http://0.0.0.0:6022/\" -H \"accept: application/json\" -H \"Content-Type: application/json\" -d \"{\\\"test_key\\\":\\\"test_val\\\"}\"\n```\n\n```text\n{\n \"received_data\": {\n \"test_key\": \"test_val\"\n }\n}\n```\n\n```text\ncurl -X POST \"http://0.0.0.0:6022/\" -H \"accept: application/json\" -H \"Content-Type: application/json\" -d \"[\\\"foo\\\",\\\"bar\\\"]\"\n```\n\n```text\n{\n \"received_data\": [\n \"foo\",\n \"bar\"\n ]\n}\n```\n\n```text\nfrom fastapi import FastAPI, Request\n\napp = FastAPI()\n\n\n@app.post(\"/\")\nasync def root(request: Request):\n return {\"received_request_body\": await request.body()}\n```\n\n```text\nfrom typing import Any\nfrom fastapi import Body, FastAPI\n\napp = FastAPI()\n\n\n@app.post('/test')\nasync def update_item(\n payload: Any = Body(None)\n):\n return payload\n```\n\n```text\nBody\n```\n\n```text\n...\n```\n\n```text\nnull\n```\n\n```text\ntrue\n```\n\n```text\nfalse\n```\n\n```text\nasync def print_request(request):\n print(f'request header : {dict(request.headers.items())}' )\n print(f'request query params : {dict(request.query_params.items())}') \n try : \n print(f'request json : {await request.json()}')\n except Exception as err:\n # could not parse json\n print(f'request body : {await request.body()}')\n \n \n @app.post(\"/printREQUEST\")\n async def create_file(request: Request):\n try:\n await print_request(request)\n return {\"status\": \"OK\"}\n except Exception as err:\n logging.error(f'could not print REQUEST: {err}')\n return {\"status\": \"ERR\"}\n```\n\n```text\nRequest\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.encoders import jsonable_encoder\nfrom pydantic import BaseModel\nimport simplejson as json\n\nclass SubmitGeneral(BaseModel):\n controllerIPaddress: str\n readerIPaddress: str\n ntpServer: str\n\n@app.post(\"/submitGeneral\")\nasync def submitGeneral(data: SubmitGeneral):\n data = jsonable_encoder(data)\n #data = json.loads(data.json()) # same as above line\n \n print(f\"data = {json.dumps(data)}\")\n\n # you have to access the properties with brackets, not by dot notation\n query = f\"update LocalPLC set ControllerIpAddress = '{data['controllerIPaddress']}', ReaderIPAddress = '{data['readerIPaddress']}'\"\n\n return {\"status\": \"OK\"}\n```\n\n```text\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel, Json, Field\n\n\napp = FastAPI()\n\n\nclass MockEndpoint(BaseModel):\n endpoint: str = Field(description=\"API endpoint to mock\")\n response: Json = Field(description=\"Example response of the endpoint\")\n\n\n@app.get(\"/\")\nasync def root():\n return {\"message\": \"Hello World\"}\n\n\n@app.post(\"/mock\")\nasync def mock_request(mock_endpoint: MockEndpoint):\n return mock_endpoint\n```\n\n```text\n@app.post(\"/dict/\")\nasync def post_dict(data: Dict[str, Any]):\n return data\n```\n\n```text\nfrom fastapi import Request, HTTPException, Depends, Body\n\nclass SearchRequest(BaseModel):\n prompt: str\n chat_history: Optional[List[Any]] = Field(default=[], alias=\"chatHistory\")\n search_type: Optional[str] = Field(default=\"default_type\", alias=\"searchType\")\n search_language: str = Field(default=\"en\")\n source_types: Optional[List[str]] = Field(default=[], alias=\"sourceTypes\")\n\nasync def process_message(self, search_request: SearchRequest = Body(...)) -> StreamingResponse:\n async def event_stream():\n try:\n```\n\n```py\nfrom typing import Any\nfrom fastapi import Request, FastAPI\nfrom pydantic import Json\n\n\n@app.post(\"/test\")\nasync def get_body(payload: Annotated[Any, Body()]):\n return payload\n```\n\n```py\nimport json\nimport pytest\nfrom fastapi.testclient import TestClient\n\n\nclient = TestClient(app)\n\n@pytest.mark.parametrize(\n (\"payload\",\"expected\"),\n [\n pytest.param('{\"key\": 1}', {\"key\": 1}, id=\"simple json\"),\n pytest.param(json.dumps({\"key\": None}), {\"key\": None}, id=\"json with None\"),\n pytest.param(json.dumps([1, 2, 3]), [1, 2, 3], id=\"json list\"),\n pytest.param(json.dumps([{\"a\":1}, {\"b\": 2}, 3]), [{\"a\":1}, {\"b\": 2}, 3], id=\"json list of mixed types\"),\n pytest.param(\"{}\", {}, id=\"empty json\"),\n pytest.param(\"[]\", [], id=\"empty json list\"),\n pytest.param(json.dumps(6), 6, id=\"just a number\"),\n ]\n)\ndef test_get_body(payload, expected):\n response = client.post(\"/test\", data=payload)\n assert response.status_code == 200\n assert response.json() == expected\n```\n\n```text\ntyping.Annotated\n```\n\n```text\nAny\n```\n\n```text\n.validate_json()\n```\n\n========================================\n\nComments:\n- Please have a look at this answer, as well as this answer.\n- In the `edit` history of this answer it seems that `request.body()` has been replaced by `request.json()` only inside the code block :-)\n- I make a request with form-data selected in the body and get this error \"ValueError: [TypeError(\"'coroutine' object is not iterable\"), TypeError('vars() argument must have **dict** attribute')]\"\n- Parsed JSON could be a number of different types, not just a dictionary.\n- I am trying to access the body for error logging. when I try to access the body with request.body() from a logger, I get \"\" instead of the body as a string.\n- Use `await` if you are getting coroutine object. That means that file descriptor is still waiting.\n- Why the public method `json` from the class or module `Request` is a `coroutine`?, I should read the FastAPI docs.\n- I am using this code, without the async clause, but I still get a coroutine. How is it possible?\n- It is so simple. If you are getting coroutine you are not using `await`.\n- @ChristianSicari Please have a look at this answer, if you would like to get the raw `body` or JSON (using `.json()`, which actually returns a `dict` object, as shown here) in an endpoint defined with normal `def` instead of `async def`.\n- That is not right, if it is not a valid JSON, Pydantic would throw an error. In addition to that there is nothing called \"JSON array\" Python parses JSON as Dictionary, so OP 's question is very clear, he wants to get actual JSON which is unparsed one and there is only way to get actual JSON is from `request.body()`.\n- @YagizcanDegirmenci Yes, there is something called **JSON Array** which cant not be parsed into a Python ***dict***, but a Python ***list***\n- Yes, I'm pretty sure OP did not mean JSON Array in the question.\n- OP didn't mention JSON Object too. This answer is meant for those who want to get an *arbitrary JSON( either array or object)* from the request ***not as a string***, as I already mentioned\n- Actually, I want ANYTHING that is a valid JSON. Including numbers, booleans, null and strings. Not only objects and arrays.\n- `dict = Body()` for the win. This simple line has eluded me for far too long.\n- @zelusp I don't know why `request.json()` is recommended and used so often alongside with the regular arg typing stuff. To my mind `Body()` is the most natural way for FastAPI unless you need to deal with a complex body processing or so\n- This is undeniably the correct way to do this and should be the accepted answer.\n- why use `dict`?\n- Sorry, but I doubt this accepts `null`, `true`, `false`, any string, any number, and arrays.\n- @caeus it actually can consume arrays. Thanks for heads up, slightly corrected my answer to reflect that in type hint, but anyway it would work. `null`, `true`, `false`, any string, any number - those alone can't be a valid JSON, so it shouldn't accept them\n- `null` is a valid json, `true` is a valid json `\"Hello world!\"` is a valid json, `12345.67` is a valid json. It's not usual to see them at the root of the whole json, but they're as valid as an object or an array. And the question actually states that\n- @caeus my bad, checked the standards, you're right. However, this approach still fits, corrected again\n- I still wonder; why isn't `Any` just enough? Why the `Any = Body(None)` ?\n- @CutePoison I suppose it's a way for FastAPI to tell the full body from regular query params\n- request.json() weirdly will not work for me, even if the content is definitely JSON. I can even dir request and see the json method in the list but it just calls a memory pointer when i use it.\n- json data can be an array of objects, so `[{\"foo\": \"bar\"}]` would fail here.\n- This does not really answer the question. If you have a different question, you can ask it by clicking Ask Question. To get notified when this question gets new answers, you can this question. Once you have enough reputation, you can also add a bounty to draw more attention to this question. - From Review\n- Using Pydantic's `Json` type does **not** seem to be a proper solution, in this case. It doesn't look like that, by using it, it affects the way the input data are handled. One might as well use `payload: Any = Body()` or simply `payload=Body()`. It is the `Body` type that controls the data handling. They would all have the same result. They would all, for instance, take input data such as `1` or `123` as valid, whereas they are not valid JSON data compared to `{\"num\": 123}`, for example.\n- If `payload: Json = Body()` was used instead (similar to the example demonstrated in Method 3 of this answer - only difference is that `Form` was used there, which is a class that inherits directly from `Body`, regardless), an error would be raised, as the `JSON input should be string, bytes or bytearray`. This is because the `Json` data type is used to pass a raw JSON string (**not** a `dict`/JSON object) that you need to validate into `dict`/JSON object.\n- Thanks for the comments. let me revise my solution.\n- Updated, would love your perspective @Chris\n- Using `RootModel` would still allow one passing a single string or number (wich might be considered a valid JSON, according to the most recent RFC8259 - *\"A JSON text is a serialized value. Note that certain previous specifications of JSON constrained a JSON text to be an object or an array...\"*). However, if you are expecting the user to pass only a valid dictionary (*key-value* pairs) or array of dictionary objects, `RootModel` would not be the solution to constrain the input data.\n- Side note: Please make sure to include only the proper import statements in your example, as well as return the `payload`; using `await request.json()` in your example wouldn't make that sense (especially, if `request: Request` is not defined in your endpoint). Also, if the user passes a single number, returning `payload` would raise an error, and thus, in that case, you might need to cast this into `dict(payload)`, which would return, for instance, `{'root': 123}` (which might not make that sense to the user).","metadata":{"transformedAt":"2026-08-18T18:32:29.084Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":27,"totalLines":320,"estimatedTokens":3149}}12{"id":"stack-64943693","source":"stackoverflow","questionId":64943693,"title":"What are the best practices for structuring a FastAPI project?","tags":["python","fastapi"],"text":"Title: What are the best practices for structuring a FastAPI project?\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nThe problem that I want to solve related the project setup:\n\n- Good names of directories so that their purpose is clear.\nKeeping all project files (including virtualenv) in one place, so I\ncan easily copy, move, archive, remove the whole project, or estimate disk\nspace usage.\nCreating multiple copies of some selected file sets such as entire\napplication, repository, or virtualenv, while keeping a single copy of\nother files that I don't want to clone.\nDeploying the right set of files to the server simply by resyncing\nselected one dir.\n\n- handling both frontend and backend nicely.\n\n========================================\n\nTop Answer:\nThe official documentation suggests the below style like Flask blueprints.\n\n```\n.\n├── app # \"app\" is a Python package\n│ ├── __init__.py # this file makes \"app\" a \"Python package\"\n│ ├── main.py # \"main\" module, e.g. import app.main\n│ ├── dependencies.py # \"dependencies\" module, e.g. import app.dependencies\n│ └── routers # \"routers\" is a \"Python subpackage\"\n│ │ ├── __init__.py # makes \"routers\" a \"Python subpackage\"\n│ │ ├── items.py # \"items\" submodule, e.g. import app.routers.items\n│ │ └── users.py # \"users\" submodule, e.g. import app.routers.users\n│ └── internal # \"internal\" is a \"Python subpackage\"\n│ ├── __init__.py # makes \"internal\" a \"Python subpackage\"\n│ └── admin.py # \"admin\" submodule, e.g. import app.internal.admin\n```\n\nTaken from the official link, read more at https://fastapi.tiangolo.com/tutorial/bigger-applications/\n\n========================================\n\nCode:\n```py\nyour_project\n├── __init__.py\n├── main.py\n├── core\n│ ├── models\n│ │ ├── database.py\n│ │ └── __init__.py\n│ ├── schemas\n│ │ ├── __init__.py\n│ │ └── schema.py\n│ └── settings.py\n├── tests\n│ ├── __init__.py\n│ └── v1\n│ ├── __init__.py\n│ └── test_v1.py\n└── v1\n ├── api.py\n ├── endpoints\n │ ├── endpoint.py\n │ └── __init__.py\n └── __init__.py\n```\n\n```py\nfrom my_project.v1.endpoints.endpoint import something\n```\n\n```text\n__init__\n```\n\n```text\n__init__\n```\n\n```text\n.\n├── app # \"app\" is a Python package\n│ ├── __init__.py # this file makes \"app\" a \"Python package\"\n│ ├── main.py # \"main\" module, e.g. import app.main\n│ ├── dependencies.py # \"dependencies\" module, e.g. import app.dependencies\n│ └── routers # \"routers\" is a \"Python subpackage\"\n│ │ ├── __init__.py # makes \"routers\" a \"Python subpackage\"\n│ │ ├── items.py # \"items\" submodule, e.g. import app.routers.items\n│ │ └── users.py # \"users\" submodule, e.g. import app.routers.users\n│ └── internal # \"internal\" is a \"Python subpackage\"\n│ ├── __init__.py # makes \"internal\" a \"Python subpackage\"\n│ └── admin.py # \"admin\" submodule, e.g. import app.internal.admin\n```\n\n========================================\n\nComments:\n- Check this github.com/ycd/manage-fastapi\n- 66 upvotes and someone closed this question, wow\n- This is a GREAT question. What more focused do you need it to be?!\n- question : how do you version core ? Let's say you need to change your pydantic model from v1 to v2\n- where i add migrations folder when using alembic?\n- Why is it good to have the tests in the backend folder? AFAIK separation of tests and business logic is preferable?","metadata":{"transformedAt":"2026-08-18T18:32:29.084Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":5,"totalLines":105,"estimatedTokens":860}}13{"id":"stack-63793662","source":"stackoverflow","questionId":63793662,"title":"How to give a Pydantic list field a default value?","tags":["python","fastapi","python-dataclasses","pydantic"],"text":"Title: How to give a Pydantic list field a default value?\nTags: python, fastapi, python-dataclasses, pydantic\nSource: Stack Overflow\n\nQuestion:\nI want to create a Pydantic model in which there is a list field, which left uninitialized has a default value of an empty list. Is there an idiomatic way to do this?\n\nFor Python's built-in dataclass objects you can use `field(default_factory=list)`, however in my own experiments this seems to prevent my Pydantic models from being pickled. A naive implementation might be, something like this:\n\n```\nfrom pydantic import BaseModel\n\nclass Foo(BaseModel):\n defaulted_list_field: Sequence[str] = [] # Bad!\n```\n\nBut we all know not to use a mutable value like the empty-list literal as a default.\n\nSo what's the correct way to give a Pydantic list-field a default value?\n\n========================================\n\nTop Answer:\nWhile reviewing my colleague's merge request I saw the usage of a mutable object as a default argument and pointed that out. To my surprise, it works as if have done a deepcopy of the object. I found an example in the project's readme, but without any clarification. And suddenly realized that developers constantly ignore this question for a long time (see links at the bottom).\n\nIndeed, you can write something like this. And expect *correct* behavior:\n\n```\nfrom pydantic import BaseModel\n\nclass Foo(BaseModel):\n defaulted_list_field: List[str] = []\n```\n\nBut what happens underhood?\nWe need to go deeper...\n\nAfter a quick search through the source code I found this:\n\n```\nclass ModelField(Representation):\n ...\n def get_default(self) -> Any:\n return smart_deepcopy(self.default) if self.default_factory is None else self.default_factory()\n```\n\nWhile `smart_deepcopy` function is:\n\n```\ndef smart_deepcopy(obj: Obj) -> Obj:\n \"\"\"\n Return type as is for immutable built-in types\n Use obj.copy() for built-in empty collections\n Use copy.deepcopy() for non-empty collections and unknown objects\n \"\"\"\n\n obj_type = obj.__class__\n if obj_type in IMMUTABLE_NON_COLLECTIONS_TYPES:\n return obj # fastest case: obj is immutable and not collection therefore will not be copied anyway\n try:\n if not obj and obj_type in BUILTIN_COLLECTIONS:\n # faster way for empty collections, no need to copy its members\n return obj if obj_type is tuple else obj.copy() # type: ignore # tuple doesn't have copy method\n except (TypeError, ValueError, RuntimeError):\n # do we really dare to catch ALL errors? Seems a bit risky\n pass\n\n return deepcopy(obj) # slowest way when we actually might need a deepcopy\n```\n\nAlso, as mentioned in the comments you can not use mutable defaults in databases attributes declaration directly (use default_factory instead). So this example **is not valid**:\n\n```\nfrom pydantic.dataclasses import dataclass\n\n@dataclass\nclass Foo:\n bar: list = []\n```\n\nAnd gives:\n\n```\nValueError: mutable default for field bar is not allowed: use default_factory\n```\n\nLinks to open discussions (no answers so far):\n\n- Why isn't mutable default value (field = List[int] = []) a documented feature?\n\n- How does pydantic.BaseModel handle mutable default args?\n\n========================================\n\nCode:\n```text\nfrom pydantic import BaseModel\n\nclass Foo(BaseModel):\n defaulted_list_field: Sequence[str] = [] # Bad!\n```\n\n```text\nfield(default_factory=list)\n```\n\n```text\nclass Foo(BaseModel):\n defaulted_list_field: List[str] = []\n\nf1, f2 = Foo(), Foo()\nf1.defaulted_list_field.append(\"hey!\")\n\nprint(f1) # defaulted_list_field=['hey!']\nprint(f2) # defaulted_list_field=[]\n```\n\n```text\nfrom typing import List\nfrom pydantic import BaseModel, Field\nfrom uuid import UUID, uuid4\n\nclass Foo(BaseModel):\n defaulted_list_field: List[str] = Field(default_factory=list)\n uid: UUID = Field(default_factory=uuid4)\n```\n\n```text\ndefault_factory\n```\n\n```text\nfrom pydantic import BaseModel\n\nclass Foo(BaseModel):\n defaulted_list_field: List[str] = []\n```\n\n```text\nclass ModelField(Representation):\n ...\n def get_default(self) -> Any:\n return smart_deepcopy(self.default) if self.default_factory is None else self.default_factory()\n```\n\n```text\ndef smart_deepcopy(obj: Obj) -> Obj:\n \"\"\"\n Return type as is for immutable built-in types\n Use obj.copy() for built-in empty collections\n Use copy.deepcopy() for non-empty collections and unknown objects\n \"\"\"\n\n obj_type = obj.__class__\n if obj_type in IMMUTABLE_NON_COLLECTIONS_TYPES:\n return obj # fastest case: obj is immutable and not collection therefore will not be copied anyway\n try:\n if not obj and obj_type in BUILTIN_COLLECTIONS:\n # faster way for empty collections, no need to copy its members\n return obj if obj_type is tuple else obj.copy() # type: ignore # tuple doesn't have copy method\n except (TypeError, ValueError, RuntimeError):\n # do we really dare to catch ALL errors? Seems a bit risky\n pass\n\n return deepcopy(obj) # slowest way when we actually might need a deepcopy\n```\n\n```text\nfrom pydantic.dataclasses import dataclass\n\n@dataclass\nclass Foo:\n bar: list = []\n```\n\n```text\nValueError: mutable default <class 'list'> for field bar is not allowed: use default_factory\n```\n\n```text\nsmart_deepcopy\n```\n\n========================================\n\nComments:\n- docs.pydantic.dev/latest/concepts/fields/…\n- \"It will be handled correctly (deep copy) and each model instance will have its own empty list.\" This doesn't seem to be called out in the docs (that I can find) but it really shows off how well-designed `pydantic` actually is.\n- Not sure if that chaged or because I'm using pydantic's @dataclass decorator, but I get `ValueError: mutable default for field defaulted_list_field is not allowed: use default_factory`\n- `@dataclass` does not allow mutable default fields like standard dataclasses.\n- There is an example with mutable default in the pydantic docs here: pydantic-docs.helpmanual.io/usage/validators/…. It uses `List[int] = []`. It does not mention explicitly that it handles the mutable default arg though.\n- @kevlarr It appears to be called out in the documentation now: docs.pydantic.dev/latest/concepts/models/…\n- Documentation link update : docs.pydantic.dev/latest/concepts/fields/…","metadata":{"transformedAt":"2026-08-18T18:32:29.084Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":11,"totalLines":193,"estimatedTokens":1562}}14{"id":"stack-62856818","source":"stackoverflow","questionId":62856818,"title":"How can I run the FastAPI server using Pycharm?","tags":["python","pycharm","fastapi"],"text":"Title: How can I run the FastAPI server using Pycharm?\nTags: python, pycharm, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have a simple API function as below,\n\n```\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/\")\nasync def read_root():\n return {\"Hello\": \"World\"}\n```\n\nI am starting the server using **`uvicorn`** command as,\n\n```\nuvicorn main:app\n```\n\nSince we are not calling any python file *directly*, it is not possible to call `uvicorn` command from Pycharm.\n\nSo, **How can I run the fast-api server using Pycharm?**\n\n========================================\n\nTop Answer:\nYou can do it without adding code to main.py\n\n- In `target to run` instead of `Script path` choose `Module name`\n\n- In `Module name` type `uvicorn`\n\n- In parameters `app.main:app --reload --port 5000`\n\nhttps://i.sstatic.net/mMMIb.png\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n\n@app.get(\"/\")\nasync def read_root():\n return {\"Hello\": \"World\"}\n```\n\n```text\nuvicorn main:app\n```\n\n```text\nuvicorn\n```\n\n```text\nuvicorn\n```\n\n```text\n# main.py\n\nimport uvicorn\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n\n@app.get(\"/\")\nasync def read_root():\n return {\"Hello\": \"World\"}\n\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n```\n\n```text\npython main.py\n```\n\n```text\n# main.py\n\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n\n@app.get(\"/\")\nasync def read_root():\n return {\"Hello\": \"World\"}\n```\n\n```text\nuvicorn main:app --reload\n```\n\n```text\nuvicorn.run(...)\n```\n\n```text\nuvicorn\n```\n\n```text\nuvicorn\n```\n\n```text\nuvicorn\n```\n\n```text\nwhich uvicorn\n```\n\n```text\nuvicorn\n```\n\n```text\nfrom fastapi import FastAPI\nimport uvicorn\n\napp = FastAPI()\n\n\n@app.get(\"/\")\nasync def read_root():\n return {\"Hello\": \"World\"}\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", port=5000, log_level=\"info\")\n```\n\n```text\ntarget to run\n```\n\n```text\nScript path\n```\n\n```text\nModule name\n```\n\n```text\nModule name\n```\n\n```text\nuvicorn\n```\n\n```text\napp.main:app --reload --port 5000\n```\n\n```text\n# fastapi_demo.py\n\nimport uvicorn\nfrom fastapi import FastAPI, Response\n\napp = FastAPI()\n\n@app.route('/', methods=['POST'])\ndef demo(request):\n try:\n print(request)\n except Exception as e:\n print(e)\n return Response(content='OK')\n\n\nif __name__ == '__main__':\n uvicorn.run(app='fastapi_demo:app')\n```\n\n========================================\n\nComments:\n- There is an easy workaround by `pip install uvicorn` and then running it as a python module: `python -m uvicorn main:app`. Works like a... (Py)Charm.\n- This seems more like a dev setting/tweak, is it acceptable to push this code out to prod environment?\n- @Neeraj, there is no difference.\n- The problem is that you can't deploy to production this way because you can't really pass other parameters to uvicorn...say \"workers\", etc. At least I can't get it to work.\n- Also, this is *not for production*. Suppose if you want to update the number of workers, you need to update your code, which is of course not a good idea. That's why unicorn supports the commandline setup.\n- BTW, the `uvicorn.run(...)` supports all the args supported by the commandline\n- You can pass in args via pycharm and dynamically configure uvicorn all args supported via config = Config(app, **kwargs)\n- Could you explain why that matter here? Sorry that I didn't get your point @TimothyMugayi\n- I was looking for this solution for the past 2 (two) years now :)\n- Is running on `0.0.0.0` safe? I'm a novice but someone might have told me at some point, \"don't do that\". I changed it to `localhost` and it works.\n- Awesome, couln't find an answer anywhere else on how to debug AND reload at the same time\n- This is the best answer in my opinion as it is the only one that lets you use `--reload`\n- Ensure to check working directory if you get 'app' module not found.\n- Server log output is better using this method, it should be the best answer.\n- this results in the fastapi_demo to be run twice. If you have a (for example) global variable it will be initialized\n- Thanks, @Coco to identify my mistake. It was running twice just because of misconfiguration. Actually, I have added `reload=True` and it leads to double initialization. To avaid that you must add `reload_dirs=['/app_dir_name',]`. But, this approach is not wrong to run app by PyCharm. Check this FYI\n- you would need to run `uvicorn.run(app)` instead, that'd not start the app twice\n- Can you add the image itself to answer and not just a link of it?","metadata":{"transformedAt":"2026-08-18T18:32:29.084Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":22,"totalLines":210,"estimatedTokens":1134}}15{"id":"stack-63726203","source":"stackoverflow","questionId":63726203,"title":"Is it possible to use FastAPI with Django?","tags":["django","django-rest-framework","fastapi"],"text":"Title: Is it possible to use FastAPI with Django?\nTags: django, django-rest-framework, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm a Django developer and recently stumbled onto the FastAPI framework.\n\nThen I decided to give it a shot. But usually when you talk about building RESTful APIs with Django you usually use the Django Rest Framework (DRF).\n\nIs anybody aware if it is possible to substitute DRF by FastAPI using Django perks, like its ORM, and still have access to all of FastAPI's `async` features?\n\nUp until now I only found one article on this. But in the process of integration the author lost most of the features of FastAPI.\nYou can find it here.\n\nIn the FastAPI docs, they do mention that it is possible to redirect certain request to a WSGI application here.\n\n========================================\n\nTop Answer:\n### Latest Update\n\nWhile it is possible in the approach listed below, I genuinely think that we should **avoid** coupling different frameworks in such a monolith. Doing so could lead to unexpected bugs and make it harder to scale.\n\nInstead, we could build 1 backend service in FastAPI, 1 Django Admin service for example, and then use NGINX to route traffic to these backend services. Using NGINX as a reverse proxy to route traffic to different backend services in production is common anyway.\n\n### Integration Of FastAPI With Django (WSGI)\n\nhttps://github.com/jordaneremieff/django-fastapi-example.git\n\nAfter hours of searching finally I found a great implementation in the link above. It worked seamlessly for me!\n\n### Testing\n\nIn order to make this simple to test, below are some few adjustments I made to the above reference:\n\n**api/models.py**\n\n```\nclass Item(models.Model):\n title = models.CharField(max_length=50)\n description = models.TextField()\n # owner = models.ForeignKey(\n # settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name=\"items\"\n # )\n```\n\n**api/schemas.py**\n\n```\nclass Item(ItemBase):\n # id: int\n # owner_id: int\n\n class Config:\n orm_mode = True\n```\n\n**POST**\n\n```\ncurl -d \"{\\\"title\\\":\\\"le titre\\\", \\\"description\\\":\\\"la description\\\"}\" -H \"Content-Type: application/json\" -X POST http://127.0.0.1:8000/api/items\n```\n\n**GET**\n\n```\ncurl http://127.0.0.1:8000/api/items\n```\n\n========================================\n\nCode:\n```text\nasync\n```\n\n```text\nimport os\nfrom importlib.util import find_spec\n\nfrom configurations.wsgi import get_wsgi_application\nfrom fastapi import FastAPI\nfrom fastapi.middleware.wsgi import WSGIMiddleware\nfrom fastapi.staticfiles import StaticFiles\n\nfrom api import router\n\nos.environ.setdefault(\"DJANGO_SETTINGS_MODULE\", \"myapp.settings\")\nos.environ.setdefault(\"DJANGO_CONFIGURATIN\", \"Localdev\")\n\napplication = get_wsgi_application()\n\napp = FastAPI()\napp.mount(\"/admin\", WSGIMiddleware(application))\napp.mount(\"/static\",\n StaticFiles(\n directory=os.path.normpath(\n os.path.join(find_spec(\"django.contrib.admin\").origin, \"..\", \"static\")\n )\n ),\n name=\"static\",\n)\n```\n\n```text\nfrom fastapi import FastAPI\nfrom fastapi.middleware.wsgi import WSGIMiddleware\nfrom flask import Flask, escape, request\n\nflask_app = Flask(__name__)\n\n\n@flask_app.route(\"/\")\ndef flask_main():\n name = request.args.get(\"name\", \"World\")\n return f\"Hello, {escape(name)} from Flask!\"\n\n\napp = FastAPI()\n\n\n@app.get(\"/v2\")\ndef read_main():\n return {\"message\": \"Hello World\"}\n\n\napp.mount(\"/v1\", WSGIMiddleware(flask_app))\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.middleware.wsgi import WSGIMiddleware\nfrom django.core.wsgi import get_wsgi_application\nimport os\nfrom importlib.util import find_spec\nfrom fastapi.staticfiles import StaticFiles\nfrom django.conf import settings\n\n\n# Export Django settings env variable\nos.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings')\n\n# Get Django WSGI app\ndjango_app = get_wsgi_application()\n\n# Import a model\n# And always import your models after you export settings\n# and you get Django WSGI app\nfrom accounts.models import Account\n\n# Create FasatAPI instance\napp = FastAPI()\n\n# Serve Django static files\napp.mount('/static',\n StaticFiles(\n directory=os.path.normpath(\n os.path.join(find_spec('django.contrib.admin').origin, '..', 'static')\n )\n ),\n name='static',\n)\n\n# Define a FastAPI route\n@app.get('/fastapi-test')\ndef read_main():\n return {\n 'total_accounts': Account.objects.count(),\n 'is_debug': settings.DEBUG \n }\n\n# Mount Django app\napp.mount('/django-test', WSGIMiddleware(django_app))\n```\n\n```sh\n.\n├── accounts\n│ ├── __init__.py\n│ ├── admin.py\n│ ├── apps.py\n│ ├── migrations\n│ │ ├── 0001_initial.py\n│ │ ├── __init__.py\n│ ├── models.py\n│ ├── tests.py\n│ └── views.py\n├── app.py\n├── db.sqlite3\n├── project\n│ ├── __init__.py\n│ ├── asgi.py\n│ ├── settings.py\n│ ├── urls.py\n│ └── wsgi.py\n└── manage.py\n```\n\n```sh\n(myvenv) ➜ project uvicorn --host 0.0.0.0 --port 8000 app:app --reload\nINFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)\nINFO: Started reloader process [48366] using statreload\nINFO: Started server process [48368]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\n```\n\n```text\napp.py\n```\n\n```text\n/django-test\n```\n\n```text\n/fastapi-test\n```\n\n```py\nclass Item(models.Model):\n title = models.CharField(max_length=50)\n description = models.TextField()\n # owner = models.ForeignKey(\n # settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name=\"items\"\n # )\n```\n\n```py\nclass Item(ItemBase):\n # id: int\n # owner_id: int\n\n class Config:\n orm_mode = True\n```\n\n```text\ncurl -d \"{\\\"title\\\":\\\"le titre\\\", \\\"description\\\":\\\"la description\\\"}\" -H \"Content-Type: application/json\" -X POST http://127.0.0.1:8000/api/items\n```\n\n```text\ncurl http://127.0.0.1:8000/api/items\n```\n\n```text\npip install django-ninja\n```\n\n```text\nfrom ninja import NinjaAPI\napi = NinjaAPI()\n\n@api.get(\"/add\")\ndef add(request, a: int, b: int):\n return {\"result\": a + b}\n```\n\n```text\nfrom .api import api\nurlpatterns = [\n path(\"admin/\", admin.site.urls),\n path(\"api/\", api.urls), # <---------- !]\n```\n\n```text\nInstallation:\n```\n\n```text\nUsage\n```\n\n```text\nIn your django project next to urls.py create new api.py file:\n```\n\n```text\nNow go to urls.py and add the following:\n```\n\n========================================\n\nComments:\n- What feature of FastAPI would you like to have in Django (or in DRF)?\n- django-ninja.rest-framework.com is an alternate for DRF, which is built on top of FastAPI.\n- @Sumithran According to the [github.com/vitalik/django-ninja/blob/master/… Django ninja does not require FastAPI and also their documentation states `This project was heavily inspired by FastAPI`. So it is a parallel development, not built on top of FastAPI\n- yes, an example: stavros.io/posts/fastapi-with-django\n- I don't understand who are the ones deciding to close a question like this. Sometimes the despotic behaviour of the \"moderators\" on SO is indignant. This is a perfectly valid and useful question.\n- The only thing preventing me to use FastAPI is that I didn't want to use another ORM and learn again everything. Django ninja is exactly what I needed for simple APIs. Best of both worlds! thanks guys! Hope the projets gains some traction.\n- Voted the question to reopen.\n- You can apply domain-driven design to your django without django rest framework like its done in fastapi github.com/qu3vipon/django-ddd\n- Appreciate bro! I'll try it out! But it seems neat. So, this line `app.mount(\"/admin\", WSGIMiddleware(application))` would reference to the /admin on the urls.py of my django application?\n- @LeonardoGuerreiro Yup. Also this repo could be useful for you\n- when I try to acess django's admin page, it is not serving the static files well. Do you know what might be causing that?\n- The initial page of the admin is ok, but when I access the inner pages, for example \"Users\", it is not able to load the static files: `INFO: 127.0.0.1:48012 - \"GET /static/admin/img/tooltag-add.svg HTTP/1.1\" 404 Not Found INFO: 127.0.0.1:48004 - \"GET /static/admin/img/sorting-icons.svg HTTP/1.1\" 404 Not Found`\n- btw, do you know if there is anything like django's admin page for FastAPI? It's not required that I use the django's ORM and admin page, I just don't wanna do it myself.\n- Yup, i really like Dashboard encode behind this project(Creators of DRF-Starlette-Uvicorn-HTTPx etc)\n- But if you are okay for a tortoise, fastapi-admin is a good option tho.\n- `STATIC_URL = \"/static/\" # Media files MEDIA_URL = config(\"MEDIA_URL\", default=\"/media/\") MEDIA_ROOT = os.path.join(BASE_DIR, \"media\") # Static Files STATIC_ROOT = os.path.join(BASE_DIR, \"static\")`\n- I managed to fix it. Turns out that I only needed to add `app.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")` to my `asgi.py` file inside the function where I call de FastAPI instance and refer it to my STATIC_ROOT on the settings.py. checkit out here\n- what is that ` \"..\"` thing do in the line `os.path.join(find_spec(\"django.contrib.admin\").origin, \"..\", \"static\")`??\n- Please use google for these such things instead of necrobumping, see: What is double dot(..) and single dot(.) in Linux?\n- help please I got `ModuleNotFoundError: No module named 'myapp.settings'` with `os.environ.setdefault(\"DJANGO_SETTINGS_MODULE\", \"mysite.settings\")` when I run `uvicorn myapp.myapp.wsgi:app --port 8001 --host localhost`\n- I don't know why you are necrobumping, the problem you are facing is unrelated to the question and violates SO rules @alial-karaawi.\n- @YagizDegirmenci I used the cope of the answer and I copied it and paste it and modified it to suits my project then I got the issue so it is reallited\n- i have concerns about connections created by django orm because normally django manage the db connection in request-response cycle which is not works well with starlette requests, i think the connections created by fastapi endpoints not gonna be closed as excepted .\n- It should be possible to extend this further, by interrogating django to get all the urls to mount.\n- When providing an answer it's great to add an external link for reference, but it shouldn't be the whole answer. Extract relevant information and write it out/quote it here directly.\n- ok thanks for highlighting this mate.\n- That's a bad idea because now you're coupling two different ORMs via their shared database.\n- The question asked for \"possible to substitute DRF by FastAPI\" while **still have access to all of FastAPI's async features**. This is what my answer actually answers. The author wants to use FastAPI features in django. This is what Ninja provides.\n- It's a review suggestion, take it or leave it, it's up to you.\n- Dude, using FastAPI will bring in one of the greatest joys to your life as you will avoid using the nastiness of DRF, if you can even call that that.\n- I wouldnt call DRF nasty. FastAPI is a delight, but DRF is an absolute powerhouse of a framework. It just takes a bit of reading and a bit of uncomfortable boilerplate to get working. That said, although its a little bit undercooked, it really needs another good year of dev to be what I'd consider stable, Ninja does bring a tonne of ergonomics (and OpenAPI stuff) to the table.\n- You echoed my mind !\n- This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker. - From Review\n- django_ninja is close to what the OP is looking for. Please do not -ve vote this answer.","metadata":{"transformedAt":"2026-08-18T18:32:29.084Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":20,"totalLines":318,"estimatedTokens":2917}}16{"id":"stack-64497615","source":"stackoverflow","questionId":64497615,"title":"How to add a custom decorator to a FastAPI route?","tags":["python","python-decorators","fastapi","pydantic"],"text":"Title: How to add a custom decorator to a FastAPI route?\nTags: python, python-decorators, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI want to add an `auth_required` decorator to my endpoints.\n(*Please consider that this question is about decorators, not middleware*)\n\nSo a simple decorator looks like this:\n\n```\ndef auth_required(func):\n def wrapper(*args, **kwargs):\n if user_ctx.get() is None:\n raise HTTPException(...)\n return func(*args, **kwargs)\n return wrapper\n```\n\nSo there are 2 usages:\n\n```\n@auth_required\n@router.post(...)\n```\n\nor\n\n```\n@router.post(...)\n@auth_required\n```\n\nThe first way doesn't work because `router.post` creates a router that saved into `self.routes` of APIRouter object. The second way doesn't work because it fails to verify pydantic object. For any request model, it says `missing args, missing kwargs`.\n\nSo my question is - how can I add any decorators to FastAPI endpoints? Should I get into `router.routes` and modify the existing endpoint? Or use some `functools.wraps` like functions?\n\n========================================\n\nTop Answer:\nSimply use the dependencies inside of the path operation decorator:\n\n```\nfrom fastapi import Depends, FastAPI, Header, HTTPException\n\napp = FastAPI()\n\nasync def verify_token(x_token: str = Header()):\n if x_token != \"fake-super-secret-token\":\n raise HTTPException(status_code=400, detail=\"X-Token header invalid\")\n\nasync def verify_key(x_key: str = Header()):\n if x_key != \"fake-super-secret-key\":\n raise HTTPException(status_code=400, detail=\"X-Key header invalid\")\n return x_key\n\n@app.get(\"/items/\", dependencies=[Depends(verify_token), Depends(verify_key)])\nasync def read_items():\n return [{\"item\": \"Foo\"}, {\"item\": \"Bar\"}]\n```\n\n========================================\n\nCode:\n```text\ndef auth_required(func):\n def wrapper(*args, **kwargs):\n if user_ctx.get() is None:\n raise HTTPException(...)\n return func(*args, **kwargs)\n return wrapper\n```\n\n```text\n@auth_required\n@router.post(...)\n```\n\n```text\n@router.post(...)\n@auth_required\n```\n\n```text\nauth_required\n```\n\n```text\nrouter.post\n```\n\n```text\nself.routes\n```\n\n```text\nmissing args, missing kwargs\n```\n\n```text\nrouter.routes\n```\n\n```text\nfunctools.wraps\n```\n\n```text\nfrom functools import wraps\n\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\n\n\nclass SampleModel(BaseModel):\n name: str\n age: int\n\n\napp = FastAPI()\n\n\ndef auth_required(func):\n @wraps(func)\n async def wrapper(*args, **kwargs):\n return await func(*args, **kwargs)\n\n return wrapper\n\n\n@app.post(\"/\")\n@auth_required # Custom decorator\nasync def root(payload: SampleModel):\n return {\"message\": \"Hello World\", \"payload\": payload}\n```\n\n```text\nfrom fastapi import Request\n\n\n@app.post(\"/\")\n@auth_required # Custom decorator\nasync def root(request: Request, payload: SampleModel):\n return {\"message\": \"Hello World\", \"payload\": payload}\n```\n\n```text\n@functools.wraps(...)\n```\n\n```text\nrequest\n```\n\n```text\n@app.middleware(...)\n```\n\n```py\nfrom fastapi import FastAPI, Request\nfrom pydantic import BaseModel\n\n\nclass SampleModel(BaseModel):\n name: str\n age: int\n\n\napp = FastAPI()\n\ndef do_something_with_request_object(request: Request):\n print(request)\n\ndef auth_required(handler):\n async def wrapper(request: Request, *args, **kwargs):\n do_something_with_request_object(request)\n return await handler(*args, **kwargs)\n\n # Fix signature of wrapper\n import inspect\n wrapper.__signature__ = inspect.Signature(\n parameters = [\n # Use all parameters from handler\n *inspect.signature(handler).parameters.values(),\n\n # Skip *args and **kwargs from wrapper parameters:\n *filter(\n lambda p: p.kind not in (inspect.Parameter.VAR_POSITIONAL, inspect.Parameter.VAR_KEYWORD),\n inspect.signature(wrapper).parameters.values()\n )\n ],\n return_annotation = inspect.signature(handler).return_annotation,\n )\n\n return wrapper\n\n\n@app.post(\"/\")\n@auth_required # Custom decorator\nasync def root(payload: SampleModel):\n return {\"message\": f\"Hello {payload.name}, {payload.age} years old!\"}\n```\n\n```py\nfrom fastapi import Depends, FastAPI, Header, HTTPException\n\napp = FastAPI()\n\n\nasync def verify_token(x_token: str = Header()):\n if x_token != \"fake-super-secret-token\":\n raise HTTPException(status_code=400, detail=\"X-Token header invalid\")\n\n\nasync def verify_key(x_key: str = Header()):\n if x_key != \"fake-super-secret-key\":\n raise HTTPException(status_code=400, detail=\"X-Key header invalid\")\n return x_key\n\n\n@app.get(\"/items/\", dependencies=[Depends(verify_token), Depends(verify_key)])\nasync def read_items():\n return [{\"item\": \"Foo\"}, {\"item\": \"Bar\"}]\n```\n\n```text\ndef render_template(template):\n \"\"\"decorator to render a template with a context\"\"\"\n def decorator(func):\n @wraps(func)\n def wrapper(*args, **kwargs):\n\n # access request object\n request = kwargs.get('request')\n\n context = func(*args, **kwargs)\n if context is None:\n context = {}\n return templates.TemplateResponse(template, {**context, 'request': request})\n return wrapper\n return decorator\n```\n\n```text\nRequest\n```\n\n```text\nkwargs.get('request')\n```\n\n```text\nRequest\n```\n\n```text\nRuntimeError: cannot reuse already awaited coroutine\n```\n\n```text\ndef auth_required(func):\n @wraps(func)\n async def wrapper(*args, **kwargs):\n return func(*args, **kwargs) #DO NOT WAIT\n return wrapper\n\n@app.post(\"/\")\n@auth_required # Custom decorator\ndef root(payload: SampleModel): #NOT ASYNC\n return {\"message\": \"Hello World\", \"payload\": payload}\n```\n\n```text\nnonlocal\n```\n\n```text\nasync\n```\n\n```py\noauth2_scheme = OAuth2PasswordBearer(tokenUrl=\"token\")\n\ndef authorize(scope: str):\n @depends\n def decorator(token: str = Depends(oauth2_scheme)):\n jwt = jwt_decode(token)\n if scope in not jwt.scopes:\n raise HTTPException(status_code=403, detail=\"Unauthorized\")\n\n return decorator\n\n\n@app.put(\"/users/{user_id}\")\n@authorize(\"users:write\")\ndef update_user(*, user_id: int, user_update: UserUpdate):\n ...\n```\n\n```text\n@depends()\n```\n\n========================================\n\nComments:\n- Is there a reason you need it to be a decorator? Coming from Flask to FastAPI, I sometimes think I need a decorator, but a custom APIRoute class for endpoints that need auth or a Depends(User) injection can also solve the problem.\n- I want to add that decorator to some endpoints, not every. So custom APIRoute class (Im actually using it) doesnt help. And I have an issue with middleware - it works in another thread, so I can't set up global context variable from another thread. I saw some solutions to it, but now i really want to know is decorators possible.\n- The recommended style with FastAPI seems to be to use Dependencies. You add something like `user: User = Depends(auth_function)` to the path or function. That gets called before your endpoint function, similar to how a decorator wraps it. It should also have access to the req-resp context.\n- I know how to use depends. It has access to context, but since it is working in another thread, im getting empty context in main thread.\n- \"Depends\" also can't do any \"around\" actions (it can't do stuff after the route method body has completed.\n- can you please elaborate on the `@app.middleware(...)` you mean that can work as decorators also? any example or tutorial of this?\n- This works for post requests but not for get requests. Any idea why?\n- `@auth_required` is independent of the request method.\n- @AnkitJain Please make sure to declare the endpoint functions with `async def`. Above `@auth_required` decorator will only work with functions declared with `async def`. If you don't use `async`/`await` in endpoint functions, just drop it from `def wrapper(*args, **kwargs)` definition.\n- @FahadMunir Thanks a lot! This worked. I have added async in endpoint functions. However, this was not an issue with post requests.\n- @FahadMunir Hi, I want to ask question, why I got error when I remove `async` of `wrapper`? But after adding `async` everything will work. How it work?\n- \"what's wrong with the FastAPI middleware\" Two things about Middlewares: they apply to all routes so you end up having to write a bunch of awkward centralized conditionals. Also, they don't have access to the deserialized object(s) passed to the controller method. All they have is the raw request.\n- Tried, but got `TypeError: wrapper() missing 1 required positional argument: 'request'`\n- @JPG. I have updated the code after a lot of investigation and testing. However, I have tested with my own code; I haven't tested the code above.\n- gist.github.com/md2perpe/ee146e547a0bd910ea9683a2eea47c59\n- same error `TypeError: wrapper() missing 1 required positional argument: 'request'`\n- @gocreating. Did you try my gist?\n- @md2perpe Sure, but my handler takes both positional and keyword args: `def create_user(user: schemas.UserCreate, session: Session = Depends(get_session)):` so I get `ValueError: non-default argument follows default argument`\n- I have answered myself on fastapi's issue: github.com/tiangolo/fastapi/issues/2662\n- @md2perpe: error regarding positional arguments occurs when decorator is applied to function with default values. Some additional logic are needed to provide list of parameters in order of positional parameter `(a, b)`, parameters with default `(c=1, d=2)`, keyword-only parameter i.e `(*args)`, etc...\n- How would you make the @auth_requried add a real fastapi Depends() to the decorated function? That way one of the fastapi security schemes could be used? Not to mention being to using dependency overrides in tests. fastapi.tiangolo.com/tutorial/security/first-steps/… fastapi.tiangolo.com/reference/security\n- This is not a custom decorator though.","metadata":{"transformedAt":"2026-08-18T18:32:29.084Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":26,"totalLines":328,"estimatedTokens":2489}}17{"id":"stack-67599119","source":"stackoverflow","questionId":67599119,"title":"FastAPI asynchronous background tasks blocks other requests?","tags":["python","asynchronous","async-await","python-asyncio","fastapi"],"text":"Title: FastAPI asynchronous background tasks blocks other requests?\nTags: python, asynchronous, async-await, python-asyncio, fastapi\nSource: Stack Overflow\n\nQuestion:\nI want to run a simple background task in FastAPI, which involves some computation before dumping it into the database. However, the computation would block it from receiving any more requests.\n\n```\nfrom fastapi import BackgroundTasks, FastAPI\n\napp = FastAPI()\ndb = Database()\n\nasync def task(data):\n otherdata = await db.fetch(\"some sql\")\n newdata = somelongcomputation(data,otherdata) # this blocks other requests\n await db.execute(\"some sql\",newdata)\n \n\n@app.post(\"/profile\")\nasync def profile(data: Data, background_tasks: BackgroundTasks):\n background_tasks.add_task(task, data)\n return {}\n```\n\nWhat is the best way to solve this issue?\n\n========================================\n\nTop Answer:\nRead this issue.\n\nAlso in the example below, `my_model.function_b` could be any blocking function or process.\n\nTL;DR\n\n```\nfrom starlette.concurrency import run_in_threadpool\n\n@app.get(\"/long_answer\")\nasync def long_answer():\n rst = await run_in_threadpool(my_model.function_b, arg_1, arg_2)\n return rst\n```\n\n========================================\n\nCode:\n```py\nfrom fastapi import BackgroundTasks, FastAPI\n\napp = FastAPI()\ndb = Database()\n\nasync def task(data):\n otherdata = await db.fetch(\"some sql\")\n newdata = somelongcomputation(data,otherdata) # this blocks other requests\n await db.execute(\"some sql\",newdata)\n \n\n\n@app.post(\"/profile\")\nasync def profile(data: Data, background_tasks: BackgroundTasks):\n background_tasks.add_task(task, data)\n return {}\n```\n\n```py\nfrom fastapi.concurrency import run_in_threadpool\nasync def task(data):\n otherdata = await db.fetch(\"some sql\")\n newdata = await run_in_threadpool(lambda: somelongcomputation(data, otherdata))\n await db.execute(\"some sql\", newdata)\n```\n\n```py\nimport asyncio\nasync def task(data):\n otherdata = await db.fetch(\"some sql\")\n loop = asyncio.get_running_loop()\n newdata = await loop.run_in_executor(None, lambda: somelongcomputation(data, otherdata))\n await db.execute(\"some sql\", newdata)\n```\n\n```text\ntask\n```\n\n```text\nasync\n```\n\n```text\nsomelongcomputation\n```\n\n```text\nuvicorn main:app --workers 4\n```\n\n```text\nsomelongcomputation\n```\n\n```text\nasync\n```\n\n```text\ndef task(data): ...\n```\n\n```text\nfastapi.concurrency.run_in_threadpool\n```\n\n```text\nasyncios\n```\n\n```text\nrun_in_executor\n```\n\n```text\nrun_in_threadpool\n```\n\n```text\nconcurrent.futures.ProcessPoolExecutor\n```\n\n```text\nrun_in_executor\n```\n\n```text\nconcurrent.futures\n```\n\n```py\nfrom starlette.concurrency import run_in_threadpool\n\n@app.get(\"/long_answer\")\nasync def long_answer():\n rst = await run_in_threadpool(my_model.function_b, arg_1, arg_2)\n return rst\n```\n\n```text\nmy_model.function_b\n```\n\n```py\nimport asyncio\nfrom fastapi import FastAPI\n\napp = FastAPI()\nx = [1] # a global variable x\n\n\n@app.get(\"/\")\ndef hello():\n return {\"message\": \"hello\", \"x\": x}\n\nasync def periodic():\n while True:\n # code to run periodically starts here\n x[0] += 1\n print(f\"x is now {x}\")\n # code to run periodically ends here\n # sleep for 3 seconds after running above code\n await asyncio.sleep(3)\n\n@app.on_event(\"startup\")\nasync def schedule_periodic():\n loop = asyncio.get_event_loop()\n loop.create_task(periodic())\n\n\nif __name__ == \"__main__\":\n import uvicorn\n uvicorn.run(app)\n```\n\n========================================\n\nComments:\n- If the computation is heavy and do not involve IO it is better to use multiprocessing.\n- i am using the docker fastapi for deployment it's using all cpu cores for the server by default. I dont want to use another service like celery as the product is still in prototyping phase and has no users.\n- @GaryOng Please have a look at this related answer as well.\n- I am facing the same problem here and I wonder why not just using `asyncio.create_task(task(data))`? I am doing some tests and seems to be the solution.\n- You mean instead of using `BackgroundTasks`? Are you sure that works? Because `asyncio.create_task` will run the task (and therefore `somelongcomputation`) in the event loop, which will then be blocked, just like in the question. The reason that `run_in_threadpool` works is that it runs the computation in the underlying threadpool directly, sidestepping the event loop.\n- if not using `async` spawns another thread, isn't this better than using `async`?\n- @Crashalot depends on the situation. Have a look at some of the answers here: stackoverflow.com/questions/27435284/…, and maybe here: discuss.python.org/t/….\n- where would one need to pass `concurrent.futures.ProcessPoolExecutor` in exactly? In `newdata = await loop.run_in_executor(ProcessPoolExecutor(), lambda: somelongcomputation(data, otherdata))`?\n- @ben yep, have a look at the documenation for some examples (docs.python.org/3/library/…)\n- I don't think Threads are of any help here. Since Python doesn't utilize true Parallelism, spawning thread for heavy CPU computation will still hold the entire program. Use Proccesses instead.\n- I agree with Alexander, threads do not help for CPU bounded operations in python, but given the high number of votes here it makes me wonder if I miss something or not... @mihi - would love to here your thoughts here\n- @ShayTsadok Threads won't help with overall throughput, that is true. But using them does prevent blocking of other requests, as context switching between the threads still happens. They won't run in parallel, but rather interleaved.\n- please explain how this solves the problem at hand and why this solution is non-blocking. that would greatly help understanding the code.","metadata":{"transformedAt":"2026-08-18T18:32:29.085Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":20,"totalLines":201,"estimatedTokens":1438}}18{"id":"stack-63177681","source":"stackoverflow","questionId":63177681,"title":"is there a difference between running fastapi from uvicorn command in dockerfile and from pythonfile?","tags":["python","docker","fastapi","uvicorn"],"text":"Title: is there a difference between running fastapi from uvicorn command in dockerfile and from pythonfile?\nTags: python, docker, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI am running a fast api and when i was developing i had the following piece of code in my app.py file\n\ncode in app.py:\n\n```\nimport uvicorn\n\nif __name__==\"__main__\":\n uvicorn.run(\"app.app:app\",host='0.0.0.0', port=4557, reload=True, debug=True, workers=3)\n```\n\nso i was about to run `CMD [\"python3\",\"app.py\"]` in my Dockerfile.\n\non the fastapi example they did something like this :\n\n```\nCMD [\"uvicorn\", \"app.main:app\", \"--host\", \"0.0.0.0\", \"--port\", \"80\"]\n```\n\nI want to know what is the difference between these two methods as i think both of them will work.\n\n========================================\n\nTop Answer:\nThe answer is **no**. There will be no difference in app, deploying with **Docker** just making it **easier**, without Docker you need to run it with **ASGI** compatible server like Uvicorn, also you might want to set up some tooling to make sure it is restarted automatically if it stops or crashes. Instead of trying to handle it manually, a Docker image can handle all these jobs automatically.\n\n========================================\n\nCode:\n```text\nimport uvicorn\n\n\nif __name__==\"__main__\":\n uvicorn.run(\"app.app:app\",host='0.0.0.0', port=4557, reload=True, debug=True, workers=3)\n```\n\n```text\nCMD [\"uvicorn\", \"app.main:app\", \"--host\", \"0.0.0.0\", \"--port\", \"80\"]\n```\n\n```text\nCMD [\"python3\",\"app.py\"]\n```\n\n```text\nuvicorn.run(\"app.app:app\",host='0.0.0.0', port=4557, reload=True, debug=True, workers=3)\n```\n\n```text\nuvicorn app.app:app --host 0.0.0.0 --port 4557 --reload --debug --workers 3\n```\n\n```text\nv 0.19.0\n```\n\n```text\n--debug\n```\n\n```text\nuvicorn app.main:app\n```\n\n```text\npython app.py\n```\n\n```text\nuvicorn.main.run(...)\n```\n\n```text\nuvicorn\n```\n\n```text\nuvicorn.run(...)\n```\n\n```text\nuvicorn\n```\n\n========================================\n\nComments:\n- The `--debug` option no longer exists, the answer can be updated. ~ maintainer of uvicorn here.","metadata":{"transformedAt":"2026-08-18T18:32:29.085Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":13,"totalLines":94,"estimatedTokens":516}}19{"id":"stack-65209934","source":"stackoverflow","questionId":65209934,"title":"Pydantic enum field does not get converted to string","tags":["python","serialization","fastapi","pydantic"],"text":"Title: Pydantic enum field does not get converted to string\nTags: python, serialization, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI am trying to restrict one field in a class to an enum. However, when I try to get a dictionary out of class, it doesn't get converted to string. Instead it retains the enum. I checked pydantic documentation, but couldn't find anything relevant to my problem.\n\nThis code is representative of what I actually need.\n\n```\nfrom enum import Enum\nfrom pydantic import BaseModel\n\nclass S(str, Enum):\n am = 'am'\n pm = 'pm'\n\nclass K(BaseModel):\n k: S\n z: str\n\na = K(k='am', z='rrrr')\nprint(a.dict()) # {'k': , 'z': 'rrrr'}\n```\n\nI'm trying to get the `.dict()` method to return `{'k': 'am', 'z': 'rrrr'}`\n\n========================================\n\nTop Answer:\n### Pydantic 2.0\n\nBy default, Pydantic preserves the enum data type in its serialization. To override this behavior, specify `use_enum_values` in the model config.\n\n```\nfrom enum import Enum\nfrom pydantic import BaseModel, ConfigDict\n\nclass S(str, Enum):\n am = 'am'\n pm = 'pm'\n\nclass K(BaseModel):\n model_config = ConfigDict(use_enum_values=True)\n\n k: S\n z: str\n\na = K(k='am', z='rrrr')\nprint(a.model_dump()) # {'k': 'am', 'z': 'rrrr'}\n```\n\nNote: `model_config` is now an attribute of type `ConfigDict` (this is a breaking change from V1).\n\n### Neater: Specify config options as model class kwargs\n\nAlternatively, you can populate directly in the class definition:\n\n```\nclass K(BaseModel, use_enum_values=True):\n k: S\n z: str\n```\n\n========================================\n\nCode:\n```text\nfrom enum import Enum\nfrom pydantic import BaseModel\n\nclass S(str, Enum):\n am = 'am'\n pm = 'pm'\n\nclass K(BaseModel):\n k: S\n z: str\n\na = K(k='am', z='rrrr')\nprint(a.dict()) # {'k': <S.am: 'am'>, 'z': 'rrrr'}\n```\n\n```text\n.dict()\n```\n\n```text\n{'k': 'am', 'z': 'rrrr'}\n```\n\n```text\nfrom enum import Enum\nfrom pydantic import BaseModel\n\nclass S(str, Enum):\n am='am'\n pm='pm'\n\nclass K(BaseModel):\n k:S\n z:str\n\n class Config: \n use_enum_values = True # <--\n\na = K(k='am', z='rrrr')\nprint(a.dict())\n```\n\n```text\nuse_enum_values\n```\n\n```text\nuse_enum_values\n```\n\n```text\nvalue\n```\n\n```text\nmodel.dict()\n```\n\n```text\nFalse\n```\n\n```text\nfrom enum import Enum\nfrom pydantic import BaseModel\nfrom fastapi.encoders import jsonable_encoder\n\nclass S(str, Enum):\n am = 'am'\n pm = 'pm'\n\nclass K(BaseModel):\n k: S\n z: str\n\na = K(k='am', z='rrrr')\nprint(jsonable_encoder(a)) # {'k': 'am', 'z': 'rrrr'}\n```\n\n```text\njsonable_encoder\n```\n\n```py\nfrom enum import Enum\n\nclass StrEnum(str, Enum):\n def __repr__(self) -> str:\n return str.__repr__(self.value)\n\nclass A(str, Enum):\n FOO = \"foo\"\n\nclass B(StrEnum):\n BAR= \"bar\"\n\nclass C(BaseModel):\n a: A = Field(...)\n b: B = Field(...)\n\nprint(C(a=\"foo\", b=\"bar\").dict())\n\nimport json\n\nprint(json.dumps(C(a=\"foo\", b=\"bar\").dict()))\n```\n\n```text\n{'a': <A.FOO: 'foo'>, 'b': 'bar'}\n{\"a\": \"foo\", \"b\": \"bar\"}\n```\n\n```text\nConfig\n```\n\n```text\n(Str,Enum)\n```\n\n```text\nStrEnum\n```\n\n```text\nA\n```\n\n```text\nB\n```\n\n```text\n(str, Enum)\n```\n\n```text\nStrEnum\n```\n\n```text\nStrEnum\n```\n\n```py\nfrom enum import Enum\nfrom pydantic import BaseModel, ConfigDict\n\nclass S(str, Enum):\n am = 'am'\n pm = 'pm'\n\n\nclass K(BaseModel):\n model_config = ConfigDict(use_enum_values=True)\n\n k: S\n z: str\n\na = K(k='am', z='rrrr')\nprint(a.model_dump()) # {'k': 'am', 'z': 'rrrr'}\n```\n\n```py\nclass K(BaseModel, use_enum_values=True):\n k: S\n z: str\n```\n\n```text\nuse_enum_values\n```\n\n```text\nmodel_config\n```\n\n```text\nConfigDict\n```\n\n```py\na = K(k='am', z='rrrr')\nprint(a.model_dump(mode='json', exclude_unset=True))\n```\n\n========================================\n\nComments:\n- literals are the easier way to achieve the result stackoverflow.com/a/76973419/3140992\n- is there a reason that this option is False by default? I feel in most of the cases we would require that to be true.\n- @Krishna one could argue why not leave dates as ISO8601 strings? Principle of least surprise is that you get what you ask for, you asked for an Enum\n- Is there a way to use the enum values when serializing using .dict() but keep the full enum when deserializing and constructing the pydantic object ?\n- I was wondering the same as @vianmixt. The whole reason why anyone would use an enum is so that when working with the object, one has the convenience that enums offer, but yet it can be serialized as a string as this is the simplest way to be language independent.\n- @vianmixt See y26805's answer for a solution that relies on FastAPI.\n- Actually when using straight `str` based `Enum` where each member has the same name and value (e.g. `MALE = \"MALE\" ; FEMALE = \"FEMALE\"` etc.) I don't find any convenience in having the `Enum` instance. It's more verbose and requires a reference. Given Pydantic has validated the input nicely I can rely on a derived `str` being one of the allowed values and can use less verbose string comparisons if I need to. The primary reason I have for using `Enum` is to create the OpenAPI description.\n- This is nice because you can keep the full `Enum` when deserializing and constructing the Pydantic object.\n- This is my preferred way of doing this as you don't always want to loose the enum type when using `model_dump`, would be nicer to pass `use_enum_values` when calling `model_dump`. Using `model_dump_json` does not always work in our use case either.\n- This doesn't work with Pydantic, there you need use_enum_values=True as described above.\n- Calling `.model_dump(mode=\"json\")` allows for being able to get a json-able dict when dumping the object while retaining the ability to construct and deserialize objects with the actual enum type.\n- @BradK. You should use `model.dump_json()` instead","metadata":{"transformedAt":"2026-08-18T18:32:29.085Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":27,"totalLines":269,"estimatedTokens":1444}}20{"id":"stack-75740652","source":"stackoverflow","questionId":75740652,"title":"FastAPI StreamingResponse not streaming with generator function","tags":["python","python-requests","streaming","fastapi","openai-api"],"text":"Title: FastAPI StreamingResponse not streaming with generator function\nTags: python, python-requests, streaming, fastapi, openai-api\nSource: Stack Overflow\n\nQuestion:\nI have a relatively simple FastAPI app that accepts a query and streams back the response from ChatGPT's API. ChatGPT is streaming back the result and I can see this being printed to console as it comes in.\n\nWhat's not working is the `StreamingResponse` back from FastAPI. The response gets sent all together instead. I'm really at a loss as to why this isn't working.\n\nHere is the FastAPI app code:\n\n```\nimport os\nimport time\n\nimport openai\n\nimport fastapi\nfrom fastapi import Depends, HTTPException, status, Request\nfrom fastapi.security import HTTPBearer, HTTPAuthorizationCredentials\nfrom fastapi.responses import StreamingResponse\n\nauth_scheme = HTTPBearer()\napp = fastapi.FastAPI()\n\nopenai.api_key = os.environ[\"OPENAI_API_KEY\"]\n\ndef ask_statesman(query: str):\n #prompt = router(query)\n \n completion_reason = None\n response = \"\"\n while not completion_reason or completion_reason == \"length\":\n openai_stream = openai.ChatCompletion.create(\n model=\"gpt-3.5-turbo\",\n messages=[{\"role\": \"user\", \"content\": query}],\n temperature=0.0,\n stream=True,\n )\n for line in openai_stream:\n completion_reason = line[\"choices\"][0][\"finish_reason\"]\n if \"content\" in line[\"choices\"][0].delta:\n current_response = line[\"choices\"][0].delta.content\n print(current_response)\n yield current_response\n time.sleep(0.25)\n\n@app.post(\"/\")\nasync def request_handler(auth_key: str, query: str):\n if auth_key != \"123\":\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Invalid authentication credentials\",\n headers={\"WWW-Authenticate\": auth_scheme.scheme_name},\n )\n else:\n stream_response = ask_statesman(query)\n return StreamingResponse(stream_response, media_type=\"text/plain\")\n\nif __name__ == \"__main__\":\n import uvicorn\n uvicorn.run(app, host=\"0.0.0.0\", port=8000, debug=True, log_level=\"debug\")\n```\n\nAnd here is the very simple `test.py` file to test the above:\n\n```\nimport requests\n\nquery = \"How tall is the Eiffel tower?\"\nurl = \"http://localhost:8000\"\nparams = {\"auth_key\": \"123\", \"query\": query}\n\nresponse = requests.post(url, params=params, stream=True)\n\nfor chunk in response.iter_lines():\n if chunk:\n print(chunk.decode(\"utf-8\"))\n```\n\n========================================\n\nTop Answer:\nIf you opt to use Langchain to interact with OpenAI (which I highly recommend), it provides stream method, which effectively returns a generator.\n\nSlight modification to Chris' code above,\n\n### `api.py`\n\n```\nfrom fastapi import FastAPI\nfrom fastapi.responses import StreamingResponse\nfrom langchain.llms import OpenAI\n\nllm = OpenAI(\n streaming=True,\n verbose=True,\n temperature=0,\n)\n\napp = FastAPI()\n\ndef chat_gpt_streamer(query: str):\n for resp in llm.stream(query):\n yield resp[\"choices\"][0][\"text\"]\n\n@app.get('/streaming/ask')\nasync def main(query: str):\n return StreamingResponse(chat_gpt_streamer(query), media_type='text/event-stream')\n\nif __name__ == \"__main__\":\n import uvicorn\n uvicorn.run(app, host=\"0.0.0.0\", port=8000, log_level=\"debug\")\n```\n\nSimilarly you can test with httpx, or requests (again copy paste from Chris' code):\n\n### `test.py`\n\n```\nimport httpx\n\nurl = 'http://127.0.0.1:8000/streaming/ask?query=How are you, write in 10 sentences'\nwith httpx.stream('GET', url) as r:\n for chunk in r.iter_raw(): # or, for line in r.iter_lines():\n print(chunk)\n```\n\n========================================\n\nCode:\n```py\nimport os\nimport time\n\nimport openai\n\nimport fastapi\nfrom fastapi import Depends, HTTPException, status, Request\nfrom fastapi.security import HTTPBearer, HTTPAuthorizationCredentials\nfrom fastapi.responses import StreamingResponse\n\nauth_scheme = HTTPBearer()\napp = fastapi.FastAPI()\n\nopenai.api_key = os.environ[\"OPENAI_API_KEY\"]\n\n\ndef ask_statesman(query: str):\n #prompt = router(query)\n \n completion_reason = None\n response = \"\"\n while not completion_reason or completion_reason == \"length\":\n openai_stream = openai.ChatCompletion.create(\n model=\"gpt-3.5-turbo\",\n messages=[{\"role\": \"user\", \"content\": query}],\n temperature=0.0,\n stream=True,\n )\n for line in openai_stream:\n completion_reason = line[\"choices\"][0][\"finish_reason\"]\n if \"content\" in line[\"choices\"][0].delta:\n current_response = line[\"choices\"][0].delta.content\n print(current_response)\n yield current_response\n time.sleep(0.25)\n\n\n@app.post(\"/\")\nasync def request_handler(auth_key: str, query: str):\n if auth_key != \"123\":\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Invalid authentication credentials\",\n headers={\"WWW-Authenticate\": auth_scheme.scheme_name},\n )\n else:\n stream_response = ask_statesman(query)\n return StreamingResponse(stream_response, media_type=\"text/plain\")\n\n\nif __name__ == \"__main__\":\n import uvicorn\n uvicorn.run(app, host=\"0.0.0.0\", port=8000, debug=True, log_level=\"debug\")\n```\n\n```py\nimport requests\n\nquery = \"How tall is the Eiffel tower?\"\nurl = \"http://localhost:8000\"\nparams = {\"auth_key\": \"123\", \"query\": query}\n\nresponse = requests.post(url, params=params, stream=True)\n\nfor chunk in response.iter_lines():\n if chunk:\n print(chunk.decode(\"utf-8\"))\n```\n\n```text\nStreamingResponse\n```\n\n```text\ntest.py\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.responses import StreamingResponse\nimport asyncio\n\n\napp = FastAPI()\n\n\nasync def fake_data_streamer():\n for i in range(10):\n yield b'some fake data\\n\\n'\n await asyncio.sleep(0.5)\n\n\n# If your generator contains blocking operations such as time.sleep(), then define the\n# generator function with normal `def`. Alternatively, use `async def` and run any \n# blocking operations in an external ThreadPool/ProcessPool. (see 2nd paragraph of this answer)\n'''\nimport time\n\ndef fake_data_streamer():\n for i in range(10):\n yield b'some fake data\\n\\n'\n time.sleep(0.5)\n''' \n\n \n@app.get('/')\nasync def main():\n return StreamingResponse(fake_data_streamer(), media_type='text/event-stream')\n # or, use:\n '''\n headers = {'X-Content-Type-Options': 'nosniff'}\n return StreamingResponse(fake_data_streamer(), headers=headers, media_type='text/plain')\n '''\n```\n\n```py\nimport requests\n\nurl = \"http://localhost:8000/\"\n\nwith requests.get(url, stream=True) as r:\n for chunk in r.iter_content(1024): # or, for line in r.iter_lines():\n print(chunk)\n```\n\n```py\nimport httpx\n\nurl = 'http://127.0.0.1:8000/'\n\nwith httpx.stream('GET', url) as r:\n for chunk in r.iter_raw(): # or, for line in r.iter_lines():\n print(chunk)\n```\n\n```text\nPOST\n```\n\n```text\nGET\n```\n\n```text\nauth_key\n```\n\n```text\nHeaders\n```\n\n```text\nCookies\n```\n\n```text\nHTTPS\n```\n\n```text\nStreamingResponse\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\ntime.sleep()\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\niterate_in_threadpool()\n```\n\n```text\nawait\n```\n\n```text\nStreamingResponse\n```\n\n```text\nasync def\n```\n\n```text\nThreadPool\n```\n\n```text\nProcessPool\n```\n\n```text\nawait\n```\n\n```text\nawait asyncio.sleep()\n```\n\n```text\ntime.sleep()\n```\n\n```text\nrequests\n```\n\n```text\niter_lines()\n```\n\n```text\n\\n\n```\n\n```text\niter_content()\n```\n\n```text\nchunk_size\n```\n\n```text\nStreamingResponse\n```\n\n```text\nmedia_type\n```\n\n```text\ntext/plain\n```\n\n```text\napplication/json\n```\n\n```text\ntext/event-stream\n```\n\n```text\ntext/plain\n```\n\n```text\nmedia_type\n```\n\n```text\ntext/event-stream\n```\n\n```text\ntext/plain\n```\n\n```text\nX-Content-Type-Options\n```\n\n```text\nnosniff\n```\n\n```text\nrequests\n```\n\n```text\nhttpx\n```\n\n```text\nhttpx\n```\n\n```text\nrequests\n```\n\n```text\nimport os\nimport time\n\nimport openai\n\nimport fastapi\nfrom fastapi import Depends, HTTPException, status, Request\nfrom fastapi.security import HTTPBearer, HTTPAuthorizationCredentials\nfrom fastapi.responses import StreamingResponse\n\nauth_scheme = HTTPBearer()\napp = fastapi.FastAPI()\n\nopenai.api_key = os.environ[\"OPENAI_API_KEY\"]\n\n\ndef ask_statesman(query: str):\n #prompt = router(query)\n \n completion_reason = None\n response = \"\"\n while not completion_reason or completion_reason == \"length\":\n openai_stream = openai.ChatCompletion.create(\n model=\"gpt-3.5-turbo\",\n messages=[{\"role\": \"user\", \"content\": query}],\n temperature=0.0,\n stream=True,\n )\n for line in openai_stream:\n completion_reason = line[\"choices\"][0][\"finish_reason\"]\n if \"content\" in line[\"choices\"][0].delta:\n current_response = line[\"choices\"][0].delta.content\n print(current_response)\n yield {\"data\": current_response}\n time.sleep(0.25)\n\n\n@app.post(\"/\")\nasync def request_handler(auth_key: str, query: str):\n if auth_key != \"123\":\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Invalid authentication credentials\",\n headers={\"WWW-Authenticate\": auth_scheme.scheme_name},\n )\n else:\n return StreamingResponse((line for line in ask_statesman(query)), media_type=\"text/plain\")\n\n\nif __name__ == \"__main__\":\n import uvicorn\n uvicorn.run(app, host=\"0.0.0.0\", port=8000, debug=True, log_level=\"debug\")\n```\n\n```text\nask_statesman\n```\n\n```text\nyield current_response\n```\n\n```text\n{\"data\": current_response}\n```\n\n```text\n\"data\"\n```\n\n```text\nrequest_handler\n```\n\n```text\nstream_response\n```\n\n```text\nask_statesman\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.responses import StreamingResponse\nfrom langchain.llms import OpenAI\n\n\nllm = OpenAI(\n streaming=True,\n verbose=True,\n temperature=0,\n)\n\napp = FastAPI()\n\n\ndef chat_gpt_streamer(query: str):\n for resp in llm.stream(query):\n yield resp[\"choices\"][0][\"text\"]\n\n\n@app.get('/streaming/ask')\nasync def main(query: str):\n return StreamingResponse(chat_gpt_streamer(query), media_type='text/event-stream')\n\nif __name__ == \"__main__\":\n import uvicorn\n uvicorn.run(app, host=\"0.0.0.0\", port=8000, log_level=\"debug\")\n```\n\n```py\nimport httpx\n\nurl = 'http://127.0.0.1:8000/streaming/ask?query=How are you, write in 10 sentences'\nwith httpx.stream('GET', url) as r:\n for chunk in r.iter_raw(): # or, for line in r.iter_lines():\n print(chunk)\n```\n\n```text\napi.py\n```\n\n```text\ntest.py\n```\n\n```py\nfrom fastapi import FastAPI\nfrom sse_starlette.sse import EventSourceResponse\nimport time\n\n\napp = FastAPI()\n\n\ndef data_streamer():\n for i in range(10):\n yield f\"_{i}_\".encode(\"utf-8\")\n time.sleep(1)\n\n\n@app.get('/')\nasync def main():\n return EventSourceResponse(data_streamer(), media_type='text/event-stream')\n```\n\n```text\npip install sse-starlette\n```\n\n```bash\ncurl -X POST \"http://localhost:12345/api/generate\" -H \"Content-Type: application/json\" -d '{\"model\": \"wizard-vicuna-uncensored\", \"prompt\": \"why is the sky blue? be verbose\"}'\n```\n\n```bash\ncurl -N -X POST \"http://localhost:12345/api/generate\" -H \"Content-Type: application/json\" -d '{\"model\": \"wizard-vicuna-uncensored\", \"prompt\": \"why is the sky blue? be verbose\"}'\n```\n\n```text\ncurl\n```\n\n```text\n-N\n```\n\n========================================\n\nComments:\n- Unfortunately this didn't work. I tried variations as well (returning a dict only, doing both your suggestions and the generator in a generator). None of these worked. It's possible it's my testing code, I may try to test this in JS.\n- Thank you for the very comprehensive answer. Anyone looking at this later should the recommendations Chris gives. Also, I should note that my original code actually worked (although with some issues, as Chris described). There was some issue with iter_lines and my test file, but I got this sorted. The root issue stemmed from an issue with a serverless provider I was using to host this app.\n- @Chris also a big thanks from my side, but what I quite don´t get is whether a request (assuming it´s net I/O) that being made inside the StreamingResponse should use an async def generator? From my understanding of those links is that it should be done via an async request, or am I mistaken?\n- @Bennimi If you are using a library that performs blocking I/O-bound operations, such as `requests`, it might be best to use a `def` generator, as explained in the 2nd paragraph of the answer above (as well as the references included). I would, though, suggest defining the generator with `async def` and use a library that provides `async` API, such as `httpx` - have a look here, here, here and here\n- but if you don't use sleep after yield, it send them together\n- @masoudvali I am afraid you are mistaken. If `await asyncio.sleep(0.5)` was omitted, the generator would **still** return the data in chunks. However, without the `sleep()` function in place, it would be hard for you to notice that, as the `for loop` is quite fast, making you think that all data were sent at once. That is exactly the reason the `sleep()` function was placed there. In real-world scenarios, and always depending on your needs, you wouldn't necessarily need to have the `sleep()` function. You could also use it on client side instead, in order to confirm/test the above.\n- Thanks for the answer. While your answer works, I fail to see the advantages of LangChain. At best, it reduces code, but at the expense of flexibility. I'm actually using LangChain elsewhere in this app but only as it is useful.\n- You have a point, using langchain is not a big win in this case, but just wanted to highlight `llm.stream()` returning a generator is useful. Though not difficult to implement it with basic OpenAI sdk\n- this answer is helping me so much, thanks!\n- Very helpful answer. Thank you. I disagree that Langchain adds no value, it has its use cases and is a popular choice for many working on AI projects. Cheers!\n- I in fact am! I'm using Modal Endpoints and it works great. modal.com\n- I've been looking for this for about an hour now. Thanks a lot!","metadata":{"transformedAt":"2026-08-18T18:32:29.085Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":66,"totalLines":615,"estimatedTokens":3527}}21{"id":"stack-70872276","source":"stackoverflow","questionId":70872276,"title":"FastAPI python: How to run a thread in the background?","tags":["python","multithreading","fastapi","background-task","uvicorn"],"text":"Title: FastAPI python: How to run a thread in the background?\nTags: python, multithreading, fastapi, background-task, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI'm making a server in python using FastAPI, and I want a function that is not related to my API, to run in the background every 5 minutes (like checking stuff from an API and printing stuff depending on the response).\n\nI've tried to make a thread that runs the `start_worker()` function , but it doesn't print anything.\n\nDoes anyone know how to do so?\n\n```\ndef start_worker():\n print('[main]: starting worker...')\n my_worker = worker.Worker()\n my_worker.working_loop() # this function prints \"hello\" every 5 seconds\n\nif __name__ == '__main__':\n print('[main]: starting...')\n uvicorn.run(app, host=\"0.0.0.0\", port=8000, reload=True)\n _worker_thread = Thread(target=start_worker, daemon=False)\n _worker_thread.start()\n```\n\n========================================\n\nCode:\n```py\ndef start_worker():\n print('[main]: starting worker...')\n my_worker = worker.Worker()\n my_worker.working_loop() # this function prints \"hello\" every 5 seconds\n\nif __name__ == '__main__':\n print('[main]: starting...')\n uvicorn.run(app, host=\"0.0.0.0\", port=8000, reload=True)\n _worker_thread = Thread(target=start_worker, daemon=False)\n _worker_thread.start()\n```\n\n```text\nstart_worker()\n```\n\n```py\nfrom fastapi import FastAPI\nimport threading\nimport uvicorn\nimport time\n\napp = FastAPI()\n\n\nclass BackgroundTasks(threading.Thread):\n def run(self,*args,**kwargs):\n while True:\n print('Hello')\n time.sleep(5)\n\n\nif __name__ == '__main__':\n t = BackgroundTasks()\n t.start()\n uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n```\n\n```py\n@app.on_event(\"startup\")\nasync def startup_event():\n t = BackgroundTasks()\n t.start()\n```\n\n```py\nfrom fastapi import FastAPI\nfrom threading import Thread\nimport uvicorn\nimport sched, time\n\napp = FastAPI()\ns = sched.scheduler(time.time, time.sleep)\n\n\ndef print_event(sc): \n print(\"Hello\")\n sc.enter(5, 1, print_event, (sc,))\n\n\ndef start_scheduler():\n s.enter(5, 1, print_event, (s,))\n s.run()\n\n\n@app.on_event(\"startup\")\nasync def startup_event():\n thread = Thread(target=start_scheduler)\n thread.start()\n\n\nif __name__ == '__main__':\n uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n```\n\n```py\nfrom fastapi import FastAPI\nfrom contextlib import asynccontextmanager\nimport asyncio\n\n\nasync def print_task(s): \n while True:\n print('Hello')\n await asyncio.sleep(s)\n\n \n@asynccontextmanager\nasync def lifespan(app: FastAPI):\n # Run at startup\n asyncio.create_task(print_task(5))\n yield\n # Run on shutdown (if required)\n print('Shutting down...')\n\n\napp = FastAPI(lifespan=lifespan)\n```\n\n```text\nThread\n```\n\n```text\nuvicorn.run\n```\n\n```text\nuvicorn.run\n```\n\n```text\nThread\n```\n\n```text\nlifespan\n```\n\n```text\nstartup\n```\n\n```text\nwhile True:\n```\n\n```text\nasync def\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\nasyncio.create_task()\n```\n\n```text\ncreate_task()\n```\n\n```text\nasync def\n```\n\n```text\nTask\n```\n\n```text\nawait\n```\n\n```text\ncancel\n```\n\n```text\nawait\n```\n\n```text\ncreate_task()\n```\n\n```text\nuvicorn\n```\n\n```text\nuvicorn.run(app)\n```\n\n```text\nuvicorn app:app\n```\n\n```text\nasyncio.create_task()\n```\n\n```text\nasyncio.get_running_loop()\n```\n\n```text\nloop\n```\n\n```text\nloop.create_task()\n```\n\n```text\nlifespan\n```\n\n```text\nstartup\n```\n\n```text\nshutdown\n```\n\n```text\nApScheduler\n```\n\n```text\nAsyncIOScheduler\n```\n\n```text\nsubprocess\n```\n\n========================================\n\nComments:\n- Try moving the thread stuff to before the run(). It's possible the run() doesn't return until the server dies.\n- doesn't work as well, it doesn't even print('[main]: starting...'), but the api is working\n- The solution I found was to create an endpoint for background work. The endpoint is hit with a CRON job. The upside of using an endpoint is that you can have the code running with async/await functions including a database. I used the \"background.add_task\" function to launch the background job and return an ok immediately to the CRON request.\n- How resilient is the subprocess? Is it possible for the BackgroundTasks service to be killed, and if so, does FastAPI's event handler restart it automatically?\n- Thank you for the answer! Do you know what are the pros and cons of each?\n- @DM You should opt going for the third option, if possible, as in that case, your task would run in the event loop, which runs in the main thread, while in the first two options, a separate thread would have to be created for running the task. Please have a look at this answer for more details on *asynchronous* programming and how FastAPI works under the hood.","metadata":{"transformedAt":"2026-08-18T18:32:29.085Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":37,"totalLines":260,"estimatedTokens":1182}}22{"id":"stack-63872924","source":"stackoverflow","questionId":63872924,"title":"How can I send an HTTP request from my FastAPI app to another site (API)?","tags":["python","async-await","httprequest","python-asyncio","fastapi"],"text":"Title: How can I send an HTTP request from my FastAPI app to another site (API)?\nTags: python, async-await, httprequest, python-asyncio, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to send 100 requests at a time to a server `http://httpbin.org/uuid` using the following code snippet \n\n```\nfrom fastapi import FastAPI\nfrom time import sleep\nfrom time import time\nimport requests\nimport asyncio\n\napp = FastAPI()\n\nURL= \"http://httpbin.org/uuid\"\n\n# @app.get(\"/\")\nasync def main():\n r = requests.get(URL)\n # print(r.text)\n \n return r.text\n\nasync def task():\n tasks = [main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main()]\n # print(tasks)\n # input(\"stop\")\n result = await asyncio.gather(*tasks)\n print (result)\n\n@app.get('/')\ndef f():\n start = time()\n asyncio.run(task())\n print(\"time: \",time()-start)\n```\n\nI am using FastAPI with Asyncio to achieve the lowest time possible around 3 seconds or less but using the above method I am getting an overall time of 66 seconds that is more than a minute. I also want to keep the `main` function for additional operations on `r.text`. I understand that to achieve such low time, concurrency is required but I am not sure what mistake I'm doing here.\n\n========================================\n\nTop Answer:\n@Alex Noname has made a good point of using asynchronous request library. If you want to make code faster I would suggest using **asyncio.Queue** as an alternate. In this example I spun up 100 producers and 100 consumers. you can limit the maximum number of messages in the queue like, then producer waits until there is space for new message\n\nasyncio.Queue(maxsize=100)\n\nalso I have made use of **AsyncClient** from **httpx**.\n\nIf you want to know more about queues I would suggest this article\nhttps://realpython.com/async-io-python/\n\n```\nfrom time import time\nfrom typing import List\n\nfrom fastapi import FastAPI\nfrom httpx import AsyncClient\n\napp = FastAPI()\n\nURL = \"http://httpbin.org/uuid\"\nclient = AsyncClient()\n\nasync def main():\n r = await client.get(URL)\n return r.text\n\nasync def producer(queue: asyncio.Queue):\n await queue.put(main)\n\nasync def consumer(queue: asyncio.Queue, resp: List):\n # await queue.get() == main -> without arguments\n resp.append(await (await queue.get())())\n\nasync def task():\n q = asyncio.Queue(maxsize=100)\n response = []\n consumers = []\n producers = []\n [consumers.append(consumer(q, response)) for c in range(100)]\n [producers.append(producer(q)) for p in range(100)]\n\n await asyncio.gather(*producers)\n await asyncio.gather(*consumers)\n print(response)\n\n@app.get('/')\ndef f():\n start = time()\n asyncio.run(task())\n print(\"time: \", time() - start)\n\nif __name__ == '__main__':\n f()\n```\n\noutput\n\n```\n['{\\n \"uuid\": \"a7713d07-ea5d-40d3-95b4-6673f3c50a8b\"\\n}\\n', '{\\n \"uuid\": \"c93f8b89-2c44-40fa-9e5f-736e22ad5f23\"\\n}\\n', '{\\n \"uuid\": \"cbb4ad76-7790-45ae-87f1-e425eddc8021\"\\n}\\n', '{\\n \"uuid\": \"4c1d81c0-ae7d-401a-99df-e98af3651335\"\\n}\\n', '{\\n \"uuid\": \"c5f70738-fbba-4cf9-8fdf-29f8b4eabe63\"\\n}\\n', '{\\n \"uuid\": \"d016b852-4312-4502-a336-a6a110237d1d\"\\n}\\n', '{\\n \"uuid\": \"22d8b00b-4266-4236-b5a3-ed5d7c5be416\"\\n}\\n', '{\\n \"uuid\": \"cd54fdbb-7de9-4df3-90cc-e6b108d5fdf8\"\\n}\\n', '{\\n \"uuid\": \"757f0a26-7896-4a04-bea2-60c66a38b05b\"\\n}\\n', '{\\n \"uuid\": \"72eb6584-21f4-449b-b6bd-d0f88666126f\"\\n}\\n', '{\\n \"uuid\": \"b3deadf5-5b79-491b-829c-0404c306cb68\"\\n}\\n', '{\\n \"uuid\": \"789e7422-493d-49d2-9585-e5ca34b7cf36\"\\n}\\n', '{\\n \"uuid\": \"48d29a82-ff7c-41f5-8af2-42784326a31f\"\\n}\\n', '{\\n \"uuid\": \"84b2d67c-331c-4037-b6e4-c299d93c1899\"\\n}\\n', '{\\n \"uuid\": \"386e79f9-073a-4f27-961c-7befcdf95cd4\"\\n}\\n', '{\\n \"uuid\": \"8dfdb5e4-dd69-4043-b174-48ec8505f36f\"\\n}\\n', '{\\n \"uuid\": \"633e634b-b107-42bb-a7d3-c6bbfff089a0\"\\n}\\n', '{\\n \"uuid\": \"962d665f-8663-4be7-a3c6-9426ba500bf4\"\\n}\\n', '{\\n \"uuid\": \"320fb858-a751-4c34-9cdb-ddd2f4e28efa\"\\n}\\n', '{\\n \"uuid\": \"46a75693-5255-4ac7-8d7a-54910b4d6f68\"\\n}\\n', '{\\n \"uuid\": \"5323734b-7ff9-455e-ba5a-66383e6b9a1f\"\\n}\\n', '{\\n \"uuid\": \"622a579f-35b6-4e4b-9dba-a8a69c2049c8\"\\n}\\n', '{\\n \"uuid\": \"593d5e82-cef3-4be0-99ab-e3034855d7a1\"\\n}\\n', '{\\n \"uuid\": \"80f139df-2a27-40c1-8329-e4faa035c45c\"\\n}\\n', '{\\n \"uuid\": \"a97e084c-4d30-4c7b-a96e-89ed00dcfe2a\"\\n}\\n', '{\\n \"uuid\": \"360d49eb-7222-4064-81c2-6eba2d43a9a5\"\\n}\\n', '{\\n \"uuid\": \"a81b6eab-a646-4e58-b986-96a90baa52aa\"\\n}\\n', '{\\n \"uuid\": \"0160337e-b400-41d6-ae89-aa46c5131f40\"\\n}\\n', '{\\n \"uuid\": \"e600722f-8c15-4959-948b-4c4e5296feb2\"\\n}\\n', '{\\n \"uuid\": \"f15403e4-3674-43b2-a0c9-649fd828ba7e\"\\n}\\n', '{\\n \"uuid\": \"36bf139c-cc18-45a8-bc55-e7f90ce290b5\"\\n}\\n', '{\\n \"uuid\": \"b2368a3c-d86b-4fcd-a0d3-bf7f8f657a83\"\\n}\\n', '{\\n \"uuid\": \"d9f16c36-3572-4c70-8a41-3d4e279d76bf\"\\n}\\n', '{\\n \"uuid\": \"796087cc-a202-40dd-9921-14802a73323d\"\\n}\\n', '{\\n \"uuid\": \"089fa0d7-4c48-4daa-a80d-cb5ebd37dfb7\"\\n}\\n', '{\\n \"uuid\": \"e5582bc7-0f8a-4da7-b640-79a0d812154d\"\\n}\\n', '{\\n \"uuid\": \"bac0640b-0d0b-4bf2-a3c1-36bdda7cce03\"\\n}\\n', '{\\n \"uuid\": \"b4353004-02b2-4846-8692-33dd77ad1d3f\"\\n}\\n', '{\\n \"uuid\": \"1b34a744-d0ea-4acf-8bda-33743800d86a\"\\n}\\n', '{\\n \"uuid\": \"4d9dd269-6ee2-4356-9bc4-ddf188445320\"\\n}\\n', '{\\n \"uuid\": \"a1f380df-0c0d-4aee-bbb7-c3e99fbfe54f\"\\n}\\n', '{\\n \"uuid\": \"7cb762eb-1a42-433d-97ea-aa9de4504e35\"\\n}\\n', '{\\n \"uuid\": \"981c40e2-64bf-4746-8103-9430bda2a5ca\"\\n}\\n', '{\\n \"uuid\": \"22b778eb-82d1-48b9-9874-5ebb80ddb8b1\"\\n}\\n', '{\\n \"uuid\": \"e7a9e0e8-7964-400c-aafe-9c36b9b7e1a0\"\\n}\\n', '{\\n \"uuid\": \"21a59b91-2732-4bb6-a47e-84008a03c20c\"\\n}\\n', '{\\n \"uuid\": \"a78eeb39-5ecb-4509-87c2-b4a2529e3536\"\\n}\\n', '{\\n \"uuid\": \"4a332579-ce03-4f69-9db5-78da9196d6b2\"\\n}\\n', '{\\n \"uuid\": \"55fbc34f-4eb3-4356-98e3-1df38054a4b2\"\\n}\\n', '{\\n \"uuid\": \"257ac454-09c2-4fd4-bdb3-303495360fa2\"\\n}\\n', '{\\n \"uuid\": \"7505cc0d-01b3-47f8-91d4-3e54d0f387de\"\\n}\\n', '{\\n \"uuid\": \"0fd67af2-622e-4688-b3c8-f64e20f1f3ec\"\\n}\\n', '{\\n \"uuid\": \"07653ccf-f408-4807-8ff5-e6098d657451\"\\n}\\n', '{\\n \"uuid\": \"b9d0ff18-fd67-4afa-adbe-ebcb53380804\"\\n}\\n', '{\\n \"uuid\": \"70d4d53b-2f06-41be-bb38-47f010cfa40f\"\\n}\\n', '{\\n \"uuid\": \"a6d49873-e749-4578-ae9c-e6c6f473535d\"\\n}\\n', '{\\n \"uuid\": \"e67efee5-76ad-4812-bb97-016ef9ff87e8\"\\n}\\n', '{\\n \"uuid\": \"67886926-b2d9-44fb-b836-26b81c53e5fb\"\\n}\\n', '{\\n \"uuid\": \"dcbd4ff8-e3cd-4e03-b12d-5fb3834b0e00\"\\n}\\n', '{\\n \"uuid\": \"65c2eaee-5fa2-4b58-a1c3-adeb04d92c71\"\\n}\\n', '{\\n \"uuid\": \"2cee4ec9-952e-45c5-91b7-f4f5848c3455\"\\n}\\n', '{\\n \"uuid\": \"8e94bf1c-ee5a-483a-a962-d0b9aea48c95\"\\n}\\n', '{\\n \"uuid\": \"c1fe17bc-bedf-4c4c-952d-a5921f693d9f\"\\n}\\n', '{\\n \"uuid\": \"221456fd-48ca-4826-a8b5-5fa0b23db6e4\"\\n}\\n', '{\\n \"uuid\": \"62fda759-b382-44e4-ad7d-d19a952fc1c7\"\\n}\\n', '{\\n \"uuid\": \"73faeb91-215e-4e49-8f11-11b98e499cc7\"\\n}\\n', '{\\n \"uuid\": \"f3279c45-ebcc-4079-b823-3efe825c7cf8\"\\n}\\n', '{\\n \"uuid\": \"b892672b-4510-44f4-b61e-9cccaa52421e\"\\n}\\n', '{\\n \"uuid\": \"8926979d-71a7-4171-9389-ddafff89e229\"\\n}\\n', '{\\n \"uuid\": \"d97cef59-4862-42ca-b0f2-261f98fd4b6f\"\\n}\\n', '{\\n \"uuid\": \"3362ff93-89e4-4889-a2f2-2e03771e86ce\"\\n}\\n', '{\\n \"uuid\": \"9f525251-4fe4-4a9c-97b5-2f01d2b37aaf\"\\n}\\n', '{\\n \"uuid\": \"036959d4-3179-40f9-bbf3-32274f2cede2\"\\n}\\n', '{\\n \"uuid\": \"157f8c22-6214-4e27-ab5d-08d39f96d1d3\"\\n}\\n', '{\\n \"uuid\": \"e4bfbf62-7c33-4fd7-a231-47f5ce398041\"\\n}\\n', '{\\n \"uuid\": \"a41512c1-3346-4457-a379-64d690ffc2ea\"\\n}\\n', '{\\n \"uuid\": \"7bb07cfb-294b-44fa-a8dc-6d283c54409f\"\\n}\\n', '{\\n \"uuid\": \"f2297d22-a2d0-47ff-8d65-24c6fe7877a7\"\\n}\\n', '{\\n \"uuid\": \"645e255b-4c93-4c8f-9ff2-43da293db660\"\\n}\\n', '{\\n \"uuid\": \"9190e370-dfa9-47a6-8cef-8df7ab762433\"\\n}\\n', '{\\n \"uuid\": \"83216551-9f1b-48b2-8cd6-fd125a7ce965\"\\n}\\n', '{\\n \"uuid\": \"aaddb98c-879b-472d-aa39-1a684ef7d179\"\\n}\\n', '{\\n \"uuid\": \"4bd7e2fd-1453-4433-aa9f-bc29d82f5b9d\"\\n}\\n', '{\\n \"uuid\": \"b02d65e8-2063-4060-96af-088ec497fc10\"\\n}\\n', '{\\n \"uuid\": \"e10e3dd2-83c5-4595-afe4-4145bce79193\"\\n}\\n', '{\\n \"uuid\": \"8cb62784-1b5d-4dcc-8342-02ad7d417ca9\"\\n}\\n', '{\\n \"uuid\": \"13ef1509-4f69-4426-ac42-cb29a2d0f094\"\\n}\\n', '{\\n \"uuid\": \"4d4571d5-69bb-4625-b246-b5eef50aa10d\"\\n}\\n', '{\\n \"uuid\": \"75e7a2ca-bfa8-43b9-b33a-f3f927453579\"\\n}\\n', '{\\n \"uuid\": \"0a8cc8ff-2039-4873-9e38-afad3e10d726\"\\n}\\n', '{\\n \"uuid\": \"189ae75b-4879-4897-9725-f9be17e49844\"\\n}\\n', '{\\n \"uuid\": \"ba482468-f45f-4060-a0c1-3ef31bb283c8\"\\n}\\n', '{\\n \"uuid\": \"3809f1c7-2f11-487d-bf96-8abf64e08298\"\\n}\\n', '{\\n \"uuid\": \"da5ea88b-974d-4238-9654-ac56c657c8b4\"\\n}\\n', '{\\n \"uuid\": \"edc3de79-7cf4-42a3-a5f4-b754136a6fd3\"\\n}\\n', '{\\n \"uuid\": \"6f5ecd91-537c-4009-8435-6c31ce035d36\"\\n}\\n', '{\\n \"uuid\": \"4a33b29d-78ba-468f-8f30-a01b3d9e2a87\"\\n}\\n', '{\\n \"uuid\": \"a5a2ef2d-d4a2-48e1-8335-f8c1309328c4\"\\n}\\n', '{\\n \"uuid\": \"3d1679da-afdd-4f04-9c16-0aaea4c53d0c\"\\n}\\n', '{\\n \"uuid\": \"c4025845-0d4c-4549-acb8-1a249b33e644\"\\n}\\n']\ntime: 1.0535461902618408\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nfrom time import sleep\nfrom time import time\nimport requests\nimport asyncio\n\napp = FastAPI()\n\nURL= \"http://httpbin.org/uuid\"\n\n\n# @app.get(\"/\")\nasync def main():\n r = requests.get(URL)\n # print(r.text)\n \n return r.text\n\nasync def task():\n tasks = [main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main(),main()]\n # print(tasks)\n # input(\"stop\")\n result = await asyncio.gather(*tasks)\n print (result)\n\n@app.get('/')\ndef f():\n start = time()\n asyncio.run(task())\n print(\"time: \",time()-start)\n```\n\n```text\nhttp://httpbin.org/uuid\n```\n\n```text\nmain\n```\n\n```text\nr.text\n```\n\n```text\nfrom fastapi import FastAPI\nfrom time import time\nimport httpx\nimport asyncio\n\napp = FastAPI()\n\nURL = \"http://httpbin.org/uuid\"\n\n\nasync def request(client):\n response = await client.get(URL)\n return response.text\n\n\nasync def task():\n async with httpx.AsyncClient() as client:\n tasks = [request(client) for i in range(100)]\n result = await asyncio.gather(*tasks)\n print(result)\n\n\n@app.get('/')\nasync def f():\n start = time()\n await task()\n print(\"time: \", time() - start)\n```\n\n```text\n['{\\n \"uuid\": \"65c454bf-9b12-4ba8-98e1-de636bffeed3\"\\n}\\n', '{\\n \"uuid\": \"03a48e56-2a44-48e3-bd43-a0b605bef359\"\\n}\\n',...\ntime: 0.5911855697631836\n```\n\n```text\nfrom fastapi import FastAPI\nfrom time import time\nimport aiohttp\nimport asyncio\n\napp = FastAPI()\n\nURL = \"http://httpbin.org/uuid\"\n\n\nasync def request(session):\n async with session.get(URL) as response:\n return await response.text()\n\n\nasync def task():\n async with aiohttp.ClientSession() as session:\n tasks = [request(session) for i in range(100)]\n result = await asyncio.gather(*tasks)\n print(result)\n\n\n@app.get('/')\nasync def f():\n start = time()\n await task()\n print(\"time: \", time() - start)\n```\n\n```text\nMAX_IN_PARALLEL = 10\nlimit_sem = asyncio.Semaphore(MAX_IN_PARALLEL)\n\n\nasync def request(client):\n async with limit_sem:\n response = await client.get(URL)\n return response.text\n```\n\n```text\nrequests\n```\n\n```text\nasyncio\n```\n\n```text\nhttpx\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\naiohttp\n```\n\n```text\nasyncio.semaphore\n```\n\n```text\nfrom time import time\nfrom typing import List\n\nfrom fastapi import FastAPI\nfrom httpx import AsyncClient\n\napp = FastAPI()\n\nURL = \"http://httpbin.org/uuid\"\nclient = AsyncClient()\n\n\nasync def main():\n r = await client.get(URL)\n return r.text\n\n\nasync def producer(queue: asyncio.Queue):\n await queue.put(main)\n\n\nasync def consumer(queue: asyncio.Queue, resp: List):\n # await queue.get() == main -> without arguments\n resp.append(await (await queue.get())())\n\n\nasync def task():\n q = asyncio.Queue(maxsize=100)\n response = []\n consumers = []\n producers = []\n [consumers.append(consumer(q, response)) for c in range(100)]\n [producers.append(producer(q)) for p in range(100)]\n\n await asyncio.gather(*producers)\n await asyncio.gather(*consumers)\n print(response)\n\n\n@app.get('/')\ndef f():\n start = time()\n asyncio.run(task())\n print(\"time: \", time() - start)\n\n\nif __name__ == '__main__':\n f()\n```\n\n```text\n['{\\n \"uuid\": \"a7713d07-ea5d-40d3-95b4-6673f3c50a8b\"\\n}\\n', '{\\n \"uuid\": \"c93f8b89-2c44-40fa-9e5f-736e22ad5f23\"\\n}\\n', '{\\n \"uuid\": \"cbb4ad76-7790-45ae-87f1-e425eddc8021\"\\n}\\n', '{\\n \"uuid\": \"4c1d81c0-ae7d-401a-99df-e98af3651335\"\\n}\\n', '{\\n \"uuid\": \"c5f70738-fbba-4cf9-8fdf-29f8b4eabe63\"\\n}\\n', '{\\n \"uuid\": \"d016b852-4312-4502-a336-a6a110237d1d\"\\n}\\n', '{\\n \"uuid\": \"22d8b00b-4266-4236-b5a3-ed5d7c5be416\"\\n}\\n', '{\\n \"uuid\": \"cd54fdbb-7de9-4df3-90cc-e6b108d5fdf8\"\\n}\\n', '{\\n \"uuid\": \"757f0a26-7896-4a04-bea2-60c66a38b05b\"\\n}\\n', '{\\n \"uuid\": \"72eb6584-21f4-449b-b6bd-d0f88666126f\"\\n}\\n', '{\\n \"uuid\": \"b3deadf5-5b79-491b-829c-0404c306cb68\"\\n}\\n', '{\\n \"uuid\": \"789e7422-493d-49d2-9585-e5ca34b7cf36\"\\n}\\n', '{\\n \"uuid\": \"48d29a82-ff7c-41f5-8af2-42784326a31f\"\\n}\\n', '{\\n \"uuid\": \"84b2d67c-331c-4037-b6e4-c299d93c1899\"\\n}\\n', '{\\n \"uuid\": \"386e79f9-073a-4f27-961c-7befcdf95cd4\"\\n}\\n', '{\\n \"uuid\": \"8dfdb5e4-dd69-4043-b174-48ec8505f36f\"\\n}\\n', '{\\n \"uuid\": \"633e634b-b107-42bb-a7d3-c6bbfff089a0\"\\n}\\n', '{\\n \"uuid\": \"962d665f-8663-4be7-a3c6-9426ba500bf4\"\\n}\\n', '{\\n \"uuid\": \"320fb858-a751-4c34-9cdb-ddd2f4e28efa\"\\n}\\n', '{\\n \"uuid\": \"46a75693-5255-4ac7-8d7a-54910b4d6f68\"\\n}\\n', '{\\n \"uuid\": \"5323734b-7ff9-455e-ba5a-66383e6b9a1f\"\\n}\\n', '{\\n \"uuid\": \"622a579f-35b6-4e4b-9dba-a8a69c2049c8\"\\n}\\n', '{\\n \"uuid\": \"593d5e82-cef3-4be0-99ab-e3034855d7a1\"\\n}\\n', '{\\n \"uuid\": \"80f139df-2a27-40c1-8329-e4faa035c45c\"\\n}\\n', '{\\n \"uuid\": \"a97e084c-4d30-4c7b-a96e-89ed00dcfe2a\"\\n}\\n', '{\\n \"uuid\": \"360d49eb-7222-4064-81c2-6eba2d43a9a5\"\\n}\\n', '{\\n \"uuid\": \"a81b6eab-a646-4e58-b986-96a90baa52aa\"\\n}\\n', '{\\n \"uuid\": \"0160337e-b400-41d6-ae89-aa46c5131f40\"\\n}\\n', '{\\n \"uuid\": \"e600722f-8c15-4959-948b-4c4e5296feb2\"\\n}\\n', '{\\n \"uuid\": \"f15403e4-3674-43b2-a0c9-649fd828ba7e\"\\n}\\n', '{\\n \"uuid\": \"36bf139c-cc18-45a8-bc55-e7f90ce290b5\"\\n}\\n', '{\\n \"uuid\": \"b2368a3c-d86b-4fcd-a0d3-bf7f8f657a83\"\\n}\\n', '{\\n \"uuid\": \"d9f16c36-3572-4c70-8a41-3d4e279d76bf\"\\n}\\n', '{\\n \"uuid\": \"796087cc-a202-40dd-9921-14802a73323d\"\\n}\\n', '{\\n \"uuid\": \"089fa0d7-4c48-4daa-a80d-cb5ebd37dfb7\"\\n}\\n', '{\\n \"uuid\": \"e5582bc7-0f8a-4da7-b640-79a0d812154d\"\\n}\\n', '{\\n \"uuid\": \"bac0640b-0d0b-4bf2-a3c1-36bdda7cce03\"\\n}\\n', '{\\n \"uuid\": \"b4353004-02b2-4846-8692-33dd77ad1d3f\"\\n}\\n', '{\\n \"uuid\": \"1b34a744-d0ea-4acf-8bda-33743800d86a\"\\n}\\n', '{\\n \"uuid\": \"4d9dd269-6ee2-4356-9bc4-ddf188445320\"\\n}\\n', '{\\n \"uuid\": \"a1f380df-0c0d-4aee-bbb7-c3e99fbfe54f\"\\n}\\n', '{\\n \"uuid\": \"7cb762eb-1a42-433d-97ea-aa9de4504e35\"\\n}\\n', '{\\n \"uuid\": \"981c40e2-64bf-4746-8103-9430bda2a5ca\"\\n}\\n', '{\\n \"uuid\": \"22b778eb-82d1-48b9-9874-5ebb80ddb8b1\"\\n}\\n', '{\\n \"uuid\": \"e7a9e0e8-7964-400c-aafe-9c36b9b7e1a0\"\\n}\\n', '{\\n \"uuid\": \"21a59b91-2732-4bb6-a47e-84008a03c20c\"\\n}\\n', '{\\n \"uuid\": \"a78eeb39-5ecb-4509-87c2-b4a2529e3536\"\\n}\\n', '{\\n \"uuid\": \"4a332579-ce03-4f69-9db5-78da9196d6b2\"\\n}\\n', '{\\n \"uuid\": \"55fbc34f-4eb3-4356-98e3-1df38054a4b2\"\\n}\\n', '{\\n \"uuid\": \"257ac454-09c2-4fd4-bdb3-303495360fa2\"\\n}\\n', '{\\n \"uuid\": \"7505cc0d-01b3-47f8-91d4-3e54d0f387de\"\\n}\\n', '{\\n \"uuid\": \"0fd67af2-622e-4688-b3c8-f64e20f1f3ec\"\\n}\\n', '{\\n \"uuid\": \"07653ccf-f408-4807-8ff5-e6098d657451\"\\n}\\n', '{\\n \"uuid\": \"b9d0ff18-fd67-4afa-adbe-ebcb53380804\"\\n}\\n', '{\\n \"uuid\": \"70d4d53b-2f06-41be-bb38-47f010cfa40f\"\\n}\\n', '{\\n \"uuid\": \"a6d49873-e749-4578-ae9c-e6c6f473535d\"\\n}\\n', '{\\n \"uuid\": \"e67efee5-76ad-4812-bb97-016ef9ff87e8\"\\n}\\n', '{\\n \"uuid\": \"67886926-b2d9-44fb-b836-26b81c53e5fb\"\\n}\\n', '{\\n \"uuid\": \"dcbd4ff8-e3cd-4e03-b12d-5fb3834b0e00\"\\n}\\n', '{\\n \"uuid\": \"65c2eaee-5fa2-4b58-a1c3-adeb04d92c71\"\\n}\\n', '{\\n \"uuid\": \"2cee4ec9-952e-45c5-91b7-f4f5848c3455\"\\n}\\n', '{\\n \"uuid\": \"8e94bf1c-ee5a-483a-a962-d0b9aea48c95\"\\n}\\n', '{\\n \"uuid\": \"c1fe17bc-bedf-4c4c-952d-a5921f693d9f\"\\n}\\n', '{\\n \"uuid\": \"221456fd-48ca-4826-a8b5-5fa0b23db6e4\"\\n}\\n', '{\\n \"uuid\": \"62fda759-b382-44e4-ad7d-d19a952fc1c7\"\\n}\\n', '{\\n \"uuid\": \"73faeb91-215e-4e49-8f11-11b98e499cc7\"\\n}\\n', '{\\n \"uuid\": \"f3279c45-ebcc-4079-b823-3efe825c7cf8\"\\n}\\n', '{\\n \"uuid\": \"b892672b-4510-44f4-b61e-9cccaa52421e\"\\n}\\n', '{\\n \"uuid\": \"8926979d-71a7-4171-9389-ddafff89e229\"\\n}\\n', '{\\n \"uuid\": \"d97cef59-4862-42ca-b0f2-261f98fd4b6f\"\\n}\\n', '{\\n \"uuid\": \"3362ff93-89e4-4889-a2f2-2e03771e86ce\"\\n}\\n', '{\\n \"uuid\": \"9f525251-4fe4-4a9c-97b5-2f01d2b37aaf\"\\n}\\n', '{\\n \"uuid\": \"036959d4-3179-40f9-bbf3-32274f2cede2\"\\n}\\n', '{\\n \"uuid\": \"157f8c22-6214-4e27-ab5d-08d39f96d1d3\"\\n}\\n', '{\\n \"uuid\": \"e4bfbf62-7c33-4fd7-a231-47f5ce398041\"\\n}\\n', '{\\n \"uuid\": \"a41512c1-3346-4457-a379-64d690ffc2ea\"\\n}\\n', '{\\n \"uuid\": \"7bb07cfb-294b-44fa-a8dc-6d283c54409f\"\\n}\\n', '{\\n \"uuid\": \"f2297d22-a2d0-47ff-8d65-24c6fe7877a7\"\\n}\\n', '{\\n \"uuid\": \"645e255b-4c93-4c8f-9ff2-43da293db660\"\\n}\\n', '{\\n \"uuid\": \"9190e370-dfa9-47a6-8cef-8df7ab762433\"\\n}\\n', '{\\n \"uuid\": \"83216551-9f1b-48b2-8cd6-fd125a7ce965\"\\n}\\n', '{\\n \"uuid\": \"aaddb98c-879b-472d-aa39-1a684ef7d179\"\\n}\\n', '{\\n \"uuid\": \"4bd7e2fd-1453-4433-aa9f-bc29d82f5b9d\"\\n}\\n', '{\\n \"uuid\": \"b02d65e8-2063-4060-96af-088ec497fc10\"\\n}\\n', '{\\n \"uuid\": \"e10e3dd2-83c5-4595-afe4-4145bce79193\"\\n}\\n', '{\\n \"uuid\": \"8cb62784-1b5d-4dcc-8342-02ad7d417ca9\"\\n}\\n', '{\\n \"uuid\": \"13ef1509-4f69-4426-ac42-cb29a2d0f094\"\\n}\\n', '{\\n \"uuid\": \"4d4571d5-69bb-4625-b246-b5eef50aa10d\"\\n}\\n', '{\\n \"uuid\": \"75e7a2ca-bfa8-43b9-b33a-f3f927453579\"\\n}\\n', '{\\n \"uuid\": \"0a8cc8ff-2039-4873-9e38-afad3e10d726\"\\n}\\n', '{\\n \"uuid\": \"189ae75b-4879-4897-9725-f9be17e49844\"\\n}\\n', '{\\n \"uuid\": \"ba482468-f45f-4060-a0c1-3ef31bb283c8\"\\n}\\n', '{\\n \"uuid\": \"3809f1c7-2f11-487d-bf96-8abf64e08298\"\\n}\\n', '{\\n \"uuid\": \"da5ea88b-974d-4238-9654-ac56c657c8b4\"\\n}\\n', '{\\n \"uuid\": \"edc3de79-7cf4-42a3-a5f4-b754136a6fd3\"\\n}\\n', '{\\n \"uuid\": \"6f5ecd91-537c-4009-8435-6c31ce035d36\"\\n}\\n', '{\\n \"uuid\": \"4a33b29d-78ba-468f-8f30-a01b3d9e2a87\"\\n}\\n', '{\\n \"uuid\": \"a5a2ef2d-d4a2-48e1-8335-f8c1309328c4\"\\n}\\n', '{\\n \"uuid\": \"3d1679da-afdd-4f04-9c16-0aaea4c53d0c\"\\n}\\n', '{\\n \"uuid\": \"c4025845-0d4c-4549-acb8-1a249b33e644\"\\n}\\n']\ntime: 1.0535461902618408\n```\n\n```text\nasync def async_request(url,payload,**kwargs): \n return await asyncio.to_thread(requests.post,url,payload)\n\nasync def main():\n await async_request(url,payload)\n```\n\n========================================\n\nComments:\n- even with curl i'm getting 0.111 ms for 100 requests `time for _ in {1..100}; do curl http://httpbin.org/uuid & done` this is pretty weird.\n- it's because each curl is splitting into a different process but the same thing is not working in my code - imgur.com/a/pmh7qLb `time for _ in {1..100}; do curl http://httpbin.org/uuid & done && ps aux | grep curl`\n- IKR i was talking about this, asyncio should behave exactly like curl, i tried on my machine with different approach that didn't worked out too, then i thinked about uvicorn is just an another event loop maybe it's the issue, after that i ran it normally, also it took so long tho..\n- Also i'm using this pattern for asyncio, which looks pretty solid for me, i created a gist you might want to check it out\n- My machine died thrice even for range(10).\n- So, a combination of asyncio and aiohttp would help in the case of URL request scenarios?\n- You could also try python-httpx.org . Create an AsyncClient with the base url, then use the client (equivalent of a `request` session) to perform 100 calls to the url\n- @johnmich hey, i needed to use my gist again, then I found I used `main()` inside main, it should be working as expected now, sorry for killing your machine :(\n- You might want to create a single session in `task` and pass it to `main()`. That will allow aiohttp to be more efficient by e.g. reusing TCP connections.\n- @any reason to use httpx? versus aiohttp? I ask because httpx is considered to be in beta version, so in production, you want the \"more\" stable one, thx\n- @AlexJolig the page you've linked to is dated 2021-04-17. This answer is dated 2020-09-14. The page's title is identical to this question. Perhaps you should direct your remark to the maintainer of that site, and retract your accusation towards this answer's author.\n- Future readers should find this answer and this answer helpful as well.\n- Can you explain how is this code faster than in the other answer? In the example there are couple programming flaws one might want to avoid, like appending an item to an external list inside a comprehension list instead of using the comprehension list directly. Also the code will hang forever when `q`'s `maxsize` is below 100, as the producers will eventually hang on `queue.put()` and so the `gather(*producers)` never completes. You'd have to schedule the two gathers as independent tasks, but that's not happening here. Downvoted.\n- what problem are you solving?","metadata":{"transformedAt":"2026-08-18T18:32:29.085Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":18,"totalLines":338,"estimatedTokens":5475}}23{"id":"stack-63511413","source":"stackoverflow","questionId":63511413,"title":"FastAPI redirection for trailing slash returns non-SSL link","tags":["python","fastapi","uvicorn"],"text":"Title: FastAPI redirection for trailing slash returns non-SSL link\nTags: python, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nWhen we call an endpoint and a redirect occurs due to a missing trailing slash. As you can see in the image below, when a request is made to `https://.../notifications`, the FastAPI server responds with a redirect to `http://.../notifications/`\n\nI suspect that it's an app configuration issue rather than a server configuration issue. Does anyone have an idea of how to resolve this issue?\n\nhttps://i.sstatic.net/l0hc7.png\n\n========================================\n\nTop Answer:\nI experienced this issue when using FastAPI with react-admin.\n\nOne workaround is to change FastAPI app so it doesn't make redirects, but treats both URLs as valid API endpoints (with and without slash).\n\nYou can use this snippet wrote by malthunayan to change behaviour of `APIRouter`:\n\n```\nfrom typing import Any, Callable\n\nfrom fastapi import APIRouter as FastAPIRouter\nfrom fastapi.types import DecoratedCallable\n\nclass APIRouter(FastAPIRouter):\n def api_route(\n self, path: str, *, include_in_schema: bool = True, **kwargs: Any\n ) -> Callable[[DecoratedCallable], DecoratedCallable]:\n if path.endswith(\"/\"):\n path = path[:-1]\n\n add_path = super().api_route(\n path, include_in_schema=include_in_schema, **kwargs\n )\n\n alternate_path = path + \"/\"\n add_alternate_path = super().api_route(\n alternate_path, include_in_schema=False, **kwargs\n )\n\n def decorator(func: DecoratedCallable) -> DecoratedCallable:\n add_alternate_path(func)\n return add_path(func)\n\n return decorator\n```\n\nsource: https://github.com/tiangolo/fastapi/issues/2060#issuecomment-834868906\n\n(you can also see other similar solutions in this GitHub issue)\n\nAnother workaround is to add:\n\n```\n\n```\n\nto `index.html` file in frontend. It will upgrade all requests from `http` to `https` (also when run locally, so it may not be the best workaround)\n\n========================================\n\nCode:\n```text\nhttps://.../notifications\n```\n\n```text\nhttp://.../notifications/\n```\n\n```text\nX-Forwarded-Proto\n```\n\n```text\nuvicorn\n```\n\n```text\n--forwarded-allow-ips '*'\n```\n\n```text\ngunicorn\n```\n\n```text\n--forwarded-allow-ips=\"*\"\n```\n\n```text\nFORWARDED_ALLOW_IPS\n```\n\n```text\n*\n```\n\n```text\nX-Forwarded-*\n```\n\n```py\nfrom typing import Any, Callable\n\nfrom fastapi import APIRouter as FastAPIRouter\nfrom fastapi.types import DecoratedCallable\n\n\nclass APIRouter(FastAPIRouter):\n def api_route(\n self, path: str, *, include_in_schema: bool = True, **kwargs: Any\n ) -> Callable[[DecoratedCallable], DecoratedCallable]:\n if path.endswith(\"/\"):\n path = path[:-1]\n\n add_path = super().api_route(\n path, include_in_schema=include_in_schema, **kwargs\n )\n\n alternate_path = path + \"/\"\n add_alternate_path = super().api_route(\n alternate_path, include_in_schema=False, **kwargs\n )\n\n def decorator(func: DecoratedCallable) -> DecoratedCallable:\n add_alternate_path(func)\n return add_path(func)\n\n return decorator\n```\n\n```html\n<meta http-equiv=\"Content-Security-Policy\" content=\"upgrade-insecure-requests\">\n```\n\n```text\nAPIRouter\n```\n\n```text\nindex.html\n```\n\n```text\nhttp\n```\n\n```text\nhttps\n```\n\n```text\nimport { environment } from './environments/environment';\n\nif (environment.production) {\n const meta = document.createElement('meta');\n meta.httpEquiv = \"Content-Security-Policy\";\n meta.content=\"upgrade-insecure-requests\";\n document.head.appendChild(meta);\n}\n```\n\n```py\nfrom fastapi import FastAPI, APIRouter\n\n\nhealthcheck_router = APIRouter(redirect_slashes=False)\n\n\n@healthcheck_router.get('/')\nasync def healtcheck() -> dict:\n return {'state': 'healthy'}\n\n\ndef create_app() -> FastAPI:\n app = FastAPI(redirect_slashes=False)\n return app.include_router(healthcheck_router, prefix='/api/health')\n```\n\n```py\nimport pytest\nfrom starlette.testclient import TestClient\n\nfrom app import create_app\n\n\n@pytest.fixture\ndef test_client() -> TestClient:\n app = create_app()\n return TestClient(app=app)\n\n\ndef test_healthcheck_returns_200(test_client: TestClient):\n response = test_client.get('/api/health/')\n\n assert response.status_code == 200\n\n\ndef test_healthcheck_without_trailing_slash_returns_404(test_client: TestClient):\n response = test_client.get('/api/health')\n\n assert response.status_code == 404\n```\n\n```text\nredirect_slashes\n```\n\n```text\nFalse\n```\n\n```text\nTrue\n```\n\n========================================\n\nComments:\n- In your code, do you use @app.get(\"notifications\") or @app.get(\"notifications/\") ? Also, have you tried fastapi.tiangolo.com/advanced/middleware/… maybe it helps setting the https response\n- It seemed like the HTTPSRedirect wouldn't solve the issue as the incoming request was in the correct schema. The way I understood the documentation was to provide the functionality: http (incoming request) -> https (redirected request). This seems to be https (incoming request) -> http (redirected request). Perhaps I'm misguided, though, so I'm testing right now...\n- The redirect could be due to difference in path (the @app.get stuff) and the requested path. Do you mind sharing the code of the handling function and the one for performing the request?\n- Did you ever resolve this problem? I'm having the problem right now as well. This issue might be relevant but adding the \"--prefix-headers\" to the uvicorn call didn't resolve the issue for me. github.com/encode/starlette/issues/538\n- Are you guys running your server behind a reverse proxy? @Ben\n- @gustavo-kawamoto yes we are\n- the meta tag solved it for me using FastAPI and Uvicron.\n- This fixed my problem with redirects. Thanks\n- Can you add more info on why you preferred changing that on FastAPI instead of gunicorn/uvicorn? It's good practice to add reasons and then link, as links might die and leave the answer stranded.\n- Thanks for your comment. I included *my* main reason in the answer. But I think the main value here is to add this important alternative (including code snippets, tests and links to the relevant docs) to the mix, to allow others make their own informed decision.\n- Thanks for adding it! It's also super fine to add links to enrich your point, just wanted to make sure the answer I wanted to upvote wouldn't go down the drain if anything happened to the link ;)\n- Agreed with you. Strict behavior looks better. But in our team we decide to use endpoints without trailing slashes. What is your agrument to use trailing slash everywhere?\n- @broomrider: we don't use trailing slashes, too, but this answer and my blog post align with the official docs. \"Slash or not to slash\" is another more opinionated topic ;)","metadata":{"transformedAt":"2026-08-18T18:32:29.086Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":22,"totalLines":235,"estimatedTokens":1684}}24{"id":"stack-70351360","source":"stackoverflow","questionId":70351360,"title":"Keep getting \"307 Temporary Redirect\" before returning status 200 hosted on FastAPI + uvicorn + Docker app - how to return status 200?","tags":["python","http-redirect","fastapi","http-status-code-307"],"text":"Title: Keep getting \"307 Temporary Redirect\" before returning status 200 hosted on FastAPI + uvicorn + Docker app - how to return status 200?\nTags: python, http-redirect, fastapi, http-status-code-307\nSource: Stack Overflow\n\nQuestion:\nEdit:\n\nI found the problem but not sure why this happens. Whenever I query: `http://localhost:4001/hello/` with the \"`/`\" in the end - I get a proper 200 status response.\nI do not understand why.\n\nOriginal Post:\n\nWhenever I send a query to my app - I keep getting a 307 redirect.\nHow to get my app to return regular status 200 instead of redirecting it through 307\n\nThis is the request output:\n\n```\nabm | INFO: 172.18.0.1:46476 - \"POST /hello HTTP/1.1\" 307 Temporary Redirect\nabm | returns the apples data. nothing special here.\nabm | INFO: 172.18.0.1:46480 - \"POST /hello/ HTTP/1.1\" 200 OK\n```\n\npytest returns:\n\n```\nE assert 307 == 200\nE + where 307 = .status_code\n\ntest_main.py:24: AssertionError\n```\n\nin my root dir: `/__init__.py` file:\n\n```\nfrom fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware\n# from .configs import cors\nfrom .subapp import router_hello\nfrom .potato import router_potato\nfrom .apple import router_apple\n\nabm = FastAPI(\n title = \"ABM\"\n)\n\n# potato.add_middleware(cors)\nabm.add_middleware(\n CORSMiddleware,\n allow_origins=[\"*\"],\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n\nabm.include_router(router_hello.router)\nabm.include_router(router_potato.router)\nabm.include_router(router_apple.router)\n\n@abm.post(\"/test\", status_code = 200)\ndef test():\n print('test')\n return 'test'\n```\n\n`/subapp/router_hello.py` file:\n\n```\nrouter = APIRouter(\n prefix='/hello',\n tags=['hello'],\n)\n\n@router.post(\"/\", status_code = 200)\ndef hello(req: helloBase, apple: appleHeader = Depends(set_apple_header), db: Session = Depends(get_db)) -> helloResponse:\n db_apple = apple_create(apple, db, req.name)\n if db_apple:\n return set_hello_res(db_apple.potato.api, db_apple.name, 1)\n else:\n return \"null\"\n```\n\nin `/Dockerfile`:\n\n```\nCMD [\"uvicorn\", \"abm:abm\", \"--reload\", \"--proxy-headers\", \"--host\", \"0.0.0.0\", \"--port\", \"4001\", \"--forwarded-allow-ips\", \"*\", \"--log-level\", \"debug\"]\n```\n\nI tried with and without `\"--forwarded-allow-ips\", \"*\"` part.\n\n========================================\n\nTop Answer:\nHere's a TL;DR solution: use `redirect_slashes=False` to disable redirect\n\n```\nabm = FastAPI(\n title = \"ABM\",\n redirect_slashes=False\n)\n```\n\n========================================\n\nCode:\n```text\nabm | INFO: 172.18.0.1:46476 - \"POST /hello HTTP/1.1\" 307 Temporary Redirect\nabm | returns the apples data. nothing special here.\nabm | INFO: 172.18.0.1:46480 - \"POST /hello/ HTTP/1.1\" 200 OK\n```\n\n```text\nE assert 307 == 200\nE + where 307 = <Response [307]>.status_code\n\ntest_main.py:24: AssertionError\n```\n\n```text\nfrom fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware\n# from .configs import cors\nfrom .subapp import router_hello\nfrom .potato import router_potato\nfrom .apple import router_apple\n\n\nabm = FastAPI(\n title = \"ABM\"\n)\n\n# potato.add_middleware(cors)\nabm.add_middleware(\n CORSMiddleware,\n allow_origins=[\"*\"],\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n\nabm.include_router(router_hello.router)\nabm.include_router(router_potato.router)\nabm.include_router(router_apple.router)\n\n@abm.post(\"/test\", status_code = 200)\ndef test():\n print('test')\n return 'test'\n```\n\n```text\nrouter = APIRouter(\n prefix='/hello',\n tags=['hello'],\n)\n\n@router.post(\"/\", status_code = 200)\ndef hello(req: helloBase, apple: appleHeader = Depends(set_apple_header), db: Session = Depends(get_db)) -> helloResponse:\n db_apple = apple_create(apple, db, req.name)\n if db_apple:\n return set_hello_res(db_apple.potato.api, db_apple.name, 1)\n else:\n return \"null\"\n```\n\n```text\nCMD [\"uvicorn\", \"abm:abm\", \"--reload\", \"--proxy-headers\", \"--host\", \"0.0.0.0\", \"--port\", \"4001\", \"--forwarded-allow-ips\", \"*\", \"--log-level\", \"debug\"]\n```\n\n```text\nhttp://localhost:4001/hello/\n```\n\n```text\n/\n```\n\n```text\n/__init__.py\n```\n\n```text\n/subapp/router_hello.py\n```\n\n```text\n/Dockerfile\n```\n\n```text\n\"--forwarded-allow-ips\", \"*\"\n```\n\n```text\nyourdomainname/hello/\n```\n\n```text\n/\n```\n\n```text\n/\n```\n\n```text\nstatus code 307\n```\n\n```text\nfunction/view\n```\n\n```text\nstatus code 200\n```\n\n```text\nabm = FastAPI(\n title = \"ABM\",\n redirect_slashes=False\n)\n```\n\n```text\nredirect_slashes=False\n```\n\n```text\nfastapi\n```\n\n```text\nfastapi\n```\n\n```text\n0.109.0\n```\n\n```text\n0.123.3\n```\n\n========================================\n\nComments:\n- +1. for some odd reason when I was testing my API locally it was fine, but when deployed to AWS Lambda, i was getting infinite redirects. Thanks!\n- Since this is an issue with FastAPI in my case, I just removed the '/' at the end, and it solved my issue. Not sure whether everyone can do that :) FYI, locally, this works just fine; the issue arises when we deploy to AWS Lambda.\n- Also check out this post github.com/fastapi/fastapi/discussions/… regarding redirect behind nginx.","metadata":{"transformedAt":"2026-08-18T18:32:29.086Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":23,"totalLines":250,"estimatedTokens":1287}}25{"id":"stack-60098005","source":"stackoverflow","questionId":60098005,"title":"FastAPI (starlette) get client real IP","tags":["python","fastapi","x-forwarded-for","starlette"],"text":"Title: FastAPI (starlette) get client real IP\nTags: python, fastapi, x-forwarded-for, starlette\nSource: Stack Overflow\n\nQuestion:\nI have an API on FastAPI and i need to get the client real IP address when he request my page.\n\nI'm ty to use starlette Request. But it returns my server IP, not client remote IP.\n\nMy code:\n\n```\n@app.post('/my-endpoint')\nasync def my_endpoint(stats: Stats, request: Request):\n ip = request.client.host\n print(ip)\n return {'status': 1, 'message': 'ok'}\n```\n\nWhat i'm doing wrong? How to get real IP (like in Flask request.remote_addr)?\n\n========================================\n\nTop Answer:\nThe FastAPI using-request-directly doc page shows this example:\n\n```\nfrom fastapi import FastAPI, Request\n\napp = FastAPI()\n\n@app.get(\"/items/{item_id}\")\ndef read_root(item_id: str, request: Request):\n client_host = request.client.host\n return {\"client_host\": client_host, \"item_id\": item_id}\n```\n\nHaving had this example would have saved me ten minutes of mussing with Starlette's Request class\n\n========================================\n\nCode:\n```text\n@app.post('/my-endpoint')\nasync def my_endpoint(stats: Stats, request: Request):\n ip = request.client.host\n print(ip)\n return {'status': 1, 'message': 'ok'}\n```\n\n```text\nrequest.client\n```\n\n```text\n--proxy-headers\n```\n\n```text\nserver {\n # the port your site will be served on\n listen 80;\n # the domain name it will serve for\n server_name <your_host_name>; # substitute your machine's IP address or FQDN\n\n# add_header Access-Control-Allow-Origin *;\n # add_header Access-Control-Allow-Credentials: true;\n add_header Access-Control-Allow-Headers Content-Type,XFILENAME,XFILECATEGORY,XFILESIZE;\n add_header access-control-allow-headers authorization;\n # Finally, send all non-media requests to the Django server.\n location / {\n proxy_pass http://127.0.0.1:8000/; # the uvicorn server address\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n }\n}\n```\n\n```text\nThis middleware can be applied to add HTTP proxy support to an\napplication that was not designed with HTTP proxies in mind. It\nsets REMOTE_ADDR, HTTP_HOST from X-Forwarded headers. While\nWerkzeug-based applications already can use\n:py:func:werkzeug.wsgi.get_host to retrieve the current host even if\nbehind proxy setups, this middleware can be used for applications which\naccess the WSGI environment directly。\nIf you have more than one proxy server in front of your app, set\nnum_proxies accordingly.\nDo not use this middleware in non-proxy setups for security reasons.\nThe original values of REMOTE_ADDR and HTTP_HOST are stored in\nthe WSGI environment as werkzeug.proxy_fix.orig_remote_addr and\nwerkzeug.proxy_fix.orig_http_host\n:param app: the WSGI application\n:param num_proxies: the number of proxy servers in front of the app.\n```\n\n```text\nproxy-headers\n```\n\n```text\nHost\n```\n\n```text\nX-Real-IP\n```\n\n```text\nX-Forwarded-For\n```\n\n```text\n--proxy-headers\n```\n\n```text\n--forwarded-allow-ips='*'\n```\n\n```text\nfrom fastapi import FastAPI, Request\n\napp = FastAPI()\n\n\n@app.get(\"/items/{item_id}\")\ndef read_root(item_id: str, request: Request):\n client_host = request.client.host\n return {\"client_host\": client_host, \"item_id\": item_id}\n```\n\n```text\n@app.post('/my-endpoint')\nasync def my_endpoint(stats: Stats, request: Request):\n x = 'x-forwarded-for'.encode('utf-8')\n for header in request.headers.raw:\n if header[0] == x:\n print(\"Find out the forwarded-for ip address\")\n origin_ip, forward_ip = re.split(', ', header[1].decode('utf-8'))\n print(f\"origin_ip:\\t{origin_ip}\")\n print(f\"forward_ip:\\t{forward_ip}\")\n return {'status': 1, 'message': 'ok'}\n```\n\n```text\n--proxy-headers\n```\n\n```text\n--forwarded-allow-ips\n```\n\n```text\n127.0.0.1\n```\n\n```text\n'*'\n```\n\n```text\n--forwarded-allow-ips='[::1]'\n```\n\n```text\n--forwarded-allow-ips='127.0.0.1,[::1]'\n```\n\n```text\n--proxy-headers / --no-proxy-headers\n```\n\n```text\n--forwarded-allow-ips\n```\n\n```text\nlocation / {\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_pass http://localhost:8000;\n}\n```\n\n```text\nEXPOSE 8000\n\nCMD [\"uvicorn\", \"app.main:app\", \"--host\", \"0.0.0.0\"]\n```\n\n```text\nversion: \"3.7\"\nservices:\n app:\n build: ./fastapi\n container_name: ipinfo\n restart: always\n ports:\n - \"8000:8000\"\n network_mode: host\n\n nginx:\n build: ./nginx\n container_name: nginx\n restart: always\n ports:\n - \"80:80\"\n - \"443:443\"\n network_mode: host\n```\n\n```py\nfrom fastapi import FastAPI, Header\n\napp = FastAPI()\n\n@app.get(\"/API/path1\")\ndef path1(X_Forwarded_For: Optional[str] = Header(None)):\n print(\"X_Forwarded_For:\",X_Forwarded_For)\n return { \"X_Forwarded_For\":X_Forwarded_For }\n```\n\n```text\nuvicorn launch1:app --port 5010 --host 0.0.0.0 --root-path /site1\n```\n\n```text\nProxyPreserveHost On\n\n ProxyPass /site1/ http://127.0.0.1:5010/\n ProxyPassReverse /site1/ http://127.0.0.1:5010/\n```\n\n```text\na2enmod proxy_http\nsystemctl restart apache2\n```\n\n```text\nX_Forwarded_For\n```\n\n```text\nlaunch1.py\n```\n\n```text\n@app.get\n```\n\n```text\nlocation /api/ {\n proxy_pass http://backend:8000/;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n}\n```\n\n```text\n- FORWARDED_ALLOW_IPS=*\n```\n\n```text\nfrom fastapi import FastAPI, Depends, Header\n\napp = FastAPI()\n\n@app.get('/')\ndef index(real_ip: str = Header(None, alias='X-Real-IP')):\nreturn real_ip\n```\n\n```text\nHTTP/1.1 200 OK\ncontent-length: 17 \ncontent-type: application/json\nserver: uvicorn\n```\n\n```text\nlocation /api {\n include proxy_params;\n proxy_pass http://localhost:8000;\n}\n```\n\n```text\nproxy_params file\n```\n\n========================================\n\nComments:\n- That is correct, but do notice also the comment of @RcoderNY I would like to confirm this answer with my case described here github.com/tiangolo/full-stack-fastapi-postgresql/issues/…\n- upstream uvicorn { server unix:/tmp/uvicorn.sock; } Don't we add this one? Its in documentation\n- For security reason only use **--forwarded-allow-ips='*'** for testing. Later for production system we need to specify the ips of the actual proxies explicitly.\n- In my case, it only shows my IPv6. But how do I obtain both IPv4 and IPv6?\n- @Houman, you don't. IP4 and IP6 are totally seperate, and if a connection is made over IPv6, there's no way to know the corresponding IP4-address. In fact, in principle it's possible that the client doesn't even *have* an IP4-address. To use an old-fashioned analogy, it's like asking how to get the phonenumber for voicecalls from someone, if you got a fax from them.\n- @EmilBode If you open websites like ipleak.net, they show both.\n- @Houman, not always. In my case, behind a proxy, I only see an IP4-address. The thing to realise, is that services like that can afford to apply complicated tricks where they use multiple connections. But if you only have one (like with FastAPI), there's only one IP-address applicable. To get back to the analogy of a fax, I'm sure it's quite easy to find a telephonenumber of a company of which you have a fax-number. But that doesn't mean fax and telephone are always inextricably linked\n- What to do in case of Apache?\n- Use `Header(None, alias='x-forwarded-for')` instead of `Header(None, alias='X-Real-IP')` worked for me.","metadata":{"transformedAt":"2026-08-18T18:32:29.086Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":37,"totalLines":306,"estimatedTokens":1906}}26{"id":"stack-63616798","source":"stackoverflow","questionId":63616798,"title":"How to pass the default value to a variable if None was passed?","tags":["python","fastapi","pydantic"],"text":"Title: How to pass the default value to a variable if None was passed?\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nCan I make a default value in Pydantic if None is passed in the field?\n\nI have the following code, but it seems to me that the validator here only works on initialization of the model and not otherwise.\n\n**My Code:**\n\n```\nclass User(BaseModel):\n name: Optional[str] = ''\n password: Optional[str] = ''\n email: EmailStr\n \n\n @validator('name')\n def set_name(cls, name):\n return name or 'foo'\n```\n\n**Problem Encountered:**\n\n```\nuser = User(name=None, password='some_password', email='user@example.com')\nprint(\"Name is \", user.name)\n# > 'Name is foo'\n\nuser.name = None\nprint(\"Name is \", user.name)\n# > 'Name is None'\n```\n\n**Desired Output:**\n\n```\nuser = User(name='some_name', password='some_password', email='user@example.com')\nuser.name = None\nprint(\"Name is \", user.name)\n# > 'Name is foo'\n```\n\nAny ideas on how I can obtain the desired output? I think having getters and setters will help in tackling the issue. However, I could not get them to work in a Pydantic model:\n\n**Attempting to implement getters and setters:**\n\n```\nclass User(BaseModel):\n name: Optional[str] = ''\n password: Optional[str] = ''\n email: EmailStr\n\n def get_password(self):\n return self.password\n\n def set_password(self, password):\n self.password = hash_password(password)\n\n password = property(get_password, set_password)\n\nuser = User(name='some_name', password='some_password', email='user@example.com')\n# > RecursionError: maximum recursion depth exceeded\n```\n\n**I also tried the property decorator:**\n\n```\nclass User(BaseModel):\n name: Optional[str] = ''\n password: Optional[str] = ''\n email: EmailStr\n\n @property\n def password(self):\n return self._password\n\n @password.setter\n def password(self, password):\n pwd_context = CryptContext(schemes=[\"bcrypt\"], deprecated=\"auto\")\n self._password = pwd_context.hash(password)\n\nuser = User(name='some_name', email='user@example.com')\nuser.password = 'some_password'\n# > ValueError: \"User\" object has no field \"password\"\n```\n\n**I also tried overwriting the init**:\n\n```\nclass User(BaseModel):\nname: Optional[str] = \"\"\npassword: Optional[str] = \"\"\nemail: EmailStr\n\ndef __init__(self, name, password, email):\n pwd_context = CryptContext(schemes=[\"bcrypt\"], deprecated=\"auto\")\n password = pwd_context.hash(password)\n super().__init__(name=name, password=password, email=email)\n\nuser = User(name=\"some_name\", password=\"some_password\", email='user@example.com')\nprint(user.password)\n# > AYylwSnbQgCHrl4uue6kO7yiuT20lazSzK7x # Works as expected\n\nuser.password = \"some_other_password\"\nprint(user.password)\n# > \"some_other_password\" # Does not work\n\nuser.password = None\nprint(user.password)\n# > None # Does not work either\n```\n\n========================================\n\nTop Answer:\n**This question asked perfectly so i wanted to provide a wider example, because there are many ways to assign a value dynamically.**\n\nAlex's answer is correct but it only works on when the Field directly inherits a dataclass more specifically something like this won't work.\n\n```\nclass User(BaseModel):\n name: Optional[str] = \"\"\n password: Optional[str] = \"\"\n\n class Config:\n validate_assignment = True\n\n @validator(\"name\")\n def set_name(cls, name):\n return name or \"bar\"\n\nuser_dict = {\"password\": \"so_secret\"}\nuser_one = User(**user_dict)\nOut: name='' password='so_secret'\n```\n\n### Validate Always\n\nFor performance reasons, by default validators are not called for fields when a value is not supplied. But situations like this when you need to set a **Dynamic Default Value** we can set that to **True**\n\n```\nclass User(BaseModel):\n name: Optional[str] = \"\"\n\n @validator(\"name\", pre=True, always=True)\n def set_name(cls, name):\n return name or \"bar\"\n\nIn: user_one = User(name=None)\nIn: user_two = User()\nOut: name='bar'\nOut: name='bar'\n```\n\nBut there is a one important catch with always, since we are using always=True pydantic would try to validate the default None which would cause an error.\n\nSetting Pre to **`True`** it will call that field before validation error occurs, the default of a validator pre is set to **`False`** , in which case they're called after field validation.\n\n### Using Config\n\nBut this has some disadvantages.\n\n```\nclass User(BaseModel):\n name: Optional[str] = \"\"\n\n class Config:\n validate_assignment = True\n\n @validator(\"name\")\n def set_name(cls, name):\n return name or \"foo\"\n\nIn: user = User(name=None)\nOut: name='foo'\n```\n\nWhen you set it to None it returns the dynamic value correctly but some situations like it is completely **`None`**, it fails.\n\n```\nIn: user = User()\nOut: name=''\n```\n\nAgain you need to set, to make that work.\n\n```\npre=True\nalways=True\n```\n\n### Using `default_factory`\n\nThis is mostly useful in cases when you want to set a default value, like UUID or datetime etc. In that cases you might want to use **`default_factory`**, but there is a big catch you can't assign a `Callable` argument to the default_factory.\n\n```\nclass User(BaseModel):\n created_at: datetime = Field(default_factory=datetime.now)\n\nIn: user = User()\nOut: created_at=datetime.datetime(2020, 8, 29, 2, 40, 12, 780986)\n```\n\n========================================\n\nCode:\n```text\nclass User(BaseModel):\n name: Optional[str] = ''\n password: Optional[str] = ''\n email: EmailStr\n \n\n @validator('name')\n def set_name(cls, name):\n return name or 'foo'\n```\n\n```text\nuser = User(name=None, password='some_password', email='user@example.com')\nprint(\"Name is \", user.name)\n# > 'Name is foo'\n\nuser.name = None\nprint(\"Name is \", user.name)\n# > 'Name is None'\n```\n\n```text\nuser = User(name='some_name', password='some_password', email='user@example.com')\nuser.name = None\nprint(\"Name is \", user.name)\n# > 'Name is foo'\n```\n\n```text\nclass User(BaseModel):\n name: Optional[str] = ''\n password: Optional[str] = ''\n email: EmailStr\n\n def get_password(self):\n return self.password\n\n def set_password(self, password):\n self.password = hash_password(password)\n\n password = property(get_password, set_password)\n\nuser = User(name='some_name', password='some_password', email='user@example.com')\n# > RecursionError: maximum recursion depth exceeded\n```\n\n```text\nclass User(BaseModel):\n name: Optional[str] = ''\n password: Optional[str] = ''\n email: EmailStr\n\n @property\n def password(self):\n return self._password\n\n @password.setter\n def password(self, password):\n pwd_context = CryptContext(schemes=[\"bcrypt\"], deprecated=\"auto\")\n self._password = pwd_context.hash(password)\n\nuser = User(name='some_name', email='user@example.com')\nuser.password = 'some_password'\n# > ValueError: \"User\" object has no field \"password\"\n```\n\n```text\nclass User(BaseModel):\nname: Optional[str] = \"\"\npassword: Optional[str] = \"\"\nemail: EmailStr\n\ndef __init__(self, name, password, email):\n pwd_context = CryptContext(schemes=[\"bcrypt\"], deprecated=\"auto\")\n password = pwd_context.hash(password)\n super().__init__(name=name, password=password, email=email)\n\n\nuser = User(name=\"some_name\", password=\"some_password\", email='user@example.com')\nprint(user.password)\n# > AYylwSnbQgCHrl4uue6kO7yiuT20lazSzK7x # Works as expected\n\nuser.password = \"some_other_password\"\nprint(user.password)\n# > \"some_other_password\" # Does not work\n\nuser.password = None\nprint(user.password)\n# > None # Does not work either\n```\n\n```text\nfrom typing import Optional\n\nfrom pydantic import BaseModel, validator\n\n\nclass User(BaseModel):\n name: Optional[str] = ''\n password: Optional[str] = ''\n\n class Config:\n validate_assignment = True\n\n @validator('name')\n def set_name(cls, name):\n return name or 'foo'\n\n\nuser = User(name=None, password='some_password', )\nprint(\"Name is \", user.name)\n\n\nuser.name = None\nprint(\"Name is \", user.name)\n```\n\n```text\nName is foo\nName is foo\n```\n\n```text\nvalidate_assignment\n```\n\n```text\nclass User(BaseModel):\n name: Optional[str] = \"\"\n password: Optional[str] = \"\"\n\n class Config:\n validate_assignment = True\n\n @validator(\"name\")\n def set_name(cls, name):\n return name or \"bar\"\n\n\nuser_dict = {\"password\": \"so_secret\"}\nuser_one = User(**user_dict)\nOut: name='' password='so_secret'\n```\n\n```text\nclass User(BaseModel):\n name: Optional[str] = \"\"\n\n @validator(\"name\", pre=True, always=True)\n def set_name(cls, name):\n return name or \"bar\"\n\nIn: user_one = User(name=None)\nIn: user_two = User()\nOut: name='bar'\nOut: name='bar'\n```\n\n```text\nclass User(BaseModel):\n name: Optional[str] = \"\"\n\n class Config:\n validate_assignment = True\n\n @validator(\"name\")\n def set_name(cls, name):\n return name or \"foo\"\n\nIn: user = User(name=None)\nOut: name='foo'\n```\n\n```text\nIn: user = User()\nOut: name=''\n```\n\n```text\npre=True\nalways=True\n```\n\n```text\nclass User(BaseModel):\n created_at: datetime = Field(default_factory=datetime.now)\n\nIn: user = User()\nOut: created_at=datetime.datetime(2020, 8, 29, 2, 40, 12, 780986)\n```\n\n```text\nTrue\n```\n\n```text\nFalse\n```\n\n```text\nNone\n```\n\n```text\ndefault_factory\n```\n\n```text\ndefault_factory\n```\n\n```text\nCallable\n```\n\n```py\nclass User(BaseModel):\n id: str = uuid.uuid4()\n```\n\n```py\nclass User(BaseModel):\n id: Optional[str] = uuid.uuid4()\n```\n\n```py\nclass User(BaseModel):\n id: str = Field(default=uuid.uuid4())\n```\n\n```py\nclass User(BaseModel):\n id: str = Field(default_factory=uuid.uuid4) # uuid.uuid4 is not executed immediately\n```\n\n```text\nid\n```\n\n```text\nid\n```\n\n```text\nid\n```\n\n```text\nid\n```\n\n```text\nunique UUIDs\n```\n\n```text\nTimestamps\n```\n\n```py\nIdValidator = BeforeValidator(lambda id: id or str(uuid.uuid4()))\n\nclass User(BaseModel):\n id: Annotated[str, IdValidator] = Field(default=None, validate_default=True)\n```\n\n```py\nclass User(BaseModel):\n id: str = Field(default=None, validate_default=True)\n\n @field_validator('id', mode='before')\n @classmethod\n def ensure_id(cls, id: Optional[str]) -> str:\n return id or str(uuid.uuid4())\n```\n\n```text\nBeforeValidator()\n```\n\n```text\nField(default=None, validate_default=True)\n```\n\n```text\n@field_validator('id', mode='before')\n```\n\n```text\nid\n```\n\n```text\nisinstance()\n```\n\n========================================\n\nComments:\n- @manas-sombre You need to use `@validator(pre=True, always=True)` and then return a default value. I used `return v or cls.__name__.lower()` to set the lowercase class name as the default value for an `Optional[str]` field.\n- Should a validator contain any logic to alter values? This sound like some violation of responsibilities.\n- @Kuchara unfortunately pydantic has this misnomer deliberately. Feel free to read docs.pydantic.dev/latest/concepts/models/#tldr\n- The `default_factory` can now accept one argument, which is a dictionary of the already validated data within the model. Docs here.\n- Method 4 works on the python side, but in the openapi spec FastAPI generates it sill marks the field as optional (even with the required bool in the Field)\n- Massive insight!","metadata":{"transformedAt":"2026-08-18T18:32:29.086Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":38,"totalLines":514,"estimatedTokens":2763}}27{"id":"stack-67699451","source":"stackoverflow","questionId":67699451,"title":"Make every field as optional with Pydantic","tags":["python","python-3.x","fastapi","pydantic"],"text":"Title: Make every field as optional with Pydantic\nTags: python, python-3.x, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI'm making an API with FastAPI and Pydantic.\n\nI would like to have some PATCH endpoints, where 1 or N fields of a record could be edited at once. **Moreover, I would like the client to only pass the necessary fields in the payload.**\n\nExample:\n\n```\nclass Item(BaseModel):\n name: str\n description: str\n price: float\n tax: float\n\n@app.post(\"/items\", response_model=Item)\nasync def post_item(item: Item):\n ...\n\n@app.patch(\"/items/{item_id}\", response_model=Item)\nasync def update_item(item_id: str, item: Item):\n ...\n```\n\nIn this example, for the POST request, I want every field to be required. However, in the PATCH endpoint, I don't mind if the payload only contains, for example, the description field. That's why I wish to have all fields as optional.\n\nNaive approach:\n\n```\nclass UpdateItem(BaseModel):\n name: Optional[str] = None\n description: Optional[str] = None\n price: Optional[float] = None\n tax: Optional[float]\n```\n\nBut that would be terrible in terms of code repetition.\n\nAny better option?\n\n========================================\n\nTop Answer:\nGood news and bad news:\n\n**Bad**: it's a `wontfix`, even in `pydantic v2`: https://github.com/pydantic/pydantic/issues/3120\n\n**Good**: @adriangb - one of the core devs of `pydantic` - made a solution, which I translated into a neat decorator. *It works for nested models*.\n\nHere it goes:\n\n```\nfrom typing import Optional, Type, Any, Tuple\nfrom copy import deepcopy\n\nfrom pydantic import BaseModel, create_model\nfrom pydantic.fields import FieldInfo\n\ndef partial_model(model: Type[BaseModel]):\n def make_field_optional(field: FieldInfo, default: Any = None) -> Tuple[Any, FieldInfo]:\n new = deepcopy(field)\n new.default = default\n new.annotation = Optional[field.annotation] # type: ignore\n return new.annotation, new\n return create_model(\n f'Partial{model.__name__}',\n __base__=model,\n __module__=model.__module__,\n **{\n field_name: make_field_optional(field_info)\n for field_name, field_info in model.__fields__.items()\n }\n )\n```\n\nThe original code is here.\n\nUsage:\n\n```\n@partial_model\nclass Model(BaseModel):\n i: int\n f: float\n s: str\n\nModel(i=1)\n```\n\n### Pydantic 2\n\nAs per @martintrapp's input, this solution also goes well with `pydantic 2`. The only thing you'll have to update is\n\n`model.__fields__.items()` needs to be changed to `model.model_fields.items()` to make it work\n\n========================================\n\nCode:\n```py\nclass Item(BaseModel):\n name: str\n description: str\n price: float\n tax: float\n\n\n@app.post(\"/items\", response_model=Item)\nasync def post_item(item: Item):\n ...\n\n@app.patch(\"/items/{item_id}\", response_model=Item)\nasync def update_item(item_id: str, item: Item):\n ...\n```\n\n```py\nclass UpdateItem(BaseModel):\n name: Optional[str] = None\n description: Optional[str] = None\n price: Optional[float] = None\n tax: Optional[float]\n```\n\n```py\nclass AllOptional(pydantic.main.ModelMetaclass):\n def __new__(cls, name, bases, namespaces, **kwargs):\n annotations = namespaces.get('__annotations__', {})\n for base in bases:\n annotations.update(base.__annotations__)\n for field in annotations:\n if not field.startswith('__'):\n annotations[field] = Optional[annotations[field]]\n namespaces['__annotations__'] = annotations\n return super().__new__(cls, name, bases, namespaces, **kwargs)\n```\n\n```py\nclass UpdatedItem(Item, metaclass=AllOptional):\n pass\n```\n\n```py\nfrom typing import Optional\n\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\nimport pydantic\n\napp = FastAPI()\n\nclass Item(BaseModel):\n name: str\n description: str\n price: float\n tax: float\n\n\nclass AllOptional(pydantic.main.ModelMetaclass):\n def __new__(self, name, bases, namespaces, **kwargs):\n annotations = namespaces.get('__annotations__', {})\n for base in bases:\n annotations.update(base.__annotations__)\n for field in annotations:\n if not field.startswith('__'):\n annotations[field] = Optional[annotations[field]]\n namespaces['__annotations__'] = annotations\n return super().__new__(self, name, bases, namespaces, **kwargs)\n\nclass UpdatedItem(Item, metaclass=AllOptional):\n pass\n\n# This continues to work correctly\n@app.get(\"/items/{item_id}\", response_model=Item)\nasync def get_item(item_id: int):\n return {\n 'name': 'Uzbek Palov',\n 'description': 'Palov is my traditional meal',\n 'price': 15.0,\n 'tax': 0.5,\n }\n\n@app.patch(\"/items/{item_id}\") # does using response_model=UpdatedItem makes mypy sad? idk, i did not check\nasync def update_item(item_id: str, item: UpdatedItem):\n return item\n```\n\n```text\nOptional\n```\n\n```py\nclass NewItem(BaseModel):\n name: str\n description: str\n price: float\n tax: float\n\nclass UpdateItem(BaseModel):\n name: Optional[str] = None\n description: Optional[str] = None\n price: Optional[float] = None\n tax: Optional[float] = None\n\n@app.post('/items', response_model=NewItem)\nasync def post_item(item: NewItem):\n return item\n\n@app.patch('/items/{item_id}',\n response_model=UpdateItem,\n response_model_exclude_none=True)\nasync def update_item(item_id: str, item: UpdateItem):\n return item\n```\n\n```py\nfrom fastapi import Body\nfrom typing import Dict\n\nclass Item(BaseModel):\n name: str\n description: str\n price: float\n tax: float\n\n@app.post('/items', response_model=Item)\nasync def post_item(item: Item):\n return item\n\n@app.patch('/items/{item_id}', response_model=Item)\nasync def update_item(item_id: str, payload: Dict = Body(...)):\n item = Item(\n name=payload.get('name', ''),\n description=payload.get('description', ''),\n price=payload.get('price', 0.0),\n tax=payload.get('tax', 0.0),\n )\n return item\n```\n\n```py\nfrom fastapi import HTTPException\n\n@app.patch('/items/{item_id}', response_model=Item)\nasync def update_item(item_id: str, payload: Dict = Body(...)):\n # Get intersection of keys/fields\n # Must have at least 1 common\n if not (set(payload.keys()) & set(Item.__fields__)):\n raise HTTPException(status_code=400, detail='No common fields')\n ...\n```\n\n```none\n$ cat test2.json\n{\n \"asda\": \"1923\"\n}\n$ curl -i -H'Content-Type: application/json' --data @test2.json --request PATCH localhost:8000/items/1\nHTTP/1.1 400 Bad Request\ncontent-type: application/json\n\n{\"detail\":\"No common fields\"}\n```\n\n```py\nclass Item(BaseModel):\n name: Optional[str] = None\n description: Optional[str] = None\n price: Optional[float] = None\n tax: Optional[float] = None\n```\n\n```py\n@app.post('/items', response_model=Item)\nasync def post_item(item: Item):\n new_item_values = item.dict(exclude_defaults=True, exclude_none=True)\n\n # Check if exactly same set of keys/fields\n if set(new_item_values.keys()) != set(Item.__fields__):\n raise HTTPException(status_code=400, detail='Missing some fields..')\n\n # Use `item` or `new_item_values`\n return item\n```\n\n```text\n$ cat test_empty.json\n{\n}\n$ curl -i -H'Content-Type: application/json' --data @test_empty.json --request POST localhost:8000/items\nHTTP/1.1 400 Bad Request\ncontent-type: application/json\n\n{\"detail\":\"Missing some fields..\"}\n\n$ cat test_incomplete.json \n{\n \"name\": \"test-name\",\n \"tax\": 0.44\n}\n$ curl -i -H'Content-Type: application/json' --data @test_incomplete.json --request POST localhost:8000/items\nHTTP/1.1 400 Bad Request\ncontent-type: application/json\n\n{\"detail\":\"Missing some fields..\"}\n\n$ cat test_ok.json\n{\n \"name\": \"test-name\",\n \"description\": \"test-description\",\n \"price\": 123.456,\n \"tax\": 0.44\n}\n$ curl -i -H'Content-Type: application/json' --data @test_ok.json --request POST localhost:8000/items\nHTTP/1.1 200 OK\ncontent-type: application/json\n\n{\"name\":\"test-name\",\"description\":\"test-description\",\"price\":123.456,\"tax\":0.44}\n```\n\n```text\n@app.patch('/items/{item_id}', response_model=Item)\nasync def update_item(item_id: str, item: Item):\n update_item_values = item.dict(exclude_defaults=True, exclude_none=True)\n\n # Get intersection of keys/fields\n # Must have at least 1 common\n if not (set(update_item_values.keys()) & set(Item.__fields__)):\n raise HTTPException(status_code=400, detail='No common fields')\n\n update_item = Item(**update_item_values)\n\n return update_item\n```\n\n```text\n$ cat test2.json\n{\n \"asda\": \"1923\"\n}\n$ curl -i -s -H'Content-Type: application/json' --data @test2.json --request PATCH localhost:8000/items/1\nHTTP/1.1 400 Bad Request\ncontent-type: application/json\n\n{\"detail\":\"No common fields\"}\n\n$ cat test2.json\n{\n \"description\": \"test-description\"\n}\n$ curl -i -s -H'Content-Type: application/json' --data @test2.json --request PATCH localhost:8000/items/1\nHTTP/1.1 200 OK\ncontent-type: application/json\n\n{\"name\":null,\"description\":\"test-description\",\"price\":null,\"tax\":null}\n```\n\n```text\nitem: Item\n```\n\n```text\nItem\n```\n\n```text\nOptional\n```\n\n```text\nNone\n```\n\n```text\nBody\n```\n\n```text\nItem\n```\n\n```text\nItem\n```\n\n```text\nBaseModel\n```\n\n```text\ndict\n```\n\n```text\nexclude_defaults\n```\n\n```text\nexclude_none\n```\n\n```text\nexclude_defaults\n```\n\n```text\nFalse\n```\n\n```text\nexclude_none\n```\n\n```text\nNone\n```\n\n```text\nFalse\n```\n\n```text\nItem\n```\n\n```text\nOptional[T] = None\n```\n\n```text\nitem: Item\n```\n\n```text\nexclude_defaults\n```\n\n```text\nexclude_none\n```\n\n```text\nitem\n```\n\n```text\nItem\n```\n\n```py\nfrom pydantic.main import ModelMetaclass, BaseModel\nfrom typing import Any, Dict, Optional, Tuple\n\nclass _AllOptionalMeta(ModelMetaclass):\n def __new__(self, name: str, bases: Tuple[type], namespaces: Dict[str, Any], **kwargs):\n annotations: dict = namespaces.get('__annotations__', {})\n\n for base in bases:\n for base_ in base.__mro__:\n if base_ is BaseModel:\n break\n\n annotations.update(base_.__annotations__)\n\n for field in annotations:\n if not field.startswith('__'):\n annotations[field] = Optional[annotations[field]]\n\n namespaces['__annotations__'] = annotations\n\n return super().__new__(mcs, name, bases, namespaces, **kwargs)\n```\n\n```text\nclass AllOptional(ModelMetaclass):\ndef __new__(self, name, bases, namespaces, **kwargs):\n annotations = namespaces.get('__annotations__', {})\n for base in bases:\n optionals = {\n key: Optional[value] if not key.startswith('__') else value for key, value in base.__annotations__.items()\n }\n annotations.update(optionals)\n\n namespaces['__annotations__'] = annotations\n return super().__new__(self, name, bases, namespaces, **kwargs)\n```\n\n```text\nfrom pydantic import BaseModel, create_model\nfrom typing import Optional\nfrom functools import lru_cache\n\n@lru_cache(maxsize=None) # avoids creating many classes with same name\ndef make_optional(baseclass: Type[BaseModel]) -> Type[BaseModel]:\n # Extracts the fields and validators from the baseclass and make fields optional\n fields = baseclass.__fields__\n validators = {'__validators__': baseclass.__validators__}\n optional_fields = {key: (Optional[item.type_], None)\n for key, item in fields.items()}\n return create_model(f'{baseclass.__name__}Optional', **optional_fields,\n __validators__=validators)\n\nclass Item(BaseModel):\n name: str\n description: str\n price: float\n tax: float\n\nItemOptional = make_optional(Item)\n```\n\n```text\n> Item.__fields__\n\n{'name': ModelField(name='name', type=str, required=True),\n 'description': ModelField(name='description', type=str, required=True),\n 'price': ModelField(name='price', type=float, required=True),\n 'tax': ModelField(name='tax', type=float, required=True)}\n\n> ItemOptional.__fields__\n\n{'name': ModelField(name='name', type=Optional[str], required=False, default=None),\n 'description': ModelField(name='description', type=Optional[str], required=False, default=None),\n 'price': ModelField(name='price', type=Optional[float], required=False, default=None),\n 'tax': ModelField(name='tax', type=Optional[float], required=False, default=None)}\n```\n\n```text\n@app.post(\"/items\", response_model=Item)\nasync def post_item(item: Item = Depends()):\n ...\n\n@app.patch(\"/items/{item_id}\", response_model=Item)\nasync def update_item(item_id: str, item: make_optional(Item) = Depends()):\n ...\n```\n\n```text\ndef make_optional_no_id(baseclass):\n ... # same as make optional\n optional_fields = {key: (Optional[item.type_], None) \n for key, item in fields.items() if key != 'ID'} # take out here ID\n ... # you can also take out also validators of ID\n\n@app.patch(\"/items/{item_id}\", response_model=Item)\nasync def update_item(item: make_optional_no_id(Item) = Depends()):\n```\n\n```py\nfrom typing import Optional, get_type_hints, Type\n\nfrom pydantic import BaseModel\n\n\ndef make_optional(\n include: Optional[list[str]] = None,\n exclude: Optional[list[str]] = None,\n):\n \"\"\"Return a decorator to make model fields optional\"\"\"\n\n if exclude is None:\n exclude = []\n\n # Create the decorator\n def decorator(cls: Type[BaseModel]):\n type_hints = get_type_hints(cls)\n fields = cls.__fields__\n if include is None:\n fields = fields.items()\n else:\n # Create iterator for specified fields\n fields = ((name, fields[name]) for name in include if name in fields)\n # Fields in 'include' that are not in the model are simply ignored, as in BaseModel.dict\n for name, field in fields:\n if name in exclude:\n continue\n if not field.required:\n continue\n # Update pydantic ModelField to not required\n field.required = False\n # Update/append annotation\n cls.__annotations__[name] = Optional[type_hints[name]]\n return cls\n\n return decorator\n```\n\n```text\nclass ModelBase(pydantic.BaseModel):\n a: int\n b: str\n\n\nclass ModelCreate(ModelBase):\n pass\n\n# Make all fields optional\n@make_optional()\nclass ModelUpdate(ModelBase):\n pass\n```\n\n```py\n# Make only `a` optional\n@make_optional(include=[\"a\"])\nclass ModelUpdate(ModelBase):\n pass\n\n# Make only `b` optional\n@make_optional(exclude=[\"a\"])\nclass ModelUpdate(ModelBase):\n pass\n```\n\n```text\ninclude\n```\n\n```text\nexclude\n```\n\n```text\nexclude\n```\n\n```text\ninclude\n```\n\n```text\nfrom typing import Optional\nimport pydantic\nfrom pydantic import BaseModel, Field\n\nclass AllOptional(pydantic.main.ModelMetaclass):\n def __new__(self, name, bases, namespaces, **kwargs):\n annotations = namespaces.get('__annotations__', {})\n for base in bases:\n annotations.update(base.__annotations__)\n for field in annotations:\n if not field.startswith('__'):\n annotations[field] = Optional[annotations[field]]\n namespaces['__annotations__'] = annotations\n return super().__new__(self, name, bases, namespaces, **kwargs)\n\nclass A(BaseModel):\n a:int = Field(gt=1)\n\nclass AO(A, metaclass=AllOptional):\n pass\n\nAO(a=-1) # This will pass through the validation even that it's wrong ⛔️\n```\n\n```text\nclass AllOptional(pydantic.main.ModelMetaclass):\n def __new__(mcls, name, bases, namespaces, **kwargs):\n cls = super().__new__(mcls, name, bases, namespaces, **kwargs)\n for field in cls.__fields__.values():\n field.required=False\n return cls\n```\n\n```text\ndef make_partial_model(model: Type[BaseModel], optional_fields: Optional[list[str]] = None) -> Type[BaseModel]:\n class NewModel(model):\n ...\n\n for field in NewModel.__fields__.values():\n if not optional_fields or field in optional_fields:\n field.required = False\n\n NewModel.__name__ = f'Partial{model.__name__}'\n return NewModel\n\nPartialRequest = cast(Type[RequestModel], make_partial_model(RequestModel))\n```\n\n```py\nfrom typing import Optional\nfrom uuid import UUID, uuid4\n\nimport pydantic\n\nclass PatchPoll(pydantic.BaseModel):\n id: UUID = pydantic.Field(default_factory=uuid4)\n subject: str = pydantic.Field(max_length=1024, default=\"\")\n description: Optional[str] = pydantic.Field(max_length=1024 * 1024, default=\"\")\n\n\nclass Poll(PatchPoll):\n id: UUID\n subject: str = pydantic.Field(max_length=1024)\n description: Optional[str] = pydantic.Field(max_length=1024 * 1024)\n```\n\n```text\n>>> PatchPoll()\nPatchPoll(id=UUID('dcd80011-e81e-41fb-872b-4f82839a2a76'), subject='', description='')\n>>> PatchPoll().__fields_set__\nset()\n>>> PatchPoll(subject=\"jskdlfjk\").__fields_set__\n{'subject'}\n```\n\n```text\ndef remove_defaults(baseclass: Type[T]) -> Type[T]:\n validators = {\"__validators__\": baseclass.__validators__}\n fields = baseclass.__fields__\n\n def remove_default(item: pydantic.fields.ModelField) -> pydantic.fields.FieldInfo:\n info = item.field_info\n if info.default == pydantic.fields.Undefined and not info.default_factory:\n raise RuntimeError(\"Field has no default\")\n\n # Funny enough, if we don't keep the default for Optional types,\n # openapi-generator will not make it optional at all.\n if item.allow_none:\n return copy.copy(item.field_info)\n\n return pydantic.Field(\n alias=item.field_info.alias,\n title=item.field_info.title,\n description=item.field_info.description,\n exclude=item.field_info.exclude,\n include=item.field_info.include,\n const=item.field_info.const,\n gt=item.field_info.gt,\n ge=item.field_info.ge,\n lt=item.field_info.lt,\n le=item.field_info.le,\n multiple_of=item.field_info.multiple_of,\n allow_inf_nan=item.field_info.allow_inf_nan,\n max_digits=item.field_info.max_digits,\n decimal_places=item.field_info.decimal_places,\n min_items=item.field_info.min_items,\n max_items=item.field_info.max_items,\n unique_items=item.field_info.unique_items,\n min_length=item.field_info.min_length,\n max_length=item.field_info.max_length,\n allow_mutation=item.field_info.allow_mutation,\n regex=item.field_info.regex,\n discriminator=item.field_info.discriminator,\n repr=item.field_info.repr,\n )\n\n nondefault_fields = {\n key: (item.type_, remove_default(item)) for key, item in fields.items()\n }\n\n return pydantic.create_model(\n __model_name=f\"{baseclass.__name__}Optional\",\n __base__=baseclass,\n __validators__=validators,\n **nondefault_fields,\n )\n\n\nclass PatchPoll(pydantic.BaseModel):\n id: UUID = pydantic.Field(default_factory=uuid4)\n subject: str = pydantic.Field(max_length=1024, default=\"\")\n description: Optional[str] = pydantic.Field(max_length=1024 * 1024, default=\"\")\n\n\nclass Poll(remove_defaults(PatchPoll)):\n ...\n```\n\n```text\nOptional\n```\n\n```text\nNone\n```\n\n```text\nPatchPoll\n```\n\n```text\n__fields_set__\n```\n\n```text\nfrom typing import Optional, Type, Any, Tuple\nfrom copy import deepcopy\n\nfrom pydantic import BaseModel, create_model\nfrom pydantic.fields import FieldInfo\n\n\ndef partial_model(model: Type[BaseModel]):\n def make_field_optional(field: FieldInfo, default: Any = None) -> Tuple[Any, FieldInfo]:\n new = deepcopy(field)\n new.default = default\n new.annotation = Optional[field.annotation] # type: ignore\n return new.annotation, new\n return create_model(\n f'Partial{model.__name__}',\n __base__=model,\n __module__=model.__module__,\n **{\n field_name: make_field_optional(field_info)\n for field_name, field_info in model.__fields__.items()\n }\n )\n```\n\n```text\n@partial_model\nclass Model(BaseModel):\n i: int\n f: float\n s: str\n\n\nModel(i=1)\n```\n\n```text\nwontfix\n```\n\n```text\npydantic v2\n```\n\n```text\npydantic\n```\n\n```text\npydantic 2\n```\n\n```text\nmodel.__fields__.items()\n```\n\n```text\nmodel.model_fields.items()\n```\n\n```text\nfrom pydantic import BaseModel, create_model\n\nclass Item(BaseModel):\n name: str\n description: str\n price: float\n tax: float\n\nUpdateItem = create_model(\n 'UpdateItem',\n __base__=Item,\n **{k: (v.annotation, None) for k, v in Item.model_fields.items()}\n)\n```\n\n```text\nIn [410]: Item.model_fields\nOut[410]: \n{'name': FieldInfo(annotation=str, required=True),\n 'description': FieldInfo(annotation=str, required=True),\n 'price': FieldInfo(annotation=float, required=True),\n 'tax': FieldInfo(annotation=float, required=True)}\n\nIn [411]: UpdateItem.model_fields\nOut[411]: \n{'name': FieldInfo(annotation=str, required=False),\n 'description': FieldInfo(annotation=str, required=False),\n 'price': FieldInfo(annotation=float, required=False),\n 'tax': FieldInfo(annotation=float, required=False)}\n\nIn [412]: UpdateItem()\nOut[412]: UpdateItem(name=None, description=None, price=None, tax=None)\n```\n\n```text\nPydantic v2\n```\n\n```text\ncreate_model()\n```\n\n```text\nv2\n```\n\n```text\nrequired\n```\n\n```text\nFieldInfo\n```\n\n```text\nfield_info.required = False\n```\n\n```text\ndef convert_to_optional(schema):\n return {k: Optional[v] for k, v in schema.__annotations__.items()}\n```\n\n```text\nclass UpdateItem(Item):\n __annotations__ = convert_to_optional(Item)\n```\n\n```text\n__annotations__\n```\n\n```text\nfrom pydantic._internal._model_construction import ModelMetaclass\n```\n\n```text\nclass Item(BaseModel):\n name: str\n description: str\n price: float\n tax: float\n\n\n@app.post(\"/items\", response_model=Item)\nasync def post_item(item: Partial[Item]):\n ...\n```\n\n```text\nModel = typing.TypeVar(\"Model\", bound=BaseModel)\nclass Partial(typing.Generic[Model]):\n\"\"\"Generate a new class with all attributes optionals.\n\nNotes:\n This will wrap a class inheriting form BaseModel and will recursively\n convert all its attributes and its children's attributes to optionals.\n\nExample:\n Partial[SomeModel]\n\"\"\"\n\ndef __new__(\n cls,\n *args: object, # noqa :ARG003\n **kwargs: object, # noqa :ARG003\n) -> \"Partial[Model]\":\n \"\"\"Cannot instantiate.\n\n Raises:\n TypeError: Direct instantiation not allowed.\n \"\"\"\n raise TypeError(\"Cannot instantiate abstract Partial class.\")\n\ndef __init_subclass__(\n cls,\n *args: object,\n **kwargs: object,\n) -> typing.NoReturn:\n \"\"\"Cannot subclass.\n\n Raises:\n TypeError: Subclassing not allowed.\n \"\"\"\n raise TypeError(\"Cannot subclass {}.Partial\".format(cls.__module__))\n\ndef __class_getitem__( # type: ignore[override]\n cls,\n wrapped_class: type[Model],\n) -> type[Model]:\n \"\"\"Convert model to a partial model with all fields being optionals.\"\"\"\n\n def _make_field_optional(\n field: pydantic.fields.FieldInfo,\n ) -> tuple[object, pydantic.fields.FieldInfo]:\n tmp_field = copy.deepcopy(field)\n\n annotation = field.annotation\n # If the field is a BaseModel, then recursively convert it's\n # attributes to optionals.\n if type(annotation) is type(BaseModel):\n tmp_field.annotation = typing.Optional[Partial[annotation]] # type: ignore[assignment, valid-type]\n tmp_field.default = {}\n else:\n tmp_field.annotation = typing.Optional[field.annotation] # type: ignore[assignment]\n tmp_field.default = None\n return tmp_field.annotation, tmp_field\n\n return pydantic.create_model( # type: ignore[no-any-return, call-overload]\n f\"Partial{wrapped_class.__name__}\",\n __base__=wrapped_class,\n __module__=wrapped_class.__module__,\n **{\n field_name: _make_field_optional(field_info)\n for field_name, field_info in wrapped_class.model_fields.items()\n },\n )\n```\n\n```text\nModelMetaclass\n```\n\n```text\npydantic.create_model\n```\n\n```text\nimport inspect\nimport typing\nfrom pydantic._internal._model_construction import ModelMetaclass\nfrom pydantic._internal._generics import PydanticGenericMetadata\nfrom pydantic.fields import FieldInfo\nfrom pydantic_core import PydanticUndefined\n\n\nclass MakeOptional(ModelMetaclass):\n def __new__(\n mcs, # noqa: N804\n cls_name: str,\n bases: tuple[type[typing.Any], ...],\n namespace: dict[str, typing.Any],\n __pydantic_generic_metadata__: typing.Optional[PydanticGenericMetadata] = None,\n __pydantic_reset_parent_namespace__: bool = True,\n _create_model_module: typing.Optional[str] = None,\n **kwargs: typing.Any,\n ) -> type:\n if len(bases) > 1:\n raise NotImplementedError(\n \"`MakeOptional` can't work with more then one base class\"\n )\n if not bases or not issubclass(bases[0], pd.BaseModel):\n raise TypeError('Must be inherited from pydantic.BaseModel')\n\n annotations: dict[str, object] = {}\n\n for base in inspect.getmro(bases[0]):\n if not issubclass(base, pd.BaseModel):\n continue\n\n annotations.update(getattr(base, '__annotations__', {}))\n for field_name in getattr(base, '__annotations__', {}):\n if field_name.startswith('__'):\n continue\n field_info = base.model_fields.get(field_name)\n if not field_info:\n continue\n field_info.annotation = typing.Optional[field_info.annotation] # type: ignore\n new_annotation = field_info.rebuild_annotation()\n new_field = FieldInfo.from_annotation(field_info.rebuild_annotation())\n if new_field.default is PydanticUndefined:\n new_field.default = None\n annotations[field_name] = new_annotation\n setattr(base, field_name, new_field)\n namespace['__annotations__'] = annotations\n return super().__new__(\n mcs,\n cls_name,\n bases,\n namespace,\n __pydantic_generic_metadata__,\n __pydantic_reset_parent_namespace__,\n _create_model_module,\n **kwargs,\n )\n```\n\n```text\nclass ResponseModelOptional(\n ResponseModelStrict,\n metaclass=MakeOptional,\n):\n pass\n```\n\n```py\nfrom copy import deepcopy\nfrom typing import Any, Callable, Optional, TypeVar\n\nfrom pydantic import BaseModel, create_model\nfrom pydantic.fields import FieldInfo\n\nT = TypeVar(\"T\", bound=\"BaseModel\")\n\n\ndef partial_model(\n include: Optional[list[str]] = None, exclude: Optional[list[str]] = None\n) -> Callable[[type[T]], type[T]]:\n \"\"\"Return a decorator to make model fields optional\"\"\"\n\n if exclude is None:\n exclude = []\n\n def decorator(model: type[T]) -> type[T]:\n def make_optional(\n field: FieldInfo, default: Any = None\n ) -> tuple[Any, FieldInfo]:\n new = deepcopy(field)\n new.default = default\n new.annotation = Optional[field.annotation or Any]\n return new.annotation, new\n\n fields = model.model_fields\n if include is None:\n fields = fields.items()\n else:\n fields = ((k, v) for k, v in fields.items() if k in include)\n\n return create_model(\n model.__name__,\n __base__=model,\n __module__=model.__module__,\n **{\n field_name: make_optional(field_info)\n for field_name, field_info in fields\n if exclude is None or field_name not in exclude\n }, # type: ignore\n )\n\n return decorator\n```\n\n```py\nfrom typing import Optional\nfrom pydantic import create_model\n\nclass Item(BaseModel):\n name: str\n description: str\n price: float\n tax: float\n\nUpdateItem = create_model(\n \"UpdateItem\", \n **{k: (Optional[v], None) for k, v in Item.__annotations__.items()})\n\nUpdateItem()\n# UpdateItem(name=None, description=None, price=None, tax=None)\n```\n\n```text\nOptional\n```\n\n```text\nNone\n```\n\n```text\nresponse_model_exclude_unset=True\n```\n\n```text\n@router.get(\n \"/mypath\",\n response_model=ResourcesListResponse,\n response_model_exclude_unset=True,\n)\nasync def get_my_func( ...\n```\n\n```text\n= None\n```\n\n```text\nimport copy\nimport typing\nimport pydantic\nimport functools\nimport weakref\n\nModel = typing.TypeVar(\"Model\", bound=pydantic.BaseModel)\n_Depth: typing.TypeAlias = typing.Union[bool, int]\n_Prefix: typing.TypeAlias = str\n\nDEFAULT_PREFIX = \"Partial\"\nTOP_LEVEL = 0\n\n# Cache for created models\n_model_cache = weakref.WeakValueDictionary()\n\n\n@typing.overload\ndef partial(\n model_cls: typing.Optional[typing.Type[Model]] = None, # noqa :ARG006\n) -> typing.Type[Model]: ...\n\n\n@typing.overload\ndef partial(\n *,\n include: typing.Optional[typing.List[str]] = None,\n depth: _Depth = TOP_LEVEL,\n prefix: typing.Optional[_Prefix] = None,\n) -> typing.Callable[[typing.Type[Model]], typing.Type[Model]]: ...\n\n\n@typing.overload\ndef partial(\n *,\n exclude: typing.Optional[typing.List[str]] = None,\n depth: _Depth = TOP_LEVEL,\n prefix: typing.Optional[_Prefix] = None,\n) -> typing.Callable[[typing.Type[Model]], typing.Type[Model]]: ...\n\n\ndef _make_optional(\n field: pydantic.fields.FieldInfo,\n default: typing.Any,\n depth: _Depth,\n prefix: typing.Optional[_Prefix],\n) -> tuple[object, pydantic.fields.FieldInfo]:\n \"\"\"Helper function to make a field optional.\n\n :param field: The field to make optional\n :param default: Default value for the optional field\n :param depth: How deep to make nested models optional\n :param prefix: String to prepend to nested model names\n :returns: Tuple of (annotation, field_info)\n :raises ValueError: If depth is negative\n \"\"\"\n tmp_field = copy.deepcopy(field)\n annotation = field.annotation or typing.Any\n\n if isinstance(depth, int) and depth < 0:\n raise ValueError(\"Depth cannot be negative\")\n\n if (\n isinstance(annotation, type)\n and issubclass(annotation, pydantic.BaseModel)\n and depth\n ):\n model_key = (annotation, depth, prefix)\n if model_key not in _model_cache:\n _model_cache[model_key] = partial(\n depth=depth - 1 if isinstance(depth, int) else depth,\n prefix=prefix,\n )(annotation)\n annotation = _model_cache[model_key]\n\n tmp_field.annotation = typing.Optional[annotation]\n tmp_field.default = default\n return tmp_field.annotation, tmp_field\n\n\ndef partial(\n model_cls: typing.Optional[typing.Type[Model]] = None, # noqa :ARG006\n *,\n include: typing.Optional[typing.List[str]] = None,\n exclude: typing.Optional[typing.List[str]] = None,\n depth: _Depth = TOP_LEVEL,\n prefix: typing.Optional[_Prefix] = None,\n) -> typing.Callable[[typing.Type[Model]], typing.Type[Model]]:\n \"\"\"\n Create a partial Pydantic model with optional fields.\n\n This decorator allows you to create a new model based on an existing one,\n where specified fields become optional. It's particularly useful for update\n operations where only some fields may be provided.\n\n :param model_cls: The Pydantic model to make partial\n :param include: List of field names to make optional. If None, all fields are included\n :param exclude: List of field names to keep required. If None, no fields are excluded\n :param depth: How deep to make nested models optional:\n - 0: Only top-level fields\n - n: n levels deep\n - True: All levels\n :param prefix: String to prepend to the new model's name\n :returns: A decorator function that creates a new model with optional fields\n :raises ValueError: If both include and exclude are provided\n :raises ValueError: If depth is negative\n\n Example:\n ```python\n @partial\n class UserUpdateSchema(UserSchema):\n pass\n\n # Make specific fields optional\n @partial(include=['name', 'email'])\n class UserPartialSchema(UserSchema):\n pass\n\n # Keep certain fields required\n @partial(exclude=['id'])\n class UserUpdateSchema(UserSchema):\n pass\n ```\n\n - Uses model caching to avoid recreating identical partial models\n \"\"\"\n if include is not None and exclude is not None:\n raise ValueError(\"Cannot specify both include and exclude\")\n\n if exclude is None:\n exclude = []\n\n @functools.lru_cache(maxsize=32)\n def create_partial_model(model_cls: typing.Type[Model]) -> typing.Type[Model]:\n \"\"\"\n Create a new Pydantic model with optional fields.\n\n Cached model creation to avoid regenerating same models.\n \"\"\"\n fields = model_cls.model_fields\n if include is None:\n fields = fields.items()\n else:\n fields = ((k, v) for k, v in fields.items() if k in include)\n\n return pydantic.create_model(\n f\"{prefix or ''}{model_cls.__name__}\",\n __base__=model_cls,\n __module__=model_cls.__module__,\n **{\n field_name: _make_optional(\n field_info,\n default=field_info.default\n if field_info.default is not pydantic.fields.PydanticUndefined\n else None,\n depth=depth,\n prefix=prefix,\n )\n for field_name, field_info in fields\n if exclude is None or field_name not in exclude\n },\n )\n\n if model_cls is None:\n return create_partial_model\n return create_partial_model(model_cls)\n\n\nclass _ModelConfig(typing.NamedTuple):\n \"\"\"Configuration for partial model creation.\"\"\"\n\n model: typing.Type[Model]\n depth: _Depth\n prefix: _Prefix\n\n\ndef _create_model_config(*args: typing.Any) -> _ModelConfig:\n \"\"\"\n Factory function to create and validate model configuration.\n\n :raises TypeError: If arguments are invalid\n \"\"\"\n if not args:\n raise TypeError(\"Model type argument is required\")\n\n if len(args) > 3:\n raise TypeError(f\"Expected at most 3 arguments, got {len(args)}\")\n\n model, *rest = args\n if not (isinstance(model, type) and issubclass(model, pydantic.BaseModel)):\n raise TypeError(f\"Expected BaseModel subclass, got {type(model)}\")\n\n if not rest:\n return _ModelConfig(model, TOP_LEVEL, DEFAULT_PREFIX)\n\n depth = rest[0]\n if not isinstance(depth, (int, bool)):\n if not isinstance(depth, str):\n raise TypeError(\n f\"Expected int, bool or str for depth/prefix, got {type(depth)}\"\n )\n # Case where first arg is prefix\n return _ModelConfig(model, TOP_LEVEL, depth)\n\n prefix = rest[1] if len(rest) > 1 else DEFAULT_PREFIX\n if not isinstance(prefix, str):\n raise TypeError(f\"Expected str for prefix, got {type(prefix)}\")\n\n return _ModelConfig(model, depth, prefix)\n\n\nclass Partial(typing.Generic[Model]):\n \"\"\"\n Type hint for creating partial Pydantic models.\n\n Supports three forms of instantiation:\n 1. Partial[Model] # Uses default depth and prefix\n 2. Partial[Model, depth] # Uses default prefix\n 3. Partial[Model, depth, prefix]\n 4. Partial[Model, prefix] # Uses default depth\n\n :param Model: The Pydantic model to make partial\n :param depth: How deep to make fields optional (int, bool)\n :param prefix: Prefix for the generated model name (str)\n\n Example:\n ```python\n class User(BaseModel):\n name: str\n age: int\n\n # These are all valid:\n PartialUser = Partial[User] # depth=0, prefix=\"Partial\"\n UpdateUser = Partial[User, \"Update\"] # depth=0, prefix=\"Update\"\n DeepUpdateUser = Partial[User, True, \"Update\"] # All nested fields optional\n ```\n \"\"\"\n\n def __class_getitem__( # type: ignore[override]\n cls,\n wrapped: typing.Union[typing.Type[Model], typing.Tuple[typing.Any, ...]],\n ) -> typing.Type[Model]:\n \"\"\"Converts model to a partial model with optional fields.\"\"\"\n args = wrapped if isinstance(wrapped, tuple) else (wrapped,)\n config = _create_model_config(*args)\n\n return partial(\n depth=config.depth,\n prefix=config.prefix,\n )(config.model) # type: ignore[no-any-return, return-value]\n\n def __new__(\n cls,\n *args: object, # noqa :ARG003\n **kwargs: object, # noqa :ARG003\n ) -> \"Partial[Model]\":\n \"\"\"Cannot instantiate.\n\n :raises TypeError: Direct instantiation not allowed.\n \"\"\"\n raise TypeError(\"Cannot instantiate abstract Partial class.\")\n\n def __init_subclass__(\n cls,\n *args: object,\n **kwargs: object,\n ) -> typing.NoReturn:\n \"\"\"Cannot subclass.\n\n :raises TypeError: Subclassing not allowed.\n \"\"\"\n raise TypeError(\"Cannot subclass {}.Partial\".format(cls.__module__))\n```\n\n========================================\n\nComments:\n- From my experience in multiple teams using `pydantic`, you should (really) consider having those models duplicated in your code, just like you presented as an example. I think you shouldn't try to do what you're trying to do. Having it automatic mightseem like a quick win, but there are so many drawbacks behind, beginning with a lower readability. What happens when you have some special cases, like, the `id` of your item is not optional anymore. What happens when you have X, Y and Z special other cases ? Such special cases are so easily solved by having multiple explicit schema. You'll see. :)\n- Future readers might find this answer helpful as well.\n- Thanks ! Great explanations. So, it looks like solution 2 is better than 3 as the manual validation for PATCH has to be done in both, while POST validation only in 3. But I agree solution 1 is easier to read when you are not alone in a project ...\n- Ah Pydantic, where instead of one model, we now need at least 3.\n- Hey - the solution doesn't appear to work for nested models, as in, if I have a model as an attribute of another and apply the metaclass to both of these objects, parse_obj will through validation errors. Any thoughts?\n- @hiimBacon does Maxim's solution work for that case?\n- It is possible in Pydantic V2?\n- @Fyzzys I haven't used Pydantic for a long time, it seems it still uses the Optional[T] syntax. I believe this code should work for the new version, you could try it out and reply if this is the case.\n- Regarding the `ModelMetaclass` , I received an error on import and because it has moved. Use this statement now: `from pydantic._internal._model_construction import ModelMetaclass`\n- Pycharm complains about \"Parameter ... unfilled\" when leaving out a parameter that is required in the base class. Anyone figured this out?\n- Is there a way to make this general so it works with any pydantic model, Rather than inheriting from PydanticModel?\n- Never mind figured it out\n- How did you figure it out ?\n- @Cwellan `class MyPydanticModelAllOptional(MyPydanticModel, metaclass=AllOptional)` See @Drdilyor 's answer\n- Thanks, Maxim. Is there a way to make this work for fields that are nested models?\n- How i can do this with Pydantic V2\n- I think I like this one even more than the decorator, because you can just stick it in a dependency and then there's nothing else to distract. This makes a lot of sense. I wonder if you could please update it to support nested models?\n- It's being many months since I did this code, but if you provide a snippet supporting that case I will update my answer. In any case if you use this approach several times with the same class I recommend to cache the result to prevent having many classes with the same name. I have edited my answer to prevent that.\n- Did you just add the `lru_cache`? I'm not sure if I saw it there before. I guess that deals with that problem very nicely. Thanks for your offer. If it's ok with you I might just create a new question and link it here. I'm not sure where to put the snippet otherwise.\n- yes lru_cache is the new edition, and sure, as you want.\n- Thanks again for your help and support @Ziur_Olpa. I have posted a new question here: stackoverflow.com/q/75167317/134044\n- I'm not sure if you started work on the sub-classes yet @Zuir_Olpa, but I've ended up working on it myself. I think I've got a solution but I need to test it and then I'll post it. If you haven't spent any time on it yet you may want to wait until I've posted mine.\n- @NeilG sure i wait, great to know :)\n- Hey @Ziur_Olpa, pretty funny, I got it working, but my test PATCH wasn't working, and still isn't. At first I thought it was implementation of `make_optional` but I've drilled down and found out several things that are wrong with other aspects of the PATCH. So FYI, you shouldn't use `Depends` with it (probably need `Body` or something like that) but also I find that Pydantic's `BaseModel.copy(update=, deep-True)` doesn't respect sub-objects as `BaseModel`. It seems to treat them as `dict`. I could have a Pydantic bug/feature here. Still working on it ...\n- There is some discussion on a class-based solution to be built into Pydantic, possibly in v2: github.com/pydantic/pydantic/discussions/3089\n- Yes, this issue is acknowledged in Pydantic and relates to the inability of `BaseModel.copy` to properly treat sub-objects, as described, reflected in these two issues which are closely similar: github.com/pydantic/pydantic/issues/4177 and github.com/pydantic/pydantic/issues/3785\n- Hi @Zuir_Olpa, developing your answer further I've now added support for nested models. I've also got a working solution for `PATCH`ing Pydantic nested `BaseModel` without using `BaseModel.copy`, which fails to update correctly for nested models. So my `PATCH` now works: stackoverflow.com/a/75205570\n- This is a nice clean alternative and a creative idea to use a decorator. I wonder if you could help with 2 improvements: 1. clarify use of `include` and `exclude` parameters to the decorator, as it's not clear to me which \"way round\" the sense / meaning is of those. Perhaps illustrate with a usage example. 2. please fix up to apply to nested models (in my case I only have two sub-objects, so only one extra level)\n- @NeilG Thanks for the feedback. I've added clarification about the `include` & `exclude` fields. I need to spend a little more time to think about the nested models which I can't right now. It's not ideal, but you could try something like this: `python class A(BaseModel): ... class B(BaseModel): a: A ... @make_optional() class OptB(B): a: make_optional()(A) ...` This is not so bad for just one level but yeah, it would be worth adding support for nested models.\n- @NeilG sorry about the formatting, it will only let me edit every 5 mins and I didn't know you can't add code blocks to comments\n- Thanks @mishnea, this is great, except I don't think it descends into nested classes, does it?\n- This solution worked for me, however, you lose the config from the base model class. In my case, I needed to add this back in by adding it to the `create_model` call like this: `create_model(f'{baseclass.__name__}Update', **_fields, __validators__=validators, __config__=baseclass.Config)`\n- This doesn't work with pydantic2 for anyone who is wondering\n- It would also be useful to preserve other inherited Types using `T = TypeVar('T', bound='BaseModel')` and updating the annotation for decorator to `def decorator(cls: type[T]) -> type[T]:`\n- Thanks for the warning, @Amine_Bk. I haven't tested but if this is correct then I will use Zuir's answer stackoverflow.com/a/72365032/134044 because I think it's taking the same approach you are (functionally iterating over already built instance) but doesn't require going down into `__new__` and can just be applied as a dependency with no other distraction in the code.\n- Thanks for the catch! I will link this in my solution, you can edit this into my answer if you want\n- I got the following error with this decorator: `File \"pydantic/json.py\", line 90, in pydantic.json.pydantic_encoder / TypeError: Object of type 'ModelField' is not JSON serializable`\n- what is your code?\n- github.com/refstudio/refstudio/blob/…\n- @danvk it's a part of a project, which I don't want to run. You should provide a minimal reproducible example, so I can stick it into REPL and figure it out. And I almost certainly guarantee you, that if you **yourself** were to figure out a MRE, you'd debug it easily and could post your edit of my code.\n- It breaks the pickling on the created model object.\n- Nice! Best solution for Pydantic v2 so far. `model.__fields__.items()` needs to be changed to `model.model_fields.items()` to make it work.\n- This is an outstanding solution for pydantic v2.\n- @Gibbs it's because it dynamically creates a new class under the hood. Code is right before your eyes, man...\n- @winwin Be kind, just because it's clear to you doesn't mean it's clear to others. I'm also running into this same issue though as I need to serialize these classes. I tried looking into [using **reduce**] but didn't seem to have much luck getting that to work generically. Any advice?\n- @Brendan be kind, but the person did not ask, he just threw his \"boo\", as if I'm getting paid on SO for \"customer service\". No way I'm kind to this kind of people.\n- @Brendan on the other hand, you can first make a dictionary, and pickle that. If not, you should search up, how to unpickle into a dynamically created class, which, I'm sure, there should be answers on SO.\n- This should be the accepted solution, it works in Pydantic v2 including the auto-generated OpenAPI swagger docs.\n- I don't know if I would recommend prepending `Partial` to the model name. After all, whoever uses the decorator can set the model name in the class name. And it's ambiguous to declare it, for instance, as class `User` (with the decorator), even though it's meant for partial usage, and you get a class `PartialUser`.\n- Not working for nested models\n- @ahmelq only current model's fields should become `Optional`: nested models are things of their own. I don't think that modifying nested types is a good thing.\n- Yeah but the answer mentions \"It works for nested models\" which confused me a bit\n- @ahmelq it *does* work for nested models. Meaning, that you get the regular expected pydantic behavior. I suppose, you expected it to propagate \"partialness\" to your nested models, however, this isn't an expected behavior at all, in my opinion. Seems very intrusive.\n- **Breaks** default values and even somehow damages nested dictionaries for pydantic 2.\n- Doesn't work any more since Pydantic 2.12.0. The Partial class in this github comment seems to be a viable alternative.\n- This is the way for Pydantic V2. I would recommend adding the base model as a parameter to `create_model()` to ensure any model_config is also copied over.\n- In this problem, `__base__` is not required and If `UpdateItem` is to be configured or validated differently from the base class `Item`, `__base__` cannot be used together with `__config__` or `__validators__` arguments. So, I'm not sure if I would set `__base__=Item`.\n- This solution works but fails to validate. I only tested with a field with `conint(ge=0)`. @winwin's solution seems to keep validation.\n- This looks promising (doesn't use create_model so maybe it could be picked), but it would be great to see this with functioning imports and a working example of usage. From what I can tell, some of these imports look to be using private (underscored) APIs?\n- @Brendan Added usage example. There is no private imports, `__pydantic_generic_metadata__` and others it's pydantic arg names and I saved these names for no trigger pylint rule \"too-many-args\". So, this code passes mypy/pylint/ruff\n- Are you able to post a full example with the imports you used? I can't find any reference to e.g. `ModelMetaclass` or `PydanticGenericMetadata` in the pydantic docs.\n- I edited to add support for imports. This answer is quite nice, but unfortunately doesn't seem to work for my, admittedly very niche, use case (involving using schema from this to dynamically generate pyspark UDF return types).\n- Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.","metadata":{"transformedAt":"2026-08-18T18:32:29.087Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":95,"totalLines":1514,"estimatedTokens":12144}}28{"id":"stack-71525132","source":"stackoverflow","questionId":71525132,"title":"How to write a custom FastAPI middleware class","tags":["python","fastapi","middleware","starlette"],"text":"Title: How to write a custom FastAPI middleware class\nTags: python, fastapi, middleware, starlette\nSource: Stack Overflow\n\nQuestion:\nI have read FastAPI's documentation about middlewares (specifically, the middleware tutorial, the CORS middleware section and the advanced middleware guide), but couldn't find a concrete example of how to write a middleware class which you can add using the `add_middleware` function (in contrast to a basic middleware function added using a decorator) there nor on this site.\n\nThe reason I prefer to use `add_middleware` over the app based decorator, is that I want to write a middleware in a shared library that will be used by several different projects, and therefore I can't tie it to a specific `FastAPI` instance.\n\nSo my question is: how do you do it?\n\n========================================\n\nTop Answer:\nA potential workaround for the BaseHTTPMiddleware bug raised by @Error - Syntactical Remorse, which seems to work for me at least, is to use partial and use a functional approach to your middleware definition:\n\n### middleware.py\n\n```\nfrom typing import Any, Callable, Coroutine\nfrom fastapi import Response\n\nasync def my_middleware(request: Request, call_next: Callable, some_attribute: Any) -> Response:\n request.state.attr = some_attribute # Do what you need with your attribute\n return await call_next(request)\n```\n\n### app.py\n\n```\nfrom functools import partial\nfrom fastapi import FastAPI\nfrom middleware import my_middleware\n\napp = FastAPI()\n\nmy_custom_middleware: partial[Coroutine[Any, Any, Any]] = partial(my_middleware, some_attribute=\"my-app\")\n\napp.middleware(\"http\")(my_custom_middlware)\n```\n\n========================================\n\nCode:\n```text\nadd_middleware\n```\n\n```text\nadd_middleware\n```\n\n```text\nFastAPI\n```\n\n```py\nfrom fastapi import Request\n\nclass MyMiddleware:\n def __init__(self, some_attribute: str):\n self.some_attribute = some_attribute\n\n async def __call__(self, request: Request, call_next):\n # do something with the request object\n content_type = request.headers.get('Content-Type')\n print(content_type)\n \n # process the request and get the response \n response = await call_next(request)\n \n return response\n```\n\n```text\nfrom fastapi import FastAPI\nfrom middlewares import MyMiddleware\nfrom starlette.middleware.base import BaseHTTPMiddleware\n\napp = FastAPI()\nmy_middleware = MyMiddleware(some_attribute=\"some_attribute_here_if_needed\")\napp.add_middleware(BaseHTTPMiddleware, dispatch=my_middleware)\n```\n\n```py\nfrom fastapi import Request\nfrom starlette.middleware.base import BaseHTTPMiddleware\n\nclass MyMiddleware(BaseHTTPMiddleware):\n async def dispatch(self, request: Request, call_next):\n # do something with the request object, for example\n content_type = request.headers.get('Content-Type')\n print(content_type)\n \n # process the request and get the response \n response = await call_next(request)\n \n return response\n```\n\n```py\nfrom fastapi import FastAPI\nfrom middlewares import MyMiddleware\n\napp = FastAPI()\napp.add_middleware(MyMiddleware)\n```\n\n```py\nfrom fastapi import Request\nfrom starlette.middleware.base import BaseHTTPMiddleware\n\nclass MyMiddleware(BaseHTTPMiddleware):\n def __init__(self, app, some_attribute: str):\n super().__init__(app)\n self.some_attribute = some_attribute\n\n async def dispatch(self, request: Request, call_next):\n # do something with the request object, for example:\n content_type = request.headers.get('Content-Type')\n print(content_type)\n \n # process the request and get the response \n response = await call_next(request)\n \n # add new header to the response\n response.headers['Custom'] = self.some_attribute\n \n return response\n```\n\n```py\nfrom fastapi import FastAPI\nfrom middlewares import MyMiddleware\n\napp = FastAPI()\napp.add_middleware(MyMiddleware, some_attribute=\"some_attribute_here_if_needed\")\n```\n\n```text\nBaseHTTPMiddleware\n```\n\n```text\nadd_middleware()\n```\n\n```text\nBackgroundTasks\n```\n\n```text\nBaseHTTPMiddleware\n```\n\n```text\n__init_\n```\n\n```text\napp\n```\n\n```text\nfrom typing import Any, Callable, Coroutine\nfrom fastapi import Response\n\n\nasync def my_middleware(request: Request, call_next: Callable, some_attribute: Any) -> Response:\n request.state.attr = some_attribute # Do what you need with your attribute\n return await call_next(request)\n```\n\n```text\nfrom functools import partial\nfrom fastapi import FastAPI\nfrom middleware import my_middleware\n\n\napp = FastAPI()\n\nmy_custom_middleware: partial[Coroutine[Any, Any, Any]] = partial(my_middleware, some_attribute=\"my-app\")\n\napp.middleware(\"http\")(my_custom_middlware)\n```\n\n========================================\n\nComments:\n- The specification is the general ASGI middleware specification. A short introduction can be found on pgjones.dev/blog/how-to-write-asgi-middleware-2021 - You can see how the CORS middleware has been implemented here: github.com/encode/starlette/blob/…\n- For anyone that uses this approach, please make sure to read the bug about using `BaseHTTPMiddleware` (The red box at the bottom). The middleware with starlette does not play well with background tasks. Just be warned because it caught us by suprise.\n- @Error-SyntacticalRemorse I don't see any red box in that link. Was the problem fixed?\n- @PedroA Appears it was fixed. The wayback machine shows it but it was removed in the newest link. I will leave the comment because we recently used it again with fastapi but when we put it under extreme load, the raw middleware was faster and the BaseHTTPMiddleware appeared to have a memory leak with its Depends on checks. (That last sentence was just an opinion we had after testing, not a fact). I would try to use `BaseHTTPMiddleware` if you can!\n- I tried the same but, it is giving Nonetype is not callable for `app.middleware(\"http\")(my_custom_middlware)`","metadata":{"transformedAt":"2026-08-18T18:32:29.087Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":17,"totalLines":194,"estimatedTokens":1504}}29{"id":"stack-65916537","source":"stackoverflow","questionId":65916537,"title":"A minimal fastapi example loading index.html","tags":["fastapi"],"text":"Title: A minimal fastapi example loading index.html\nTags: fastapi\nSource: Stack Overflow\n\nQuestion:\nIn my project folder I have a basic `index.html` file plus static files (js, css) as well as my `main.py`:\n\n```\nfrom fastapi.staticfiles import StaticFiles\nfrom fastapi.templating import Jinja2Templates\nfrom fastapi import Request\n\napp = FastAPI()\n\ntemplates = Jinja2Templates(directory=\"/\")\napp.mount(\"/\", StaticFiles(directory=\"/\"))\n\n@app.get(\"/\")\ndef serve_home(request: Request):\n return templates.TemplateResponse(\"index.html\", context= {\"request\": request})\n```\n\nHow can I make fastapi work here? I just want my `index.html` and static files served on localhost.\nIs it problematic not to have a `static` or `templates` folder?\n\n========================================\n\nTop Answer:\nThe best and most simple solution that worked for me:\n\n```\nfrom fastapi import FastAPI\nfrom fastapi.staticfiles import StaticFiles\n\napi_app = FastAPI(title=\"api app\")\n\n@api_app.post(\"/set_influencers_to_follow\")\nasync def set_influencers_to_follow(request):\n return {}\n\napp = FastAPI(title=\"main app\")\n\napp.mount(\"/api\", api_app)\napp.mount(\"/\", StaticFiles(directory=\"ui\", html=True), name=\"ui\")\n```\n\nIf project structure is like:\n\n```\n├── main.py\n├── ui\n│ ├── index.html\n│ ├── style.css\n│ ├── script.js\n```\n\n========================================\n\nCode:\n```py\nfrom fastapi.staticfiles import StaticFiles\nfrom fastapi.templating import Jinja2Templates\nfrom fastapi import Request\n\napp = FastAPI()\n\ntemplates = Jinja2Templates(directory=\"/\")\napp.mount(\"/\", StaticFiles(directory=\"/\"))\n\n@app.get(\"/\")\ndef serve_home(request: Request):\n return templates.TemplateResponse(\"index.html\", context= {\"request\": request})\n```\n\n```text\nindex.html\n```\n\n```text\nmain.py\n```\n\n```text\nindex.html\n```\n\n```text\nstatic\n```\n\n```text\ntemplates\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.staticfiles import StaticFiles\n\napp = FastAPI()\n\napp.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")\n```\n\n```py\napp.mount(\"/\", StaticFiles(directory=\"static\",html = True), name=\"static\")\n```\n\n```py\nfrom starlette.responses import FileResponse \n\n@app.get(\"/\")\nasync def read_index():\n return FileResponse('index.html')\n```\n\n```text\nindex.html\n```\n\n```text\nstatic\n```\n\n```text\nindex.html\n```\n\n```text\nhttp://localhost:8000/static/index.html\n```\n\n```text\nhttp://localhost:8000/\n```\n\n```text\n/static\n```\n\n```text\n.html\n```\n\n```text\n/\n```\n\n```text\n/static\n```\n\n```text\ntrue\n```\n\n```text\nindex.html\n```\n\n```text\nhttp://localhost:8000/\n```\n\n```text\nindex.html\n```\n\n```text\nFileResponse\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.staticfiles import StaticFiles\n\napi_app = FastAPI(title=\"api app\")\n\n@api_app.post(\"/set_influencers_to_follow\")\nasync def set_influencers_to_follow(request):\n return {}\n\napp = FastAPI(title=\"main app\")\n\napp.mount(\"/api\", api_app)\napp.mount(\"/\", StaticFiles(directory=\"ui\", html=True), name=\"ui\")\n```\n\n```sh\n├── main.py\n├── ui\n│ ├── index.html\n│ ├── style.css\n│ ├── script.js\n```\n\n```text\nfrom fastapi.responses import HTMLResponse\n\n#\n# Raw HTML option\n# Or dumping the index.html into the response\n#\n@app.get(\"/\", response=HTMLResponse)\nasync def home():\n return \"<h1> HTML option </h1>\"\n\n#\n# Mako templates\n#\n@app.get(\"/\", response=HTMLResponse)\nasync def home():\n template = mylookup.get_template('templates/')\n return template.render_unicode('index.html')\n```\n\n```text\nindex.html\n```\n\n```text\nstatic/\n```\n\n```text\nindex.html\n```\n\n```text\nindex.html\n```\n\n```text\nresponse=HTMLResponse\n```\n\n```text\ntext/html\n```\n\n```text\napplication/json\n```\n\n========================================\n\nComments:\n- I find that pretty baffling tbh.\n- Would it help if I said you can import `FileResponse` from `fastapi.responses`? It's just a class that fastapi's rendering mechanism will see as the contents of file *index.html*.\n- Option 1 caused my server to return `405 Method Not Allowed` on post requests, just a warning\n- @AryeP. that's expected as mounted static files should only allow for GET requests. Why would you fire a POST request for static files anyway?\n- @do-me I used a POST request on a different rout, not root.\n- Please be aware that the order in which endpoints (as well as independent applications, such as `StaticFiles`) are defined **matters**. Please have a look at this answer and this answer for more details.\n- where does FastAPI believe static and template are relative to? When i start uvicorn passing the full path to where my main is, the tutroial code does not work\n- Thank you friend!\n- It's better to separate your api routes from the route used for static files, I edited your answer for it.\n- I got a problem with `instance order`, I solved by placing `api_app = FastAPI(title=\"api app\")` after `app = FastAPI(title=\"main app\")`. Details: stackoverflow.com/a/75045872/7009215\n- should one use routers instead of new FastAPIs here?\n- what is mylookup?\n- @mike01010 oh sorry, it's a Mako Template lib ... docs.makotemplates.org/en/latest/… but it can be anything you're using to convert a template -> HTML ...\n- Newer FastAPI versions use @app.get(\"/\", response_class=HTMLResponse)","metadata":{"transformedAt":"2026-08-18T18:32:29.087Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":33,"totalLines":260,"estimatedTokens":1289}}30{"id":"stack-61596911","source":"stackoverflow","questionId":61596911,"title":"Catch `Exception` globally in FastAPI","tags":["python-3.x","exception","fastapi"],"text":"Title: Catch `Exception` globally in FastAPI\nTags: python-3.x, exception, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to catch unhandled exceptions at global level. So somewhere in `main.py` file I have the below:\n\n```\n@app.exception_handler(Exception)\nasync def exception_callback(request: Request, exc: Exception):\n logger.error(exc.detail)\n```\n\nBut the above method is never executed. However, if I write a custom exception and try to catch it (as shown below), it works just fine.\n\n```\nclass MyException(Exception):\n #some code\n\n@app.exception_handler(MyException)\nasync def exception_callback(request: Request, exc: MyException):\n logger.error(exc.detail)\n```\n\nI have gone through Catch exception type of Exception and process body request #575. But this bug talks about accessing request body. After seeing this bug, I feel it should be possible to catch `Exception`.\nFastAPI version I am using is: `fastapi>=0.52.0`.\n\nThanks in advance :)\n\n### *Update*\n\nThere are multiple answers, I am thankful to all the readers and authors here.\nI was revisiting this solution in my application. Now I see that I needed to set `debug=False`, default it's `False`, but I had it set to `True` in\n\n```\nserver = FastAPI(\n title=app_settings.PROJECT_NAME,\n version=app_settings.VERSION,\n)\n```\n\nIt seems that I missed it when @iedmrc commented on answer given by @Kavindu Dodanduwa.\n\n========================================\n\nTop Answer:\nYou can do something like this. It should return a json object with your custom error message also works in debugger mode.\n\n```\nfrom fastapi import FastAPI, Request\nfrom fastapi.responses import JSONResponse\n\napp = FastAPI()\n\n@app.exception_handler(Exception)\nasync def validation_exception_handler(request: Request, exc: Exception):\n # Change here to Logger\n return JSONResponse(\n status_code=500,\n content={\n \"message\": (\n f\"Failed method {request.method} at URL {request.url}.\"\n f\" Exception message is {exc!r}.\"\n )\n },\n )\n```\n\n========================================\n\nCode:\n```py\n@app.exception_handler(Exception)\nasync def exception_callback(request: Request, exc: Exception):\n logger.error(exc.detail)\n```\n\n```py\nclass MyException(Exception):\n #some code\n\n@app.exception_handler(MyException)\nasync def exception_callback(request: Request, exc: MyException):\n logger.error(exc.detail)\n```\n\n```text\nserver = FastAPI(\n title=app_settings.PROJECT_NAME,\n version=app_settings.VERSION,\n)\n```\n\n```text\nmain.py\n```\n\n```text\nException\n```\n\n```text\nfastapi>=0.52.0\n```\n\n```text\ndebug=False\n```\n\n```text\nFalse\n```\n\n```text\nTrue\n```\n\n```text\nfrom fastapi import FastAPI\nfrom starlette.requests import Request\nfrom starlette.responses import Response\nfrom traceback import print_exception\n\napp = FastAPI()\n\nasync def catch_exceptions_middleware(request: Request, call_next):\n try:\n return await call_next(request)\n except Exception:\n # you probably want some kind of logging here\n print_exception(e)\n return Response(\"Internal server error\", status_code=500)\n\napp.middleware('http')(catch_exceptions_middleware)\n```\n\n```text\n@app.get(\"/\")\ndef read_root(response: Response):\n raise ArithmeticError(\"Divide by zero\")\n\n\n@app.exception_handler(Exception)\nasync def validation_exception_handler(request, exc):\n print(str(exc))\n return PlainTextResponse(\"Something went wrong\", status_code=400)\n```\n\n```text\n@app.exception_handler\n```\n\n```text\nException\n```\n\n```text\nRequestValidationError\n```\n\n```text\nValueError\n```\n\n```text\nException\n```\n\n```text\nlogger.error(exc.detail)\n```\n\n```text\nSomething went wrong\n```\n\n```text\nfrom fastapi import FastAPI, Request\nfrom fastapi.responses import JSONResponse\n\napp = FastAPI()\n\n@app.exception_handler(Exception)\nasync def validation_exception_handler(request: Request, exc: Exception):\n # Change here to Logger\n return JSONResponse(\n status_code=500,\n content={\n \"message\": (\n f\"Failed method {request.method} at URL {request.url}.\"\n f\" Exception message is {exc!r}.\"\n )\n },\n )\n```\n\n```py\nimport uvicorn\n\nfrom fastapi import FastAPI\nfrom starlette.requests import Request\nfrom starlette.exceptions import HTTPException as StarletteHTTPException\nfrom starlette.responses import JSONResponse\n\napp = FastAPI()\n\n\n@app.exception_handler(StarletteHTTPException)\nasync def exception_callback(request: Request, exc: Exception):\n print(\"test\")\n return JSONResponse({\"detail\": \"test_error\"}, status_code=500)\n\n\nif __name__ == \"__main__\":\n uvicorn.run(\"test:app\", host=\"0.0.0.0\", port=1111, reload=True)\n```\n\n```py\nimport uvicorn\n\nfrom fastapi import FastAPI\nfrom starlette.requests import Request\nfrom starlette.exceptions import HTTPException as StarletteHTTPException\nfrom starlette.responses import JSONResponse\n\napp = FastAPI()\n\n\n@app.exception_handler(Exception)\nasync def exception_callback(request: Request, exc: Exception):\n print(\"test\")\n return JSONResponse({\"detail\": \"test_error\"}, status_code=500)\n\n\nif __name__ == \"__main__\":\n uvicorn.run(\"test:app\", host=\"0.0.0.0\", port=1111, reload=True)\n```\n\n```text\n@app.middleware(\"http\")\nasync def exception_handling(request: Request, call_next):\n try:\n return await call_next(request)\n except Exception as exc:\n log.error(\"Do some logging here\")\n return JSONResponse(status_code=500, content=\"some content\")\n```\n\n```py\nfrom typing import Callable\n\nfrom fastapi import Request, Response, HTTPException, APIRouter, FastAPI\nfrom fastapi.routing import APIRoute\nfrom .logging import logger\n\n\nclass RouteErrorHandler(APIRoute):\n \"\"\"Custom APIRoute that handles application errors and exceptions\"\"\"\n\n def get_route_handler(self) -> Callable:\n original_route_handler = super().get_route_handler()\n\n async def custom_route_handler(request: Request) -> Response:\n try:\n return await original_route_handler(request)\n except Exception as ex:\n if isinstance(ex, HTTPException):\n raise ex\n logger.exception(\"uncaught error\")\n # wrap error into pretty 500 exception\n raise HTTPException(status_code=500, detail=str(ex))\n\n return custom_route_handler\n\n\nrouter = APIRouter(route_class=RouteErrorHandler)\n\napp = FastAPI()\napp.include_router(router)\n```\n\n```text\nAPIRoute\n```\n\n```text\nclass GenericExceptionMiddleware(ExceptionMiddleware):\n\n # Intentional: Defer __init__(...) to super class ExceptionMiddleware\n\n # @Override(ExceptionMiddleware)\n def _lookup_exception_handler(\n self, exc: Exception\n ) -> Optional[Callable]:\n if isinstance(exc, HTTPException):\n return self.__http_exception_handler\n else:\n return self.__exception_handler\n\n @classmethod\n async def __http_exception_handler(cls, request: fastapi.Request, # @Debug\n ex: HTTPException):\n\n log.error(\"Unexpected error\", cause=ex)\n resp = PlainTextResponse(content=f\"Unexpected error: {ex.detail}\"\n f\"\\n\"\n f\"\\nException stack trace\"\n f\"\\n=====================\"\n f\"\\n{ex}\", # Improve to add full stack trace\n status_code=ex.status_code)\n return resp\n\n @classmethod\n async def __exception_handler(cls, request: fastapi.Request, # @Debug\n ex: Exception):\n\n log.error(\"Unexpected error\", cause=ex)\n resp = PlainTextResponse(content=f\"Unexpected error: {ex}\"\n f\"\\n\"\n f\"\\nException stack trace\"\n f\"\\n=====================\"\n f\"\\n{ex}\", # Improve to add full stack trace\n status_code=fastapi.status.HTTP_500_INTERNAL_SERVER_ERROR)\n return resp\n```\n\n```text\nfast_api = FastAPI()\nfast_api.add_middleware(GenericExceptionMiddleware, debug=fast_api.debug)\n```\n\n```text\nstarlette.middleware.exceptions.ExceptionMiddleware\n```\n\n```text\n_lookup_exception_handler()\n```\n\n```text\nstarlette.applications.Starlette.build_middleware_stack()\n```\n\n========================================\n\nComments:\n- Ajeet I must say that I cannot reproduce your problems using fastapi[all]==0.65.1 and starlette==0.14.2 . I have a project with the exact setup as you describe except that I have an additional `return JSONResponse(status_code=500, content={\"message\": \"internal server error\"})` in `exception_callback`.\n- Related answers can be found here and here, as well as here and here\n- Future readers might find this answer helpful as well, which demonstrates how to catch any `Exception`, including Starlette's `HTTPException`.\n- This code doesn't work for me. Unless I change the exception handler to @app.exception_handler(ArithmeticError), which is what OP is describing (parent class Exception not catching derived classes). I am not sure if this is a working solution.\n- For me it works (I get to the handler for ValueError) but remember that this doesn't catch an exception so exception will propagate further.\n- First I invite you to get familiar with the question. You can realize that the OP is already doing same thing that you suggested. Secondly read through what exactly OP is asking. They are proficient and don't need consultation on Python basics. What you must understand is that \"debug\" mode of FastAPI is catching exceptions prior to such a handler.\n- the 'middleware' example doesn't work for me but the usage of 'route' in the official documentation works like a charm fastapi.tiangolo.com/advanced/custom-request-and-route/…\n- from Starlette 0.21.0 it's possible to to use BackgroundTasks with BaseHTTPMiddleware see github.com/laurentS/slowapi/issues/98#issuecomment-125982673‌​9\n- With recent fastapi 0.115.11 and starlette 0.46.0, using Response in this way in the middleware generates `anyio.WouldBlock` exception. Sorry, still trying to find a way out.\n- This is a great solution that actually worked for me.\n- As mentioned above this still produces an \"Exception in ASGI application_\"\n- @Chris Now it must be fixed since version 0.15. I did not test it yet.\n- What I did to prevent \"Exception in ASGI application_\" was to add a noop middleware like so: `async def noop_middleware(request, call_next): return await call_next(request)` `app.middleware(\"http\")(noop_middleware)`\n- While this works in the app, I have found issues with this approach during testing using TestApp and pytest when trying to throw in some exception for chaos engineering. I haven't been able to resolve them, it seems the exception is just not handled and it bubbles breaking the test\n- but this seems to work if `raise_server_exceptions=False` is set in TestClient\n- This was fixed by Starlette\n- Note that `@app.exception_handler`s appear to be invoked *after* the route handler is called. You will need to check for and `raise` any other exception type that you have define an app exception handler for, e.g. `RequestValidationError`.\n- I found this solution to be optimal, with the only caveat that as per fastapi.tiangolo.com/how-to/custom-request-and-route/… I had to `app.router.route_class = RouteErrorHandler` in `fastapi==0.111.0`","metadata":{"transformedAt":"2026-08-18T18:32:29.087Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":29,"totalLines":364,"estimatedTokens":2873}}31{"id":"stack-60127234","source":"stackoverflow","questionId":60127234,"title":"How to use a Pydantic model with Form data in FastAPI?","tags":["python","fastapi","pydantic"],"text":"Title: How to use a Pydantic model with Form data in FastAPI?\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI am trying to submit data from HTML forms and validate it with a Pydantic model.\n\nUsing this code\n\n```\nfrom fastapi import FastAPI, Form\nfrom pydantic import BaseModel\nfrom starlette.responses import HTMLResponse\n\napp = FastAPI()\n\n@app.get(\"/form\", response_class=HTMLResponse)\ndef form_get():\n return ''' \n \n \n \n '''\n\nclass SimpleModel(BaseModel):\n no: int\n nm: str = \"\"\n\n@app.post(\"/form\", response_model=SimpleModel)\ndef form_post(form_data: SimpleModel = Form(...)):\n return form_data\n```\n\nHowever, I get the HTTP error: \"`422` Unprocessable Entity\"\n\n```\n{\n \"detail\": [\n {\n \"loc\": [\n \"body\",\n \"form_data\"\n ],\n \"msg\": \"field required\",\n \"type\": \"value_error.missing\"\n }\n ]\n}\n```\n\nThe equivalent curl command (generated by Firefox) is\n\n```\ncurl 'http://localhost:8001/form' -H 'Content-Type: application/x-www-form-urlencoded' --data 'no=1&nm=abcd'\n```\n\nHere the request body contains `no=1&nm=abcd`.\n\nWhat am I doing wrong?\n\n========================================\n\nTop Answer:\nYou can do this even simpler using dataclasses\n\n```\nfrom dataclasses import dataclass\nfrom fastapi import FastAPI, Form, Depends\nfrom starlette.responses import HTMLResponse\n\napp = FastAPI()\n\n@app.get(\"/form\", response_class=HTMLResponse)\ndef form_get():\n return ''' \n \n \n \n '''\n\n@dataclass\nclass SimpleModel:\n no: int = Form(...)\n nm: str = Form(...)\n\n@app.post(\"/form\")\ndef form_post(form_data: SimpleModel = Depends()):\n return form_data\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI, Form\nfrom pydantic import BaseModel\nfrom starlette.responses import HTMLResponse\n\n\napp = FastAPI()\n\n@app.get(\"/form\", response_class=HTMLResponse)\ndef form_get():\n return '''<form method=\"post\"> \n <input type=\"text\" name=\"no\" value=\"1\"/> \n <input type=\"text\" name=\"nm\" value=\"abcd\"/> \n <input type=\"submit\"/> \n </form>'''\n\n\nclass SimpleModel(BaseModel):\n no: int\n nm: str = \"\"\n\n@app.post(\"/form\", response_model=SimpleModel)\ndef form_post(form_data: SimpleModel = Form(...)):\n return form_data\n```\n\n```text\n{\n \"detail\": [\n {\n \"loc\": [\n \"body\",\n \"form_data\"\n ],\n \"msg\": \"field required\",\n \"type\": \"value_error.missing\"\n }\n ]\n}\n```\n\n```none\ncurl 'http://localhost:8001/form' -H 'Content-Type: application/x-www-form-urlencoded' --data 'no=1&nm=abcd'\n```\n\n```text\n422\n```\n\n```text\nno=1&nm=abcd\n```\n\n```text\nclass AnyForm(BaseModel):\n any_param: str\n any_other_param: int = 1\n\n @classmethod\n def as_form(\n cls,\n any_param: str = Form(...),\n any_other_param: int = Form(1)\n ) -> AnyForm:\n return cls(any_param=any_param, any_other_param=any_other_param)\n\n@router.post('')\nasync def any_view(form_data: AnyForm = Depends(AnyForm.as_form)):\n ...\n```\n\n```text\nimport inspect\nfrom typing import Type\n\nfrom fastapi import Form\nfrom pydantic import BaseModel\nfrom pydantic.fields import ModelField\n\ndef as_form(cls: Type[BaseModel]):\n new_parameters = []\n\n for field_name, model_field in cls.__fields__.items():\n model_field: ModelField # type: ignore\n\n new_parameters.append(\n inspect.Parameter(\n model_field.alias,\n inspect.Parameter.POSITIONAL_ONLY,\n default=Form(...) if model_field.required else Form(model_field.default),\n annotation=model_field.outer_type_,\n )\n )\n\n async def as_form_func(**data):\n return cls(**data)\n\n sig = inspect.signature(as_form_func)\n sig = sig.replace(parameters=new_parameters)\n as_form_func.__signature__ = sig # type: ignore\n setattr(cls, 'as_form', as_form_func)\n return cls\n```\n\n```text\n@as_form\nclass Test(BaseModel):\n param: str\n a: int = 1\n b: str = '2342'\n c: bool = False\n d: Optional[float] = None\n\n\n@router.post('/me', response_model=Test)\nasync def me(request: Request, form: Test = Depends(Test.as_form)):\n return form\n```\n\n```text\n@app.post(\"/form\", response_model=SimpleModel)\ndef form_post(no: int = Form(...),nm: str = Form(...)):\n return SimpleModel(no=no,nm=nm)\n```\n\n```text\nfrom fastapi import Form, Depends\n\nclass AnyForm:\n def __init__(self, any_param: str = Form(...), any_other_param: int = Form(1)):\n self.any_param = any_param\n self.any_other_param = any_other_param\n\n def __str__(self):\n return \"AnyForm \" + str(self.__dict__)\n\n@app.post('/me')\nasync def me(form: AnyForm = Depends()):\n print(form)\n return form\n```\n\n```text\nfrom uuid import UUID, uuid4\nfrom fastapi import Form, Depends\nfrom pydantic import BaseModel\n\nclass AnyForm(BaseModel):\n id: UUID\n any_param: str\n any_other_param: int\n\n def __init__(self, any_param: str = Form(...), any_other_param: int = Form(1)):\n id = uuid4()\n super().__init__(id, any_param, any_other_param)\n\n@app.post('/me')\nasync def me(form: AnyForm = Depends()):\n print(form)\n return form\n```\n\n```text\nfrom fastapi.testclient import TestClient\nfrom fastapi import FastAPI, Depends, Form\nfrom pydantic import BaseModel\n\n\napp = FastAPI()\n\n\ndef form_body(cls):\n cls.__signature__ = cls.__signature__.replace(\n parameters=[\n arg.replace(default=Form(...))\n for arg in cls.__signature__.parameters.values()\n ]\n )\n return cls\n\n\n@form_body\nclass Item(BaseModel):\n name: str\n another: str\n\n\n@app.post('/test', response_model=Item)\ndef endpoint(item: Item = Depends(Item)):\n return item\n\n\ntc = TestClient(app)\n\n\nr = tc.post('/test', data={'name': 'name', 'another': 'another'})\n\nassert r.status_code == 200\nassert r.json() == {'name': 'name', 'another': 'another'}\n```\n\n```py\nfrom fastapi import Form\n\nclass SomeForm:\n\n def __init__(\n self,\n username: str = Form(...),\n password: str = Form(...),\n authentication_code: str = Form(...)\n ):\n self.username = username\n self.password = password\n self.authentication_code = authentication_code\n\n\n@app.post(\"/login\", tags=['Auth & Users'])\nasync def auth(\n user: SomeForm = Depends()\n):\n # return something / set cookie\n```\n\n```js\nconst fd = new FormData()\nfd.append('username', username)\nfd.append('password', password)\n\naxios.post(`/login`, fd)\n```\n\n```py\nfrom dataclasses import dataclass\nfrom fastapi import FastAPI, Form, Depends\nfrom starlette.responses import HTMLResponse\n\napp = FastAPI()\n\n\n@app.get(\"/form\", response_class=HTMLResponse)\ndef form_get():\n return '''<form method=\"post\"> \n <input type=\"text\" name=\"no\" value=\"1\"/> \n <input type=\"text\" name=\"nm\" value=\"abcd\"/> \n <input type=\"submit\"/> \n </form>'''\n\n\n@dataclass\nclass SimpleModel:\n no: int = Form(...)\n nm: str = Form(...)\n\n\n@app.post(\"/form\")\ndef form_post(form_data: SimpleModel = Depends()):\n return form_data\n```\n\n```py\n# Example usage\nclass ExampleForm(FormBaseModel):\n name: str\n age: int\n\n@api.post(\"/test\")\nasync def endpoint(form: ExampleForm = Depends(ExampleForm.as_form)):\n return form.dict()\n```\n\n```py\nimport inspect\nfrom pydantic import BaseModel, ValidationError\nfrom fastapi import Form\nfrom fastapi.exceptions import RequestValidationError\n\nclass FormBaseModel(BaseModel):\n\n def __init_subclass__(cls, *args, **kwargs):\n field_default = Form(...)\n new_params = []\n schema_params = []\n for field in cls.__fields__.values():\n new_params.append(\n inspect.Parameter(\n field.alias,\n inspect.Parameter.POSITIONAL_ONLY,\n default=Form(field.default) if not field.required else field_default,\n annotation=inspect.Parameter.empty,\n )\n )\n schema_params.append(\n inspect.Parameter(\n field.alias,\n inspect.Parameter.POSITIONAL_ONLY,\n default=Form(field.default) if not field.required else field_default,\n annotation=field.annotation,\n )\n )\n\n async def _as_form(**data):\n try:\n return cls(**data)\n except ValidationError as e:\n raise RequestValidationError(e.raw_errors)\n\n async def _schema_mocked_call(**data):\n \"\"\"\n A fake version which is given the actual annotations, rather than typing.Any,\n this version is used to generate the API schema, then the routes revert back to the original afterwards.\n \"\"\"\n pass\n\n _as_form.__signature__ = inspect.signature(_as_form).replace(parameters=new_params) # type: ignore\n setattr(cls, \"as_form\", _as_form)\n _schema_mocked_call.__signature__ = inspect.signature(_schema_mocked_call).replace(parameters=schema_params) # type: ignore\n # Set the schema patch func as an attr on the _as_form func so it can be accessed later from the route itself:\n setattr(_as_form, \"_schema_mocked_call\", _schema_mocked_call)\n\n @staticmethod\n def as_form(parameters=[]) -> \"FormBaseModel\":\n raise NotImplementedError\n```\n\n```py\nfrom fastapi.routing import APIRoute\nfrom fastapi import FastAPI\nfrom fastapi.openapi.utils import get_openapi\nfrom fastapi.dependencies.utils import get_dependant, get_body_field\n\napi = FastAPI()\n\n\ndef custom_openapi():\n if api.openapi_schema:\n return api.openapi_schema\n\n def create_reset_callback(route, deps, body_field):\n def reset_callback():\n route.dependant.dependencies = deps\n route.body_field = body_field\n\n return reset_callback\n\n # The functions to call after schema generation to reset the routes to their original state:\n reset_callbacks = []\n\n for route in api.routes:\n if isinstance(route, APIRoute):\n orig_dependencies = list(route.dependant.dependencies)\n orig_body_field = route.body_field\n\n is_modified = False\n for dep_index, dependency in enumerate(route.dependant.dependencies):\n # If it's a form dependency, set the annotations to their true values:\n if dependency.call.__name__ == \"_as_form\": # type: ignore\n is_modified = True\n route.dependant.dependencies[dep_index] = get_dependant(\n path=dependency.path if dependency.path else route.path,\n # This mocked func was set as an attribute on the original, correct function,\n # replace it here temporarily:\n call=dependency.call._schema_mocked_call, # type: ignore\n name=dependency.name,\n security_scopes=dependency.security_scopes,\n use_cache=False, # Overriding, so don't want cached actual version.\n )\n\n if is_modified:\n route.body_field = get_body_field(dependant=route.dependant, name=route.unique_id)\n\n reset_callbacks.append(\n create_reset_callback(route, orig_dependencies, orig_body_field)\n )\n\n openapi_schema = get_openapi(\n title=\"foo\",\n version=\"bar\",\n routes=api.routes,\n )\n\n for callback in reset_callbacks:\n callback()\n\n api.openapi_schema = openapi_schema\n return api.openapi_schema\n\n\napi.openapi = custom_openapi # type: ignore[assignment]\n```\n\n```text\ntyping.Any\n```\n\n```text\nform_utils.py\n```\n\n```text\n# asgi.py\n```\n\n```text\ndef as_form(cls):\n new_params = [\n inspect.Parameter(\n field_name,\n inspect.Parameter.POSITIONAL_ONLY,\n default=model_field.default,\n annotation=Annotated[model_field.annotation, *model_field.metadata, Form()],\n )\n for field_name, model_field in cls.model_fields.items()\n ]\n\n cls.__signature__ = cls.__signature__.replace(parameters=new_params)\n\n return cls\n```\n\n```text\ndef before_validate_int(value: int) -> int:\n raise ValueError('before int')\n\n\nMyInt = Annotated[int, BeforeValidator(before_validate_int)]\n\n\n@as_form\nclass User(BaseModel):\n age: MyInt\n\n\n@app.post(\"/postdata\")\ndef postdata(user: User = Depends()):\n return {\"age\": user.age}\n```\n\n```text\n{\n \"detail\": [\n {\n \"type\": \"value_error\",\n \"loc\": [\n \"body\",\n \"age\"\n ],\n \"msg\": \"Value error, before int\",\n \"input\": \"12\",\n \"ctx\": {\n \"error\": {}\n },\n \"url\": \"https://errors.pydantic.dev/2.3/v/value_error\"\n }\n ]\n}\n```\n\n```py\nfrom typing import Any\nimport inspect\n\nfrom pydantic import BaseModel, ValidationError\nfrom fastapi import Form\nfrom fastapi.exceptions import RequestValidationError\n\napi = FastAPI()\n\nclass FormBaseModel(BaseModel):\n @classmethod\n def __pydantic_init_subclass__(cls, *args: Any, **kwargs: Any) -> None:\n super().__pydantic_init_subclass__(*args, **kwargs)\n new_params = []\n schema_params = []\n for field_name, field in cls.model_fields.items():\n field_default = Form(...)\n new_params.append(\n inspect.Parameter(\n field_name,\n inspect.Parameter.POSITIONAL_ONLY,\n default=Form(field.default) if not field.is_required() else field_default,\n annotation=inspect.Parameter.empty,\n )\n )\n schema_params.append(\n inspect.Parameter(\n field_name,\n inspect.Parameter.POSITIONAL_ONLY,\n default=Form(field.default) if not field.is_required() else field_default,\n annotation=field.annotation,\n )\n )\n\n async def _as_form(**data: dict[str, Any]) -> BaseModel:\n try:\n return cls(**data)\n except ValidationError as e:\n raise RequestValidationError(e.raw_errors)\n\n async def _schema_mocked_call(**data: dict[str, Any]) -> None:\n \"\"\"\n A fake version which is given the actual annotations, rather than typing.Any,\n this version is used to generate the API schema, then the routes revert back to the original afterwards.\n \"\"\"\n pass\n\n _as_form.__signature__ = inspect.signature(_as_form).replace(parameters=new_params) # type: ignore\n setattr(cls, \"as_form\", _as_form)\n _schema_mocked_call.__signature__ = inspect.signature(_schema_mocked_call).replace( # type: ignore\n parameters=schema_params\n )\n # Set the schema patch func as an attr on the _as_form func so it can be accessed later from the route itself:\n setattr(_as_form, \"_schema_mocked_call\", _schema_mocked_call)\n\n @staticmethod\n def as_form(parameters: list[str] = []) -> \"FormBaseModel\":\n raise NotImplementedError\n\napi.openapi = custom_openapi # type: ignore[assignment]\n```\n\n```text\n# form_utils.py\n```\n\n```py\nfrom typing import Annotated\n\nfrom fastapi import FastAPI, Form\nfrom pydantic import BaseModel\n\napp = FastAPI()\n\n\nclass FormData(BaseModel):\n username: str\n password: str\n\n\n@app.post(\"/login/\")\nasync def login(data: Annotated[FormData, Form()]):\n return data\n```\n\n========================================\n\nComments:\n- Well looks like the body is empty, or at least `form_data` is missing. But impossible to help more without seeing what you're submitting.\n- In the above code GET request gives a HTML form, I click submit on that. I get error for all values i give.\n- The first step to working out what's going wrong is to inspect the POST request and see what's being submitted.\n- The request body contains `no=1&nm=abcd`\n- Please have a look at this and this answer as well.\n- Thanks for the answer but this doesn't help. I am asking for specific usage. I am trying to avoid any extra code adding complexity. Also I plan to mix this with other simple variables/files submitted from form. Similar to what can be done using `Path` or `Body`\n- Not sure how this is helpful. Can you give a short working example.\n- Check it out now\n- how is the body model named in the swagger ui using this? Thats the only reason I want to use a Pydantic class.\n- this solution isn't working with fastapi 0.103.0\n- Solution for fastapi 0.103.1: stackoverflow.com/a/77113651/7433128\n- FastAPI 0.113.0 added first class support for using Pydantic models as Form fields: fastapi.tiangolo.com/tutorial/request-form-models\n- @MatsLindh If I include binary data (images) inside the model, it works well also, but on Swagger application/x-www-form-urlencoded as content-type is given instead of multipart/form-data, and using application/x-www-form-urlencoded gives 422.\n- Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.\n- This solution is the cleanest looking but is it the fastest approach in terms of data validation speed?\n- Interesting, I’ll do a comparison between this and Pydantic Dataclass on the speed and make an update.\n- Data validation speed, really? Do you really care about shaving a few milliseconds off of your HTTP requests? I'm familiar with only very few use cases where that would matter.\n- Just wondering, is there any advantage to inheriting the BaseModel pydantic class?\n- @TedStresen-Reuter, yes there are few advantages like faster serialization, support for certain data types, data validation that Pydantic offers, etc.\n- I have re-define to use pydantic BaseModel: `python class SimpleModel(BaseModel): no: int = Form(...) nm: str = Form(...)` and it takes as query again, why is that?\n- I tried your suggested solution but I get: `SyntaxError: invalid syntax. Perhaps you forgot a comma?`. in as_form definition.\n- I don't see where there could be a comma. I works in python 3.11\n- pyflakes reported the same `pyflakes:Error:invalid syntax. Perhaps you forgot a comma?` On line: `annotation=Annotated[model_field.annotation, *model_field.metadata, Form()]` However, it still works as expected. :)\n- Yes, it is the comma at the end of line. It was added by black. You can remove it.\n- Pydantic alias was not working for me. So changed `Form()` to `Form(alias=model_field.alias, alias_priority=model_field.alias_priority)`\n- annotation=Annotated[model_field.annotation, *model_field.metadata, Form()], SyntaxError: invalid syntax. Perhaps you forgot a comma? removing the last comma does not solve the problem on fastapi 0.111.1\n- It does not support multipart/form-data, which is the standard for binary/image uploads together with key-value data.","metadata":{"transformedAt":"2026-08-18T18:32:29.087Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":27,"totalLines":667,"estimatedTokens":4741}}32{"id":"stack-63069190","source":"stackoverflow","questionId":63069190,"title":"How to capture arbitrary paths at one route in FastAPI?","tags":["python","fastapi"],"text":"Title: How to capture arbitrary paths at one route in FastAPI?\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm serving **React** app from **FastAPI** by\nmounting\n\n```\napp.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")\n\n@app.route('/session')\nasync def renderReactApp(request: Request):\n return templates.TemplateResponse(\"index.html\", {\"request\": request})\n```\n\nby this React app get served and React routing also works fine at client side\nbut as soon as client reloads on a route which is not defined on server but used in React app FastAPI return `not found` to fix this I did something as below.\n\n- `@app.route('/network')`\n\n- `@app.route('/gat')`\n\n- `@app.route('/session')`\n\n```\nasync def renderReactApp(request: Request):\n return templates.TemplateResponse(\"index.html\", {\"request\": request})\n```\n\nbut it seems weird and wrong to me as I need to add every route at the back-end as well as at frontend.\n\nI'm sure there must be something like Flask `@flask_app.add_url_rule('/', 'index', index)` in FastAPI which will server all arbitrary path\n\n========================================\n\nTop Answer:\nAs @mecampbellsoup pointed out: there are usually other static files that need to be served with an application like this.\n\nHopefully this comes in handy to someone else:\n\n```\nimport os\nfrom typing import Tuple\n\nfrom fastapi import FastAPI\nfrom fastapi.staticfiles import StaticFiles\n\napp = FastAPI()\n\nclass SinglePageApplication(StaticFiles):\n \"\"\"Acts similar to the bripkens/connect-history-api-fallback\n NPM package.\"\"\"\n\n def __init__(self, directory: os.PathLike, index='index.html') -> None:\n self.index = index\n\n # set html=True to resolve the index even when no\n # the base path is passed in\n super().__init__(directory=directory, packages=None, html=True, check_dir=True)\n\n async def lookup_path(self, path: str) -> Tuple[str, os.stat_result]:\n \"\"\"Returns the index file when no match is found.\n\n Args:\n path (str): Resource path.\n\n Returns:\n [tuple[str, os.stat_result]]: Always retuens a full path and stat result.\n \"\"\"\n full_path, stat_result = await super().lookup_path(path)\n\n # if a file cannot be found\n if stat_result is None:\n return await super().lookup_path(self.index)\n\n return (full_path, stat_result)\n\napp.mount(\n path='/',\n app=SinglePageApplication(directory='path/to/dist'),\n name='SPA'\n)\n```\n\nThese modifications make the StaticFiles mount act similar to the connect-history-api-fallback NPM package.\n\n========================================\n\nCode:\n```text\napp.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")\n\n@app.route('/session')\nasync def renderReactApp(request: Request):\n return templates.TemplateResponse(\"index.html\", {\"request\": request})\n```\n\n```text\nasync def renderReactApp(request: Request):\n return templates.TemplateResponse(\"index.html\", {\"request\": request})\n```\n\n```text\nnot found\n```\n\n```text\n@app.route('/network')\n```\n\n```text\n@app.route('/gat')\n```\n\n```text\n@app.route('/session')\n```\n\n```text\n@flask_app.add_url_rule('/<path:path>', 'index', index)\n```\n\n```text\n@app.get(\"/my-app/{rest_of_path:path}\")\nasync def serve_my_app(request: Request, rest_of_path: str):\n print(\"rest_of_path: \"+rest_of_path)\n return templates.TemplateResponse(\"index.html\", {\"request\": request})\n```\n\n```text\n@app.route(\"/{full_path:path}\")\nasync def catch_all(request: Request, full_path: str):\n print(\"full_path: \"+full_path)\n return templates.TemplateResponse(\"index.html\", {\"request\": request})\n```\n\n```text\npath\n```\n\n```text\n/\n```\n\n```text\n/my-app/\n```\n\n```text\nrest_of_path\n```\n\n```text\n/my-app/\n```\n\n```text\n/my-app/\n```\n\n```text\n/my-app\n```\n\n```text\n├── main.py\n└── routers\n └── my_router.py\n```\n\n```text\nfrom fastapi import APIRouter\n\nrouter = APIRouter()\n\n@router.get(\"/some\")\nasync def some_path():\n pass\n\n@router.get(\"/path\")\nasync def some_other_path():\n pass\n\n@router.post(\"/some_post_path\")\nasync def some_post_path():\n pass\n```\n\n```text\nfrom routers import my_router\n```\n\n```text\nfrom fastapi import FastAPI\nfrom routers import my_router\n\napp = FastAPI()\n```\n\n```text\nfrom fastapi import FastAPI\nfrom routers import my_router\n\napp = FastAPI()\n\napp.include_router(my_router.router)\n```\n\n```text\nfrom fastapi import FastAPI\nfrom routers import my_router\n\napp = FastAPI()\n\n\napp.include_router(\n my_router.router,\n prefix=\"/custom_path\",\n tags=[\"We are from router!\"],\n)\n```\n\n```text\nmy_router.py\n```\n\n```text\nmain.py\n```\n\n```text\napp.py\nroutes/\n |__helloworld.py\n |_*.py\n```\n\n```py\ndef helloworld(data):\n return data\n```\n\n```py\nfrom os.path import split, realpath\nfrom importlib.machinery import SourceFileLoader as sfl\nimport uvicorn\nfrom typing import Any\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\n\n# set app's root directory \nAPI_DIR = split(realpath(__file__))[0]\n\nclass RequestPayload(BaseModel):\n \"\"\"payload for post requests\"\"\"\n # function in `/routes` to call\n route: str = 'function_to_call'\n # data to pass to the function\n data: Any = None\n\napp = FastAPI()\n\n@app.post('/api')\nasync def api(payload: RequestPayload):\n \"\"\"post request to call function\"\"\"\n # load `.py` file from `/routes`\n route = sfl(payload.route,\n f'{API_DIR}/routes/{payload.route}.py').load_module()\n # load function from `.py` file\n func = getattr(route, payload.route)\n # check if function requires data\n if ('data' not in payload.dict().keys()):\n return func()\n return func(payload.data)\n```\n\n```sh\ncurl -X POST \"http://localhost:70/api\" -H \"accept: application/json\" -H \"Content-Type: application/json\" -d \"{\\\"route\\\":\\\"helloworld\\\",\\\"data\\\":{\\\"hello\\\": \\\"world\\\"}}\"\n```\n\n```py\ndef get_network(id: str):\n network_name = ''\n # logic to retrieve network by id from db\n return network_name\n```\n\n```py\ndef delete_network(id: str):\n network_deleted = False\n # logic to delete network by id from db\n return network_deleted\n```\n\n```text\n*.py\n```\n\n```text\nroutes/\n```\n\n```text\n{\"hello\": \"world\"}\n```\n\n```text\nget_network.py\n```\n\n```text\ndelete_network.py\n```\n\n```text\nroutes/\n```\n\n```text\n{\"route\": \"get_network\", \"data\": \"network_id\"}\n```\n\n```text\n{\"route\": \"delete_network\", \"data\": \"network_id\"}\n```\n\n```py\nimport os\nfrom typing import Tuple\n\nfrom fastapi import FastAPI\nfrom fastapi.staticfiles import StaticFiles\n\napp = FastAPI()\n\n\nclass SinglePageApplication(StaticFiles):\n \"\"\"Acts similar to the bripkens/connect-history-api-fallback\n NPM package.\"\"\"\n\n def __init__(self, directory: os.PathLike, index='index.html') -> None:\n self.index = index\n\n # set html=True to resolve the index even when no\n # the base path is passed in\n super().__init__(directory=directory, packages=None, html=True, check_dir=True)\n\n async def lookup_path(self, path: str) -> Tuple[str, os.stat_result]:\n \"\"\"Returns the index file when no match is found.\n\n Args:\n path (str): Resource path.\n\n Returns:\n [tuple[str, os.stat_result]]: Always retuens a full path and stat result.\n \"\"\"\n full_path, stat_result = await super().lookup_path(path)\n\n # if a file cannot be found\n if stat_result is None:\n return await super().lookup_path(self.index)\n\n return (full_path, stat_result)\n\n\n\napp.mount(\n path='/',\n app=SinglePageApplication(directory='path/to/dist'),\n name='SPA'\n)\n```\n\n```py\nfrom pathlib import Path\nfrom typing import Union\n\nfrom fastapi import FastAPI, Request\nfrom fastapi.staticfiles import StaticFiles\nfrom fastapi.templating import Jinja2Templates\n\n\ndef serve_react_app(app: FastAPI, build_dir: Union[Path, str]) -> FastAPI:\n \"\"\"Serves a React application in the root directory `/`\n\n Args:\n app: FastAPI application instance\n build_dir: React build directory (generated by `yarn build` or\n `npm run build`)\n\n Returns:\n FastAPI: instance with the react application added\n \"\"\"\n if isinstance(build_dir, str):\n build_dir = Path(build_dir)\n\n app.mount(\n \"/static/\",\n StaticFiles(directory=build_dir / \"static\"),\n name=\"React App static files\",\n )\n templates = Jinja2Templates(directory=build_dir.as_posix())\n\n @app.get(\"/{full_path:path}\")\n async def serve_react_app(request: Request, full_path: str):\n \"\"\"Serve the react app\n `full_path` variable is necessary to serve each possible endpoint with\n `index.html` file in order to be compatible with `react-router-dom\n \"\"\"\n return templates.TemplateResponse(\"index.html\", {\"request\": request})\n\n return app\n```\n\n```py\nimport uvicorn\nfrom fastapi import FastAPI\n\n\napp = FastAPI()\n\npath_to_react_app_build_dir = \"./frontend/build\"\napp = serve_react_app(app, path_to_react_app_build_dir)\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", port=8001)\n```\n\n```text\nreact-router\n```\n\n```text\nreact-router\n```\n\n```text\ncreate-react-app\n```\n\n```text\nfrom starlette.routing import Route\n\napp.mount(\"/static\", StaticFiles(directory=static_path), name=\"static\")\n\nasync def catch_all(request: Request, **kwargs):\n return templates.TemplateResponse(\"index.html\", {\"request\": request})\n\ncatch_all_route = Route('/{path:path}', catch_all)\napp.routes.append(catch_all_route)\n```\n\n```text\n@app.route\n```\n\n========================================\n\nComments:\n- Can you the full error message?\n- hey @YagizcanDegirmenci I'm not getting any error\n- Does this helps? returning react frontend from fastapi backend\n- Unfortunately, I'm not looking for a way to render a web app. I am looking for a way in FastAPI using which (single route) I can serve multiple route requests. `@app.route(\"/some-route\") def serveAllRoute(): # servers /some-route as well as /another-woute`\n- Ah got it, needed this explanation, check my answer below.\n- I have this same issue. What is `templates` in this code?\n- You are still defining all the routes. Are you aware of this flask feature stackoverflow.com/a/15117464/4887475 We are looking for same\n- Assuming there are other static files in addition to `index.html` (e.g. JS, CSS, asset files) in the OP's static directory that he has mounted i.e. `app.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")`, won't this strategy prevent those being served by fastapi?\n- @mecampbellsoup no it shouldn't interfere with that if you have the `catch_all` after the static definition, and after all other routes for that matter. You want your catch-all method at the end. In fact, React builds tend to have html, js and css files that all get stashed in the static dir -- this approach will serve all of those files and others as expected.\n- missing 1 required positional argument: 'rest_of_path'\n- super().lookup_path(path) is not async function so in my case, I have to remove await\n- I have a question about this method. How do you know what host to specify in the react app when making calls to the FAST API other endpoints? For example, you have an endpoint in your API like `/books/{book_id}` and you want to call this endpoint from the react app that's served in this method. Your FASTAPI currently is on localhost, but you don't want to hardcode `localhost/books/{book_id}` how do you replace this 'localhost' with the IP FASTAPI server is running on?\n- @Curtwagner1984 I am not really sure that I understood your question but I think that the answer to it is to tell you that by default, when you call `fetch` if you pass a route like \"/favicon.ico\" to the path parameter, it will automatically assume that the full path is `https://www./favicon.ico`","metadata":{"transformedAt":"2026-08-18T18:32:29.087Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":46,"totalLines":473,"estimatedTokens":2899}}33{"id":"stack-62976648","source":"stackoverflow","questionId":62976648,"title":"Architecture Flask vs FastAPI","tags":["python","fastapi"],"text":"Title: Architecture Flask vs FastAPI\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have been tinkering around Flask and FastAPI to see how it acts as a server.\n\nOne of the main things that I would like to know is how Flask and FastAPI deal with multiple requests from multiple clients.\n\nEspecially when the code has efficiency issues (long database query time).\n\nSo, I tried making a simple code to understand this problem.\n\nThe code is simple, when the client access the route, the application sleeps for 10 seconds before it returns results.\n\nIt looks something like this:\n\n**FastAPI**\n\n```\nimport uvicorn\nfrom fastapi import FastAPI\nfrom time import sleep\napp = FastAPI()\n\n@app.get('/')\nasync def root():\n print('Sleeping for 10')\n sleep(10)\n print('Awake')\n return {'message': 'hello'}\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"127.0.0.1\", port=8000)\n```\n\n**Flask**\n\n```\nfrom flask import Flask\nfrom flask_restful import Resource, Api\nfrom time import sleep\n\napp = Flask(__name__)\napi = Api(app)\n\nclass Root(Resource):\n def get(self):\n print('Sleeping for 10')\n sleep(10)\n print('Awake')\n return {'message': 'hello'}\n\napi.add_resource(Root, '/')\n\nif __name__ == \"__main__\":\n app.run()\n```\n\nOnce the applications are up, I tried accessing them at the same time through 2 different chrome clients.\nThe below are the results:\n\n**FastAPI**\n\n**Flask**\n\nAs you can see, for FastAPI, the code first waits 10 seconds before processing the next request. Whereas for Flask, the code processes the next request while the 10-second sleep is still happening.\n\nDespite doing a bit of googling, there is not really a straight answer on this topic.\n\nIf anyone has any comments that can shed some light on this, please drop them in the comments.\n\nYour opinions are all appreciated. Thank you all very much for your time.\n\n**EDIT**\nAn update on this, I am exploring a bit more and found this concept of Process manager. For example, we can run uvicorn using a process manager (gunicorn). By adding more workers, I am able to achieve something like Flask. Still testing the limits of this, however.\nhttps://www.uvicorn.org/deployment/\n\nThanks to everyone who left comments! Appreciate it.\n\n========================================\n\nTop Answer:\nYou are using the `time.sleep()` function, in a `async` endpoint. `time.sleep()` is blocking and should never be used in asynchronous code. What you should be using is probably the `asyncio.sleep()` function:\n\n```\nimport asyncio\nimport uvicorn\nfrom fastapi import FastAPI\napp = FastAPI()\n\n@app.get('/')\nasync def root():\n print('Sleeping for 10')\n await asyncio.sleep(10)\n print('Awake')\n return {'message': 'hello'}\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"127.0.0.1\", port=8000)\n```\n\nThat way, each request will take ~10 sec to complete, but you will be able to serve multiple requests concurrently.\n\nIn general, async frameworks offer replacements for all blocking functions inside the standard library (sleep functions, IO functions, etc.). You are meant to use those replacements when writing async code and (optionally) `await` them.\n\nSome non-blocking frameworks and libraries such as gevent, do not offer replacements. They instead monkey-patch functions in the standard library to make them non-blocking. This is not the case, as far as I know, for the newer async frameworks and libraries though, because they are meant to allow the developer to use the async-await syntax.\n\n========================================\n\nCode:\n```text\nimport uvicorn\nfrom fastapi import FastAPI\nfrom time import sleep\napp = FastAPI()\n\n@app.get('/')\nasync def root():\n print('Sleeping for 10')\n sleep(10)\n print('Awake')\n return {'message': 'hello'}\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"127.0.0.1\", port=8000)\n```\n\n```text\nfrom flask import Flask\nfrom flask_restful import Resource, Api\nfrom time import sleep\n\napp = Flask(__name__)\napi = Api(app)\n\nclass Root(Resource):\n def get(self):\n print('Sleeping for 10')\n sleep(10)\n print('Awake')\n return {'message': 'hello'}\n\napi.add_resource(Root, '/')\n\nif __name__ == \"__main__\":\n app.run()\n```\n\n```text\nfrom flask import Flask\nfrom flask_restful import Resource, Api\n\n\napp = Flask(__name__)\napi = Api(app)\n\n\nclass Root(Resource):\n def get(self):\n return {\"message\": \"hello\"}\n\n\napi.add_resource(Root, \"/\")\n```\n\n```text\nfrom fastapi import FastAPI\n\n\napp = FastAPI(debug=False)\n\n\n@app.get(\"/\")\nasync def root():\n return {\"message\": \"hello\"}\n```\n\n```text\nConcurrency Level: 500\nTime taken for tests: 0.577 seconds\nComplete requests: 5000\nFailed requests: 0\nTotal transferred: 720000 bytes\nHTML transferred: 95000 bytes\nRequests per second: 8665.48 [#/sec] (mean)\nTime per request: 57.700 [ms] (mean)\nTime per request: 0.115 [ms] (mean, across all concurrent requests)\nTransfer rate: 1218.58 [Kbytes/sec] received\n\nConnection Times (ms)\n min mean[+/-sd] median max\nConnect: 0 6 4.5 6 30\nProcessing: 6 49 21.7 45 126\nWaiting: 1 42 19.0 39 124\nTotal: 12 56 21.8 53 127\n\nPercentage of the requests served within a certain time (ms)\n 50% 53\n 66% 64\n 75% 69\n 80% 73\n 90% 81\n 95% 98\n 98% 112\n 99% 116\n 100% 127 (longest request)\n```\n\n```text\nConcurrency Level: 500\nTime taken for tests: 1.562 seconds\nComplete requests: 5000\nFailed requests: 0\nTotal transferred: 720000 bytes\nHTML transferred: 95000 bytes\nRequests per second: 3200.62 [#/sec] (mean)\nTime per request: 156.220 [ms] (mean)\nTime per request: 0.312 [ms] (mean, across all concurrent requests)\nTransfer rate: 450.09 [Kbytes/sec] received\n\nConnection Times (ms)\n min mean[+/-sd] median max\nConnect: 0 8 4.8 7 24\nProcessing: 26 144 13.1 143 195\nWaiting: 2 132 13.1 130 181\nTotal: 26 152 12.6 150 203\n\nPercentage of the requests served within a certain time (ms)\n 50% 150\n 66% 155\n 75% 158\n 80% 160\n 90% 166\n 95% 171\n 98% 195\n 99% 199\n 100% 203 (longest request)\n```\n\n```text\nConcurrency Level: 500\nTime taken for tests: 27.827 seconds\nComplete requests: 5000\nFailed requests: 0\nTotal transferred: 830000 bytes\nHTML transferred: 105000 bytes\nRequests per second: 179.68 [#/sec] (mean)\nTime per request: 2782.653 [ms] (mean)\nTime per request: 5.565 [ms] (mean, across all concurrent requests)\nTransfer rate: 29.13 [Kbytes/sec] received\n\nConnection Times (ms)\n min mean[+/-sd] median max\nConnect: 0 87 293.2 0 3047\nProcessing: 14 1140 4131.5 136 26794\nWaiting: 1 1140 4131.5 135 26794\nTotal: 14 1227 4359.9 136 27819\n\nPercentage of the requests served within a certain time (ms)\n 50% 136\n 66% 148\n 75% 179\n 80% 198\n 90% 295\n 95% 7839\n 98% 14518\n 99% 27765\n 100% 27819 (longest request)\n```\n\n```text\nServer Software: waitress\nServer Hostname: 127.0.0.1\nServer Port: 8000\n\nDocument Path: /\nDocument Length: 21 bytes\n\nConcurrency Level: 1000\nTime taken for tests: 3.403 seconds\nComplete requests: 5000\nFailed requests: 0\nTotal transferred: 830000 bytes\nHTML transferred: 105000 bytes\nRequests per second: 1469.47 [#/sec] (mean)\nTime per request: 680.516 [ms] (mean)\nTime per request: 0.681 [ms] (mean, across all concurrent requests)\nTransfer rate: 238.22 [Kbytes/sec] received\n\nConnection Times (ms)\n min mean[+/-sd] median max\nConnect: 0 4 8.6 0 30\nProcessing: 31 607 156.3 659 754\nWaiting: 1 607 156.3 658 753\nTotal: 31 611 148.4 660 754\n\nPercentage of the requests served within a certain time (ms)\n 50% 660\n 66% 678\n 75% 685\n 80% 691\n 90% 702\n 95% 728\n 98% 743\n 99% 750\n 100% 754 (longest request)\n```\n\n```text\nServer Software: uvicorn\nServer Hostname: 127.0.0.1\nServer Port: 8000\n\nDocument Path: /\nDocument Length: 19 bytes\n\nConcurrency Level: 1000\nTime taken for tests: 0.634 seconds\nComplete requests: 5000\nFailed requests: 0\nTotal transferred: 720000 bytes\nHTML transferred: 95000 bytes\nRequests per second: 7891.28 [#/sec] (mean)\nTime per request: 126.722 [ms] (mean)\nTime per request: 0.127 [ms] (mean, across all concurrent requests)\nTransfer rate: 1109.71 [Kbytes/sec] received\n\nConnection Times (ms)\n min mean[+/-sd] median max\nConnect: 0 28 13.8 30 62\nProcessing: 18 89 35.6 86 203\nWaiting: 1 75 33.3 70 171\nTotal: 20 118 34.4 116 243\n\nPercentage of the requests served within a certain time (ms)\n 50% 116\n 66% 126\n 75% 133\n 80% 137\n 90% 161\n 95% 189\n 98% 217\n 99% 230\n 100% 243 (longest request)\n```\n\n```text\nServer Software: uvicorn\nServer Hostname: 127.0.0.1\nServer Port: 8000\n\nDocument Path: /\nDocument Length: 19 bytes\n\nConcurrency Level: 1000\nTime taken for tests: 1.147 seconds\nComplete requests: 5000\nFailed requests: 0\nTotal transferred: 720000 bytes\nHTML transferred: 95000 bytes\nRequests per second: 4359.68 [#/sec] (mean)\nTime per request: 229.375 [ms] (mean)\nTime per request: 0.229 [ms] (mean, across all concurrent requests)\nTransfer rate: 613.08 [Kbytes/sec] received\n\nConnection Times (ms)\n min mean[+/-sd] median max\nConnect: 0 20 16.3 17 70\nProcessing: 17 190 96.8 171 501\nWaiting: 3 173 93.0 151 448\nTotal: 51 210 96.4 184 533\n\nPercentage of the requests served within a certain time (ms)\n 50% 184\n 66% 209\n 75% 241\n 80% 260\n 90% 324\n 95% 476\n 98% 504\n 99% 514\n 100% 533 (longest request)\n```\n\n```text\nApacheBench\n```\n\n```text\ngunicorn -w 4 -k uvicorn.workers.UvicornWorker fast_api:app\n```\n\n```text\nuvicorn fast_api:app --reload\n```\n\n```text\nuvicorn fastapi:app --workers 4\n```\n\n```text\nimport asyncio\nimport uvicorn\nfrom fastapi import FastAPI\napp = FastAPI()\n\n@app.get('/')\nasync def root():\n print('Sleeping for 10')\n await asyncio.sleep(10)\n print('Awake')\n return {'message': 'hello'}\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"127.0.0.1\", port=8000)\n```\n\n```text\ntime.sleep()\n```\n\n```text\nasync\n```\n\n```text\ntime.sleep()\n```\n\n```text\nasyncio.sleep()\n```\n\n```text\nawait\n```\n\n```py\nfrom time import sleep\n\nimport uvicorn\nfrom fastapi import FastAPI\n\n\napp = FastAPI()\n\n@app.get('/')\ndef root():\n print('Sleeping for 10')\n sleep(10)\n print('Awake')\n return {'message': 'hello'}\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"127.0.0.1\", port=8000)\n```\n\n```text\nsleep()\n```\n\n```text\ntime.sleep()\n```\n\n```text\nasyncio.sleep()\n```\n\n```text\nasync\n```\n\n```text\nasyncio.sleep\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\ndef\n```\n\n```text\nawait asyncio.sleep()\n```\n\n```text\nfrom fastapi import FastAPI, BackgroundTasks\nimport time\napp = FastAPI()\n\ndef sleep(msg):\n time.sleep(10)\n print(msg)\n\n@app.get('/')\nasync def root(background_tasks: BackgroundTasks):\n msg= 'Sleeping for 10'\n background_tasks.add_task(sleep, msg)\n print('Awake')\n return {'message': 'hello'}\n```\n\n========================================\n\nComments:\n- The most important part regarding performance and concurrency if not the framework used but the WSGI server and it's settings. (The built-in dev server is not suitable for production.) In an extensive tests I did I notice that it can make the diffetence between \"fails under load\" and \"hundreds of requests per second\".\n- Future readers might find this related answer helpful\n- How did you run flask app? It is strange it takes 2.7 seconds in each request for such a simple example...\n- @marianobianchi i ran with `app.run()` , with a high concurrency it's not that strange i think.\n- That's what I thought. You are comparing a production-ready server like uvicorn with a development server like Werkzeug. You should compare with flask running with waitress, which is the recommended way of deploying a production ready flask app: flask.palletsprojects.com/en/1.1.x/tutorial/deploy/…\n- @marianobianchi great, actually i benchmarked from OP's code, but i will ran the tests again with waitress and update the question with new results , thanks!\n- accurate analysis, we are compromised almost migrate to FastAPI for new versions of our products. I came across even more delays in debug mode specifically when was using behind reverse proxy.\n- And yes. There is a WSGIMIDDLEWARE for fastapi. It enables fastapi wsgi option. Could you pls try that with gunicorn with meinheld workers?\n- @YagizDegirmenci: why not compare apples with apples and run Flask with `gunicorn` too (and the same number of workers). This would be even more fair comparison IMO than using `waitress` (see: stackshare.io/stackups/gunicorn-vs-waitress).\n- @YagizDegirmenci, what is the command you have used to run \"Gunicorn with Uvicorn Workers\" test. i mean `gunicorn -k uvicorn.workers.xxx -w x` and what machine(num cpu threads, ram and OS) did you run this on? or were these tests run on docker on raw metal?\n- @NaveenReddyMarthala I ran the tests with 4 workers without docker, i don't remember the specs of the machine but should be 8 CPU.\n- Do flask 2.0's `async` capabilities change that picture?\n- why arent you running Flask with workers as well? This makes no sense...","metadata":{"transformedAt":"2026-08-18T18:32:29.088Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":31,"totalLines":527,"estimatedTokens":3460}}34{"id":"stack-65686318","source":"stackoverflow","questionId":65686318,"title":"Sharing python objects across multiple workers","tags":["python","asynchronous","python-asyncio","fastapi"],"text":"Title: Sharing python objects across multiple workers\nTags: python, asynchronous, python-asyncio, fastapi\nSource: Stack Overflow\n\nQuestion:\nWe have created a service using FastAPI. When our service starts it creates a few python objects that the endpoints then use to store or retrieve data from.\n\nFastAPI in production starts with multiple workers. Our problem is that **each worker creates its own object rather than sharing a single one**.\n\nThe script below shows a (simplified) example of what we are doing, though in our case the usage of Meta() is considerably more complex.\n\n```\nfrom fastapi import FastAPI, status\n\nclass Meta:\n def __init__(self):\n self.count = 0 \n\napp = FastAPI()\n\nmeta = Meta()\n\n# increases the count variable in the meta object by 1\n@app.get(\"/increment\")\nasync def increment():\n meta.count += 1\n return status.HTTP_200_OK\n\n# returns a json containing the current count from the meta object\n@app.get(\"/report\")\nasync def report():\n return {'count':meta.count}\n\n# resets the count in the meta object to 0\n@app.get(\"/reset\")\nasync def reset():\n meta.count = 0\n return status.HTTP_200_OK\n```\n\nAs mentioned above, the problem with multiple workers is that each one will have its own `meta` object. Please be aware that the issue is not visible when running the api with a single worker.\n\nMore explicitly, when we hit the `/increment` endpoint for the first time we will see only one of the two workers responding to the call (this is correct, we don't want both workers doing the same thing). However, because there are two separate `meta` objects, only one of the two will be incremented. \n When hitting the `/report` endpoint, depending on which worker responds to the request, either 1 or 0 will be returned.\n\nThe question then is, how do we get the workers to and operate on the same object?\n\nAs a side question, the problem above affects the `/reset` endpoint too. If this endpoint is called then only one of the workers will reset its object. Is there a way to force all workers to respond to a single call on an endpoint?\n\nThanks!\n\nEdit: I forgot to mention that we have tried (with no success) to store the `meta` object in the `app.state` instead. Essentially:\n\n```\napp.state.meta = Meta()\n...\n@app.get(\"/report\")\nasync def report():\n return {'count':app.state.meta.count}\n```\n\n========================================\n\nTop Answer:\nIf you run your FastAPI service using a setup with gunicorn and uvicorn as is described in the docs you can employ the method described here by Yagiz Degimenci in a simpler way. You can use gunicorn's `--preload` setting in combination with multiprocessing.Manager in order to avoid the necessity to start another server. In particular the following does need no extra setup to make it work in a single Docker Container.\n\n```\nimport logging\nfrom multiprocessing import Manager\n\nmanager = Manager()\n\nstore = manager.dict()\n\nstore[\"count\"] = 0\n\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.post(\"/increment\")\nasync def increment():\n store[\"count\"] = store[\"count\"] + 1\n\n@app.get(\"/count\")\nasync def get_count():\n return store[\"count\"]\n\n@app.on_event(\"startup\")\nasync def startup_event():\n uv_logger = logging.getLogger(\"uvicorn.access\")\n handler = logging.StreamHandler()\n handler.setFormatter(\n logging.Formatter(\n \"%(process)d - %(processName)s - %(asctime)s - %(levelname)s - %(message)s\"\n )\n )\n uv_logger.addHandler(handler)\n```\n\nSave this is `demo.py` and run via (you need fastapi, guvicorn and uvicorn libraries):\n\n```\nGUNICORN_CMD_ARGS=\"--bind=127.0.0.1 --workers=3 --preload --access-logfile=-\" gunicorn -k uvicorn.workers.UvicornWorker demo:app\n```\n\n(the `--preload` is essential here!)\n\nTry incrementing via the OpenApi UI at http://localhost:8000/docs and compare multiple calls to the /count endpoint with the process ids in access log output to see that it returns the incremented value regardless of which worker process is responding.\n\n**Note:** I do not make any claims about thread / async safety here and this method should probably not be employed in production services. In case of any doubt you should always rely on a proper database / caching / memory store solution for production setups. I myself only use this in demo code!\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI, status\n\nclass Meta:\n def __init__(self):\n self.count = 0 \n\napp = FastAPI()\n\nmeta = Meta()\n\n# increases the count variable in the meta object by 1\n@app.get(\"/increment\")\nasync def increment():\n meta.count += 1\n return status.HTTP_200_OK\n\n# returns a json containing the current count from the meta object\n@app.get(\"/report\")\nasync def report():\n return {'count':meta.count}\n\n# resets the count in the meta object to 0\n@app.get(\"/reset\")\nasync def reset():\n meta.count = 0\n return status.HTTP_200_OK\n```\n\n```text\napp.state.meta = Meta()\n...\n@app.get(\"/report\")\nasync def report():\n return {'count':app.state.meta.count}\n```\n\n```text\nmeta\n```\n\n```text\n/increment\n```\n\n```text\nmeta\n```\n\n```text\n/report\n```\n\n```text\n/reset\n```\n\n```text\nmeta\n```\n\n```text\napp.state\n```\n\n```text\n.\n├── app_cache.py\n├── app_db.py\n├── docker-compose.yml\n├── __init__.py\n```\n\n```text\nversion: '3'\n\nservices:\n database:\n image: postgres:12-alpine\n ports:\n - \"5432:5432\"\n environment:\n POSTGRES_PASSWORD: test_pass\n POSTGRES_USER: test_user\n POSTGRES_DB: test_db\n redis:\n image: redis:6-alpine\n ports:\n - \"6379:6379\"\n```\n\n```text\ndocker-compose up -d\n```\n\n```text\nuvicorn app_cache:app --host localhost --port 8000 --workers 5\n```\n\n```text\n# app_cache.py\nimport os\nfrom aiocache import Cache\nfrom fastapi import FastAPI, status\n\n\napp = FastAPI()\ncache = Cache(Cache.REDIS, endpoint=\"localhost\", port=6379, namespace=\"main\")\n\n\nclass Meta:\n def __init__(self):\n pass\n\n async def get_count(self) -> int:\n return await cache.get(\"count\", default=0)\n\n async def set_count(self, value: int) -> None:\n await cache.set(\"count\", value)\n\n async def increment_count(self) -> None:\n await cache.increment(\"count\", 1)\n\n\nmeta = Meta()\n\n\n# increases the count variable in the meta object by 1\n@app.post(\"/increment\")\nasync def increment():\n await meta.increment_count()\n return status.HTTP_200_OK\n\n\n# returns a json containing the current count from the meta object\n@app.get(\"/report\")\nasync def report():\n count = await meta.get_count()\n return {'count': count, \"current_process_id\": os.getpid()}\n\n\n# resets the count in the meta object to 0\n@app.post(\"/reset\")\nasync def reset():\n await meta.set_count(0)\n return status.HTTP_200_OK\n```\n\n```text\nuvicorn app_db:app --host localhost --port 8000 --workers 1\n[Ctrl-C] \nuvicorn app_db:app --host localhost --port 8000 --workers 5\n```\n\n```text\n# app_db.py\nfrom fastapi import FastAPI, status\nfrom tortoise import Model, fields\nfrom tortoise.contrib.fastapi import register_tortoise\n\n\nclass MetaModel(Model):\n count = fields.IntField(default=0)\n\n\napp = FastAPI()\n\n\n# increases the count variable in the meta object by 1\n@app.post(\"/increment\")\nasync def increment():\n meta, is_created = await MetaModel.get_or_create(id=1)\n meta.count += 1 # it's better do it in transaction\n await meta.save()\n return status.HTTP_200_OK\n\n\n# returns a json containing the current count from the meta object\n@app.get(\"/report\")\nasync def report():\n meta, is_created = await MetaModel.get_or_create(id=1)\n return {'count': meta.count}\n\n\n# resets the count in the meta object to 0\n@app.post(\"/reset\")\nasync def reset():\n meta, is_created = await MetaModel.get_or_create(id=1)\n meta.count = 0\n await meta.save()\n return status.HTTP_200_OK\n\nregister_tortoise(\n app,\n db_url=\"postgres://test_user:test_pass@localhost:5432/test_db\", # Don't expose login/pass in src, use environment variables\n modules={\"models\": [\"app_db\"]},\n generate_schemas=True,\n add_exception_handlers=True,\n)\n```\n\n```text\nmultiprocessing\n```\n\n```text\nPostgreSQL\n```\n\n```text\nMariaDB\n```\n\n```text\nMongoDB\n```\n\n```text\nRedis\n```\n\n```text\nMemcached\n```\n\n```text\nFastAPI\n```\n\n```text\naiocache\n```\n\n```text\nRedis\n```\n\n```text\nTortoise ORM\n```\n\n```text\nPostgreSQL\n```\n\n```text\nFastAPI\n```\n\n```text\nasyncio\n```\n\n```text\n5432\n```\n\n```text\n6379\n```\n\n```text\nlocalhost\n```\n\n```text\nSimpleMemoryCache\n```\n\n```text\nRedisCache\n```\n\n```text\naioredis\n```\n\n```text\nMemCache\n```\n\n```text\naiomcache\n```\n\n```text\nserializers\n```\n\n```text\nStringSerializer\n```\n\n```text\nPickleSerializer\n```\n\n```text\nJsonSerializer\n```\n\n```text\nMsgPackSerializer\n```\n\n```text\nmultiprocessing\n```\n\n```text\nmultiprocessing\n```\n\n```text\ngunicorn\n```\n\n```text\nredis-py\n```\n\n```py\nfrom multiprocessing.managers import SyncManager\n\n\nclass MyManager(SyncManager):\n pass\n\nsyncdict = {}\n\ndef get_dict():\n return syncdict\n\nif __name__ == \"__main__\":\n MyManager.register(\"syncdict\", get_dict)\n manager = MyManager((\"127.0.0.1\", 5000), authkey=b\"password\")\n manager.start()\n input()\n manager.shutdown()\n```\n\n```py\nfrom multiprocessing.managers import SyncManager\nfrom typing import Optional, Dict, Any, Union\n\n\nclass MyManager(SyncManager):\n ...\n\n\nclass Meta:\n def __init__(self, *, port: int) -> None:\n self.manager = MyManager((\"127.0.0.1\", port), authkey=b\"password\")\n self.manager.connect()\n MyManager.register(\"syncdict\")\n\n self.syndict = self.manager.syncdict()\n\n def update(self, kwargs: Dict[Any, Any]) -> None:\n self.syndict.update(kwargs)\n\n def increase_one(self, key: str) -> None:\n self.syndict.update([(key, self.syndict.get(key) + 1)])\n\n def report(self, item: Union[str, int]) -> int:\n return self.syndict.get(item)\n\n\nmeta = Meta(port=5000)\n```\n\n```py\nfrom fastapi import FastAPI, status\n\nfrom multiprocessing.managers import SyncManager\nfrom typing import Optional, Dict, Any, Union\n\n\nclass MyManager(SyncManager):\n ...\n\n\nclass Meta:\n def __init__(self, *, port: int, **kwargs: Dict[Any, Any]):\n self.manager = MyManager((\"127.0.0.1\", port), authkey=b\"password\")\n self.manager.connect()\n MyManager.register(\"syncdict\")\n\n self.syndict = self.manager.syncdict()\n self.syndict.update(**kwargs)\n\n def increase_one(self, key: str):\n self.syndict.update([(key, self.syndict.get(key) + 1)])\n\n def reset(self, key: str):\n self.syndict.update([(key, 0)])\n\n def report(self, item: Union[str, int]):\n return self.syndict.get(item)\n\n\napp = FastAPI()\n\nmeta = Meta(port=5000, cnt=0)\n\n# increases the count variable in the meta object by 1\n@app.get(\"/increment\")\nasync def increment(key: str):\n meta.increase_one(key)\n return status.HTTP_200_OK\n\n\n# returns a json containing the current count from the meta object\n@app.get(\"/report\")\nasync def report(key: str):\n return {\"count\": meta.report(key)}\n\n\n# resets the count in the meta object to 0\n@app.get(\"/reset\")\nasync def reset(key: str):\n meta.reset(key)\n return status.HTTP_200_OK\n```\n\n```py\nIn: curl -X GET \"http://127.0.0.1:8000/report?key=cnt\"\nOut: {\"count\": 0}\n\nIn: curl -X GET \"http://127.0.0.1:8001/report?key=cnt\"\nOut: {\"count\": 0}\n```\n\n```py\nfor _ in {1..10}; do curl -X GET \"http://127.0.0.1:8000/increment?key=cnt\" &; done\n```\n\n```py\nIn: curl -X GET \"http://127.0.0.1:8001/report?key=cnt\" \nOut: {\"cnt\": 10}\n```\n\n```text\nserver.py\n```\n\n```text\npython server.py\n```\n\n```text\n8000\n```\n\n```text\ncnt\n```\n\n```text\n8001\n```\n\n```text\nuvicorn my_app:app\n```\n\n```py\nimport logging\nfrom multiprocessing import Manager\n\nmanager = Manager()\n\nstore = manager.dict()\n\nstore[\"count\"] = 0\n\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n\n@app.post(\"/increment\")\nasync def increment():\n store[\"count\"] = store[\"count\"] + 1\n\n\n@app.get(\"/count\")\nasync def get_count():\n return store[\"count\"]\n\n\n@app.on_event(\"startup\")\nasync def startup_event():\n uv_logger = logging.getLogger(\"uvicorn.access\")\n handler = logging.StreamHandler()\n handler.setFormatter(\n logging.Formatter(\n \"%(process)d - %(processName)s - %(asctime)s - %(levelname)s - %(message)s\"\n )\n )\n uv_logger.addHandler(handler)\n```\n\n```text\nGUNICORN_CMD_ARGS=\"--bind=127.0.0.1 --workers=3 --preload --access-logfile=-\" gunicorn -k uvicorn.workers.UvicornWorker demo:app\n```\n\n```text\n--preload\n```\n\n```text\ndemo.py\n```\n\n```text\n--preload\n```\n\n```py\nfrom multiprocessing.managers import SyncManager\nfrom typing import Any, Dict, Optional, Union\n\nimport uvicorn\n\nfrom fastapi import FastAPI, status\nfrom UltraDict import UltraDict\n\nclass Meta:\n def __init__(self, **kwargs: Dict[Any, Any]):\n self.ultradict = UltraDict(name='fastapi_dict')\n self.ultradict.update(**kwargs)\n\n def increase_one(self, key: str):\n self.ultradict.update([(key, self.ultradict.get(key) + 1)])\n\n def reset(self, key: str):\n self.ultradict.update([(key, 0)])\n\n def report(self, item: Union[str, int]):\n return self.ultradict.get(item)\n\n\napp = FastAPI()\nmeta = Meta(cnt=0)\n\n\n# increases the count variable in the meta object by 1\n@app.get('/increment')\nasync def increment(key: str):\n meta.increase_one(key)\n return status.HTTP_200_OK\n\n# returns a json containing the current count from the meta object\n@app.get('/report')\nasync def report(key: str):\n return {'count': meta.report(key)}\n\n# resets the count in the meta object to 0\n@app.get('/reset')\nasync def reset(key: str):\n meta.reset(key)\n return status.HTTP_200_OK\n```\n\n```bash\nuvicorn main:app --workers 5\n\ncurl -X GET \"http://127.0.0.1:8000/report?key=cnt\"\n#> {\"count\":0}\n\n$ for _ in {1..10} ; do curl -X GET \"http://127.0.0.1:8000/increment?key=cnt\" & done\n#> Big bash stuff\n\n$ curl -X GET \"http://127.0.0.1:8000/report?key=cnt\"\n#> {\"count\":10}\n```\n\n```text\nINFO: Application startup complete.\nINFO: 127.0.0.1:19122 - \"GET /report?key=cnt HTTP/1.1\" 200 OK\nINFO: 127.0.0.1:19123 - \"GET /increment?key=cnt HTTP/1.1\" 200 OK\nINFO: 127.0.0.1:19124 - \"GET /increment?key=cnt HTTP/1.1\" 200 OK\nINFO: 127.0.0.1:19125 - \"GET /increment?key=cnt HTTP/1.1\" 200 OK\nINFO: 127.0.0.1:19126 - \"GET /increment?key=cnt HTTP/1.1\" 200 OK\nINFO: 127.0.0.1:19127 - \"GET /increment?key=cnt HTTP/1.1\" 200 OK\nINFO: 127.0.0.1:19128 - \"GET /increment?key=cnt HTTP/1.1\" 200 OK\nINFO: 127.0.0.1:19129 - \"GET /increment?key=cnt HTTP/1.1\" 200 OK\nINFO: 127.0.0.1:19130 - \"GET /increment?key=cnt HTTP/1.1\" 200 OK\nINFO: 127.0.0.1:19131 - \"GET /increment?key=cnt HTTP/1.1\" 200 OK\nINFO: 127.0.0.1:19132 - \"GET /increment?key=cnt HTTP/1.1\" 200 OK\nINFO: 127.0.0.1:19144 - \"GET /report?key=cnt HTTP/1.1\" 200 OK\n```\n\n```text\nUltraDict\n```\n\n```text\npip install UltraDict\n```\n\n```text\nmultiprocessing.Manager\n```\n\n```text\nfrom keyvalue_sqlite import KeyValueSqlite\n\nDB_PATH = '/path/to/db.sqlite'\n\ndb = KeyValueSqlite(DB_PATH, 'table-name')\n# Now use standard dictionary operators\ndb.set_default('0', '1')\nactual_value = db.get('0')\nassert '1' == actual_value\ndb.set_default('0', '2')\nassert '1' == db.get('0')\n```\n\n```text\ndict\n```\n\n```text\npip install keyvalue-sqlite\n```\n\n========================================\n\nComments:\n- I used cache = cache(Cache.MEMORY) for the purpose of sharing data between gunicorn workers. It did not work, one worker cant access the data written to the cache by another.\n- @Baenka `Cache.MEMORY` is the same as raw python 'dict', so you need to use `Cache.REDIS` or something else\n- Great answer! When I create the Redis Cache, I got the next error: TypeError: issubclass() arg 1 must be a class. What I'm doing wrong? It's the same code as here.\n- Did you install dependency as `aiocache[redis]` ?\n- thanks alex_noname, same error of eduardosufan. The solution as you correctly said is to install aiocache[redis]. Work perfectly now!\n- how to implement starting fastAPI app in a different process ?\n- From uvicorn docs: \"The `--reload` and `--workers` arguments are mutually exclusive.\", so it works propperly because you use only one worker due to \"essential `--reload`\"\n- @AlexKosh : You were probably mislead by a typo at the beginning of my answer (now fixed): This is about the `--preload` feature of gunicorn. It has nothing to do with the reload feature of either gunicorn or uvicorn.\n- Add a lock, then you can remove your caveat. You should really put that up front :-)\n- @Wyrmwood : Uvicorn worker afaik means only one main thread per worker process for handling requests for async endpoints in one asyncio event loop. So accesses / increments cannot interfere as changing/reading the dict itself is synchronous. This means for the specific described scenario (uvicorn workers, only async endpoints) the code should be okay: Neither an asyncio.Lock nor a threading.Lock should be necessary. However, in my experience, people's apps often are more involved, starting threads for background tasks.... I simply do not want my answer to be regarded as general recommendation.","metadata":{"transformedAt":"2026-08-18T18:32:29.088Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":72,"totalLines":756,"estimatedTokens":4229}}35{"id":"stack-63580229","source":"stackoverflow","questionId":63580229,"title":"How to save UploadFile in FastAPI","tags":["python","python-asyncio","temporary-files","fastapi"],"text":"Title: How to save UploadFile in FastAPI\nTags: python, python-asyncio, temporary-files, fastapi\nSource: Stack Overflow\n\nQuestion:\nI accept the file via POST. When I save it locally, I can read the content using file.read (), but the name via file.name incorrect(16) is displayed. When I try to find it by this name, I get an error. What might be the problem?\n\n**My code:**\n\n```\n@router.post(\n path=\"/upload\",\n response_model=schema.ContentUploadedResponse,\n)\nasync def upload_file(\n background_tasks: BackgroundTasks,\n uploaded_file: UploadFile = File(...)):\n uploaded_file.file.rollover()\n uploaded_file.file.flush()\n #shutil.copy(uploaded_file.file.name, f'../api/{uploaded_file.filename}')\n background_tasks.add_task(s3_upload, uploaded_file=fp)\n return schema.ContentUploadedResponse()\n```\n\n========================================\n\nTop Answer:\nYou can save the uploaded files this way,\n\n```\nfrom fastapi import FastAPI, File, UploadFile\n\napp = FastAPI()\n\n@app.post(\"/upload-file/\")\nasync def create_upload_file(uploaded_file: UploadFile = File(...)):\n file_location = f\"files/{uploaded_file.filename}\"\n with open(file_location, \"wb+\") as file_object:\n file_object.write(uploaded_file.file.read())\n return {\"info\": f\"file '{uploaded_file.filename}' saved at '{file_location}'\"}\n```\n\nYou can also use the **`shutil.copyfileobj(...)`** method (see this detailed answer to how both are working behind the scenes).\n\nSo, as an alternative way, you can write something like the below using the `shutil.copyfileobj(...)` to achieve the file upload functionality.\n\n```\n**import shutil**\nfrom fastapi import FastAPI, File, UploadFile\n\napp = FastAPI()\n\n@app.post(\"/upload-file/\")\nasync def create_upload_file(uploaded_file: UploadFile = File(...)): \nfile_location = f\"files/{uploaded_file.filename}\"\n with open(file_location, \"wb+\") as file_object:\n **shutil.copyfileobj(uploaded_file.file, file_object)** \nreturn {\"info\": f\"file '{uploaded_file.filename}' saved at '{file_location}'\"}\n```\n\n========================================\n\nCode:\n```text\n@router.post(\n path=\"/upload\",\n response_model=schema.ContentUploadedResponse,\n)\nasync def upload_file(\n background_tasks: BackgroundTasks,\n uploaded_file: UploadFile = File(...)):\n uploaded_file.file.rollover()\n uploaded_file.file.flush()\n #shutil.copy(uploaded_file.file.name, f'../api/{uploaded_file.filename}')\n background_tasks.add_task(s3_upload, uploaded_file=fp)\n return schema.ContentUploadedResponse()\n```\n\n```text\n@app.post(\"/\")\nasync def post_endpoint(in_file: UploadFile=File(...)):\n # ...\n async with aiofiles.open(out_file_path, 'wb') as out_file:\n content = await in_file.read() # async read\n await out_file.write(content) # async write\n\n return {\"Result\": \"OK\"}\n```\n\n```text\n@app.post(\"/\")\nasync def post_endpoint(in_file: UploadFile=File(...)):\n # ...\n async with aiofiles.open(out_file_path, 'wb') as out_file:\n while content := await in_file.read(1024): # async read chunk\n await out_file.write(content) # async write chunk\n\n return {\"Result\": \"OK\"}\n```\n\n```text\nimport shutil\nfrom pathlib import Path\nfrom tempfile import NamedTemporaryFile\nfrom typing import Callable\n\nfrom fastapi import UploadFile\n\n\ndef save_upload_file(upload_file: UploadFile, destination: Path) -> None:\n try:\n with destination.open(\"wb\") as buffer:\n shutil.copyfileobj(upload_file.file, buffer)\n finally:\n upload_file.file.close()\n\n\ndef save_upload_file_tmp(upload_file: UploadFile) -> Path:\n try:\n suffix = Path(upload_file.filename).suffix\n with NamedTemporaryFile(delete=False, suffix=suffix) as tmp:\n shutil.copyfileobj(upload_file.file, tmp)\n tmp_path = Path(tmp.name)\n finally:\n upload_file.file.close()\n return tmp_path\n\n\ndef handle_upload_file(\n upload_file: UploadFile, handler: Callable[[Path], None]\n) -> None:\n tmp_path = save_upload_file_tmp(upload_file)\n try:\n handler(tmp_path) # Do something with the saved temp file\n finally:\n tmp_path.unlink() # Delete the temp file\n```\n\n```text\nUploadFile\n```\n\n```text\nSpooledTemporaryFile\n```\n\n```text\nUploadFile.file\n```\n\n```text\nTemporaryFile\n```\n\n```text\nasync def\n```\n\n```text\nUploadFile\n```\n\n```text\nwrite\n```\n\n```text\nread\n```\n\n```text\nseek\n```\n\n```text\nclose\n```\n\n```text\naiofiles\n```\n\n```text\ndef\n```\n\n```text\nshutil.copyfileobj\n```\n\n```text\nUploadFile.file\n```\n\n```text\ndef\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\nfrom fastapi import FastAPI, File, UploadFile\n\napp = FastAPI()\n\n\n@app.post(\"/upload-file/\")\nasync def create_upload_file(uploaded_file: UploadFile = File(...)):\n file_location = f\"files/{uploaded_file.filename}\"\n with open(file_location, \"wb+\") as file_object:\n file_object.write(uploaded_file.file.read())\n return {\"info\": f\"file '{uploaded_file.filename}' saved at '{file_location}'\"}\n```\n\n```text\nimport shutil\nfrom fastapi import FastAPI, File, UploadFile\n\napp = FastAPI()\n\n\n@app.post(\"/upload-file/\")\nasync def create_upload_file(uploaded_file: UploadFile = File(...)): \nfile_location = f\"files/{uploaded_file.filename}\"\n with open(file_location, \"wb+\") as file_object:\n shutil.copyfileobj(uploaded_file.file, file_object) \nreturn {\"info\": f\"file '{uploaded_file.filename}' saved at '{file_location}'\"}\n```\n\n```text\nshutil.copyfileobj(...)\n```\n\n```text\nshutil.copyfileobj(...)\n```\n\n```text\nimport os\nimport logging\n\nfrom fastapi import FastAPI, BackgroundTasks, File, UploadFile\n\nlog = logging.getLogger(__name__)\n\napp = FastAPI()\n\nDESTINATION = \"/\"\nCHUNK_SIZE = 2 ** 20 # 1MB\n\n\nasync def chunked_copy(src, dst):\n await src.seek(0)\n with open(dst, \"wb\") as buffer:\n while True:\n contents = await src.read(CHUNK_SIZE)\n if not contents:\n log.info(f\"Src completely consumed\\n\")\n break\n log.info(f\"Consumed {len(contents)} bytes from Src file\\n\")\n buffer.write(contents)\n\n\n@app.post(\"/uploadfile/\")\nasync def create_upload_file(file: UploadFile = File(...)):\n fullpath = os.path.join(DESTINATION, file.filename)\n await chunked_copy(file, fullpath)\n return {\"File saved to disk at\": fullpath}\n```\n\n```text\ncreate_upload_file\n```\n\n```text\nfastapi import (\n FastAPI\n UploadFile,\n File,\n status\n)\nfrom fastapi.responses import JSONResponse\n\nimport aiofiles\napp = FastAPI( debug = True ) \n\n@app.post(\"/upload_file/\", response_description=\"\", response_model = \"\")\nasync def result(file:UploadFile = File(...)):\n try:\n async with aiofiles.open(file.filename, 'wb') as out_file:\n content = await file.read() # async read\n await out_file.write(content) # async write\n\n except Exception as e:\n return JSONResponse(\n status_code = status.HTTP_400_BAD_REQUEST,\n content = { 'message' : str(e) }\n )\n else:\n return JSONResponse(\n status_code = status.HTTP_200_OK,\n content = {\"result\":'success'}\n )\n```\n\n```text\nfastapi import (\n FastAPI\n UploadFile,\n File,\n status\n)\nfrom fastapi.responses import JSONResponse\n\nimport aiofiles\napp = FastAPI( debug = True ) \n@router.post(\"/upload_multiple_file/\", response_description=\"\", response_model = \"\")\n\nasync def result(files:List[UploadFile] = File(...), secret_key: str = Depends(secretkey_middleware)):\n try:\n \n for file in files:\n\n async with aiofiles.open(eventid+file.filename, 'wb') as out_file:\n content = await file.read() \n await out_file.write(content) \n \n\n\n pass\n except Exception as e:\n \n return JSONResponse(\n status_code = status.HTTP_400_BAD_REQUEST,\n content = { 'message' : str(e) }\n )\n else:\n return JSONResponse(\n status_code = status.HTTP_200_OK,\n content = {\"result\":'result'}\n )\n```\n\n```text\nfrom fastapi import UploadFile\n\nimport shutil\nfrom pathlib import Path\n\ndef save_upload_file(upload_file: UploadFile, destination: Path) -> str:\n try:\n with destination.open(\"wb\") as buffer:\n shutil.copyfileobj(upload_file.file, buffer)\n file_name = buffer.name\n print(type(file_name))\n finally:\n upload_file.file.close()\n return file_name\n```\n\n```text\ndef unique_id():\n return str(uuid.uuid4())\n\ndef delete_file(filename):\n os.remove(filename)\n```\n\n```text\n@router.post(\"/use_upload_file\", response_model=dict)\nasync def use_uploaded_file(\n file_one: UploadFile = File(),\n file_two: UploadFile = File()\n ):\n\n\n file_one_path = save_upload_file(audio_one, Path(f\"{unique_id()}\"))\n file_two_path = save_upload_file(audio_two, Path(f\"{unique_id()}\"))\n\n result = YourFunctionThatUsestheSaveFile(audio_one_path, audio_two_path)\n\n delete_file(audio_one_path)\n delete_file(audio_two_path)\n\n return result\n```\n\n```text\n@router.post(path=\"/test\", tags=['File Upload'])\ndef color_classification_predict(uploadFile: UploadFile):\n try:\n if uploadFile.filename:\n # saved_dir- directory path where we'll save the uploaded file \n test_filename = os.path.join(saved_dir, uploadFile.filename)\n with open(test_filename, \"wb+\") as file_object:\n shutil.copyfileobj(uploadFile.file, file_object)\n except Exception as e:\n raise e\n print('[INFO] Uploaded file saved.')\n```\n\n```text\nfrom fastapi import APIRouter, File, status, Depends, HTTPException, UploadFile\n\nimport shutil\nfrom pathlib import Path\n\nfrom database.user_functions import *\nfrom database.auth_functions import *\nfrom database.form_functions import *\n\nfrom model import *\nfrom model_form import *\n\nfile_routes = APIRouter()\n\n\n# @file_routes.post(\"/files/\")\n# async def create_file(file: bytes = File()):\n# return {\"file_size\": len(file)}\n\n\n# @file_routes.post(\"/uploadfile/\")\n# async def create_upload_file(file: UploadFile):\n# return {\"filename\": file.filename}\n\n\n@file_routes.post(\"/upload-file/\")\nasync def create_upload_file(uploaded_file: UploadFile = File(...)): \n\n file_location = f\"./{uploaded_file.filename}\"\n with open(file_location, \"wb+\") as file_object:\n shutil.copyfileobj(uploaded_file.file, file_object) \n return {\"info\": f\"file '{uploaded_file.filename}' saved at '{file_location}'\"}\n```\n\n```py\nimport shutil\nfrom datetime import datetime, timedelta\nfrom fastapi import UploadFile\n\n\n@app.post(\"/upload-image\")\ndef upload_image(image: UploadFile):\n now = str(datetime.now())[:19]\n now = now.replace(\":\", \"_\")\n #this is just to make sure the file not exist and added as a new file\n path = \"./static/images/\" + image.filename.split('.')[0] + now + \".\" + image.filename.split('.')[-1]\n with open(path, 'wb+') as buffer:\n shutil.copyfileobj(image.file, buffer)\n\n return {\"image_destination\":path}\n```\n\n```py\nimport shutil\nfrom datetime import datetime, timedelta\nfrom fastapi import UploadFile\n\n\n@app.post(\"/upload-image\")\ndef upload_image(image: UploadFile):\n now = str(datetime.now())[:19]\n now = now.replace(\":\", \"_\")\n #this is just to make sure the file not exist and added as a new file\n path = \"./static/images/\" + image.filename.split('.')[0] + now + \".\" + image.filename.split('.')[-1]\n shutil.move(image.filename, path)\n\n return {\"image_destination\":path}\n```\n\n```text\n./my_folder_destination\n```\n\n```text\nmy_folder_destionation\n```\n\n```text\nFileNotFoundError: [Errno 2] No such file or directory: some/directory\n```\n\n```text\n/\n```\n\n```text\n./\n```\n\n========================================\n\nComments:\n- A noob to python. Can anyone please tell me the meaning of `uploaded_file.file.flush()`? Thank you.\n- Please have a look at **this answer**, if you are using a `def` endpoint, as well as **this answer**, if you are using an `async def` endpoint.\n- Why you use `async` for this task? FastApi tells that not asynchronus endpoints anyway will be runned via `async`, so as I get it, if you don't have another operations after your async call - you should NOt to use `async` fastapi.tiangolo.com/async\n- you are missing a `:` behind `while content := await in_file.read(1024)`\n- Can you please add a snippet for `aiofiles.tempfile.TemporaryFile` so we can first store file in temporary location and can raise error for various validations. If all validations are passed we can move this temp file to our storage. Regards.\n- The two functions above are **not** equivalent. In the first one, the entire contents of the file will be read into memory, whereas, in the second one, the data will be read in chunks (this is the default behaviour). Please have a look at this answer for more details.\n- Indeed your answer is wonderful, I appreciate it. But, I didn't say they are \"equivalent\", but *\"almost* identical\"\n- *\"almost identical\"* might be too vague for the reader, and *\"the above function can be re-written\"* implies writing the same function in a diiferent way. I think it is important for future readers to know the difference between the two.\n- I completely get it. I just updated my answer, I hope now it's better.\n- As a final touch-up, you may want to replace `async def` with `def`, as both functions perform blocking I/O operations that would block the main thread.\n- You can access `.stream()`, which provides the byte chunks without storing the entire file into memory (even though a large file is never stored entirely into memory, as Starlette currently uses a `SpooledTemporaryFile` with the `max_size` set to 1MB, meaning that the file data is spooled in memory until the file size exceeds 1MB, at which point the contents are written to a temporary file on disk). Please have a look at this answer and this answer for more details and code examples.","metadata":{"transformedAt":"2026-08-18T18:32:29.088Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":41,"totalLines":511,"estimatedTokens":3470}}36{"id":"stack-77001129","source":"stackoverflow","questionId":77001129,"title":"How to configure FastAPI logging so that it works both with Uvicorn locally and in production?","tags":["python","logging","fastapi","uvicorn"],"text":"Title: How to configure FastAPI logging so that it works both with Uvicorn locally and in production?\nTags: python, logging, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI have the following FastAPI application:\n\n```\nfrom fastapi import FastAPI\nimport logging\nimport uvicorn\n\napp = FastAPI(title=\"api\")\n\nLOG = logging.getLogger(__name__)\nLOG.info(\"API is starting up\")\nLOG.info(uvicorn.Config.asgi_version)\n\n@app.get(\"/\")\nasync def get_index():\n LOG.info(\"GET /\")\n return {\"Hello\": \"Api\"}\n```\n\nThe application locally is run with:\n\n```\nuvicorn api:app --reload\n```\n\n```\nINFO: Will watch for changes in these directories: ['/Users/user/code/backend/api']\nINFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\nINFO: Started reloader process [44258] using StatReload\nINFO: Started server process [44260]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\n```\n\nIt is not logging any of the startup messages. Later on when sending an HTTP request to the API:\n\n```\nINFO: 127.0.0.1:50538 - \"POST /api/v1/endpoint HTTP/1.1\" 200 OK\n```\n\nin the function body, there is `LOG.info(\"example\")` that does not get logged either. Is there a way to make FastAPI logging work with Uvicorn and also in production (independently of the execution environments like Uvicorn)?\n\n========================================\n\nTop Answer:\nLooking at how uvicorn set its loggers in the recent versions I came up with this:\n\n```\nlogger = logging.getLogger('uvicorn.error')\n\n@app.get('/')\nasync def main():\n logger.debug('this is a debug message')\n return 'ok'\n```\n\nThe log level is controlled by the uvicorn command line option `--log-level debug` and produces:\n\n```\nINFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)\nDEBUG: this is a debug message\n```\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI\nimport logging\nimport uvicorn\n\napp = FastAPI(title=\"api\")\n\nLOG = logging.getLogger(__name__)\nLOG.info(\"API is starting up\")\nLOG.info(uvicorn.Config.asgi_version)\n\n@app.get(\"/\")\nasync def get_index():\n LOG.info(\"GET /\")\n return {\"Hello\": \"Api\"}\n```\n\n```bash\nuvicorn api:app --reload\n```\n\n```py\nINFO: Will watch for changes in these directories: ['/Users/user/code/backend/api']\nINFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\nINFO: Started reloader process [44258] using StatReload\nINFO: Started server process [44260]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\n```\n\n```bash\nINFO: 127.0.0.1:50538 - \"POST /api/v1/endpoint HTTP/1.1\" 200 OK\n```\n\n```text\nLOG.info(\"example\")\n```\n\n```py\nuvicorn main:app --log-level trace\n```\n\n```py\nuvicorn.run(app, log_level=\"trace\")\n```\n\n```py\nfrom fastapi import FastAPI\nimport uvicorn\nimport logging\n\n\napp = FastAPI(title='api')\nlogger = logging.getLogger('uvicorn.error')\n\n@app.get('/')\nasync def main():\n logger.info('GET /') # or logger.debug(), logger.error(), etc.\n return 'success'\n \n \nif __name__ == '__main__':\n uvicorn.run(app, log_level=\"trace\")\n```\n\n```py\nfrom fastapi import FastAPI\nimport uvicorn\nimport logging\nimport settings\n\n\napp = FastAPI(title='api')\nlogger = logging.getLogger('uvicorn.error')\n\n\n@app.get('/')\nasync def main():\n logger.info('GET /') # or logger.debug(), logger.error(), etc.\n return 'success'\n \n \nif __name__ == '__main__':\n uvicorn.run(app, log_config=settings.LOGGING_CONFIG)\n```\n\n```py\nLOGGING_CONFIG = { \n 'version': 1,\n 'disable_existing_loggers': True,\n 'formatters': { \n 'standard': { \n 'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'\n },\n 'custom_formatter': { \n 'format': \"%(asctime)s [%(processName)s: %(process)d] [%(threadName)s: %(thread)d] [%(levelname)s] %(name)s: %(message)s\"\n \n },\n },\n 'handlers': { \n 'default': { \n 'formatter': 'standard',\n 'class': 'logging.StreamHandler',\n 'stream': 'ext://sys.stdout', # Default is stderr\n },\n 'stream_handler': { \n 'formatter': 'custom_formatter',\n 'class': 'logging.StreamHandler',\n 'stream': 'ext://sys.stdout', # Default is stderr\n },\n 'file_handler': { \n 'formatter': 'custom_formatter',\n 'class': 'logging.handlers.RotatingFileHandler',\n 'filename': 'app.log',\n 'maxBytes': 1024 * 1024 * 1, # = 1MB\n 'backupCount': 3,\n },\n },\n 'loggers': { \n 'uvicorn': {\n 'handlers': ['default', 'file_handler'],\n 'level': 'TRACE',\n 'propagate': False\n },\n 'uvicorn.access': {\n 'handlers': ['stream_handler', 'file_handler'],\n 'level': 'TRACE',\n 'propagate': False\n },\n 'uvicorn.error': { \n 'handlers': ['stream_handler', 'file_handler'],\n 'level': 'TRACE',\n 'propagate': False\n },\n 'uvicorn.asgi': {\n 'handlers': ['stream_handler', 'file_handler'],\n 'level': 'TRACE',\n 'propagate': False\n },\n\n },\n}\n```\n\n```py\nLOGGING_CONFIG = { \n 'version': 1,\n 'disable_existing_loggers': True,\n 'formatters': {\n 'standard': ..., # same as above or customize that as well\n 'custom_formatter': { \n 'format': \"{'time':'%(asctime)s', 'process_name': '%(processName)s', 'process_id': '%(process)s', 'thread_name': '%(threadName)s', 'thread_id': '%(thread)s','level': '%(levelname)s', 'logger_name': '%(name)s', 'message': '%(message)s'}\" \n },\n },\n ... # the rest is the same as in the original settings.py above\n}\n```\n\n```text\nlogger.info(\"some msg\", extra={'extra_info': get_extra_info(request, response)})\n```\n\n```py\nimport logging, json\n\n\nclass CustomJSONFormatter(logging.Formatter):\n def __init__(self, fmt):\n logging.Formatter.__init__(self, fmt)\n\n def format(self, record):\n logging.Formatter.format(self, record)\n return json.dumps(get_log(record), indent=2)\n\n\ndef get_log(record):\n d = {\n \"time\": record.asctime,\n \"process_name\": record.processName,\n \"process_id\": record.process,\n \"thread_name\": record.threadName,\n \"thread_id\": record.thread,\n \"level\": record.levelname,\n \"logger_name\": record.name,\n \"pathname\": record.pathname,\n \"line\": record.lineno,\n \"message\": record.message,\n }\n\n if hasattr(record, \"extra_info\"):\n d[\"req\"] = record.extra_info[\"req\"]\n d[\"res\"] = record.extra_info[\"res\"]\n\n return d\n\n\nLOGGING_CONFIG = { \n 'version': 1,\n 'disable_existing_loggers': True,\n 'formatters': {\n 'standard': ..., # same as above or customize that as well\n 'custom_formatter': { \n '()': lambda: CustomJSONFormatter(fmt='%(asctime)s') \n },\n },\n ... # the rest is the same as in the original settings.py above\n}\n```\n\n```json\n{\n \"time\": \"2024-10-27 11:05:00,300\",\n \"process_name\": \"MainProcess\",\n \"process_id\": 4102,\n \"thread_name\": \"AnyIO worker thread\",\n \"thread_id\": 1147,\n \"level\": \"INFO\",\n \"logger_name\": \"uvicorn.error\",\n \"pathname\": \"C:\\\\...\",\n \"line\": 33,\n \"message\": \"GET /\",\n \"req\": {\n \"url\": \"/\",\n \"headers\": {\n \"host\": \"localhost:8000\",\n \"user-agent\": \"Mozilla...\",\n \"accept\": \"text/html,application/xhtml+xml,...\"\n },\n \"method\": \"GET\",\n \"http_version\": \"1.1\",\n \"original_url\": \"/\",\n \"query\": {}\n },\n \"res\": {\n \"status_code\": 200,\n \"status\": \"OK\"\n }\n}\n```\n\n```py\nfrom fastapi import FastAPI\nimport logging\nimport uvicorn\nimport sys\n\napp = FastAPI()\n\nlogger = logging.getLogger(__name__)\nlogger.setLevel(logging.DEBUG)\nformatter = logging.Formatter(\"%(asctime)s [%(processName)s: %(process)d] [%(threadName)s: %(thread)d] [%(levelname)s] %(name)s: %(message)s\")\n\nstream_handler = logging.StreamHandler(sys.stdout)\nstream_handler.setFormatter(formatter)\nfile_handler = logging.FileHandler(\"info.log\")\nfile_handler.setFormatter(formatter)\n\nlogger.addHandler(stream_handler)\nlogger.addHandler(file_handler)\n\nlogger.info('API is starting up')\n\n\n@app.get('/')\nasync def main():\n logger.info('GET /')\n return 'ok'\n\n\nif __name__ == '__main__':\n uvicorn.run(app, log_level=\"trace\") # or `log_config=settings.LOGGING_CONFIG`\n```\n\n```text\nuvicorn\n```\n\n```text\n--log-config <path>\n```\n\n```text\ndictConfig()\n```\n\n```text\nfileConfig()\n```\n\n```text\nformatters.default.use_colors\n```\n\n```text\nformatters.access.use_colors\n```\n\n```text\n[standard]\n```\n\n```text\n--log-level <str>\n```\n\n```text\n--no-access-log\n```\n\n```text\n--use-colors\n```\n\n```text\n--no-use-colors\n```\n\n```text\n--log-config\n```\n\n```text\n--log-level\n```\n\n```text\ntrace\n```\n\n```text\ncritical\n```\n\n```text\ninfo\n```\n\n```text\ninfo\n```\n\n```text\nwarning\n```\n\n```text\nerror\n```\n\n```text\ncritical\n```\n\n```text\ndebug\n```\n\n```text\ntrace\n```\n\n```text\ntrace\n```\n\n```text\nuvicorn\n```\n\n```text\n--no-access-log\n```\n\n```text\n--access-log\n```\n\n```text\nhost\n```\n\n```text\nport\n```\n\n```text\n--host 0.0.0.0\n```\n\n```text\n--port 8000\n```\n\n```text\nmain\n```\n\n```text\nmain.py\n```\n\n```text\nuvicorn\n```\n\n```text\nuvicorn\n```\n\n```text\nlog_level\n```\n\n```text\nuvicorn.run()\n```\n\n```text\naccess_log\n```\n\n```text\nFalse\n```\n\n```text\naccess_log=False\n```\n\n```text\nhost\n```\n\n```text\nport\n```\n\n```text\nhost='0.0.0.0'\n```\n\n```text\nport=8000\n```\n\n```text\nuvicorn\n```\n\n```text\nuvicorn\n```\n\n```text\nuvicorn.access\n```\n\n```text\nuvicorn.error\n```\n\n```text\nuvicorn.asgi\n```\n\n```text\nuvicorn.error\n```\n\n```text\nuvicorn.access\n```\n\n```text\nuvicorn.asgi\n```\n\n```text\nuvicorn.error\n```\n\n```text\nuvicorn\n```\n\n```text\nlog_level\n```\n\n```text\nuvicorn.run()\n```\n\n```text\nuvicorn.error\n```\n\n```text\npropagate\n```\n\n```text\nuvicorn\n```\n\n```text\nuvicorn\n```\n\n```text\nroot\n```\n\n```text\nuvicorn\n```\n\n```text\npropagate\n```\n\n```text\nFalse\n```\n\n```text\nroot\n```\n\n```text\nroot\n```\n\n```text\nuvicorn.error\n```\n\n```text\npropagate\n```\n\n```text\nFalse\n```\n\n```text\nlogger.propagate = False\n```\n\n```text\nuvicorn\n```\n\n```text\nuvicorn\n```\n\n```text\nuvicorn\n```\n\n```text\nuvicorn\n```\n\n```text\nlog_config\n```\n\n```text\nuvicorn.run()\n```\n\n```text\ndictConfig()\n```\n\n```text\nformatters\n```\n\n```text\nhandlers\n```\n\n```text\nloggers\n```\n\n```text\nuvicorn.error\n```\n\n```text\nmain.py\n```\n\n```text\nRotatingFileHandler\n```\n\n```text\nmaxBytes\n```\n\n```text\nbackupCount\n```\n\n```text\nmaxBytes\n```\n\n```text\nmaxBytes\n```\n\n```text\nbackupCount\n```\n\n```text\nbackupCount\n```\n\n```text\nmaxBytes\n```\n\n```text\nbackupCount\n```\n\n```text\nbackupCount\n```\n\n```text\napp.log\n```\n\n```text\napp.log\n```\n\n```text\napp.log.1\n```\n\n```text\napp.log.2\n```\n\n```text\napp.log.5\n```\n\n```text\napp.log\n```\n\n```text\napp.log.1\n```\n\n```text\napp.log.1\n```\n\n```text\napp.log.2\n```\n\n```text\napp.log.2\n```\n\n```text\napp.log.3\n```\n\n```text\nRequest\n```\n\n```text\nResponse\n```\n\n```text\nextra\n```\n\n```text\nextra\n```\n\n```text\nextra_info\n```\n\n```text\nget_log()\n```\n\n```text\nuvicorn\n```\n\n```text\nuvicorn\n```\n\n```text\nStreamHandler\n```\n\n```text\nFileHandler\n```\n\n```text\nDEBUG\n```\n\n```text\nINFO\n```\n\n```text\nWARNING\n```\n\n```text\nlogging\n```\n\n```text\nDEBUG\n```\n\n```text\nWARNING\n```\n\n```text\ndictConfig()\n```\n\n```text\nlogging\n```\n\n```text\nLogRecord\n```\n\n```text\nlog_level=\"trace\"\n```\n\n```text\nuvicorn.run()\n```\n\n```text\nuvicorn\n```\n\n```text\ntrace\n```\n\n```text\nuvicorn\n```\n\n```text\nLOGGING_CONFIG\n```\n\n```text\nuvicorn.run(..., log_config=settings.LOGGING_CONFIG)\n```\n\n```text\nuvicorn\n```\n\n```text\nlogger\n```\n\n```text\nlifespan\n```\n\n```text\napp.state\n```\n\n```text\nrequest.state\n```\n\n```text\nAPIRouter\n```\n\n```text\nrouters\n```\n\n```py\nlogger = logging.getLogger('uvicorn.error')\n\n@app.get('/')\nasync def main():\n logger.debug('this is a debug message')\n return 'ok'\n```\n\n```text\nINFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)\nDEBUG: this is a debug message\n```\n\n```text\n--log-level debug\n```\n\n```text\nimport logging\n\nlogging.getLogger(f\"uvicorn.{__name__}\")\n```\n\n========================================\n\nComments:\n- You might find this answer and this answer helpful.\n- thanks @chris these are helpful but do not solve my problem.\n- To log startup messages, please try using a `startup`/`lifespan` event handler, as demonstrated here and here\n- Thanks for the answer. Another thing I added here is a message formatter. Instead of logger.addHandler(logging.StreamHandler(sys.stdout)) I added consoleHandler = logging.StreamHandler(sys.stdout) consoleHandler.setFormatter(logging.Formatter(fmt='%(asctime‌​)s - %(levelname)s - %(message)s')) logger.addHandler(consoleHandler)\n- @AnnGuseva Please have a look at this answer (given in the answer above as well) on how to further customise the log messages.\n- I was struggling to figure out how to get uvicorn logs to just use the same config that I have set up for all my other logging stuff. After learning uvicorn sets `propagate = False`, I was able to fix it by including `logging.getLogger(\"uvicorn\").propagate = True` (or equivalent) as part of my global config. Now the uvicorn logs finally use the same formatting and handlers as everything else.\n- much thanks @chris for the excellent and thorough response. I'm using the log_config option successfully in development. I wanted to add one other option that is a simple one liner that adds your app's log messages directly into stream and format (propagate) of the uvicorn logger's default. 'logging.getLogger(f\"uvicorn.{**name**}\")'\n- Love this super simple answer. Worked a treat.","metadata":{"transformedAt":"2026-08-18T18:32:29.088Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":154,"totalLines":919,"estimatedTokens":3372}}37{"id":"stack-69306103","source":"stackoverflow","questionId":69306103,"title":"Is it possible to change the output alias in pydantic?","tags":["python","json","json-deserialization","fastapi","pydantic"],"text":"Title: Is it possible to change the output alias in pydantic?\nTags: python, json, json-deserialization, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\n**Setup:**\n\n```\n# Pydantic Models\n\nclass TMDB_Category(BaseModel):\n name: str = Field(alias=\"strCategory\")\n description: str = Field(alias=\"strCategoryDescription\")\n\nclass TMDB_GetCategoriesResponse(BaseModel):\n categories: list[TMDB_Category]\n\n@router.get(path=\"category\", response_model=TMDB_GetCategoriesResponse)\nasync def get_all_categories():\n async with httpx.AsyncClient() as client:\n response = await client.get(Endpoint.GET_CATEGORIES)\n return TMDB_GetCategoriesResponse.parse_obj(response.json())\n```\n\n**Problem:**\n\nAlias is being used when creating a response, and I want to avoid it. I only need this alias to correctly map the incoming data but when returning a response, I want to use actual field names.\n\n**Actual response:**\n\n```\n{\n \"categories\": [\n {\n \"strCategory\": \"Beef\",\n \"strCategoryDescription\": \"Beef is ...\"\n },\n {\n \"strCategory\": \"Chicken\",\n \"strCategoryDescription\": \"Chicken is ...\"\n }\n}\n```\n\n**Expected response:**\n\n```\n{\n \"categories\": [\n {\n \"name\": \"Beef\",\n \"description\": \"Beef is ...\"\n },\n {\n \"name\": \"Chicken\",\n \"description\": \"Chicken is ...\"\n }\n}\n```\n\n========================================\n\nTop Answer:\n**Update (2023-10-07)**: Check the comments in the question for other answers and this answer in the same question for pydantic 2.0 or newer.\n\nSwitch aliases and field names and use the `allow_population_by_field_name` model config option:\n\n```\nclass TMDB_Category(BaseModel):\n strCategory: str = Field(alias=\"name\")\n strCategoryDescription: str = Field(alias=\"description\")\n\n class Config:\n allow_population_by_field_name = True\n```\n\nLet the aliases configure the names of the fields that you want to return, but enable `allow_population_by_field_name` to be able to parse data that uses different names for the fields.\n\n========================================\n\nCode:\n```py\n# Pydantic Models\n\nclass TMDB_Category(BaseModel):\n name: str = Field(alias=\"strCategory\")\n description: str = Field(alias=\"strCategoryDescription\")\n\n\nclass TMDB_GetCategoriesResponse(BaseModel):\n categories: list[TMDB_Category]\n\n\n@router.get(path=\"category\", response_model=TMDB_GetCategoriesResponse)\nasync def get_all_categories():\n async with httpx.AsyncClient() as client:\n response = await client.get(Endpoint.GET_CATEGORIES)\n return TMDB_GetCategoriesResponse.parse_obj(response.json())\n```\n\n```py\n{\n \"categories\": [\n {\n \"strCategory\": \"Beef\",\n \"strCategoryDescription\": \"Beef is ...\"\n },\n {\n \"strCategory\": \"Chicken\",\n \"strCategoryDescription\": \"Chicken is ...\"\n }\n}\n```\n\n```py\n{\n \"categories\": [\n {\n \"name\": \"Beef\",\n \"description\": \"Beef is ...\"\n },\n {\n \"name\": \"Chicken\",\n \"description\": \"Chicken is ...\"\n }\n}\n```\n\n```py\nfrom fastapi import FastAPI, Path, Query\nfrom pydantic import BaseModel, Field\n\napp = FastAPI()\n\nclass Item(BaseModel):\n name: str = Field(..., alias=\"keck\")\n\n@app.post(\"/item\")\nasync def read_items(\n item: Item,\n):\n return item.dict(by_alias=False)\n```\n\n```json\n{\n \"keck\": \"string\"\n}\n```\n\n```json\n{\n \"name\": \"string\"\n}\n```\n\n```text\nby_alias\n```\n\n```python\nclass TMDB_Category(BaseModel):\n strCategory: str = Field(alias=\"name\")\n strCategoryDescription: str = Field(alias=\"description\")\n\n class Config:\n allow_population_by_field_name = True\n```\n\n```text\nallow_population_by_field_name\n```\n\n```text\nallow_population_by_field_name\n```\n\n```py\nfrom dataclasses import dataclass\n\nfrom dataclass_wizard import JSONWizard, json_field\n\n\n@dataclass\nclass TMDB_Category:\n name: str = json_field('strCategory')\n description: str = json_field('strCategoryDescription')\n\n\n@dataclass\nclass TMDB_GetCategoriesResponse(JSONWizard):\n categories: list[TMDB_Category]\n```\n\n```py\ninput_dict = {\n \"categories\": [\n {\n \"strCategory\": \"Beef\",\n \"strCategoryDescription\": \"Beef is ...\"\n },\n {\n \"strCategory\": \"Chicken\",\n \"strCategoryDescription\": \"Chicken is ...\"\n }\n ]\n}\n\nc = TMDB_GetCategoriesResponse.from_dict(input_dict)\nprint(repr(c))\n# TMDB_GetCategoriesResponse(categories=[TMDB_Category(name='Beef', description='Beef is ...'), TMDB_Category(name='Chicken', description='Chicken is ...')])\n\nprint(c.to_dict())\n# {'categories': [{'name': 'Beef', 'description': 'Beef is ...'}, {'name': 'Chicken', 'description': 'Chicken is ...'}]}\n```\n\n```py\nfrom dataclasses import dataclass\nfrom timeit import timeit\n\nfrom pydantic import BaseModel, Field\n\nfrom dataclass_wizard import JSONWizard, json_field\n\n\n# Pydantic Models\nclass Pydantic_TMDB_Category(BaseModel):\n name: str = Field(alias=\"strCategory\")\n description: str = Field(alias=\"strCategoryDescription\")\n\n\nclass Pydantic_TMDB_GetCategoriesResponse(BaseModel):\n categories: list[Pydantic_TMDB_Category]\n\n\n# Dataclasses\n@dataclass\nclass TMDB_Category:\n name: str = json_field('strCategory', all=True)\n description: str = json_field('strCategoryDescription', all=True)\n\n\n@dataclass\nclass TMDB_GetCategoriesResponse(JSONWizard):\n categories: list[TMDB_Category]\n\n\n# Input dict which contains sufficient data for testing (100 categories)\ninput_dict = {\n \"categories\": [\n {\n \"strCategory\": f\"Beef {i * 2}\",\n \"strCategoryDescription\": \"Beef is ...\" * i\n }\n for i in range(100)\n ]\n}\n\nn = 10_000\n\nprint('=== LOAD (deserialize)')\nprint('dataclass-wizard: ',\n timeit('c = TMDB_GetCategoriesResponse.from_dict(input_dict)',\n globals=globals(), number=n))\nprint('pydantic: ',\n timeit('c = Pydantic_TMDB_GetCategoriesResponse.parse_obj(input_dict)',\n globals=globals(), number=n))\n\nc = TMDB_GetCategoriesResponse.from_dict(input_dict)\npydantic_c = Pydantic_TMDB_GetCategoriesResponse.parse_obj(input_dict)\n\nprint('=== DUMP (serialize)')\nprint('dataclass-wizard: ',\n timeit('c.to_dict()',\n globals=globals(), number=n))\nprint('pydantic: ',\n timeit('pydantic_c.dict()',\n globals=globals(), number=n))\n```\n\n```text\n=== LOAD (deserialize)\ndataclass-wizard: 1.742989194\npydantic: 5.31538175\n=== DUMP (serialize)\ndataclass-wizard: 2.300118940\npydantic: 5.582638598\n```\n\n```text\npydantic\n```\n\n```text\nField(alias=...)\n```\n\n```text\nall\n```\n\n```text\njson_field\n```\n\n```text\ndataclasses\n```\n\n```text\npydantic\n```\n\n```text\npydantic\n```\n\n```text\npydantic\n```\n\n```text\nfrom pydantic import BaseModel, Field\n\n\nclass TMDB_Category(BaseModel):\n name: str = Field(alias=\"strCategory\")\n description: str = Field(alias=\"strCategoryDescription\")\n\n\ndata = {\n \"strCategory\": \"Beef\",\n \"strCategoryDescription\": \"Beef is ...\"\n}\n\n\nobj = TMDB_Category.parse_obj(data)\n\n# {'name': 'Beef', 'description': 'Beef is ...'}\nprint(obj.dict())\n```\n\n```py\nclass TMDB_Category(BaseModel):\n name: str\n description: str\n def __init__(self, **data):\n if \"strCategory\" in data:\n data[\"name\"] = data.pop(\"strCategory\")\n if \"strCategoryDescription\" in data:\n data[\"description\"] = data.pop(\"strCategoryDescription\")\n super().__init__(**data)\n```\n\n```text\n>>> TMDB_Category(strCategory=\"name\", strCategoryDescription=\"description\").json()\n'{\"name\": \"name\", \"description\": \"description\"}'\n```\n\n```py\nclass TMDB_Category(BaseModel):\n strCategory: str = Field(alias=\"name\")\n strCategoryDescription: str = Field(alias=\"description\")\n class Config:\n allow_population_by_field_name = True\n @property\n def name(self):\n return self.strCategory\n @name.setter\n def name(self, value):\n self.strCategory = value\n @property\n def description(self):\n return self.strCategoryDescription\n @description.setter\n def description(self, value):\n self.strCategoryDescription = value\n```\n\n```text\n>>> TMDB_Category(name=\"name\", description=\"description\")\nTMDB_Category(strCategory='name', strCategoryDescription='description')\n```\n\n```text\npattern\n```\n\n```text\npatterns\n```\n\n```text\n__init__\n```\n\n```text\nclass TMDB_Category(BaseModel):\n name: str = Field(validation_alias=\"strCategory\")\n description: str = Field(validation_alias=\"strCategoryDescription\")\n```\n\n```text\nalias\n```\n\n```text\nvalidation_alias\n```\n\n```text\nserialization_alias\n```\n\n========================================\n\nComments:\n- I'm actually observing exactly the opposite behavior that the alias is not used in `.dict()` and `.json()` by default. According to the documentation whether they are used depends on the `by_alias` boolean keyword argument. And by default that is a weird default, considering that the author considers aliases as: \"a mapping between the names of fields used 'publicly' and the names used in your application. Where publicly means in javascript, in an API, in the file you're parsing etc.\"\n- I think you want to use `response_model_by_alias=False` in your path decorator, as mentioned in this answer: stackoverflow.com/a/69679104/8031815\n- Future readers might find this answer helpful as well.\n- Considering the setup you've shown. Will I be able to later access these properties in code by alias? For example, after parsing: `r = TMDB_GetCategoriesResponse.parse_obj(response.json())` `print(r.name)` `print(r.description)` or will I be forced to use these awful `r.strCategory` and `r.strCategoryDescription`\n- @Rechu, as far as I know, there is no direct way to access the values of the fields by alias and you have to use the field names. By direct way I mean without exporting it to a dict for example. Check issue #565 where the library author explains aliases as \"a mapping between the names of fields used 'publicly' and the names used in your application. Where publicly means in javascript, in an API, in the file you're parsing etc.\". This does not go well with your scenario because you have two different public names.\n- Does this solution integrate with pylance?\n- It appears you are the author of dataclass-wizard - it might be advisable to add a disclaimer to that effect, in particular since you're making critical claims about a competing solution.\n- @Seb good point - can't believe I overlooked that. just added a disclaimer to the post, stating as such.\n- This is the working answer.\n- this will not work if you have `response_model` set in the router's configuration. As OP has, `@router.get(path=\"category\", response_model=TMDB_GetCategoriesResponse)` the response field names will be different and will cause the it to fail validation while returning response\n- @Faizi Just use `validation_alias` and `serialization_alias` `id: str = Field(validation_alias=\"org_id\", serialization_alias=\"id\")`\n- This is a brilliant. Solves the issue where you don't want the model json to use alias by default. Very helpful where you let for e.g. FastAPI handle the model to json conversion.\n- validation_alias and serialization_alias will resolve the problem both ways. If you are using something like 'model_dump' to output the JSON model make sure to use 'by_alias=True' to honor the serialization alias.\n- man, u saved my life, so much effort wasted on searching...","metadata":{"transformedAt":"2026-08-18T18:32:29.088Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":34,"totalLines":431,"estimatedTokens":2794}}38{"id":"stack-68231936","source":"stackoverflow","questionId":68231936,"title":"How can I get headers or a specific header from my backend API?","tags":["python","fastapi"],"text":"Title: How can I get headers or a specific header from my backend API?\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI want to retrieve a specific header from my API inside a function with fastAPI, but I can't found a solution for this.\n\nIn flask was simply: `request.headers['your-header-name']`\n\nWhy the hell with fastAPI is so complicated to do a simple thing like this?\n\nAnyone know a solution to retrieve a header? Thanks :)\n\nThe decorator:\n\n```\ndef token_required(f):\n @wraps(f)\n def decorator(*args, **kwargs):\n CONFIG = settings.read_config()\n token = None\n headers = Request.headers\n if \"Authorization\" in headers:\n auth_header = Request.headers\n token = auth_header\n elif not token:\n return {\"Error\": \"Token is missing or incorrect header name\"}, 401\n\n try:\n public_key = CONFIG[\"APPLICATION\"][\"PUBLIC_KEY\"]\n claim = jwt.decode(token, public_key)\n claim.validate()\n except UnicodeDecodeError as err:\n return {\"Error\": f\"An error occurred -> {err} check your token\"}, 401\n\n return f(*args, **kwargs)\n\n return decorator\n```\n\nI need to read 'Authorization' header to check if exist or not.\n\n========================================\n\nTop Answer:\nOr, as described in the fastapi documentation (https://fastapi.tiangolo.com/tutorial/header-params/):\n\n```\nfrom typing import Optional\n\nfrom fastapi import FastAPI, Header\n\napp = FastAPI()\n\n@app.get(\"/items/\")\nasync def read_items(user_agent: Optional[str] = Header(None)):\n return {\"User-Agent\": user_agent}\n```\n\nthis will fetch the `user_agent` header parameter.\n\n========================================\n\nCode:\n```text\ndef token_required(f):\n @wraps(f)\n def decorator(*args, **kwargs):\n CONFIG = settings.read_config()\n token = None\n headers = Request.headers\n if \"Authorization\" in headers:\n auth_header = Request.headers\n token = auth_header\n elif not token:\n return {\"Error\": \"Token is missing or incorrect header name\"}, 401\n\n try:\n public_key = CONFIG[\"APPLICATION\"][\"PUBLIC_KEY\"]\n claim = jwt.decode(token, public_key)\n claim.validate()\n except UnicodeDecodeError as err:\n return {\"Error\": f\"An error occurred -> {err} check your token\"}, 401\n\n return f(*args, **kwargs)\n\n return decorator\n```\n\n```text\nrequest.headers['your-header-name']\n```\n\n```py\nfrom fastapi import FastAPI, Request\n\n\n@app.get(\"/\")\nasync def root(request: Request):\n my_header = request.headers.get('header-name')\n ...\n```\n\n```py\nfrom fastapi import FastAPI, Request\n\napp = FastAPI()\n\n\n@app.get(\"/\")\nasync def root(request: Request):\n my_header = request.headers.get('my-header')\n return {\"message\": my_header}\n```\n\n```py\ndef token_required(func):\n @wraps(func)\n async def wrapper(*args, request: Request, **kwargs):\n my_header = request.headers.get('my-header')\n # my_header will be now available in decorator\n return await func(*args, request, **kwargs)\n return wrapper\n```\n\n```text\ncurl\n```\n\n```text\ncurl -H \"My-Header: test\" -X GET http://localhost:8000\n```\n\n```text\n{\"message\":\"test\"}\n```\n\n```text\nfrom typing import Optional\n\nfrom fastapi import FastAPI, Header\n\napp = FastAPI()\n\n\n@app.get(\"/items/\")\nasync def read_items(user_agent: Optional[str] = Header(None)):\n return {\"User-Agent\": user_agent}\n```\n\n```text\nuser_agent\n```\n\n========================================\n\nComments:\n- Hi, I need to do this inside a decorator function. I'll update my question to clarify my problem\n- using middleware for this purpose doesn't suit your needs ?\n- anyways, I'll update my answer accordingly\n- I am converting a flask project to a fastAPI one, but in my flask project I was using the decorator on the paths I wanted them to be with authentication. I don't know how I can do the same thing but with fastAPI.\n- it might make sense for you to look into fast api middleware fastapi.tiangolo.com/tutorial/middleware Long story short you can use middleware to setup authentication in single function, but this would probably bring some complexity, since you'd either need to define two applications one for public routes and second for private. Easier way is using a decorator as you've mentioned, please check if update answer suits your needs\n- In that way decorator want a request value when I call it but if i pass inside him \"Request\" from fastAPI library return an error... I think I have to check how I can use middleware for two reasons. First: my decorator it seems unstable to me in fastAPI. Second: I want to the best practices for this framework. you confirm that middleware is the correct way to authenticate my private APIs, right?\n- This highly depends on your needs and weather you need to authenticate all routes or part of them. If it's only part of them, then take a look on dependencies fastapi.tiangolo.com/tutorial/dependencies, here's a nice example that covers authentication github.com/tiangolo/fastapi/issues/2037. If you need to authenticate all routes than you can use middleware\n- Yes, I have to authenticate only a part of them, not all routes. I will take a look to the links. Thank you ihoryam\n- I think it would be helpful to mention that request parameter can be used alongside with all other types of parameters. At least from the examples that wasn't obvious for me\n- Thanks for the answer. I have an additional doubt. Why cannot one access the Request object directly inside the decorator code? Why does one need to pass the Request as a function param?\n- What if you have several headers' fields you want to retrieve? Do you need to repeat the `Optional[str] = Header(None)` several times.","metadata":{"transformedAt":"2026-08-18T18:32:29.089Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":10,"totalLines":168,"estimatedTokens":1413}}39{"id":"stack-60424390","source":"stackoverflow","questionId":60424390,"title":"Is there a way to kill uvicorn cleanly?","tags":["python","python-3.x","fastapi","uvicorn"],"text":"Title: Is there a way to kill uvicorn cleanly?\nTags: python, python-3.x, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nIs there a way to kill uvicorn cleanly?\n\nI.e., I can type ^C at it, if it is running in the foreground on a terminal. This causes the uvivorn process to die and all of the worker processes to be cleaned up. (I.e., they go away.)\n\nOn the other hand, if uvicorn is running in the background without a terminal, then I can't figure out a way to kill it cleanly. It seems to ignore SIGTERM, SIGINT, and SIGHUP. I can kill it with SIGKILL (i.e. -9), but then the worker processes remain alive, and I have to track all the worker processes down and kill them too. This is not ideal.\n\nI am using uvicorn with CPython 3.7.4, uvivorn version 0.11.2, and FastAPI 0.46.0 on Red Hat Enterprise Linux Server 7.3 (Maipo).\n\n========================================\n\nTop Answer:\n```\nlsof -i :8000\n```\n\nThis will check processes using port :8000. If you are using different port for fastAPI then change the port number. I was using postman and python for fastAPI. So check process with python, then copy the PID usually 4-5 numbers.\n\nThen run\n\n```\nkill -9 PID\n```\n\n**Where PID is the PID number you copied**\n\n========================================\n\nCode:\n```bash\n$ kill $(pgrep -P $uvicorn_pid)\n```\n\n```text\nuvicorn\n```\n\n```text\nuvicorn\n```\n\n```text\nkill\n```\n\n```text\n^C\n```\n\n```text\nstdin\n```\n\n```sh\nPID=\"$(pgrep -f example:app)\"\nif [[ -n \"$PID\" ]]\nthen\n PGID=\"$(ps --no-headers -p $PID -o pgid)\"\n kill -SIGINT -- -${PGID// /}\nfi\n```\n\n```text\nuvicorn\n```\n\n```text\npgrep -P\n```\n\n```text\n^C\n```\n\n```text\npgrep -f example:app\n```\n\n```text\nuvicorn ... example:app\n```\n\n```text\n[[ -n \"$PID\" ]]\n```\n\n```text\nuvicorn\n```\n\n```text\nps --no-headers -p $PID -o pgid\n```\n\n```text\nkill -SIGINT\n```\n\n```text\n^C\n```\n\n```text\nkill -9\n```\n\n```text\n--\n```\n\n```text\n-\n```\n\n```text\n-${PGID\n```\n\n```text\nkill\n```\n\n```text\n${PGID// /}\n```\n\n```text\nps\n```\n\n```bash\nlsof -i :8000\n```\n\n```bash\nkill -9 PID\n```\n\n```text\nkill -9 $(ps -ef | grep uvicorn | awk '{print $2}')\n```\n\n```text\nalias uvicornprocess=\"kill -9 $(ps -ef | grep uvicorn | awk '{print $2}')\"\n```\n\n```text\ndocker ps # to get the CONTAINER ID\ndocker stop <CONTAINER ID>\n```\n\n```text\nsudo pkill 'uvicorn'\n```\n\n```py\ndef shutdown_rest_of_app(_, __):\n raise KeyboardInterrupt\n\n# Run this after your server starts up.\nimport signal\nsignal.signal(signal.SIGINT, shutdown_rest_of_app)\n\n# In your __main__.py where you start the server.\nimport uvicorn\nimport asyncio\n\ntry:\n loop = asyncio.new_event_loop()\n asyncio.set_event_loop(loop)\n\n web_config = {...}\n web_server = uvicorn.Server(config=web_config)\n\n loop.create_task(web_server.serve())\n loop.run_forever()\n\nexcept KeyboardInterrupt:\n logger.info(\"Caught Ctrl+C. Exiting gracefully.\")\n```\n\n```py\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.on_event(\"startup\")\nasync def startup_hook():\n import signal\n\n signal.signal(signal.SIGINT, shutdown_rest_of_app)\n```\n\n```text\n# oh_my_god.py\n\nimport asyncio\nimport logging\n\nfrom fastapi import FastAPI\nimport uvicorn\n\nlogger = logging.getLogger(__name__)\napp = FastAPI()\n\ndef shutdown_rest_of_app(_, __):\n raise KeyboardInterrupt\n\n# @app.on_event(\"startup\")\n# def startup_hook():\n# import signal\n\n# signal.signal(signal.SIGINT, shutdown_rest_of_app)\n\ndef main():\n try:\n loop = asyncio.new_event_loop()\n asyncio.set_event_loop(loop)\n\n web_config = uvicorn.Config(\n \"oh_my_god:app\",\n host=\"0.0.0.0\",\n port=1404,\n loop=\"asyncio\",\n workers=4,\n )\n\n web_server = uvicorn.Server(config=web_config)\n loop.create_task(web_server.serve())\n loop.run_forever()\n except KeyboardInterrupt:\n logger.info(\"Caught Ctrl+C. Exiting gracefully.\")\n\nif __name__ == \"__main__\":\n main()\n```\n\n```text\n^C\n```\n\n```text\nKeyboardInterrupt\n```\n\n```text\npython oh_my_god.py\n```\n\n```text\npkill -SIGINT python\n```\n\n```text\npkill -9 python\n```\n\n```text\npkill -SIGINT python\n```\n\n```text\nps aux | grep uvicorn or ps aux | grep python\n```\n\n```text\nfrom psutil import process_iter\nfrom time import time\n\n\n# ----------------------------------------------------------------\nclass CTime:\n def __init__(self):\n self.start = round(time())\n\n def PastTime(self):\n pt = int(round(time()) - self.start)\n return pt\n \n def PastTimeOf(self, period):\n pto = round(time()) - self.start > period\n return bool(pto)\n \n\n# ----------------------------------------------------------------\nclass Proc:\n \"\"\" Process Name: 'uvicorn' \"\"\"\n def __init__(self, ProcessName):\n self.ProcessName = ProcessName\n\n\n def Exist(self, Period:float=0):\n \"\"\" Des: If Exist Proc Returns True Else False \"\"\"\n pto = CTime()\n while True:\n for proc in process_iter():\n if proc.name() == f'{self.ProcessName}.exe': return True\n if pto.PastTimeOf(Period): return False\n\n def kill(self, Verbose:bool=False):\n \"\"\" Des: Kill Process If Exist \"\"\"\n if self.Exist():\n for proc in process_iter():\n if proc.name() == f'{self.ProcessName}.exe':\n proc.kill()\n if Verbose: print(f'Killed {self.ProcessName}')\n return True\n if Verbose: print(f'Process {self.ProcessName} not Exist')\n return False\n \n\n# ------------------------------------------------------- Usage ->\nProc('uvicorn').Exist()\nProc('uvicorn').kill()\n```\n\n========================================\n\nComments:\n- Might be related to #364, could you explain how to run it in the background without a terminal so that I can have a look at it? sigterm and sigint are the only 2 that are \"listened\" at\n- @euri10 There are many ways to run uvicorn in the background without a terminal. One way is to run it, and then to type ^Z to pause it. And then type \"bg\" to continue it in the background. And then type \"exit\" to the shell to make the shell and terminal go away. Alternatively, you could initially run it with \"&\" on the end of the command line, and elide the ^Z and the \"bg\". (You still need to type \"exit\" to the shell to make the shell and terminal go away.)\n- @euri10 P.S Thanks for looking into this!\n- just tested and I cant reproduce, in a terminal I run uvicorn example:app &! (I'm using zsh so have to use the ! to disown the process or I cant exit the terminal having running jobs) then I close the terminal and I kill -15 pidof uvicorn and it's gone, if you have a way to reproduce happy to try\n- Hmmm, weird! Sometimes things behave differently under different shells, but I can't install zsh easily on the computer in question. It could be a problem specific to Red Hat for some reason, but I wouldn't be able to reproduce that without giving you a Docker image, or something. Or it might be an issue with specific versions of things that I am running. But I can't easily change those either for various reasons. In any case, thanks for looking into this!\n- How do you run your uvicorn? Are you using uvicornWorkers with gunicorn or pure uvicorn?\n- I run it like so: (cd /home/foo; anaconda3-2019.10/bin/uvicorn --workers 20 --port 6700 en_pam_gb:app &> LOG.txt &)\n- uvicorn.org/server-behavior/#graceful-process-shutdown\n- I'd like to use this tip of killing background uvicorn workers but when I try to run `kill $(pgrep -P $uvicorn_pid)` I get the following error : `pgrep: option requires an argument -- P` `kill: not enough arguments`\n- You need to replace $uvicorn_pid with `uvicorn`'s PID, that's why `pgrep` is complaining about not having an argument.\n- Thank you for the quick reply. Still a beginner so got stuck. Cheers 🍻\n- To get uvicorn_pid, You can use something like `uvicorn_pid=pgrep -f 'uvicorn'`\n- Please do not `kill -9` processes, as the pid resources might go corrupt. Proper graceful termination is required to free these resources.\n- Having to use \"kill -9\" is not what I'm looking for, unfortunately. \"kill -9\" is a solution of last resort because something is not quite right.\n- I don't want to kill things with ^C. I want to do so by sending them a signal. We run these services as daemons that have no terminal.\n- Hitting `^C` in the terminal sends `SIGINT`.\n- These services have no terminal.\n- I think there's some fundamental misunderstanding here. Typing `^C` is a terminal window is equivalent to sending `SIGINT` to the process. You can send signals to processes with the `kill` command. Specifically `kill -s SIGINT $process_id`. If you're running your process in Docker you can use `docker kill --signal SIGINT $conainer_name`.\n- `SIGINT` is the standard way to ask a process to shut down gracefully but there's no reason you can't repurpose another one if that's you're desire. I would recommend `SIGUSR1` or `SIGUSR2` docs.python.org/3/library/signal.html.\n- As I mentioned in my OP, sending SIGINT to the uvicorn process did not work.\n- I'm not really sure what the communication gap here is. The code changes outlined by the answer make sending SIGINT work. See the edit for a complete runnable example.\n- While your answer is technically not wrong, it's missing the point that `uvicorn` is not a process manager. Stick to `gunicorn` and `SIGINT` should work properly. Reimplementing process management in `uvicorn` can be dangerous, as shutting down the FastAPI server is just one part of the process.\n- What an odd statement, `uvicorn` absolutely is a process manager. uvicorn.org/deployment -- it's the first deployment option. It's not \"dangerous\" at all.\n- @EstellePoulin the first option in your link is \"for local development\". The second option (gunicorn) is \"for production\".\n- Unless you know something I don't outside the linked documentation I have seen no indication of this. Not even the source github.com/encode/uvicorn/blob/master/uvicorn/supervisors/… has anything to say about its production readiness. It's been running fine in production for me for more than a year now. Given that supervisord and circus are also production-ready I see no reason to assume that their \"general rule\" based on ease of setup implies that only Gunicorn is safe in production.\n- As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.\n- While this code may answer the question, might you please edit your post to add an explanation as to why/how it works as suggested by How do I write a good answer? Thanks!","metadata":{"transformedAt":"2026-08-18T18:32:29.089Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":41,"totalLines":350,"estimatedTokens":2662}}40{"id":"stack-67255653","source":"stackoverflow","questionId":67255653,"title":"How to set up and tear down a database between tests in FastAPI?","tags":["python","unit-testing","fastapi"],"text":"Title: How to set up and tear down a database between tests in FastAPI?\nTags: python, unit-testing, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have set up my unit tests as per FastAPI documentation, but it only covers a case where database is persisted among tests.\n\nWhat if I want to build and tear down database per test? (for example, the second test below will fail, because the database will no longer be empty after the first test).\n\nI am currently doing it by calling `create_all` and `drop_all` (commented out in code below) on the beginning and end of each test, but this is obviously not ideal (if a test fails, the database will be never torn down, impacting the result of the next test).\n\nHow can I do it properly? Should I create some kind of Pytest fixture around `override_get_db` dependency?\n\n```\nfrom fastapi.testclient import TestClient\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import sessionmaker\n\nfrom main import app, get_db\nfrom database import Base\n\nSQLALCHEMY_DATABASE_URL = \"sqlite:///./test.db\"\n\nengine = create_engine(\n SQLALCHEMY_DATABASE_URL, connect_args={\"check_same_thread\": False}\n)\nTestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)\n\n# Base.metadata.create_all(bind=engine)\n\ndef override_get_db():\n try:\n db = TestingSessionLocal()\n yield db\n finally:\n db.close()\n\napp.dependency_overrides[get_db] = override_get_db\n\nclient = TestClient(app)\n\ndef test_get_todos():\n # Base.metadata.create_all(bind=engine)\n\n # create\n response = client.post('/todos/', json={'text': 'some new todo'})\n data1 = response.json()\n response = client.post('/todos/', json={'text': 'some even newer todo'})\n data2 = response.json()\n\n assert data1['user_id'] == data2['user_id']\n\n response = client.get('/todos/')\n\n assert response.status_code == 200\n assert response.json() == [\n {'id': data1['id'], 'user_id': data1['user_id'], 'text': data1['text']},\n {'id': data2['id'], 'user_id': data2['user_id'], 'text': data2['text']}\n ]\n\n # Base.metadata.drop_all(bind=engine)\n\ndef test_get_empty_todos_list():\n # Base.metadata.create_all(bind=engine)\n\n response = client.get('/todos/')\n\n assert response.status_code == 200\n assert response.json() == []\n\n # Base.metadata.drop_all(bind=engine)\n```\n\n========================================\n\nTop Answer:\nHere's a solution for a full FastAPI test environment, including database setup and teardown. Despite the fact that there is already an accepted answer, I'd like to contribute my thoughts.\n\nWhen configuring a test environment, you'll want to include these fixtures in your conftest.py file. Fixtures defined within it will be automatically accessible to any of your tests contained within the test package.\n\n**a) First of all, do the imports.**\n\nRemember that your imports path may differ from mine, so double-check that as well.\n\n```\nimport pytest\nfrom fastapi.testclient import TestClient\n\n# Import the SQLAlchemy parts\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.orm import sessionmaker\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom app.main import app\nfrom app.database import get_db,Base\n\n# Create the new database session\n\nSQLALCHEMY_DATABASE_URL = \"sqlite:///./test.db\"\n\nengine = create_engine(SQLALCHEMY_DATABASE_URL)\n\nTestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)\n```\n\nFollowing that, we'll use Pytest fixtures, which are functions that run before each test function to which they're applied.\n\n**b). Session fixture**\n\n```\n@pytest.fixture()\ndef session():\n\n Base.metadata.drop_all(bind=engine)\n Base.metadata.create_all(bind=engine)\n\n db = TestingSessionLocal()\n\n try:\n yield db\n finally:\n db.close()\n```\n\nThe above session fixture ensures that every time a test is run, we connect to a testing database, create tables, and then delete the tables once the test is finished.\n\n**c) client fixture**\n\n```\n@pytest.fixture()\ndef client(session):\n\n # Dependency override\n\n def override_get_db():\n try:\n\n yield session\n finally:\n session.close()\n\n app.dependency_overrides[get_db] = override_get_db\n\n yield TestClient(app)\n```\n\nThe above fixture connects us to the new test database and overrides the initial database connection made by the main app. The session fixture is required for this client fixture to function.\n\nAfter that, you can use the fixtures as shown without needing to import anything as shown below.\n\n```\ndef test_index(client):\n res = client.get(\"/\")\n assert res.status_code == 200\n```\n\nYour complete conftest.py file should now look like this:\n\n```\nimport pytest\nfrom fastapi.testclient import TestClient\n\n# Import the SQLAlchemy parts\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.orm import sessionmaker\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom app.main import app\nfrom app.database import get_db, Base\n\n# Create the new database session\n\nSQLALCHEMY_DATABASE_URL = \"sqlite:///./test.db\"\n\nengine = create_engine(SQLALCHEMY_DATABASE_URL)\n\nTestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)\n\n@pytest.fixture()\ndef session():\n\n # Create the database\n\n Base.metadata.drop_all(bind=engine)\n Base.metadata.create_all(bind=engine)\n\n db = TestingSessionLocal()\n try:\n yield db\n finally:\n db.close()\n\n@pytest.fixture()\ndef client(session):\n\n # Dependency override\n\n def override_get_db():\n try:\n yield session\n finally:\n session.close()\n\n app.dependency_overrides[get_db] = override_get_db\n\n yield TestClient(app)\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi.testclient import TestClient\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import sessionmaker\n\nfrom main import app, get_db\nfrom database import Base\n\nSQLALCHEMY_DATABASE_URL = \"sqlite:///./test.db\"\n\nengine = create_engine(\n SQLALCHEMY_DATABASE_URL, connect_args={\"check_same_thread\": False}\n)\nTestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)\n\n# Base.metadata.create_all(bind=engine)\n\ndef override_get_db():\n try:\n db = TestingSessionLocal()\n yield db\n finally:\n db.close()\n\napp.dependency_overrides[get_db] = override_get_db\n\nclient = TestClient(app)\n\ndef test_get_todos():\n # Base.metadata.create_all(bind=engine)\n\n # create\n response = client.post('/todos/', json={'text': 'some new todo'})\n data1 = response.json()\n response = client.post('/todos/', json={'text': 'some even newer todo'})\n data2 = response.json()\n\n assert data1['user_id'] == data2['user_id']\n\n response = client.get('/todos/')\n\n assert response.status_code == 200\n assert response.json() == [\n {'id': data1['id'], 'user_id': data1['user_id'], 'text': data1['text']},\n {'id': data2['id'], 'user_id': data2['user_id'], 'text': data2['text']}\n ]\n\n # Base.metadata.drop_all(bind=engine)\n\ndef test_get_empty_todos_list():\n # Base.metadata.create_all(bind=engine)\n\n response = client.get('/todos/')\n\n assert response.status_code == 200\n assert response.json() == []\n\n # Base.metadata.drop_all(bind=engine)\n```\n\n```text\ncreate_all\n```\n\n```text\ndrop_all\n```\n\n```text\noverride_get_db\n```\n\n```text\n@pytest.fixture()\ndef test_db():\n Base.metadata.create_all(bind=engine)\n yield\n Base.metadata.drop_all(bind=engine)\n```\n\n```text\ndef test_get_empty_todos_list(test_db):\n response = client.get('/todos/')\n\n assert response.status_code == 200\n assert response.json() == []\n```\n\n```text\nimport pytest\nfrom fastapi.testclient import TestClient\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.orm import sessionmaker\n\nfrom main import app, get_db\nfrom database import Base\n\n\nSQLALCHEMY_DATABASE_URL = \"sqlite:///./test.db\"\n\nengine = create_engine(\n SQLALCHEMY_DATABASE_URL, connect_args={\"check_same_thread\": False}\n)\nTestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)\n\n\ndef override_get_db():\n try:\n db = TestingSessionLocal()\n yield db\n finally:\n db.close()\n\n\n@pytest.fixture()\ndef test_db():\n Base.metadata.create_all(bind=engine)\n yield\n Base.metadata.drop_all(bind=engine)\n\napp.dependency_overrides[get_db] = override_get_db\n\nclient = TestClient(app)\n\n\ndef test_get_todos(test_db):\n response = client.post(\"/todos/\", json={\"text\": \"some new todo\"})\n data1 = response.json()\n response = client.post(\"/todos/\", json={\"text\": \"some even newer todo\"})\n data2 = response.json()\n\n assert data1[\"user_id\"] == data2[\"user_id\"]\n\n response = client.get(\"/todos/\")\n\n assert response.status_code == 200\n assert response.json() == [\n {\"id\": data1[\"id\"], \"user_id\": data1[\"user_id\"], \"text\": data1[\"text\"]},\n {\"id\": data2[\"id\"], \"user_id\": data2[\"user_id\"], \"text\": data2[\"text\"]},\n ]\n\n\ndef test_get_empty_todos_list(test_db):\n response = client.get(\"/todos/\")\n\n assert response.status_code == 200\n assert response.json() == []\n```\n\n```text\nimport pytest\nimport sqlalchemy as sa\nfrom fastapi.testclient import TestClient\nfrom sqlalchemy.orm import sessionmaker\n\nfrom database import Base\nfrom main import app, get_db\n\nSQLALCHEMY_DATABASE_URL = \"sqlite:///./test.db\"\n\nengine = sa.create_engine(\n SQLALCHEMY_DATABASE_URL, connect_args={\"check_same_thread\": False}\n)\nTestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)\n\n# Set up the database once\nBase.metadata.drop_all(bind=engine)\nBase.metadata.create_all(bind=engine)\n\n\n# These two event listeners are only needed for sqlite for proper\n# SAVEPOINT / nested transaction support. Other databases like postgres\n# don't need them. \n# From: https://docs.sqlalchemy.org/en/14/dialects/sqlite.html#serializable-isolation-savepoints-transactional-ddl\n@sa.event.listens_for(engine, \"connect\")\ndef do_connect(dbapi_connection, connection_record):\n # disable pysqlite's emitting of the BEGIN statement entirely.\n # also stops it from emitting COMMIT before any DDL.\n dbapi_connection.isolation_level = None\n\n\n@sa.event.listens_for(engine, \"begin\")\ndef do_begin(conn):\n # emit our own BEGIN\n conn.exec_driver_sql(\"BEGIN\")\n\n\n# This fixture is the main difference to before. It creates a nested\n# transaction, recreates it when the application code calls session.commit\n# and rolls it back at the end.\n# Based on: https://docs.sqlalchemy.org/en/14/orm/session_transaction.html#joining-a-session-into-an-external-transaction-such-as-for-test-suites\n@pytest.fixture()\ndef session():\n connection = engine.connect()\n transaction = connection.begin()\n session = TestingSessionLocal(bind=connection)\n\n # Begin a nested transaction (using SAVEPOINT).\n nested = connection.begin_nested()\n\n # If the application code calls session.commit, it will end the nested\n # transaction. Need to start a new one when that happens.\n @sa.event.listens_for(session, \"after_transaction_end\")\n def end_savepoint(session, transaction):\n nonlocal nested\n if not nested.is_active:\n nested = connection.begin_nested()\n\n yield session\n\n # Rollback the overall transaction, restoring the state before the test ran.\n session.close()\n transaction.rollback()\n connection.close()\n\n\n# A fixture for the fastapi test client which depends on the\n# previous session fixture. Instead of creating a new session in the\n# dependency override as before, it uses the one provided by the\n# session fixture.\n@pytest.fixture()\ndef client(session):\n def override_get_db():\n yield session\n\n app.dependency_overrides[get_db] = override_get_db\n yield TestClient(app)\n del app.dependency_overrides[get_db]\n\n\ndef test_get_empty_todos_list(client):\n response = client.get(\"/todos/\")\n\n assert response.status_code == 200\n assert response.json() == []\n```\n\n```text\ndef test_something(session):\n session.query(...)\n```\n\n```text\ndef test_something_else(client, session):\n session.add(...)\n session.commit()\n client.get(...)\n```\n\n```text\npytest.fixture\n```\n\n```text\ntest_db\n```\n\n```text\nBase.metadata.create_all(bind=engine)\n```\n\n```text\nBase.metadata.drop_all(bind=engine)\n```\n\n```text\nsession\n```\n\n```text\nclient\n```\n\n```text\nimport pytest\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.orm import sessionmaker, declarative_base\nfrom contextlib import contextmanager\n\nengine = create_engine('postgresql://...')\nSession = sessionmaker(bind=engine)\nBase = declarative_base()\n\n\n@contextmanager\ndef session_scope():\n \"\"\"Provide a transactional scope around a series of operations.\"\"\"\n session = Session()\n try:\n yield session\n session.commit()\n except:\n session.rollback()\n raise\n finally:\n session.close()\n\n\ndef clear_tables():\n with session_scope() as conn:\n for table in Base.metadata.sorted_tables:\n conn.execute(\n f\"TRUNCATE {table.name} RESTART IDENTITY CASCADE;\"\n )\n conn.commit()\n\n\n@pytest.fixture\ndef test_db_session():\n yield engine\n engine.dispose()\n clear_tables()\n\n\ndef test_some_feature(test_db_session):\n test_db_session.query(...)\n (...)\n```\n\n```py\nimport pytest\nfrom fastapi.testclient import TestClient\n\n# Import the SQLAlchemy parts\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.orm import sessionmaker\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom app.main import app\nfrom app.database import get_db,Base\n\n# Create the new database session\n\nSQLALCHEMY_DATABASE_URL = \"sqlite:///./test.db\"\n\nengine = create_engine(SQLALCHEMY_DATABASE_URL)\n\nTestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)\n```\n\n```py\n@pytest.fixture()\ndef session():\n\n Base.metadata.drop_all(bind=engine)\n Base.metadata.create_all(bind=engine)\n\n db = TestingSessionLocal()\n\n try:\n yield db\n finally:\n db.close()\n```\n\n```py\n@pytest.fixture()\ndef client(session):\n\n # Dependency override\n\n def override_get_db():\n try:\n\n yield session\n finally:\n session.close()\n\n app.dependency_overrides[get_db] = override_get_db\n\n yield TestClient(app)\n```\n\n```py\ndef test_index(client):\n res = client.get(\"/\")\n assert res.status_code == 200\n```\n\n```py\nimport pytest\nfrom fastapi.testclient import TestClient\n\n# Import the SQLAlchemy parts\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.orm import sessionmaker\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom app.main import app\nfrom app.database import get_db, Base\n\n# Create the new database session\n\nSQLALCHEMY_DATABASE_URL = \"sqlite:///./test.db\"\n\nengine = create_engine(SQLALCHEMY_DATABASE_URL)\n\nTestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)\n\n\n@pytest.fixture()\ndef session():\n\n # Create the database\n\n Base.metadata.drop_all(bind=engine)\n Base.metadata.create_all(bind=engine)\n\n db = TestingSessionLocal()\n try:\n yield db\n finally:\n db.close()\n\n\n@pytest.fixture()\ndef client(session):\n\n # Dependency override\n\n def override_get_db():\n try:\n yield session\n finally:\n session.close()\n\n app.dependency_overrides[get_db] = override_get_db\n\n yield TestClient(app)\n```\n\n```text\nfrom fastapi.testclient import TestClient\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.orm import sessionmaker\nfrom app.main import app\nfrom app.db.database import Base, get_db\nimport pytest\n\nTEST_DATABASE_URL = 'postgresql://postgres:admin@localhost:5432/yourdatabsename'\nmain_app = app # this app comes from my main file, in which i declared FAST API as app\n\ndef start_application(): # start application\n return main_app\n\nSQLALCHEMY_DATABASE_URL = TEST_DATABASE_URL\nengine = create_engine(SQLALCHEMY_DATABASE_URL) # create engine\n\nSessionTesting = sessionmaker(autocommit=False, autoflush=False, bind=engine) # now we create test-session \n\n\n@pytest.fixture(scope=\"function\")\ndef app():\n \"\"\"\n Create a fresh database on each test case.\n \"\"\"\n Base.metadata.create_all(engine) # Create the tables.\n _app = start_application()\n yield _app\n Base.metadata.drop_all(engine) # drop that tables\n\n\n@pytest.fixture(scope=\"function\")\ndef db_session(app: FastAPI):\n connection = engine.connect()\n transaction = connection.begin()\n session = SessionTesting(bind=connection)\n yield session # use the session in tests.\n session.close()\n transaction.rollback()\n connection.close()\n\n@pytest.fixture(scope=\"function\")\ndef client(app: FastAPI, db_session: SessionTesting):\n \"\"\"\n Create a new FastAPI TestClient that uses the `db_session` fixture to override the `get_db` dependency that is injected into routes.\n \"\"\"\n \n def _get_test_db():\n db_session = SessionTesting()\n try:\n yield db_session\n finally:\n db_session.close() \n\n app.dependency_overrides[get_db] = _get_test_db\n with TestClient(app) as client:\n yield client\n```\n\n```text\nfrom app.models.models import OrganizationType\n\n\ndef test_get_organization_type(client, db_session):\n response_post = client.post(URL will comes Here, json={'type_name': 'test_organization'})\n assert response_post.status_code == 201\n\n response_get = client.get(URL will come Here) # get_request\n data = response_get.json()\n assert response_get.status_code == 200\n```\n\n```text\nconfest.py\n```\n\n```text\ncontest.py\n```\n\n========================================\n\nComments:\n- I just wanted to say this post is gold -- thank you for writing it because its exactly what I was looking for. Cheers.\n- Great answer! For those that are looking for an ASYNC variant of the above session fixture, here is a recipe from the SQLAlchemy issue board: github.com/sqlalchemy/sqlalchemy/issues/…\n- This post is gold indeed. Should be a part of FastAPI/SQLAlchemy official docs ;)\n- For the first solution, my code freezes up after running the test function with post request. Any ideas why that happens?\n- @FariborzGhavamian Hmm, unexpected freezing in database code can e.g. happen when there is a transaction being kept open in another thread/program. (An then in your case maybe prevent `Base.metadata.drop_all` from finishing). Do you perhaps launch any background threads that access the db in your code?\n- Hi, i am using a solution very similar to this, but I have a problem with duplicate keys. I have other pytest fixtures that set up database content using the 'session' object here. Lets say, i create 2 items in my `content` table, with id 1 and 2. If i now have a test calling that feature, and doing `post` request on that endpoint, it will complain the id 1 is taken. i run it again, will complain that id 2 is taken. next time, will pass.... so basically, the issue is that the 'fixture' doesn't increment the the postgres content_seq_id). Anybody ran into this ?\n- Best SO post I've read in a while. Agree that these should end up in docs for database testing.\n- I can see that we can use session in the test but there is no way to use the session in the fixture.\n- @JeetPatel You can use a fixture within another fixture, just add it as an argument as usual. (Like the `client` fixture above depends on the `session` fixture)\n- @mihi, great solution thanks a lot! How would you go about mocking the serveur_default=func.now() attribute since it's executed at tables creation and outside the scope of the fixture? :/\n- Spent a day until i found this one. Brilliant post\n- This is levels better than official documentation !\n- The 2.0 docs mentions a new `join_mode` for sessions (docs.sqlalchemy.org/en/20/changelog/…) in order to avoid listening on events.","metadata":{"transformedAt":"2026-08-18T18:32:29.089Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":26,"totalLines":736,"estimatedTokens":4924}}41{"id":"stack-65296604","source":"stackoverflow","questionId":65296604,"title":"How to return a HTMLResponse with FastAPI","tags":["python","web","fastapi"],"text":"Title: How to return a HTMLResponse with FastAPI\nTags: python, web, fastapi\nSource: Stack Overflow\n\nQuestion:\nIs it possible to display an HTML file at the endpoint?\n\nFor example the home page then the user is visiting `\"/\"`?\n\n========================================\n\nCode:\n```text\n\"/\"\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.responses import HTMLResponse\n\napp = FastAPI()\n\n@app.get(\"/\", response_class=HTMLResponse)\nasync def read_items():\n html_content = \"\"\"\n <html>\n <head>\n <title>Some HTML in here</title>\n </head>\n <body>\n <h1>Look ma! HTML!</h1>\n </body>\n </html>\n \"\"\"\n return HTMLResponse(content=html_content, status_code=200)\n```\n\n```py\nfrom fastapi import FastAPI, Request\nfrom fastapi.responses import HTMLResponse\nfrom fastapi.staticfiles import StaticFiles\nfrom fastapi.templating import Jinja2Templates\n\napp = FastAPI()\n\napp.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")\n\n\ntemplates = Jinja2Templates(directory=\"templates\")\n\n\n@app.get(\"/items/{id}\", response_class=HTMLResponse)\nasync def read_item(request: Request, id: str):\n return templates.TemplateResponse(\"item.html\", {\"request\": request, \"id\": id}\n```\n\n```text\nHTMLResponse\n```\n\n```text\nHTMLResponse\n```\n\n========================================\n\nComments:\n- Does this mean, we can use FastAPI to run a full fledged website?\n- Yes, FastAPI can run a full fledged website.","metadata":{"transformedAt":"2026-08-18T18:32:29.089Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":69,"estimatedTokens":361}}42{"id":"stack-69504352","source":"stackoverflow","questionId":69504352,"title":"FastAPI - GET request results in typeerror (value is not a valid dict)","tags":["python","get","fastapi","pydantic"],"text":"Title: FastAPI - GET request results in typeerror (value is not a valid dict)\nTags: python, get, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nthis is my database schema.\n\nhttps://i.sstatic.net/JnTih.jpg\n\nI defined my Schema like this:\n\nfrom pydantic import BaseModel\n\n```\nclass Userattribute(BaseModel):\n name: str\n value: str\n user_id: str\n id: str\n```\n\nThis is my model:\n\n```\nclass Userattribute(Base):\n __tablename__ = \"user_attribute\"\n\n name = Column(String)\n value = Column(String)\n user_id = Column(String)\n id = Column(String, primary_key=True, index=True)\n```\n\nIn a crud.py I define a `get_attributes` method.\n\n```\ndef get_attributes(db: Session, skip: int = 0, limit: int = 100):\n return db.query(models.Userattribute).offset(skip).limit(limit).all()\n```\n\nThis is my `GET` endpoint:\n\n```\n@app.get(\"/attributes/\", response_model=List[schemas.Userattribute])\ndef read_attributes(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):\n users = crud.get_attributes(db, skip=skip, limit=limit)\n print(users)\n return users\n```\n\nThe connection to the database seems to work, but a problem is the datatype:\n\n```\npydantic.error_wrappers.ValidationError: 7 validation errors for Userattribute\nresponse -> 0\n value is not a valid dict (type=type_error.dict)\nresponse -> 1\n value is not a valid dict (type=type_error.dict)\nresponse -> 2\n value is not a valid dict (type=type_error.dict)\nresponse -> 3\n value is not a valid dict (type=type_error.dict)\nresponse -> 4\n value is not a valid dict (type=type_error.dict)\nresponse -> 5\n value is not a valid dict (type=type_error.dict)\nresponse -> 6\n value is not a valid dict (type=type_error.dict)\n```\n\nWhy does FASTApi expect a dictionary here? I don´t really understand it, since I am not able to even print the response. How can I fix this?\n\n========================================\n\nTop Answer:\nThis error is caused by two things:\n\nThe reponse_model parameter in the path operation decorator, which defines the type/shape of response to be returned. Removing this will eliminate the errors you see, as it will remove the validation against what is being returned.\n\nThe internal Config class that is missing in your Pydantic schemas.\n\nMake sure to add the Config class to avoid this problem, or at worst, remove the response_model parameter (which I doubt anyone would consider). Example is:\n\n```\nclass ItemBase(BaseModel):\n title: str\n description: Union[str, None] = None\n\n class Config:\n orm_mode = True\n```\n\nAdding this class allows Pydantic model to read data in non-dictionary format, thereby allowing you to return database model.\n\nCheckout the fastAPI documentation for more\n\n========================================\n\nCode:\n```text\nclass Userattribute(BaseModel):\n name: str\n value: str\n user_id: str\n id: str\n```\n\n```text\nclass Userattribute(Base):\n __tablename__ = \"user_attribute\"\n\n name = Column(String)\n value = Column(String)\n user_id = Column(String)\n id = Column(String, primary_key=True, index=True)\n```\n\n```text\ndef get_attributes(db: Session, skip: int = 0, limit: int = 100):\n return db.query(models.Userattribute).offset(skip).limit(limit).all()\n```\n\n```text\n@app.get(\"/attributes/\", response_model=List[schemas.Userattribute])\ndef read_attributes(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):\n users = crud.get_attributes(db, skip=skip, limit=limit)\n print(users)\n return users\n```\n\n```text\npydantic.error_wrappers.ValidationError: 7 validation errors for Userattribute\nresponse -> 0\n value is not a valid dict (type=type_error.dict)\nresponse -> 1\n value is not a valid dict (type=type_error.dict)\nresponse -> 2\n value is not a valid dict (type=type_error.dict)\nresponse -> 3\n value is not a valid dict (type=type_error.dict)\nresponse -> 4\n value is not a valid dict (type=type_error.dict)\nresponse -> 5\n value is not a valid dict (type=type_error.dict)\nresponse -> 6\n value is not a valid dict (type=type_error.dict)\n```\n\n```text\nget_attributes\n```\n\n```text\nGET\n```\n\n```py\nclass Userattribute(BaseModel):\n name: str\n value: str\n user_id: str\n id: str\n\n class Config:\n orm_mode = True\n```\n\n```py\nclass OurBaseModel(BaseModel):\n class Config:\n orm_mode = True\n\n\nclass Userattribute(OurBaseModel):\n name: str\n value: str\n user_id: str\n id: str\n```\n\n```py\nfrom pydantic import ConfigDict\n\nclass OurBaseModel(BaseModel):\n model_config = ConfigDict(from_attributes=True)\n```\n\n```text\nreturn\n```\n\n```text\norm_mode = True\n```\n\n```text\nBaseModel\n```\n\n```text\norm_mode\n```\n\n```text\nBaseModel\n```\n\n```text\nConfig\n```\n\n```text\nmodel_config\n```\n\n```text\norm_mode\n```\n\n```text\nclass ItemBase(BaseModel):\n title: str\n description: Union[str, None] = None\n\n class Config:\n orm_mode = True\n```\n\n========================================\n\nComments:\n- Thanks in my case I had got code from another dev and he had typo `class config:`\n- Using the `orm_mode` in my parent class fixed it... THANK YOU","metadata":{"transformedAt":"2026-08-18T18:32:29.089Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":19,"totalLines":233,"estimatedTokens":1248}}43{"id":"stack-64364499","source":"stackoverflow","questionId":64364499,"title":"Set description for query parameter in swagger doc using Pydantic model (FastAPI)","tags":["python","fastapi"],"text":"Title: Set description for query parameter in swagger doc using Pydantic model (FastAPI)\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nThis is continue to this question.\n\nI have added a model to get query params to pydantic model\n\n```\nclass QueryParams(BaseModel):\n x: str = Field(description=\"query x\")\n y: str = Field(description=\"query y\")\n z: str = Field(description=\"query z\")\n\n@app.get(\"/test-query-url/{test_id}\")\nasync def get_by_query(test_id: int, query_params: QueryParams = Depends()):\n print(test_id)\n print(query_params.dict(by_alias=True))\n return True\n```\n\nit is working as expected but description(added in model) is not reflecting in swagger ui\n\nhttps://i.sstatic.net/m46op.png\n\nBut if same model is used for request body, then description is shown in swagger\n\nhttps://i.sstatic.net/Sa0ei.png\n\nAm I missing anything to get the description for QueryParams(model) in swagger ui?\n\n========================================\n\nTop Answer:\nThis worked for me\n\n```\nfrom fastapi import Depends, FastAPI, Query\n\n@app.post(\"/route\")\ndef some_api(\n self,\n query_param_1: float = Query(None, description=\"description goes here\", ),\n query_param_2: float = Query(None, description=\"Param 2 does xyz\"),\n):\n \nreturn \"hello world\"\n```\n\n========================================\n\nCode:\n```text\nclass QueryParams(BaseModel):\n x: str = Field(description=\"query x\")\n y: str = Field(description=\"query y\")\n z: str = Field(description=\"query z\")\n\n\n@app.get(\"/test-query-url/{test_id}\")\nasync def get_by_query(test_id: int, query_params: QueryParams = Depends()):\n print(test_id)\n print(query_params.dict(by_alias=True))\n return True\n```\n\n```text\nfrom fastapi import Depends, FastAPI, Query\n\napp = FastAPI()\n\n\nclass CustomQueryParams:\n def __init__(\n self,\n foo: str = Query(..., description=\"Cool Description for foo\"),\n bar: str = Query(..., description=\"Cool Description for bar\"),\n ):\n self.foo = foo\n self.bar = bar\n\n\n@app.get(\"/test-query/\")\nasync def get_by_query(params: CustomQueryParams = Depends()):\n return params\n```\n\n```py\nfrom fastapi import Depends, FastAPI, Query\n\n@app.post(\"/route\")\ndef some_api(\n self,\n query_param_1: float = Query(None, description=\"description goes here\", ),\n query_param_2: float = Query(None, description=\"Param 2 does xyz\"),\n):\n \nreturn \"hello world\"\n```\n\n```text\nclass QueryParams:\n def __init__(self, \n x: Query(\n None, description=\"Arg1\", example=10),\n y: Query(\n None, description=\"Arg2\", example=20)\n ):\n self.x = x\n self.y = y\n```\n\n```text\n@dataclass\nclass QueryParams:\n x: Query(None, description=\"Arg1\", example=10)\n y: Query(None, description=\"Arg2\", example=20)\n```\n\n```text\n__init__\n```\n\n```py\nfrom enum import Enum\nfrom typing import List\nfrom fastapi import APIRouter, Depends, Query\nfrom pydantic import BaseModel, Field\n\nROUTER = APIRouter()\n\nclass MyEnum(str, Enum):\n OPTION_ONE = \"option_one\"\n OPTION_TWO = \"option_two\"\n\nclass QueryParams(BaseModel):\n foo: List[str] = Field(Query(\n default_factory=list,\n description=\"List of foo parameters\",\n ))\n bar: MyEnum = Field(Query(\n default=MyEnum.OPTION_ONE,\n description=\"Enum for bar parameters\",\n ))\n\n@ROUTER.get(\"/endpoint\")\nasync def endpoint(params: QueryParams = Depends()):\n foobar = \"something\" # Dummy response\n return {\"foobar\": foobar}\n```\n\n========================================\n\nComments:\n- I disagree with Arakkabal's answer, i was able to this, also OpenAPI Spec & Swagger allows this and query parameters has a description field see.So that means you should be doing this, because FastAPI is based on OpenAPI specification. I'll take a look at this again, later today.\n- It **is now possible**. In the recent versions of FastAPI, one could wrap the `Query()` in a `Field()`, and hence, be able to set the `description` (and other arguments) for a query parameter defined in a Pydantic model. Please have a look at this answer and this answer for more details.\n- Since FastAPI 0.115.0 you can use this example from official FastAPI manual. fastapi.tiangolo.com/tutorial/query-param-models/…\n- This would do. But wanted to have pydantic model\n- You can't do this with Pydantic. ref this\n- not sure why to use Query though, it has similar attributes as pydantic Field\n- `Query(...)` is used to generate the OpenAPI schema\n- this should be accepted answer for Pydantic V2 at least\n- Like Pydantic-based model, this doesn't work with *path* params; e.g: `stage: tp.Literal['add','delete'] = fa.Path(description='this is the stage')`\n- As a matter of fact though, \"wrapping\" the `Query` inside the `Field` function call does not quite work. `pydantic.Field` actually has it's own `default`, `description` and `example` parameters, which work exactly as `fastapi.Query`.","metadata":{"transformedAt":"2026-08-18T18:32:29.089Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":7,"totalLines":165,"estimatedTokens":1224}}44{"id":"stack-66444620","source":"stackoverflow","questionId":66444620,"title":"asyncpg - cannot perform operation: another operation is in progress","tags":["python-3.x","asynchronous","python-asyncio","fastapi","asyncpg"],"text":"Title: asyncpg - cannot perform operation: another operation is in progress\nTags: python-3.x, asynchronous, python-asyncio, fastapi, asyncpg\nSource: Stack Overflow\n\nQuestion:\nI am attempting to resolve the following error:\n\n```\nasyncpg.exceptions._base.InterfaceError: cannot perform operation: another operation is in progress\n```\n\nHere is the full traceback:\n\n```\nTraceback (most recent call last):\n\n File \"\", line 1, in \n File \"/Users/ddd/.pyenv/versions/3.8.6/lib/python3.8/multiprocessing/spawn.py\", line 116, in spawn_main\n exitcode = _main(fd, parent_sentinel)\n │ │ └ 4\n │ └ 7\n └ \n File \"/Users/ddd/.pyenv/versions/3.8.6/lib/python3.8/multiprocessing/spawn.py\", line 129, in _main\n return self._bootstrap(parent_sentinel)\n │ │ └ 4\n │ └ \n └ \n File \"/Users/ddd/.pyenv/versions/3.8.6/lib/python3.8/multiprocessing/process.py\", line 315, in _bootstrap\n self.run()\n │ └ \n └ \n File \"/Users/ddd/.pyenv/versions/3.8.6/lib/python3.8/multiprocessing/process.py\", line 108, in run\n self._target(*self._args, **self._kwargs)\n │ │ │ │ │ └ {'config': , 'target': \n │ │ │ └ ()\n │ │ └ \n │ └ \n └ \n File \"/Users/ddd/Desktop/repos/xxx/.venv/lib/python3.8/site-packages/uvicorn/subprocess.py\", line 61, in subprocess_started\n target(sockets=sockets)\n │ └ []\n └ >\n File \"/Users/ddd/Desktop/repos/xxx/.venv/lib/python3.8/site-packages/uvicorn/server.py\", line 48, in run\n loop.run_until_complete(self.serve(sockets=sockets))\n │ │ │ │ └ []\n │ │ │ └ \n │ │ └ \n │ └ \n └ \n File \"/Users/ddd/.pyenv/versions/3.8.6/lib/python3.8/asyncio/base_events.py\", line 603, in run_until_complete\n self.run_forever()\n │ └ \n └ \n File \"/Users/ddd/.pyenv/versions/3.8.6/lib/python3.8/asyncio/base_events.py\", line 570, in run_forever\n self._run_once()\n │ └ \n └ \n File \"/Users/ddd/.pyenv/versions/3.8.6/lib/python3.8/asyncio/base_events.py\", line 1859, in _run_once\n handle._run()\n │ └ \n └ ()>\n File \"/Users/ddd/.pyenv/versions/3.8.6/lib/python3.8/asyncio/events.py\", line 81, in _run\n self._context.run(self._callback, *self._args)\n │ │ │ │ │ └ \n │ │ │ │ └ ()>\n │ │ │ └ \n │ │ └ ()>\n │ └ \n └ ()>\n\n> File \"./xxx/xxx/xxx.py\", line 144, in get_disclosure_data\n hh_json, db_json = await asyncio.gather(*coroutines)\n │ │ └ [, ]\n │ └ \n └ \n\n File \"./xxx/xxx/xxx.py\", line 52, in db_call\n db_json = await asyncio.gather(*coroutines, loop=asyncio.get_event_loop())\n │ │ │ │ └ \n │ │ │ └ \n │ │ └ [, \n └ \n\n File \"./xxx/xxx/xx.py\", line 97, in fetch_item\n await self._connection_pool.release(self.con)\n │ │ │ │ └ \n │ │ │ └ \n │ │ └ \n │ └ \n └ \n\n File \"/Users/ddd/Desktop/repos/xxx/.venv/lib/python3.8/site-packages/asyncpg/pool.py\", line 666, in release\n return await asyncio.shield(ch.release(timeout))\n │ │ │ │ └ None\n │ │ │ └ \n │ │ └ \n │ └ \n └ \n File \"/Users/ddd/Desktop/repos/xxx/.venv/lib/python3.8/site-packages/asyncpg/pool.py\", line 218, in release\n raise ex\n File \"/Users/ddd/Desktop/repos/xxx/.venv/lib/python3.8/site-packages/asyncpg/pool.py\", line 208, in release\n await self._con.reset(timeout=budget)\n │ │ └ None\n │ └ \n └ \n File \"/Users/ddd/Desktop/repos/xxx/.venv/lib/python3.8/site-packages/asyncpg/connection.py\", line 1311, in reset\n await self.execute(reset_query, timeout=timeout)\n │ │ │ └ None\n │ │ └ 'SELECT pg_advisory_unlock_all();\\nCLOSE ALL;\\nUNLISTEN *;\\nRESET ALL;'\n │ └ \n └ \n File \"/Users/ddd/Desktop/repos/xxx/.venv/lib/python3.8/site-packages/asyncpg/connection.py\", line 297, in execute\n return await self._protocol.query(query, timeout)\n │ │ │ └ None\n │ │ └ 'SELECT pg_advisory_unlock_all();\\nCLOSE ALL;\\nUNLISTEN *;\\nRESET ALL;'\n │ └ \n └ \n File \"asyncpg/protocol/protocol.pyx\", line 321, in query\n self._check_state()\n File \"asyncpg/protocol/protocol.pyx\", line 684, in asyncpg.protocol.protocol.BaseProtocol._check_state\n raise apg_exc.InterfaceError(\n │ └ \n └ where I have the following code to set up a connection pool and execute queries with connections in the pool:\n\n```\nclass DBConnectionManager(object):\n \"\"\" Class for setting up and tearing down db connection \"\"\"\n\n def __init__(self):\n self.host = SETTINGS.db_host\n self.database = SETTINGS.db_name\n self.user = SETTINGS.db_user\n self.password = SETTINGS.db_password\n self.port = \"5432\"\n\n self._connection_pool = None\n self.con = None\n\n async def connect(self):\n if not self._connection_pool:\n try:\n self._connection_pool = await asyncpg.create_pool(\n host=self.host,\n database=self.database,\n user=self.user,\n password=self.password,\n port=self.port,\n min_size=50,\n max_size=100,\n )\n logger.info(\"Database pool connection opened\")\n\n except Exception as e:\n logger.exception(e)\n\n async def fetch_item(self, query: str, *args):\n if not self._connection_pool:\n await self.connect()\n else:\n self.con = await self._connection_pool.acquire()\n try:\n result = await self.con.fetch(query, *args)\n return result\n except Exception as e:\n logger.exception(e)\n finally:\n await self._connection_pool.release(self.con)\n\n async def close(self):\n if not self._connection_pool:\n try:\n await self._connection_pool.close()\n logger.info(\"Database pool connection closed\")\n except Exception as e:\n logger.exception(e)\n```\n\nand am attempting to execute some 22 database calls using the following:\n\n```\nasync def db_call(db, lat, lng):\n \"\"\"\n Performs the necessary db calls given a lat, lng\n\n Required Input:\n lat::float a latitude in decimal degrees. Must be specified with `lng` (i.e. 39.2994)\n lng::float a longitude in decimal degrees. Must be specified with `lat` (i.e. -122.33)\n\n Returns:\n dict\n \"\"\"\n coroutines = []\n for table in db_map:\n\n # SQL columns\n db_fields = \",\".join(\n [\n f\"{col} AS {db_map[table]['fields'][col]}\"\n for col in db_map[table][\"fields\"]\n ]\n )\n\n # Output names\n api_fields = [db_map[table][\"fields\"][col] for col in db_map[table][\"fields\"]]\n\n if db_map[table][\"query_type\"] == \"pip\":\n limit = db_map[table][\"options\"][\"LIMIT\"]\n query = f\"SELECT {db_fields} from {table} WHERE (ST_Covers(geom, GeomFromEWKT('SRID=4326;POINT({lng} {lat})'))) LIMIT {limit};\"\n\n else:\n distance = db_map[table][\"options\"][\"DISTANCE\"]\n geo2geo = f\"geom::geography, GeomFromEWKT('SRID=4326;POINT({lng} {lat})')::geography\"\n query = (\n f\"SELECT {db_fields}, ST_Distance({geo2geo})\"\n f\"from {table} WHERE (ST_DWithin({geo2geo}, {distance}))\"\n f\"ORDER BY ST_Distance({geo2geo}) LIMIT 1;\"\n )\n\n coroutines.append(db.fetch_item(query))\n\n db_res = await asyncio.gather(*coroutines)\n \n .... code for processing results\n```\n\nI have examined several issues on the asyncpg github concerning this error and am still not finding an appropriate solution. Note also, this call is being performed in FastAPI.\n\nWhy this error may be occurring and how to resolve it?\n\n========================================\n\nCode:\n```text\nasyncpg.exceptions._base.InterfaceError: cannot perform operation: another operation is in progress\n```\n\n```text\nTraceback (most recent call last):\n\n File \"<string>\", line 1, in <module>\n File \"/Users/ddd/.pyenv/versions/3.8.6/lib/python3.8/multiprocessing/spawn.py\", line 116, in spawn_main\n exitcode = _main(fd, parent_sentinel)\n │ │ └ 4\n │ └ 7\n └ <function _main at 0x109c8aca0>\n File \"/Users/ddd/.pyenv/versions/3.8.6/lib/python3.8/multiprocessing/spawn.py\", line 129, in _main\n return self._bootstrap(parent_sentinel)\n │ │ └ 4\n │ └ <function BaseProcess._bootstrap at 0x109b1f8b0>\n └ <SpawnProcess name='SpawnProcess-4' parent=36604 started>\n File \"/Users/ddd/.pyenv/versions/3.8.6/lib/python3.8/multiprocessing/process.py\", line 315, in _bootstrap\n self.run()\n │ └ <function BaseProcess.run at 0x109b18ee0>\n └ <SpawnProcess name='SpawnProcess-4' parent=36604 started>\n File \"/Users/ddd/.pyenv/versions/3.8.6/lib/python3.8/multiprocessing/process.py\", line 108, in run\n self._target(*self._args, **self._kwargs)\n │ │ │ │ │ └ {'config': <uvicorn.config.Config object at 0x109cd55b0>, 'target': <bound method Server.run of <uvicorn.server.Server object...\n │ │ │ │ └ <SpawnProcess name='SpawnProcess-4' parent=36604 started>\n │ │ │ └ ()\n │ │ └ <SpawnProcess name='SpawnProcess-4' parent=36604 started>\n │ └ <function subprocess_started at 0x10a4aca60>\n └ <SpawnProcess name='SpawnProcess-4' parent=36604 started>\n File \"/Users/ddd/Desktop/repos/xxx/.venv/lib/python3.8/site-packages/uvicorn/subprocess.py\", line 61, in subprocess_started\n target(sockets=sockets)\n │ └ [<socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('0.0.0.0', 80)>]\n └ <bound method Server.run of <uvicorn.server.Server object at 0x109cd56a0>>\n File \"/Users/ddd/Desktop/repos/xxx/.venv/lib/python3.8/site-packages/uvicorn/server.py\", line 48, in run\n loop.run_until_complete(self.serve(sockets=sockets))\n │ │ │ │ └ [<socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('0.0.0.0', 80)>]\n │ │ │ └ <function Server.serve at 0x10a4abca0>\n │ │ └ <uvicorn.server.Server object at 0x109cd56a0>\n │ └ <function BaseEventLoop.run_until_complete at 0x10a205820>\n └ <_UnixSelectorEventLoop running=True closed=False debug=False>\n File \"/Users/ddd/.pyenv/versions/3.8.6/lib/python3.8/asyncio/base_events.py\", line 603, in run_until_complete\n self.run_forever()\n │ └ <function BaseEventLoop.run_forever at 0x10a205790>\n └ <_UnixSelectorEventLoop running=True closed=False debug=False>\n File \"/Users/ddd/.pyenv/versions/3.8.6/lib/python3.8/asyncio/base_events.py\", line 570, in run_forever\n self._run_once()\n │ └ <function BaseEventLoop._run_once at 0x10a209310>\n └ <_UnixSelectorEventLoop running=True closed=False debug=False>\n File \"/Users/ddd/.pyenv/versions/3.8.6/lib/python3.8/asyncio/base_events.py\", line 1859, in _run_once\n handle._run()\n │ └ <function Handle._run at 0x10a13ed30>\n └ <Handle <TaskWakeupMethWrapper object at 0x10bb75a60>(<_GatheringFu...in progress')>)>\n File \"/Users/ddd/.pyenv/versions/3.8.6/lib/python3.8/asyncio/events.py\", line 81, in _run\n self._context.run(self._callback, *self._args)\n │ │ │ │ │ └ <member '_args' of 'Handle' objects>\n │ │ │ │ └ <Handle <TaskWakeupMethWrapper object at 0x10bb75a60>(<_GatheringFu...in progress')>)>\n │ │ │ └ <member '_callback' of 'Handle' objects>\n │ │ └ <Handle <TaskWakeupMethWrapper object at 0x10bb75a60>(<_GatheringFu...in progress')>)>\n │ └ <member '_context' of 'Handle' objects>\n └ <Handle <TaskWakeupMethWrapper object at 0x10bb75a60>(<_GatheringFu...in progress')>)>\n\n> File \"./xxx/xxx/xxx.py\", line 144, in get_disclosure_data\n hh_json, db_json = await asyncio.gather(*coroutines)\n │ │ └ [<coroutine object xxxx at 0x10bb2cb40>, <coroutine object db_call at 0x10bb2cc40>]\n │ └ <function gather at 0x10a1fad30>\n └ <module 'asyncio' from '/Users/ddd/.pyenv/versions/3.8.6/lib/python3.8/asyncio/__init__.py'>\n\n File \"./xxx/xxx/xxx.py\", line 52, in db_call\n db_json = await asyncio.gather(*coroutines, loop=asyncio.get_event_loop())\n │ │ │ │ └ <built-in function get_event_loop>\n │ │ │ └ <module 'asyncio' from '/Users/ddd/.pyenv/versions/3.8.6/lib/python3.8/asyncio/__init__.py'>\n │ │ └ [<coroutine object DBConnectionManager.fetch_item at 0x10bb434c0>, <coroutine object DBConnectionManager.fetch_item at 0x10bb...\n │ └ <function gather at 0x10a1fad30>\n └ <module 'asyncio' from '/Users/ddd/.pyenv/versions/3.8.6/lib/python3.8/asyncio/__init__.py'>\n\n File \"./xxx/xxx/xx.py\", line 97, in fetch_item\n await self._connection_pool.release(self.con)\n │ │ │ │ └ <PoolConnectionProxy [released] 0x10bbc9cd0>\n │ │ │ └ <chd_api.data.db.DBConnectionManager object at 0x10b946a30>\n │ │ └ <function Pool.release at 0x10b956a60>\n │ └ <asyncpg.pool.Pool object at 0x10bb131e0>\n └ <chd_api.data.db.DBConnectionManager object at 0x10b946a30>\n\n File \"/Users/ddd/Desktop/repos/xxx/.venv/lib/python3.8/site-packages/asyncpg/pool.py\", line 666, in release\n return await asyncio.shield(ch.release(timeout))\n │ │ │ │ └ None\n │ │ │ └ <function PoolConnectionHolder.release at 0x10b952e50>\n │ │ └ <asyncpg.pool.PoolConnectionHolder object at 0x10bb2a5c0>\n │ └ <function shield at 0x10a1faee0>\n └ <module 'asyncio' from '/Users/ddd/.pyenv/versions/3.8.6/lib/python3.8/asyncio/__init__.py'>\n File \"/Users/ddd/Desktop/repos/xxx/.venv/lib/python3.8/site-packages/asyncpg/pool.py\", line 218, in release\n raise ex\n File \"/Users/ddd/Desktop/repos/xxx/.venv/lib/python3.8/site-packages/asyncpg/pool.py\", line 208, in release\n await self._con.reset(timeout=budget)\n │ │ └ None\n │ └ <member '_con' of 'PoolConnectionHolder' objects>\n └ <asyncpg.pool.PoolConnectionHolder object at 0x10bb2a5c0>\n File \"/Users/ddd/Desktop/repos/xxx/.venv/lib/python3.8/site-packages/asyncpg/connection.py\", line 1311, in reset\n await self.execute(reset_query, timeout=timeout)\n │ │ │ └ None\n │ │ └ 'SELECT pg_advisory_unlock_all();\\nCLOSE ALL;\\nUNLISTEN *;\\nRESET ALL;'\n │ └ <function Connection.execute at 0x10b93f3a0>\n └ <asyncpg.connection.Connection object at 0x10bc34120>\n File \"/Users/ddd/Desktop/repos/xxx/.venv/lib/python3.8/site-packages/asyncpg/connection.py\", line 297, in execute\n return await self._protocol.query(query, timeout)\n │ │ │ └ None\n │ │ └ 'SELECT pg_advisory_unlock_all();\\nCLOSE ALL;\\nUNLISTEN *;\\nRESET ALL;'\n │ └ <member '_protocol' of 'Connection' objects>\n └ <asyncpg.connection.Connection object at 0x10bc34120>\n File \"asyncpg/protocol/protocol.pyx\", line 321, in query\n self._check_state()\n File \"asyncpg/protocol/protocol.pyx\", line 684, in asyncpg.protocol.protocol.BaseProtocol._check_state\n raise apg_exc.InterfaceError(\n │ └ <class 'asyncpg.exceptions._base.InterfaceError'>\n └ <module 'asyncpg.exceptions' from '/Users/ddd/Desktop/repos/chd-api/.venv/lib/python3.8/site-packages/asyncpg/exception...\n\nasyncpg.exceptions._base.InterfaceError: cannot perform operation: another operation is in progress\n```\n\n```text\nclass DBConnectionManager(object):\n \"\"\" Class for setting up and tearing down db connection \"\"\"\n\n def __init__(self):\n self.host = SETTINGS.db_host\n self.database = SETTINGS.db_name\n self.user = SETTINGS.db_user\n self.password = SETTINGS.db_password\n self.port = \"5432\"\n\n self._connection_pool = None\n self.con = None\n\n async def connect(self):\n if not self._connection_pool:\n try:\n self._connection_pool = await asyncpg.create_pool(\n host=self.host,\n database=self.database,\n user=self.user,\n password=self.password,\n port=self.port,\n min_size=50,\n max_size=100,\n )\n logger.info(\"Database pool connection opened\")\n\n except Exception as e:\n logger.exception(e)\n\n async def fetch_item(self, query: str, *args):\n if not self._connection_pool:\n await self.connect()\n else:\n self.con = await self._connection_pool.acquire()\n try:\n result = await self.con.fetch(query, *args)\n return result\n except Exception as e:\n logger.exception(e)\n finally:\n await self._connection_pool.release(self.con)\n\n async def close(self):\n if not self._connection_pool:\n try:\n await self._connection_pool.close()\n logger.info(\"Database pool connection closed\")\n except Exception as e:\n logger.exception(e)\n```\n\n```text\nasync def db_call(db, lat, lng):\n \"\"\"\n Performs the necessary db calls given a lat, lng\n\n Required Input:\n lat::float a latitude in decimal degrees. Must be specified with `lng` (i.e. 39.2994)\n lng::float a longitude in decimal degrees. Must be specified with `lat` (i.e. -122.33)\n\n Returns:\n dict\n \"\"\"\n coroutines = []\n for table in db_map:\n\n # SQL columns\n db_fields = \",\".join(\n [\n f\"{col} AS {db_map[table]['fields'][col]}\"\n for col in db_map[table][\"fields\"]\n ]\n )\n\n # Output names\n api_fields = [db_map[table][\"fields\"][col] for col in db_map[table][\"fields\"]]\n\n if db_map[table][\"query_type\"] == \"pip\":\n limit = db_map[table][\"options\"][\"LIMIT\"]\n query = f\"SELECT {db_fields} from {table} WHERE (ST_Covers(geom, GeomFromEWKT('SRID=4326;POINT({lng} {lat})'))) LIMIT {limit};\"\n\n else:\n distance = db_map[table][\"options\"][\"DISTANCE\"]\n geo2geo = f\"geom::geography, GeomFromEWKT('SRID=4326;POINT({lng} {lat})')::geography\"\n query = (\n f\"SELECT {db_fields}, ST_Distance({geo2geo})\"\n f\"from {table} WHERE (ST_DWithin({geo2geo}, {distance}))\"\n f\"ORDER BY ST_Distance({geo2geo}) LIMIT 1;\"\n )\n\n coroutines.append(db.fetch_item(query))\n\n db_res = await asyncio.gather(*coroutines)\n \n .... code for processing results\n```\n\n```text\nself.con\n```\n\n```text\nfetch_item\n```\n\n```text\nself.con\n```\n\n```text\ncon\n```\n\n========================================\n\nComments:\n- How did you obtain that traceback? The level of detail is quite impressive.\n- The assignment to `self.con` in `fetch_item` looks fishy. You want multiple coroutines to the connection pool, but you don't want them all to the same *connection*. Replace usage of `self.con` with a local variable `con` and see if that helps.\n- that resolved it. wow. Give me a proper answer and I'm happy to mark it accepted! Also, the detail is from loguru!\n- > You want multiple coroutines to the connection pool, but you don't want them all to the same connection. What if I DO want them to the same connection, because I want them to be in the same transaction block?\n- See also this comment in the most relevant github issue (How to maintain global pool of db connection and use it in each and every request?) github.com/tiangolo/fastapi/issues/1800#issuecomment-9260819‌​49","metadata":{"transformedAt":"2026-08-18T18:32:29.090Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":8,"totalLines":475,"estimatedTokens":4759}}45{"id":"stack-64716495","source":"stackoverflow","questionId":64716495,"title":"How to delete the file after a `return FileResponse(file_path)`","tags":["python","python-asyncio","fastapi","starlette"],"text":"Title: How to delete the file after a `return FileResponse(file_path)`\nTags: python, python-asyncio, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nI'm using FastAPI to receive an image, process it and then return the image as a FileResponse.\n\nBut the returned file is a temporary one that need to be deleted after the endpoint return it.\n\n```\n@app.post(\"/send\")\nasync def send(imagem_base64: str = Form(...)):\n\n # Convert to a Pillow image\n image = base64_to_image(imagem_base64)\n\n temp_file = tempfile.mkstemp(suffix = '.jpeg')\n image.save(temp_file, dpi=(600, 600), format='JPEG', subsampling=0, quality=85)\n\n return FileResponse(temp_file)\n\n # I need to remove my file after return it\n os.remove(temp_file)\n```\n\nHow can I delete the file after return it ?\n\n========================================\n\nTop Answer:\nYou can pass the cleanup task as a parameter of `FileResponse`:\n\n```\nfrom starlette.background import BackgroundTask\n\n# ...\n\ndef cleanup():\n os.remove(temp_file)\n\nreturn FileResponse(\n temp_file,\n background=BackgroundTask(cleanup),\n)\n```\n\n### UPDATE 12-08-2022\n\nIf someone is generating the filename dynamically, then one may pass the parameters to the background task, e.g., as follows\n\n```\nreturn FileResponse(\n temp_file,\n background=BackgroundTask(cleanup, file_path),\n)\n```\n\nThe `cleanup` function then needs to be adapted to accept a parameter, which will be the filename, and call the `os.remove` function with the filename as parameter instead of the global variable\n\n========================================\n\nCode:\n```py\n@app.post(\"/send\")\nasync def send(imagem_base64: str = Form(...)):\n\n # Convert to a Pillow image\n image = base64_to_image(imagem_base64)\n\n temp_file = tempfile.mkstemp(suffix = '.jpeg')\n image.save(temp_file, dpi=(600, 600), format='JPEG', subsampling=0, quality=85)\n\n return FileResponse(temp_file)\n\n # I need to remove my file after return it\n os.remove(temp_file)\n```\n\n```text\nimport os\nimport tempfile\n\nfrom fastapi import FastAPI\nfrom fastapi.responses import FileResponse\n\nfrom starlette.background import BackgroundTasks\n\napp = FastAPI()\n\n\ndef remove_file(path: str) -> None:\n os.unlink(path)\n\n\n@app.post(\"/send\")\nasync def send(background_tasks: BackgroundTasks):\n fd, path = tempfile.mkstemp(suffix='.txt')\n with os.fdopen(fd, 'w') as f:\n f.write('TEST\\n')\n background_tasks.add_task(remove_file, path)\n return FileResponse(path)\n```\n\n```text\nimport os\nimport tempfile\n\nfrom fastapi import FastAPI, Depends\nfrom fastapi.responses import FileResponse\n\n\napp = FastAPI()\n\n\ndef create_temp_file():\n fd, path = tempfile.mkstemp(suffix='.txt')\n with os.fdopen(fd, 'w') as f:\n f.write('TEST\\n')\n try:\n yield path\n finally:\n os.unlink(path)\n\n\n@app.post(\"/send\")\nasync def send(file_path=Depends(create_temp_file)):\n return FileResponse(file_path)\n```\n\n```text\nfinally\n```\n\n```py\nfrom starlette.background import BackgroundTask\n\n# ...\n\ndef cleanup():\n os.remove(temp_file)\n\nreturn FileResponse(\n temp_file,\n background=BackgroundTask(cleanup),\n)\n```\n\n```text\nreturn FileResponse(\n temp_file,\n background=BackgroundTask(cleanup, file_path),\n)\n```\n\n```text\nFileResponse\n```\n\n```text\ncleanup\n```\n\n```text\nos.remove\n```\n\n```py\n# ... other important imports\nfrom starlette.background import BackgroundTasks\n\n@app.post(\"/send\")\nasync def send(imagem_base64: str = Form(...), bg_tasks: BackgroundTasks):\n\n # Convert to a Pillow image\n image = base64_to_image(imagem_base64)\n\n temp_file = tempfile.mkstemp(suffix = '.jpeg')\n image.save(temp_file, dpi=(600, 600), format='JPEG', subsampling=0, quality=85)\n\n\n bg_tasks.add_task(os.remove, temp_file)\n \n return FileResponse(\n temp_file,\n background=bg_tasks\n )\n```\n\n```text\nFileResponse\n```\n\n```py\nimport os\nfrom typing import Annotated\n\nfrom fastapi import Depends, FastAPI\nfrom fastapi.responses import FileResponse\n\napp = FastAPI()\n\n\nasync def temp_path():\n \"\"\"Create (and finally delete) a temporary file in a safe and non-blocking fashion.\"\"\"\n loop = asyncio.get_running_loop()\n _, path = await loop.run_in_executor(None, tempfile.mkstemp)\n try:\n yield path\n finally:\n await loop.run_in_executor(None, os.unlink, path)\n\n\n@app.get(\"/test\")\nasync def test(\n ...,\n temp_path_1: Annotated[str, Depends(temp_path, use_cache=False)],\n temp_path_2: Annotated[str, Depends(temp_path, use_cache=False)],\n):\n assert temp_path_1 != temp_path_2, \"2 unique files due to use_cache=False\"\n\n if \"x\" in temp_path_1:\n raise RuntimeError(\"Unexpected internal server error still deletes the files\")\n\n return FileResponse(\n temp_path_1,\n media_type=\"video/mp4\",\n filename=\"video_out.mp4\",\n )\n```\n\n```text\nimport tempfile\nfrom fastapi import FileResponse\n\n\nclass TempFileResponse(FileResponse):\n def __init__(self, prefix, **params) -> None:\n self.temp_file = tempfile.NamedTemporaryFile(prefix=prefix)\n super().__init__(path=self.temp_file.name, **params)\n\n def __del__(self):\n # This will delete the file\n self.temp_file.close()\n\n\n@router.get(\"/produce-data\", response_class=FileResponse)\nasync def produce() -> FileResponse:\n file_name = \"some_file_data.txt\"\n logger.info(f\"Downloading data as {file_name}\")\n response_file = TempFileResponse(prefix=\"some_file_\", filename=file_name)\n with open(response_file.temp_file.name, \"w\") as f:\n f.write(\"Hello, world!\")\n return response_file\n```\n\n========================================\n\nComments:\n- I tried the second approach, with the dependency, but the file is deleted too soon in the flow and the response fails with `RuntimeError: File at path ... does not exist.`.\n- Even simpler: you can use `background=BackgroundTask(os.remove, temp_file)`. `os.remove` is already a callable function you can pass to BackgroundTask, you don't need to wrap it into another one.\n- The problem with BackgroundTasks is that in case of any exception, they are not run.","metadata":{"transformedAt":"2026-08-18T18:32:29.090Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":13,"totalLines":261,"estimatedTokens":1508}}46{"id":"stack-63853813","source":"stackoverflow","questionId":63853813,"title":"How to create routes with FastAPI within a class","tags":["python","python-3.x","class","self","fastapi"],"text":"Title: How to create routes with FastAPI within a class\nTags: python, python-3.x, class, self, fastapi\nSource: Stack Overflow\n\nQuestion:\nSo I need to have some routes inside a class, but the route methods need to have the `self` attr (to access the class' attributes).\nHowever, FastAPI then assumes `self` is its own required argument and puts it in as a query param\n\nThis is what I've got:\n\n```\napp = FastAPI()\nclass Foo:\n def __init__(y: int):\n self.x = y\n\n @app.get(\"/somewhere\")\n def bar(self): return self.x\n```\n\nHowever, this returns `422` unless you go to `/somewhere?self=something`. The issue with this, is that `self` is then str, and thus useless.\n\nI need some way that I can still access `self` without having it as a required argument.\n\n========================================\n\nTop Answer:\nThis can be done by using an `APIRouter`'s `add_api_route` method:\n\n```\nfrom fastapi import FastAPI, APIRouter\n\nclass Hello:\n\n def __init__(self, name: str):\n self.name = name\n self.router = APIRouter()\n self.router.add_api_route(\"/hello\", self.hello, methods=[\"GET\"])\n\n def hello(self):\n return {\"Hello\": self.name}\n\napp = FastAPI()\nhello = Hello(\"World\")\napp.include_router(hello.router)\n```\n\nExample:\n\n```\n$ curl 127.0.0.1:5000/hello\n{\"Hello\":\"World\"}\n```\n\n`add_api_route`'s second argument (`endpoint`) has type `Callable[..., Any]`, so any callable should work (as long as FastAPI can find out how to parse its arguments HTTP request data). This callable is also known in the FastAPI docs as the **path operation function** (referred to as \"POF\" below).\n\n### Why decorating methods doesn't work\n\n*WARNING: Ignore the rest of this answer if you're not interested in a technical explanation of why the code in the OP's answer doesn't work*\n\nDecorating a method with `@app.get` and friends in the class body doesn't work because you'd be effectively passing `Hello.hello`, not `hello.hello` (a.k.a. `self.hello`) to `add_api_route`. Bound and unbound methods (a.k.a simply as \"functions\" since Python 3) have different signatures:\n\n```\nimport inspect\ninspect.signature(Hello.hello) # \ninspect.signature(hello.hello) # \n```\n\nFastAPI does a lot of magic to try to automatically parse the data in the HTTP request (body or query parameters) into the objects actually used by the POF.\n\nBy using an unbound method (=regular function) (`Hello.hello`) as the POF, FastAPI would either have to:\n\nMake assumptions about the nature of the class that contains the route and generate `self` (a.k.a call `Hello.__init__`) on the fly. This would likely add a lot of complexity to FastAPI and is a use case that FastAPI devs (understandably) don't seem interested in supporting. It seems the recommended way of dealing with application/resource state is deferring the whole problem to an external dependency with `Depends`.\n\nSomehow be able to generate a `self` object from the HTTP request data (usually JSON) sent by the caller. This is not technically feasible for anything other than strings or other builtins and therefore not really usable.\n\nWhat happens in the OP's code is #2. FastAPI tries to parse the first argument of `Hello.hello` (=`self`, of type `Hello`) from the HTTP request query parameters, obviously fails and raises a `RequestValidationError` which is shown to the caller as an HTTP 422 response.\n\n### Parsing `self` from query parameters\n\nJust to prove #2 above, here's a (useless) example of when FastAPI can actually \"parse\" `self` from the HTTP request:\n\n(*Disclaimer: Do not use the code below for any real application*)\n\n```\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\nclass Hello(str):\n @app.get(\"/hello\")\n def hello(self):\n return {\"Hello\": self}\n```\n\nExample:\n\n```\n$ curl '127.0.0.1:5000/hello?self=World'\n{\"Hello\":\"World\"}\n```\n\n========================================\n\nCode:\n```py\napp = FastAPI()\nclass Foo:\n def __init__(y: int):\n self.x = y\n\n @app.get(\"/somewhere\")\n def bar(self): return self.x\n```\n\n```text\nself\n```\n\n```text\nself\n```\n\n```text\n422\n```\n\n```text\n/somewhere?self=something\n```\n\n```text\nself\n```\n\n```text\nself\n```\n\n```text\nfrom fastapi import Depends, FastAPI\nfrom fastapi_utils.cbv import cbv\nfrom fastapi_utils.inferring_router import InferringRouter\n\n\ndef get_x():\n return 10\n\n\napp = FastAPI()\nrouter = InferringRouter() # Step 1: Create a router\n\n\n@cbv(router) # Step 2: Create and decorate a class to hold the endpoints\nclass Foo:\n # Step 3: Add dependencies as class attributes\n x: int = Depends(get_x)\n\n @router.get(\"/somewhere\")\n def bar(self) -> int:\n # Step 4: Use `self.<dependency_name>` to access shared dependencies\n return self.x\n\n\napp.include_router(router)\n```\n\n```py\nclass Foo(FastAPI):\n def __init__(y: int):\n self.x = y\n\n self.include_router(\n health.router,\n prefix=\"/api/v1/health\",\n )\n```\n\n```text\nAPIRouter\n```\n\n```text\nfrom fastapi import FastAPI\nfrom fastapi.responses import HTMLResponse\n\nclass CustomAPI(FastAPI):\n def __init__(self, title: str = \"CustomAPI\") -> None:\n super().__init__(title=title)\n\n @self.get('/')\n async def home():\n \"\"\"\n Home page\n \"\"\"\n return HTMLResponse(\"<h1>CustomAPI</h1><br/><a href='/docs'>Try api now!</a>\", status_code=status.HTTP_200_OK)\n```\n\n```text\ndef __init__\n```\n\n```text\n$ pip install cbfa\n```\n\n```text\nfrom typing import Optional\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\nfrom cbfa import ClassBased\n\n\napp = FastAPI()\nwrapper = ClassBased(app)\n\nclass Item(BaseModel):\n name: str\n price: float\n is_offer: Optional[bool] = None\n\n@wrapper('/item')\nclass Item:\n def get(item_id: int, q: Optional[str] = None):\n return {\"item_id\": item_id, \"q\": q}\n\n def post(item_id: int, item: Item):\n return {\"item_name\": item.name, \"item_id\": item_id}\n```\n\n```py\nfrom classy_fastapi import Routable, get, delete\n\nclass UserRoutes(Routable):\n \"\"\"Inherits from Routable.\"\"\"\n\n # Note injection here by simply passing values\n # to the constructor. Other injection frameworks also \n # supported as there's nothing special about this __init__ method.\n def __init__(self, dao: Dao) -> None:\n \"\"\"Constructor. The Dao is injected here.\"\"\"\n super().__init__()\n self.__dao = Dao\n\n @get('/user/{name}')\n def get_user_by_name(name: str) -> User:\n # Use our injected DAO instance.\n return self.__dao.get_user_by_name(name)\n\n @delete('/user/{name}')\n def delete_user(name: str) -> None:\n self.__dao.delete(name)\n\n\ndef main():\n args = parse_args()\n # Configure the DAO per command line arguments\n dao = Dao(args.url, args.user, args.password)\n # Simple intuitive injection\n user_routes = UserRoutes(dao)\n \n app = FastAPI()\n # router member inherited from Routable and configured per the annotations.\n app.include_router(user_routes.router)\n```\n\n```text\ncbv\n```\n\n```text\npip install classy-fastapi\n```\n\n```py\nfrom functools import wraps\n\n_api_routes_registry = []\n\n\nclass api_route(object):\n def __init__(self, path, **kwargs):\n self._path = path\n self._kwargs = kwargs\n\n def __call__(self, fn):\n cls, method = fn.__repr__().split(\" \")[1].split(\".\")\n _api_routes_registry.append(\n {\n \"fn\": fn,\n \"path\": self._path,\n \"kwargs\": self._kwargs,\n \"cls\": cls,\n \"method\": method,\n }\n )\n\n @wraps(fn)\n def decorated(*args, **kwargs):\n return fn(*args, **kwargs)\n\n return decorated\n\n @classmethod\n def add_api_routes(cls, router):\n for reg in _api_routes_registry:\n if router.__class__.__name__ == reg[\"cls\"]:\n router.add_api_route(\n path=reg[\"path\"],\n endpoint=getattr(router, reg[\"method\"]),\n **reg[\"kwargs\"],\n )\n```\n\n```py\nclass ItemRouter(APIRouter):\n @api_route(\"/\", description=\"this reads an item\")\n def read_item(a: str = \"de\"):\n return [7262, 324323, a]\n\n @api_route(\"/\", methods=[\"POST\"], description=\"add an item\")\n def post_item(a: str = \"de\"):\n return a\n\n def __init__(self, *args, **kwargs):\n super().__init__(*args, **kwargs)\n add_api_routes(self)\n\n\napp.include_router(\n ItemRouter(\n prefix=\"/items\",\n )\n)\n```\n\n```text\nAPIRouter\n```\n\n```text\n__init__\n```\n\n```py\nfrom fastapi import FastAPI, APIRouter\n\n\nclass Hello:\n\n def __init__(self, name: str):\n self.name = name\n self.router = APIRouter()\n self.router.add_api_route(\"/hello\", self.hello, methods=[\"GET\"])\n\n def hello(self):\n return {\"Hello\": self.name}\n\n\napp = FastAPI()\nhello = Hello(\"World\")\napp.include_router(hello.router)\n```\n\n```bash\n$ curl 127.0.0.1:5000/hello\n{\"Hello\":\"World\"}\n```\n\n```py\nimport inspect\ninspect.signature(Hello.hello) # <Signature (self)>\ninspect.signature(hello.hello) # <Signature ()>\n```\n\n```text\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\nclass Hello(str):\n @app.get(\"/hello\")\n def hello(self):\n return {\"Hello\": self}\n```\n\n```bash\n$ curl '127.0.0.1:5000/hello?self=World'\n{\"Hello\":\"World\"}\n```\n\n```text\nAPIRouter\n```\n\n```text\nadd_api_route\n```\n\n```text\nadd_api_route\n```\n\n```text\nendpoint\n```\n\n```text\nCallable[..., Any]\n```\n\n```text\n@app.get\n```\n\n```text\nHello.hello\n```\n\n```text\nhello.hello\n```\n\n```text\nself.hello\n```\n\n```text\nadd_api_route\n```\n\n```text\nHello.hello\n```\n\n```text\nself\n```\n\n```text\nHello.__init__\n```\n\n```text\nDepends\n```\n\n```text\nself\n```\n\n```text\nHello.hello\n```\n\n```text\nself\n```\n\n```text\nHello\n```\n\n```text\nRequestValidationError\n```\n\n```text\nself\n```\n\n```text\nself\n```\n\n```text\nclass UseCase:\n @abstractmethod\n def run(self):\n pass\n\n\nclass ProductionUseCase(UseCase):\n def run(self):\n return \"Production Code\"\n\n\nclass AppController:\n\n def __init__(self, app: FastAPI, use_case: UseCase):\n @app.get(\"/items/{item_id}\")\n def read_item(item_id: int, q: Optional[str] = None):\n return {\n \"item_id\": item_id, \"q\": q, \"use_case\": use_case.run()\n }\n\n\ndef startup(use_case: UseCase = ProductionUseCase()):\n app = FastAPI()\n AppController(app, use_case)\n return app\n\n\nif __name__ == \"__main__\":\n uvicorn.run(startup(), host=\"0.0.0.0\", port=8080)\n```\n\n```py\nfrom fastapi \nimport FastAPI, APIRouter\n\nclass Hello:\n\n def __init__(self, name: str):\n self.name = name\n self.router = APIRouter()\n self.router.get(\"/hello\")(self.hello) # use decorator\n\n def hello(self):\n return {\"Hello\": self.name}\n\napp = FastAPI()\nhello = Hello(\"World\")\napp.include_router(hello.router)\n```\n\n========================================\n\nComments:\n- If you have `session` as a shared dependency, concurrent requests would the same instance?\n- The class instance is created and dependencies are called for each request independently\n- When I try to inject an instance of my own class like that, it throws an error saying that it was supposed to be a Pydantic-aware type o_O Is that expected?\n- This \"breaks\" the navigation in your IDE, ie. you cannot hop into `home()` as it's declared and lost within the constructor's scope.\n- @OliverDain In your code above, app=FastApi() is in the main() function. How is main() called and how are the args passed to main()?\n- @HenryThornton up to you. You could do the normal `if __name__ == '__main__'` thing and then call it. In my example above, my `main` parses the argument by calling `parse_args` (first line of main) but you could parse elsewhere and pass the arguments in.\n- This is a very nice answer. However, this actually fails with routers with parameters like `\"/{item_id}\"` and I don't know exactly why...\n- Just to note - it is probably better to use `fn.__qualname__` rather than `fn.__repr__().split(\" \")[1]`.\n- What is the purpose the ProductionUseCase class?","metadata":{"transformedAt":"2026-08-18T18:32:29.090Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":49,"totalLines":538,"estimatedTokens":2991}}47{"id":"stack-61577643","source":"stackoverflow","questionId":61577643,"title":"Python - How to use FastAPI and uvicorn.run without blocking the thread?","tags":["python","multiprocessing","fastapi","uvicorn"],"text":"Title: Python - How to use FastAPI and uvicorn.run without blocking the thread?\nTags: python, multiprocessing, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI'm looking for a possibility to use uvicorn.run() with a FastAPI app but without uvicorn.run() is blocking the thread. I already tried to use processes, subprocessesand threads but nothing worked.\nMy problem is that I want to start the Server from another process that should go on with other tasks after starting the server. Additinally I have problems closing the server like this from another process.\n\nHas anyone an idea how to use uvicorn.run() non blocking and how to stop it from another process?\n\n========================================\n\nTop Answer:\nApproach given by @HadiAlqattan will not work because `uvicorn.run` expects to be run in the main thread. Errors such as `signal only works in main thread` will be raised.\n\nCorrect approach is:\n\n```\nimport contextlib\nimport time\nimport threading\nimport uvicorn\n\nclass Server(uvicorn.Server):\n def install_signal_handlers(self):\n pass\n\n @contextlib.contextmanager\n def run_in_thread(self):\n thread = threading.Thread(target=self.run)\n thread.start()\n try:\n while not self.started:\n time.sleep(1e-3)\n yield\n finally:\n self.should_exit = True\n thread.join()\n\nconfig = uvicorn.Config(\"example:app\", host=\"127.0.0.1\", port=5000, log_level=\"info\")\nserver = Server(config=config)\n\nwith server.run_in_thread():\n # Server is started.\n ...\n # Server will be stopped once code put here is completed\n ...\n\n# Server stopped.\n```\n\nVery handy to run a live test server locally using a pytest fixture:\n\n```\n# conftest.py\nimport pytest\n\n@pytest.fixture(scope=\"session\")\ndef server():\n server = ...\n with server.run_in_thread():\n yield\n```\n\nCredits: uvicorn#742 by florimondmanca\n\n========================================\n\nCode:\n```py\nfrom multiprocessing import Process\nimport uvicorn\n\n# global process variable\nproc = None\n\n\ndef run(): \n \"\"\"\n This function to run configured uvicorn server.\n \"\"\"\n uvicorn.run(app=app, host=host, port=port)\n\n\ndef start():\n \"\"\"\n This function to start a new process (start the server).\n \"\"\"\n global proc\n # create process instance and set the target to run function.\n # use daemon mode to stop the process whenever the program stopped.\n proc = Process(target=run, args=(), daemon=True)\n proc.start()\n\n\ndef stop(): \n \"\"\"\n This function to join (stop) the process (stop the server).\n \"\"\"\n global proc\n # check if the process is not None\n if proc: \n # join (stop) the process with a timeout setten to 0.25 seconds.\n # using timeout (the optional arg) is too important in order to\n # enforce the server to stop.\n proc.join(0.25)\n```\n\n```py\nfrom time import sleep\n\nif __name__ == \"__main__\":\n # to start the server call start function.\n start()\n # run some codes ....\n # to stop the server call stop function.\n stop()\n```\n\n```py\nimport contextlib\nimport time\nimport threading\nimport uvicorn\n\nclass Server(uvicorn.Server):\n def install_signal_handlers(self):\n pass\n\n @contextlib.contextmanager\n def run_in_thread(self):\n thread = threading.Thread(target=self.run)\n thread.start()\n try:\n while not self.started:\n time.sleep(1e-3)\n yield\n finally:\n self.should_exit = True\n thread.join()\n\nconfig = uvicorn.Config(\"example:app\", host=\"127.0.0.1\", port=5000, log_level=\"info\")\nserver = Server(config=config)\n\nwith server.run_in_thread():\n # Server is started.\n ...\n # Server will be stopped once code put here is completed\n ...\n\n# Server stopped.\n```\n\n```py\n# conftest.py\nimport pytest\n\n@pytest.fixture(scope=\"session\")\ndef server():\n server = ...\n with server.run_in_thread():\n yield\n```\n\n```text\nuvicorn.run\n```\n\n```text\nsignal only works in main thread\n```\n\n```text\nimport pytest\nfrom fastapi.testclient import TestClient\nfrom app.main import app\nimport multiprocessing\nfrom uvicorn import Config, Server\n\n\nclass UvicornServer(multiprocessing.Process):\n\n def __init__(self, config: Config):\n super().__init__()\n self.server = Server(config=config)\n self.config = config\n\n def stop(self):\n self.terminate()\n\n def run(self, *args, **kwargs):\n self.server.run()\n\n\n\n\n@pytest.fixture(scope=\"session\")\ndef server():\n config = Config(\"app.main:app\", host=\"127.0.0.1\", port=5000, log_level=\"debug\")\n instance = UvicornServer(config=config)\n instance.start()\n yield instance\n instance.stop()\n\n@pytest.fixture(scope=\"module\")\ndef mock_app(server):\n client = TestClient(app)\n yield client\n```\n\n```text\ndef test_root(mock_app):\n response = mock_app.get(\"\")\n assert response.status_code == 200\n```\n\n```text\nconftest.py\n```\n\n```text\ntest_app.py\n```\n\n```py\nimport uvicorn\nfrom fastapi import FastAPI, APIRouter\nfrom multiprocessing import cpu_count\nimport os\n\nrouter = APIRouter()\napp = FastAPI()\n\n\n@router.post(\"/test\")\nasync def detect_img():\n print(\"pid:{}\".format(os.getpid()))\n return os.getpid\n\nif __name__ == '__main__':\n app.include_router(router)\n print(\"cpu个数:{}\".format(cpu_count()))\n workers = 2*cpu_count() + 1\n print(\"workers:{}\".format(workers))\n reload = False\n #reload = True\n uvicorn.run(\"__main__:app\", host=\"0.0.0.0\", port=8082, reload=reload, workers=workers, timeout_keep_alive=5,\n limit_concurrency=100)\n```\n\n```text\nimport asyncio\n\nimport uvicorn\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n\n@app.get(\"/\")\nasync def root():\n return {\"message\": \"Hello, World!\"}\n\n\nasync def main():\n config = uvicorn.Config(app, port=5000, log_level=\"info\")\n server = uvicorn.Server(config)\n await server.serve()\n\n\nif __name__ == \"__main__\":\n asyncio.run(main())\n```\n\n========================================\n\nComments:\n- Solutions could be found in this answer and this answer\n- Thanks for the answer but did you try your code above? I'm trying to run the code on Win10 with python 3.7 and I get errors either starting uvicorn in a Thread or starting it in a new process. The error using a thread looks like this: Traceback (most recent call last): File \"C:\\Python37\\lib\\site-packages\\uvicorn\\main.py\", line 565, in install_signal_handlers loop.add_signal_handler(sig, self.handle_exit, sig, None) File \"C:\\Python37\\lib\\asyncio\\events.py\", line 540, in add_signal_handler raise NotImplementedError NotImplementedError and signal only works in main thread\n- Using a new process the following error occurs: cant pickle _thread.RLock objects. Any suggestions how I can solve this problem? Due to this post github.com/tiangolo/fastapi/issues/650 it is better to run it in a process but it's not working for me.\n- Ok found a solution on my own. First it is important to use a new process to start uvicorn in it. Then you can kill or terminate the process if you want to stop uvicorn. But this does not seem to work on windows, at least for me it is just working on linux. To avoid the error of \"cant pickle _thread.RLock objects\" it is important not to use a method with self. So for example run_server(self) is not working with a new Process but run_server() is.\n- @Leuko Posted an answer with a proper fix to the \"main thread\" errors\n- I'm getting that Config is undefined.. Should it be `uvicorn.Config` ?\n- @StealthRabbi Should be fixed now, thanks\n- Caution: subclassed uvicorn.Server seems to ignore \"workers\" config value and handles requests only in a single process.\n- actually uvicorn.Server is a single proces by design. It is uvicorn.run that actually utilizes the workers config and starts multiple server.run via uvicorn.supervisors.Multiprocess\n- Hi @polka, this works but I have one question: How can I try/except a keyboard interrupt? I mean if I press ctrl + c the application exits which is fine (it recognizes SIGNALS). However, I want to add some logging to the exit process but I don't know where I can do this. There is no exception thrown. It just exits. Any recommendations?\n- Ok, I answered my question myself. You can just put logging messages below the server.run() line because ofc it is not async so the thread is blocked on that line. And if you ctrl + c the run gets cancelled and the following lines are executed.","metadata":{"transformedAt":"2026-08-18T18:32:29.090Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":12,"totalLines":288,"estimatedTokens":2080}}48{"id":"stack-61140398","source":"stackoverflow","questionId":61140398,"title":"FastAPI, return a File response with the output of a sql query","tags":["python","fastapi","starlette"],"text":"Title: FastAPI, return a File response with the output of a sql query\nTags: python, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nI'm using FastAPI and currently I return a csv which I read from SQL server with pandas. (pd.read_sql())\nHowever the csv is quite big for the browser and I want to return it with a File response:\nhttps://fastapi.tiangolo.com/advanced/custom-response/ (end of the page).\nI cannot seem to do this without first writing it to a csv file which seems slow and will clutter the filesystem with csv's on every request. \n\nSo my questions way, is there way to return a FileResponse from a sql database or pandas dataframe.\n\nAnd if not, is there a way to delete the generated csv files, after it has all been read by the client?\n\nThanks for your help!\n\nKind regards,\n\nStephan\n\n========================================\n\nTop Answer:\nAdding to the code that was previously mentioned, I found it useful to place another response header, in order for the client to be able to see the \"Content-Disposition\". This is due to the fact, that only CORS-safelisted response headers can be seen by default by the client. \"Content-Disposition\" is not part of this list, so it must be added explicitly https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers.\n\nI don't know if there is another way to specify this, for the client or server in a more general way so that it applies to all the necessary endpoints, but this is the way I applied it.\n\n```\n@router.post(\"/files\", response_class = StreamingResponse)\nasync def anonymization(file: bytes = File(...), config: str = Form(...)):\n # file as str\n inputFileAsStr = StringIO(str(file,'utf-8'))\n # dataframe\n df = pd.read_csv(inputFileAsStr)\n # send to function to handle anonymization\n results_df = anonymize(df, config)\n # output file\n outFileAsStr = StringIO()\n results_df.to_csv(outFileAsStr, index = False)\n response = StreamingResponse(\n iter([outFileAsStr.getvalue()]),\n media_type='text/csv',\n headers={\n 'Content-Disposition': 'attachment;filename=dataset.csv',\n 'Access-Control-Expose-Headers': 'Content-Disposition'\n }\n )\n # return\n return response\n```\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI\nfrom fastapi.responses import StreamingResponse\nimport io\nimport pandas as pd\n\napp = FastAPI()\n\n@app.get(\"/get_csv\")\nasync def get_csv():\n df = pd.DataFrame(dict(col1 = 1, col2 = 2), index=[0])\n stream = io.StringIO()\n df.to_csv(stream, index = False)\n response = StreamingResponse(iter([stream.getvalue()]),\n media_type=\"text/csv\"\n )\n response.headers[\"Content-Disposition\"] = \"attachment; filename=export.csv\"\n return response\n```\n\n```text\nfrom fastapi.responses import StreamingResponse\nfrom io import BytesIO\n\n@router.get('/attachment/{id}')\nasync def get_attachment(id: int):\n mdb = messages(s.MARIADB)\n\n attachment = mdb.getAttachment(id)\n memfile = BytesIO(attachment['content'])\n response = StreamingResponse(memfile, media_type=attachment['contentType'])\n response.headers[\"Content-Disposition\"] = f\"inline; filename={attachment['name']}\"\n\n return response\n```\n\n```text\n@router.post(\"/files\", response_class = StreamingResponse)\nasync def anonymization(file: bytes = File(...), config: str = Form(...)):\n # file as str\n inputFileAsStr = StringIO(str(file,'utf-8'))\n # dataframe\n df = pd.read_csv(inputFileAsStr)\n # send to function to handle anonymization\n results_df = anonymize(df, config)\n # output file\n outFileAsStr = StringIO()\n results_df.to_csv(outFileAsStr, index = False)\n response = StreamingResponse(\n iter([outFileAsStr.getvalue()]),\n media_type='text/csv',\n headers={\n 'Content-Disposition': 'attachment;filename=dataset.csv',\n 'Access-Control-Expose-Headers': 'Content-Disposition'\n }\n )\n # return\n return response\n```\n\n========================================\n\nComments:\n- Does this answer your question? How to stream DataFrame using FastAPI without saving the data to csv file?\n- Related answers should be found here, as well as here and here.\n- `response = StreamingResponse(io.StringIO(df.to_csv(index=False)), media_type=\"text/csv\")` should also work\n- This saved my day.\n- df = pandas.DataFrame(dict(col1 = 1, col2 = 2)) add index in values instead of scaler values `df = pandas.DataFrame(dict(col1 = [1], col2 = [2]))`\n- does StreamingResponse literally means streaming? meanding a client would have to read it in chunks of some kind? what if there exists a client that is expecting it all at once?\n- @mike01010 no it's not for things the client has to read in chunks, its for things you have to read in chunks","metadata":{"transformedAt":"2026-08-18T18:32:29.090Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":3,"totalLines":124,"estimatedTokens":1194}}49{"id":"stack-66622020","source":"stackoverflow","questionId":66622020,"title":"FastAPI {\"detail\":\"Method Not Allowed\"}","tags":["python","scikit-learn","fastapi"],"text":"Title: FastAPI {\"detail\":\"Method Not Allowed\"}\nTags: python, scikit-learn, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am using FAST API for my ML Model.\n\nI have a pipeline.\n\n```\nlr_tfidf = Pipeline([('vect', tfidf),\n ('clf', LogisticRegression(penalty='l2'))])\n```\n\nNow In Fast API, when I want to predict, and display result as API, my code is\n\n```\napp = FastAPI()\n\n@app.post('/predict')\ndef predict_species(data: str):\n data = np.array([data])\n\n prob = lr_tfidf.predict_proba(data).max()\n pred = lr_tfidf.predict(data)\n return {'Probability': f'{prob}', \n 'Predictions':f'{pred}'}\n```\n\nI copied it from a tutorial. When I test it on GUI by FASTAPI, it works good as shown in Image, i.e it shows probability and predictions.\n\nhttps://i.sstatic.net/4VPtz.png\n\nWhen I go to request URL, as provided by the GUI, which is `http://127.0.0.1:8000/predict?data=hello` (test data is hello) It gives me error.\n\n```\n{\"detail\":\"Method Not Allowed\"}\n```\n\nOn my Terminal, the error message is\n\n```\nINFO: 127.0.0.1:42568 - \"GET /predict?data=hello HTTP/1.1\" 405 Method Not Allowed\n```\n\n========================================\n\nTop Answer:\n**Using curl**\n\nOpen a terminal or command prompt and run the following command:\n\n```\ncurl -X POST http://127.0.0.1:8000/predict?data=hello\n```\n\nThis command uses curl to make a POST request to the specified URL.\n\n**Using Python requests library**\n\nIf you prefer using a Python script, first ensure you have the requests library installed. If not, you can install it using pip:\n\n```\npip install requests\n```\n\nThen, you can use the following Python script to make the POST request:\n\n```\nimport requests\n\nurl = \"http://127.0.0.1:8000/predict\"\nparams = {\"data\": \"hello\"}\n\nresponse = requests.post(url, params=params)\n\nprint(response.text)\n```\n\nThis script sends a POST request to the URL with the specified query parameters.\n\nYou can also use Postman, or create an api using JavaScript to perform a POST request\n\n========================================\n\nCode:\n```py\nlr_tfidf = Pipeline([('vect', tfidf),\n ('clf', LogisticRegression(penalty='l2'))])\n```\n\n```py\napp = FastAPI()\n\n\n@app.post('/predict')\ndef predict_species(data: str):\n data = np.array([data])\n\n prob = lr_tfidf.predict_proba(data).max()\n pred = lr_tfidf.predict(data)\n return {'Probability': f'{prob}', \n 'Predictions':f'{pred}'}\n```\n\n```py\n{\"detail\":\"Method Not Allowed\"}\n```\n\n```py\nINFO: 127.0.0.1:42568 - \"GET /predict?data=hello HTTP/1.1\" 405 Method Not Allowed\n```\n\n```text\nhttp://127.0.0.1:8000/predict?data=hello\n```\n\n```text\nPOST\n```\n\n```text\n@app.post('/predict')\n```\n\n```text\nGET\n```\n\n```text\nGET\n```\n\n```text\n@app.get\n```\n\n```text\ncurl -X POST http://127.0.0.1:8000/predict?data=hello\n```\n\n```text\npip install requests\n```\n\n```text\nimport requests\n\nurl = \"http://127.0.0.1:8000/predict\"\nparams = {\"data\": \"hello\"}\n\nresponse = requests.post(url, params=params)\n\nprint(response.text)\n```\n\n```text\n@app.post(\"/api/chunking\", tags=[\"chunking\"])\n```\n\n========================================\n\nComments:\n- When you call the URL from your browser, the HTTP Method is `GET`. But your endpoint defines it must be `POST`.\n- So, I should change it to `GET`? I do not have much experience with APIs, and I was following a blog by someone.\n- It depends :) It would work, but it will most probably violate the rules how name endpoints and when to use which method. A good starting point: restfulapi.net/resource-naming But maybe you are designing a RPC (remote procedure call)? Than it can be different as well.\n- Thanks, It is working. You can write the answer, I will tick it\n- Future readers might find this answer. as well as this answer and this answer helpful.\n- I found out that Postman would not send POST request even when selected, if the body was empty. I had to use CLI at the end","metadata":{"transformedAt":"2026-08-18T18:32:29.090Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":14,"totalLines":169,"estimatedTokens":957}}50{"id":"stack-76322463","source":"stackoverflow","questionId":76322463,"title":"How to initialize a global object or variable and reuse it in every FastAPI endpoint?","tags":["python","global-variables","fastapi","background-task","starlette"],"text":"Title: How to initialize a global object or variable and reuse it in every FastAPI endpoint?\nTags: python, global-variables, fastapi, background-task, starlette\nSource: Stack Overflow\n\nQuestion:\nI am having a class to send notifications. When being initialized, it involves making a connection to a notification server, which is time-consuming. I use a background task in FastAPI to send notifications, as I don't want to delay the response due to the notification. Below is the sample code:\n\n**file1.py**\n\n```\nnoticlient = NotificationClient()\n\n@app.post(\"/{data}\")\ndef send_msg(somemsg: str, background_tasks: BackgroundTasks):\n result = add_some_tasks(data, background_tasks, noticlient)\n return result\n```\n\n**file2.py**\n\n```\ndef add_some_tasks(data, background_tasks: BackgroundTasks, noticlient):\n background_tasks.add_task(noticlient.send, param1, param2)\n result = some_operation\n return result\n```\n\nHere, the notification client is declared globally. I could have it initialized in **file2.py**, under `add_some_tasks`, but it would get initialized every time a request arrives, and that would require some time. Is there any way to use a middleware to re-use it every time a request arrives, so that it doesn't need to be initialized every time?\n\nOr, another approach might be to initialize notification in class definition:\n\n**file1.py**\n\n```\nclass childFastApi(FastAPI):\n noticlient = NotificationClient()\n\napp = childFastApi()\n\n@app.post(\"/{data}\")\ndef send_msg(somemsg: str, background_tasks: BackgroundTasks):\n result = add_some_tasks(data, background_tasks, app.noticlient)\n return result\n```\n\n========================================\n\nCode:\n```py\nnoticlient = NotificationClient()\n\n@app.post(\"/{data}\")\ndef send_msg(somemsg: str, background_tasks: BackgroundTasks):\n result = add_some_tasks(data, background_tasks, noticlient)\n return result\n```\n\n```py\ndef add_some_tasks(data, background_tasks: BackgroundTasks, noticlient):\n background_tasks.add_task(noticlient.send, param1, param2)\n result = some_operation\n return result\n```\n\n```py\nclass childFastApi(FastAPI):\n noticlient = NotificationClient()\n\napp = childFastApi()\n\n@app.post(\"/{data}\")\ndef send_msg(somemsg: str, background_tasks: BackgroundTasks):\n result = add_some_tasks(data, background_tasks, app.noticlient)\n return result\n```\n\n```text\nadd_some_tasks\n```\n\n```py\nfrom fastapi import FastAPI, Request\nfrom contextlib import asynccontextmanager\n\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI):\n ''' Run at startup\n Initialize the Client and add it to app.state\n '''\n app.state.n_client = NotificationClient()\n yield\n ''' Run on shutdown\n Close the connection\n Clear variables and release the resources\n '''\n app.state.n_client.close()\n\n\napp = FastAPI(lifespan=lifespan)\n\n\n@app.get('/')\nasync def main(request: Request):\n n_client = request.app.state.n_client\n # ...\n```\n\n```py\nfrom fastapi import FastAPI, Request\nfrom contextlib import asynccontextmanager\n\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI):\n ''' Run at startup\n Initialize the Client and add it to request.state\n '''\n n_client = NotificationClient()\n yield {'n_client': n_client}\n ''' Run on shutdown\n Close the connection\n Clear variables and release the resources\n '''\n n_client.close()\n\n\napp = FastAPI(lifespan=lifespan)\n\n\n@app.get('/')\nasync def main(request: Request):\n n_client = request.state.n_client\n # ...\n```\n\n```py\nfrom fastapi import FastAPI, Request\nfrom contextlib import asynccontextmanager\n\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI):\n yield {\"data\": {\"val\": 1}}\n #yield {\"val\": 1} # changes to `val` would not take effect globally\n\n\napp = FastAPI(lifespan=lifespan)\n\n\n@app.get('/set')\nasync def set(request: Request):\n #request.state.val = 2 # changes to `val` would not take effect globally\n request.state.data[\"val\"] = 2\n return request.state\n\n\n@app.get(\"/get\")\nasync def get(request: Request):\n return request.state\n```\n\n```py\nimport httpx\n\nr = httpx.get(url=\"http://127.0.0.1:8000/get\")\nprint(r.json())\n#{'_state': {'data': {'val': 1}}}\n\nr = httpx.get(url=\"http://127.0.0.1:8000/set\")\nprint(r.json())\n#{'_state': {'data': {'val': 2}}}\n\nr = httpx.get(url=\"http://127.0.0.1:8000/get\")\nprint(r.json())\n#{'_state': {'data': {'val': 2}}}\n```\n\n```text\napp.state\n```\n\n```text\napp.state\n```\n\n```text\nstate\n```\n\n```text\nrouters\n```\n\n```text\nAPIRouter\n```\n\n```text\nRequest\n```\n\n```text\nrequest.app.state\n```\n\n```text\nstartup\n```\n\n```text\nlifespan\n```\n\n```text\nlifespan\n```\n\n```text\nstartup\n```\n\n```text\nshutdown\n```\n\n```text\nrequest.state\n```\n\n```text\napp.state\n```\n\n```text\nlifespan\n```\n\n```text\nstate\n```\n\n```text\nstate\n```\n\n```text\nstate\n```\n\n```text\nAPIRouter\n```\n\n```text\nrequest.state\n```\n\n```text\napp.state\n```\n\n```text\nrequest.state\n```\n\n```text\nstate\n```\n\n```text\nstate\n```\n\n```text\nrequst.state\n```\n\n```text\nstr\n```\n\n```text\nint\n```\n\n```text\nfloat\n```\n\n```text\ndict\n```\n\n```text\nlist\n```\n\n```text\nstate\n```\n\n```text\nstate\n```\n\n```text\nstate\n```\n\n```text\nlifespan\n```\n\n```text\nuvicorn\n```\n\n```text\nlist\n```\n\n```text\ndict\n```\n\n```text\nstr\n```\n\n```text\nint\n```\n\n```text\nfloat\n```\n\n```text\nstate\n```\n\n```text\nstr\n```\n\n```text\nint\n```\n\n```text\nfloat\n```\n\n```text\napp.state\n```\n\n```text\nrequest.state\n```\n\n```text\napp.state\n```\n\n```text\nrequest.state\n```\n\n========================================\n\nComments:\n- I achieved this by creating childFastApi(FastAPI) class inherited from FastApi and initialized noticlient = NotificationClient() under it. Global variable: app = childFastApi(FastAPI) and than use app.noticlient .Do you see any issue here\n- It seems the Option 1 and Option 2 are (close to) identical, no? What is the difference between the two methods?\n- @FreelanceConsultant You should rather go with Option 2; `app.state` might be removed from future Starlette versions.\n- @Chris do you have a reference for that? I would be interested to look into this in more detail\n- @FreelanceConsultant A Starlette maintainer (same one mentioned in the links below) talked about having it removed in a video about lifespan. In a more recent discussion, it seems that they are *\"not deprecating `app.state`, **but** lifespan state is recommended\"*. See this as well.\n- Is it possible to access lifespan state (option 2) outside of request context? i.e. from a background job?","metadata":{"transformedAt":"2026-08-18T18:32:29.090Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":56,"totalLines":379,"estimatedTokens":1601}}51{"id":"stack-67800698","source":"stackoverflow","questionId":67800698,"title":"Is it possible to impose the length for a list attribute of the request body with fastapi?","tags":["fastapi","pydantic"],"text":"Title: Is it possible to impose the length for a list attribute of the request body with fastapi?\nTags: fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nIs it possible to specify the length of a list in the schema of the request body (or response)? There is support for validating the length of a string passed in the url with the *Query* function, but I see nothing for lists.\n\nPossible use case would be sending list of floats of fixed size to feed to a ML model.\n\n========================================\n\nTop Answer:\nAs of Python 3.9 and Pydantic v2, the recommended way is to use `Annotated` types:\n\n```\n# tested with Python 3.9 & Pydantic 2.6\n\nfrom typing import Annotated\nfrom annotated_types import Len\nfrom pydantic import BaseModel\n\nclass Foo(BaseModel):\n my_list: Annotated[list[str], Len(min_length=1, max_length=1)]\n\nok = Foo(my_list=[\"bar\"])\n\n# these will throw ValidationError exceptions\ntoo_few = Foo(my_list=[])\ntoo_many = Foo(my_list=[\"bar\", \"bar\"])\n```\n\nReferences:\n\n- Pydantic\n\n- annotated_types: MinLen, MaxLen, Len\n\n========================================\n\nCode:\n```text\nfrom pydantic import Field\n\nclass Foo(BaseModel):\n fixed_size_list_parameter: list[float] = Field(..., min_length=4, max_length=4)\n```\n\n```text\nfrom pydantic import conlist\n\nclass Foo(BaseModel):\n # these were named min_length and max_length in Pydantic v1.10\n fixed_size_list_parameter: conlist(float, min_length=4, max_length=4)\n```\n\n```text\nField\n```\n\n```text\nmin_length\n```\n\n```text\nmax_length\n```\n\n```text\nconlist\n```\n\n```text\nfloat\n```\n\n```py\n# tested with Python 3.9 & Pydantic 2.6\n\nfrom typing import Annotated\nfrom annotated_types import Len\nfrom pydantic import BaseModel\n\nclass Foo(BaseModel):\n my_list: Annotated[list[str], Len(min_length=1, max_length=1)]\n\n\nok = Foo(my_list=[\"bar\"])\n\n# these will throw ValidationError exceptions\ntoo_few = Foo(my_list=[])\ntoo_many = Foo(my_list=[\"bar\", \"bar\"])\n```\n\n```text\nAnnotated\n```\n\n========================================\n\nComments:\n- Just an addition, if you are using `Path` parameters along with list as json payload then use `Body(...)` for payload else it will throw `Not a valid list error`. E.g. `def add_item(self, request: Request, list_id: int, payload: conlist(ListItem, min_items=1, max_items=10) = Body(...)):` this is kind of required in version 0.108.0, works fine without `Body(...)` in 0.89.0, not sure if it's a bug.\n- I believe you meant `fixed_size_list_parameter: list[float]` rather than `fixed_size_list_parameter: float`. Also, `min_length` and `max_length` params are in the *version 2.x*. In contrast, there were named `min_items` and `max_items` in the *version 1.x*.\n- @BenyaminJafari Thanks, I've corrected the type hint.\n- In case you also want to validate the items in the list e.g. (set minimun length for each item), you could also do the following. Import `Field` as `from pydantic import Field`. `min_length_str = Annotated[str, Field(min_length=3)] # Set min length for each item to 3` and then use it as `my_list = Annotated[list[min_length_str], Field(min_length=1, max_length=1)]`.","metadata":{"transformedAt":"2026-08-18T18:32:29.090Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":9,"totalLines":104,"estimatedTokens":771}}52{"id":"stack-62279710","source":"stackoverflow","questionId":62279710,"title":"FastAPI variable query parameters","tags":["python","fastapi"],"text":"Title: FastAPI variable query parameters\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am writing a Fast API server that accepts requests, checks if users are authorized and then redirects them to another URL if successful.\n\nI need to carry over URL parameters, e.g. `http://localhost:80/data/?param1=val1¶m2=val2` should redirect to\n`http://some.other.api/?param1=val1¶m2=val2`, thus keeping previously allotted parameters.\n\nThe parameters are not controlled by me and could change at any moment.\n\nHow can I achieve this?\n\n**Code:**\n\n```\nfrom fastapi import FastAPI\nfrom starlette.responses import RedirectResponse\n\napp = FastAPI()\n\n@app.get(\"/data/\")\nasync def api_data():\n params = '' # I need this value\n url = f'http://some.other.api/{params}'\n response = RedirectResponse(url=url)\n return response\n```\n\n========================================\n\nTop Answer:\nIf the query parameters are known when starting the API but you still wish to have them dynamically set:\n\n```\nfrom fastapi import FastAPI, Depends\nfrom pydantic import create_model\n\napp = FastAPI()\n\n# Put your query arguments in this dict\nquery_params = {\"name\": (str, \"me\")}\n\nquery_model = create_model(\"Query\", **query_params) # This is subclass of pydantic BaseModel\n\n# Create a route\n@app.get(\"/items\")\nasync def get_items(params: query_model = Depends()):\n params_as_dict = params.dict()\n ...\n```\n\nThis has the benefit that you see the parameters in the automatic documentation:\n\nhttps://i.sstatic.net/hhgkI.png\n\nBut you are still able to define them dynamically (when starting the API).\n\n**Note:** if your model has dicts, lists or other BaseModels as field types, the request body pops up. GET should not have body content so you might want to avoid those types.\n\nSee more about dynamic model creation from Pydantic documentation.\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nfrom starlette.responses import RedirectResponse\n\napp = FastAPI()\n\n@app.get(\"/data/\")\nasync def api_data():\n params = '' # I need this value\n url = f'http://some.other.api/{params}'\n response = RedirectResponse(url=url)\n return response\n```\n\n```text\nhttp://localhost:80/data/?param1=val1¶m2=val2\n```\n\n```text\nhttp://some.other.api/?param1=val1¶m2=val2\n```\n\n```text\nfrom fastapi import FastAPI, Request\nfrom starlette.responses import RedirectResponse\n\napp = FastAPI()\n\n@app.get(\"/data/\")\nasync def api_data(request: Request):\n params = request.query_params\n url = f'http://some.other.api/?{params}'\n response = RedirectResponse(url=url)\n return response\n```\n\n```text\n@app.get(\"/\")\n def read_root(param1: Optional[str] = None, param2: Optional[str] = None):\n url = f'http://some.other.api/{param1}/{param2}'\n return {'url': str(url)}\n```\n\n```text\nfrom fastapi import FastAPI, Depends\nfrom pydantic import create_model\n\napp = FastAPI()\n\n# Put your query arguments in this dict\nquery_params = {\"name\": (str, \"me\")}\n\nquery_model = create_model(\"Query\", **query_params) # This is subclass of pydantic BaseModel\n\n# Create a route\n@app.get(\"/items\")\nasync def get_items(params: query_model = Depends()):\n params_as_dict = params.dict()\n ...\n```\n\n```text\n# imports\nfrom typing import Union\nfrom pydantic import BaseModel\nfrom fastapi import Depends, Request\n\n# the base model\nclass QueryParams(BaseModel):\n required: str\n optional: Union[None, str] = None\n dynamic: dict\n\n# dependency\nasync def query_params(\n request: Request, requiredParam1: str, optionalParam1: Union[None, str] = None\n ):\n # process the request here\n dynamicParams = {}\n for k in request.query_params.keys():\n if 'dynamicParam' not in k:\n continue\n dynamicParams[k] = request.query_params[k]\n\n # also maybe do some other things on the arguments\n # ...\n\n return {\n 'required': requiredParam1,\n 'optional': optionalParam1,\n 'dynamic': dynamicParams\n }\n\n# the endpoint\n@app.get(\"api/\")\nasync def hello(params: QueryParams = Depends(query_params)):\n\n # Maybe do domething with params here,\n # Use it as you would any BaseModel object\n # ...\n\n return params\n```\n\n```text\nDepends\n```\n\n```text\nBaseModel\n```\n\n```text\nRequest\n```\n\n```text\nlocalhost:5000/api?requiredParam1=value1&optionalParam2=value2&dynamicParam1=value3&dynamicParam2=value4\n```\n\n```text\nquery_params\n```\n\n```text\nRequest\n```\n\n```py\nfrom pydantic import (\n BaseModel,\n)\nfrom typing import (\n Dict,\n List,\n Optional,\n)\n\nfrom fastapi import (\n Depends,\n FastAPI,\n Query,\n Request,\n)\n\n\nclass QueryParameters(BaseModel):\n \"\"\"Model for query parameter.\"\"\"\n fixId: Optional[str]\n fixStr: Optional[str]\n fixList: Optional[List[str]]\n fixBool: Optional[bool]\n dynFields: Dict\n\n _aliases: Dict[str,str] = {\"id\": \"fixId\"}\n\n @classmethod\n def parser(\n cls, \n request: Request,\n fixId: Optional[str] = Query(None, alias=\"id\"),\n fixStr: Optional[str] = Query(None),\n fixList: Optional[List[str]] = Query(None),\n fixBool: bool = Query(True),\n ) -> Dict:\n \"\"\"Parse query string parameters.\"\"\"\n dynFields = {}\n reserved_keys = cls.__fields__\n query_keys = request.query_params\n for key in query_keys:\n key = cls._aliases.get(key, key) \n if key in reserved_keys:\n continue\n dynFields[key] = request.query_params[key]\n \n return {\n \"fixId\": fixId,\n \"fixStr\": fixStr,\n \"fixList\": fixList,\n \"fixBool\": fixBool,\n \"dynFields\": dynFields\n }\n\n\napp = FastAPI()\n\n\n@app.get(\"/msg\")\ndef get_msg(\n parameters: QueryParameters = Depends(\n QueryParameters.parser,\n ),\n) -> None:\n return parameters\n```\n\n```bash\n> curl -s -X 'GET' 'http://127.0.0.1:8000/msg?id=Victor&fixStr=hi&fixList=eggs&fixList=milk&fixList=oranges&fixBool=true' -H 'accept: application/json' | python3 -m json.tool\n{\n \"fixId\": \"Victor\",\n \"fixStr\": \"hi\",\n \"fixList\": [\n \"eggs\",\n \"milk\",\n \"oranges\"\n ],\n \"fixBool\": true,\n \"dynFields\": {}\n}\n```\n\n```bash\n> curl -s -X 'GET' 'http://127.0.0.1:8000/msg?id=Victor&fixStr=hi&fixList=eggs&fixList=milk&fixList=oranges&fixBool=true&key1=value1&key2=value2' -H 'accept: application/json' | python3 -m json.tool\n{\n \"fixId\": \"Victor\",\n \"fixStr\": \"hi\",\n \"fixList\": [\n \"eggs\",\n \"milk\",\n \"oranges\"\n ],\n \"fixBool\": true,\n \"dynFields\": {\n \"key1\": \"value1\",\n \"key2\": \"value2\"\n }\n}\n```\n\n```text\nparams = request.query_params._dict\n# {'names': 'names2,names1,names3', 'values': 'value1,value2,value3'}\nprint(params)\n\nfor key, value in params.items():\n value = value.split(',')\n params[key] = value\n\n# {'names': ['names2', 'names1', 'names3'], 'values': ['value1', 'value2', 'value3']}\nprint(params)\n\n\nindex = params['names'].index('names2')\nvalue = params['values'][index]\n# 'value3'\nprint(value)\n```\n\n```text\nnames\n```\n\n```text\nvalues\n```\n\n```text\nnames\n```\n\n```text\nvalues\n```\n\n```text\nhttp://localhost:80/data/?names=name1,name2,name3&values=value1,value2,value3\n```\n\n========================================\n\nComments:\n- Please try `@app.get(\"/files/{file_path:path}\")`, fastapi.tiangolo.com/tutorial/path-params\n- Future readers might find this answer, as well as this answer and this answer helpful.\n- how about if you want to get each of the params passed? any way to get all of the params from the string `params`?\n- Ah yes this works too, but does not account for any number of parameters that might have been passed in\n- like this answer also..there is a great use-case for this answer...when i need to do some other things with the query parameters\n- this is not how it usually works with query parameter with multiple values. Usually it is like `names=name1&names=name2&names=name3&values=value1&values=val‌​ue2&values=value3`","metadata":{"transformedAt":"2026-08-18T18:32:29.090Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":22,"totalLines":343,"estimatedTokens":1992}}53{"id":"stack-68932099","source":"stackoverflow","questionId":68932099,"title":"How to get Alembic to recognise SQLModel database model?","tags":["python","sqlalchemy","fastapi","alembic","sqlmodel"],"text":"Title: How to get Alembic to recognise SQLModel database model?\nTags: python, sqlalchemy, fastapi, alembic, sqlmodel\nSource: Stack Overflow\n\nQuestion:\nUsing SQLModel how to get alembic to recognise the below model?\n\n```\nfrom sqlmodel import Field, SQLModel\n\nclass Hero(SQLModel, table=True):\n id: int = Field(default=None, primary_key=True)\n name: str\n secret_name: str\n age: Optional[int] = None\n```\n\nOne approach I've been looking at is to import the SQLalchemy model for Alembic but looking through the source code I can't find how to do that.\n\nHow to make Alembic work with SQLModel models?\n\n========================================\n\nTop Answer:\nHere you can find a fastapi-alembic and SQLmodel integration with async PostgreSQL database\nhttps://github.com/jonra1993/fastapi-sqlmodel-alembic\n\n========================================\n\nCode:\n```text\nfrom sqlmodel import Field, SQLModel\n\nclass Hero(SQLModel, table=True):\n id: int = Field(default=None, primary_key=True)\n name: str\n secret_name: str\n age: Optional[int] = None\n```\n\n```text\n#script.py.mako\nfrom alembic import op\nimport sqlalchemy as sa\nimport sqlmodel # added\n```\n\n```text\n#env.py\nfrom logging.config import fileConfig\n\nfrom sqlalchemy import engine_from_config\nfrom sqlalchemy import pool\n\nfrom alembic import context\n\nfrom app.models import * # necessarily to import something from file where your models are stored\n\n# this is the Alembic Config object, which provides\n# access to the values within the .ini file in use.\nconfig = context.config\n\n# Interpret the config file for Python logging.\n# This line sets up loggers basically.\nfileConfig(config.config_file_name)\n\n# add your model's MetaData object here\n# for 'autogenerate' support\n# from myapp import mymodel\n# target_metadata = mymodel.Base.metadata\ntarget_metadata = None \n# comment line above and instead of that write\ntarget_metadata = SQLModel.metadata\n```\n\n```text\nalembic revision --autogenerate -m \"your message\"\n```\n\n```text\nalembic upgrade head\n```\n\n```text\nalembic init migrations\n```\n\n```text\nimport sqlmodel\n```\n\n========================================\n\nComments:\n- What do you mean by \"get alembic to recognise the below model\"? I tried to run migrations with alembic a couple of days ago and changes were recognisable\n- Anyway I can try to spell out detail how I got it all working.\n- If you got the changes to be recognisable that's all I was after, can you post your solution?\n- As mentioned at TestDriven.io Post too.\n- Three is a PR for this here, you can look in the comments and see the instructions there too: github.com/tiangolo/sqlmodel/pull/512\n- It would be better to use `from app import models` instead of `from app.models import *` in `env.py`\n- When you add `target_metadata = SQLModel.metadata` to your env.py, did you need to also add the `from sqlmodel import SQLModel` there? In my case when I ran `alembic revisons --autogenerate -m \"your message\"` it gave the error: \"NameError: name 'SQLModel' is not defined\".\n- yes, `from sqlmodel import SQLModel` has to be added too","metadata":{"transformedAt":"2026-08-18T18:32:29.090Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":7,"totalLines":102,"estimatedTokens":763}}54{"id":"stack-57412825","source":"stackoverflow","questionId":57412825,"title":"How to start a Uvicorn + FastAPI in background when testing with PyTest","tags":["python","testing","pytest","fastapi","uvicorn"],"text":"Title: How to start a Uvicorn + FastAPI in background when testing with PyTest\nTags: python, testing, pytest, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI have an REST-API app written with Uvicorn+FastAPI\n\nWhich I want to test using PyTest.\n\nI want to start the server in a fixture when I start the tests, so when the test complete, the fixture will kill the app.\n\nFastAPI Testing shows how to test the API app, \n\n```\nfrom fastapi import FastAPI\nfrom starlette.testclient import TestClient\n\napp = FastAPI()\n\n@app.get(\"/\")\nasync def read_main():\n return {\"msg\": \"Hello World\"}\n\nclient = TestClient(app)\n\ndef test_read_main():\n response = client.get(\"/\")\n assert response.status_code == 200\n assert response.json() == {\"msg\": \"Hello World\"}\n```\n\nThis doesn't bring the server online in the usual way. It seems that the specific functionality that is triggered by the client.get command is the only thing that runs.\n\nI found these additional resources, but I can't make them work for me:\n\nhttps://medium.com/@hmajid2301/pytest-with-background-thread-fixtures-f0dc34ee3c46\n\nHow to run server as fixture for py.test\n\n**How would you run the Uvicorn+FastAPI app from PyTest, so it goes up and down with the tests?**\n\n========================================\n\nTop Answer:\nIf you want to bring the server up you will have to do it in a different process/thread, since uvicorn.run() is a blocking call. \n\nThen instead of using the TestClient you will have to use something like requests to hit the actual URL your server is listening to.\n\n```\nfrom multiprocessing import Process\n\nimport pytest\nimport requests\nimport uvicorn\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/\")\nasync def read_main():\n return {\"msg\": \"Hello World\"}\n\ndef run_server():\n uvicorn.run(app)\n\n@pytest.fixture\ndef server():\n proc = Process(target=run_server, args=(), daemon=True)\n proc.start() \n yield\n proc.kill() # Cleanup after test\n\ndef test_read_main(server):\n response = requests.get(\"http://localhost:8000/\")\n assert response.status_code == 200\n assert response.json() == {\"msg\": \"Hello World\"}\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nfrom starlette.testclient import TestClient\n\napp = FastAPI()\n\n\n@app.get(\"/\")\nasync def read_main():\n return {\"msg\": \"Hello World\"}\n\n\nclient = TestClient(app)\n\n\ndef test_read_main():\n response = client.get(\"/\")\n assert response.status_code == 200\n assert response.json() == {\"msg\": \"Hello World\"}\n```\n\n```text\nimport logging\nfrom fastapi import FastAPI\n\nclass App:\n \"\"\" Core application to test. \"\"\"\n\n def __init__(self):\n self.api = FastAPI()\n # register endpoints\n self.api.get(\"/\")(self.read_root)\n self.api.on_event(\"shutdown\")(self.close)\n\n async def close(self):\n \"\"\" Gracefull shutdown. \"\"\"\n logging.warning(\"Shutting down the app.\")\n\n async def read_root(self):\n \"\"\" Read the root. \"\"\"\n return {\"Hello\": \"World\"}\n\n\"\"\" Testing part.\"\"\"\nfrom multiprocessing import Process\nimport asynctest\nimport asyncio\nimport aiohttp\nimport uvicorn\n\nclass TestApp(asynctest.TestCase):\n \"\"\" Test the app class. \"\"\"\n\n async def setUp(self):\n \"\"\" Bring server up. \"\"\"\n app = App()\n self.proc = Process(target=uvicorn.run,\n args=(app.api,),\n kwargs={\n \"host\": \"127.0.0.1\",\n \"port\": 5000,\n \"log_level\": \"info\"},\n daemon=True)\n self.proc.start()\n await asyncio.sleep(0.1) # time for the server to start\n\n async def tearDown(self):\n \"\"\" Shutdown the app. \"\"\"\n self.proc.terminate()\n\n async def test_read_root(self):\n \"\"\" Fetch an endpoint from the app. \"\"\"\n async with aiohttp.ClientSession() as session:\n async with session.get(\"http://127.0.0.1:5000/\") as resp:\n data = await resp.json()\n self.assertEqual(data, {\"Hello\": \"World\"})\n```\n\n```py\nfrom multiprocessing import Process\n\nimport pytest\nimport requests\nimport uvicorn\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n\n@app.get(\"/\")\nasync def read_main():\n return {\"msg\": \"Hello World\"}\n\n\ndef run_server():\n uvicorn.run(app)\n\n\n@pytest.fixture\ndef server():\n proc = Process(target=run_server, args=(), daemon=True)\n proc.start() \n yield\n proc.kill() # Cleanup after test\n\n\ndef test_read_main(server):\n response = requests.get(\"http://localhost:8000/\")\n assert response.status_code == 200\n assert response.json() == {\"msg\": \"Hello World\"}\n```\n\n```py\nfrom typing import List, Optional\nimport asyncio\n\nimport pytest\n\nimport uvicorn\n\nPORT = 8000\n\n\nclass UvicornTestServer(uvicorn.Server):\n \"\"\"Uvicorn test server\n\n Usage:\n @pytest.fixture\n server = UvicornTestServer()\n await server.up()\n yield\n await server.down()\n \"\"\"\n\n def __init__(self, app, host='127.0.0.1', port=PORT):\n \"\"\"Create a Uvicorn test server\n\n Args:\n app (FastAPI, optional): the FastAPI app. Defaults to main.app.\n host (str, optional): the host ip. Defaults to '127.0.0.1'.\n port (int, optional): the port. Defaults to PORT.\n \"\"\"\n self._startup_done = asyncio.Event()\n super().__init__(config=uvicorn.Config(app, host=host, port=port))\n\n async def startup(self, sockets: Optional[List] = None) -> None:\n \"\"\"Override uvicorn startup\"\"\"\n await super().startup(sockets=sockets)\n self.config.setup_event_loop()\n self._startup_done.set()\n\n async def up(self) -> None:\n \"\"\"Start up server asynchronously\"\"\"\n self._serve_task = asyncio.create_task(self.serve())\n await self._startup_done.wait()\n\n async def down(self) -> None:\n \"\"\"Shut down server asynchronously\"\"\"\n self.should_exit = True\n await self._serve_task\n\n\n@pytest.fixture\nasync def startup_and_shutdown_server():\n \"\"\"Start server as test fixture and tear down after test\"\"\"\n server = UvicornTestServer()\n await server.up()\n yield\n await server.down()\n\n\n@pytest.mark.asyncio\nasync def test_chat_simple(startup_and_shutdown_server):\n \"\"\"A simple websocket test\"\"\"\n # any test code here\n```\n\n```text\nimport unittest\nfrom fastapi.testclient import TestClient\nfrom engine.routes.base import app\n\n\nclass PostTest(unittest.TestCase):\n def setUp(self) -> None:\n self.client = TestClient(app)\n\n def test_home_page(self):\n response = self.client.get(\"/\")\n assert response.status_code == 200\n```\n\n```py\ndef test_read_main():\n with TestClient(app) as client:\n response = client.get(\"/\")\n assert response.status_code == 200\n assert response.json() == {\"msg\": \"Hello World\"}\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.testclient import TestClient\n\napp = FastAPI()\n\n@app.on_event(\"startup\")\nasync def startup_event():\n # This will not be reached in pytest, but in gunicorn it will\n print(\"Block reached\")\n\n@app.get(\"/\")\nasync def read_main():\n return {\"msg\": \"Hello World\"}\n\ndef test_read_main():\n client = TestClient(app)\n response = client.get(\"/\")\n assert response.status_code == 200\n assert response.json() == {\"msg\": \"Hello World\"}\n```\n\n```text\nwith TestClient(app) as client\n```\n\n```text\n@app.on_event(\"startup\")\n```\n\n```text\n@app.on_event(\"shutdown\")\n```\n\n```text\ngunicorn\n```\n\n```text\n@app.on_event(\"startup\")\n```\n\n```text\n@app.on_event(\"shutdown\")\n```\n\n```text\ngunicorn\n```\n\n```text\nBlock reached\n```\n\n```text\nfrom fastapi import FastAPI\nimport asyncio\nimport uvicorn\nimport aiohttp\nfrom datetime import datetime\nimport random\nfrom contextlib import asynccontextmanager\n\nasync def fetch(session:aiohttp.ClientSession, url):\n async with session.get(url) as response:\n data = await response.text()\n return data\n \nasync def test(n_reqs:int=1):\n async with aiohttp.ClientSession() as session:\n tasks = [fetch(session, 'http://127.0.0.1:8000/') for _ in range(n_reqs)]\n\n print('Fetching results...')\n results = await asyncio.gather(*tasks)\n\n for i, result in enumerate(results):\n print(f'Result {i}: {result}')\n\napp = FastAPI()\n\n@app.get('/')\nasync def root():\n await asyncio.sleep(random.randint(1, 5))\n return f'Current time: {datetime.now()}'\n\n@asynccontextmanager\nasync def running_server(server:uvicorn.Server):\n print('Starting server...')\n asyncio.create_task(server.serve())\n\n try:\n while not server.started:\n # give server some time to start up\n await asyncio.sleep(1e-3)\n yield # server started - do some other stuff\n finally:\n print('Shutting down server...')\n server.should_exit = True\n await server.shutdown()\n\nasync def main():\n n_reqs = 7\n\n config = uvicorn.Config(app, loop=asyncio.get_running_loop())\n server = uvicorn.Server(config)\n\n async with running_server(server):\n async with asyncio.TaskGroup() as tg:\n tg.create_task(test(n_reqs=n_reqs))\n\n print('All done!')\n\nif __name__ == '__main__':\n asyncio.run(main())\n```\n\n```text\nimport asyncio\nimport pytest\nimport pytest_asyncio\nimport aiohttp\nimport random\nfrom fastapi import FastAPI\nimport uvicorn\nfrom contextlib import asynccontextmanager\nfrom typing import Literal\nfrom fastapi.responses import PlainTextResponse\n\napp = FastAPI()\n\n@app.get('/', response_class=PlainTextResponse)\nasync def root():\n await asyncio.sleep(random.randint(1, 4))\n return 'Hello world!'\n\n@app.get('/foo')\nasync def foo():\n await asyncio.sleep(random.randint(1, 4))\n return {'a':1}\n\nasync def fetch(session:aiohttp.ClientSession, url:str, content_type:Literal['text', 'json']='text'):\n print(f'Fetching {content_type} response...')\n async with session.get(url) as response:\n res = None\n match content_type:\n case 'text':\n res = await response.text()\n case 'json':\n res = await response.json()\n case _:\n raise ValueError(f'Unknown content type {content_type}')\n return res\n print(f'{content_type} response fetched!')\n\n@asynccontextmanager\nasync def running_server(server:uvicorn.Server):\n print('Starting server...')\n asyncio.create_task(server.serve())\n\n try:\n while not server.started:\n # give server some time to start up\n await asyncio.sleep(1e-3)\n print('Server started!')\n yield # server started - give up control so other code can do stuff\n finally:\n print('Shutting down server...')\n server.should_exit = True\n await server.shutdown()\n print('Server shut down!')\n\n@pytest.fixture(scope='class') # see https://docs.pytest.org/en/7.1.x/how-to/fixtures.html#fixture-scopes (VERY IMPORTANT!)\ndef server_cfg():\n return uvicorn.Config(app)\n\n@pytest_asyncio.fixture(scope='class')\nasync def server_ctx(request:pytest.FixtureRequest, server_cfg:uvicorn.Config):\n request.cls.loop = asyncio.get_running_loop()\n request.cls.server_cfg = server_cfg\n\n server = uvicorn.Server(server_cfg)\n async with running_server(server):\n yield\n\n@pytest.mark.asyncio(loop_scope='class')\nclass TestGracefulAsyncServer():\n loop: asyncio.AbstractEventLoop\n server_cfg: uvicorn.Config\n\n @pytest.mark.parametrize('n_reqs', [1, 3])\n async def test_root_endpoint(self, server_ctx, n_reqs:int):\n assert TestGracefulAsyncServer.loop is asyncio.get_running_loop()\n \n server_cfg = TestGracefulAsyncServer.server_cfg\n\n async with aiohttp.ClientSession() as session:\n tasks = [\n fetch(\n session, \n f'{\"https\" if server_cfg.ssl else \"http\"}://{server_cfg.host}:{server_cfg.port}{app.url_path_for(\"root\")}',\n content_type='text',\n ) for _ in range(n_reqs)\n ]\n results = await asyncio.gather(*tasks)\n \n assert len(results) == n_reqs\n\n for res in results:\n assert res == 'Hello world!'\n\n @pytest.mark.parametrize('n_reqs', [1, 3])\n async def test_foo_endpoint(self, server_ctx, n_reqs:int):\n assert TestGracefulAsyncServer.loop is asyncio.get_running_loop()\n server_cfg = TestGracefulAsyncServer.server_cfg\n\n async with aiohttp.ClientSession() as session:\n tasks = [\n fetch(\n session, \n f'{\"https\" if server_cfg.ssl else \"http\"}://{server_cfg.host}:{server_cfg.port}{app.url_path_for(\"foo\")}',\n content_type='json',\n ) for _ in range(n_reqs)\n ]\n results = await asyncio.gather(*tasks)\n \n assert len(results) == n_reqs\n\n for res in results:\n assert res == {'a':1}\n```\n\n========================================\n\nComments:\n- This is a related question to this question stackoverflow.com/q/61577643/4165272 and this question stackoverflow.com/q/68603658/4165272\n- See github.com/encode/uvicorn/discussions/1103\n- This is not working with pytest >= 4.0, since it doesn't support `yield` anymore\n- I just tested with pytest 4.0.0 and 5.4.2 and yield still works. In the documentation it even says you should use this approach\n- It says here in the documentation that yield-test are deprecated. In my case I couldn't get it running with yield. The server didn't stop without it\n- With your input I got it running with a `fixture(scope=\"module\")` and `yield proc` (instead of just yield). Thank you very much!\n- @M.Winkens, you're talking about `yield`s inside of **test functions**, which is deprecated. In this example, yield is in fixture, which is not at all deprecated. Here you go: docs.pytest.org/en/2.8.7/yieldfixture.html#yieldfixture\n- Note, if you `yield` immediately after starting the Uvicorn process you will get a `ConnectionError` because the server takes time to start\n- multiprocessing won't work if non-pickable stuff is used\n- And what about coverage? This method is working, but coverage doesn't see affected lines of code :(\n- what additional values does asynctest bring unit testing? I can understand it can be important for end to end testing, or load test etc, but for unit test, didn't get it.\n- asynctest is a testing framework above unittest convinient to test coroutines. Unittest was only able to test sync functions, but maybe it has change since.\n- I don't think you need async test suite to test async FastAPI functions. Here is the tutorial: fastapi.tiangolo.com/tutorial/testing.\n- Here I have another solution that spins up the server in the same process and does a graceful shutdown.\n- From my newbie point of view, if you introduce new elements not required by the OP like the async approach, an explanation on why this is required or which benefits does it have if it's not required, would be appreciated. This would also help people who can't make it work without this approach find out if it's a requirement or not and why.\n- Didn't work for me. The server just got stuck and didn't reply. Tried to reach the host in a browser: the same story. Had to kill it with kill -9. Python 3.7.5\n- @GlaIZier, your testing code must be asynchronous too. Have you been using requests? You should use aiohttp. If you want the server to respond, everything must be non-blocking.\n- Works like a charm for me. I needed the uvicorn server to run on the same process as pytest because I monkeypatch some functions and I disable the network for unit tests. With the solution above running on a different process, the monkeypatching and disabling the network had no effect (probs because a different interpretor is spawned in the new process).\n- Good solution. For compatibility with recent Pytest versions, I had to replace `@pytest.fixture` with `@pytest_asyncio.fixture`.\n- @TimNieradzik Cool. The docs (pytest-asyncio.readthedocs.io/en/latest/concepts.html) seems to require it only for strict mode. I think, I used auto mode.\n- You shouldn't rely on `setup_event_loop`. It was removed on version 0.36.0.","metadata":{"transformedAt":"2026-08-18T18:32:29.091Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":17,"totalLines":535,"estimatedTokens":4065}}55{"id":"stack-60132045","source":"stackoverflow","questionId":60132045,"title":"FastAPI/uvicorn not working when specifying host","tags":["python","windows","localhost","fastapi","uvicorn"],"text":"Title: FastAPI/uvicorn not working when specifying host\nTags: python, windows, localhost, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI'm running a FastAPI app in Python using uvicorn on a Windows machine without a frontend (e.g. Next.js, etc.) so there should NOT be any iteraction between a local frontend and backend like there is in this question. Plus the answer(s) to that question would not have solved my issue/question. That question was also asked AFTER this one so THIS QUESTION IS NOT A DUPLICATE!\n\nIt works fine when I do any one of the following options:\n\n- Run the following code on my mac, or\n\n- When I don't specify the port for uvicorn (remove the `host` parameter from the uvicorn.run call)\n\n- When I specify port '127.0.0.1', which is the host it uses when I don't specify a host at all.\n\n```\nfrom fastapi import FastAPI\nimport uvicorn\n\napp = FastAPI()\n\n@app.get(\"/\")\nasync def root():\n return {\"message\": \"Hello World\"}\n\nif __name__ == '__main__':\n uvicorn.run(app, port=8080, host='0.0.0.0')\n```\n\nWhen I go to 0.0.0.0:8080 on my browser, I get an error that says \"This site can’t be reached\".\n\nI have checked my current active ports to make sure I'm not getting a collision using `netstat -ao |find /i \"listening\"` and 0.0.0.0:8080 is not in use.\n\nMy current file configuration looks like this:\n\n```\nworking_directory\n└── app\n ├── gunicorn_conf.py\n └── main.py\n```\n\nMy gunicorn_conf.py is super simple and just tries to set the host and port:\n\n```\nhost = \"0.0.0.0\"\nport = \"8080\"\n```\n\nHow can I get this to work when I specify host '0.0.0.0'?\n\n========================================\n\nTop Answer:\nRun this in terminal `uvicorn main:app --port 8086 --reload`\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nimport uvicorn\n\napp = FastAPI()\n\n\n@app.get(\"/\")\nasync def root():\n return {\"message\": \"Hello World\"}\n\n\nif __name__ == '__main__':\n uvicorn.run(app, port=8080, host='0.0.0.0')\n```\n\n```text\nworking_directory\n└── app\n ├── gunicorn_conf.py\n └── main.py\n```\n\n```text\nhost = \"0.0.0.0\"\nport = \"8080\"\n```\n\n```text\nhost\n```\n\n```text\nnetstat -ao |find /i \"listening\"\n```\n\n```text\nuvicorn main:app --port 8086 --reload\n```\n\n```text\n0.0.0.0\n```\n\n```text\nlocalhost\n```\n\n```text\n127.0.0.1\n```\n\n```text\nlocalhost\n```\n\n========================================\n\nComments:\n- This solution works for me too. But It's still kinda magic to me. Why it's work using localhost instead of 127.0.0.1 or 0.0.0.0 ?\n- this is it for me.\n- this works for me if you want to add this in your debug configuration then just add --port 8086 --reload","metadata":{"transformedAt":"2026-08-18T18:32:29.091Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":10,"totalLines":121,"estimatedTokens":650}}56{"id":"stack-64936440","source":"stackoverflow","questionId":64936440,"title":"Python uvicorn : The term 'uvicorn' is not recognized as the name of a cmdlet, function, script file","tags":["python","fastapi","uvicorn"],"text":"Title: Python uvicorn : The term 'uvicorn' is not recognized as the name of a cmdlet, function, script file\nTags: python, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nGood evening,\n\nI am using python 3.9 and try to run a new FastAPI service on Windows 10 Pro based on the documentation on internet https://www.uvicorn.org/ i executed the following statements\n\n```\npip install uvicorn pip install uvicorn[standard]\n```\n\ncreate the sample file app.py\n\n```\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/\")\nasync def root():\n return {\"message\": \"Hello World\"}\n```\n\nBut when i run the code below :\n\n```\nuvicorn main:app --reload\n\nuvicorn : The term 'uvicorn' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify t\nhat the path is correct and try again.\nAt line:1 char:1\n+ uvicorn\n+ ~~~~~~~\n + CategoryInfo : ObjectNotFound: (uvicorn:String) [], CommandNotFoundException\n + FullyQualifiedErrorId : CommandNotFoundException\n```\n\nI also add the path of Python in the envroment settings\n\nI also re-install Python 3.9 and make the default path for installation to c:\\ProgramFiles\\Python39 this path is also include now in the system enviroment and user enviroment settings.\n\nhttps://i.sstatic.net/0LgMN.png\n\nif i run pip install uvicorn again it shows the following statement:\n\n```\nλ pip install uvicorn\nDefaulting to user installation because normal site-packages is not writeable\nRequirement already satisfied: uvicorn in c:\\users\\username\\appdata\\roaming\\python\\python39\\site-packages (0.12.2)\nRequirement already satisfied: h11>=0.8 in c:\\users\\username\\appdata\\roaming\\python\\python39\\site-packages (from uvicorn) (0.11.0)\nRequirement already satisfied: click==7.* in c:\\users\\username\\appdata\\roaming\\python\\python39\\site-packages (from uvicorn) (7.1.2)\nWARNING: You are using pip version 20.2.3; however, version 20.2.4 is available.\nYou should consider upgrading via the 'c:\\program files\\python39\\python.exe -m pip install --upgrade pip' command.\n```\n\nMany thanks\n\nErik\n\n========================================\n\nTop Answer:\nYou can also run `uvicorn` with the following command:\n\n```\npython -m uvicorn main:app --reload\n```\n\n========================================\n\nCode:\n```text\npip install uvicorn pip install uvicorn[standard]\n```\n\n```text\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n\n@app.get(\"/\")\nasync def root():\n return {\"message\": \"Hello World\"}\n```\n\n```text\nuvicorn main:app --reload\n\n\nuvicorn : The term 'uvicorn' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify t\nhat the path is correct and try again.\nAt line:1 char:1\n+ uvicorn\n+ ~~~~~~~\n + CategoryInfo : ObjectNotFound: (uvicorn:String) [], CommandNotFoundException\n + FullyQualifiedErrorId : CommandNotFoundException\n```\n\n```text\nλ pip install uvicorn\nDefaulting to user installation because normal site-packages is not writeable\nRequirement already satisfied: uvicorn in c:\\users\\username\\appdata\\roaming\\python\\python39\\site-packages (0.12.2)\nRequirement already satisfied: h11>=0.8 in c:\\users\\username\\appdata\\roaming\\python\\python39\\site-packages (from uvicorn) (0.11.0)\nRequirement already satisfied: click==7.* in c:\\users\\username\\appdata\\roaming\\python\\python39\\site-packages (from uvicorn) (7.1.2)\nWARNING: You are using pip version 20.2.3; however, version 20.2.4 is available.\nYou should consider upgrading via the 'c:\\program files\\python39\\python.exe -m pip install --upgrade pip' command.\n```\n\n```text\npython -m uvicorn main:app --reload\n```\n\n```text\nuvicorn\n```\n\n```text\npython -m uvicorn main:app --reload\n```\n\n```text\nactivate xxx\n```\n\n```text\nuvicorn Example:app --reload\n```\n\n========================================\n\nComments:\n- Try adding `\\pip` to the end of that path.\n- @John: I did what you say! But it does not solve the problem yet! See adjusted question\n- Hmm. Try `%APPDATA%\\Python` instead?\n- @John thanks for the fast reply. It is still not working. I have changed the question again\n- Have you tried installing it with `pip3 install ...` ?\n- Hi Isabi, yes I also tried that, but that didn't work\n- Hi Ognyan! thanks for the reply of the solution. I found the solution of this problem. And it is in system path variable. It seams that Python install the script s in c:\\users\\username\\appdata\\roaming\\python\\python39\\scripts\\\n- But thanks to the removal script a saw where the uvicorn.exe is placed.\n- if python does not work use python3 instead\n- Work for the windows user\n- This works even without PATH set.","metadata":{"transformedAt":"2026-08-18T18:32:29.091Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":9,"totalLines":145,"estimatedTokens":1163}}57{"id":"stack-71031816","source":"stackoverflow","questionId":71031816,"title":"how do you properly reuse an httpx.AsyncClient within a FastAPI application?","tags":["python","fastapi","httpx"],"text":"Title: how do you properly reuse an httpx.AsyncClient within a FastAPI application?\nTags: python, fastapi, httpx\nSource: Stack Overflow\n\nQuestion:\nI have a FastAPI application which, in several different occasions, needs to call external APIs. I use httpx.AsyncClient for these calls. The point is that I don't fully understand how I shoud use it.\n\nFrom httpx' documentation I should use context managers,\n\n```\nasync def foo():\n \"\"\"\"\n I need to call foo quite often from different \n parts of my application\n \"\"\"\n async with httpx.AsyncClient() as aclient:\n # make some http requests, e.g.,\n await aclient.get(\"http://example.it\")\n```\n\nHowever, I understand that in this way a new client is spawned each time I call `foo()`, and is precisely what we want to avoid by using a client in the first place.\n\nI suppose an alternative would be to have some global client defined somewhere, and just import it whenever I need it like so\n\n```\naclient = httpx.AsyncClient()\n\nasync def bar():\n # make some http requests using the global aclient, e.g.,\n await aclient.get(\"http://example.it\")\n```\n\nThis second option looks somewhat fishy, though, as nobody is taking care of closing the session and the like.\n\nSo the question is: how do I properly (re)use `httpx.AsyncClient()` within a FastAPI application?\n\n========================================\n\nTop Answer:\nThe answer to this question depends on how you structure your FastAPI application and how you manage your dependencies. One possible way to use httpx.AsyncClient() is to create a custom dependency function that returns an instance of the client and closes it when the request is finished. For example:\n\n```\nfrom fastapi import FastAPI, Depends\nimport httpx\n\napp = FastAPI()\n\nasync def get_client():\n # create a new client for each request\n async with httpx.AsyncClient() as client:\n # yield the client to the endpoint function\n yield client\n # close the client when the request is done\n\n@app.get(\"/foo\")\nasync def foo(client: httpx.AsyncClient = Depends(get_client)):\n # use the client to make some http requests, e.g.,\n response = await client.get(\"http://example.it\")\n return response.json()\n```\n\nThis way, you don't need to create a global client or worry about closing it manually. FastAPI will handle the dependency injection and the context management for you. You can also use the same dependency function for other endpoints that need to use the client.\n\nAlternatively, you can create a global client and close it when the application shuts down. For example:\n\n```\nfrom fastapi import FastAPI, Depends\nimport httpx\nimport atexit\n\napp = FastAPI()\n\n# create a global client\nclient = httpx.AsyncClient()\n\n# register a function to close the client when the app exits\natexit.register(client.aclose)\n\n@app.get(\"/bar\")\nasync def bar():\n # use the global client to make some http requests, e.g.,\n response = await client.get(\"http://example.it\")\n return response.json()\n```\n\nThis way, you don't need to create a new client for each request, but you need to make sure that the client is closed properly when the application stops. You can use the atexit module to register a function that will be called when the app exits, or you can use other methods such as signal handlers or event hooks.\n\nBoth methods have their pros and cons, and you should choose the one that suits your needs and preferences. You can also check out the FastAPI documentation on dependencies and testing for more examples and best practices.\n\n========================================\n\nCode:\n```text\nasync def foo():\n \"\"\"\"\n I need to call foo quite often from different \n parts of my application\n \"\"\"\n async with httpx.AsyncClient() as aclient:\n # make some http requests, e.g.,\n await aclient.get(\"http://example.it\")\n```\n\n```text\naclient = httpx.AsyncClient()\n\nasync def bar():\n # make some http requests using the global aclient, e.g.,\n await aclient.get(\"http://example.it\")\n```\n\n```text\nfoo()\n```\n\n```text\nhttpx.AsyncClient()\n```\n\n```text\nimport logging\nfrom fastapi import FastAPI\nimport httpx\n\nlogging.basicConfig(level=logging.INFO, format=\"%(levelname)-9s %(asctime)s - %(name)s - %(message)s\")\nLOGGER = logging.getLogger(__name__)\n\n\nclass HTTPXClientWrapper:\n\n async_client = None\n\n def start(self):\n \"\"\" Instantiate the client. Call from the FastAPI startup hook.\"\"\"\n self.async_client = httpx.AsyncClient()\n LOGGER.info(f'httpx AsyncClient instantiated. Id {id(self.async_client)}')\n\n async def stop(self):\n \"\"\" Gracefully shutdown. Call from FastAPI shutdown hook.\"\"\"\n LOGGER.info(f'httpx async_client.is_closed(): {self.async_client.is_closed} - Now close it. Id (will be unchanged): {id(self.async_client)}')\n await self.async_client.aclose()\n LOGGER.info(f'httpx async_client.is_closed(): {self.async_client.is_closed}. Id (will be unchanged): {id(self.async_client)}')\n self.async_client = None\n LOGGER.info('httpx AsyncClient closed')\n\n def __call__(self):\n \"\"\" Calling the instantiated HTTPXClientWrapper returns the wrapped singleton.\"\"\"\n # Ensure we don't use it if not started / running\n assert self.async_client is not None\n LOGGER.info(f'httpx async_client.is_closed(): {self.async_client.is_closed}. Id (will be unchanged): {id(self.async_client)}')\n return self.async_client\n\n\nhttpx_client_wrapper = HTTPXClientWrapper()\napp = FastAPI()\n\n\n@app.get('/test-call-external')\nasync def call_external_api(url: str = 'https://stackoverflow.com'):\n async_client = httpx_client_wrapper()\n res = await async_client.get(url)\n result = res.text\n return {\n 'result': result,\n 'status': res.status_code\n }\n\n\n@app.on_event(\"startup\")\nasync def startup_event():\n httpx_client_wrapper.start()\n\n\n@app.on_event(\"shutdown\")\nasync def shutdown_event():\n await httpx_client_wrapper.stop()\n\n\nif __name__ == '__main__':\n import uvicorn\n LOGGER.info(f'starting...')\n uvicorn.run(f\"{__name__}:app\", host=\"127.0.0.1\", port=8000)\n```\n\n```text\naiohttp\n```\n\n```text\nlocalhost:8000/docs\n```\n\n```text\nstart()\n```\n\n```text\nasync\n```\n\n```text\nstop()\n```\n\n```text\nself.async_client = None\n```\n\n```text\nasync_client = None\n```\n\n```py\nfrom fastapi import FastAPI, Depends\nimport httpx\n\napp = FastAPI()\n\nasync def get_client():\n # create a new client for each request\n async with httpx.AsyncClient() as client:\n # yield the client to the endpoint function\n yield client\n # close the client when the request is done\n\n@app.get(\"/foo\")\nasync def foo(client: httpx.AsyncClient = Depends(get_client)):\n # use the client to make some http requests, e.g.,\n response = await client.get(\"http://example.it\")\n return response.json()\n```\n\n```py\nfrom fastapi import FastAPI, Depends\nimport httpx\nimport atexit\n\napp = FastAPI()\n\n# create a global client\nclient = httpx.AsyncClient()\n\n# register a function to close the client when the app exits\natexit.register(client.aclose)\n\n@app.get(\"/bar\")\nasync def bar():\n # use the global client to make some http requests, e.g.,\n response = await client.get(\"http://example.it\")\n return response.json()\n```\n\n========================================\n\nComments:\n- This question has already been answered here and here.\n- This is not sufficient. You need to instantiate the client in an async context since it depends on the event loop being available.\n- The `start()` method is called from the startup hook, which only happens once the event loop is running. I've added the uvicorn bootstrapping so that it's now fully executable as a single file to make it easier to try out locally. In a real world app you would import the wrapper from anywhere in your app (`from my_app.main import httpx_client_wrapper`) and call it to get the client - just as is done in the `call_external_api()` route here.\n- In a real world app, I would use a `Depends` injection for the client.\n- But using `get_client` as dependency injection still is spawninig client each time you call `foo()` right?","metadata":{"transformedAt":"2026-08-18T18:32:29.091Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":14,"totalLines":260,"estimatedTokens":2013}}58{"id":"stack-59391560","source":"stackoverflow","questionId":59391560,"title":"How to run UVICORN in Heroku?","tags":["python","heroku","fastapi","uvicorn"],"text":"Title: How to run UVICORN in Heroku?\nTags: python, heroku, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nSo I have figured out how to code a fastAPI and I am ready to deploy my script to heroku that I have worked with fastAPI (https://fastapi.tiangolo.com/) however the problem is that when I do a request to heroku it will just return:\n\n```\n\n \n Internal Server Error\n \n \n Internal Server Error\n\n \n\n```\n\nWhich means the script is on but I can't see the error and locally it works totally fine I would say.\n\nI am not able to see any logs where the problem is however I would say my problem might be that I am not sure if my **procfile** is correct because I haven't edited it at all and I am quite new at this and I am here to ask how I am able to run my fastapi script in heroku?\n\nWhat I know is that to be able to run the script, you have to use command `uvicorn main:app --reload` and it won't work if you do etc `py main.py` What am I doing wrong?\n\n========================================\n\nTop Answer:\nThe answer(s) are correct, but to use FastAPI in production running as **WSGI** with **ASGI** workers is a better choice here is why, i ran a benchmark for this **question**, so here is the results.\n\n### **Gunicorn with Uvicorn workers**\n\n```\nRequests per second: 8665.48 [#/sec] (mean)\nConcurrency Level: 500\nTime taken for tests: 0.577 seconds\nComplete requests: 5000\nTime per request: 57.700 [ms] (mean)\n```\n\n### **Pure Uvicorn**\n\n```\nRequests per second: 3200.62 [#/sec] (mean)\nConcurrency Level: 500\nTime taken for tests: 1.562 seconds\nComplete requests: 5000\nTime per request: 156.220 [ms] (mean)\n```\n\nAs you can see there is a huge difference in **RPS(Request per second)** and response time for each request.\n\n### Procfiles\n\nGunicorn with Uvicorn Workers\n\n```\nweb: gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app\n```\n\nPure uvicorn\n\n```\nweb: uvicorn main:app --workers 4\n```\n\n========================================\n\nCode:\n```text\n<html>\n <head>\n <title>Internal Server Error</title>\n </head>\n <body>\n <h1><p>Internal Server Error</p></h1>\n\n </body>\n</html>\n```\n\n```text\nuvicorn main:app --reload\n```\n\n```text\npy main.py\n```\n\n```text\nweb: uvicorn src.main:app --host=0.0.0.0 --port=${PORT:-5000}\n```\n\n```text\nimport socket\nimport sys\n\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\nhostname = socket.gethostname()\n\nversion = f\"{sys.version_info.major}.{sys.version_info.minor}\"\n\n\n@app.get(\"/\")\nasync def read_root():\n return {\n \"name\": \"my-app\",\n \"host\": hostname,\n \"version\": f\"Hello world! From FastAPI running on Uvicorn. Using Python {version}\"\n }\n```\n\n```text\nheroku local\n```\n\n```text\n__init__.py\n```\n\n```text\nmain.py\n```\n\n```text\nweb: gunicorn -w 3 -k uvicorn.workers.UvicornWorker main:app\n```\n\n```text\nGunicorn\n```\n\n```text\nuvicorn\n```\n\n```text\nRequests per second: 8665.48 [#/sec] (mean)\nConcurrency Level: 500\nTime taken for tests: 0.577 seconds\nComplete requests: 5000\nTime per request: 57.700 [ms] (mean)\n```\n\n```text\nRequests per second: 3200.62 [#/sec] (mean)\nConcurrency Level: 500\nTime taken for tests: 1.562 seconds\nComplete requests: 5000\nTime per request: 156.220 [ms] (mean)\n```\n\n```text\nweb: gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app\n```\n\n```text\nweb: uvicorn main:app --workers 4\n```\n\n```text\ngunicorn pm.wsgi --log-level=debug \\\n-k uvicorn.workers.UvicornWorker --log-file - --timeout 60\n```\n\n```text\nimport os\n\nfrom django.core.wsgi import get_wsgi_application\nfrom dj_static import Cling\nfrom uvicorn.middleware.wsgi import WSGIMiddleware\nos.environ.setdefault(\"DJANGO_SETTINGS_MODULE\", \"pm.settings\")\n\n# added the WSGIMiddleWare wrapper\napplication = WSGIMiddleware(Cling(get_wsgi_application()))\n```\n\n```text\nWSGIMiddleware\n```\n\n========================================\n\nComments:\n- Ohhh you are right, I believe my issue was the Procfile actually. Because I had the rest correct but not the Procfile and seems to work as it should now! Thanks for the github too because that helps me out quite alot too!\n- How does this change if using Google Cloud Run? Would you just use a single Uvicorn worker and let google handle the scaling?\n- So, this means that Gunicorn does better jobs in worker managerments.\n- i want to deploy fastapi for serving ml models in k8s on AWS EKS and stumbled on your benchmarks. what is the proper smallest machine configuration(cpu threads and ram, or better which aws ec2 instance) that can handle 4 `UvicornWorker` instances with `gunicorn` for maximum performance and optimal and maximum resource usage.","metadata":{"transformedAt":"2026-08-18T18:32:29.091Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":18,"totalLines":191,"estimatedTokens":1145}}59{"id":"stack-70477787","source":"stackoverflow","questionId":70477787,"title":"How to get current path in FastAPI with domain?","tags":["python","fastapi"],"text":"Title: How to get current path in FastAPI with domain?\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have a simple route as below that written in FastAPI,\n\n```\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/foo/bar/{rand_int}/foo-bar/\")\nasync def main(rand_int: int):\n return {\"path\": f\"https://some-domain.com/foo/bar/{rand_int}/foo-bar/?somethig=foo\"}\n```\n\nHow can I get the current path *\"programmatically\"* with,\n\n- domain (`some-domain.com`)\n\n- path (`/foo/bar/{rand_int}/foo-bar/`)\n\n- and query parameters (`?somethig=foo`)\n\n========================================\n\nTop Answer:\nIn latest version of FastAPI (0.103.1)\n\nusing `Request` module from `from fastapi import Request` we can get the domain, path and query params\n\nusing\n\n```\ndomain = request.base_url\npath = request.url.path\nquery_params = request.query_params\n```\n\nexample would be\n\n```\nfrom fastapi import FastAPI, Request\n\napp = FastAPI()\n\n@app.get(\"/foo/bar/{rand_int}/foo-bar/\")\nasync def main(rand_int: int, request: Request):\n domain = request.base_url\n path = request.url.path\n query_params = request.query_params\n\n return {\"domain\": domain, \"path\": path, \"query_params\": query_params}\n```\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n\n@app.get(\"/foo/bar/{rand_int}/foo-bar/\")\nasync def main(rand_int: int):\n return {\"path\": f\"https://some-domain.com/foo/bar/{rand_int}/foo-bar/?somethig=foo\"}\n```\n\n```text\nsome-domain.com\n```\n\n```text\n/foo/bar/{rand_int}/foo-bar/\n```\n\n```text\n?somethig=foo\n```\n\n```text\nfrom fastapi import FastAPI, Request\n\napp = FastAPI()\n\n\n@app.get(\"/foo/bar/{rand_int}/foo-bar/\")\nasync def main(rand_int: int, request: Request):\n return {\"raw_url\": str(request.url)}\n```\n\n```text\nRequest.url\n```\n\n```text\nRequest.url._url\n```\n\n```text\nstr(Request.url)\n```\n\n```text\ndomain = request.base_url\npath = request.url.path\nquery_params = request.query_params\n```\n\n```text\nfrom fastapi import FastAPI, Request\n\napp = FastAPI()\n\n\n@app.get(\"/foo/bar/{rand_int}/foo-bar/\")\nasync def main(rand_int: int, request: Request):\n domain = request.base_url\n path = request.url.path\n query_params = request.query_params\n\n return {\"domain\": domain, \"path\": path, \"query_params\": query_params}\n```\n\n```text\nRequest\n```\n\n```text\nfrom fastapi import Request\n```\n\n========================================\n\nComments:\n- People looking for how to get the raw URL path, for instance, `/foo/bar/{rand_int}/foo-bar/` instead of `/foo/bar/1/foo-bar/`, you may find this answer helpful.\n- It's also possible to call `str(request.url)` to get an string of the url to avoid accessing a private variable.\n- @Abbas Good point, much more pythonic. I use it in f-strings, e.g. `f\"{request.url}: {some_log_message}\"`.\n- Note that for query parameters, if you expect multiple values for a certain key, using `dict(request.query_params)` wouldn't work as expected. Please take a look at this answer and this answer for more details and solutions.\n- yes, didn't thought of that case, was encounter with this problem today so give this solution. for that case your provided solution will work or need to write custom parser for that not default one","metadata":{"transformedAt":"2026-08-18T18:32:29.091Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":12,"totalLines":142,"estimatedTokens":809}}60{"id":"stack-71268169","source":"stackoverflow","questionId":71268169,"title":"Optional query parameters in FastAPI","tags":["python","fastapi","optional-parameters"],"text":"Title: Optional query parameters in FastAPI\nTags: python, fastapi, optional-parameters\nSource: Stack Overflow\n\nQuestion:\nI don't understand optional query parameters in FastAPI. How is it different from default query parameters with a default value of `None`?\n\nWhat is the difference between `arg1` and `arg2` in the example below where `arg2` is made an optional query parameter as described in the above link?\n\n```\n@app.get(\"/info/\")\nasync def info(arg1: int = None, arg2: int | None = None):\n return {\"arg1\": arg1, \"arg2\": arg2}\n```\n\n========================================\n\nTop Answer:\nIn addition to the answer by @MatsLindh, you can also use the `fastapi.Query` class with a `default` parameter set.\n\nFor example:\n\n```\nasync def get_companies(company_id: int = Query(default=None, alias=\"id\"), limit: int = Query(default=15), page: int = Query(default=1)):\n```\n\ndefines a function `get_companies,` with an optional `company_id` (parsed in the request arguments as `id`), an optional `limit`, as well as an optional `page`. To mark the argument as required, you can remove the `default=` param.\n\n========================================\n\nCode:\n```py\n@app.get(\"/info/\")\nasync def info(arg1: int = None, arg2: int | None = None):\n return {\"arg1\": arg1, \"arg2\": arg2}\n```\n\n```text\nNone\n```\n\n```text\narg1\n```\n\n```text\narg2\n```\n\n```text\narg2\n```\n\n```text\nasync def read_items(q: Optional[str] = None):\n```\n\n```text\nOptional[str]\n```\n\n```text\nOptional[str]\n```\n\n```text\nstr | None\n```\n\n```text\nOptional\n```\n\n```py\nasync def get_companies(company_id: int = Query(default=None, alias=\"id\"), limit: int = Query(default=15), page: int = Query(default=1)):\n```\n\n```text\nfastapi.Query\n```\n\n```text\ndefault\n```\n\n```text\nget_companies,\n```\n\n```text\ncompany_id\n```\n\n```text\nid\n```\n\n```text\nlimit\n```\n\n```text\npage\n```\n\n```text\ndefault=\n```\n\n```py\nfrom typing import Union\n\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n\n@app.get(\"/items/{item_id}\")\nasync def read_item(item_id: str, q: Union[str, None] = None):\n if q:\n return {\"item_id\": item_id, \"q\": q}\n return {\"item_id\": item_id}\n```\n\n========================================\n\nComments:\n- afaik, there is no difference between them\n- Please have a look at this answer and this answer for more details and examples.\n- `The Optional in Optional[str] is not used by FastAPI, but will allow your editor to give you better support and detect errors.` - this is an important point that you addressed. I was confused that fast-api still requires it even after marking it `Optional`","metadata":{"transformedAt":"2026-08-18T18:32:29.091Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":20,"totalLines":130,"estimatedTokens":634}}61{"id":"stack-70658748","source":"stackoverflow","questionId":70658748,"title":"Using FastAPI in a sync way, how can I get the raw body of a POST request?","tags":["python","fastapi","starlette"],"text":"Title: Using FastAPI in a sync way, how can I get the raw body of a POST request?\nTags: python, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nUsing FastAPI in a **sync**, not `async` mode, I would like to be able to receive the raw, unchanged body of a POST request.\n\nAll examples I can find show `async` code, when I try it in a normal sync way, the `request.body()` shows up as a coroutine object.\n\nWhen I test it by posting some `XML` to this endpoint, I get a `500 \"Internal Server Error\"`.\n\n```\nfrom fastapi import FastAPI, Response, Request, Body\n\napp = FastAPI()\n\n@app.get(\"/\")\ndef read_root():\n return {\"Hello\": \"World\"}\n\n@app.post(\"/input\")\ndef input_request(request: Request):\n # how can I access the RAW request body here? \n body = request.body()\n\n # do stuff with the body here \n\n return Response(content=body, media_type=\"application/xml\")\n```\n\nIs this not possible with FastAPI?\n\nNote: a simplified input request would look like:\n\n```\nPOST http://127.0.0.1:1083/input\nContent-Type: application/xml\n\n TEST\n\n```\n\nand I have no control over how input requests are sent, because I need to replace an existing SOAP API.\n\n========================================\n\nTop Answer:\nFor convenience, you can simply use `asgiref`, this package supports `async_to_sync` and `sync_to_async`:\n\n```\nfrom asgiref.sync import async_to_sync\n\nsync_body_func = async_to_sync(request.body)\nprint(sync_body_func())\n```\n\n`async_to_sync` execute an async function in an eventloop, `sync_to_async` execute a sync function in a threadpool.\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI, Response, Request, Body\n\napp = FastAPI()\n\n@app.get(\"/\")\ndef read_root():\n return {\"Hello\": \"World\"}\n\n@app.post(\"/input\")\ndef input_request(request: Request):\n # how can I access the RAW request body here? \n body = request.body()\n\n # do stuff with the body here \n\n return Response(content=body, media_type=\"application/xml\")\n```\n\n```text\nPOST http://127.0.0.1:1083/input\nContent-Type: application/xml\n\n<XML>\n <BODY>TEST</BODY>\n</XML>\n```\n\n```text\nasync\n```\n\n```text\nasync\n```\n\n```text\nrequest.body()\n```\n\n```text\nXML\n```\n\n```text\n500 \"Internal Server Error\"\n```\n\n```py\nfrom fastapi import Request\n\n@app.post(\"/input\")\nasync def input_request(request: Request):\n return await request.body()\n```\n\n```py\nfrom fastapi import Body\n\n@app.post(\"/input\")\ndef input_request(payload: dict = Body(...)):\n return payload\n```\n\n```py\nfrom fastapi import File\n\n@app.post(\"/input\") \ndef input_request(contents: bytes = File(...)): \n return contents\n```\n\n```py\nfrom fastapi import FastAPI, Depends, Request\nimport time\n\napp = FastAPI()\n\nasync def get_body(request: Request):\n return await request.body()\n\n@app.post(\"/input\")\ndef input_request(body: bytes = Depends(get_body)):\n print(\"New request arrived.\")\n #time.sleep(5)\n return body\n```\n\n```text\nasync def\n```\n\n```text\nawait\n```\n\n```text\nbody\n```\n\n```text\nasync\n```\n\n```text\nawait\n```\n\n```text\nasync def\n```\n\n```text\ndef\n```\n\n```text\nJSON\n```\n\n```text\ndef\n```\n\n```text\nBody\n```\n\n```text\nJSON\n```\n\n```text\nXML\n```\n\n```text\nFiles\n```\n\n```text\ndef\n```\n\n```text\nasync\n```\n\n```text\nasync\n```\n\n```text\nbody\n```\n\n```text\nasync\n```\n\n```text\nnon-async\n```\n\n```text\ndef\n```\n\n```text\nasync\n```\n\n```text\nawait\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\nasync def\n```\n\n```text\nawait\n```\n\n```text\ntime.sleep()\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\nasync def\n```\n\n```py\nfrom asgiref.sync import async_to_sync\n\nsync_body_func = async_to_sync(request.body)\nprint(sync_body_func())\n```\n\n```text\nasgiref\n```\n\n```text\nasync_to_sync\n```\n\n```text\nsync_to_async\n```\n\n```text\nasync_to_sync\n```\n\n```text\nsync_to_async\n```\n\n========================================\n\nComments:\n- In sync there's no await, that's why I'm asking. FastAPI supports sync requests after all...\n- I'll check and get back to this\n- the \"File\" approach returns \"HTTP/1.1 422 Unprocessable Entity\". I added an example request to the original question. Note: I can't control how clients requests look like because I'm recreating a legacy SOAP API to be able to re-route the request from the legacy system to a Python service that will replace the old service.\n- Thanks for revisiting this. Update #2 works for me (using FastAPI 0.79.0 and Python 3.10.5 on Windows 10) - it also works fine if several requests are made at the same time.","metadata":{"transformedAt":"2026-08-18T18:32:29.091Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":47,"totalLines":303,"estimatedTokens":1101}}62{"id":"stack-65491184","source":"stackoverflow","questionId":65491184,"title":"Ratelimit in Fastapi","tags":["python","fastapi","rate-limiting"],"text":"Title: Ratelimit in Fastapi\nTags: python, fastapi, rate-limiting\nSource: Stack Overflow\n\nQuestion:\nHow to ratelimit API endpoint request in Fastapi application ? I need to ratelimit API call 5 request per second per user and exceeding that limit blocks that particular user for 60 seconds.\n\nIn main.py\n\n```\ndef get_application() -> FastAPI:\n application = FastAPI(title=PROJECT_NAME, debug=DEBUG, version=VERSION)\n application.add_event_handler(\n \"startup\", create_start_app_handler(application))\n application.add_event_handler(\n \"shutdown\", create_stop_app_handler(application))\n return application\napp = get_application()\n```\n\nIn events.py\n\n```\ndef create_start_app_handler(app: FastAPI) -> Callable: \n async def start_app() -> None: \n\n redis = await aioredis.create_redis_pool(\"redis://localhost:8080\")\n FastAPILimiter.init(redis)\n return start_app\n```\n\nIn endpoint\n\n```\n@router.post('/user',\n tags=[\"user\"],\n name=\"user:user\", dependencies=[Depends(RateLimiter(times=5, seconds=60))])\n***code****\n```\n\nRun from this file test.py.\n\n```\nimport uvicorn\n\nfrom app.main import app\n\nif __name__ == \"__main__\":\n uvicorn.run(\"test:app\", host=\"0.0.0.0\", port=8000, reload=True)\n```\n\nI edited as above but got following error.\n\n```\nFile \"****ite-packages\\starlette\\routing.py\", line 526, in lifespan\n async for item in self.lifespan_context(app):\n File \"****site-packages\\starlette\\routing.py\", line 467, in default_lifespan\n await self.startup()\n File \"****site-packages\\starlette\\routing.py\", line 502, in startup\n await handler()\n File \"****app\\core\\services\\events.py\", line 15, in start_app\n redis = await aioredis.create_redis_pool(\"redis://localhost:8080\")\n File \"****\\site-packages\\aioredis\\commands\\__init__.py\", line 188, in create_redis_pool\n pool = await create_pool(address, db=db,\n File \"****site-packages\\aioredis\\pool.py\", line 58, in create_pool\n await pool._fill_free(override_min=False)\n File \"C****\\site-packages\\aioredis\\pool.py\", line 383, in _fill_free\n conn = await self._create_new_connection(self._address)\n File \"****site-packages\\aioredis\\connection.py\", line 111, in create_connection\n reader, writer = await asyncio.wait_for(open_connection(\n File \"****\\asyncio\\tasks.py\", line 455, in wait_for\n return await fut\n File \"****\\site-packages\\aioredis\\stream.py\", line 23, in open_connection\n transport, _ = await get_event_loop().create_connection(\n File \"****\\asyncio\\base_events.py\", line 1033, in create_connection\n raise OSError('Multiple exceptions: {}'.format(\nOSError: Multiple exceptions: [Errno 10061] Connect call failed ('::1', 8080, 0, 0), [Errno 10061] Connect call failed ('127.0.0.1', 8080)\n```\n\n========================================\n\nTop Answer:\nFastAPI doesn't natively support this, but it's possible with a few libraries such the ones below, but will usually require some sort of database backing(redis, memcached, etc), although slowapi has a memory fallback in case of no database.\n\n- https://pypi.org/project/fastapi-limiter/\n\n- https://pypi.org/project/slowapi/\n\nIn order to use `fastapi-limiter`, as seen in their documentation:\n\nNote: You will need a running Redis for this to work.\n\n```\nimport aioredis\nimport uvicorn\nfrom fastapi import Depends, FastAPI\n\nfrom fastapi_limiter import FastAPILimiter\nfrom fastapi_limiter.depends import RateLimiter\n\napp = FastAPI()\n\n@app.on_event(\"startup\")\nasync def startup():\n redis = await aioredis.create_redis_pool(\"redis://localhost\")\n FastAPILimiter.init(redis)\n\n@app.get(\"/\", dependencies=[Depends(RateLimiter(times=2, seconds=5))])\nasync def index():\n return {\"msg\": \"Hello World\"}\n\nif __name__ == \"__main__\":\n uvicorn.run(\"main:app\", debug=True, reload=True)\n```\n\n========================================\n\nCode:\n```text\ndef get_application() -> FastAPI:\n application = FastAPI(title=PROJECT_NAME, debug=DEBUG, version=VERSION)\n application.add_event_handler(\n \"startup\", create_start_app_handler(application))\n application.add_event_handler(\n \"shutdown\", create_stop_app_handler(application))\n return application\napp = get_application()\n```\n\n```text\ndef create_start_app_handler(app: FastAPI) -> Callable: \n async def start_app() -> None: \n\n redis = await aioredis.create_redis_pool(\"redis://localhost:8080\")\n FastAPILimiter.init(redis)\n return start_app\n```\n\n```text\n@router.post('/user',\n tags=[\"user\"],\n name=\"user:user\", dependencies=[Depends(RateLimiter(times=5, seconds=60))])\n***code****\n```\n\n```text\nimport uvicorn\n\nfrom app.main import app\n\nif __name__ == \"__main__\":\n uvicorn.run(\"test:app\", host=\"0.0.0.0\", port=8000, reload=True)\n```\n\n```text\nFile \"****ite-packages\\starlette\\routing.py\", line 526, in lifespan\n async for item in self.lifespan_context(app):\n File \"****site-packages\\starlette\\routing.py\", line 467, in default_lifespan\n await self.startup()\n File \"****site-packages\\starlette\\routing.py\", line 502, in startup\n await handler()\n File \"****app\\core\\services\\events.py\", line 15, in start_app\n redis = await aioredis.create_redis_pool(\"redis://localhost:8080\")\n File \"****\\site-packages\\aioredis\\commands\\__init__.py\", line 188, in create_redis_pool\n pool = await create_pool(address, db=db,\n File \"****site-packages\\aioredis\\pool.py\", line 58, in create_pool\n await pool._fill_free(override_min=False)\n File \"C****\\site-packages\\aioredis\\pool.py\", line 383, in _fill_free\n conn = await self._create_new_connection(self._address)\n File \"****site-packages\\aioredis\\connection.py\", line 111, in create_connection\n reader, writer = await asyncio.wait_for(open_connection(\n File \"****\\asyncio\\tasks.py\", line 455, in wait_for\n return await fut\n File \"****\\site-packages\\aioredis\\stream.py\", line 23, in open_connection\n transport, _ = await get_event_loop().create_connection(\n File \"****\\asyncio\\base_events.py\", line 1033, in create_connection\n raise OSError('Multiple exceptions: {}'.format(\nOSError: Multiple exceptions: [Errno 10061] Connect call failed ('::1', 8080, 0, 0), [Errno 10061] Connect call failed ('127.0.0.1', 8080)\n```\n\n```text\nfrom fastapi import FastAPI, Request\nfrom slowapi.errors import RateLimitExceeded\nfrom slowapi import Limiter, _rate_limit_exceeded_handler\nfrom slowapi.util import get_remote_address\n\n\nlimiter = Limiter(key_func=get_remote_address)\napp = FastAPI()\napp.state.limiter = limiter\napp.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)\n\n@app.get(\"/home\")\n@limiter.limit(\"5/minute\")\nasync def homepage(request: Request):\n return PlainTextResponse(\"test\")\n\n@app.get(\"/mars\")\n@limiter.limit(\"5/minute\")\nasync def homepage(request: Request, response: Response):\n return {\"key\": \"value\"}\n```\n\n```text\nimport aioredis\nimport uvicorn\nfrom fastapi import Depends, FastAPI\n\nfrom fastapi_limiter import FastAPILimiter\nfrom fastapi_limiter.depends import RateLimiter\n\napp = FastAPI()\n\n\n@app.on_event(\"startup\")\nasync def startup():\n redis = await aioredis.create_redis_pool(\"redis://localhost\")\n FastAPILimiter.init(redis)\n\n\n@app.get(\"/\", dependencies=[Depends(RateLimiter(times=2, seconds=5))])\nasync def index():\n return {\"msg\": \"Hello World\"}\n\n\nif __name__ == \"__main__\":\n uvicorn.run(\"main:app\", debug=True, reload=True)\n```\n\n```text\nfastapi-limiter\n```\n\n```text\nfrom walrus import Database, RateLimitException\nfrom fastapi import FastAPI, Request\nfrom fastapi.responses import JSONResponse\nimport uvicorn\n\ndb = Database()\nrate = db.rate_limit('xxx', limit=5, per=60) # in 60s just can only click 5 times\n\napp = FastAPI()\n\n\n@app.exception_handler(RateLimitException)\ndef parse_rate_litmit_exception(request: Request, exc: RateLimitException):\n msg = {'success': False, 'msg': f'please have a tea for sleep, your ip is: {request.client.host}.'}\n return JSONResponse(status_code=429, content=msg)\n\n\n@app.get('/')\ndef index():\n return {'success': True}\n\n\n@app.get('/important_api')\n@rate.rate_limited(lambda request: request.client.host)\ndef query_important_data(request: Request):\n data = 'important data'\n return {'success': True, 'data': data}\n\n\nif __name__ == \"__main__\":\n uvicorn.run(\"code1228:app\", debug=True, reload=True)\n```\n\n```text\nfastapi-limiter\n```\n\n```text\nslowapi\n```\n\n```text\nRatelimit in Fastapi\n```\n\n```text\nwalrus\n```\n\n```text\nredis\n```\n\n```text\nredis\n```\n\n```text\ncode1228.py\n```\n\n```text\nhttp://127.0.0.1:8000/important_api\n```\n\n```py\napp.add_middleware(\n RateLimitMiddleware,\n authenticate=AUTH_FUNCTION,\n backend=RedisBackend(),\n config={\n r\"^/user\": [Rule(second=5, block_time=60)],\n },\n)\n```\n\n```text\nfrom fastapi import FastAPI, Request, HTTPException, Depends\nimport time\n\n# Initialize FastAPI app\napp = FastAPI()\n\n# In-memory storage for request counters\nrequest_counters = {}\n\n# Custom RateLimiter class with dynamic rate limiting values per route\nclass RateLimiter:\n def __init__(self, requests_limit: int, time_window: int):\n self.requests_limit = requests_limit\n self.time_window = time_window\n\n async def __call__(self, request: Request):\n client_ip = request.client.host\n route_path = request.url.path\n\n # Get the current timestamp\n current_time = int(time.time())\n\n # Create a unique key based on client IP and route path\n key = f\"{client_ip}:{route_path}\"\n\n # Check if client's request counter exists\n if key not in request_counters:\n request_counters[key] = {\"timestamp\": current_time, \"count\": 1}\n else:\n # Check if the time window has elapsed, reset the counter if needed\n if current_time - request_counters[key][\"timestamp\"] > self.time_window:\n # Reset the counter and update the timestamp\n request_counters[key][\"timestamp\"] = current_time\n request_counters[key][\"count\"] = 1\n else:\n # Check if the client has exceeded the request limit\n if request_counters[key][\"count\"] >= self.requests_limit:\n raise HTTPException(status_code=429, detail=\"Too Many Requests\")\n else:\n request_counters[key][\"count\"] += 1\n\n # Clean up expired client data (optional)\n for k in list(request_counters.keys()):\n if current_time - request_counters[k][\"timestamp\"] > self.time_window:\n request_counters.pop(k)\n\n return True\n\n# Include the custom RateLimiter dependency on specific routes\n@app.get(\"/limited\", dependencies=[Depends(RateLimiter(requests_limit=10, time_window=60))])\nasync def limited_endpoint():\n return {\"message\": \"This endpoint has rate limiting (10 requests per 60 seconds).\"}\n\n@app.get(\"/limited/other\", dependencies=[Depends(RateLimiter(requests_limit=5, time_window=60))])\nasync def limited_other_endpoint():\n return {\"message\": \"This endpoint has rate limiting (5 requests per 60 seconds).\"}\n\n@app.get(\"/unlimited\")\nasync def unlimited_endpoint():\n return {\"message\": \"This endpoint has no rate limiting.\"}\n```\n\n```text\nRateLimiter\n```\n\n```text\nrequests_limit\n```\n\n```text\ntime_window\n```\n\n```text\nRemember:\n```\n\n```text\nrequests_limit\n```\n\n```text\ntime_window\n```\n\n```text\nNote:\n```\n\n```text\n__init__\n```\n\n```text\n(requests_limit and time_window)\n```\n\n```text\n__call__\n```\n\n========================================\n\nComments:\n- Is there any rate limiter implementation for FastApi and websocket protocol? I am investing do it one for my needs.\n- I'd suggest to run your app behind a full-fledged web browser like nginx which provides great rate limiting functionality.\n- @FrancoGil - \"websocket endpoints are not supported yet\" (source)\n- Got error .Added on question after adding fastapi-limiter\n- `File \"****\\site-packages\\aioredis\\stream.py\", line 23, in open_connection` this would probably mean that the redis server isn't up and running, which fastapi-limiter requires.\n- I couldn't edit it myself to add the import of `from slowapi.errors import RateLimitExceeded`, referencing the docs: slowapi.readthedocs.io/en/latest\n- Also note that Request must be a Starlette request. Doesn't seem like you can use Pydantic types?\n- Upvoted but also you should import Request from fastapi\n- Nice catch @DamianJankov, I've updated the answer!\n- How to write auth_fuction for blocking IP address or registered user's id ?\n- Does this ratelimiter works for app working in AWS Lambda?\n- @HimalAcharya You can use it in any ASGI applicatoin. About write auth_function, please read the project README, it's a bit long.\n- I set this up for 1 request per 5 seconds to prevent user smashing the damn compare button and it works perfect.","metadata":{"transformedAt":"2026-08-18T18:32:29.091Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":29,"totalLines":429,"estimatedTokens":3160}}63{"id":"stack-68668417","source":"stackoverflow","questionId":68668417,"title":"Is it possible to pass Path arguments into FastAPI dependency functions?","tags":["python","fastapi"],"text":"Title: Is it possible to pass Path arguments into FastAPI dependency functions?\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nIs there any way for a FastAPI \"dependency\" to interpret Path parameters?\n\nI have a lot of functions of the form:\n\n```\n@app.post(\"/item/{item_id}/process\", response_class=ProcessResponse)\nasync def process_item(item_id: UUID, session: UserSession = Depends(security.user_session)) -> ProcessResponse:\n item = await get_item(client_id=session.client_id, item_id=item_id)\n await item.process()\n```\n\nOver and over, I need to pass in [multiple] arguments to fetch the required item before doing something with it. This is very repetitive and makes the code very verbose. What I'd really like to do is pass the `item` in as an argument to the method.\n\nIdeally I'd like to make `get_item` a dependency or embed it somehow in the router. This would dramatically reduce the repetitive logic and excessively verbose function arguments. The problem is that some critical arguments are passed by the client in the Path.\n\nIs it possible to pass Path arguments into a dependency or perhaps execute the dependency in the router and pass the result?\n\n========================================\n\nTop Answer:\nIt's been a while, but since it can still be useful to someone... If you want to pass an extra argument you can do so by using a lambda function. In my case I wanted to use the response_model in a validation, so I had something like this:\n\n```\nparam: Annotated[str, Depends(lambda param: validate_func(OutputModel, param))]\n```\n\n========================================\n\nCode:\n```py\n@app.post(\"/item/{item_id}/process\", response_class=ProcessResponse)\nasync def process_item(item_id: UUID, session: UserSession = Depends(security.user_session)) -> ProcessResponse:\n item = await get_item(client_id=session.client_id, item_id=item_id)\n await item.process()\n```\n\n```text\nitem\n```\n\n```text\nget_item\n```\n\n```py\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n\n@app.get(\"/items/{item_id}\")\nasync def read_item(item_id):\n return {\"item_id\": item_id}\n```\n\n```py\nfrom fastapi import Depends, FastAPI\n\napp = FastAPI()\n\nasync def my_dependency_function(item_id: int):\n return {\"item_id\": item_id}\n\n\n@app.get(\"/items/{item_id}\")\nasync def read_item(item_id: int, my_dependency: dict = Depends(my_dependency_function)):\n return my_dependency\n```\n\n```py\nfrom fastapi import Depends, FastAPI, Path\n\napp = FastAPI()\n\nasync def my_dependency_function(item_id: int = Path(...)):\n return {\"item_id\": item_id}\n\n\n@app.get(\"/items/{item_id}\")\nasync def read_item(my_dependency: dict = Depends(my_dependency_function)):\n return my_dependency\n```\n\n```py\nitems_router = APIRouter(\n prefix=\"/items\",\n tags=[\"items\"],\n dependencies=[Depends(my_dependency_function)],\n)\n```\n\n```py\napp.include_router(\n items_router,\n prefix=\"/items\",\n dependencies=[Depends(my_dependency_function)],\n)\n```\n\n```text\nPath\n```\n\n```text\nQuery\n```\n\n```text\nPath\n```\n\n```text\ninclude_router\n```\n\n```text\nclass ItemIdExtractor:\n async def __call__(self, item_id: int = Path()) -> int | None:\n # DO SOMETHING HERE IF NEEDED. MAYBE VALIDATE ETC.\n return item_id\n\n\nItemIdDep = Depends(ItemIdExtractor())\n```\n\n```text\n@app.get(\"/items/{item_id}\")\nasync def retrieve_item(item_id: int = ItemIdDep):\n print(item_id)\n return Response(status_code=status.HTTP_200_OK)\n```\n\n```text\nparam: Annotated[str, Depends(lambda param: validate_func(OutputModel, param))]\n```\n\n========================================\n\nComments:\n- You can make your dependency depend on a path parameter, effectively doing `Depends(item_for_client_from_path)` and having `item_for_client_from_path` depend on `item_for_client_from_path(item_id=Path(), session=Depends(security.user_session)); i.e. you make dependencies that abstract away those subdependencies that you use each time. Does that match what you're looking for?\n- @MatsLindh it might. from your comment I can't see how you would extract the *parameter* from the `Path()`. I'm new(ish) to FastAPI so I most likely missed something obvious. As in the example above I need to extract a part of the path which may not be in an entirely uniform position. For some functions there may be other items before `/item/{item_id}/` ... `/foo/bar/item/{item_id}/`.\n- As long as the parameter is named `item_id` in both locations it'll work as you expect. I'll try to make an example when I have time\n- That'd be awesome thanks!\n- That's really great thanks. Regarding doing it on the router, I thought the return value of dependencies defined like that discarded. Obviously I can make the dependency function attach the result to `Request.state`. I was just wondering if I'd missed a more elegant approach.\n- Oh, no wait. I think this explains how. Thanks very much for your help!\n- What if `my_dependency_function` needs another parameters like a database service?\n- @maudev Well ideally you would have a dependency function which creates a database connection, at which point just call that function from within whatever dependency needs it. That is what I would do.","metadata":{"transformedAt":"2026-08-18T18:32:29.091Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":15,"totalLines":152,"estimatedTokens":1288}}64{"id":"stack-64019054","source":"stackoverflow","questionId":64019054,"title":"FastAPI app results in 404 error response when it is started using uvicorn.run","tags":["python-3.x","http-status-code-404","fastapi","uvicorn"],"text":"Title: FastAPI app results in 404 error response when it is started using uvicorn.run\nTags: python-3.x, http-status-code-404, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nNew to FastAPI and uvicorn, but I'm wondering why when I run my \"hello world\" service by starting it using uvicorn from the command line, it works fine, but when using the \"uvicorn.run\" method from inside my service, the service starts, but when I send a GET I always get a `404` with a response body of `{\"detail\": \"Not Found\"}`?\n\nHere is my code:\n\n```\nimport uvicorn\nfrom fastapi import FastAPI\n\napp = FastAPI()\nuvicorn.run(app, host=\"127.0.0.1\", port=5049)\n\n@app.get(\"/\")\nasync def root():\n return {\"message\": \"Hello World\"}\n```\n\nThat always returns with a 404 as follows:\n\n```\n# curl http://127.0.0.1:5049/\n{\"detail\":\"Not Found\"}\n```\n\nThe output from my service shows:\n\n```\nINFO: Started server process [28612]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\nINFO: Uvicorn running on http://127.0.0.1:5049 (Press CTRL+C to quit)\nINFO: 127.0.0.1:55446 - \"GET / HTTP/1.1\" 404 Not Found\n```\n\nIf I comment out the \"uvicorn.run\" line and then start the service from the command line with (running on Windows 10):\n\n```\nuvicorn.exe test:app --host=127.0.0.1 --port=5049\n```\n\nI get the correct response:\n\n```\n# curl http://127.0.0.1:5049/\n{\"message\":\"Hello World\"}\n```\n\n========================================\n\nCode:\n```text\nimport uvicorn\nfrom fastapi import FastAPI\n\napp = FastAPI()\nuvicorn.run(app, host=\"127.0.0.1\", port=5049)\n\n\n@app.get(\"/\")\nasync def root():\n return {\"message\": \"Hello World\"}\n```\n\n```text\n# curl http://127.0.0.1:5049/\n{\"detail\":\"Not Found\"}\n```\n\n```text\nINFO: Started server process [28612]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\nINFO: Uvicorn running on http://127.0.0.1:5049 (Press CTRL+C to quit)\nINFO: 127.0.0.1:55446 - \"GET / HTTP/1.1\" 404 Not Found\n```\n\n```text\nuvicorn.exe test:app --host=127.0.0.1 --port=5049\n```\n\n```text\n# curl http://127.0.0.1:5049/\n{\"message\":\"Hello World\"}\n```\n\n```text\n404\n```\n\n```text\n{\"detail\": \"Not Found\"}\n```\n\n```text\nimport uvicorn\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n\n@app.get(\"/\")\nasync def root():\n return {\"message\": \"Hello World\"}\n\n\n # at last, the bottom of the file/module\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"127.0.0.1\", port=5049)\n```\n\n```text\nuvicorn.run(app, host=\"127.0.0.1\", port=5049)\n```\n\n```text\nroot(...)\n```\n\n```text\nroot(...)\n```\n\n```text\nroot(...)\n```\n\n========================================\n\nComments:\n- With regard to `404 Not Found` error responses, future readers might find the following answers helpful: this, this, as well as this and this","metadata":{"transformedAt":"2026-08-18T18:32:29.091Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":12,"totalLines":134,"estimatedTokens":680}}65{"id":"stack-63420889","source":"stackoverflow","questionId":63420889,"title":"FastAPI / Pydantic circular references in separate files","tags":["python","circular-dependency","fastapi","pydantic"],"text":"Title: FastAPI / Pydantic circular references in separate files\nTags: python, circular-dependency, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI would love to use a schema that looks something like the following in FastAPI:\n\n```\nfrom __future__ import annotations\nfrom typing import List\nfrom pydantic import BaseModel\n\nclass Project(BaseModel):\n members: List[User]\n\nclass User(BaseModel):\n projects: List[Project]\n\nProject.update_forward_refs()\n```\n\nbut in order to keep my project structure clean, I would ofc. like to define these in separate files. How could I do this without creating a circular reference?\n\nWith the code above the schema generation in FastAPI works fine, I just dont know how to separate it out into separate files. In a later step I would then instead of using attributes use `@property`s to define the getters for these objects in subclasses of them. But for the OpenAPI doc generation, I need this combined - I think.\n\n========================================\n\nTop Answer:\nJust place all your schema `imports` **to the bottom of the file**, after all classes, and call `update_forward_refs()`.\n\n```\n#1/4\nfrom __future__ import annotations # this is important to have at the top\nfrom pydantic import BaseModel\n\n#2/4\nclass A(BaseModel):\n my_x: X # a pydantic schema from another file\n\nclass B(BaseModel):\n my_y: Y # a pydantic schema from another file\n\nclass C(BaseModel):\n my_z: int\n\n#3/4\nfrom myapp.schemas.x import X # related schemas we import after all classes\nfrom myapp.schemas.y import Y\n\n#4/4\nA.update_forward_refs() # tell the system that A has a related pydantic schema\nB.update_forward_refs() # tell the system that B has a related pydantic schema\n # for C we don't need it, because C has just an integer field.\n```\n\n**NOTE:**\nDo this **in every file** that has schema imports.\nThat will enable you make any combination without circular import problems.\n\n**NOTE 2:**\nPeople usually put the imports and `update_forward_refs()` after every `class`, and then report that it doesn't work. That is usually because if an app is complex, you do not know what `import` is calling which `class` and when. Therefore, if you put it at the bottom, you are sure that every `class` will be 'scanned' and visible for others.\n\n========================================\n\nCode:\n```text\nfrom __future__ import annotations\nfrom typing import List\nfrom pydantic import BaseModel\n\n\nclass Project(BaseModel):\n members: List[User]\n\n\nclass User(BaseModel):\n projects: List[Project]\n\n\nProject.update_forward_refs()\n```\n\n```text\n@property\n```\n\n```text\n# project.py\nfrom typing import List\nfrom pydantic import BaseModel\n\n\nclass Project(BaseModel):\n members: \"List[User]\"\n\n\nfrom user import User\nProject.update_forward_refs()\n```\n\n```text\n# user.py\nfrom typing import List\nfrom pydantic import BaseModel\n\n\nclass User(BaseModel):\n projects: \"List[Project]\"\n\n\nfrom project import Project\nUser.update_forward_refs()\n```\n\n```text\nimport package.module\n```\n\n```text\nfrom package.module import attribute\n```\n\n```text\nupdate_forward_refs\n```\n\n```text\n#project_base.py\nfrom pydantic import BaseModel\n\nclass ProjectBase(BaseModel):\n id: int\n title: str\n \n class Config:\n orm_mode=True\n```\n\n```text\n#user_base.py\nfrom pydantic import BaseModel\n\nclass UserBase(BaseModel):\n id: int\n title: str\n \n class Config:\n orm_mode=True\n```\n\n```text\n#project.py\nfrom typing import List\nfrom .project_base import ProjectBase\nfrom .user_base import UserBase\n\nclass Project(ProjectBase):\n members: List[UserBase] = []\n```\n\n```text\n#user.py\nfrom typing import List\nfrom .project_base import ProjectBase\nfrom .user_base import UserBase\n\nclass User(UserBase):\n projects: List[ProjectBase] = []\n```\n\n```text\n#1/4\nfrom __future__ import annotations # this is important to have at the top\nfrom pydantic import BaseModel\n\n#2/4\nclass A(BaseModel):\n my_x: X # a pydantic schema from another file\n\nclass B(BaseModel):\n my_y: Y # a pydantic schema from another file\n\nclass C(BaseModel):\n my_z: int\n\n#3/4\nfrom myapp.schemas.x import X # related schemas we import after all classes\nfrom myapp.schemas.y import Y\n\n#4/4\nA.update_forward_refs() # tell the system that A has a related pydantic schema\nB.update_forward_refs() # tell the system that B has a related pydantic schema\n # for C we don't need it, because C has just an integer field.\n```\n\n```text\nimports\n```\n\n```text\nupdate_forward_refs()\n```\n\n```text\nupdate_forward_refs()\n```\n\n```text\nclass\n```\n\n```text\nimport\n```\n\n```text\nclass\n```\n\n```text\nclass\n```\n\n```text\nfrom typing import TYPE_CHECKING, List\nfrom pydantic import BaseModel\n\nif TYPE_CHECKING:\n from project import Project\n\nclass User(BaseModel):\n projects: List['Project']\n```\n\n```text\nfrom typing import TYPE_CHECKING, List\nfrom pydantic import BaseModel\n\nif TYPE_CHECKING:\n from user import User\n\nclass Project(BaseModel):\n members: List['User']\n```\n\n```text\nfrom project import Project\nfrom user import User\n\n# Update the references that are as strings\nProject.update_forward_refs(User=User)\nUser.update_forward_refs(Project=Project)\n\n# Example: Projects into User and Users into Project\nProject(\n members=[\n User(\n projects=[\n Project(members=[])\n ]\n )\n ]\n)\n```\n\n```text\nmain.py\n```\n\n```text\n__init__.py\n```\n\n```text\nUser=User\n```\n\n```text\nProject=Project\n```\n\n```text\nupdate_forward_refs\n```\n\n```text\nif TYPE_CHECKING:\n```\n\n```text\ntyping-extensions\n```\n\n```text\naws-sam-cli\n```\n\n```text\npoetry add typing-extensions@4.5.0\n```\n\n```text\npip install typing-extensions==4.5.0\n```\n\n========================================\n\nComments:\n- Please help me to understand clearly, as i understand you want to store `class User` in `models_user.py` and you want to store `class Project` in `models_project.py` is it right?\n- yes, something like this would be the plan\n- For me (Pydantic user) this helped: `pip install --force-reinstall typing-extensions==4.5.0`\n- Hi alex, thanks for the answer and the input - I agree that I need to find another way how to model this generally!\n- This and especially with **init**.py looks cleanest to me.","metadata":{"transformedAt":"2026-08-18T18:32:29.092Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":32,"totalLines":313,"estimatedTokens":1550}}66{"id":"stack-58642528","source":"stackoverflow","questionId":58642528,"title":"Displaying of FastAPI validation errors to end users","tags":["python","swagger","openapi","fastapi"],"text":"Title: Displaying of FastAPI validation errors to end users\nTags: python, swagger, openapi, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm looking for some library or example of code to format FastAPI validation messages into human-readable format. E.g. this endpoint:\n\n```\n@app.get(\"/\")\nasync def hello(name: str):\n return {\"hello\": name}\n```\n\nWill produce the next json output if we miss `name` query parameter:\n\n```\n{ \n \"detail\":[ \n { \n \"loc\":[ \n \"query\",\n \"name\"\n ],\n \"msg\":\"field required\",\n \"type\":\"value_error.missing\"\n }\n ]\n}\n```\n\nSo my questions is, how to:\n\n- Transform it into something like \"name field is required\" (for all kinds of possible errors) to show in toasts.\n\n- Use it to display form validation messages\n\n- Generate forms themselves from api description if it's possible\n\n========================================\n\nTop Answer:\nI reached here with a similar question - and I ended up handling the `RequestValidationError` to give back a response where every field is an array of the issues with that field.\nThe response to your request would become (with a status_code=400)\n\n```\n{\n \"detail\": \"Invalid request\",\n \"errors\": {\"name\": [\"field required\"]}\n }\n```\n\nthat's quite handy to manage on the frontend for snackbar notifications and flexible enough.\n\nHere's the handler\n\n```\nfrom collections import defaultdict\n\nfrom fastapi import status\nfrom fastapi.encoders import jsonable_encoder\nfrom fastapi.responses import JSONResponse\n\n@app.exception_handler(RequestValidationError)\nasync def custom_form_validation_error(request, exc):\n reformatted_message = defaultdict(list)\n for pydantic_error in exc.errors():\n loc, msg = pydantic_error[\"loc\"], pydantic_error[\"msg\"]\n filtered_loc = loc[1:] if loc[0] in (\"body\", \"query\", \"path\") else loc\n field_string = \".\".join(filtered_loc) # nested fields with dot-notation\n reformatted_message[field_string].append(msg)\n\n return JSONResponse(\n status_code=status.HTTP_400_BAD_REQUEST,\n content=jsonable_encoder(\n {\"detail\": \"Invalid request\", \"errors\": reformatted_message}\n ),\n )\n```\n\nIf you want then to change the error schema in the Swagger doc, define the model:\n\n```\nclass ValidationErrorResponse(BaseModel):\n detail: str = Field(\"Invalid request\", description=\"The general error message\")\n errors: dict[str, list[str]] = Field(\n description=\"Detailed field-specific errors\",\n example={\"field_name\": [\"Field related error 1\", \"Field related error 2\"]},\n )\n```\n\nAnd change the response model in the relevant endpoints where you do the form validation, i.e.:\n\n```\n@app.post(\"/form\")\ndef receive_form(..., responses={400: {\"model\": ValidationErrorResponse}}):\n ....\n```\n\n========================================\n\nCode:\n```py\n@app.get(\"/\")\nasync def hello(name: str):\n return {\"hello\": name}\n```\n\n```text\n{ \n \"detail\":[ \n { \n \"loc\":[ \n \"query\",\n \"name\"\n ],\n \"msg\":\"field required\",\n \"type\":\"value_error.missing\"\n }\n ]\n}\n```\n\n```text\nname\n```\n\n```text\nfrom fastapi import HTTPException\n...\n@app.get(\"/\")\nasync def hello(name: str):\n if not name:\n raise HTTPException(status_code=404, detail=\"Name field is required\")\n return {\"Hello\": name}\n```\n\n```text\nfrom typing import Optional\n...\n@app.get(\"/\")\nasync def hello(name: Optional[str] = None):\n error = {\"Error\": \"Name field is required\"}\n if name:\n return {\"Hello\": name}\n return error\n\n$ curl 127.0.0.1:8000/?name=imbolc\n{\"Hello\":\"imbolc\"}\n...\n$ curl 127.0.0.1:8000\n{\"Error\":\"Name field is required\"}\n```\n\n```text\nfrom fastapi import FastAPI, Request, status\nfrom fastapi.encoders import jsonable_encoder\nfrom fastapi.exceptions import RequestValidationError\nfrom fastapi.responses import JSONResponse\n...\n@app.exception_handler(RequestValidationError)\nasync def validation_exception_handler(request: Request, exc: RequestValidationError):\n return JSONResponse(\n status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,\n content=jsonable_encoder({\"detail\": exc.errors(), \"Error\": \"Name field is missing\"}),\n )\n...\n@app.get(\"/\")\nasync def hello(name: str):\n return {\"hello\": name}\n```\n\n```text\n$ curl 127.0.0.1:8000\n\n {\n \"detail\":[\n {\n \"loc\":[\n \"query\",\n \"name\"\n ],\n \"msg\":\"field required\",\n \"type\":\"value_error.missing\"\n }\n ],\n \"Error\":\"Name field is missing\"\n}\n```\n\n```text\n{\n\"Error\":\"Name field is missing\",\n \"Customize\":{\n \"This\":\"content\",\n \"Also you can\":\"make it simpler\"\n }\n}\n```\n\n```text\nname: str\n```\n\n```text\nOptional\n```\n\n```text\nvalidation_exception_handler\n```\n\n```text\ncontent\n```\n\n```text\n{\n \"detail\": \"Invalid request\",\n \"errors\": {\"name\": [\"field required\"]}\n }\n```\n\n```text\nfrom collections import defaultdict\n\nfrom fastapi import status\nfrom fastapi.encoders import jsonable_encoder\nfrom fastapi.responses import JSONResponse\n\n\n@app.exception_handler(RequestValidationError)\nasync def custom_form_validation_error(request, exc):\n reformatted_message = defaultdict(list)\n for pydantic_error in exc.errors():\n loc, msg = pydantic_error[\"loc\"], pydantic_error[\"msg\"]\n filtered_loc = loc[1:] if loc[0] in (\"body\", \"query\", \"path\") else loc\n field_string = \".\".join(filtered_loc) # nested fields with dot-notation\n reformatted_message[field_string].append(msg)\n\n return JSONResponse(\n status_code=status.HTTP_400_BAD_REQUEST,\n content=jsonable_encoder(\n {\"detail\": \"Invalid request\", \"errors\": reformatted_message}\n ),\n )\n```\n\n```text\nclass ValidationErrorResponse(BaseModel):\n detail: str = Field(\"Invalid request\", description=\"The general error message\")\n errors: dict[str, list[str]] = Field(\n description=\"Detailed field-specific errors\",\n example={\"field_name\": [\"Field related error 1\", \"Field related error 2\"]},\n )\n```\n\n```text\n@app.post(\"/form\")\ndef receive_form(..., responses={400: {\"model\": ValidationErrorResponse}}):\n ....\n```\n\n```text\nRequestValidationError\n```\n\n```py\nfrom fastapi.exceptions import RequestValidationError\n\n@app.exception_handler(RequestValidationError)\nasync def validation_exception_handler(request, exc):\n return PlainTextResponse(str(exc), status_code=400)\n```\n\n```text\n1 validation error\npath -> item_id\n value is not a valid integer (type=type_error.integer)\n```\n\n```text\nPlainTextResponse\n```\n\n```text\n@app.exception_handler(RequestValidationError)\nasync def validation_exception_handler(\n request: Request, exc: RequestValidationError\n):\n # Write user friendly error messages\n error_messages = []\n for error in exc.errors():\n field = error[\"loc\"][-1] # Get the field name\n message = error[\"msg\"]\n error_messages.append(f\"{field.capitalize()}: {message}\")\n\n return JSONResponse(\n status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,\n content={\n \"message\": \".\\n\".join(error_messages),\n \"source_errors\": exc.errors(),\n },\n )\n```\n\n```text\nName: String should have at most 120 characters\n```\n\n========================================\n\nComments:\n- Please see related answers here, here and here, as well as have a look at this, this and this.\n- Not one of a great ideas to override `validation_exception_handler` and hardcode an error message in there; basically you can apply it only on a hello world example..\n- @Michele,, you can basically handle all the cases since you have access to the `Request` object or the `RequestValidationError`.\n- @Erez, you have validation out-of-box without doing anything, yes FastAPI is great at error handling, if your expectation is the handle all the cases error cases without writing any code, I have bad news for you.\n- `jsonable_encoder` did it for me, `AssertionError` and `ValueError` don't get encoded alone on a JSONResponse\n- This is great -- were you able to get your openapi spec to show the schema you created as the validation error schema?\n- Good point @Jonathon - I've updated the response (after discovering I can't use code-blocks in comments 😅). You can define a ValidationErrorResponse model and use it to define the 400 responses on the relevant endpoints","metadata":{"transformedAt":"2026-08-18T18:32:29.092Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":22,"totalLines":319,"estimatedTokens":2051}}67{"id":"stack-62934384","source":"stackoverflow","questionId":62934384,"title":"How to add timestamp to each request in uvicorn logs?","tags":["python","fastapi","uvicorn"],"text":"Title: How to add timestamp to each request in uvicorn logs?\nTags: python, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nWhen I run my FastAPI server using uvicorn:\n\n```\nuvicorn main:app --host 0.0.0.0 --port 8000 --log-level info\n```\n\nThe log I get after running the server:\n\n```\nINFO: Started server process [405098]\nINFO: Waiting for application startup.\nINFO: Connect to database...\nINFO: Successfully connected to the database!\nINFO: Application startup complete.\nINFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)\nINFO: 122.179.31.158:54604 - \"GET /api/hello_world?num1=5&num2=10 HTTP/1.1\" 200 OK\n```\n\nHow do I get the time stamp along with the request logging? Like:\n\n```\nINFO: \"2020-07-16:23:34:78\" - 122.179.31.158:54604 - \"GET /api/hello_world?num1=5&num2=10 HTTP/1.1\" 200 OK\n```\n\n========================================\n\nTop Answer:\nYou can create a ***dict logger config*** and initialize the same using **`dictConfig`** function in your main application.\n\n```\n#main.py\n\nfrom logging.config import dictConfig\nfrom config import log_config\n\nfrom fastapi import FastAPI\n\n**dictConfig(log_config.sample_logger)**\n\napp = FastAPI()\n\n@app.get(\"/\")\nasync def root():\n return {\"message\": \"Hello World\"}\n\n#config/log_config.py\n\nsample_logger = {\n \"version\": 1,\n \"disable_existing_loggers\": False,\n \"formatters\": {\n \"access\": {\n \"()\": \"uvicorn.logging.AccessFormatter\",\n **\"fmt\": '%(levelprefix)s %(asctime)s :: %(client_addr)s - \"%(request_line)s\" %(status_code)s',**\n \"use_colors\": True\n },\n },\n \"handlers\": {\n \"access\": {\n \"formatter\": \"access\",\n \"class\": \"logging.StreamHandler\",\n \"stream\": \"ext://sys.stdout\",\n },\n },\n \"loggers\": {\n \"uvicorn.access\": {\n \"handlers\": [\"access\"],\n \"level\": \"INFO\",\n \"propagate\": False\n },\n },\n}\n```\n\n========================================\n\nCode:\n```text\nuvicorn main:app --host 0.0.0.0 --port 8000 --log-level info\n```\n\n```text\nINFO: Started server process [405098]\nINFO: Waiting for application startup.\nINFO: Connect to database...\nINFO: Successfully connected to the database!\nINFO: Application startup complete.\nINFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)\nINFO: 122.179.31.158:54604 - \"GET /api/hello_world?num1=5&num2=10 HTTP/1.1\" 200 OK\n```\n\n```text\nINFO: \"2020-07-16:23:34:78\" - 122.179.31.158:54604 - \"GET /api/hello_world?num1=5&num2=10 HTTP/1.1\" 200 OK\n```\n\n```text\nimport uvicorn\nfrom uvicorn.config import LOGGING_CONFIG\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\ndef run():\n LOGGING_CONFIG[\"formatters\"][\"default\"][\"fmt\"] = \"%(asctime)s [%(name)s] %(levelprefix)s %(message)s\"\n uvicorn.run(app)\n\nif __name__ == '__main__':\n run()\n```\n\n```text\n2020-08-20 02:33:53,765 [uvicorn.error] INFO: Started server process [107131]\n2020-08-20 02:33:53,765 [uvicorn.error] INFO: Waiting for application startup.\n2020-08-20 02:33:53,765 [uvicorn.error] INFO: Application startup complete.\n2020-08-20 02:33:53,767 [uvicorn.error] INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\n```\n\n```text\nLOGGING_CONFIG\n```\n\n```text\n#main.py\n\nfrom logging.config import dictConfig\nfrom config import log_config\n\nfrom fastapi import FastAPI\n\ndictConfig(log_config.sample_logger)\n\napp = FastAPI()\n\n\n@app.get(\"/\")\nasync def root():\n return {\"message\": \"Hello World\"}\n\n#config/log_config.py\n\nsample_logger = {\n \"version\": 1,\n \"disable_existing_loggers\": False,\n \"formatters\": {\n \"access\": {\n \"()\": \"uvicorn.logging.AccessFormatter\",\n \"fmt\": '%(levelprefix)s %(asctime)s :: %(client_addr)s - \"%(request_line)s\" %(status_code)s',\n \"use_colors\": True\n },\n },\n \"handlers\": {\n \"access\": {\n \"formatter\": \"access\",\n \"class\": \"logging.StreamHandler\",\n \"stream\": \"ext://sys.stdout\",\n },\n },\n \"loggers\": {\n \"uvicorn.access\": {\n \"handlers\": [\"access\"],\n \"level\": \"INFO\",\n \"propagate\": False\n },\n },\n}\n```\n\n```text\ndictConfig\n```\n\n```py\nLOGGING_CONFIG[\"formatters\"][\"default\"][\"fmt\"] = \"%(asctime)s [%(name)s] %(levelprefix)s %(message)s\"\nLOGGING_CONFIG[\"formatters\"][\"access\"][\n \"fmt\"] = '%(asctime)s [%(name)s] %(levelprefix)s %(client_addr)s - \"%(request_line)s\" %(status_code)s'\n```\n\n```text\n2021-03-31 18:38:22,728 [uvicorn.error] INFO: Started server process [21824]\n2021-03-31 18:38:22,729 [uvicorn.error] INFO: Waiting for application startup.\n2021-03-31 18:38:22,729 [uvicorn.error] INFO: Application startup complete.\n2021-03-31 18:38:22,729 [uvicorn.error] INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)\n2021-03-31 18:38:26,359 [uvicorn.access] INFO: 127.0.0.1:51932 - \"POST /limit HTTP/1.1\" 200 OK\n```\n\n```text\nuvicorn main:app --host 0.0.0.0 --port 8000 --log-config log_conf.json --log-level info\n```\n\n```json\n{\n \"version\": 1,\n \"disable_existing_loggers\": false,\n \"formatters\": {\n \"default\": {\n \"()\": \"uvicorn.logging.DefaultFormatter\",\n \"format\": \"%(asctime)s - %(name)s - %(levelname)s - %(message)s\"\n },\n \"access\": {\n \"()\": \"uvicorn.logging.AccessFormatter\",\n \"format\": \"%(asctime)s - %(name)s - %(levelname)s - %(message)s\"\n }\n },\n \"handlers\": {\n \"default\": {\n \"formatter\": \"default\",\n \"class\": \"logging.StreamHandler\",\n \"stream\": \"ext://sys.stderr\"\n },\n \"access\": {\n \"formatter\": \"access\",\n \"class\": \"logging.StreamHandler\",\n \"stream\": \"ext://sys.stdout\"\n }\n },\n \"loggers\": {\n \"uvicorn.error\": {\n \"level\": \"INFO\",\n \"handlers\": [\n \"default\"\n ],\n \"propagate\": \"no\"\n },\n \"uvicorn.access\": {\n \"level\": \"INFO\",\n \"handlers\": [\n \"access\"\n ],\n \"propagate\": \"no\"\n }\n }\n}\n```\n\n```text\n--log-config\n```\n\n```py\nimport logging\nfrom uvicorn.logging import AccessFormatter\n\naccess_log = logging.getLogger(\"uvicorn.access\")\n\n# get stdout handler\nhnd = access_log.handlers[0]\n\n# alternative: append new file handler\n# hnd = logging.FileHandler(\"access.log\")\n# access_log.addHandler(hnd)\n\n# prefix timestamp to logs\nhnd.setFormatter(AccessFormatter(\n '%(asctime)s %(levelprefix)s %(client_addr)s - \"%(request_line)s\" %(status_code)s'))\n```\n\n```text\nuvicorn.config.LOGGING_CONFIG\n```\n\n```text\nuvicorn.run(app)\n```\n\n```text\nlogging.config.dictConfig\n```\n\n```text\nuvicorn --log-config\n```\n\n```text\naccess.log\n```\n\n```text\nstdout\n```\n\n```text\ndocker\n```\n\n```text\nstdout\n```\n\n```text\ndocker compose logs -t\n```\n\n========================================\n\nComments:\n- You can use **`--log-config`** to specify the log configuration file\n- This worked perfectly for me! And it seems the less changing from my standpoint\n- How to disable colors, bold, italic etc? Simply setting the `\"use_colors\": False` did not work. nor using uvicorn flag `--no-use-colors`. I am redirecting the log to a file and it keeps writing ANSI color escape codes to the log file (like `[1m`, `[0m`, `[32m`)\n- `LOGGING_CONFIG[\"formatters\"][\"default\"][\"datefmt\"] = \"%Y-%m-%d %H:%M:%S\"` is also useful.\n- `LOGGING_CONFIG[\"formatters\"][\"access\"][\"fmt\"] = '%(asctime)s %(levelprefix)s %(client_addr)s - \"%(request_line)s\" %(status_code)s'`\n- This is what I used! Thanks! :)\n- Why does it say `uvicorn.error` when its an `INFO`? :/\n- @matthaeus That's the current, very unfortunate, name of the uvicorn logger.","metadata":{"transformedAt":"2026-08-18T18:32:29.092Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":23,"totalLines":308,"estimatedTokens":1891}}68{"id":"stack-73972660","source":"stackoverflow","questionId":73972660,"title":"How to return data in JSON format using FastAPI?","tags":["python","json","serialization","fastapi","starlette"],"text":"Title: How to return data in JSON format using FastAPI?\nTags: python, json, serialization, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nI have written the same API application with the same function in both FastAPI and Flask. However, when returning the JSON, the format of data differs between the two frameworks. Both use the same `json` library and even the same exact code:\n\n```\nimport json\nfrom google.cloud import bigquery\nbigquery_client = bigquery.Client()\n\n@router.get('/report')\nasync def report(request: Request):\n response = get_clicks_impression(bigquery_client, source_id)\n return response\n\ndef get_user(client, source_id):\n try:\n query = \"\"\" SELECT * FROM .....\"\"\"\n job_config = bigquery.QueryJobConfig(\n query_parameters=[\n bigquery.ScalarQueryParameter(\"source_id\", \"STRING\", source_id),\n ]\n )\n query_job = client.query(query, job_config=job_config) # Wait for the job to complete.\n result = []\n for row in query_job:\n result.append(dict(row))\n json_obj = json.dumps(result, indent=4, sort_keys=True, default=str)\n\n except Exception as e:\n return str(e)\n\n return json_obj\n```\n\nThe returned data in Flask was object:\n\n```\n{\n \"User\": \"fasdf\",\n \"date\": \"2022-09-21\",\n \"count\": 205\n },\n {\n \"User\": \"abd\",\n \"date\": \"2022-09-27\",\n \"count\": 100\n }\n]\n```\n\nWhile in FastAPI was string:\n\n```\n\"[\\n {\\n \\\"User\\\": \\\"aaa\\\",\\n \\\"date\\\": \\\"2022-09-26\\\",\\n \\\"count\\\": 840,\\n]\"\n```\n\nThe reason I use `json.dumps()` is that `date` cannot be iterable.\n\n========================================\n\nTop Answer:\nHeavily based and building on @Chris answer:\n\nTL;DR:\n\nFor the first option, if you are using e.g. pandas first do e.g.:\n\n```\nJSONResponse(df.fillna(np.nan).replace([np.nan], [None]).to_dict())\n```\n\nFor the second\nsecond answer,\n**do not send extra spaces by using indent**, but do it like this:\n\n`Response(content=json_str, media_type='application/json')`\n\nReasons:\n\nThe first options fails if you try to send any nan value, even if it is one value on a long table or pandas, and so it might work now for your try, but in the future might fail (Murphy -> will fail). Fix is from here.\n\nFor the second part, any indent that is not 0 is for human consumption and will not help your code run faster. Consider modern packages even often remove the indentation of javascript for pages. If debugging is needed, indenting the message is something any computer will be happy to do for you, and your favorite piece of code will be happy to indent is with exactly as many spaces you (the observer, as opposed to the one writing the code) is comfortable with.\n\n[Answer changed based on comments. Also check comments for more. Especially if streaming.]\n\n========================================\n\nCode:\n```python\nimport json\nfrom google.cloud import bigquery\nbigquery_client = bigquery.Client()\n\n@router.get('/report')\nasync def report(request: Request):\n response = get_clicks_impression(bigquery_client, source_id)\n return response\n\ndef get_user(client, source_id):\n try:\n query = \"\"\" SELECT * FROM .....\"\"\"\n job_config = bigquery.QueryJobConfig(\n query_parameters=[\n bigquery.ScalarQueryParameter(\"source_id\", \"STRING\", source_id),\n ]\n )\n query_job = client.query(query, job_config=job_config) # Wait for the job to complete.\n result = []\n for row in query_job:\n result.append(dict(row))\n json_obj = json.dumps(result, indent=4, sort_keys=True, default=str)\n\n except Exception as e:\n return str(e)\n\n return json_obj\n```\n\n```json\n{\n \"User\": \"fasdf\",\n \"date\": \"2022-09-21\",\n \"count\": 205\n },\n {\n \"User\": \"abd\",\n \"date\": \"2022-09-27\",\n \"count\": 100\n }\n]\n```\n\n```json\n\"[\\n {\\n \\\"User\\\": \\\"aaa\\\",\\n \\\"date\\\": \\\"2022-09-26\\\",\\n \\\"count\\\": 840,\\n]\"\n```\n\n```text\njson\n```\n\n```text\njson.dumps()\n```\n\n```text\ndate\n```\n\n```py\nimport json\n\n@app.get('/user')\nasync def get_user():\n return json.dumps(some_dict, indent=4, default=str)\n```\n\n```json\n\"[\\n {\\n \\\"User\\\": \\\"aaa\\\",\\n \\\"date\\\": \\\"2022-09-26\\\",\\n ...\n```\n\n```py\nfrom datetime import date\n\n\nd = [\n {\"User\": \"a\", \"date\": date.today(), \"count\": 1},\n {\"User\": \"b\", \"date\": date.today(), \"count\": 2},\n]\n\n\n@app.get('/')\nasync def main():\n return d\n```\n\n```py\nfrom fastapi.responses import JSONResponse\nfrom fastapi.encoders import jsonable_encoder\n\n@app.get('/')\nasync def main():\n return JSONResponse(content=jsonable_encoder(d))\n```\n\n```json\n[{\"User\":\"a\",\"date\":\"2022-10-21\",\"count\":1},{\"User\":\"b\",\"date\":\"2022-10-21\",\"count\":2}]\n```\n\n```py\nfrom fastapi import Response, status\n\n@app.get('/')\nasync def main(response: Response):\n response.status_code = status.HTTP_201_CREATED # or simply = 201\n return d\n```\n\n```py\nfrom fastapi import status\nfrom fastapi.responses import JSONResponse\nfrom fastapi.encoders import jsonable_encoder\n\n@app.get('/')\nasync def main():\n return JSONResponse(content=jsonable_encoder(d), status_code=status.HTTP_201_CREATED)\n```\n\n```py\nfrom fastapi import Response\nfrom datetime import date\nimport json\n\n\nd = [\n {\"User\": \"a\", \"date\": date.today(), \"count\": 1},\n {\"User\": \"b\", \"date\": date.today(), \"count\": 2},\n]\n\n\n@app.get('/')\nasync def main():\n json_str = json.dumps(d, indent=4, default=str)\n return Response(content=json_str, media_type='application/json')\n```\n\n```json\n[\n {\n \"User\": \"a\",\n \"date\": \"2022-10-21\",\n \"count\": 1\n },\n {\n \"User\": \"b\",\n \"date\": \"2022-10-21\",\n \"count\": 2\n }\n]\n```\n\n```py\nfrom fastapi import FastAPI, Response, status\nfrom pydantic import BaseModel\n\n\nclass MyModel(BaseModel):\n msg: str\n \n\napp = FastAPI()\n\n\n@app.get('/')\nasync def main():\n m = MyModel(msg=\"test\")\n return Response(content=m.model_dump_json(), status_code=status.HTTP_201_CREATED, media_type='application/json')\n```\n\n```text\njson.dumps()\n```\n\n```text\ndict\n```\n\n```text\nlist\n```\n\n```text\nreturn some_dict\n```\n\n```text\njsonable_encoder\n```\n\n```text\njsonable_encoder\n```\n\n```text\ndatetime\n```\n\n```text\nstr\n```\n\n```text\nJSONResponse\n```\n\n```text\napplication/json\n```\n\n```text\nJSONResponse\n```\n\n```text\njson.dumps()\n```\n\n```text\ndict\n```\n\n```text\nstatus_code\n```\n\n```text\nstatus_code\n```\n\n```text\ndict\n```\n\n```text\nResponse\n```\n\n```text\nstatus_code\n```\n\n```text\nJSONResponse\n```\n\n```text\nResponse\n```\n\n```text\nResponse\n```\n\n```text\nJSONResponse\n```\n\n```text\nint\n```\n\n```text\nResponse\n```\n\n```text\nResponse\n```\n\n```text\nmedia_type\n```\n\n```text\nmedia_type\n```\n\n```text\napplication/json\n```\n\n```text\nstatus_code\n```\n\n```text\nResponse\n```\n\n```text\nJSONResponse\n```\n\n```text\nResponse(content=json_str, status_code=status.HTTP_201_CREATED, ...)\n```\n\n```text\n/docs\n```\n\n```text\napplication/json\n```\n\n```text\nmedia_type\n```\n\n```text\nResponse\n```\n\n```text\nContent-Type\n```\n\n```text\napplication/json\n```\n\n```text\ndefault\n```\n\n```text\nstr\n```\n\n```text\njson.dumps()\n```\n\n```text\ndate\n```\n\n```text\nTypeError: Object of type date is not JSON serializable\n```\n\n```text\ndefault\n```\n\n```text\nstr\n```\n\n```text\nJSONEncoder\n```\n\n```text\norjson\n```\n\n```text\njson\n```\n\n```text\nResponse\n```\n\n```text\ncontent\n```\n\n```text\nstr\n```\n\n```text\nbytes\n```\n\n```text\nbytes\n```\n\n```text\ncontent.encode(self.charset)\n```\n\n```text\ndict\n```\n\n```text\nAttributeError: 'dict' object has no attribute 'encode'\n```\n\n```text\nstr\n```\n\n```text\nbytes\n```\n\n```text\nResponse\n```\n\n```text\nreturn MyModel(msg=\"test\")\n```\n\n```text\nmodel_dump()\n```\n\n```text\ndict()\n```\n\n```text\ndict\n```\n\n```text\nMyModel(msg=\"test\").model_dump()\n```\n\n```text\nmodel_dump_json()\n```\n\n```text\njson()\n```\n\n```text\nResponse\n```\n\n```text\nasync def\n```\n\n```text\njson.dumps()\n```\n\n```text\nmodel_dump_json()\n```\n\n```text\nJSONResponse(df.fillna(np.nan).replace([np.nan], [None]).to_dict())\n```\n\n```text\nResponse(content=json_str, media_type='application/json')\n```\n\n```text\nfrom fastapi.responses import JSONResponse\n@app.get(\"/db/{jobid}\", include_in_schema=True, response_class=JSONResponse)\nasync def dbget(jobid:int):\n \"\"\" read data stored on the jobid \"\"\"\n return db.read(f\"jobid=={jobid}\")\n```\n\n```text\nresponse_class=JSONResponse\n```\n\n========================================\n\nComments:\n- You're returning a string in FastAPI, so it will return a string. Don't serialize it yourself - instead, return the object and FastAPI will serialize it for you. It should handle date/datetime just fine: fastapi.tiangolo.com/tutorial/extra-data-types\n- The json encoder does not allow `NaN` values. Thus, to use Option 1, you would have to replace `NaN` values in the `DataFrame`, using, for instance, `df = df.fillna('')`. Since you are dealing with a pandas `DataFrame`, you may want to have a look here, as well as here and here.\n- Good points, more research is needed to see which solution is best... (especially when streaming, on your 3rd link)... I am now uncertain which option is best\n- This answer is incorrect. The default `response_calss` is `JSONResponse`, regardless. Please have a look at the accepted answer above for more details.\n- @chris added a screenshot showing this works just fine. It is strongly discourage to not explicitly set response_class\n- I am afraid you are mistaken. Straight from the documentation: *\"**By default**, FastAPI will return the responses using `JSONResponse`\"*. Again, please take a closer look at the accepted answer. Also, please avoid posting images of code, data, response messages, etc. - instead, copy or type the text into the answer (see here for more details).","metadata":{"transformedAt":"2026-08-18T18:32:29.092Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":90,"totalLines":570,"estimatedTokens":2372}}69{"id":"stack-66632841","source":"stackoverflow","questionId":66632841,"title":"FastAPI dependency vs middleware","tags":["python","fastapi"],"text":"Title: FastAPI dependency vs middleware\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am new to FastAPI . I have worked with multiple web frameworks in other languages and found the common pattern of middlewares for various purposes. e.g. If I have an API route that I want to authenticate then I would use a middleware that does the authentication. If I want to augment the incoming request I would use a middleware. FastAPI does have middlewares (A very small section in docs) but also has dependencies. I was looking to authenticate my API routes and started looking for examples and all the examples I find use dependencies. What (dependency or middleware) would be recommended way to authenticate an API route and why?\n\n========================================\n\nTop Answer:\nIn a general sense, the answer given by @lsabi is correct.\n\nIn the context of FastAPI though, there's no way of defining a middleware on a particular API router (as of Aug 2022).\n\nAll the middlewares are usually on global app level (though you can write your own logic to apply it on only a specific route by regex/filtering, not very clean solution imo), and if that's the only way you want to go, you have to create a separate application for each route (using mounts), and then you can write their own middlewares, as explained here:\nhttps://github.com/tiangolo/fastapi/issues/1174#issuecomment-605508353\n\nBut for route dependencies, this statement isn't entirely true:\n\nThe middleware can be seen as a superset of a Dependency\n\nEven though, dependencies by defination don't reject/forward stuff, In FastAPI, you can always raise an exception (might be HTTPException) from a dependency which will cause it to reject the request, before it reaches to the route handler.\n\nso you can do something like:\n\n```\nasync def auth_middleware(request: Request):\n # your code to check if user is authenticated\n # ...\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Not authenticated bruh\"\n )\n\nrouter = APIRouter(dependencies=[Depends(auth_middleware)])\n```\n\nnow, before executing any route handler defined on the **router**, first it will run the **auth_middleware** function. Which is exactly how a middleware is supposed to work.\n\nThe only caveat here is that, because it's a dependency, it has to run before the route handler.\n\nSo if your use case requires you to handle something after, this wouldn't work.\nI didn't come across any such requirement, selective gzipping might be one example, but you shouldn't be gzipping your http response in python anyway.\n\nHope that helps!\n\n========================================\n\nCode:\n```text\nDependency\n```\n\n```text\nMiddleware\n```\n\n```text\nDependency\n```\n\n```text\nDependency\n```\n\n```text\nMiddleware\n```\n\n```text\nasync def auth_middleware(request: Request):\n # your code to check if user is authenticated\n # ...\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Not authenticated bruh\"\n )\n\nrouter = APIRouter(dependencies=[Depends(auth_middleware)])\n```\n\n========================================\n\nComments:\n- If user session/state is not needed and only a fixed api key or an auth token, is it ok to use middleware to reject request on invalid key?\n- @27px I would use a dependency, since I guess that the api key or auth token will hold a user id or something. Also, it's much simpler to reject or pass forward in a `Dependency` rather than in the middleware. I would use the middleware for logging, although one has to pay attention on not exposing tokens/keys\n- Which one will be executed first (Either middleware or Dependencies)?\n- @BennisonJ `Middleware` then `Dependency` (assuming the `middleware` doesn't block/deny the request). Thus you may use the `middleware` as a rate limiter, logger, DOS checker and so on, both before and after the request has been fulfilled. It's kinda like `pre` and `post` triggers in a database\n- One example is custom access logging, where you want to / need to write the log line *after* completion of the request (whether it succeeded or failed).","metadata":{"transformedAt":"2026-08-18T18:32:29.092Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":6,"totalLines":89,"estimatedTokens":1022}}70{"id":"stack-75714883","source":"stackoverflow","questionId":75714883,"title":"How to test a FastAPI endpoint that uses lifespan function?","tags":["python","testing","fastapi"],"text":"Title: How to test a FastAPI endpoint that uses lifespan function?\nTags: python, testing, fastapi\nSource: Stack Overflow\n\nQuestion:\nCould someone tell me how I can test an endpoint that uses the new lifespan feature from FastAPI?\n\nI am trying to set up tests for my endpoints that use resources from the lifespan function, but the test failed since the dict I set up in the lifespan function is not passed to the TestClient as part of the FastAPI app.\n\nMy API looks as follows.\n\n```\nfrom fastapi import FastAPI\nfrom contextlib import asynccontextmanager\n\nml_model = {}\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI):\n predictor = Predictor(model_version)\n ml_model[\"predict\"] = predictor.predict_from_features\n yield\n # Clean up the ML models and release the resources\n ml_model.clear()\n\napp = FastAPI(lifespan=lifespan)\n\n@app.get(\"/prediction/\")\nasync def get_prediction(model_input: str):\n prediction = ml_model[\"predict\"](model_input)\n return prediction\n```\n\nAnd the test code for the `/prediction` endpoint looks as follows:\n\n```\nfrom fastapi.testclient import TestClient\n\nfrom app.main import app\n\nclient = TestClient(app)\n\ndef test_read_prediction():\n model_input= \"test\"\n response = client.get(f\"/prediction/?model_input={model_input}\")\n assert response.status_code == 200\n```\n\nThe test failed with an error message saying\n`KeyError: 'predict'`, which shows that the `ml_models` dict was not passed with the app object. I also tried using `app.state.ml_models = {}`, but that didn't work either. I would appreciate any help!\n\n========================================\n\nTop Answer:\nTry importing lifespan instead of passing in `FASTApi` as you can give `startup` and `shutdown` in `testClient`\n\n```\nfrom app.main import app, lifespan\n\nclient = TestClient(app, startup=lifespan, shutdown=lifespan)\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nfrom contextlib import asynccontextmanager\n\nml_model = {}\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI):\n predictor = Predictor(model_version)\n ml_model[\"predict\"] = predictor.predict_from_features\n yield\n # Clean up the ML models and release the resources\n ml_model.clear()\n\n\napp = FastAPI(lifespan=lifespan)\n\n@app.get(\"/prediction/\")\nasync def get_prediction(model_input: str):\n prediction = ml_model[\"predict\"](model_input)\n return prediction\n```\n\n```text\nfrom fastapi.testclient import TestClient\n\nfrom app.main import app\n\nclient = TestClient(app)\n\ndef test_read_prediction():\n model_input= \"test\"\n response = client.get(f\"/prediction/?model_input={model_input}\")\n assert response.status_code == 200\n```\n\n```text\n/prediction\n```\n\n```text\nKeyError: 'predict'\n```\n\n```text\nml_models\n```\n\n```text\napp.state.ml_models = {}\n```\n\n```py\nfrom fastapi.testclient import TestClient\n\nfrom app.main import app\n\ndef test_read_prediction():\n with TestClient(app) as client:\n model_input= \"test\"\n response = client.get(f\"/prediction/?model_input={model_input}\")\n assert response.status_code == 200\n```\n\n```text\nTestClient\n```\n\n```text\nfrom app.main import app, lifespan\n\nclient = TestClient(app, startup=lifespan, shutdown=lifespan)\n```\n\n```text\nFASTApi\n```\n\n```text\nstartup\n```\n\n```text\nshutdown\n```\n\n```text\ntestClient\n```\n\n```text\n--lifespan on\n```\n\n========================================\n\nComments:\n- Quality answer! Thanks a lot 🙏\n- The function `get_prediction` is asynchronous. So why does using `TestClient` work? Is it not the case that `TestClient` is for testing of synchronous paths?","metadata":{"transformedAt":"2026-08-18T18:32:29.092Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":14,"totalLines":164,"estimatedTokens":888}}71{"id":"stack-63492123","source":"stackoverflow","questionId":63492123,"title":"How do add an assembled field to a Pydantic model","tags":["python","fastapi","pydantic"],"text":"Title: How do add an assembled field to a Pydantic model\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nSay I have model\n\n```\nclass UserDB(BaseModel):\n first_name: Optional[str] = None\n last_name: Optional[str] = None\n```\n\nHow do I make another model that is constructed from this one and has a field that changes based on the fields in this model?\n\nFor instance, something like this\n\n```\nclass User(BaseModel):\n full_name: str = first_name + ' ' + last_name\n```\n\nConstructed like this maybe\n\n```\nUser.parse_obj(UserDB)\n```\n\nThanks!\n\n========================================\n\nTop Answer:\nPlease use at least `pydantic>=2.0`. Then you could use `computed_field` from pydantic.\n\n```\nfrom pydantic import BaseModel, computed_field\n\nclass UserDB(BaseModel):\n first_name: Optional[str] = None\n last_name: Optional[str] = None\n\n @computed_field\n def full_name(self) -> str:\n return f\"{self.first_name} {self.last_name}\"\n```\n\nThen you should get:\n\n```\nprint(UserDB(first_name=\"John\", last_name=\"Doe\").model_dump())\n#> {'first_name': 'John, 'last_name': 'Doe', 'full_name': 'John Doe'}\n```\n\n========================================\n\nCode:\n```text\nclass UserDB(BaseModel):\n first_name: Optional[str] = None\n last_name: Optional[str] = None\n```\n\n```text\nclass User(BaseModel):\n full_name: str = first_name + ' ' + last_name\n```\n\n```text\nUser.parse_obj(UserDB)\n```\n\n```py\nfrom typing import Optional\nfrom pydantic import BaseModel, validator\n\n\nclass UserDB(BaseModel):\n first_name: Optional[str] = None\n last_name: Optional[str] = None\n\n\nclass User_1(BaseModel):\n location: str # for a change\n full_name: Optional[str] = None\n\n def __init__(self, user_db: UserDB, **data):\n super().__init__(full_name=f\"{user_db.first_name} {user_db.last_name}\", **data)\n\n\nuser_db = UserDB(first_name=\"John\", last_name=\"Stark\")\nuser = User_1(user_db, location=\"Mars\")\nprint(user)\n\n\nclass User_2(BaseModel):\n first_name: Optional[str] = None\n last_name: Optional[str] = None\n full_name: Optional[str] = None\n\n @validator('full_name', always=True)\n def ab(cls, v, values) -> str:\n return f\"{values['first_name']} {values['last_name']}\"\n\n\nuser = User_2(**user_db.dict())\nprint(user)\n```\n\n```text\nlocation='Mars' full_name='John Stark'\nfirst_name='John' last_name='Stark' full_name='John Stark'\n```\n\n```text\nclass User_1(BaseModel):\n location: str # for a change\n full_name: Optional[str] = None\n\n # def __init__(self, user_db: UserDB, **data):\n def __init__(self, first_name, last_name, **data):\n super().__init__(full_name=f\"{first_name} {last_name}\", **data)\n\n\nuser_db = UserDB(first_name=\"John\", last_name=\"Stark\")\nuser = User_1(**user_db.dict(), location=\"Mars\")\nprint(user)\n```\n\n```text\nfirst_name\n```\n\n```text\nlast_name\n```\n\n```text\nUser\n```\n\n```text\n__init__\n```\n\n```text\nfull_name\n```\n\n```text\nresponse_model\n```\n\n```text\n__init__\n```\n\n```python\nfrom pydantic import BaseModel\nfrom pydantic_computed import Computed, computed\n\nclass UserDB(BaseModel):\n first_name: Optional[str] = None\n last_name: Optional[str] = None\n\nclass User(UserDB):\n full_name: Computed[str]\n\n @computed(\"full_name\")\n def compute_full_name(first_name: str, last_name: str):\n return f\"{first_name} {last_name}\"\n\n\n# parsing also works as normal:\nuser_db = UserDB(first_name=\"John\", last_name=\"Doe\")\nuser = User.parse_obj(user_db)\nprint(user.full_name) # Outputs \"John Doe\"\n```\n\n```text\nfrom pydantic import BaseModel, computed_field\n\n\nclass UserDB(BaseModel):\n first_name: Optional[str] = None\n last_name: Optional[str] = None\n\n @computed_field\n def full_name(self) -> str:\n return f\"{self.first_name} {self.last_name}\"\n```\n\n```text\nprint(UserDB(first_name=\"John\", last_name=\"Doe\").model_dump())\n#> {'first_name': 'John, 'last_name': 'Doe', 'full_name': 'John Doe'}\n```\n\n```text\npydantic>=2.0\n```\n\n```text\ncomputed_field\n```\n\n========================================\n\nComments:\n- Future readers might find this answer helpful as well.\n- This works under normal conditions, thanks! For bonus points, do you happen to know how to get this to work with the fastapi response_model? If I just return the db model with the response model set to the api model, it throws `pydantic.error_wrappers.ValidationError: 1 validation error for User response __init__() missing 1 required positional argument: 'user_db' (type=type_error)`\n- I'm using the 2nd approach in my project, but i've always felt that using a validator to set a property just seems ...dirty. I also played around with adding @property but then it gets excluded from `.dict()` method\n- is there any decorator by pydentic instead of using other package?\n- @mdhv_kothari See my solution: stackoverflow.com/a/76812041/5507055.\n- This should be the accepted top answer now.","metadata":{"transformedAt":"2026-08-18T18:32:29.092Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":18,"totalLines":214,"estimatedTokens":1204}}72{"id":"stack-64588486","source":"stackoverflow","questionId":64588486,"title":"Address already in use - FastAPI","tags":["python","linux","ip","port","fastapi"],"text":"Title: Address already in use - FastAPI\nTags: python, linux, ip, port, fastapi\nSource: Stack Overflow\n\nQuestion:\nI keep getting `[Errno 98] Address already in use` But the address is not in use.\nI tried to change the ip and port but It isn't budging.\n\n```\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/\")\nasync def main():\nreturn {\"message\": \"Helloworld,FastAPI\"}\n\nif __name__ == '__main__':\nimport uvicorn\nuvicorn.run(app, host=\"127.0.0.1\", port=8000)\n```\n\n`uvicorn main:app --reload`\nalso tried `uvicorn main:app --host=172.0.0.2 --port=5000`\nthen it gives `[Errno 99] error while attempting to bind on address ('172.0.0.2', 5000): cannot assign requested address`\nI tried running a flask dev server and it was also running on 172.0.0.1 without a problem?\n\nusing Arch-Manjaro-Linux\n\nI used nmap to see what the fuss was about.\n\nBut only 2 ports in use on the 127.0.0.1 IP\n\n```\nPORT STATE SERVICE\n631/tcp open ipp\n8000/tcp open http-alt\n```\n\nI would use another IP and port but it gives an error that it can't be assigned.\n\n========================================\n\nTop Answer:\nIf port 8000 is being used, you can сhange the port you are using, for example to port 8080:\n\n```\nuvicorn.run(app, host=\"127.0.0.1\", port=8080)\n```\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n\n@app.get(\"/\")\nasync def main():\nreturn {\"message\": \"Helloworld,FastAPI\"}\n\n\nif __name__ == '__main__':\nimport uvicorn\nuvicorn.run(app, host=\"127.0.0.1\", port=8000)\n```\n\n```text\nPORT STATE SERVICE\n631/tcp open ipp\n8000/tcp open http-alt\n```\n\n```text\n[Errno 98] Address already in use\n```\n\n```text\nuvicorn main:app --reload\n```\n\n```text\nuvicorn main:app --host=172.0.0.2 --port=5000\n```\n\n```text\n[Errno 99] error while attempting to bind on address ('172.0.0.2', 5000): cannot assign requested address\n```\n\n```text\nsudo lsof -t -i tcp:8000 | xargs kill -9\n```\n\n```py\nuvicorn.run(app, host=\"127.0.0.1\", port=8080)\n```\n\n========================================\n\nComments:\n- Run ss -lnp | grep 5000 to see the process holding the port.\n- it does not return anything. it happens with all ports and IP's. I tried running flask and I don't get this error when running on 127.0.0.1, 5000, 3000, 8000\n- Yeah, it depends on the OS you are using, are you on a Unix like OS ? @RajathRao","metadata":{"transformedAt":"2026-08-18T18:32:29.092Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":8,"totalLines":105,"estimatedTokens":580}}73{"id":"stack-67569529","source":"stackoverflow","questionId":67569529,"title":"Using FastAPI & Pydantic, how do I define an Optional field with a description","tags":["python","fastapi","pydantic"],"text":"Title: Using FastAPI & Pydantic, how do I define an Optional field with a description\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nFor a FastAPI Pydanctic class I have these values\n\n```\nclass ErrorReportRequest(BaseModel):\n sender: Optional[str] = Field(..., description=\"Who sends the error message.\")\n error_message_displayed_to_client: str = Field(..., description=\"The error message displayed to the client.\")\n```\n\nI use the class as an input model\n\n```\nrouter = APIRouter()\n\n@router.post(\n \"/error_report\",\n response_model=None,\n include_in_schema=True,\n\n)\ndef error_report(err: ErrorReportRequest):\n pass\n```\n\nWhen I run this, `sender` is a required field. If it's not included in the incoming JSON, I get a validation error.\n\nInput:\n\n```\n{\n \"error_message_displayed_to_client\": \"string\"\n}\n```\n\nResults in:\n\n```\n{\n \"detail\": [\n {\n \"loc\": [\n \"body\",\n \"sender\"\n ],\n \"msg\": \"field required\",\n \"type\": \"value_error.missing\"\n }\n ]\n}\n```\n\nIf I remove the Field description like this:\n\n```\nclass ErrorReportRequest(BaseModel):\n sender: Optional[str]\n error_message_displayed_to_client: str = Field(..., description=\"The error message displayed to the client.\")\n```\n\nthe request passes.\n\nHow can I add a Field description to an optional field so that it's still allowed to omit the field name?\n\n========================================\n\nCode:\n```text\nclass ErrorReportRequest(BaseModel):\n sender: Optional[str] = Field(..., description=\"Who sends the error message.\")\n error_message_displayed_to_client: str = Field(..., description=\"The error message displayed to the client.\")\n```\n\n```text\nrouter = APIRouter()\n\n@router.post(\n \"/error_report\",\n response_model=None,\n include_in_schema=True,\n\n)\ndef error_report(err: ErrorReportRequest):\n pass\n```\n\n```text\n{\n \"error_message_displayed_to_client\": \"string\"\n}\n```\n\n```text\n{\n \"detail\": [\n {\n \"loc\": [\n \"body\",\n \"sender\"\n ],\n \"msg\": \"field required\",\n \"type\": \"value_error.missing\"\n }\n ]\n}\n```\n\n```text\nclass ErrorReportRequest(BaseModel):\n sender: Optional[str]\n error_message_displayed_to_client: str = Field(..., description=\"The error message displayed to the client.\")\n```\n\n```text\nsender\n```\n\n```py\nclass ErrorReportRequest(BaseModel):\n sender: Optional[str] = Field(None, description=\"Who sends the error message.\")\n error_message_displayed_to_client: str = Field(..., description=\"The error message displayed to the client.\")\n```\n\n```text\nField\n```\n\n```text\nNone\n```\n\n```text\n...\n```\n\n```text\n...\n```\n\n```text\nOptional\n```\n\n```text\n...\n```\n\n```text\nField\n```\n\n```text\ndefault\n```\n\n```text\nField\n```\n\n```text\n...\n```\n\n========================================\n\nComments:\n- thanks for saving me from sandtrap #427 for fastapi/pydantic/typehints noobs that isn't made clear by docs/books/tutorials (this has been a frustrating experience)\n- also, that still leaves the problem of how to tell the difference between clients leaving the field out and clients explicitly setting the field to None\n- @odigity this answer might help with that: stackoverflow.com/a/66231175/5768147","metadata":{"transformedAt":"2026-08-18T18:32:29.092Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":17,"totalLines":172,"estimatedTokens":782}}74{"id":"stack-64901945","source":"stackoverflow","questionId":64901945,"title":"How to send a progress of operation in a FastAPI app?","tags":["python","python-3.x","fastapi","uvicorn"],"text":"Title: How to send a progress of operation in a FastAPI app?\nTags: python, python-3.x, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI have deployed a fastapi endpoint,\n\n```\nfrom fastapi import FastAPI, UploadFile\nfrom typing import List\n\napp = FastAPI()\n\n@app.post('/work/test')\nasync def testing(files: List(UploadFile)):\n for i in files:\n .......\n # do a lot of operations on each file\n\n # after than I am just writing that processed data into mysql database\n # cur.execute(...)\n # cur.commit()\n .......\n \n # just returning \"OK\" to confirm data is written into mysql\n return {\"response\" : \"OK\"}\n```\n\nI can request output from the API endpoint and its working fine for me perfectly.\n\nNow, the biggest challenge for me to know how much time it is taking for each iteration. Because in the UI part (those who are accessing my API endpoint) I want to help them show a progress bar (TIME TAKEN) for each iteration/file being processed.\n\nIs there any possible way for me to achieve it? If so, please help me out on how can I proceed further?\n\nThank you.\n\n========================================\n\nTop Answer:\n### Approaches\n\n### Polling\n\nThe most preferred approach to track the progress of a task is polling:\n\nAfter receiving a `request` to start a task on a backend:\n\n- Create a `task object` in the storage (e.g in-memory, `redis` and etc.). The `task object` must contain the following data: `task ID`, `status` (pending, completed), `result`, and others.\n\n- Run task in the background (coroutines, threading, multiprocessing, task queue like `Celery`, `arq`, `aio-pika`, `dramatiq` and etc.)\n\n- Response immediately the answer `202 (Accepted)` by returning the previously received `task ID`.\n\nUpdate task status:\n\n- This can be from within the task itself, if it knows about the task store and has access to it. Periodically, the task itself updates information about itself.\n\n- Or use a task monitor (`Observer`, `producer-consumer` pattern), which will monitor the status of the task and its result. And it will also update the information in the storage.\n\n- On the `client side` (`front-end`) start a *polling cycle* for the task status to endpoint `/task/{ID}/status`, which takes information from the task storage.\n\n### Streaming response\n\nStreaming is a less convenient way of getting the status of request processing periodically. When we gradually push responses without closing the connection. It has a number of significant disadvantages, for example, if the connection is broken, you can lose information. Streaming Api is another approach than REST Api.\n\n### Websockets\n\nYou can also use websockets for real-time notifications and bidirectional communication.\n\n### Links:\n\n- Examples of polling approach for the progress bar and a more detailed description for `django + celery` can be found at these links:\n\nhttps://www.dangtrinh.com/2013/07/django-celery-display-progress-bar-of.html\n\nhttps://buildwithdjango.com/blog/post/celery-progress-bars/\n\n- I have provided simplified examples of running background tasks in FastAPI using multiprocessing here:\n\nhttps://stackoverflow.com/a/63171013/13782669\n\n### Old answer:\n\nYou could run a task in the background, return its `id` and provide a `/status` endpoint that the front would periodically call. In the status response, you could return what state your task is now (for example, pending with the number of the currently processed file). I provided a few simple examples here.\n\n### Demo\n\n### Polling\n\nDemo of the approach using asyncio tasks (single worker solution):\n\n```\nimport asyncio\nfrom http import HTTPStatus\nfrom fastapi import BackgroundTasks\nfrom typing import Dict, List\nfrom uuid import UUID, uuid4\nimport uvicorn\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel, Field\n\nclass Job(BaseModel):\n uid: UUID = Field(default_factory=uuid4)\n status: str = \"in_progress\"\n progress: int = 0\n result: int = None\n\napp = FastAPI()\njobs: Dict[UUID, Job] = {} # Dict as job storage\n\nasync def long_task(queue: asyncio.Queue, param: int):\n for i in range(1, param): # do work and return our progress\n await asyncio.sleep(1)\n await queue.put(i)\n await queue.put(None)\n\nasync def start_new_task(uid: UUID, param: int) -> None:\n\n queue = asyncio.Queue()\n task = asyncio.create_task(long_task(queue, param))\n\n while progress := await queue.get(): # monitor task progress\n jobs[uid].progress = progress\n\n jobs[uid].status = \"complete\"\n\n@app.post(\"/new_task/{param}\", status_code=HTTPStatus.ACCEPTED)\nasync def task_handler(background_tasks: BackgroundTasks, param: int):\n new_task = Job()\n jobs[new_task.uid] = new_task\n background_tasks.add_task(start_new_task, new_task.uid, param)\n return new_task\n\n@app.get(\"/task/{uid}/status\")\nasync def status_handler(uid: UUID):\n return jobs[uid]\n```\n\n### Adapted example for loop from question\n\nBackground processing function is defined as `def` and FastAPI runs it on the thread pool.\n\n```\nimport time\nfrom http import HTTPStatus\n\nfrom fastapi import BackgroundTasks, UploadFile, File\nfrom typing import Dict, List\nfrom uuid import UUID, uuid4\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel, Field\n\nclass Job(BaseModel):\n uid: UUID = Field(default_factory=uuid4)\n status: str = \"in_progress\"\n processed_files: List[str] = Field(default_factory=list)\n\napp = FastAPI()\njobs: Dict[UUID, Job] = {}\n\ndef process_files(task_id: UUID, files: List[UploadFile]):\n for i in files:\n time.sleep(5) # pretend long task\n # ...\n # do a lot of operations on each file\n # then append the processed file to a list\n # ...\n jobs[task_id].processed_files.append(i.filename)\n jobs[task_id].status = \"completed\"\n\n@app.post('/work/test', status_code=HTTPStatus.ACCEPTED)\nasync def work(background_tasks: BackgroundTasks, files: List[UploadFile] = File(...)):\n new_task = Job()\n jobs[new_task.uid] = new_task\n background_tasks.add_task(process_files, new_task.uid, files)\n return new_task\n\n@app.get(\"/work/{uid}/status\")\nasync def status_handler(uid: UUID):\n return jobs[uid]\n```\n\n### Streaming\n\n```\nasync def process_files_gen(files: List[UploadFile]):\n for i in files:\n time.sleep(5) # pretend long task\n # ...\n # do a lot of operations on each file\n # then append the processed file to a list\n # ...\n yield f\"{i.filename} processed\\n\"\n yield f\"OK\\n\"\n\n@app.post('/work/stream/test', status_code=HTTPStatus.ACCEPTED)\nasync def work(files: List[UploadFile] = File(...)):\n return StreamingResponse(process_files_gen(files))\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI, UploadFile\nfrom typing import List\n\napp = FastAPI()\n\n@app.post('/work/test')\nasync def testing(files: List(UploadFile)):\n for i in files:\n .......\n # do a lot of operations on each file\n\n # after than I am just writing that processed data into mysql database\n # cur.execute(...)\n # cur.commit()\n .......\n \n # just returning \"OK\" to confirm data is written into mysql\n return {\"response\" : \"OK\"}\n```\n\n```text\nfrom fastapi import FastAPI, UploadFile\nimport uuid\nfrom typing import List\n\n\nimport asyncio\n\n\ncontext = {'jobs': {}}\n\napp = FastAPI()\n\n\n\nasync def do_work(job_key, files=None):\n iter_over = files if files else range(100)\n for file, file_number in enumerate(iter_over):\n jobs = context['jobs']\n job_info = jobs[job_key]\n job_info['iteration'] = file_number\n job_info['status'] = 'inprogress'\n await asyncio.sleep(1)\n pending_jobs[job_key]['status'] = 'done'\n\n\n@app.post('/work/test')\nasync def testing(files: List[UploadFile]):\n identifier = str(uuid.uuid4())\n context[jobs][identifier] = {}\n asyncio.run_coroutine_threadsafe(do_work(identifier, files), loop=asyncio.get_running_loop())\n\n return {\"identifier\": identifier}\n\n\n@app.get('/')\nasync def get_testing():\n identifier = str(uuid.uuid4())\n context['jobs'][identifier] = {}\n asyncio.run_coroutine_threadsafe(do_work(identifier), loop=asyncio.get_running_loop())\n\n return {\"identifier\": identifier}\n\n@app.get('/status')\ndef status():\n return {\n 'all': list(context['jobs'].values()),\n }\n\n@app.get('/status/{identifier}')\nasync def status(identifier):\n return {\n \"status\": context['jobs'].get(identifier, 'job with that identifier is undefined'),\n }\n```\n\n```text\nmain.py\n```\n\n```text\nuvicorn main:app --reload\n```\n\n```text\nhttp://127.0.0.1:8000/\n```\n\n```text\nhttp://127.0.0.1/status\n```\n\n```text\nhttp://127.0.0.1/status/{identifier}\n```\n\n```text\nimport asyncio\nfrom http import HTTPStatus\nfrom fastapi import BackgroundTasks\nfrom typing import Dict, List\nfrom uuid import UUID, uuid4\nimport uvicorn\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel, Field\n\n\nclass Job(BaseModel):\n uid: UUID = Field(default_factory=uuid4)\n status: str = \"in_progress\"\n progress: int = 0\n result: int = None\n\n\napp = FastAPI()\njobs: Dict[UUID, Job] = {} # Dict as job storage\n\n\nasync def long_task(queue: asyncio.Queue, param: int):\n for i in range(1, param): # do work and return our progress\n await asyncio.sleep(1)\n await queue.put(i)\n await queue.put(None)\n\n\nasync def start_new_task(uid: UUID, param: int) -> None:\n\n queue = asyncio.Queue()\n task = asyncio.create_task(long_task(queue, param))\n\n while progress := await queue.get(): # monitor task progress\n jobs[uid].progress = progress\n\n jobs[uid].status = \"complete\"\n\n\n@app.post(\"/new_task/{param}\", status_code=HTTPStatus.ACCEPTED)\nasync def task_handler(background_tasks: BackgroundTasks, param: int):\n new_task = Job()\n jobs[new_task.uid] = new_task\n background_tasks.add_task(start_new_task, new_task.uid, param)\n return new_task\n\n\n@app.get(\"/task/{uid}/status\")\nasync def status_handler(uid: UUID):\n return jobs[uid]\n```\n\n```text\nimport time\nfrom http import HTTPStatus\n\nfrom fastapi import BackgroundTasks, UploadFile, File\nfrom typing import Dict, List\nfrom uuid import UUID, uuid4\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel, Field\n\n\nclass Job(BaseModel):\n uid: UUID = Field(default_factory=uuid4)\n status: str = \"in_progress\"\n processed_files: List[str] = Field(default_factory=list)\n\n\napp = FastAPI()\njobs: Dict[UUID, Job] = {}\n\n\ndef process_files(task_id: UUID, files: List[UploadFile]):\n for i in files:\n time.sleep(5) # pretend long task\n # ...\n # do a lot of operations on each file\n # then append the processed file to a list\n # ...\n jobs[task_id].processed_files.append(i.filename)\n jobs[task_id].status = \"completed\"\n\n\n@app.post('/work/test', status_code=HTTPStatus.ACCEPTED)\nasync def work(background_tasks: BackgroundTasks, files: List[UploadFile] = File(...)):\n new_task = Job()\n jobs[new_task.uid] = new_task\n background_tasks.add_task(process_files, new_task.uid, files)\n return new_task\n\n\n@app.get(\"/work/{uid}/status\")\nasync def status_handler(uid: UUID):\n return jobs[uid]\n```\n\n```py\nasync def process_files_gen(files: List[UploadFile]):\n for i in files:\n time.sleep(5) # pretend long task\n # ...\n # do a lot of operations on each file\n # then append the processed file to a list\n # ...\n yield f\"{i.filename} processed\\n\"\n yield f\"OK\\n\"\n\n\n@app.post('/work/stream/test', status_code=HTTPStatus.ACCEPTED)\nasync def work(files: List[UploadFile] = File(...)):\n return StreamingResponse(process_files_gen(files))\n```\n\n```text\nrequest\n```\n\n```text\ntask object\n```\n\n```text\nredis\n```\n\n```text\ntask object\n```\n\n```text\ntask ID\n```\n\n```text\nstatus\n```\n\n```text\nresult\n```\n\n```text\nCelery\n```\n\n```text\narq\n```\n\n```text\naio-pika\n```\n\n```text\ndramatiq\n```\n\n```text\n202 (Accepted)\n```\n\n```text\ntask ID\n```\n\n```text\nObserver\n```\n\n```text\nproducer-consumer\n```\n\n```text\nclient side\n```\n\n```text\nfront-end\n```\n\n```text\n/task/{ID}/status\n```\n\n```text\ndjango + celery\n```\n\n```text\nid\n```\n\n```text\n/status\n```\n\n```text\ndef\n```\n\n========================================\n\nComments:\n- do you have access to UI code ?\n- No actually, I don't have access to UI code. I just want to provide some indication of each file being processed behind the scenes which they can access. Just some basic indication. Nothing to complicated. Currently, they can only get the final response after processing all files. so no way to provide some indication.\n- is that fine to provide separate url to get the status of processing ?\n- Yes, its totally fine. I tried using web-socket and all but I was not able to figure it out.\n- no need for web sockets, you can work that out with other approaches, does answers below answer your question (if no I can give it a look )?\n- I tried one of the approach given below but couldn't make it work for my code. I am looking for other approaches. Please feel free to post your approach it would help a lot.\n- how many threads and processes in use by the application ?\n- you can give it a shot :)\n- If I use `joblib` library to run my loop on multiple processor then will the below approach work for me?\n- no, you will need database which holds jobs and the job status shall query database to view it's status\n- okay, I'll try the approach below and will let you know if it works out for me. Thank you\n- sure, the async web servers is pretty powerful, so I bet single web server thread could handle plenty of items, if that's for prototype than it's more than enough :) Have a nice weekend man !\n- How to extend the Old Answer Demo Polling Example to multiple workers and servers?\n- Soln to my comment above: One solution to deploy the app using uvicorn with multiple workers is to create task_id as a string combination of uuid4 and pid.\n- Instead of worker-local dictionary you can use shared storage like database or in-memory storage. Related topic stackoverflow.com/questions/65686318/…\n- This seems to be working for me on single worker. Thank you! If you have some free time can you point out how can I parallelize the for loop inside the do_work function? I want to use something like joblib or something similar to parallelize the for loop. I have asked the question here\n- you can create `async def` which handles input from every iteration and store the future objects in a list, than call async io gather: docs.python.org/3/library/asyncio-task.html#asyncio.gather, outside of the for loop. You can try by own, I can provide some sample once I have time for this ;)\n- Thank you so much. I am not very familiar with async io operations, but I will try and please when you have some time, please try to tackle the question here, stackoverflow.com/questions/65132243/…\n- If you have some time, please try to help me out. I have been trying to find a way but failed, if you are familiar with a way using which I can parallelize the for loop and also being able to track the iteration? Here is the bounty question link : stackoverflow.com/questions/65132243/…\n- @user_12 sure, i will take a look on it :)\n- pending_jobs variable is undefined and the status isn't reached 100. Please guide.","metadata":{"transformedAt":"2026-08-18T18:32:29.093Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":32,"totalLines":527,"estimatedTokens":3755}}75{"id":"stack-64501193","source":"stackoverflow","questionId":64501193,"title":"FastAPI - How to use HTTPException in responses?","tags":["python","fastapi","starlette"],"text":"Title: FastAPI - How to use HTTPException in responses?\nTags: python, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nThe documentation suggests raising an HTTPException with client errors, which is great.\nBut how can I show those specific errors in the documentation following HTTPException's model? Meaning a dict with the \"detail\" key.\n\nThe following does not work because HTTPException is not a Pydantic model.\n\n```\n@app.get(\n '/test', \n responses={\n 409 : {\n 'model' : HTTPException, \n 'description': 'This endpoint always raises an error'\n }\n }\n)\ndef raises_error():\n raise HTTPException(409, detail='Error raised')\n```\n\n========================================\n\nCode:\n```text\n@app.get(\n '/test', \n responses={\n 409 : {\n 'model' : HTTPException, \n 'description': 'This endpoint always raises an error'\n }\n }\n)\ndef raises_error():\n raise HTTPException(409, detail='Error raised')\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.exceptions import HTTPException\nfrom pydantic import BaseModel\n\n\nclass Dummy(BaseModel):\n name: str\n\n\nclass HTTPError(BaseModel):\n detail: str\n\n class Config:\n schema_extra = {\n \"example\": {\"detail\": \"HTTPException raised.\"},\n }\n\n\napp = FastAPI()\n\n\n@app.get(\n \"/test\",\n responses={\n 200: {\"model\": Dummy},\n 409: {\n \"model\": HTTPError,\n \"description\": \"This endpoint always raises an error\",\n },\n },\n)\ndef raises_error():\n raise HTTPException(409, detail=\"Error raised\")\n```\n\n========================================\n\nComments:\n- Wouldn't an `example` do that? If not, can you show us how it would look like in the swagger doc?\n- Here an example answer: exception_handler Can this help you?\n- thanks for this, I was wondering why I couldn't get the error to show in the swagger docs. I see you need to add in the `responses:` arg.\n- for 200 status, you can use the `response_model`. Also, one note: whatever models you add in responses, FastAPI does not validate it with your actual response for that code. It's just for the swagger.","metadata":{"transformedAt":"2026-08-18T18:32:29.093Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":2,"totalLines":84,"estimatedTokens":528}}76{"id":"stack-62994795","source":"stackoverflow","questionId":62994795,"title":"How to secure fastapi API endpoint with JWT Token based authorization?","tags":["python","jwt","fastapi"],"text":"Title: How to secure fastapi API endpoint with JWT Token based authorization?\nTags: python, jwt, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am a little new to FastAPI in python. I am building an API backend framework that needs to have JWT token based authorization. Now, I know how to generate JWT tokens, but not sure how to integrate that with API methods in fast api in Python. Any pointers will be really appreciated.\n\n========================================\n\nTop Answer:\nI found certain improvements that could be made to the accepted answer:\n\n- If you choose to use the **HTTPBearer security schema**, the format of the *Authorization* header content is automatically validated, and there is no need to have a function like the one in the accepted answer, `get_token_auth_header`. Moreover, the generated docs end up being super clear and explanatory, with regards to authentication:\n\nhttps://i.sstatic.net/2jufy.png\n\n- When you decode the token, you can catch all exceptions that are descendants of the class `JOSEError`, and print their message, avoiding catching specific exceptions, and writing custom messages\n\n- Bonus: in the jwt decode method, you can specify what claims you want to ignore, given the fact you don't wanna validate them\n\nSample snippet:\nWhere ...\n\n```\n/endpoints\n - hello.py\n - __init__.p\ndependency.py\nmain.py\n```\n\n```\n# dependency.py script\nfrom jose import jwt\nfrom jose.exceptions import JOSEError\nfrom fastapi import HTTPException, Depends\nfrom fastapi.security import HTTPAuthorizationCredentials, HTTPBearer\n\nsecurity = HTTPBearer()\n\nasync def has_access(credentials: HTTPAuthorizationCredentials= Depends(security)):\n \"\"\"\n Function that is used to validate the token in the case that it requires it\n \"\"\"\n token = credentials.credentials\n\n try:\n payload = jwt.decode(token, key='secret', options={\"verify_signature\": False,\n \"verify_aud\": False,\n \"verify_iss\": False})\n print(\"payload => \", payload)\n except JOSEError as e: # catches any exception\n raise HTTPException(\n status_code=401,\n detail=str(e))\n```\n\n```\n# main.py script\nfrom fastapi import FastAPI, Depends\nfrom endpoints import hello\nfrom dependency import has_access\n\napp = FastAPI()\n\n# routes\nPROTECTED = [Depends(has_access)]\n\napp.include_router(\n hello.router,\n prefix=\"/hello\",\n dependencies=PROTECTED\n)\n```\n\n```\n# hello.py script\nfrom fastapi import APIRouter\n\nrouter = APIRouter()\n\n@router.get(\"\")\nasync def say_hi(name: str):\n return \"Hi \" + name\n```\n\nBy taking advantage of all the mentioned features, you end up building an API with security super fast :)\n\n========================================\n\nCode:\n```text\nimport json \nimport os \nimport datetime \nfrom fastapi import HTTPException, Header \nfrom urllib.request import urlopen \nfrom jose import jwt \nfrom jose import exceptions as JoseExceptions \nfrom utils import logger\n\nAUTH0_DOMAIN = os.environ.get(\n 'AUTH0_DOMAIN', 'https://<domain>/<tenant-id>/')\n\nAUTH0_ISSUER = os.environ.get(\n 'AUTO0_ISSUER', 'https://sts.windows.net/<tenant>/')\n\nAUTH0_API_AUDIENCE = os.environ.get(\n 'AUTH0_API_AUDIENCE', '<audience url>')\n\nAZURE_OPENID_CONFIG = os.environ.get(\n 'AZURE_OPENID_CONFIG', 'https://login.microsoftonline.com/common/.well-known/openid-configuration')\n\n\ndef get_token_auth_header(authorization):\n parts = authorization.split()\n\n if parts[0].lower() != \"bearer\":\n raise HTTPException(\n status_code=401, \n detail='Authorization header must start with Bearer')\n elif len(parts) == 1:\n raise HTTPException(\n status_code=401, \n detail='Authorization token not found')\n elif len(parts) > 2:\n raise HTTPException(\n status_code=401, \n detail='Authorization header be Bearer token')\n \n token = parts[1]\n return token\n\n\ndef get_payload(unverified_header, token, jwks_properties):\n try:\n payload = jwt.decode(\n token,\n key=jwks_properties[\"jwks\"],\n algorithms=jwks_properties[\"algorithms\"], # [\"RS256\"] typically\n audience=AUTH0_API_AUDIENCE,\n issuer=AUTH0_ISSUER\n )\n except jwt.ExpiredSignatureError:\n raise HTTPException(\n status_code=401, \n detail='Authorization token expired')\n except jwt.JWTClaimsError:\n raise HTTPException(\n status_code=401, \n detail='Incorrect claims, check the audience and issuer.')\n except Exception:\n raise HTTPException(\n status_code=401, \n detail='Unable to parse authentication token')\n\n return payload\n\n\nclass AzureJWKS:\n def __init__(self, openid_config: str=AZURE_OPENID_CONFIG):\n self.openid_url = openid_config\n self._jwks = None\n self._signing_algorithms = []\n self._last_updated = datetime.datetime(2000, 1, 1, 12, 0, 0)\n \n def _refresh_cache(self):\n openid_reader = urlopen(self.openid_url)\n azure_config = json.loads(openid_reader.read())\n self._signing_algorithms = azure_config[\"id_token_signing_alg_values_supported\"]\n jwks_url = azure_config[\"jwks_uri\"]\n\n jwks_reader = urlopen(jwks_url)\n self._jwks = json.loads(jwks_reader.read())\n\n logger.info(f\"Refreshed jwks config from {jwks_url}.\")\n logger.info(\"Supported token signing algorithms: {}\".format(str(self._signing_algorithms)))\n self._last_updated = datetime.datetime.now()\n\n def get_jwks(self, cache_hours: int=24):\n \n logger.info(\"jwks config is out of date (last updated at {})\".format(str(self._last_updated)))\n self._refresh_cache()\n return {'jwks': self._jwks, 'algorithms': self._signing_algorithms}\n\njwks_config = AzureJWKS()\n\n\nasync def require_auth(token: str = Header(...)):\n token = get_token_auth_header(token)\n \n\n try:\n unverified_header = jwt.get_unverified_header(token)\n except JoseExceptions.JWTError:\n raise HTTPException(\n status_code=401, \n detail='Unable to decode authorization token headers')\n\n payload = get_payload(unverified_header, token, jwks_config.get_jwks())\n if not payload:\n raise HTTPException(\n status_code=401, \n detail='Invalid authorization token')\n\n return payload\n```\n\n```text\nclass User(BaseModel):\n pass\n...\noauth2_scheme = OAuth2PasswordBearer(tokenUrl=\"token\")\n...\nasync def get_current_user(token: str = Depends(oauth2_scheme)): # You created a function that depends on oauth2_scheme\n pass\n...\n@app.get(\"/users/me/models/\")\nasync def read_own_items(current_user: User = Depends(get_current_active_user)):\n pass\n```\n\n```text\nclass Url(BaseModel):\n url: str\n\nclass AuthorizationResponse(BaseModel):\n pass\n\nclass User(BaseModel):\n pass\n\nclass AuthUser(BaseModel):\n pass\n\nclass Token(BaseModel):\n pass\n```\n\n```text\nLOGIN_URL = \"https://example.com/login/oauth/authorize\"\nREDIRECT_URL = f\"{app}/auth/app\"\n...\n@app.get(\"/login\")\ndef get_login_url() -> Url:\n return Url(url=f\"{LOGIN_URL}?{urlencode(some_params_here)}\")\n\n@app.post(\"/authorize\")\nasync def verify_authorization(body: AuthorizationResponse, db: Session = Depends(some_database_fetch)) -> Token:\n return Token(access_token=access_token, token_type=\"bearer\", user=User)\n\ndef create_access_token(*, data: User, expire_time: int = None) -> bytes:\n return encoded_jwt\n\ndef get_user_from_header(*, authorization: str = Header(None)) -> User: # from fastapi import Header\n return token_data #Token data = User(**payload)\n\n@app.get(\"/me\", response_model=User)\ndef read_profile(user: User = Depends(get_user_from_header), db: Session = Depends(some_database_fetch),) -> DbUser:\n return db_user\n```\n\n```text\nLOGIN_URL\n```\n\n```text\n/authorize\n```\n\n```text\ncreate_access_token\n```\n\n```text\nget_user_from_header\n```\n\n```text\n/endpoints\n - hello.py\n - __init__.p\ndependency.py\nmain.py\n```\n\n```py\n# dependency.py script\nfrom jose import jwt\nfrom jose.exceptions import JOSEError\nfrom fastapi import HTTPException, Depends\nfrom fastapi.security import HTTPAuthorizationCredentials, HTTPBearer\n\nsecurity = HTTPBearer()\n\nasync def has_access(credentials: HTTPAuthorizationCredentials= Depends(security)):\n \"\"\"\n Function that is used to validate the token in the case that it requires it\n \"\"\"\n token = credentials.credentials\n\n try:\n payload = jwt.decode(token, key='secret', options={\"verify_signature\": False,\n \"verify_aud\": False,\n \"verify_iss\": False})\n print(\"payload => \", payload)\n except JOSEError as e: # catches any exception\n raise HTTPException(\n status_code=401,\n detail=str(e))\n```\n\n```py\n# main.py script\nfrom fastapi import FastAPI, Depends\nfrom endpoints import hello\nfrom dependency import has_access\n\napp = FastAPI()\n\n# routes\nPROTECTED = [Depends(has_access)]\n\napp.include_router(\n hello.router,\n prefix=\"/hello\",\n dependencies=PROTECTED\n)\n```\n\n```py\n# hello.py script\nfrom fastapi import APIRouter\n\nrouter = APIRouter()\n\n@router.get(\"\")\nasync def say_hi(name: str):\n return \"Hi \" + name\n```\n\n```text\nget_token_auth_header\n```\n\n```text\nJOSEError\n```\n\n========================================\n\nComments:\n- You could just put it in the `cookies` or set it in the local storage by frontend.\n- See how it is implemented in this example app - github.com/nsidnev/fastapi-realworld-example-app :-)\n- thanks for your fast response, but I am still not sure. Just to give you more details, I am trying to generate a Microsoft AD JWT token, so I have an authority end point: login.microsoftonline.com/ and I have an AD app created with audience url - api://xxxcxxxx-abb3-yyyy-34ae-15f04ce1zzzz Now, using this, I want my Fastapi endpoints to have JWT based authorization security enabled, so that only when a valid bearer token is passed as a header to the api endpoint, only then it would given back the reponse, otherwise http 401 unauthorized.\n- thanks for your fast response, but I am still not sure. Just to give you more details, I am trying to generate a Microsoft AD JWT token, so I have an authority end point: login.microsoftonline.com/ and I have an AD app created with audience url - api://xxxcxxxx-abb3-yyyy-34ae-15f04ce1zzzz Now, using this, I want my Fastapi endpoints to have JWT based authorization security enabled, so that only when a valid bearer token is passed as a header to the api endpoint, only then it would given back the reponse, otherwise http 401 unauthorized.\n- Ah okay, i saw your answer and comment now, but this is spesific case, you may want to update the question\n- That get_token_auth_header() function looks just like the documentation from Auth0.\n- based on this answer, i've created a file on github, you guys can check and : github.com/saxsax1995/fastapi-very-first-tutorial/blob/maste‌​r/…\n- -up, how can I add a front-end framework with this auth?\n- Please don't post the same answer at multiple questions\n- Multiple questions, multiple answers\n- If you think the answers are so similar that the exact same answer matches both, please flag them accordingly","metadata":{"transformedAt":"2026-08-18T18:32:29.096Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":14,"totalLines":363,"estimatedTokens":2824}}77{"id":"stack-71113116","source":"stackoverflow","questionId":71113116,"title":"ModuleNotFoundError: No module named 'fastapi'","tags":["python","fastapi","modulenotfounderror"],"text":"Title: ModuleNotFoundError: No module named 'fastapi'\nTags: python, fastapi, modulenotfounderror\nSource: Stack Overflow\n\nQuestion:\nHere is my file structure and requirements.txt:\n\nGetting `ModuleNotFoundError`, any help will be appreciated.\n\nmain.py\n\n```\nfrom fastapi import FastAPI\nfrom .import models\nfrom .database import engine\nfrom .routers import ratings\n\nmodels.Base.metadata.create_all(bind=engine)\n\napp = FastAPI()\n\napp.include_router(ratings.router)\n```\n\n========================================\n\nTop Answer:\nI had the same problem, I uninstalled fastapi several times and then reinstalled it, but it didn't work.\nI closed and reopened vscode several times, but it didn't work.\nBut when **I closed the terminal inside VScode and created a new terminal again**, the problem was solved.\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nfrom .import models\nfrom .database import engine\nfrom .routers import ratings\n\n\nmodels.Base.metadata.create_all(bind=engine)\n\n\napp = FastAPI()\n\n\napp.include_router(ratings.router)\n```\n\n```text\nModuleNotFoundError\n```\n\n```text\nCTRL + SHIFT + P\n```\n\n```text\nPython:select interpreter\n```\n\n```text\n$ pip install \"fastapi[all]\"\n```\n\n```text\npython -m pip install fastapi uvicorn[standard]\n```\n\n========================================\n\nComments:\n- same error. fastapi is included in env. i am buildin application with microservices i have like 5 simillar projects and only this one is throwing error, i am little bit confused\n- dont work to me :/\n- Thanks for the answer. Hmm.. when i started project in another direcory everything worked properly. Should i select python enterpreter everytime i open the vscode? I think that's very repetitive\n- No, usually it is necessary to select manually when we manipulate different environments, or when deleting an environment, creating a new git repo with a new environment via the VScode terminal, etc... This is not an action to be done usually, VScode takes care of it automatically, but sometimes it is necessary to do it manually.\n- Yep, same here! Closed the current terminal and opened a new one in which the problem wasn't persisted anymore","metadata":{"transformedAt":"2026-08-18T18:32:29.096Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":6,"totalLines":78,"estimatedTokens":542}}78{"id":"stack-62928450","source":"stackoverflow","questionId":62928450,"title":"how to put backend and frontend together - returning react frontend from fastapi backend endpoint","tags":["reactjs","fastapi"],"text":"Title: how to put backend and frontend together - returning react frontend from fastapi backend endpoint\nTags: reactjs, fastapi\nSource: Stack Overflow\n\nQuestion:\nFirstly, I just wanted to say that this is my first web application project. I've spent the past few days trying to find answers on how to essentially put the frontend and backend together. I have a lot of questions, but the main one I want answered is on how to return my frontend 'final product' from a backend endpoint.\n\nThis is what I understand (please correct me if I'm wrong):\n\n- The frontend code is run by the client (browser).\n\n- When the client interacts with the webpage, the frontend makes API calls to the backend to retrieve/modify data, as necessary.\n\n- The backend and frontend is often developed separately, and *could* be hosted on separate servers.\n\n- It is, however, possible (and maybe simpler) to host it on a single domain/server. I am hoping to do this, in order to avoid a whole set of issues with CORS.\n\nThen comes the following problem:\n\nWhen I want to test out my front end and see how it's coming along, I just run `npm run start`. I then go to the given url (usually `http://localhost:8080/`) and I have access to the frontend that I've developed. And when I want to deploy it, I run `npm run build`, which gives me a `dist` folder (bundled together and minified).\n\nIf I want to run and test my backend locally, as I am using `FastAPI`, I simply run `uvicorn main:app --reload`.\n\nHow to put the two together? More specifically, in my backend code, how do I return the product of my frontend work (i.e., the `dist` folder?). I've tried the following (simplified):\n\n```\n@app.get(\"/\", response_class=HTMLResponse)\ndef root():\n return open(\"../frontend/dist/index.html\", \"r\").read()\n```\n\nbut, of course, this only gives me the static html without the React components.\n\nI realize this post may be loaded with incorrect assumptions and poor practices (in which case, my apologies! and I would appreciate any corrections/suggestions.) However, if the following questions could be answered, I would greatly appreciate it. These are questions I have that will hopefully help me test my whole web application locally on my computer.\n\n- How do I return the product of my frontend work for the `GET` request at the domain root endpoint?\n\n- If there is a page A, page B, and page C for my web app, each with url `www.example.com/A`, `www.example.com/B`, and `www.example.com/C` do I have to create three separate React frontend projects? I.e., equivalent of having three `dist` folders? What is the standard way this is handled?\n\n========================================\n\nTop Answer:\nI'm adding this answer purely to provide a complete working example of serving a React App from FastAPI. The credit goes to @csum though. Their answer is what led me to this solution so if you find this answer helpful you should give this answer an upvote as well.\n\nIf you don't care for an explanation and just want the code checkout this repo.\n\nHere is my directory structure for my app for your reference. Whatever your directory structure is doesn't really matter. The important piece is knowing the path to the `build` folder generated by `npm run build`.\n\n```\nexample-app/\n├── api/ **NOTE: depending on how you have configured your React app you may have `dist` instead of `build`.**\n\nIn `main.py` there are 3 important things for serving the react app.\n\n- Mounting the `static` folder found in `build` to `/static` This allows the browser to load all the css and js needed for the React SPA to render.\n\n- Adding `index.html` as a template so it can be served up by FastAPI.\n\n- Including a path converter in the `/` route handler. This allows you to have additional routes in your React app such as `/dashboard`, `/profile` etc.\n\n`main.py`\n\n```\nfrom fastapi import FastAPI\nfrom fastapi.staticfiles import StaticFiles\nfrom fastapi.templating import Jinja2Templates\nfrom fastapi.requests import Request\n\napp = FastAPI()\n\n# Sets the templates directory to the `build` folder from `npm run build`\n# this is where you'll find the index.html file.\ntemplates = Jinja2Templates(directory=\"../ui/build\")\n\n# Mounts the `static` folder within the `build` folder to the `/static` route.\napp.mount('/static', StaticFiles(directory=\"../ui/build/static\"), 'static')\n\n# sets up a health check route. This is used later to show how you can hit\n# the API and the React App url's\n@app.get('/api/health')\nasync def health():\n return { 'status': 'healthy' }\n\n# Defines a route handler for `/*` essentially.\n# NOTE: this needs to be the last route defined b/c it's a catch all route\n@app.get(\"/{rest_of_path:path}\")\nasync def react_app(req: Request, rest_of_path: str):\n return templates.TemplateResponse('index.html', { 'request': req })\n```\n\nTo get the app running these steps.\n\n- Run `npm run build` from the ui folder\n\n- Run `uvicorn main:app --reload` from the api folder\n\nYou can verify the react app and the FastAPI app are both working by entering the following routes into your browser.\n\n- `localhost:8000/api/health` returns `{ \"status\": \"healthy\" }`\n\n- `localhost:8000` returns your React App's homepage\n\n- `localhost:8000/test-react-route` returns whatever page is setup in React Router.\n\n========================================\n\nCode:\n```text\n@app.get(\"/\", response_class=HTMLResponse)\ndef root():\n return open(\"../frontend/dist/index.html\", \"r\").read()\n```\n\n```text\nnpm run start\n```\n\n```text\nhttp://localhost:8080/\n```\n\n```text\nnpm run build\n```\n\n```text\ndist\n```\n\n```text\nFastAPI\n```\n\n```text\nuvicorn main:app --reload\n```\n\n```text\ndist\n```\n\n```text\nGET\n```\n\n```text\nwww.example.com/A\n```\n\n```text\nwww.example.com/B\n```\n\n```text\nwww.example.com/C\n```\n\n```text\ndist\n```\n\n```text\nfrom fastapi import FastAPI, Request\nfrom fastapi.staticfiles import StaticFiles\nfrom fastapi.templating import Jinja2Templates\n\napp = FastAPI()\n\napp.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")\n\ntemplates = Jinja2Templates(directory=\"templates\")\n\n@app.get(\"/\")\nasync def serve_spa(request: Request):\n return templates.TemplateResponse(\"index.html\", {\"request\": request})\n```\n\n```text\n@app.route(\"/{full_path:path}\")\nasync def catch_all(request: Request, full_path: str):\n print(\"full_path: \"+full_path)\n return templates.TemplateResponse(\"index.html\", {\"request\": request})\n```\n\n```text\ndist/\n```\n\n```text\ndist/index.html\n```\n\n```text\ntemplates/\n```\n\n```text\nstatic/\n```\n\n```text\nstatic\n```\n\n```text\nassetsDir\n```\n\n```text\nvue.config.js\n```\n\n```text\nexample.com/a\n```\n\n```text\nexample.com/b\n```\n\n```text\nserve_spa()\n```\n\n```text\n/a\n```\n\n```text\n/b\n```\n\n```text\nnpm run start\n```\n\n```text\nhttp://localhost:8080\n```\n\n```py\nimport logging\n\nfrom fastapi import FastAPI\nfrom starlette.responses import RedirectResponse\nfrom starlette.staticfiles import StaticFiles\n\napp = FastAPI()\n\n\n@app.get(\"/\")\nasync def index():\n return RedirectResponse(url=\"/index.html\")\n\napp.mount(\"/\", StaticFiles(directory=\"backend/ui/\"), name=\"ui\")\n```\n\n```text\napp.mount\n```\n\n```text\n/\n```\n\n```text\nindex.html\n```\n\n```text\nreact-scripts\n```\n\n```py\napp.mount('/', SPAStaticFiles(directory='folder', html=True), name='whatever')\n```\n\n```text\nnginx\n```\n\n```text\nJinja2\n```\n\n```text\nJinja2\n```\n\n```text\nFastAPI\n```\n\n```text\n/my-spa\n```\n\n```text\n/\n```\n\n```text\n/\n```\n\n```text\n/api\n```\n\n```text\n/api/v1/...\n```\n\n```text\nexample-app/\n├── api/ <- My FastAPI App\n └── main.py\n└── ui/ <- My React App\n └── build/\n └── static/\n └── index.html/\n └── ...\n └── src/\n └── package.json\n └── tsconfig.json\n └── ...\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.staticfiles import StaticFiles\nfrom fastapi.templating import Jinja2Templates\nfrom fastapi.requests import Request\n\napp = FastAPI()\n\n# Sets the templates directory to the `build` folder from `npm run build`\n# this is where you'll find the index.html file.\ntemplates = Jinja2Templates(directory=\"../ui/build\")\n\n# Mounts the `static` folder within the `build` folder to the `/static` route.\napp.mount('/static', StaticFiles(directory=\"../ui/build/static\"), 'static')\n\n\n# sets up a health check route. This is used later to show how you can hit\n# the API and the React App url's\n@app.get('/api/health')\nasync def health():\n return { 'status': 'healthy' }\n\n\n# Defines a route handler for `/*` essentially.\n# NOTE: this needs to be the last route defined b/c it's a catch all route\n@app.get(\"/{rest_of_path:path}\")\nasync def react_app(req: Request, rest_of_path: str):\n return templates.TemplateResponse('index.html', { 'request': req })\n```\n\n```text\nbuild\n```\n\n```text\nnpm run build\n```\n\n```text\ndist\n```\n\n```text\nbuild\n```\n\n```text\nmain.py\n```\n\n```text\nstatic\n```\n\n```text\nbuild\n```\n\n```text\n/static\n```\n\n```text\nindex.html\n```\n\n```text\n/\n```\n\n```text\n/dashboard\n```\n\n```text\n/profile\n```\n\n```text\nmain.py\n```\n\n```text\nnpm run build\n```\n\n```text\nuvicorn main:app --reload\n```\n\n```text\nlocalhost:8000/api/health\n```\n\n```text\n{ \"status\": \"healthy\" }\n```\n\n```text\nlocalhost:8000\n```\n\n```text\nlocalhost:8000/test-react-route\n```\n\n```text\nfrom fastapi import FastAPI\nfrom fastapi.staticfiles import StaticFiles\nfrom fastapi.responses import FileResponse\n\napp = FastAPI()\n\n\napp.mount(\"/assets\", StaticFiles(directory=\"frontend/dist/assets\"), name=\"assets\")\n\n\n@app.get('/api/health')\nasync def health():\n return { 'status': 'healthy' }\n\n# Route to serve React index.html (for client-side routing)\n@app.get(\"/{catchall:path}\")\nasync def serve_react_app(catchall: str):\n return FileResponse(\"frontend/dist/index.html\")\n```\n\n========================================\n\nComments:\n- I encourage you to use my simple function stackoverflow.com/a/70065066/12234006\n- Excellent answer. I spent half a day looking through SO and trying peoples suggestions and nothing worked. The trick was mounting the static folder.\n- Really nice answer. For me, using 'app.route' didn't work, it always gave me an error about a missing parameter, but it works perfectly with `app.get`.\n- It seems the usage on jinja2 is pointless\n- That works! can you elaborate about the `assets` vs. `static`? (it only works that way for me)\n- @ItayB the reason that approach works, is because the `index.html` that he serves with `FileResponse()` needs some assets to work. JS and CSS files. the src paths inside the `.html` file needs to be served as `StaticFiles` for the `React` application to load.","metadata":{"transformedAt":"2026-08-18T18:32:29.096Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":66,"totalLines":464,"estimatedTokens":2608}}79{"id":"stack-61836761","source":"stackoverflow","questionId":61836761,"title":"Get return status from Background Tasks in FastAPI","tags":["python-3.x","fastapi"],"text":"Title: Get return status from Background Tasks in FastAPI\nTags: python-3.x, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have an API which posts jobs upon which background jobs are created and I want to send status of job on another GET api. How to achieve this? In `background_work()` function I am going with multiprocessing as call internally targets `subprocess.call()` calls.\n\n```\nfrom fastapi import BackgroundTasks, FastAPI\n\napp = FastAPI()\n\ndef background_work(data: str):\n # some computation on data and return it\n return status\n\n@app.post(\"/post_job\", status_code=HTTP_201_CREATED)\nasync def send_notification(data: str, background_tasks: BackgroundTasks):\n background_tasks.add_task(background_work, data)\n return {\"message\": \"Job Created, check status after some time!\"}\n\n@app.get(\"/get_status\")\ndef status():\n #how to return status of job submitted to background task\n```\n\n========================================\n\nTop Answer:\nI'm using fastAPI exactly like this, combining `concurrent.futures.ProcessPoolExecutor()` and asyncio to manage long running jobs.\n\nIf you don't want to rely on other modules (celery etc), you need to manage yourself the state of your job, and store it somewhere. I store it in the DB so that pending jobs can be resumed after a restart of the server.\n\nNote that you must NOT perform CPU intensive computations in the `background_tasks` of the app, because it runs in the same async event loop that serves the requests and it will stall your app. Instead submit them to a thread pool or a process pool.\n\n========================================\n\nCode:\n```text\nfrom fastapi import BackgroundTasks, FastAPI\n\napp = FastAPI()\n\ndef background_work(data: str):\n # some computation on data and return it\n return status\n\n@app.post(\"/post_job\", status_code=HTTP_201_CREATED)\nasync def send_notification(data: str, background_tasks: BackgroundTasks):\n background_tasks.add_task(background_work, data)\n return {\"message\": \"Job Created, check status after some time!\"}\n\n@app.get(\"/get_status\")\ndef status():\n #how to return status of job submitted to background task\n```\n\n```text\nbackground_work()\n```\n\n```text\nsubprocess.call()\n```\n\n```text\nimport time\nfrom fastapi import BackgroundTasks, FastAPI\n\napp = FastAPI()\n\nclass TaskState:\n\n def __init__(self):\n self.counter = 0\n\n def background_work(self):\n while True:\n self.counter += 1\n time.sleep(1)\n\n def get_state(self):\n return self.counter\n\nstate = TaskState()\n\n@app.post(\"/post_job\", status_code=HTTP_201_CREATED)\nasync def send_notification(background_tasks: BackgroundTasks):\n background_tasks.add_task(state.background_work)\n return {\"message\": \"Job Created, check status after some time!\"}\n\n@app.get(\"/get_status\")\ndef status():\n return state.get_state()\n```\n\n```text\nconcurrent.futures.ProcessPoolExecutor()\n```\n\n```text\nbackground_tasks\n```\n\n========================================\n\nComments:\n- Also, I have gone through different questions asked on fastapi github - and suggest to go with tools like celery etc. Is this task can be achieved on simple fastapi\n- What do you want to do with the return status?\n- You may also try to give a look at WPS (Web Processing Service) - PyWPS is one of its Python implementations. PyWPS can run as a separate service and `owslib.wps.WPSExecution` can be used from inside your FastAPI App to control the status of your WPS process.\n- Oh jesus! This is a concurrency nightmare. TaskState is global, and there is no locking mechanism, if multiple send_notifications are getting triggered, then you are in big trouble.\n- This only works if you have one worker.\n- Such a great idea storing the task status on the DB. I've just implemented it and it's working beautifully, the task itself is responsible for updating it's status. Thanks. This should be the main answer, as it really solves the problem. Also: remember to check for failures on startup in case the app breaks. I'm using Fastapi Events: startup to mark all unsuccessful tasks as failed\n- Thank you. It works great for me also. Care must be taken with concurrent access to the DB to update the status though. I ran into some trouble with sqlAlchemy Sessions, I had to read the documentation carefully. You can't use the dependency from the examples of fastAPI, you need to create a new session in the function that is ran in the separate thread or process.\n- Would anyone care to post a MWE with this setup? Or at least link to somewhere that shows an example. It seems very interesting but I, for one, haven't the slightest ideia how to begin this.","metadata":{"transformedAt":"2026-08-18T18:32:29.096Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":6,"totalLines":115,"estimatedTokens":1153}}80{"id":"stack-64763770","source":"stackoverflow","questionId":64763770,"title":"Why we use yield to get Sessionlocal in Fastapi with sqlalchemy?","tags":["python","sqlalchemy","fastapi"],"text":"Title: Why we use yield to get Sessionlocal in Fastapi with sqlalchemy?\nTags: python, sqlalchemy, fastapi\nSource: Stack Overflow\n\nQuestion:\n```\ndef get_db():\n db = SessionLocal()\n try:\n return db\n finally:\n db.close()\n```\n\nI got this code snipped to get Sessionlocal in fastapi with Sqlalchemy. Well, when I used return instead of Yield. My code still works. Then, I do not understand the reason of using Yield. Can someone help me?\n\n========================================\n\nTop Answer:\nThere is a fundamental difference, when you use a `return`, the closing is performed **before** the function returns the `db` object, in fact you are returning a *closed* `db` object. Because\n\nWhen `return` passes control out of a `try` statement with a `finally` clause, that `finally` clause is executed **before** really leaving the function.\n\nOtherwise, when the `yield` is used, the `finally` code block is executed **after** the request has been processed and the response **has been sent**. You can read more about dependencies with yield here.\n\nWhy your code continues to work, I cannot tell without seeing the whole code.\n\n========================================\n\nCode:\n```text\ndef get_db():\n db = SessionLocal()\n try:\n return db\n finally:\n db.close()\n```\n\n```text\nreturn\n```\n\n```text\nreturn\n```\n\n```text\nyield\n```\n\n```text\nreturn\n```\n\n```text\ndb\n```\n\n```text\ndb\n```\n\n```text\nreturn\n```\n\n```text\ntry\n```\n\n```text\nfinally\n```\n\n```text\nfinally\n```\n\n```text\nyield\n```\n\n```text\nfinally\n```\n\n========================================\n\nComments:\n- I left a question here yesterday but I want to rephrase it. I feel like I don't understand why `yield` would return a new session object but `return` wouldn't. This seems to imply that the line `db = SessionLocal()` operates differently if it is in a generator or regular function which doesn't seem likely. I think the other answer that the generator will wait to close the connection is more accurate but maybe there's something I don't know about `SessionLocal()`.\n- Exactly, this should be answer. It is documented in FastAPI: fastapi.tiangolo.com/tutorial/dependencies/…\n- I've read the relevant sections of the FastAPI page and I like this explanation but I wanted to know is there a resource that explains how Depends works? I've not done a lot with generators and I'm interested in learning how it keeps the generator live without executing `finally` until after the response has been returned. Is it as simple as putting the generator in a loop, passes the yielded value to where it is needed, when that's done the loop closes and finally `finally` in the generator runs?\n- @KenMyers When the python finishes the request ie. success or fails, Python resumes the yield and passes to the finally","metadata":{"transformedAt":"2026-08-18T18:32:29.096Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":13,"totalLines":94,"estimatedTokens":693}}81{"id":"stack-57562804","source":"stackoverflow","questionId":57562804,"title":"MongoDb with FastAPI","tags":["mongodb","mongoengine","tornado-motor","fastapi","motorengine"],"text":"Title: MongoDb with FastAPI\nTags: mongodb, mongoengine, tornado-motor, fastapi, motorengine\nSource: Stack Overflow\n\nQuestion:\nI am playing around with FastAPI a bit and wanted to connect it to a MongoDB database. I however am confused which ODM to choose between motor which is async and mongoengine. Also, in the NoSQL example here they have created a new bucket and also the called the code to connect to db every time it is used. However, both motor and mongoengine seem to prefer a global connection. So what would be a good way to connect to mongodb?\n\n========================================\n\nTop Answer:\nI recently created an Async Mongo ODM well suited for FastAPI: ODMantic.\n\n```\napp = FastAPI()\nengine = AIOEngine()\n\nclass Tree(Model):\n \"\"\"This model can be used either as a Pydantic model or \n saved to the database\"\"\"\n name: str\n average_size: float\n discovery_year: int\n\n@app.get(\"/trees/\", response_model=List[Tree])\nasync def get_trees():\n trees = await engine.find(Tree)\n return trees\n\n@app.put(\"/trees/\", response_model=Tree)\nasync def create_tree(tree: Tree):\n await engine.save(tree)\n return tree\n```\n\nYou can have a look to the FastAPI example for a more detailed example.\n\n========================================\n\nCode:\n```py\n@app.on_event(\"startup\")\nasync def create_db_client():\n # start client here and reuse in future requests\n\n\n@app.on_event(\"shutdown\")\nasync def shutdown_db_client():\n # stop your client here\n```\n\n```py\napp = FastAPI()\nengine = AIOEngine()\n\nclass Tree(Model):\n \"\"\"This model can be used either as a Pydantic model or \n saved to the database\"\"\"\n name: str\n average_size: float\n discovery_year: int\n\n@app.get(\"/trees/\", response_model=List[Tree])\nasync def get_trees():\n trees = await engine.find(Tree)\n return trees\n\n@app.put(\"/trees/\", response_model=Tree)\nasync def create_tree(tree: Tree):\n await engine.save(tree)\n return tree\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.096Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":2,"totalLines":71,"estimatedTokens":479}}82{"id":"stack-65362524","source":"stackoverflow","questionId":65362524,"title":"In JSON created from a pydantic.BaseModel exclude Optional if not set","tags":["python","json","python-3.x","fastapi","pydantic"],"text":"Title: In JSON created from a pydantic.BaseModel exclude Optional if not set\nTags: python, json, python-3.x, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI want to exclude all the Optional values that are not set when I create JSON. In this example:\n\n```\nfrom pydantic import BaseModel\nfrom typing import Optional\n\nclass Foo(BaseModel):\n x: int\n y: int = 42\n z: Optional[int]\n\nprint(Foo(x=3).json())\n```\n\nI get `{\"x\": 3, \"y\": 42, \"z\": null}`. But I would like to exclude `z`. Not because its value is `None`, but because it is Optional and there was no keyword argument for `z`. In the two cases below I would like to have `z` in the JSON.\n\n```\nFoo(x=1, z=None)\nFoo(x=1, z=77)\n```\n\nIf there is any other solution to set `z` to optional in this sense, I would like to see it.\n\n========================================\n\nTop Answer:\nIf you're using FastAPI then using `exclude_none` doesn't seem to work when a response_model is mentioned in the route decorator.\n\n```\n@app.post(\"/items/\", response_model=Item)\nasync def create_item(item: Item):\n return item.dict(exclude_none=True)\n```\n\nFast api seems to reprocess the dict with the pydantic model\n\nSo overriding the dict method in the model itself should work\n\n```\ndef Item(BaseModel):\n name: str\n description: Optional[str]\n ...\n def dict(self, *args, **kwargs) -> Dict[str, Any]:\n kwargs.pop('exclude_none', None)\n return super().dict(*args, exclude_none=True, **kwargs)\n```\n\n(an actual solution would put this definition in separate subclass of BaseModel for reuse)\n\nNote: just changing the default value of the `exclude_none` keyword argument is not enough: it seems FastAPI always sends `exclude_none=False` as an argument.\n\nSource: \n\nhttps://github.com/tiangolo/fastapi/issues/3314#issuecomment-962932368\n\n========================================\n\nCode:\n```py\nfrom pydantic import BaseModel\nfrom typing import Optional\n\n\nclass Foo(BaseModel):\n x: int\n y: int = 42\n z: Optional[int]\n\n\nprint(Foo(x=3).json())\n```\n\n```text\nFoo(x=1, z=None)\nFoo(x=1, z=77)\n```\n\n```text\n{\"x\": 3, \"y\": 42, \"z\": null}\n```\n\n```text\nz\n```\n\n```text\nNone\n```\n\n```text\nz\n```\n\n```text\nz\n```\n\n```text\nz\n```\n\n```text\nfrom pydantic import BaseModel\nfrom typing import Optional\nfrom pydantic.json import pydantic_encoder\nimport json\n\n\nclass Foo(BaseModel):\n x: int\n y: int = 42\n z: Optional[int]\n\ndef exclude_optional_dict(model: BaseModel):\n return {**model.dict(exclude_unset=True), **model.dict(exclude_none=True)}\n\ndef exclude_optional_json(model: BaseModel):\n return json.dumps(exclude_optional_dict(model), default=pydantic_encoder)\n \n\n\nprint(exclude_optional_json(Foo(x=3))) # {\"x\": 3, \"y\": 42}\nprint(exclude_optional_json(Foo(x=3, z=None))) # {\"x\": 3, \"z\": null, \"y\": 42}\nprint(exclude_optional_json(Foo(x=3, z=77))) # {\"x\": 3, \"z\": 77, \"y\": 42}\n```\n\n```text\ndef union(source, destination):\n for key, value in source.items():\n if isinstance(value, dict):\n node = destination.setdefault(key, {})\n union(value, node)\n else:\n destination[key] = value\n\n return destination\n\ndef exclude_optional_dict(model: BaseModel):\n return union(model.dict(exclude_unset=True), model.dict(exclude_none=True))\n\nclass Foo(BaseModel):\n x: int\n y: int = 42\n z: Optional[int]\n\nclass Bar(BaseModel):\n a: int\n b: int = 52\n c: Optional[int]\n d: Foo\n\n\nprint(exclude_optional_json(Bar(a=4, d=Foo(x=3))))\nprint(exclude_optional_json(Bar(a=4, c=None, d=Foo(x=3, z=None))))\nprint(exclude_optional_json(Bar(a=4, c=78, d=Foo(x=3, z=77))))\n```\n\n```text\n{\"a\": 4, \"b\": 52, \"d\": {\"x\": 3, \"y\": 42}}\n{\"a\": 4, \"b\": 52, \"d\": {\"x\": 3, \"y\": 42, \"z\": null}, \"c\": null}\n{\"a\": 4, \"b\": 52, \"c\": 78, \"d\": {\"x\": 3, \"y\": 42, \"z\": 77}}\n```\n\n```text\nexclude_unset\n```\n\n```text\nFalse\n```\n\n```text\nexclude_none\n```\n\n```text\nNone\n```\n\n```text\nFalse\n```\n\n```text\na = {**b, **c}\n```\n\n```text\nc\n```\n\n```text\nb\n```\n\n```text\na = b | c\n```\n\n```py\n@app.post(\"/items/\", response_model=Item)\nasync def create_item(item: Item):\n return item.dict(exclude_none=True)\n```\n\n```py\ndef Item(BaseModel):\n name: str\n description: Optional[str]\n ...\n def dict(self, *args, **kwargs) -> Dict[str, Any]:\n kwargs.pop('exclude_none', None)\n return super().dict(*args, exclude_none=True, **kwargs)\n```\n\n```text\nexclude_none\n```\n\n```text\nexclude_none\n```\n\n```text\nexclude_none=False\n```\n\n========================================\n\nComments:\n- It is brilliant! I use other models in the main model, and it works on the whole structure fortunately.\n- Actually, no. First approach does not work if `None` is explicitly set for optional field of nested model, but I updated the answer for such cases.","metadata":{"transformedAt":"2026-08-18T18:32:29.097Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":25,"totalLines":238,"estimatedTokens":1171}}83{"id":"stack-63257839","source":"stackoverflow","questionId":63257839,"title":"Best way to specify nested dict with pydantic?","tags":["python","validation","nested","fastapi","pydantic"],"text":"Title: Best way to specify nested dict with pydantic?\nTags: python, validation, nested, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\n### Context\n\nI'm trying to validate/parse some data with `pydantic`.\n\nI want to specify that the dict can have a key `daytime`, or not.\nIf it does, I want the value of `daytime` to include both `sunrise` and `sunset`.\n\ne.g. These should be allowed:\n\n```\n{\n 'type': 'solar',\n 'daytime': {\n 'sunrise': 4, # 4am\n 'sunset': 18 # 6pm\n }\n}\n```\n\nAnd\n\n```\n{\n 'type': 'wind'\n # daytime key is omitted\n}\n```\n\nAnd\n\n```\n{\n 'type': 'wind',\n 'daytime': None\n}\n```\n\nBut I want to fail validation for\n\n```\n{\n 'type': 'solar',\n 'daytime': {\n 'sunrise': 4\n }\n}\n```\n\nBecause this has a `daytime` value, but no sunset value.\n\n### MWE\n\nI've got some code that does this.\nIf I run this script, it executes successfully.\n\n```\nfrom pydantic import BaseModel, ValidationError\nfrom typing import List, Optional, Dict\n\nclass DayTime(BaseModel):\n sunrise: int\n sunset: int\n \nclass Plant(BaseModel):\n daytime: Optional[DayTime] = None\n type: str\n\np = Plant.parse_obj({'type': 'wind'})\np = Plant.parse_obj({'type': 'wind', 'daytime': None})\np = Plant.parse_obj({\n 'type': 'solar', \n 'daytime': {\n 'sunrise': 5, \n 'sunset': 18\n }})\n \ntry:\n p = Plant.parse_obj({\n 'type': 'solar', \n 'daytime': {\n 'sunrise': 5\n }})\nexcept ValidationError:\n pass\nelse:\n raise AssertionError(\"Should have failed\")\n```\n\n### Question\n\nWhat I'm wondering is,\n**is this how you're supposed to use pydantic for nested data?**\n\nI have lots of layers of nesting, and this seems a bit verbose.\n\nIs there any way to do something more concise, like:\n\n```\nclass Plant(BaseModel):\n daytime: Optional[Dict[('sunrise', 'sunset'), int]] = None\n type: str\n```\n\n========================================\n\nTop Answer:\nLike this?\n\n```\nclass DayTime(BaseModel):\n sunrise: int\n sunset: int\n \nclass Plant(BaseModel):\n daytime: Optional[DayTime] = None\n type: str\n\nyo_data = {\n 'type': 'solar', \n 'daytime': {\n 'sunrise': 5, \n 'sunset': 18\n }}\n\n# then simply\n\na_plant = Plant(**yo_data)\n```\n\nsee\n\n========================================\n\nCode:\n```text\n{\n 'type': 'solar',\n 'daytime': {\n 'sunrise': 4, # 4am\n 'sunset': 18 # 6pm\n }\n}\n```\n\n```text\n{\n 'type': 'wind'\n # daytime key is omitted\n}\n```\n\n```text\n{\n 'type': 'wind',\n 'daytime': None\n}\n```\n\n```text\n{\n 'type': 'solar',\n 'daytime': {\n 'sunrise': 4\n }\n}\n```\n\n```text\nfrom pydantic import BaseModel, ValidationError\nfrom typing import List, Optional, Dict\n\nclass DayTime(BaseModel):\n sunrise: int\n sunset: int\n \nclass Plant(BaseModel):\n daytime: Optional[DayTime] = None\n type: str\n\np = Plant.parse_obj({'type': 'wind'})\np = Plant.parse_obj({'type': 'wind', 'daytime': None})\np = Plant.parse_obj({\n 'type': 'solar', \n 'daytime': {\n 'sunrise': 5, \n 'sunset': 18\n }})\n \ntry:\n p = Plant.parse_obj({\n 'type': 'solar', \n 'daytime': {\n 'sunrise': 5\n }})\nexcept ValidationError:\n pass\nelse:\n raise AssertionError(\"Should have failed\")\n```\n\n```text\nclass Plant(BaseModel):\n daytime: Optional[Dict[('sunrise', 'sunset'), int]] = None\n type: str\n```\n\n```text\npydantic\n```\n\n```text\ndaytime\n```\n\n```text\ndaytime\n```\n\n```text\nsunrise\n```\n\n```text\nsunset\n```\n\n```text\ndaytime\n```\n\n```py\nfrom pydantic import BaseModel, create_model\n\nclass Plant(BaseModel):\n daytime: Optional[create_model('DayTime', sunrise=(int, ...), sunset=(int, ...))] = None\n type: str\n```\n\n```text\ncreate_model\n```\n\n```py\nclass DayTime(BaseModel):\n sunrise: int\n sunset: int\n \nclass Plant(BaseModel):\n daytime: Optional[DayTime] = None\n type: str\n\nyo_data = {\n 'type': 'solar', \n 'daytime': {\n 'sunrise': 5, \n 'sunset': 18\n }}\n\n# then simply\n\na_plant = Plant(**yo_data)\n```\n\n========================================\n\nComments:\n- is there any way to leave it untyped? Just say dict of dict?\n- @Nickpick You can simply declare dict as the type for daytime if you didn't want further typing, like so: `daytime: dict`\n- How is this different from the questioner's MWE? I can't see the advantage of `create_model('DayTime', ...)` over `class DayTime(BaseModel): ...`. The docs only say that `create_model()` is for when the shape of a model is not known until runtime.\n- I'd rather avoid this solution at least for OP's case, it's harder to understand, and still 'flat is better than nested'\n- This seems to be the best solution imho.","metadata":{"transformedAt":"2026-08-18T18:32:29.097Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":15,"totalLines":276,"estimatedTokens":1119}}84{"id":"stack-60711576","source":"stackoverflow","questionId":60711576,"title":"How do I write SQLAlchemy test fixtures for FastAPI applications","tags":["sqlalchemy","fastapi","test-fixture"],"text":"Title: How do I write SQLAlchemy test fixtures for FastAPI applications\nTags: sqlalchemy, fastapi, test-fixture\nSource: Stack Overflow\n\nQuestion:\nI am writing a FastAPI application that uses a SQLAlchemy database. I have copied the example from the FastAPI documentation, simplifying the database schema for concisions' sake. The complete source is at the bottom of this post.\n\nThis works. I can run it with `uvicorn sql_app.main:app` and interact with the database via the Swagger docs. When it runs it creates a `test.db` in the working directory.\n\nNow I want to add a unit test. Something like this.\n\n```\nfrom fastapi import status\nfrom fastapi.testclient import TestClient\nfrom pytest import fixture\n\nfrom main import app\n\n@fixture\ndef client() -> TestClient:\n return TestClient(app)\n\ndef test_fast_sql(client: TestClient):\n response = client.get(\"/users/\")\n assert response.status_code == status.HTTP_200_OK\n assert response.json() == []\n```\n\nUsing the source code below, this takes the `test.db` in the working directory as the database. Instead I want to create a new database for every unit test that is deleted at the end of the test.\n\nI could put the global `database.engine` and `database.SessionLocal` inside an object that is created at runtime, like so:\n\n```\nclass UserDatabase:\n def __init__(self, directory: Path):\n directory.mkdir(exist_ok=True, parents=True)\n sqlalchemy_database_url = f\"sqlite:///{directory}/store.db\"\n self.engine = create_engine(\n sqlalchemy_database_url, connect_args={\"check_same_thread\": False}\n )\n self.SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=self.engine)\n models.Base.metadata.create_all(bind=self.engine)\n```\n\nbut I don't know how to make that work with `main.get_db`, since the `Depends(get_db)` logic ultimately assumes `database.engine` and `database.SessionLocal` are available globally.\n\nI'm used to working with Flask, whose unit testing facilities handle all this for you. I don't know how to write it myself. Can someone show me the minimal changes I'd have to make in order to generate a new database for each unit test in this framework?\n\nThe complete source of the simplified FastAPI/SQLAlchemy app is as follows.\n\n**database.py**\n\n```\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import sessionmaker\n\nSQLALCHEMY_DATABASE_URL = \"sqlite:///./test.db\"\n\nengine = create_engine(\n SQLALCHEMY_DATABASE_URL, connect_args={\"check_same_thread\": False}\n)\nSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)\n\nBase = declarative_base()\n```\n\n**models.py**\n\n```\nfrom sqlalchemy import Column, Integer, String\n\nfrom database import Base\n\nclass User(Base):\n __tablename__ = \"users\"\n\n id = Column(Integer, primary_key=True, index=True)\n name = Column(String)\n age = Column(Integer)\n```\n\n**schemas.py**\n\n```\nfrom pydantic import BaseModel\n\nclass UserBase(BaseModel):\n name: str\n age: int\n\nclass UserCreate(UserBase):\n pass\n\nclass User(UserBase):\n id: int\n\n class Config:\n orm_mode = True\n```\n\n**crud.py**\n\n```\nfrom sqlalchemy.orm import Session\n\nimport schemas\nimport models\n\ndef get_user(db: Session, user_id: int):\n return db.query(models.User).filter(models.User.id == user_id).first()\n\ndef get_users(db: Session, skip: int = 0, limit: int = 100):\n return db.query(models.User).offset(skip).limit(limit).all()\n\ndef create_user(db: Session, user: schemas.UserCreate):\n db_user = models.User(name=user.name, age=user.age)\n db.add(db_user)\n db.commit()\n db.refresh(db_user)\n return db_user\n```\n\n**main.py**\n\n```\nfrom typing import List\n\nfrom fastapi import Depends, FastAPI, HTTPException\nfrom sqlalchemy.orm import Session\n\nimport schemas\nimport models\nimport crud\nfrom database import SessionLocal, engine\n\nmodels.Base.metadata.create_all(bind=engine)\n\napp = FastAPI()\n\n# Dependency\ndef get_db():\n try:\n db = SessionLocal()\n yield db\n finally:\n db.close()\n\n@app.post(\"/users/\", response_model=schemas.User)\ndef create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):\n return crud.create_user(db=db, user=user)\n\n@app.get(\"/users/\", response_model=List[schemas.User])\ndef read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):\n users = crud.get_users(db, skip=skip, limit=limit)\n return users\n\n@app.get(\"/users/{user_id}\", response_model=schemas.User)\ndef read_user(user_id: int, db: Session = Depends(get_db)):\n db_user = crud.get_user(db, user_id=user_id)\n if db_user is None:\n raise HTTPException(status_code=404, detail=\"User not found\")\n return db_user\n```\n\n========================================\n\nCode:\n```py\nfrom fastapi import status\nfrom fastapi.testclient import TestClient\nfrom pytest import fixture\n\nfrom main import app\n\n\n@fixture\ndef client() -> TestClient:\n return TestClient(app)\n\n\ndef test_fast_sql(client: TestClient):\n response = client.get(\"/users/\")\n assert response.status_code == status.HTTP_200_OK\n assert response.json() == []\n```\n\n```py\nclass UserDatabase:\n def __init__(self, directory: Path):\n directory.mkdir(exist_ok=True, parents=True)\n sqlalchemy_database_url = f\"sqlite:///{directory}/store.db\"\n self.engine = create_engine(\n sqlalchemy_database_url, connect_args={\"check_same_thread\": False}\n )\n self.SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=self.engine)\n models.Base.metadata.create_all(bind=self.engine)\n```\n\n```py\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import sessionmaker\n\nSQLALCHEMY_DATABASE_URL = \"sqlite:///./test.db\"\n\nengine = create_engine(\n SQLALCHEMY_DATABASE_URL, connect_args={\"check_same_thread\": False}\n)\nSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)\n\nBase = declarative_base()\n```\n\n```py\nfrom sqlalchemy import Column, Integer, String\n\nfrom database import Base\n\n\nclass User(Base):\n __tablename__ = \"users\"\n\n id = Column(Integer, primary_key=True, index=True)\n name = Column(String)\n age = Column(Integer)\n```\n\n```py\nfrom pydantic import BaseModel\n\n\nclass UserBase(BaseModel):\n name: str\n age: int\n\n\nclass UserCreate(UserBase):\n pass\n\n\nclass User(UserBase):\n id: int\n\n class Config:\n orm_mode = True\n```\n\n```py\nfrom sqlalchemy.orm import Session\n\nimport schemas\nimport models\n\n\ndef get_user(db: Session, user_id: int):\n return db.query(models.User).filter(models.User.id == user_id).first()\n\n\ndef get_users(db: Session, skip: int = 0, limit: int = 100):\n return db.query(models.User).offset(skip).limit(limit).all()\n\n\ndef create_user(db: Session, user: schemas.UserCreate):\n db_user = models.User(name=user.name, age=user.age)\n db.add(db_user)\n db.commit()\n db.refresh(db_user)\n return db_user\n```\n\n```py\nfrom typing import List\n\nfrom fastapi import Depends, FastAPI, HTTPException\nfrom sqlalchemy.orm import Session\n\nimport schemas\nimport models\nimport crud\nfrom database import SessionLocal, engine\n\nmodels.Base.metadata.create_all(bind=engine)\n\napp = FastAPI()\n\n\n# Dependency\ndef get_db():\n try:\n db = SessionLocal()\n yield db\n finally:\n db.close()\n\n\n@app.post(\"/users/\", response_model=schemas.User)\ndef create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):\n return crud.create_user(db=db, user=user)\n\n\n@app.get(\"/users/\", response_model=List[schemas.User])\ndef read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):\n users = crud.get_users(db, skip=skip, limit=limit)\n return users\n\n\n@app.get(\"/users/{user_id}\", response_model=schemas.User)\ndef read_user(user_id: int, db: Session = Depends(get_db)):\n db_user = crud.get_user(db, user_id=user_id)\n if db_user is None:\n raise HTTPException(status_code=404, detail=\"User not found\")\n return db_user\n```\n\n```text\nuvicorn sql_app.main:app\n```\n\n```text\ntest.db\n```\n\n```text\ntest.db\n```\n\n```text\ndatabase.engine\n```\n\n```text\ndatabase.SessionLocal\n```\n\n```text\nmain.get_db\n```\n\n```text\nDepends(get_db)\n```\n\n```text\ndatabase.engine\n```\n\n```text\ndatabase.SessionLocal\n```\n\n```py\n@fixture\ndef db_fixture() -> Session:\n raise NotImplementError() # Make this return your temporary session\n\n@fixture\ndef client(db_fixture) -> TestClient:\n\n def _get_db_override():\n return db_fixture\n\n app.dependency_overrides[get_db] = _get_db_override\n return TestClient(app)\n```\n\n```text\nget_db\n```\n\n========================================\n\nComments:\n- Relevant question on the FastAPI site: github.com/tiangolo/fastapi/issues/831\n- Actually it looks like this is addressed directly here: fastapi.tiangolo.com/advanced/testing-database. I overlooked that documentation.","metadata":{"transformedAt":"2026-08-18T18:32:29.097Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":18,"totalLines":375,"estimatedTokens":2186}}85{"id":"stack-68890763","source":"stackoverflow","questionId":68890763,"title":"How to reload FastAPI app when a file, other than *.py files, changes?","tags":["fastapi","uvicorn"],"text":"Title: How to reload FastAPI app when a file, other than *.py files, changes?\nTags: fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI want my FastAPI app to reload when a `.csv` file in the same directory changes.\n\nI tried the following command, but it isn't working.\n\n```\nuvicorn main:app --reload --reload-include *.csv\n```\n\nDoes anyone know a solution to this problem?\n\n========================================\n\nTop Answer:\nAccording to Uvicorn Documentation, `--reload-include` does work only if optional dependency Watchfiles (previously called watchgod) is installed.\n\nTry installing it with `pip install watchfiles` and then run uvicorn again\n\n========================================\n\nCode:\n```text\nuvicorn main:app --reload --reload-include *.csv\n```\n\n```text\n.csv\n```\n\n```bash\nuvicorn main:app --reload --reload-include *.csv\n```\n\n```text\n--reload-include\n```\n\n```text\n--reload-exclude\n```\n\n```text\n--reload-include\n```\n\n```text\npip install watchfiles\n```\n\n========================================\n\nComments:\n- See accepted answer. The \"watchgod\" package was renamed to \"watchfiles\".\n- Would be interesting if uvicorn detected the plugin is missing when it's needed.","metadata":{"transformedAt":"2026-08-18T18:32:29.097Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":7,"totalLines":58,"estimatedTokens":295}}86{"id":"stack-73442335","source":"stackoverflow","questionId":73442335,"title":"How to Upload a large File (≥3GB) to FastAPI backend?","tags":["python","file-upload","upload","fastapi","starlette"],"text":"Title: How to Upload a large File (≥3GB) to FastAPI backend?\nTags: python, file-upload, upload, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nI am trying to upload a large file (≥3GB) to my FastAPI server, **without** loading the entire file into memory, as my server has only 2GB of free memory.\n\n**Server side**:\n\n```\n@app.post(\"/uploadfiles\")\nasync def uploadfiles(upload_file: UploadFile = File(...):\n pass\n```\n\n**Client side**:\n\n```\nfile_name=\"afd.tgz\"\nm = MultipartEncoder(fields = {\"upload_file\":open(file_name,'rb')})\nprefix = \"http://xxx:5000\"\nurl = \"{}/v1/uploadfiles\".format(prefix)\ntry:\n req = requests.post(\n url,\n data=m,\n verify=False,\n )\n```\n\nwhich returns the following `422 (Unprocessable entity)` error:\n\n```\nHTTP 422 {\"detail\":[{\"loc\":[\"body\",\"upload_file\"],\"msg\":\"field required\",\"type\":\"value_error.missing\"}]}\n```\n\nI am not sure what `MultipartEncoder` actually sends to the server, so that the request does not match. Any ideas?\n\n========================================\n\nCode:\n```py\n@app.post(\"/uploadfiles\")\nasync def uploadfiles(upload_file: UploadFile = File(...):\n pass\n```\n\n```py\nfile_name=\"afd.tgz\"\nm = MultipartEncoder(fields = {\"upload_file\":open(file_name,'rb')})\nprefix = \"http://xxx:5000\"\nurl = \"{}/v1/uploadfiles\".format(prefix)\ntry:\n req = requests.post(\n url,\n data=m,\n verify=False,\n )\n```\n\n```json\nHTTP 422 {\"detail\":[{\"loc\":[\"body\",\"upload_file\"],\"msg\":\"field required\",\"type\":\"value_error.missing\"}]}\n```\n\n```text\n422 (Unprocessable entity)\n```\n\n```text\nMultipartEncoder\n```\n\n```py\nfilename = 'my_file.txt'\nm = MultipartEncoder(fields={'upload_file': (filename, open(filename, 'rb'))})\nr = requests.post(url, data=m, headers={'Content-Type': m.content_type})\nprint(r.request.headers) # confirm that the 'Content-Type' header has been set\n```\n\n```py\nfrom fastapi import FastAPI, Request, HTTPException\nfrom fastapi.responses import HTMLResponse\nfrom fastapi.templating import Jinja2Templates\nfrom urllib.parse import unquote\nimport aiofiles\nimport os\n\napp = FastAPI()\ntemplates = Jinja2Templates(directory=\"templates\")\n\n\n@app.post('/upload')\nasync def upload(request: Request):\n try:\n filename = request.headers['filename']\n filename = unquote(filename)\n filepath = os.path.join('./', os.path.basename(filename))\n async with aiofiles.open(filepath, 'wb') as f:\n async for chunk in request.stream():\n await f.write(chunk)\n except Exception:\n raise HTTPException(status_code=500, detail='Something went wrong')\n \n return {\"message\": f\"Successfuly uploaded: {filename}\"}\n \n \n@app.get(\"/\", response_class=HTMLResponse)\nasync def main(request: Request):\n return templates.TemplateResponse(request=request, name=\"index.html\")\n```\n\n```html\n<!DOCTYPE html>\n<html>\n <body>\n <label for=\"fileInput\">Choose file(s) to upload</label>\n <input type=\"file\" id=\"fileInput\" name=\"fileInput\" onchange=\"reset()\" multiple><br>\n <input type=\"button\" value=\"Submit\" onclick=\"go()\">\n <p id=\"response\"></p>\n <script>\n var resp = document.getElementById(\"response\");\n \n function reset() {\n resp.innerHTML = \"\";\n }\n \n function go() {\n var fileInput = document.getElementById('fileInput');\n if (fileInput.files[0]) {\n for (const file of fileInput.files) {\n let reader = new FileReader();\n reader.onload = function () {\n uploadFile(reader.result, file.name);\n }\n reader.readAsArrayBuffer(file);\n }\n }\n }\n \n function uploadFile(contents, filename) {\n var headers = new Headers();\n filename = encodeURI(filename);\n headers.append(\"filename\", filename);\n fetch('/upload', {\n method: 'POST',\n headers: headers,\n body: contents,\n })\n .then(response => response.json()) // or, response.text(), etc.\n .then(data => {\n resp.innerHTML += JSON.stringify(data); // data is a JSON object\n })\n .catch(error => {\n console.error(error);\n });\n }\n </script>\n </body>\n</html>\n```\n\n```py\nimport httpx\nimport time\nfrom urllib.parse import quote\n\nurl = 'http://127.0.0.1:8000/upload'\nfilename = 'bigFile.zip'\nheaders = {'filename': quote(filename)}\nstart = time.time()\n\nwith open(filename, \"rb\") as f:\n r = httpx.post(url=url, data=f, headers=headers)\n \nend = time.time()\nprint(f'Time elapsed: {end - start}s')\nprint(r.json())\n```\n\n```py\n# ...\nimport glob, os\n\npaths = glob.glob(\"big_files_dir/*\", recursive=True)\nfor p in paths:\n with open(p, \"rb\") as f:\n headers = {'filename': quote(os.path.basename(p))}\n # r = httpx...\n```\n\n```py\nfrom fastapi import FastAPI, Request, HTTPException, status\nfrom streaming_form_data import StreamingFormDataParser\nfrom streaming_form_data.targets import FileTarget, ValueTarget\nfrom streaming_form_data.validators import MaxSizeValidator\nimport streaming_form_data\nfrom starlette.requests import ClientDisconnect\nfrom urllib.parse import unquote\nimport os\n\nMAX_FILE_SIZE = 1024 * 1024 * 1024 * 4 # = 4GB\nMAX_REQUEST_BODY_SIZE = MAX_FILE_SIZE + 1024\n\napp = FastAPI()\n\nclass MaxBodySizeException(Exception):\n def __init__(self, body_len: str):\n self.body_len = body_len\n\nclass MaxBodySizeValidator:\n def __init__(self, max_size: int):\n self.body_len = 0\n self.max_size = max_size\n\n def __call__(self, chunk: bytes):\n self.body_len += len(chunk)\n if self.body_len > self.max_size:\n raise MaxBodySizeException(body_len=self.body_len)\n \n@app.post('/upload')\nasync def upload(request: Request):\n body_validator = MaxBodySizeValidator(MAX_REQUEST_BODY_SIZE)\n filename = request.headers.get('filename')\n \n if not filename:\n raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, \n detail='Filename header is missing')\n try:\n filename = unquote(filename)\n filepath = os.path.join('./', os.path.basename(filename)) \n file_ = FileTarget(filepath, validator=MaxSizeValidator(MAX_FILE_SIZE))\n data = ValueTarget()\n parser = StreamingFormDataParser(headers=request.headers)\n parser.register('file', file_)\n parser.register('data', data)\n \n async for chunk in request.stream():\n body_validator(chunk)\n parser.data_received(chunk)\n except ClientDisconnect:\n print(\"Client Disconnected\")\n except MaxBodySizeException as e:\n raise HTTPException(status_code=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE, \n detail=f'Maximum request body size limit ({MAX_REQUEST_BODY_SIZE} bytes) exceeded ({e.body_len} bytes read)')\n except streaming_form_data.validators.ValidationError:\n raise HTTPException(status_code=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE, \n detail=f'Maximum file size limit ({MAX_FILE_SIZE} bytes) exceeded') \n except Exception:\n raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, \n detail='There was an error uploading the file') \n \n if not file_.multipart_filename:\n raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail='File is missing')\n\n print(data.value.decode())\n print(file_.multipart_filename)\n \n return {\"message\": f\"Successfuly uploaded {filename}\"}\n```\n\n```py\nimport httpx\nimport time\nfrom urllib.parse import quote\n\nurl ='http://127.0.0.1:8000/upload'\nfilename = 'bigFile.zip'\nfiles = {'file': open(filename, 'rb')}\nheaders = {'filename': quote(filename)}\ndata = {'data': 'Hello World!'}\n\nwith httpx.Client() as client:\n start = time.time()\n r = client.post(url, data=data, files=files, headers=headers)\n end = time.time()\n print(f'Time elapsed: {end - start}s')\n print(r.status_code, r.json(), sep=' ')\n```\n\n```py\nfrom fastapi import FastAPI, Request, HTTPException, status\nfrom fastapi.responses import HTMLResponse\nfrom fastapi.templating import Jinja2Templates\nfrom starlette.requests import ClientDisconnect\nfrom urllib.parse import unquote\nimport streaming_form_data\nfrom streaming_form_data import StreamingFormDataParser\nfrom streaming_form_data.targets import FileTarget, ValueTarget\nimport os\n\napp = FastAPI()\ntemplates = Jinja2Templates(directory=\"templates\")\n\n\n@app.get(\"/\", response_class=HTMLResponse)\nasync def main(request: Request):\n return templates.TemplateResponse(request=request, name=\"index.html\")\n\n\n@app.post('/upload')\nasync def upload(request: Request):\n try:\n parser = StreamingFormDataParser(headers=request.headers)\n data = ValueTarget()\n parser.register('data', data)\n\n headers = dict(request.headers)\n filenames = []\n i = 0\n while True:\n filename = headers.get(f'filename{i}', None)\n if filename is None:\n break\n filename = unquote(filename)\n filenames.append(filename)\n filepath = os.path.join('./', os.path.basename(filename)) \n file_ = FileTarget(filepath)\n parser.register(f'file{i}', file_)\n i += 1\n\n async for chunk in request.stream():\n parser.data_received(chunk)\n except ClientDisconnect:\n print(\"Client Disconnected\")\n except Exception:\n raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, \n detail='There was an error uploading the file') \n\n print(data.value.decode())\n return {\"message\": f\"Successfuly uploaded {filenames}\"}\n```\n\n```html\n<!DOCTYPE html>\n<html>\n <body>\n <input type=\"file\" id=\"fileInput\" name=\"files\" onchange=\"reset()\" multiple><br>\n <input type=\"button\" value=\"Submit\" onclick=\"submitUsingFetch()\">\n <p id=\"response\"></p>\n <script>\n var resp = document.getElementById(\"response\");\n \n function reset() {\n resp.innerHTML = \"\";\n }\n \n function submitUsingFetch() {\n var fileInput = document.getElementById('fileInput');\n if (fileInput.files[0]) {\n var formData = new FormData();\n var headers = new Headers();\n formData.append(\"data\", \"Hello World!\");\n \n var i = 0;\n for (const file of fileInput.files) {\n filename = encodeURI(file.name);\n headers.append(`filename${i}`, filename);\n formData.append(`file${i}`, file, filename);\n i++;\n }\n \n fetch('/upload', {\n method: 'POST',\n headers: headers,\n body: formData,\n })\n .then(response => response.json()) // or, response.text(), etc.\n .then(data => {\n resp.innerHTML = JSON.stringify(data); // data is a JSON object\n })\n .catch(error => {\n console.error(error);\n });\n }\n }\n </script>\n </body>\n</html>\n```\n\n```py\nimport httpx\nimport time\nfrom urllib.parse import quote\n\nurl ='http://127.0.0.1:8000/upload'\nfilename0 = 'bigFile.zip'\nfilename1 = 'otherBigFile.zip'\nheaders = {'filename0': quote(filename0), 'filename1': quote(filename1)}\nfiles = [('file0', open(filename0, 'rb')), ('file1', open(filename1, 'rb'))]\ndata = {'data': 'Hello World!'}\n\nwith httpx.Client() as client:\n start = time.time()\n r = client.post(url, data=data, files=files, headers=headers)\n end = time.time()\n print(f'Time elapsed: {end - start}s')\n print(r.status_code, r.json(), sep=' ')\n```\n\n```py\n#...\nfrom fastapi import Form\nfrom pydantic import BaseModel, ValidationError\nfrom typing import Optional\nfrom fastapi.encoders import jsonable_encoder\n\n#...\n\nclass Base(BaseModel):\n name: str\n point: Optional[float] = None\n is_accepted: Optional[bool] = False\n \ndef checker(data: str = Form(...)):\n try:\n return Base.model_validate_json(data)\n except ValidationError as e:\n raise HTTPException(detail=jsonable_encoder(e.errors()), status_code=status.HTTP_422_UNPROCESSABLE_ENTITY)\n \n\n@app.post('/upload')\nasync def upload(request: Request):\n #...\n \n # place the below after the try-except block in the example given earlier\n model = checker(data.value.decode())\n print(dict(model))\n```\n\n```py\n#...\nimport json\n\ndata = {'data': json.dumps({\"name\": \"foo\", \"point\": 0.13, \"is_accepted\": False})}\n#...\n```\n\n```py\nfrom fastapi import FastAPI, File, UploadFile, Form, HTTPException, status\nimport aiofiles\nimport os\n\nCHUNK_SIZE = 1024 * 1024 # adjust the chunk size as desired\napp = FastAPI()\n\n@app.post(\"/upload\")\nasync def upload(file: UploadFile = File(...), data: str = Form(...)):\n try:\n filepath = os.path.join('./', os.path.basename(file.filename))\n async with aiofiles.open(filepath, 'wb') as f:\n while chunk := await file.read(CHUNK_SIZE):\n await f.write(chunk)\n except Exception:\n raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, \n detail='There was an error uploading the file')\n finally:\n await file.close()\n\n return {\"message\": f\"Successfuly uploaded {file.filename}\"}\n```\n\n```py\nimport httpx\nimport time\n\nurl ='http://127.0.0.1:8000/upload'\nfiles = {'file': open('bigFile.zip', 'rb')}\ndata = {'data': 'Hello World!'}\ntimeout = httpx.Timeout(None, read=180.0)\n\nwith httpx.Client(timeout=timeout) as client:\n start = time.time()\n r = client.post(url, data=data, files=files)\n end = time.time()\n print(f'Time elapsed: {end - start}s')\n print(r.status_code, r.json(), sep=' ')\n```\n\n```text\nrequests-toolbelt\n```\n\n```text\nfilename\n```\n\n```text\nfield\n```\n\n```text\nupload_file\n```\n\n```text\nContent-Type\n```\n\n```text\nContent-Type\n```\n\n```text\nmultipart/form-data\n```\n\n```text\nboundary\n```\n\n```text\nrequests-toolbelt\n```\n\n```text\nrequests\n```\n\n```text\nhttpx\n```\n\n```text\nasync\n```\n\n```text\nFile\n```\n\n```text\n.stream()\n```\n\n```text\nUploadFile\n```\n\n```text\nSpooledTemporaryFile\n```\n\n```text\nmax_size\n```\n\n```text\nmax_size\n```\n\n```text\ntemporary\n```\n\n```text\n.read()\n```\n\n```text\nrequest\n```\n\n```text\nrequest.stream()\n```\n\n```text\nForm\n```\n\n```text\nFile\n```\n\n```text\nForm\n```\n\n```text\n.stream()\n```\n\n```text\nstreaming-form-data\n```\n\n```text\nmultipart/form-data\n```\n\n```text\nForm\n```\n\n```text\nFile(s)\n```\n\n```text\nheaders\n```\n\n```text\nContent-Type\n```\n\n```text\nboundary\n```\n\n```text\nTarget\n```\n\n```text\nFileTarget\n```\n\n```text\nValueTarget\n```\n\n```text\nValueTarget\n```\n\n```text\nForm\n```\n\n```text\nFile\n```\n\n```text\nTarget\n```\n\n```text\nstreaming-form-data\n```\n\n```text\nasync\n```\n\n```text\nsync\n```\n\n```text\ndef\n```\n\n```text\n.stream()\n```\n\n```text\nasync def\n```\n\n```text\nawait\n```\n\n```text\nrun_in_threadpool()\n```\n\n```text\nawait run_in_threadpool(parser.data_received, chunk)\n```\n\n```text\nasync\n```\n\n```text\nUploadFile\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\nUploadFile\n```\n\n```text\nUploadFile\n```\n\n```text\nMaxSizeValidator\n```\n\n```text\nMaxBodySizeValidator\n```\n\n```text\nUploadFile\n```\n\n```text\nlimits\n```\n\n```text\nclient_max_body_size\n```\n\n```text\nRequest\n```\n\n```text\nUploadFile\n```\n\n```text\nForm\n```\n\n```text\n/docs\n```\n\n```text\ndata\n```\n\n```text\ndata.value\n```\n\n```text\nmultipart/form-data\n```\n\n```text\nisinstance(data.value, str)\n```\n\n```text\nfile_.multipart_filename\n```\n\n```text\nfilename\n```\n\n```text\nContent-Disposition\n```\n\n```text\nos.path.isfile(filepath)\n```\n\n```text\nTrue\n```\n\n```text\nMAX_REQUEST_BODY_SIZE\n```\n\n```text\nMAX_FILE_SIZE\n```\n\n```text\nForm\n```\n\n```text\n.stream()\n```\n\n```text\n--boundary\n```\n\n```text\nContent-Disposition\n```\n\n```text\nForm\n```\n\n```text\nMAX_FILE_SIZE + 1024\n```\n\n```text\nHTTPX\n```\n\n```text\nForm\n```\n\n```text\ndata\n```\n\n```text\nfilename\n```\n\n```text\nFileTarget\n```\n\n```text\nX-\n```\n\n```text\nFile\n```\n\n```text\nForm\n```\n\n```text\n.stream()\n```\n\n```text\nstreaming-form-data\n```\n\n```text\nfilepath\n```\n\n```text\nFileTarget()\n```\n\n```text\nFileTarget\n```\n\n```text\nValueTarget\n```\n\n```text\nrequest.stream()\n```\n\n```text\nfile_.multipart_filename\n```\n\n```text\nos.rename()\n```\n\n```text\nhttpx\n```\n\n```text\nfiles = [('file0', open('bigFile.zip', 'rb')),('file1', open('otherBigFile.zip', 'rb'))]\n```\n\n```text\n/\n```\n\n```text\nFile\n```\n\n```text\nJSON\n```\n\n```text\nForm\n```\n\n```text\nForm\n```\n\n```text\nFile\n```\n\n```text\nForm\n```\n\n```text\nUploadFile\n```\n\n```text\nForm\n```\n\n```text\nawait request.form()\n```\n\n```text\ndef\n```\n\n```text\nHTTPX\n```\n\n```text\nReadTimeout\n```\n\n```text\nSpooledTemporaryFile\n```\n\n```text\nTimeout\n```\n\n```text\nread\n```\n\n```text\nNone\n```\n\n```text\nread\n```\n\n========================================\n\nComments:\n- Thanks, and the reason I use this library is that I found somewhere saying it could help dealing with large files upload. And I just tried to upload a 3GB file using requests and encountered memory error(server only has a free memory of 2G). Are there any choices to implement this feature?\n- Please have a look at this answer and this answer on how to read the file in chunks on server side, hence avoiding loading the entire file into memory. The `requests-toolbelt` lib allows you to avoid loading the entire file into memory before being sent to the server (i.e., on client side). The equivalent of that in `requests` lib is Streaming uploads or Chunk-Encoded Requests.\n- Why would Option 1 not run into the default timeout of 5s?\n- Can you please give an example of \"finally, define the Target classes on server side accordingly\" for multiple file uploads? Not sure how to do this properly.\n- @nb123 The answer above has been updated with a relevant example on how to upload multiple files and form data, using the *fast* approach. Please have a look.\n- @Chris thank you so much! As an extension of my previous qn - how do you validate the ContentType of the file when reading in a stream? If there is no direct way, what is the security best practice to ensure you only accept a particular file extension (eg: .pdf)?\n- @nb123 You could simply check a file's extension by extracting the extension part from the `filename` that is sent in the `headers` (using the examples of Option 1 above). Alternatively (or, in addition to that), you could use `python-magic` library - please have a look at this answer, under **MIME Type** section, for more details.","metadata":{"transformedAt":"2026-08-18T18:32:29.097Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":137,"totalLines":961,"estimatedTokens":4653}}87{"id":"stack-64160594","source":"stackoverflow","questionId":64160594,"title":"FastAPI - ENUM type models not populated","tags":["python","swagger","openapi","fastapi","pydantic"],"text":"Title: FastAPI - ENUM type models not populated\nTags: python, swagger, openapi, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nBelow is my fastAPI code\n\n```\nfrom typing import Optional, Set\n\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel, HttpUrl, Field\nfrom enum import Enum\n\napp = FastAPI()\n\nclass Status(Enum):\n RECEIVED = 'RECEIVED'\n CREATED = 'CREATED'\n CREATE_ERROR = 'CREATE_ERROR'\n\nclass Item(BaseModel):\n name: str\n description: Optional[str] = None\n price: float\n tax: Optional[float] = None\n tags: Set[str] = []\n status: Status = None\n\n@app.put(\"/items/{item_id}\")\nasync def update_item(item_id: int, item: Item):\n results = {\"item_id\": item_id, \"item\": item}\n return results\n```\n\nBelow is the swagger doc generated. The Status is not shown. I am new to pydantic and i am not sure on how to show status in the docs\n\nhttps://i.sstatic.net/vOI2n.png\n\n========================================\n\nCode:\n```text\nfrom typing import Optional, Set\n\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel, HttpUrl, Field\nfrom enum import Enum\n\napp = FastAPI()\n\n\nclass Status(Enum):\n RECEIVED = 'RECEIVED'\n CREATED = 'CREATED'\n CREATE_ERROR = 'CREATE_ERROR'\n\n\nclass Item(BaseModel):\n name: str\n description: Optional[str] = None\n price: float\n tax: Optional[float] = None\n tags: Set[str] = []\n status: Status = None\n\n\n@app.put(\"/items/{item_id}\")\nasync def update_item(item_id: int, item: Item):\n results = {\"item_id\": item_id, \"item\": item}\n return results\n```\n\n```text\nclass Status(str, Enum):\n RECEIVED = 'RECEIVED'\n CREATED = 'CREATED'\n CREATE_ERROR = 'CREATE_ERROR'\n```\n\n```text\nStatus\n```\n\n```text\nstr\n```\n\n```text\nEnum\n```\n\n========================================\n\nComments:\n- I am using this example but I get 422 Unprocessable Entity\n- How can we add Enum options via code script? I would like to fetch the options from DB using Python\n- You can create an `Enum` on the fly using `CustomEnum = Enum(\"CustomEnum\", custom_enum_values)` (where `custom_enum_values` is a `Dict[str,str]`) and then just use the `CustomEnum` type in the `BaseModel`: github.com/tiangolo/fastapi/issues/13","metadata":{"transformedAt":"2026-08-18T18:32:29.097Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":98,"estimatedTokens":539}}88{"id":"stack-61582142","source":"stackoverflow","questionId":61582142,"title":"Test Pydantic settings in FastAPI","tags":["python","testing","fastapi","pydantic"],"text":"Title: Test Pydantic settings in FastAPI\nTags: python, testing, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nSuppose my `main.py` is like this (this is a simplified example, in my app I use an actual database and I have two different database URIs for development and testing):\n\n```\nfrom fastapi import FastAPI\nfrom pydantic import BaseSettings\n\napp = FastAPI()\n\nclass Settings(BaseSettings):\n ENVIRONMENT: str\n\n class Config:\n env_file = \".env\"\n case_sensitive = True\n\nsettings = Settings()\n\ndatabases = {\n \"dev\": \"Development\",\n \"test\": \"Testing\"\n}\ndatabase = databases[settings.ENVIRONMENT]\n\n@app.get(\"/\")\ndef read_root():\n return {\"Environment\": database}\n```\n\nwhile the `.env` is\n\n```\nENVIRONMENT=dev\n```\n\nSuppose I want to test my code and I want to set `ENVIRONMENT=test` to use a testing database. What should I do? In FastAPI documentation (https://fastapi.tiangolo.com/advanced/settings/#settings-and-testing) there is a good example but it is about dependencies, so it is a different case as far as I know.\n\nMy idea was the following (`test.py`):\n\n```\nimport pytest\n\nfrom fastapi.testclient import TestClient\n\nfrom main import app\n\n@pytest.fixture(scope=\"session\", autouse=True)\ndef test_config(monkeypatch):\n monkeypatch.setenv(\"ENVIRONMENT\", \"test\")\n\n@pytest.fixture(scope=\"session\")\ndef client():\n return TestClient(app)\n\ndef test_root(client):\n response = client.get(\"/\")\n assert response.status_code == 200\n assert response.json() == {\"Environment\": \"Testing\"}\n```\n\nbut it doesn't work.\n\nFurthermore I get this error:\n\n```\nScopeMismatch: You tried to access the 'function' scoped fixture 'monkeypatch' with a 'session' scoped request object, involved factories\ntest.py:7: def test_config(monkeypatch)\nenv\\lib\\site-packages\\_pytest\\monkeypatch.py:16: def monkeypatch()\n```\n\nwhile from `pytest` official documentation it should work (https://docs.pytest.org/en/3.0.1/monkeypatch.html#example-setting-an-environment-variable-for-the-test-session). I have the latest version of `pytest` installed.\n\nI tried to use specific test environment variables because of this: https://pydantic-docs.helpmanual.io/usage/settings/#field-value-priority.\n\nTo be honest I'm lost, my only real aim is to have a different test configuration (in the same way Flask works: https://flask.palletsprojects.com/en/1.1.x/tutorial/tests/#setup-and-fixtures). Am I approaching the problem the wrong way?\n\n========================================\n\nTop Answer:\nBumping an old thread because I found a solution that was a bit cleaner for my use case. I was having trouble getting test specific dotenv files to load only while tests were running and when I had a local development dotenv in the project dir.\n\nYou can do something like the below where `test.enviornment` is a special dotenv file that is NOT an `env_file` path in the settings class Config. Because env vars > dotenv for BaseSettings, this will override any settings from a local .env as long as this is run in conftest.py before your settings class is imported. It also guarantees that your test environment is only active when tests are being run.\n\n```\n#conftest.py\nfrom dotenv import load_dotenv\nload_dotenv(\"tests/fixtures/test.environment\", override=True)\n\nfrom app import settings # singleton instance of BaseSettings class\n```\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI\nfrom pydantic import BaseSettings\n\napp = FastAPI()\n\nclass Settings(BaseSettings):\n ENVIRONMENT: str\n\n class Config:\n env_file = \".env\"\n case_sensitive = True\n\nsettings = Settings()\n\ndatabases = {\n \"dev\": \"Development\",\n \"test\": \"Testing\"\n}\ndatabase = databases[settings.ENVIRONMENT]\n\n@app.get(\"/\")\ndef read_root():\n return {\"Environment\": database}\n```\n\n```text\nENVIRONMENT=dev\n```\n\n```py\nimport pytest\n\nfrom fastapi.testclient import TestClient\n\nfrom main import app\n\n@pytest.fixture(scope=\"session\", autouse=True)\ndef test_config(monkeypatch):\n monkeypatch.setenv(\"ENVIRONMENT\", \"test\")\n\n@pytest.fixture(scope=\"session\")\ndef client():\n return TestClient(app)\n\ndef test_root(client):\n response = client.get(\"/\")\n assert response.status_code == 200\n assert response.json() == {\"Environment\": \"Testing\"}\n```\n\n```text\nScopeMismatch: You tried to access the 'function' scoped fixture 'monkeypatch' with a 'session' scoped request object, involved factories\ntest.py:7: def test_config(monkeypatch)\nenv\\lib\\site-packages\\_pytest\\monkeypatch.py:16: def monkeypatch()\n```\n\n```text\nmain.py\n```\n\n```text\n.env\n```\n\n```text\nENVIRONMENT=test\n```\n\n```text\ntest.py\n```\n\n```text\npytest\n```\n\n```text\npytest\n```\n\n```text\nfrom main import settings\n\nsettings.ENVIRONMENT = 'test'\n```\n\n```text\nPydanticSettings\n```\n\n```text\ntest.py\n```\n\n```py\n...\n\nclass Settings(BaseSettings):\n ENVIRONMENT: str\n\n class Config:\n env_file = \".env\"\n case_sensitive = True\n\ndef get_settings() -> Settings:\n return Settings()\n\ndatabases = {\n \"dev\": \"Development\",\n \"test\": \"Testing\"\n}\ndatabase = databases[get_settings().ENVIRONMENT]\n\n@app.get(\"/\")\ndef read_root():\n return {\"Environment\": database}\n```\n\n```py\nimport pytest\nfrom main import get_settings\n\ndef get_settings_override() -> Settings:\n return Settings(ENVIRONMENT=\"dev\")\n\n@pytest.fixture(autouse=True)\ndef override_settings() -> None:\n app.dependency_overrides[get_settings] = get_settings_override\n```\n\n```text\nget_settings\n```\n\n```text\nENVIRONMENT\n```\n\n```text\nDEV_DSN='DSN=my_dev_dsn; UID=my_dev_user_id; PWD=my_dev_password'\nPROD_DSN='DSN=my_prod_dsn; UID=my_prod_user_id; PWD=my_prod_password'\n```\n\n```text\nexport MY_ENVIORONMENT=DEV\n```\n\n```text\nfrom pydantic import BaseSettings\nimport os\n\nclass Settings(BaseSettings):\n DSN: str\n\n class Config():\n env_prefix = f\"{os.environ['MY_ENVIORONMENT']}_\"\n env_file = \"APPNAME.cfg\"\n```\n\n```text\nfrom settings import Settings\n\ns = Settings()\ndb = pyodbc.connect(s.DSN)\n```\n\n```py\n#conftest.py\nfrom dotenv import load_dotenv\nload_dotenv(\"tests/fixtures/test.environment\", override=True)\n\nfrom app import settings # singleton instance of BaseSettings class\n```\n\n```text\ntest.enviornment\n```\n\n```text\nenv_file\n```\n\n```ini\n[tool.pytest.ini_options]\nenv = [\"DEBUG=False\"]\n```\n\n```text\nDEBUG=False pytest\n```\n\n```text\npyproject.toml\n```\n\n```text\npytest-env\n```\n\n```text\n[tool.pytest_env]\nENV_KEY = \"some-value\"\n```\n\n========================================\n\nComments:\n- Thanks for the input but, alas, it doesn't seem to work anyways. I did exactly as you told. Maybe for the dependency to work you have to use `Depends`? Can you by any chance provide a minimal working example of a test for your proposal?\n- This is right for certain situations. What the documentation neglects to say is that Depends in FastAPI only works on routes (or dependencies called from routes), not your own methods. More in this question and this issue\n- True unless `allow_mutation = False` is passed to the `Config` object of the settings.\n- Simple yet effective!\n- Should the developer manually revert the setting back to initial value?\n- If you use this trick in your tests - no\n- Use `monkeypatch.setattr(settings, 'ENVIRONMENT', 'test')`.\n- maybe need to do this before importing the fastapi app object\n- thx - this really helps and is much cleaner","metadata":{"transformedAt":"2026-08-18T18:32:29.097Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":29,"totalLines":315,"estimatedTokens":1818}}89{"id":"stack-74179020","source":"stackoverflow","questionId":74179020,"title":"The unique() method must be invoked on this Result exception raised after SQLAlchemy Select","tags":["python","sqlalchemy","fastapi"],"text":"Title: The unique() method must be invoked on this Result exception raised after SQLAlchemy Select\nTags: python, sqlalchemy, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have an issue with SQLAlchemy and I cannot figure out the cause of this error:\n\nso my class definition is:\n\n```\nclass PricingFrequency(enum.Enum):\n month = 'month'\n year = 'year'\n\nclass PlanPricing(Base):\n __tablename__ = \"PlansPricing\"\n pricing_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)\n .....\n subscription_plan = relationship(\"SubscriptionPlan\", back_populates=\"plans_pricing\")\n plan_id = Column(UUID(as_uuid=True), ForeignKey(\"SubscriptionPlans.plan_id\"))\n\n created_on = Column(DateTime, server_default=func.now())\n updated_on = Column(DateTime, server_default=func.now(), server_onupdate=func.now())\n\nclass SubscriptionPlanOption(Base):\n __tablename__ = \"SubscriptionPlanOptions\"\n option_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)\n .....\n subscription_plan = relationship(\"SubscriptionPlan\", back_populates=\"options_plan\")\n plan_id = Column(UUID(as_uuid=True), ForeignKey(\"SubscriptionPlans.plan_id\"))\n\n created_on = Column(DateTime, server_default=func.now())\n updated_on = Column(DateTime, server_default=func.now(), server_onupdate=func.now())\n\nclass SubscriptionPlan(Base):\n __tablename__ = \"SubscriptionPlans\"\n plan_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)\n plan_name = Column(String)\n plan_description = Column(String)\n is_popular = Column(Boolean, default=False)\n\n plans_pricing: List[Any] = relationship(\"PlanPricing\", back_populates=\"subscription_plan\") # , lazy='joined')\n options_plan: List[Any] = relationship(\"SubscriptionPlanOption\",\n back_populates=\"subscription_plan\") # lazy='joined')\n\n created_on = Column(DateTime, server_default=func.now())\n updated_on = Column(DateTime, server_default=func.now(), server_onupdate=func.now())\n```\n\nWhen I make this query :\n\n```\nquery = (\n select(SubscriptionPlan)\n .options(joinedload(SubscriptionPlan.options_plan, innerjoin=True),\n joinedload(SubscriptionPlan.plans_pricing.and_(PlanPricing.pricing_id == pricing_id),\n innerjoin=True))\n )\n items = await session.execute(query)\n items = items.scalars().all()\n```\n\nI got this error message:\n\n```\n**The unique() method must be invoked on this Result, as it contains results that include joined eager loads against collections**\n```\n\n**Note : session is AsyncSession**\n\nCan anyone explain the source of this issue?\nThanks\n\n========================================\n\nTop Answer:\nIn addition to the answer of Louis Huang (https://stackoverflow.com/a/76603245):\n\nIf we use async it is needed to chain the unique() to the awaited result.\n\n```\nstatement = select(Order)\nresult = await session.execute(statement)\norders = result.unique().scalars().all()\n```\n\n========================================\n\nCode:\n```text\nclass PricingFrequency(enum.Enum):\n month = 'month'\n year = 'year'\n\n\nclass PlanPricing(Base):\n __tablename__ = \"PlansPricing\"\n pricing_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)\n .....\n subscription_plan = relationship(\"SubscriptionPlan\", back_populates=\"plans_pricing\")\n plan_id = Column(UUID(as_uuid=True), ForeignKey(\"SubscriptionPlans.plan_id\"))\n\n created_on = Column(DateTime, server_default=func.now())\n updated_on = Column(DateTime, server_default=func.now(), server_onupdate=func.now())\n\n\nclass SubscriptionPlanOption(Base):\n __tablename__ = \"SubscriptionPlanOptions\"\n option_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)\n .....\n subscription_plan = relationship(\"SubscriptionPlan\", back_populates=\"options_plan\")\n plan_id = Column(UUID(as_uuid=True), ForeignKey(\"SubscriptionPlans.plan_id\"))\n\n created_on = Column(DateTime, server_default=func.now())\n updated_on = Column(DateTime, server_default=func.now(), server_onupdate=func.now())\n\n\nclass SubscriptionPlan(Base):\n __tablename__ = \"SubscriptionPlans\"\n plan_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)\n plan_name = Column(String)\n plan_description = Column(String)\n is_popular = Column(Boolean, default=False)\n\n plans_pricing: List[Any] = relationship(\"PlanPricing\", back_populates=\"subscription_plan\") # , lazy='joined')\n options_plan: List[Any] = relationship(\"SubscriptionPlanOption\",\n back_populates=\"subscription_plan\") # lazy='joined')\n\n created_on = Column(DateTime, server_default=func.now())\n updated_on = Column(DateTime, server_default=func.now(), server_onupdate=func.now())\n```\n\n```text\nquery = (\n select(SubscriptionPlan)\n .options(joinedload(SubscriptionPlan.options_plan, innerjoin=True),\n joinedload(SubscriptionPlan.plans_pricing.and_(PlanPricing.pricing_id == pricing_id),\n innerjoin=True))\n )\n items = await session.execute(query)\n items = items.scalars().all()\n```\n\n```text\n**The unique() method must be invoked on this Result, as it contains results that include joined eager loads against collections**\n```\n\n```text\nsqlalchemy.exc.InvalidRequestError: The unique() method must be invoked on this Result, as it contains results that include joined eager loads against collections\n```\n\n```py\nsession.execute(query).unique()\n```\n\n```text\njoinedload()\n```\n\n```text\nResult.unique()\n```\n\n```text\nResult.unique()\n```\n\n```text\nunique()\n```\n\n```text\nResult\n```\n\n```text\nplan_pricing_aliased1 = aliased(PlanPricing)\nplan_pricing_aliased2 = aliased(PlanPricing)\nquery = (\n select(\n plan_pricing_aliased1.pricing_id, \n plan_pricing_aliased2.pricing_id\n ).join_from(\n plan_pricing_aliased1,\n plan_pricing_aliased2,\n and_(\n plan_pricing_aliased2.currency == plan_pricing_aliased1.currency,\n plan_pricing_aliased2.plan_id == plan_pricing_aliased1.plan_id,\n plan_pricing_aliased2.pricing_frequency == plan_pricing_aliased1.pricing_frequency\n )\n ).where(\n and_(\n plan_pricing_aliased1.pricing_id == pricing_id,\n plan_pricing_aliased1.price > 0,\n plan_pricing_aliased2.price == 0\n )\n )\n)\nitems = await session.execute(query)\nitems = items.first()\nreturn items\n```\n\n```text\nstatement = select(Order)\nresult = await session.execute(statement)\norders = result.unique().scalars().all()\n```\n\n========================================\n\nComments:\n- `https://stackoverflow.com/questions/47243397/sqlalchemy-join‌​edload-filter-column`\n- Thanks. I have read this before and it does not work also with contains_eager. same error message. Not that I am using AsyncSession and not Session.\n- query = ( select(SubscriptionPlan) .join(SubscriptionPlan.plans_pricing) .join(SubscriptionPlan.options_plan) .options(contains_eager(SubscriptionPlan.options_plan), contains_eager(SubscriptionPlan.plans_pricing)) .where(PlanPricing.pricing_id == pricing_id) ) items = await session.execute(query) items = items.scalars().all()\n- As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.","metadata":{"transformedAt":"2026-08-18T18:32:29.097Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":12,"totalLines":216,"estimatedTokens":1842}}90{"id":"stack-64236572","source":"stackoverflow","questionId":64236572,"title":"FastAPI TypeError: Object of type 'ModelMetaclass' is not JSON serializable","tags":["python-3.x","fastapi"],"text":"Title: FastAPI TypeError: Object of type 'ModelMetaclass' is not JSON serializable\nTags: python-3.x, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm getting this error, the models migrate successfully when i run `uvicorn main:app --reload` but when i tried to go to 127.0.0.1:8000/docs i got this error. I'm using Postgresql for the database\n\n```\nTypeError: Object of type 'ModelMetaclass' is not JSON serializable\n```\n\nThis is my file structure\n\n```\nbackend/main.py\nbackend/pydantic_models.py\nbackend/requirements.txt\nbackend/sql\nbackend/sql/crud.py\nbackend/sql/database.py\nbackend/sql/sql_models.py\nbackend/sql/__init__.py\n```\n\nI followed the tutorial on https://fastapi.tiangolo.com/tutorial/sql-databases/\nHere is the code.\n**main.py**\n\n```\nfrom typing import List\n\nfrom fastapi import FastAPI, Depends, HTTPException, status\nfrom sqlalchemy.orm import Session\n\nfrom sql import crud, database, sql_models\nfrom pydantic_models import User, Todo, UserCreation, TodoCreation\n\nsql_models.Base.metadata.create_all(bind=database.engine)\n\napp = FastAPI()\n\ndef get_db():\n db = database.SessionLocal()\n try:\n yield db\n finally:\n db.close()\n\n@app.post(\"/users/\", response_model=User)\ndef create_user(user=User, db: Session = Depends(get_db)):\n db_user_email = crud.get_user_by_email(db, email=user.email)\n db_user_name = crud.get_user\n if db_user:\n raise HTTPException(status_code=status.HTTP_400_BAD,\n detail=\"Email already taken\")\n return crud.create_user(db=db, user=user)\n\n@app.get(\"/users/\", response_model=List[User])\ndef read_all_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):\n users = crud.get_all_users(db, skip=skip, limit=limit)\n return users\n\n@app.get(\"/users/{user_id}\", response_model=User)\ndef read_user(user_id: int, db: Session = Depends(get_db)):\n db_user = crud.get_user(db, user_id=user_id)\n if db_user is None:\n raise HTTPException(\n status_code=status.HTTP_404_NOT_FOUND, detail=\"User not found\")\n return db_user\n\n@app.post(\"/users/{user_id}/todo/\", response_model=Todo)\ndef create_todo_list(user_id: int, todo: TodoCreation, db: Session = Depends(get_db)):\n return crud.create_todo(db=db, todo=todo, user_id=user_id)\n\n@app.get(\"/items/\", response_model=List[Todo])\ndef read_todo(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):\n todos = crud.get_todo(db, skip=skip, limit=limit)\n return todos\n```\n\n**pydantic_models.py**\n\n```\nfrom typing import List, Optional\nfrom pydantic import BaseModel\n\n# Todo model\nclass TodoBase(BaseModel):\n title: str\n description: Optional[str] = None\n\nclass TodoCreation(TodoBase):\n pass\n\nclass Todo(TodoBase):\n id: int\n owner_id: int\n\n class Config:\n orm_mode = True\n \n# User model\nclass UserBase(BaseModel):\n username: str\n email: str\n\nclass UserCreation(UserBase):\n password: str\n\nclass User(UserBase):\n id: int\n is_active: bool\n todo: List[Todo] = []\n\n class Config:\n orm_mode = True\n```\n\nsql.**crud.py**\n\n```\nfrom sqlalchemy.orm import Session\n\nfrom . import sql_models\nimport pydantic_models\n\n# Get single user\ndef get_user(db: Session, user_id: int):\n return db.query(sql_models.User).filter(models.User.id == user_id).first()\n\ndef get_user_by_name(db: Session, username: str):\n return db.query(sql_models.User).filter(models.User.username == username).first()\n\n# Get user by email\ndef get_user_by_email(db: Session, email: str):\n return db.query(sql_models.User).filter(models.User.email == email).first()\n\n# Get all users\ndef get_all_users(db: Session, skip: int = 0, limit: int = 100):\n return db.query(sql_models.User).offset(skip).limit(limit).all()\n\n# Create a user\ndef create_user(db: Session, user: pydantic_models.UserCreation):\n fake_hashed_password = user.password + \"fakehash\" # Hashed user's password\n db_user = sql_models.User(username=user.username, email=user.email, password=fake_hashed_password)\n db.add(db_user)\n db.commit()\n db.refresh(db_user)\n return db_user\n\ndef get_todo(db: Session, skip: int = 0, limit: int = 100):\n return db.query(sql_models.Todo).offset(skip).limit(limit).all()\n\ndef create_todo(db: Session, todo: pydantic_models.TodoCreation, user_id: int):\n db_item = models.Item(**item.dict(), owner_id=user_id)\n db.add(db_item)\n db.commit()\n db.refresh(db_item)\n return db_item\n```\n\nsql.**database.py**\n\n```\nimport os\n\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import sessionmaker\n\nSQLALCHEMY_DATABASE_URL = os.environ[\"POSTGRES_LINK\"]\nengine = create_engine(SQLALCHEMY_DATABASE_URL)\nSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)\n\nBase = declarative_base()\n```\n\nsql.**sql_models.py**\n\n```\nfrom sql.database import Base\n\nfrom sqlalchemy import Boolean, Column, ForeignKey, Integer, String\nfrom sqlalchemy.orm import relationship\n\nclass User(Base):\n __tablename__ = \"users\"\n\n id = Column(Integer, primary_key=True, index=True)\n username = Column(String, unique=True, index=True)\n email = Column(String, unique=True, index=True)\n password = Column(String)\n is_active = Column(Boolean, default=True)\n\n todo = relationship(\"Todo\", back_populates=\"owner\")\n\nclass Todo(Base):\n __tablename__ = \"todo\"\n\n id = Column(Integer, primary_key=True, index=True)\n title = Column(String, index=True)\n description = Column(String, index=True)\n owner_id = Column(Integer, ForeignKey(\"users.id\"))\n\n owner = relationship(\"User\", back_populates=\"todo\")\n```\n\nhere is the full error\n\n```\nINFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\nINFO: Started reloader process [6844] using statreload\nINFO: Started server process [2484]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\nINFO: 127.0.0.1:51303 - \"GET /docs HTTP/1.1\" 200 OK\nINFO: 127.0.0.1:51303 - \"GET /openapi.json HTTP/1.1\" 500 Internal Server ErrorERROR: Exception in ASGI application\nTraceback (most recent call last):\n File \"c:\\users\\bryan\\source\\repos\\todoapp\\backend\\env\\lib\\site-packages\\uvicorn\\protocols\\http\\h11_impl.py\", line 388, in run_asgi\n result = await app(self.scope, self.receive, self.send)\n File \"c:\\users\\bryan\\source\\repos\\todoapp\\backend\\env\\lib\\site-packages\\uvicorn\\middleware\\proxy_headers.py\", line 45, in __call__\n return await self.app(scope, receive, send)\n File \"c:\\users\\bryan\\source\\repos\\todoapp\\backend\\env\\lib\\site-packages\\fastapi\\applications.py\", line 179, in __call__\n await super().__call__(scope, receive, send)\n File \"c:\\users\\bryan\\source\\repos\\todoapp\\backend\\env\\lib\\site-packages\\starlette\\applications.py\", line 111, in __call__\n await self.middleware_stack(scope, receive, send)\n File \"c:\\users\\bryan\\source\\repos\\todoapp\\backend\\env\\lib\\site-packages\\starlette\\middleware\\errors.py\", line 181, in __call__\n raise exc from None\n File \"c:\\users\\bryan\\source\\repos\\todoapp\\backend\\env\\lib\\site-packages\\starlette\\middleware\\errors.py\", line 159, in __call__\n await self.app(scope, receive, _send)\n File \"c:\\users\\bryan\\source\\repos\\todoapp\\backend\\env\\lib\\site-packages\\starlette\\exceptions.py\", line 82, in __call__\n raise exc from None\n File \"c:\\users\\bryan\\source\\repos\\todoapp\\backend\\env\\lib\\site-packages\\starlette\\exceptions.py\", line 71, in __call__\n await self.app(scope, receive, sender)\n File \"c:\\users\\bryan\\source\\repos\\todoapp\\backend\\env\\lib\\site-packages\\starlette\\routing.py\", line 566, in __call__\n await route.handle(scope, receive, send)\n File \"c:\\users\\bryan\\source\\repos\\todoapp\\backend\\env\\lib\\site-packages\\starlette\\routing.py\", line 227, in handle\n await self.app(scope, receive, send)\n File \"c:\\users\\bryan\\source\\repos\\todoapp\\backend\\env\\lib\\site-packages\\starlette\\routing.py\", line 41, in app\n response = await func(request)\n File \"c:\\users\\bryan\\source\\repos\\todoapp\\backend\\env\\lib\\site-packages\\fastapi\\applications.py\", line 128, in openapi\n return JSONResponse(self.openapi())\n File \"c:\\users\\bryan\\source\\repos\\todoapp\\backend\\env\\lib\\site-packages\\fastapi\\applications.py\", line 106, in openapi\n self.openapi_schema = get_openapi(\n File \"c:\\users\\bryan\\source\\repos\\todoapp\\backend\\env\\lib\\site-packages\\fastapi\\openapi\\utils.py\", line 348, in get_openapi\n result = get_openapi_path(route=route, model_name_map=model_name_map)\n File \"c:\\users\\bryan\\source\\repos\\todoapp\\backend\\env\\lib\\site-packages\\fastapi\\openapi\\utils.py\", line 177, in get_openapi_path\n operation_parameters = get_openapi_operation_parameters(\n File \"c:\\users\\bryan\\source\\repos\\todoapp\\backend\\env\\lib\\site-packages\\fastapi\\openapi\\utils.py\", line 95, in get_openapi_operation_parameters\n \"schema\": field_schema(\n File \"pydantic\\schema.py\", line 184, in pydantic.schema.field_schema\n File \"pydantic\\schema.py\", line 767, in pydantic.schema.encode_default\n File \"pydantic\\json.py\", line 62, in pydantic.json.pydantic_encoder\nTypeError: Object of type 'ModelMetaclass' is not JSON serializable\n```\n\n========================================\n\nTop Answer:\nI triggered the same error message by effectively misplacing the `response_model=User` in the function def instead of the decorator.\n\nWrong:\n\n```\n@app.post(\"/users/\")\ndef create_user(user: User, db: Session = Depends(get_db), response_model=User):\n db_user_email = crud.get_user_by_email(db, email=user.email)\n```\n\nCorrect:\n\n```\n@app.post(\"/users/\", response_model=User)\ndef create_user(user: User, db: Session = Depends(get_db)):\n db_user_email = crud.get_user_by_email(db, email=user.email)\n```\n\n========================================\n\nCode:\n```text\nTypeError: Object of type 'ModelMetaclass' is not JSON serializable\n```\n\n```text\nbackend/main.py\nbackend/pydantic_models.py\nbackend/requirements.txt\nbackend/sql\nbackend/sql/crud.py\nbackend/sql/database.py\nbackend/sql/sql_models.py\nbackend/sql/__init__.py\n```\n\n```text\nfrom typing import List\n\nfrom fastapi import FastAPI, Depends, HTTPException, status\nfrom sqlalchemy.orm import Session\n\nfrom sql import crud, database, sql_models\nfrom pydantic_models import User, Todo, UserCreation, TodoCreation\n\n\nsql_models.Base.metadata.create_all(bind=database.engine)\n\napp = FastAPI()\n\ndef get_db():\n db = database.SessionLocal()\n try:\n yield db\n finally:\n db.close()\n\n\n@app.post(\"/users/\", response_model=User)\ndef create_user(user=User, db: Session = Depends(get_db)):\n db_user_email = crud.get_user_by_email(db, email=user.email)\n db_user_name = crud.get_user\n if db_user:\n raise HTTPException(status_code=status.HTTP_400_BAD,\n detail=\"Email already taken\")\n return crud.create_user(db=db, user=user)\n\n\n@app.get(\"/users/\", response_model=List[User])\ndef read_all_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):\n users = crud.get_all_users(db, skip=skip, limit=limit)\n return users\n\n\n@app.get(\"/users/{user_id}\", response_model=User)\ndef read_user(user_id: int, db: Session = Depends(get_db)):\n db_user = crud.get_user(db, user_id=user_id)\n if db_user is None:\n raise HTTPException(\n status_code=status.HTTP_404_NOT_FOUND, detail=\"User not found\")\n return db_user\n\n\n@app.post(\"/users/{user_id}/todo/\", response_model=Todo)\ndef create_todo_list(user_id: int, todo: TodoCreation, db: Session = Depends(get_db)):\n return crud.create_todo(db=db, todo=todo, user_id=user_id)\n\n\n@app.get(\"/items/\", response_model=List[Todo])\ndef read_todo(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):\n todos = crud.get_todo(db, skip=skip, limit=limit)\n return todos\n```\n\n```text\nfrom typing import List, Optional\nfrom pydantic import BaseModel\n\n\n# Todo model\nclass TodoBase(BaseModel):\n title: str\n description: Optional[str] = None\n\nclass TodoCreation(TodoBase):\n pass\n\n\nclass Todo(TodoBase):\n id: int\n owner_id: int\n\n class Config:\n orm_mode = True\n \n# User model\nclass UserBase(BaseModel):\n username: str\n email: str\n\nclass UserCreation(UserBase):\n password: str\n\nclass User(UserBase):\n id: int\n is_active: bool\n todo: List[Todo] = []\n\n class Config:\n orm_mode = True\n```\n\n```text\nfrom sqlalchemy.orm import Session\n\nfrom . import sql_models\nimport pydantic_models\n\n# Get single user\ndef get_user(db: Session, user_id: int):\n return db.query(sql_models.User).filter(models.User.id == user_id).first()\n\ndef get_user_by_name(db: Session, username: str):\n return db.query(sql_models.User).filter(models.User.username == username).first()\n\n# Get user by email\ndef get_user_by_email(db: Session, email: str):\n return db.query(sql_models.User).filter(models.User.email == email).first()\n\n# Get all users\ndef get_all_users(db: Session, skip: int = 0, limit: int = 100):\n return db.query(sql_models.User).offset(skip).limit(limit).all()\n\n# Create a user\ndef create_user(db: Session, user: pydantic_models.UserCreation):\n fake_hashed_password = user.password + \"fakehash\" # Hashed user's password\n db_user = sql_models.User(username=user.username, email=user.email, password=fake_hashed_password)\n db.add(db_user)\n db.commit()\n db.refresh(db_user)\n return db_user\n\n\ndef get_todo(db: Session, skip: int = 0, limit: int = 100):\n return db.query(sql_models.Todo).offset(skip).limit(limit).all()\n\n\ndef create_todo(db: Session, todo: pydantic_models.TodoCreation, user_id: int):\n db_item = models.Item(**item.dict(), owner_id=user_id)\n db.add(db_item)\n db.commit()\n db.refresh(db_item)\n return db_item\n```\n\n```text\nimport os\n\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import sessionmaker\n\nSQLALCHEMY_DATABASE_URL = os.environ[\"POSTGRES_LINK\"]\nengine = create_engine(SQLALCHEMY_DATABASE_URL)\nSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)\n\nBase = declarative_base()\n```\n\n```text\nfrom sql.database import Base\n\nfrom sqlalchemy import Boolean, Column, ForeignKey, Integer, String\nfrom sqlalchemy.orm import relationship\n\nclass User(Base):\n __tablename__ = \"users\"\n\n id = Column(Integer, primary_key=True, index=True)\n username = Column(String, unique=True, index=True)\n email = Column(String, unique=True, index=True)\n password = Column(String)\n is_active = Column(Boolean, default=True)\n\n todo = relationship(\"Todo\", back_populates=\"owner\")\n\nclass Todo(Base):\n __tablename__ = \"todo\"\n\n id = Column(Integer, primary_key=True, index=True)\n title = Column(String, index=True)\n description = Column(String, index=True)\n owner_id = Column(Integer, ForeignKey(\"users.id\"))\n\n owner = relationship(\"User\", back_populates=\"todo\")\n```\n\n```text\nINFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\nINFO: Started reloader process [6844] using statreload\nINFO: Started server process [2484]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\nINFO: 127.0.0.1:51303 - \"GET /docs HTTP/1.1\" 200 OK\nINFO: 127.0.0.1:51303 - \"GET /openapi.json HTTP/1.1\" 500 Internal Server ErrorERROR: Exception in ASGI application\nTraceback (most recent call last):\n File \"c:\\users\\bryan\\source\\repos\\todoapp\\backend\\env\\lib\\site-packages\\uvicorn\\protocols\\http\\h11_impl.py\", line 388, in run_asgi\n result = await app(self.scope, self.receive, self.send)\n File \"c:\\users\\bryan\\source\\repos\\todoapp\\backend\\env\\lib\\site-packages\\uvicorn\\middleware\\proxy_headers.py\", line 45, in __call__\n return await self.app(scope, receive, send)\n File \"c:\\users\\bryan\\source\\repos\\todoapp\\backend\\env\\lib\\site-packages\\fastapi\\applications.py\", line 179, in __call__\n await super().__call__(scope, receive, send)\n File \"c:\\users\\bryan\\source\\repos\\todoapp\\backend\\env\\lib\\site-packages\\starlette\\applications.py\", line 111, in __call__\n await self.middleware_stack(scope, receive, send)\n File \"c:\\users\\bryan\\source\\repos\\todoapp\\backend\\env\\lib\\site-packages\\starlette\\middleware\\errors.py\", line 181, in __call__\n raise exc from None\n File \"c:\\users\\bryan\\source\\repos\\todoapp\\backend\\env\\lib\\site-packages\\starlette\\middleware\\errors.py\", line 159, in __call__\n await self.app(scope, receive, _send)\n File \"c:\\users\\bryan\\source\\repos\\todoapp\\backend\\env\\lib\\site-packages\\starlette\\exceptions.py\", line 82, in __call__\n raise exc from None\n File \"c:\\users\\bryan\\source\\repos\\todoapp\\backend\\env\\lib\\site-packages\\starlette\\exceptions.py\", line 71, in __call__\n await self.app(scope, receive, sender)\n File \"c:\\users\\bryan\\source\\repos\\todoapp\\backend\\env\\lib\\site-packages\\starlette\\routing.py\", line 566, in __call__\n await route.handle(scope, receive, send)\n File \"c:\\users\\bryan\\source\\repos\\todoapp\\backend\\env\\lib\\site-packages\\starlette\\routing.py\", line 227, in handle\n await self.app(scope, receive, send)\n File \"c:\\users\\bryan\\source\\repos\\todoapp\\backend\\env\\lib\\site-packages\\starlette\\routing.py\", line 41, in app\n response = await func(request)\n File \"c:\\users\\bryan\\source\\repos\\todoapp\\backend\\env\\lib\\site-packages\\fastapi\\applications.py\", line 128, in openapi\n return JSONResponse(self.openapi())\n File \"c:\\users\\bryan\\source\\repos\\todoapp\\backend\\env\\lib\\site-packages\\fastapi\\applications.py\", line 106, in openapi\n self.openapi_schema = get_openapi(\n File \"c:\\users\\bryan\\source\\repos\\todoapp\\backend\\env\\lib\\site-packages\\fastapi\\openapi\\utils.py\", line 348, in get_openapi\n result = get_openapi_path(route=route, model_name_map=model_name_map)\n File \"c:\\users\\bryan\\source\\repos\\todoapp\\backend\\env\\lib\\site-packages\\fastapi\\openapi\\utils.py\", line 177, in get_openapi_path\n operation_parameters = get_openapi_operation_parameters(\n File \"c:\\users\\bryan\\source\\repos\\todoapp\\backend\\env\\lib\\site-packages\\fastapi\\openapi\\utils.py\", line 95, in get_openapi_operation_parameters\n \"schema\": field_schema(\n File \"pydantic\\schema.py\", line 184, in pydantic.schema.field_schema\n File \"pydantic\\schema.py\", line 767, in pydantic.schema.encode_default\n File \"pydantic\\json.py\", line 62, in pydantic.json.pydantic_encoder\nTypeError: Object of type 'ModelMetaclass' is not JSON serializable\n```\n\n```text\nuvicorn main:app --reload\n```\n\n```text\n@app.post(\"/users/\", response_model=User)\ndef create_user(user=User, db: Session = Depends(get_db)):\n db_user_email = crud.get_user_by_email(db, email=user.email)\n db_user_name = crud.get_user\n if db_user:\n raise HTTPException(status_code=status.HTTP_400_BAD,\n detail=\"Email already taken\")\n return crud.create_user(db=db, user=user)\n```\n\n```text\nmain.py\n```\n\n```text\nuser=User\n```\n\n```text\nuser: User\n```\n\n```py\n@app.post(\"/users/\")\ndef create_user(user: User, db: Session = Depends(get_db), response_model=User):\n db_user_email = crud.get_user_by_email(db, email=user.email)\n```\n\n```py\n@app.post(\"/users/\", response_model=User)\ndef create_user(user: User, db: Session = Depends(get_db)):\n db_user_email = crud.get_user_by_email(db, email=user.email)\n```\n\n```text\nresponse_model=User\n```\n\n```text\n@app.post(\"/read\")\nasync def read_items(item_name: str = Optional[None]):\n # code omitted\n return\n```\n\n```text\n@app.post(\"/read\")\nasync def read_items(item_name: Optional[str] = None):\n # code omitted\n return\n```\n\n```text\nObject of type 'type' is not JSON serializable\n```\n\n```text\n:\n```\n\n```text\n=\n```\n\n```text\nuser=User\n```\n\n```text\nuser:User\n```\n\n```py\nreturn JSONResponse(status_code=status.HTTP_200_OK,\n content=MyModel(status=\"something\"))\n```\n\n```py\nreturn JSONResponse(status_code=status.HTTP_200_OK,\n content=MyModel(status=\"something\").dict())\n```\n\n```text\n.dict()\n```\n\n```text\ndef smthng(user: User) -> UserResponse:\n```\n\n```text\ndef smthng(user: User):\n```\n\n```py\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\n\n\nclass Foo(BaseModel):\n bar: str\n\n\napp = FastAPI()\n\n\n@app.get(\"/\", responses={200: {\"models\": Foo}})\ndef root():\n return Foo(bar=\"baz\")\n```\n\n```text\nTraceback (most recent call last):\n File \"/home/$USER/code/models/.venv/lib/python3.11/site-packages/uvicorn/protocols/http/httptools_impl.py\", line 411, in run_asgi\n result = await app( # type: ignore[func-returns-value]\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/home/$USER/code/models/.venv/lib/python3.11/site-packages/uvicorn/middleware/proxy_headers.py\", line 69, in __call__\n return await self.app(scope, receive, send)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/home/$USER/code/models/.venv/lib/python3.11/site-packages/fastapi/applications.py\", line 1054, in __call__\n await super().__call__(scope, receive, send)\n File \"/home/$USER/code/models/.venv/lib/python3.11/site-packages/starlette/applications.py\", line 123, in __call__\n await self.middleware_stack(scope, receive, send)\n File \"/home/$USER/code/models/.venv/lib/python3.11/site-packages/starlette/middleware/errors.py\", line 186, in __call__\n raise exc\n File \"/home/$USER/code/models/.venv/lib/python3.11/site-packages/starlette/middleware/errors.py\", line 164, in __call__\n await self.app(scope, receive, _send)\n File \"/home/$USER/code/models/.venv/lib/python3.11/site-packages/starlette/middleware/exceptions.py\", line 65, in __call__\n await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)\n File \"/home/$USER/code/models/.venv/lib/python3.11/site-packages/starlette/_exception_handler.py\", line 64, in wrapped_app\n raise exc\n File \"/home/$USER/code/models/.venv/lib/python3.11/site-packages/starlette/_exception_handler.py\", line 53, in wrapped_app\n await app(scope, receive, sender)\n File \"/home/$USER/code/models/.venv/lib/python3.11/site-packages/starlette/routing.py\", line 756, in __call__\n await self.middleware_stack(scope, receive, send)\n File \"/home/$USER/code/models/.venv/lib/python3.11/site-packages/starlette/routing.py\", line 776, in app\n await route.handle(scope, receive, send)\n File \"/home/$USER/code/models/.venv/lib/python3.11/site-packages/starlette/routing.py\", line 297, in handle\n await self.app(scope, receive, send)\n File \"/home/$USER/code/models/.venv/lib/python3.11/site-packages/starlette/routing.py\", line 77, in app\n await wrap_app_handling_exceptions(app, request)(scope, receive, send)\n File \"/home/$USER/code/models/.venv/lib/python3.11/site-packages/starlette/_exception_handler.py\", line 64, in wrapped_app\n raise exc\n File \"/home/$USER/code/models/.venv/lib/python3.11/site-packages/starlette/_exception_handler.py\", line 53, in wrapped_app\n await app(scope, receive, sender)\n File \"/home/$USER/code/models/.venv/lib/python3.11/site-packages/starlette/routing.py\", line 72, in app\n response = await func(request)\n ^^^^^^^^^^^^^^^^^^^\n File \"/home/$USER/code/models/.venv/lib/python3.11/site-packages/fastapi/applications.py\", line 1009, in openapi\n return JSONResponse(self.openapi())\n ^^^^^^^^^^^^^^\n File \"/home/$USER/code/models/.venv/lib/python3.11/site-packages/fastapi/applications.py\", line 981, in openapi\n self.openapi_schema = get_openapi(\n ^^^^^^^^^^^^\n File \"/home/$USER/code/models/.venv/lib/python3.11/site-packages/fastapi/openapi/utils.py\", line 530, in get_openapi\n return jsonable_encoder(OpenAPI(**output), by_alias=True, exclude_none=True) # type: ignore\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/home/$USER/code/models/.venv/lib/python3.11/site-packages/fastapi/encoders.py\", line 223, in jsonable_encoder\n obj_dict = _model_dump(\n ^^^^^^^^^^^^\n File \"/home/$USER/code/models/.venv/lib/python3.11/site-packages/fastapi/_compat.py\", line 179, in _model_dump\n return model.model_dump(mode=mode, **kwargs)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/home/$USER/code/models/.venv/lib/python3.11/site-packages/pydantic/main.py\", line 347, in model_dump\n return self.__pydantic_serializer__.to_python(\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\npydantic_core._pydantic_core.PydanticSerializationError: Unable to serialize unknown type: <class 'pydantic._internal._model_construction.ModelMetaclass'>\n```\n\n```text\nresponses\n```\n\n```text\n\"model\"\n```\n\n```text\n\"models\"\n```\n\n```text\nopenapi.json\n```\n\n========================================\n\nComments:\n- This answer might prove helpful to future readers\n- Nice catch @Brothersoo. I was not able to identify this mistake in my code. Minor but important. Thanks for your help.\n- though this isn't the answer to the OP's question, this *is* the first result on google for this error + fastapi, and it happened to be the solution for me!\n- Please note that if `MyModel` contains objects that are not JSON serializable, such as `datetime` objects, you would either need to convert them to a JSON serializable object (e.g., `str`) on your own before returning the `JSONResponse`, or use FastAPI's `jsonable_encoder`. Please have a look at this answer for more details and examples.","metadata":{"transformedAt":"2026-08-18T18:32:29.098Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":34,"totalLines":720,"estimatedTokens":6207}}91{"id":"stack-73700879","source":"stackoverflow","questionId":73700879,"title":"Interaction between Pydantic models/schemas in the FastAPI Tutorial","tags":["python","sqlalchemy","fastapi","pydantic"],"text":"Title: Interaction between Pydantic models/schemas in the FastAPI Tutorial\nTags: python, sqlalchemy, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI the FastAPI Tutorial and am not quite sure what the exact relationship between the proposed data objects is.\n\nWe have the `models.py` file:\n\n```\nfrom sqlalchemy import Boolean, Column, ForeignKey, Integer, String\nfrom sqlalchemy.orm import relationship\n\nfrom .database import Base\n\nclass User(Base):\n __tablename__ = \"users\"\n\n id = Column(Integer, primary_key=True, index=True)\n email = Column(String, unique=True, index=True)\n hashed_password = Column(String)\n is_active = Column(Boolean, default=True)\n\n items = relationship(\"Item\", back_populates=\"owner\")\n\nclass Item(Base):\n __tablename__ = \"items\"\n\n id = Column(Integer, primary_key=True, index=True)\n title = Column(String, index=True)\n description = Column(String, index=True)\n owner_id = Column(Integer, ForeignKey(\"users.id\"))\n\n owner = relationship(\"User\", back_populates=\"items\")\n```\n\nAnd the `schemas.py` file:\n\n```\nfrom typing import List, Union\n\nfrom pydantic import BaseModel\n\nclass ItemBase(BaseModel):\n title: str\n description: Union[str, None] = None\n\nclass ItemCreate(ItemBase):\n pass\n\nclass Item(ItemBase):\n id: int\n owner_id: int\n\n class Config:\n orm_mode = True\n\nclass UserBase(BaseModel):\n email: str\n\nclass UserCreate(UserBase):\n password: str\n\nclass User(UserBase):\n id: int\n is_active: bool\n items: List[Item] = []\n\n class Config:\n orm_mode = True\n```\n\nThose classes are then used to define db queries like in the `crud.py` file:\n\n```\nfrom sqlalchemy.orm import Session\n\nfrom . import models, schemas\n\ndef get_user(db: Session, user_id: int):\n return db.query(models.User).filter(models.User.id == user_id).first()\n\ndef get_user_by_email(db: Session, email: str):\n return db.query(models.User).filter(models.User.email == email).first()\n\ndef get_users(db: Session, skip: int = 0, limit: int = 100):\n return db.query(models.User).offset(skip).limit(limit).all()\n\ndef create_user(db: Session, user: schemas.UserCreate):\n fake_hashed_password = user.password + \"notreallyhashed\"\n db_user = models.User(email=user.email, hashed_password=fake_hashed_password)\n db.add(db_user)\n db.commit()\n db.refresh(db_user)\n return db_user\n\ndef get_items(db: Session, skip: int = 0, limit: int = 100):\n return db.query(models.Item).offset(skip).limit(limit).all()\n\ndef create_user_item(db: Session, item: schemas.ItemCreate, user_id: int):\n db_item = models.Item(**item.dict(), owner_id=user_id)\n db.add(db_item)\n db.commit()\n db.refresh(db_item)\n return db_item\n```\n\nAnd in the FastAPI code `main.py`:\n\n```\nfrom typing import List\n\nfrom fastapi import Depends, FastAPI, HTTPException\nfrom sqlalchemy.orm import Session\n\nfrom . import crud, models, schemas\nfrom .database import SessionLocal, engine\n\nmodels.Base.metadata.create_all(bind=engine)\n\napp = FastAPI()\n\n# Dependency\ndef get_db():\n db = SessionLocal()\n try:\n yield db\n finally:\n db.close()\n\n@app.post(\"/users/\", response_model=schemas.User)\ndef create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):\n db_user = crud.get_user_by_email(db, email=user.email)\n if db_user:\n raise HTTPException(status_code=400, detail=\"Email already registered\")\n return crud.create_user(db=db, user=user)\n\n@app.get(\"/users/\", response_model=List[schemas.User])\ndef read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):\n users = crud.get_users(db, skip=skip, limit=limit)\n return users\n\n@app.get(\"/users/{user_id}\", response_model=schemas.User)\ndef read_user(user_id: int, db: Session = Depends(get_db)):\n db_user = crud.get_user(db, user_id=user_id)\n if db_user is None:\n raise HTTPException(status_code=404, detail=\"User not found\")\n return db_user\n\n@app.post(\"/users/{user_id}/items/\", response_model=schemas.Item)\ndef create_item_for_user(\n user_id: int, item: schemas.ItemCreate, db: Session = Depends(get_db)\n):\n return crud.create_user_item(db=db, item=item, user_id=user_id)\n\n@app.get(\"/items/\", response_model=List[schemas.Item])\ndef read_items(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):\n items = crud.get_items(db, skip=skip, limit=limit)\n return items\n```\n\n**From what I understand:**\n\n- The `models` data classes define the SQL tables.\n\n- The `schemas` data classes define the API that FastAPI uses to interact with the database.\n\n- They must be convertible into each other so that the set-up works.\n\n**What I don't understand:**\n\n- In `crud.create_user_item` I expected the return type to be `schemas.Item`, since that return type is used by FastAPI again.\n\n- According to my understanding the response model of `@app.post(\"/users/{user_id}/items/\", response_model=schemas.Item)` in the `main.py` is wrong, or how can I understand the return type inconsistency?\n\n- However inferring from the code, the actual return type must be `models.Item`, how is that handled by FastAPI?\n\n- What would be the return type of `crud.get_user`?\n\n========================================\n\nCode:\n```py\nfrom sqlalchemy import Boolean, Column, ForeignKey, Integer, String\nfrom sqlalchemy.orm import relationship\n\nfrom .database import Base\n\n\nclass User(Base):\n __tablename__ = \"users\"\n\n id = Column(Integer, primary_key=True, index=True)\n email = Column(String, unique=True, index=True)\n hashed_password = Column(String)\n is_active = Column(Boolean, default=True)\n\n items = relationship(\"Item\", back_populates=\"owner\")\n\n\nclass Item(Base):\n __tablename__ = \"items\"\n\n id = Column(Integer, primary_key=True, index=True)\n title = Column(String, index=True)\n description = Column(String, index=True)\n owner_id = Column(Integer, ForeignKey(\"users.id\"))\n\n owner = relationship(\"User\", back_populates=\"items\")\n```\n\n```py\nfrom typing import List, Union\n\nfrom pydantic import BaseModel\n\n\nclass ItemBase(BaseModel):\n title: str\n description: Union[str, None] = None\n\n\nclass ItemCreate(ItemBase):\n pass\n\n\nclass Item(ItemBase):\n id: int\n owner_id: int\n\n class Config:\n orm_mode = True\n\n\nclass UserBase(BaseModel):\n email: str\n\n\nclass UserCreate(UserBase):\n password: str\n\n\nclass User(UserBase):\n id: int\n is_active: bool\n items: List[Item] = []\n\n class Config:\n orm_mode = True\n```\n\n```py\nfrom sqlalchemy.orm import Session\n\nfrom . import models, schemas\n\n\ndef get_user(db: Session, user_id: int):\n return db.query(models.User).filter(models.User.id == user_id).first()\n\n\ndef get_user_by_email(db: Session, email: str):\n return db.query(models.User).filter(models.User.email == email).first()\n\n\ndef get_users(db: Session, skip: int = 0, limit: int = 100):\n return db.query(models.User).offset(skip).limit(limit).all()\n\n\ndef create_user(db: Session, user: schemas.UserCreate):\n fake_hashed_password = user.password + \"notreallyhashed\"\n db_user = models.User(email=user.email, hashed_password=fake_hashed_password)\n db.add(db_user)\n db.commit()\n db.refresh(db_user)\n return db_user\n\ndef get_items(db: Session, skip: int = 0, limit: int = 100):\n return db.query(models.Item).offset(skip).limit(limit).all()\n\ndef create_user_item(db: Session, item: schemas.ItemCreate, user_id: int):\n db_item = models.Item(**item.dict(), owner_id=user_id)\n db.add(db_item)\n db.commit()\n db.refresh(db_item)\n return db_item\n```\n\n```py\nfrom typing import List\n\nfrom fastapi import Depends, FastAPI, HTTPException\nfrom sqlalchemy.orm import Session\n\nfrom . import crud, models, schemas\nfrom .database import SessionLocal, engine\n\nmodels.Base.metadata.create_all(bind=engine)\n\napp = FastAPI()\n\n\n# Dependency\ndef get_db():\n db = SessionLocal()\n try:\n yield db\n finally:\n db.close()\n\n\n@app.post(\"/users/\", response_model=schemas.User)\ndef create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):\n db_user = crud.get_user_by_email(db, email=user.email)\n if db_user:\n raise HTTPException(status_code=400, detail=\"Email already registered\")\n return crud.create_user(db=db, user=user)\n\n\n@app.get(\"/users/\", response_model=List[schemas.User])\ndef read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):\n users = crud.get_users(db, skip=skip, limit=limit)\n return users\n\n\n@app.get(\"/users/{user_id}\", response_model=schemas.User)\ndef read_user(user_id: int, db: Session = Depends(get_db)):\n db_user = crud.get_user(db, user_id=user_id)\n if db_user is None:\n raise HTTPException(status_code=404, detail=\"User not found\")\n return db_user\n\n\n@app.post(\"/users/{user_id}/items/\", response_model=schemas.Item)\ndef create_item_for_user(\n user_id: int, item: schemas.ItemCreate, db: Session = Depends(get_db)\n):\n return crud.create_user_item(db=db, item=item, user_id=user_id)\n\n\n@app.get(\"/items/\", response_model=List[schemas.Item])\ndef read_items(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):\n items = crud.get_items(db, skip=skip, limit=limit)\n return items\n```\n\n```text\nmodels.py\n```\n\n```text\nschemas.py\n```\n\n```text\ncrud.py\n```\n\n```text\nmain.py\n```\n\n```text\nmodels\n```\n\n```text\nschemas\n```\n\n```text\ncrud.create_user_item\n```\n\n```text\nschemas.Item\n```\n\n```text\n@app.post(\"/users/{user_id}/items/\", response_model=schemas.Item)\n```\n\n```text\nmain.py\n```\n\n```text\nmodels.Item\n```\n\n```text\ncrud.get_user\n```\n\n```py\ndb_item = models.Item(**item.dict(), owner_id=user_id)\n```\n\n```py\ndef create_user_item(db: Session, item: schemas.ItemCreate, user_id: int):\n db_item = models.Item(**item.dict(), owner_id=user_id)\n ...\n return db_item\n```\n\n```py\n@app.post(\"/users/{user_id}/items/\", response_model=schemas.Item)\ndef create_item_for_user(\n user_id: int, item: schemas.ItemCreate, db: Session = Depends(get_db)\n):\n return crud.create_user_item(db=db, item=item, user_id=user_id)\n```\n\n```py\nclass Config:\n orm_mode = True\n```\n\n```py\n@app.post(\"/users/{user_id}/items/\", response_model=schemas.Item)\ndef create_item_for_user(\n user_id: int, item: schemas.ItemCreate, db: Session = Depends(get_db)\n) -> models.Item:\n return crud.create_user_item(db=db, item=item, user_id=user_id)\n```\n\n```py\ndef create_item_for_user(\n user_id: int, item: schemas.ItemCreate, db: Session = Depends(get_db)\n) -> models.Item:\n return crud.create_user_item(db=db, item=item, user_id=user_id)\n\n\ncreate_item_for_user = app.post(\n \"/users/{user_id}/items/\", response_model=schemas.Item\n)(create_item_for_user)\n```\n\n```py\ndef get_user(db: Session, user_id: int) -> models.User:\n return db.query(models.User).filter(models.User.id == user_id).first()\n```\n\n```py\n@app.get(\"/users/{user_id}\", response_model=schemas.User)\ndef read_user(user_id: int, db: Session = Depends(get_db)) -> models.User:\n db_user = crud.get_user(db, user_id=user_id)\n ...\n return db_user # <-- instance of `models.User`\n```\n\n```text\nmodels\n```\n\n```text\nmodels\n```\n\n```text\nschemas\n```\n\n```text\nschemas\n```\n\n```text\nitem\n```\n\n```text\nschemas.ItemCreate\n```\n\n```text\nmodels.Item\n```\n\n```text\nowner_id\n```\n\n```text\ncrud.create_user_item\n```\n\n```text\nschemas.Item\n```\n\n```text\ncreate_user_item\n```\n\n```text\nmodels.Item\n```\n\n```text\nsession.refresh\n```\n\n```text\ncreate_item_for_user\n```\n\n```text\nmodels.Item\n```\n\n```text\n@app.post\n```\n\n```text\nresponse_model\n```\n\n```text\nschemas.Item\n```\n\n```text\norm_mode\n```\n\n```text\nschemas.Item\n```\n\n```text\n.from_orm\n```\n\n```text\nschemas.Item\n```\n\n```text\nmodels.Item\n```\n\n```text\ncreate_item_for_user\n```\n\n```text\nmodels.Item\n```\n\n```text\ncrud.get_user\n```\n\n```text\nmodels.User\n```\n\n```text\nfirst\n```\n\n```text\nread_user\n```\n\n```text\nmodels.Item\n```\n\n```text\nmodels.User\n```\n\n```text\nresponse_model\n```\n\n```text\nschemas.User.from_orm\n```\n\n```text\nschemas.User\n```\n\n========================================\n\nComments:\n- Thank you for this clear and thorough answer!\n- This could be part of the FastAPI / Pydantic documentation / tutorial. Very clear!\n- Superb answer! Thanks @Daniil Fajnberg and also to patrick for asking","metadata":{"transformedAt":"2026-08-18T18:32:29.098Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":58,"totalLines":593,"estimatedTokens":2988}}92{"id":"stack-63762387","source":"stackoverflow","questionId":63762387,"title":"How to group FastAPI endpoints in Swagger UI?","tags":["python","swagger-ui","swagger-2.0","fastapi"],"text":"Title: How to group FastAPI endpoints in Swagger UI?\nTags: python, swagger-ui, swagger-2.0, fastapi\nSource: Stack Overflow\n\nQuestion:\nI started programming using FastAPI framework and it comes with a builtin Swagger interface to handle requests and responses.\nI have completed nearly 20 APIs and its hard to manage and recognise APIs on Swagger interface.\nSomeone told me to add sections in Swagger interface to distinguish APIs, but I couldn't find any examples and I need help.\n\n========================================\n\nCode:\n```text\n@app.delete(\"/items\", tags=[\"Delete Methods\"])\n@app.put(\"/items\", tags=[\"Put Methods\"])\n@app.post(\"/items\", tags=[\"Post Methods\"])\n@app.get(\"/items\", tags=[\"Get Methods\"])\nasync def handle_items():\n return\n\n\n@app.get(\"/something\", tags=[\"Get Methods\"])\nasync def something():\n return\n```\n\n```text\nfrom fastapi import FastAPI\n\ntags_metadata = [\n {\"name\": \"Get Methods\", \"description\": \"One other way around\"},\n {\"name\": \"Post Methods\", \"description\": \"Keep doing this\"},\n {\"name\": \"Delete Methods\", \"description\": \"KILL 'EM ALL\"},\n {\"name\": \"Put Methods\", \"description\": \"Boring\"},\n]\n\napp = FastAPI(openapi_tags=tags_metadata)\n\n\n@app.delete(\"/items\", tags=[\"Delete Methods\"])\n@app.put(\"/items\", tags=[\"Put Methods\"])\n@app.post(\"/items\", tags=[\"Post Methods\"])\n@app.get(\"/items\", tags=[\"Get Methods\"])\nasync def handle_items():\n return\n```\n\n========================================\n\nComments:\n- Also worth noting that tags can be put directly on `APIRouter` objects too\n- Do we also have such metadata for fields description ? ( there are some text inputs that I need in almost every endpoint )","metadata":{"transformedAt":"2026-08-18T18:32:29.098Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":2,"totalLines":52,"estimatedTokens":413}}93{"id":"stack-72919006","source":"stackoverflow","questionId":72919006,"title":"Is there any way to have multiple response models in FastAPI/OpenAPI?","tags":["openapi","fastapi","pydantic"],"text":"Title: Is there any way to have multiple response models in FastAPI/OpenAPI?\nTags: openapi, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI am writing an app where I need to have two completely different set of response structures depending on logic.\n\nIs there any way to handle this so that I can have two different response models serialized, validated and returned and reflect in OpenAPI JSON?\n\nI am using pydantic to write models.\n\n========================================\n\nTop Answer:\nIf you need response multiple examples, you can try this:\n\n```\n@router.get(\n '/{UserId}',\n summary='get user',\n responses={\n 200: {\n \"description\": \"\",\n \"content\": {\n \"application/json\": {\n \"examples\": {\n \"Corporate user\": {\n 'value': {\n 'foo': 'bar',\n },\n },\n \"Standard user\": {\n 'value': {\n 'doo': 'www',\n },\n },\n }\n }\n }\n }\n }\n)\n```\n\nhttps://i.sstatic.net/jANJV.png\n\n========================================\n\nCode:\n```py\nfrom typing import Union\n\nfrom fastapi import FastAPI, Query\nfrom pydantic import BaseModel\n\nclass responseA(BaseModel):\n name: str\n\nclass responseB(BaseModel):\n id: int\n\napp = FastAPI()\n\n@app.get(\"/\", response_model=Union[responseA,responseB])\ndef base(q: int|str = Query(None)):\n if q and isinstance(q, str):\n return responseA(name=q)\n if q and isinstance(q, int):\n return responseB(id=q)\n raise HTTPException(status_code=400, detail=\"No q param provided\")\n\nif __name__ == \"__main__\":\n import uvicorn\n uvicorn.run(app, host=\"0.0.0.0\", port=8000, )\n```\n\n```text\nresponse_model=\n```\n\n```text\nresponse_model\n```\n\n```text\nUnion\n```\n\n```text\nresponseA|responseB\n```\n\n```py\n@router.get(\n '/{UserId}',\n summary='get user',\n responses={\n 200: {\n \"description\": \"\",\n \"content\": {\n \"application/json\": {\n \"examples\": {\n \"Corporate user\": {\n 'value': {\n 'foo': 'bar',\n },\n },\n \"Standard user\": {\n 'value': {\n 'doo': 'www',\n },\n },\n }\n }\n }\n }\n }\n)\n```\n\n========================================\n\nComments:\n- An alternative for previous python versions could be `@app.get(\"/\", response_model=Union[responseA, responseB])`\n- Is it normal that pyright reports that : `Argument of type \"Type[FirstType] | Type[SecondType]\" cannot be assigned to parameter \"response_model\" of type \"type | None\" in function \"get\"` ? Using both the Union and the pipe syntaxe\n- This example did not work for me, I only see the `responseA` on the swagger UI. For reference I am using python 3.10 with fastapi 0.92.0\n- This doesn't seem to be correct. The documentation explicitely states that we have to use `Union[responseA, responseB]` instead of `responseA | responseB`.\n- @TomášLinhart; one is the equivalent of the other. The `|` notation was introduced in python 3.10. It is the exact equivalent of `Union`.\n- @JarroVGIT did you read the documentation I linked? There's explicitly stated that it's not the same thing in the given context.\n- `response_model = response B | response A` don't work. Can someone explain why the order matters?\n- @TomášLinhart well I stand corrected! One learns everyday, I will amend the answer. Weird thing is: I tested this code before I posted it and then it worked. I thought maybe this is something new, but the docs on that part are 2 years old (so not new). Never knew though, thanks for pointing this out!\n- the correct multiple example should be with dropdown\n- For future reference. When defining a Union, include the most specific type first, followed by the less specific type. In the example of the webside (fastapi.tiangolo.com/tutorial/extra-models/#union-or-anyof)‌​, the more specific PlaneItem comes before CarItem in Union[PlaneItem, CarItem].\n- I'm using `|` with python 3.12 now and it seems to work.","metadata":{"transformedAt":"2026-08-18T18:32:29.098Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":6,"totalLines":134,"estimatedTokens":1023}}94{"id":"stack-73563804","source":"stackoverflow","questionId":73563804,"title":"What is the recommended way to instantiate and pass around a redis client with FastAPI","tags":["python","redis","fastapi"],"text":"Title: What is the recommended way to instantiate and pass around a redis client with FastAPI\nTags: python, redis, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm using FastAPI with Redis. My app looks something like this\n\n```\nfrom fastapi import FastAPI\nimport redis\n\n# Instantiate redis client\nr = redis.Redis(host='localhost', port=6379, db=0, decode_responses=True)\n\n# Instantiate fastapi app\napp = FastAPI()\n\n@app.get(\"/foo/\")\nasync def foo():\n x = r.get(\"foo\")\n return {\"message\": x}\n\n@app.get(\"/bar/\")\nasync def bar():\n x = r.get(\"bar\")\n return {\"message\": x}\n```\n\n**Is it bad practice to create `r` as a module-scoped variable like this? If so what are the drawbacks?**\n\nIn Tiangolo's tutorial on setting up a SQL database connection he uses a dependency, which I guess in my case would look something like this\n\n```\nfrom fastapi import Depends, FastAPI\nimport redis\n\n# Instantiate fastapi app\napp = FastAPI()\n\n# Dependency\ndef get_redis():\n return redis.Redis(host='localhost', port=6379, db=0, decode_responses=True)\n\n@app.get(\"/foo/\")\nasync def foo(r = Depends(get_redis)):\n x = r.get(\"foo\")\n return {\"message\": x}\n\n@app.get(\"/bar/\")\nasync def bar(r = Depends(get_redis)):\n x = r.get(\"bar\")\n return {\"message\": x}\n```\n\nI'm a bit confused as to which of these methods (or something else) would be preferred and why.\n\n========================================\n\nTop Answer:\nIn your second example, every time your creating new redis instance and one time it reach max connection limit. If you put code like this that much more clean and re-usable,\n\n```\nfrom fastapi import FastAPI\nimport redis\n\nclass AppAPI(FastAPI):\n def __init__(self):\n self.redis_client = redis.Redis(host='localhost', port=6379, db=0, decode_responses=True)\n\n @app.get(\"/foo/\")\n async def foo():\n x = self.redis_client.get(\"foo\")\n return {\"message\": x}\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nimport redis\n\n# Instantiate redis client\nr = redis.Redis(host='localhost', port=6379, db=0, decode_responses=True)\n\n# Instantiate fastapi app\napp = FastAPI()\n\n@app.get(\"/foo/\")\nasync def foo():\n x = r.get(\"foo\")\n return {\"message\": x}\n\n@app.get(\"/bar/\")\nasync def bar():\n x = r.get(\"bar\")\n return {\"message\": x}\n```\n\n```text\nfrom fastapi import Depends, FastAPI\nimport redis\n\n# Instantiate fastapi app\napp = FastAPI()\n\n# Dependency\ndef get_redis():\n return redis.Redis(host='localhost', port=6379, db=0, decode_responses=True)\n\n@app.get(\"/foo/\")\nasync def foo(r = Depends(get_redis)):\n x = r.get(\"foo\")\n return {\"message\": x}\n\n@app.get(\"/bar/\")\nasync def bar(r = Depends(get_redis)):\n x = r.get(\"bar\")\n return {\"message\": x}\n```\n\n```text\nr\n```\n\n```py\nimport redis\n\ndef create_redis():\n return redis.ConnectionPool(\n host='localhost', \n port=6379, \n db=0, \n decode_responses=True\n )\n\npool = create_redis()\n```\n\n```py\nfrom fastapi import Depends, FastAPI\nimport redis\n\nfrom config.db import pool\n\napp = FastAPI()\n\ndef get_redis():\n # Here, we re-use our connection pool\n # not creating a new one\n return redis.Redis(connection_pool=pool)\n\n@app.get(\"/items/{item_id}\")\ndef read_item(item_id: int, cache = Depends(get_redis)):\n status = cache.get(item_id)\n return {\"item_name\": status}\n\n\n@app.put(\"/items/{item_id}\")\ndef update_item(item_id: int, cache = Depends(get_redis)):\n cache.set(item_id, \"available\")\n return {\"status\": \"available\", \"item_id\": item_id}\n```\n\n```text\nDepends\n```\n\n```text\nconfig/db.py\n```\n\n```text\nmain.py\n```\n\n```text\nfrom fastapi import FastAPI\nimport redis\n\nclass AppAPI(FastAPI):\n def __init__(self):\n self.redis_client = redis.Redis(host='localhost', port=6379, db=0, decode_responses=True)\n\n @app.get(\"/foo/\")\n async def foo():\n x = self.redis_client.get(\"foo\")\n return {\"message\": x}\n```\n\n```text\npool = redis.ConnectionPool(host='localhost', port=6379, db=0)\nr = redis.Redis(connection_pool=pool)\n```\n\n========================================\n\nComments:\n- It depends (as always). Your first example reuses the same client for all your endpoints (and, blocks the event loop while using that client because you use it in async endpoints but that is another matter). In the second example, you get a new instance for each request. But actually you also get a new connection pool with each request. My recommendation would be to make a global connection pool and use dependency injection to get a connection from that pool (`redis.Redis(connection_pool=redis_pool)`). That way, you don't make a new connection pool for each request.\n- @JarroVGIT thanks, I *think* this makes sense, after reading this related question. Any chance you could provide a minimal example as a solution? (I'd be happy to accept it.)\n- Should aioredis (asyncio redis client)be used with async? aioredis.readthedocs.io/en/latest\n- @starking yes, if we run it in an async function. Not sure if we run it in normal (non async) function.","metadata":{"transformedAt":"2026-08-18T18:32:29.098Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":10,"totalLines":202,"estimatedTokens":1233}}95{"id":"stack-67266573","source":"stackoverflow","questionId":67266573,"title":"How to disable the logging of Uvicorn?","tags":["python","logging","fastapi","alembic","uvicorn"],"text":"Title: How to disable the logging of Uvicorn?\nTags: python, logging, fastapi, alembic, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI am working on FastAPI - Uvicorn. I want to disable the logging by uvicorn. I need only the logs which are logged by the server.\n\nhttps://i.sstatic.net/ANktA.png\n\nI referred to this blog and implemented the logging.\n\n========================================\n\nTop Answer:\nI think I had the same issue.\n\nTo disable the logger one must first find the loggers, that shall be disabled. I did this by following this stackoverflow post and this GitHub-Issue.\n\nFor me it works to disable just two loggers from uvicorn:\n\n```\nimport logging\n# ....CODE....\nuvicorn_error = logging.getLogger(\"uvicorn.error\")\nuvicorn_error.disabled = True\nuvicorn_access = logging.getLogger(\"uvicorn.access\")\nuvicorn_access.disabled = True\n```\n\nAt first I tried the answer provided by @Sanchouz, but this didn't work out for me - Further setting `propagate = false` is by some regarded as a bad practice (see this) . As I wanted to do it programmatically I couldn't test the answer provided by @funnydman.\n\nHope this helps anyone, thinklex.\n\n========================================\n\nCode:\n```text\nuvicorn main:app --log-level critical\n```\n\n```text\nlogger = logging.getLogger(logger_name)\nlogger.propagate = False\n```\n\n```text\nlogging\n```\n\n```text\nuvicorn ...\n```\n\n```text\npropagate\n```\n\n```text\nFalse\n```\n\n```text\nlogging\n```\n\n```text\ncallHandlers\n```\n\n```text\nimport logging\n# ....CODE....\nuvicorn_error = logging.getLogger(\"uvicorn.error\")\nuvicorn_error.disabled = True\nuvicorn_access = logging.getLogger(\"uvicorn.access\")\nuvicorn_access.disabled = True\n```\n\n```text\npropagate = false\n```\n\n```text\nif self.log_level is not None:\n if isinstance(self.log_level, str):\n log_level = LOG_LEVELS[self.log_level]\n else:\n log_level = self.log_level\n logging.getLogger(\"uvicorn.error\").setLevel(log_level)\n logging.getLogger(\"uvicorn.access\").setLevel(log_level)\n logging.getLogger(\"uvicorn.asgi\").setLevel(log_level)\n if self.access_log is False:\n logging.getLogger(\"uvicorn.access\").handlers = []\n logging.getLogger(\"uvicorn.access\").propagate = False\n```\n\n```text\n# disable uvicorn logs\n logging.getLogger(\"uvicorn.error\").handlers = []\n logging.getLogger(\"uvicorn.error\").propagate = False\n\n logging.getLogger(\"uvicorn.access\").handlers = []\n logging.getLogger(\"uvicorn.access\").propagate = False\n\n logging.getLogger(\"uvicorn.asgi\").handlers = []\n logging.getLogger(\"uvicorn.asgi\").propagate = True\n```\n\n```py\nfrom fastapi import FastAPI\nimport uvicorn\n\napp = FastAPI()\n\n\n@app.get('/')\nasync def main():\n pass\n \n \nif __name__ == '__main__':\n uvicorn.run(app, log_config=None)\n```\n\n```json\n{\n \"version\": 1\n}\n```\n\n```text\n> uvicorn app:app --log-config log_config.json\n```\n\n```text\nuvicorn\n```\n\n```text\nuvicorn\n```\n\n```text\nlog_config\n```\n\n```text\nuvicorn.run()\n```\n\n```text\nNone\n```\n\n```text\n--log-config\n```\n\n```text\nversion\n```\n\n```text\nValueError: dictionary doesn't specify a version\n```\n\n```text\n1\n```\n\n```text\nuvicorn\n```\n\n```text\napp:app\n```\n\n```text\n<module>:<attribute>\n```\n\n========================================\n\nComments:\n- Why not disable all 4 uvicorn loggers (uvicorn, uvicorn.error, uvicorn.access, uvicorn.asgi)?\n- I cant see my own print statements though becasue of this.\n- I am afraid that this answer is **incorrect**. The `--no-access-log` flag would disable the `access` **only**, as described in the documentation, as well as this answer. However, Uvicorn internally also uses other loggers that wouldn't be affected by changing that `access-log` flag - see the linked answer above for more details. To disable the Uvicorn loggers, I would suggest having a look at this answer.\n- I wrote \"To disable **API access logs**\"\n- I am afraid that OP did **not** ask for that though.","metadata":{"transformedAt":"2026-08-18T18:32:29.098Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":27,"totalLines":190,"estimatedTokens":977}}96{"id":"stack-71539448","source":"stackoverflow","questionId":71539448,"title":"Using different Pydantic models depending on the value of fields","tags":["python","fastapi","pydantic"],"text":"Title: Using different Pydantic models depending on the value of fields\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI have 2 Pydantic models (`var1` and `var2`). The input of the `PostExample` method can receive data either for the first model or the second.\nThe use of `Union` helps in solving this issue, but during validation it throws errors for both the first and the second model.\n\nHow to make it so that in case of an error in filling in the fields, validator errors are returned only for a certain model, and not for both at once? (if it helps, the models can be distinguished by the length of the field A).\n\nmain.py\n\n```\n@app.post(\"/PostExample\")\ndef postExample(request: Union[schemas.var1, schemas.var2]):\n \n result = post_registration_request.requsest_response()\n return result\n```\n\nschemas.py\n\n```\nclass var1(BaseModel):\n A: str\n B: int\n C: str\n D: str\n \n \nclass var2(BaseModel):\n A: str\n E: int\n F: str\n```\n\n========================================\n\nTop Answer:\n### For those looking for a pure pydantic solution (without FastAPI):\n\nYou would need to:\n\n- Build an additional model (technically, an intermediate annotation) to \"collect and perform\" the discriminated union,\n\n- parse using `parse_obj_as()`\n\n**This approach is demonstrated below:**\n\n(Credit to @Chris for his previous answer, on which this solution is based.)\n\n```\nfrom typing import Literal, Union, Annotated\nfrom pydantic import BaseModel, Field, parse_obj_as\n\nclass Model1(BaseModel):\n model_type: Literal['m1']\n A: str\n B: int\n C: str\n D: str\n\nclass Model2(BaseModel):\n model_type: Literal['m2']\n A: str\n E: int\n F: str\n\n# Create a new model to represent the discriminated union\nValidModel = Annotated[Union[Model1, Model2], Field(discriminator='model_type')]\n\n# Sample data\nraw_data = {\n \"model_type\": \"m1\",\n \"A\": \"foo\",\n \"B\": 1,\n \"C\": \"bar\",\n \"D\": \"zap\"\n}\n\n# Parse as the correct model based on `model_type`\nmy_model = parse_obj_as(ValidModel, raw_data)\nprint(type(my_model)) # \n```\n\n========================================\n\nCode:\n```text\n@app.post(\"/PostExample\")\ndef postExample(request: Union[schemas.var1, schemas.var2]):\n \n result = post_registration_request.requsest_response()\n return result\n```\n\n```text\nclass var1(BaseModel):\n A: str\n B: int\n C: str\n D: str\n \n \nclass var2(BaseModel):\n A: str\n E: int\n F: str\n```\n\n```text\nvar1\n```\n\n```text\nvar2\n```\n\n```text\nPostExample\n```\n\n```text\nUnion\n```\n\n```python\nimport schemas\nfrom fastapi import FastAPI, Body\nfrom typing import Union\n\napp = FastAPI()\n\n@app.post(\"/\")\ndef submit(item: Union[schemas.Model1, schemas.Model2] = Body(..., discriminator='model_type')):\n return item\n```\n\n```python\nfrom typing import Literal\nfrom pydantic import BaseModel\n\nclass Model1(BaseModel):\n model_type: Literal['m1']\n A: str\n B: int\n C: str\n D: str\n \nclass Model2(BaseModel):\n model_type: Literal['m2']\n A: str\n E: int\n F: str\n```\n\n```none\n#1 Successful Response #2 Validation error #3 Validation error\n \n# Request body # Request body # Request body\n{ { {\n \"model_type\": \"m1\", \"model_type\": \"m1\", \"model_type\": \"m2\",\n \"A\": \"string\", \"A\": \"string\", \"A\": \"string\",\n \"B\": 0, \"C\": \"string\", \"C\": \"string\",\n \"C\": \"string\", \"D\": \"string\" \"D\": \"string\"\n \"D\": \"string\" } }\n} \n \n# Server response # Server response # Server response\n200 { {\n \"detail\": [ \"detail\": [\n { {\n \"loc\": [ \"loc\": [\n \"body\", \"body\",\n \"Model1\", \"Model2\",\n \"B\" \"E\"\n ], ],\n \"msg\": \"field required\", \"msg\": \"field required\",\n \"type\": \"value_error.missing\" \"type\": \"value_error.missing\"\n } },\n ] {\n } \"loc\": [\n \"body\",\n \"Model2\",\n \"F\"\n ],\n \"msg\": \"field required\",\n \"type\": \"value_error.missing\"\n }\n ]\n }\n```\n\n```py\nfrom typing import Literal, Union, Annotated\nfrom pydantic import BaseModel, Field, parse_obj_as\n\n\nclass Model1(BaseModel):\n model_type: Literal['m1']\n A: str\n B: int\n C: str\n D: str\n\n\nclass Model2(BaseModel):\n model_type: Literal['m2']\n A: str\n E: int\n F: str\n\n\n# Create a new model to represent the discriminated union\nValidModel = Annotated[Union[Model1, Model2], Field(discriminator='model_type')]\n\n# Sample data\nraw_data = {\n \"model_type\": \"m1\",\n \"A\": \"foo\",\n \"B\": 1,\n \"C\": \"bar\",\n \"D\": \"zap\"\n}\n\n# Parse as the correct model based on `model_type`\nmy_model = parse_obj_as(ValidModel, raw_data)\nprint(type(my_model)) # <class '__main__.Model1'>\n```\n\n```text\nparse_obj_as()\n```\n\n```py\n# %%\nimport json\nfrom typing import Annotated, Literal, Union\n\nfrom pydantic import BaseModel, Field, TypeAdapter, parse_obj_as\n\n\n# %%\nclass Model1(BaseModel):\n key: Literal[\"Model1\", \"Model1A\"]\n value: int\n\n\nclass Model2(BaseModel):\n key: Literal[\"Model2\", \"Model2A\"]\n value2: int\n name: str\n\n\n# %%\nValidatorModel = Annotated[Union[Model1, Model2], Field(discriminator=\"key\")]\n\n# %%\nadaptor = TypeAdapter(ValidatorModel)\n\n# %% JSON Examples\nmodel1 = {\"key\": \"Model1\", \"value\": 1}\nmodel2 = {\"key\": \"Model2\", \"value2\": 2, \"name\": \"name\"}\nmodel1a = {\"key\": \"Model1A\", \"value\": 23}\n\n# %% Parse JSON New Way\n%%timeit\nfor model in [model1, model2, model1a]:\n x = adaptor.validate_python(model)\n# 2.06 µs ± 25.1 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)\n\n# %% Deprecated way\n%%timeit\nfor model in [model1, model2, model1a]:\n x = parse_obj_as(ValidatorModel, model)\n# 669 µs ± 43.1 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)\n```\n\n```text\nparse_obj_as\n```\n\n```text\nTypeAdapter\n```\n\n========================================\n\nComments:\n- Have you read through the docs on discriminated unions? That sounds like what you're asking for.\n- Which of your models do you want to return errors? tell me , i don't send B and E , and i send like this : { \"A\":\"1\", \"C\":\"3\", \"D\":\"4\", \"F\":\"3\" } What are you waiting for? var1 error ? var2 error ?\n- Thanks, this was a good solution. Note that if you have JSON (ie, string data) instead of a Python object, use `parse_raw_as()` instead.\n- Note that `parse_obj_as` is deprecated, the correct way now is using `TypeAdapter`: `from pydantic import TypeAdapter my_model = TypeAdapter(ValidModel).validate_python(raw_data) # or for json my_model = TypeAdapter(ValidModel).validate_json(raw_data)` source: docs.pydantic.dev/latest/api/type_adapter","metadata":{"transformedAt":"2026-08-18T18:32:29.098Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":14,"totalLines":293,"estimatedTokens":2013}}97{"id":"stack-60783222","source":"stackoverflow","questionId":60783222,"title":"How to test a FastAPI api endpoint that consumes images?","tags":["python","pytest","multipart","fastapi","starlette"],"text":"Title: How to test a FastAPI api endpoint that consumes images?\nTags: python, pytest, multipart, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nI am using pytest to test a FastAPI endpoint that gets in input an image in binary format as in\n\n```\n@app.post(\"/analyse\")\nasync def analyse(file: bytes = File(...)):\n\n image = Image.open(io.BytesIO(file)).convert(\"RGB\")\n stats = process_image(image)\n return stats\n```\n\nAfter starting the server, I can manually test the endpoint successfully by running a call with `requests`\n\n```\nimport requests\nfrom requests_toolbelt.multipart.encoder import MultipartEncoder\n\nurl = \"http://127.0.0.1:8000/analyse\"\n\nfilename = \"./example.jpg\"\nm = MultipartEncoder(\n fields={'file': ('filename', open(filename, 'rb'), 'image/jpeg')}\n )\nr = requests.post(url, data=m, headers={'Content-Type': m.content_type}, timeout = 8000)\nassert r.status_code == 200\n```\n\nHowever, setting up tests in a function of the form:\n\n```\nfrom fastapi.testclient import TestClient\nfrom requests_toolbelt.multipart.encoder import MultipartEncoder\nfrom app.server import app\n\nclient = TestClient(app)\n\ndef test_image_analysis():\n\n filename = \"example.jpg\"\n\n m = MultipartEncoder(\n fields={'file': ('filename', open(filename, 'rb'), 'image/jpeg')}\n )\n\n response = client.post(\"/analyse\",\n data=m,\n headers={\"Content-Type\": \"multipart/form-data\"}\n )\n\n assert response.status_code == 200\n```\n\nwhen running tests with `python -m pytest`, that gives me back a \n\n```\n> assert response.status_code == 200\nE assert 400 == 200\nE + where 400 = .status_code\n\ntests\\test_server.py:22: AssertionError\n-------------------------------------------------------- Captured log call --------------------------------------------------------- \nERROR fastapi:routing.py:133 Error getting request body: can't concat NoneType to bytes\n===================================================== short test summary info ====================================================== \nFAILED tests/test_server.py::test_image_analysis - assert 400 == 200\n```\n\nwhat am I doing wrong?\n\nWhat's the right way to write a test function `test_image_analysis()` using an image file?\n\n========================================\n\nTop Answer:\nBelow code is working for me:\n\n** API Structure: **\n\nFile: *api_routers.py*\n\n```\nfrom fastapi import APIRouter, File, UploadFile, Query\nrouter = APIRouter()\n@router.post(path=\"{{API_PATH}}\", tags=[\"Prediction\"])\ndef prediction(id: str, uploadFile: UploadFile):\n ...\n {{CODE}}\n return response\n```\n\n**Testing Code**\n\nFile: *test_api_router.py*\n\n```\nimport pytest\nimport os\nfrom fastapi.testclient import TestClient\nimport.api_routers\n\nclient = TestClient(api_routers.router)\n\ndef test_prediction(constants): \n # Use constants if fixture created\n file_path = \"{{IMAGE PATH}}\"\n if os.path.isfile(file_path):\n _files = {'uploadFile': open(file_path, 'rb')}\n response = client.post('{{API_PATH}}',\n params={\n \"id\": {{ID}}\n },\n files=_files\n )\n assert response.status_code == 200\n else:\n pytest.fail(\"Scratch file does not exists.\")\n```\n\n========================================\n\nCode:\n```py\n@app.post(\"/analyse\")\nasync def analyse(file: bytes = File(...)):\n\n image = Image.open(io.BytesIO(file)).convert(\"RGB\")\n stats = process_image(image)\n return stats\n```\n\n```py\nimport requests\nfrom requests_toolbelt.multipart.encoder import MultipartEncoder\n\nurl = \"http://127.0.0.1:8000/analyse\"\n\nfilename = \"./example.jpg\"\nm = MultipartEncoder(\n fields={'file': ('filename', open(filename, 'rb'), 'image/jpeg')}\n )\nr = requests.post(url, data=m, headers={'Content-Type': m.content_type}, timeout = 8000)\nassert r.status_code == 200\n```\n\n```py\nfrom fastapi.testclient import TestClient\nfrom requests_toolbelt.multipart.encoder import MultipartEncoder\nfrom app.server import app\n\nclient = TestClient(app)\n\ndef test_image_analysis():\n\n filename = \"example.jpg\"\n\n m = MultipartEncoder(\n fields={'file': ('filename', open(filename, 'rb'), 'image/jpeg')}\n )\n\n response = client.post(\"/analyse\",\n data=m,\n headers={\"Content-Type\": \"multipart/form-data\"}\n )\n\n assert response.status_code == 200\n```\n\n```text\n> assert response.status_code == 200\nE assert 400 == 200\nE + where 400 = <Response [400]>.status_code\n\ntests\\test_server.py:22: AssertionError\n-------------------------------------------------------- Captured log call --------------------------------------------------------- \nERROR fastapi:routing.py:133 Error getting request body: can't concat NoneType to bytes\n===================================================== short test summary info ====================================================== \nFAILED tests/test_server.py::test_image_analysis - assert 400 == 200\n```\n\n```text\nrequests\n```\n\n```text\npython -m pytest\n```\n\n```text\ntest_image_analysis()\n```\n\n```text\n# change it\nr = requests.post(url, data=m, headers={'Content-Type': m.content_type}, timeout = 8000)\n\n# to \nr = requests.post(url, files={\"file\": (\"filename\", open(filename, \"rb\"), \"image/jpeg\")})\n```\n\n```text\n# change\nresponse = client.post(\"/analyse\",\n data=m,\n headers={\"Content-Type\": \"multipart/form-data\"}\n )\n# to\nresponse = client.post(\n \"/analyse\", files={\"file\": (\"filename\", open(filename, \"rb\"), \"image/jpeg\")}\n)\n```\n\n```text\nrequests\n```\n\n```text\nTestClient\n```\n\n```text\nTestClient\n```\n\n```text\nrequests\n```\n\n```text\nFastAPI\n```\n\n```text\nTestClient\n```\n\n```text\nMultipartEncoder\n```\n\n```text\nrequests\n```\n\n```text\nform-data\n```\n\n```text\nfrom fastapi import APIRouter, File, UploadFile, Query\nrouter = APIRouter()\n@router.post(path=\"{{API_PATH}}\", tags=[\"Prediction\"])\ndef prediction(id: str, uploadFile: UploadFile):\n ...\n {{CODE}}\n return response\n```\n\n```text\nimport pytest\nimport os\nfrom fastapi.testclient import TestClient\nimport.api_routers\n\nclient = TestClient(api_routers.router)\n\ndef test_prediction(constants): \n # Use constants if fixture created\n file_path = \"{{IMAGE PATH}}\"\n if os.path.isfile(file_path):\n _files = {'uploadFile': open(file_path, 'rb')}\n response = client.post('{{API_PATH}}',\n params={\n \"id\": {{ID}}\n },\n files=_files\n )\n assert response.status_code == 200\n else:\n pytest.fail(\"Scratch file does not exists.\")\n```\n\n========================================\n\nComments:\n- Future readers might find this answer and this answer helpful\n- Note that other form data could be included, if needed, via `data=`, which accepts a python dictionary. No multipart encoder needed.\n- I have followed this code, but my file is a `pdf`. Its not working. Can you help?\n- in my case, I used requests first and coppy pasted the result from curlconverter.com, include `data = '------WebKitFormBoundaryvFl3VlIejTySgos8\\r\\nContent-Disposi‌​tion: form-data; name=\"file\"; filename=\"785657825.png\"\\r\\nContent-Type: image/png\\r\\n\\r\\n\\r\\n------WebKitFormBoundaryvFl3VlIejTySgos‌​8--\\r\\n'` and then `requests.post('http://0.0.0.0:8000/removebackground',...,dat‌​a=data)` but it did not work; thanks for `files={...}`","metadata":{"transformedAt":"2026-08-18T18:32:29.098Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":20,"totalLines":292,"estimatedTokens":1833}}98{"id":"stack-71882419","source":"stackoverflow","questionId":71882419,"title":"FastAPI - How to get the response body in Middleware","tags":["python","fastapi","response","middleware","starlette"],"text":"Title: FastAPI - How to get the response body in Middleware\nTags: python, fastapi, response, middleware, starlette\nSource: Stack Overflow\n\nQuestion:\nIs there any way to get the response body/content in a middleware?\nThe following code is a copy from here.\n\n```\n@app.middleware(\"http\")\nasync def add_process_time_header(request: Request, call_next):\n start_time = time.time()\n response = await call_next(request)\n process_time = time.time() - start_time\n response.headers[\"X-Process-Time\"] = str(process_time)\n return response\n```\n\n========================================\n\nCode:\n```text\n@app.middleware(\"http\")\nasync def add_process_time_header(request: Request, call_next):\n start_time = time.time()\n response = await call_next(request)\n process_time = time.time() - start_time\n response.headers[\"X-Process-Time\"] = str(process_time)\n return response\n```\n\n```py\nfrom starlette.concurrency import iterate_in_threadpool\n\n@app.middleware(\"http\")\nasync def some_middleware(request: Request, call_next):\n response = await call_next(request)\n response_body = [chunk async for chunk in response.body_iterator]\n response.body_iterator = iterate_in_threadpool(iter(response_body))\n print(f\"response_body={response_body[0].decode()}\")\n return response\n```\n\n```py\nprint(f\"response_body={(b''.join(response_body)).decode()}\")\n```\n\n```py\n@app.middleware(\"http\")\nasync def some_middleware(request: Request, call_next):\n response = await call_next(request)\n chunks = []\n async for chunk in response.body_iterator:\n chunks.append(chunk)\n response_body = b''.join(chunks)\n print(f\"response_body={response_body.decode()}\")\n return Response(content=response_body, status_code=response.status_code, \n headers=dict(response.headers), media_type=response.media_type)\n```\n\n```text\nresponse\n```\n\n```text\nlist\n```\n\n```text\nbytes\n```\n\n```text\nResponse\n```\n\n```text\nrequest\n```\n\n```text\nmiddleware\n```\n\n```text\nlist\n```\n\n```text\niterate_in_threadpool\n```\n\n```text\nStreamingResponse\n```\n\n```text\nStreamingResponse\n```\n\n```text\nresponse_body[0]\n```\n\n```text\nchunk\n```\n\n```text\nresponse\n```\n\n```text\nresponse\n```\n\n```text\n.decode()\n```\n\n```text\nbytes\n```\n\n```text\nStreamingResponse\n```\n\n```text\nresponse.body_iterator\n```\n\n```text\nresponse.body_iterator\n```\n\n```text\nStreamingResponse\n```\n\n```text\niterate_in_threadpool\n```\n\n```text\nbytes\n```\n\n```text\nResponse\n```\n\n```text\nstatus_code\n```\n\n```text\nheaders\n```\n\n```text\nmedia_type\n```\n\n========================================\n\nComments:\n- Note that while these options allow reading a response body, it cannot be simply modified without taking additional measures. Changes affecting payload size might cause mismatch between `Content-Length` header value and the actual length. I was able to overcome this limitation by removing `content-length` key (lowercase) from the headers dictionary before passing it to the new `Response` object.\n- @MaksBabarowski You do understand though that the answer addresses the problem (as defined in the question) of *getting* (**not** *modifying*) the respond body.","metadata":{"transformedAt":"2026-08-18T18:32:29.099Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":30,"totalLines":169,"estimatedTokens":771}}99{"id":"stack-71298179","source":"stackoverflow","questionId":71298179,"title":"FastAPI - How to get app instance inside a router?","tags":["python","state","fastapi","starlette"],"text":"Title: FastAPI - How to get app instance inside a router?\nTags: python, state, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nI would like to get the `app` instance inside my router file. How should I do that?\n\nMy `main.py` is as follows:\n\n```\n# ...\napp = FastAPI()\napp.machine_learning_model = joblib.load(some_path)\napp.include_router(some_router)\n# ...\n```\n\nNow, I want to use `app.machine_learning_model` in `some_router`'s file. What should I do?\n\n========================================\n\nTop Answer:\nIf it works when running, but not during tests, beware how do you create the app_client fixture. This one works for me:\n\n```\n@pytest.fixture\ndef app() -> FastAPI:\n return create_app()\n\n@pytest.fixture\ndef app_client(app: FastAPI) -> Generator[TestClient, None, None]:\n \"\"\"Provides a client connected to the real app\"\"\"\n with TestClient(app) as client:\n yield client\n```\n\n========================================\n\nCode:\n```py\n# ...\napp = FastAPI()\napp.machine_learning_model = joblib.load(some_path)\napp.include_router(some_router)\n# ...\n```\n\n```text\napp\n```\n\n```text\nmain.py\n```\n\n```text\napp.machine_learning_model\n```\n\n```text\nsome_router\n```\n\n```py\napp.state.ml_model = joblib.load(some_path)\n```\n\n```py\nfrom fastapi import Request\n\n@router.get('/')\ndef some_router_function(request: Request):\n model = request.app.state.ml_model\n```\n\n```text\napp.state\n```\n\n```text\nState\n```\n\n```text\napp\n```\n\n```text\nRequest\n```\n\n```text\nrequest\n```\n\n```text\napp\n```\n\n```text\nrequest.app\n```\n\n```text\nrequest.state\n```\n\n```text\nlifespan\n```\n\n```py\n@pytest.fixture\ndef app() -> FastAPI:\n return create_app()\n\n@pytest.fixture\ndef app_client(app: FastAPI) -> Generator[TestClient, None, None]:\n \"\"\"Provides a client connected to the real app\"\"\"\n with TestClient(app) as client:\n yield client\n```\n\n========================================\n\nComments:\n- May I add other request params in `some_router_function` ?\n- Yes. You can define params as usual.\n- Thank you for your answer! I'm quite shocked that FastAPI does not provide any streamlined possibility to store Singletons for the service lifecycle.\n- Does this load model into memory only once and then pass the reference? I assume there is, since there is only one instance of the app running in the process?\n- @ruslaniv It does, and it would be best to initialise that variable inside a startup/lifespan event hanlder, as described here. If you plan on having multiple workers active at the same time, you might want to have a look at this and this as well.\n- Is it possible to define router-specific state? Suppose I have multiple routers, one per model; can I avoid loading them all in the top-level app's startup hook?\n- Unfortunately this doesn't work if you use `uvicorn`'s reload argument for restarting the app when files are changed.\n- @BenButterworth If that's true, please report it to uvicorn","metadata":{"transformedAt":"2026-08-18T18:32:29.099Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":17,"totalLines":134,"estimatedTokens":719}}100{"id":"stack-68705698","source":"stackoverflow","questionId":68705698,"title":"How to write tests for Pydantic models in FastAPI?","tags":["python","unit-testing","pytest","fastapi","pydantic"],"text":"Title: How to write tests for Pydantic models in FastAPI?\nTags: python, unit-testing, pytest, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI just started using FastAPI but I do not know how do I write a unit test (using pytest) for a Pydantic model.\n\nHere is a sample Pydantic model:\n\n```\nclass PhoneNumber(BaseModel):\n id: int\n country: str\n country_code: str\n number: str\n extension: str\n```\n\nI want to test this model by creating a sample `PhoneNumber` instance and ensure that the `PhoneNumber` instance tallies with the field types. For example:\n\n```\nPhoneNumber(1, \"country\", \"code\", \"number\", \"extension\")\n```\n\nThen, I want to assert that PhoneNumber.country equals \"country\".\n\n========================================\n\nCode:\n```text\nclass PhoneNumber(BaseModel):\n id: int\n country: str\n country_code: str\n number: str\n extension: str\n```\n\n```text\nPhoneNumber(1, \"country\", \"code\", \"number\", \"extension\")\n```\n\n```text\nPhoneNumber\n```\n\n```text\nPhoneNumber\n```\n\n```text\nimport pytest\n\ndef test_phonenumber():\n pn = PhoneNumber(id=1, country=\"country\", country_code=\"code\", number=\"number\", extension=\"extension\")\n\n assert pn.id == 1\n assert pn.country == 'country'\n assert pn.country_code == 'code'\n assert pn.number == 'number'\n assert pn.extension == 'extension'\n```\n\n```text\nfrom pydantic import BaseModel, root_validator\n\nclass PhoneNumber(BaseModel):\n ...\n\n @root_validator(pre=True)\n def check_country(cls, values):\n \"\"\"Check that country_code is the 1st 2 letters of country\"\"\"\n country: str = values.get('country')\n country_code: str = values.get('country_code')\n if not country.lower().startswith(country_code.lower()):\n raise ValueError('country_code and country do not match')\n return values\n```\n\n```text\nimport pytest\n\ndef test_phonenumber_country_code():\n \"\"\"Expect test to fail because country_code and country do not match\"\"\"\n with pytest.raises(ValueError):\n PhoneNumber(id=1, country='JAPAN', country_code='XY', number='123', extension='456')\n```\n\n```text\n@app.post(\"/phonenumber\")\nasync def add_phonenumber(phonenumber: PhoneNumber):\n \"\"\"The model is used here as part of the Request Body\"\"\"\n # Do something with phonenumber\n return JSONResponse({'message': 'OK'}, status_code=200)\n```\n\n```text\nfrom fastapi.testclient import TestClient\n\nclient = TestClient(app)\n\ndef test_add_phonenumber_ok():\n \"\"\"Valid PhoneNumber, should be 200/OK\"\"\"\n # This would be what the JSON body of the request would look like\n body = {\n \"id\": 1,\n \"country\": \"Japan\",\n \"country_code\": \"JA\",\n \"number\": \"123\",\n \"extension\": \"81\",\n }\n response = client.post(\"/phonenumber\", json=body)\n assert response.status_code == 200\n\n\ndef test_add_phonenumber_error():\n \"\"\"Invalid PhoneNumber, should be a validation error\"\"\"\n # This would be what the JSON body of the request would look like\n body = {\n \"id\": 1,\n \"country\": \"Japan\",\n # `country_code` is missing\n \"number\": 99999, # `number` is int, not str\n \"extension\": \"81\",\n }\n response = client.post(\"/phonenumber\", json=body)\n assert response.status_code == 422\n assert response.json() == {\n 'detail': [{\n 'loc': ['body', 'country_code'],\n 'msg': 'field required',\n 'type': 'value_error.missing'\n }]\n }\n```\n\n```text\nPhoneNumber\n```\n\n```text\ncountry\n```\n\n```text\ncountry_code\n```\n\n========================================\n\nComments:\n- What do you expect the test to check? How does it relate to FastAPI? Because you can use pydantic models *without* using FastAPI.\n- @GinoMempin Please check my edit.\n- @Mark Yes, it was. I've made changes. Thanks for pointing it out.\n- Generally speaking, you *don't* write tests like this. Pydantic has a good test suite (including a unit test like the one you're proposing) . Your test should cover the code and logic you wrote, not the packages you imported.\n- @Mark Oh! I see. Thanks a lot!\n- Since you tagged this with FastAPI, and if you are using this model as part of a route (either as a request parameter or a response model), then a more useful test is to check that calling your route/API correctly uses your model (ex. passing a JSON body translates correctly into you PhoneNumber model).\n- @GinoMempin I understand now. Thanks!\n- How are you mimicking database operations and pydantic models in between\n- @PrashantGupta It depends on what exactly you are testing. If it's an integration test (API - DB), then you don't mimick anything, you have a local DB and you let your API access that normally. If it's unit tests, then you can mock them: docs.python.org/3/library/unittest.mock.html","metadata":{"transformedAt":"2026-08-18T18:32:29.099Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":12,"totalLines":160,"estimatedTokens":1195}}101{"id":"stack-65699977","source":"stackoverflow","questionId":65699977,"title":"FastApi Sqlalchemy how to manage transaction (session and multiple commits)","tags":["python","database","sqlalchemy","transactions","fastapi"],"text":"Title: FastApi Sqlalchemy how to manage transaction (session and multiple commits)\nTags: python, database, sqlalchemy, transactions, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have a CRUD with insert and update functions with `commit` at the end of the each one as follows:\n\n```\n@staticmethod\ndef insert(db: Session, item: Item) -> None:\n db.add(item)\n db.commit()\n \n \n@staticmethod\ndef update(db: Session, item: Item) -> None:\n ...\n db.commit()\n```\n\nI have an endpoint which receives a sqlalchemy session from a FastAPI dependency and needs to insert and update atomically (DB transaction).\n\nWhat's the best practice when working with transactions? I can't work with the CRUD since it does more than one `commit`.\n\nHow should I handle the transactions? Where do you commit your session? in the CRUD? or only once in the FastAPI dependency function for each request?\n\n========================================\n\nTop Answer:\nA more pythonic approach is to let a context manager perform a commit or rollback depending on whether or not there was an exception.\n\nA `Transaction` is a nice abstraction of what we are trying to accomplish.\n\n```\nclass Transaction:\n def __init__(self, session: Session = Depends(get_session)):\n self.session = session\n\n def __enter__(self):\n return self\n\n def __exit__(self, exc_type, exc_val, exc_tb):\n if exc_type is not None:\n # rollback and let the exception propagate\n self.session.rollback()\n return False\n\n self.session.commit()\n return True\n```\n\nAnd, use it in your APIs, like so:\n\n```\ndef some_api(tx: Transaction = Depends(Transaction)):\n with tx:\n ThingOne().go()\n ThingTwo().go()\n```\n\nNo need to pass session to ThingOne and ThingTwo. Inject it into them, like so:\n\n```\nclass ThingOne:\n def __init__(self, session: Session = Depends(get_session)):\n ...\n\nclass ThingTwo:\n def __init__(self, session: Session = Depends(get_session)):\n ...\n```\n\nI would also inject ThingOne and ThingTwo in the APIs as well:\n\n```\ndef some_api(tx: Transaction = Depends(Transaction), \n one: ThingOne = Depends(ThingOne), \n two: ThingTwo = Depends(ThingTwo)):\n with tx:\n one.go()\n two.go()\n```\n\n========================================\n\nCode:\n```py\n@staticmethod\ndef insert(db: Session, item: Item) -> None:\n db.add(item)\n db.commit()\n \n \n@staticmethod\ndef update(db: Session, item: Item) -> None:\n ...\n db.commit()\n```\n\n```text\ncommit\n```\n\n```text\ncommit\n```\n\n```text\ndef run_my_program():\n # This happens in the `database = SessionLocal()` of the `get_db` method below\n session = Session()\n try:\n ThingOne().go(session)\n ThingTwo().go(session)\n\n session.commit()\n except:\n session.rollback()\n raise\n finally:\n # This is the same as the `get_db` method below\n session.close()\n```\n\n```text\ndef create_user(db: Session, user: UserCreate):\n \"\"\"\n Create user record\n \"\"\"\n fake_hashed_password = user.password + \"notreallyhashed\"\n db_user = models.User(email=user.email, hashed_password=fake_hashed_password)\n db.add(db_user)\n db.flush() # Changed this to a flush\n return db_user\n```\n\n```text\nfrom typing import List\nfrom fastapi import Depends, HTTPException\nfrom sqlalchemy.orm import Session\n\n...\n\ndef get_db():\n \"\"\"\n Get SQLAlchemy database session\n \"\"\"\n database = SessionLocal()\n try:\n yield database\n finally:\n database.close()\n\n@router.post(\"/users\", response_model=List[schemas.User])\ndef create_users(user_1: schemas.UserCreate, user_2: schemas.UserCreate, db: Session = Depends(get_db)):\n \"\"\"\n Create two users\n \"\"\"\n try:\n user_1 = crud.create_user(db=db, user=user_1)\n user_2 = crud.create_user(db=db, user=user_2)\n db.commit()\n return [user_1, user_2]\n except:\n db.rollback()\n raise HTTPException(status_code=400, detail=\"Duplicated user\")\n```\n\n```text\ncommit\n```\n\n```text\ncommit\n```\n\n```text\nrollback\n```\n\n```text\ncommit\n```\n\n```py\nclass Transaction:\n def __init__(self, session: Session = Depends(get_session)):\n self.session = session\n\n def __enter__(self):\n return self\n\n def __exit__(self, exc_type, exc_val, exc_tb):\n if exc_type is not None:\n # rollback and let the exception propagate\n self.session.rollback()\n return False\n\n self.session.commit()\n return True\n```\n\n```py\ndef some_api(tx: Transaction = Depends(Transaction)):\n with tx:\n ThingOne().go()\n ThingTwo().go()\n```\n\n```py\nclass ThingOne:\n def __init__(self, session: Session = Depends(get_session)):\n ...\n\nclass ThingTwo:\n def __init__(self, session: Session = Depends(get_session)):\n ...\n```\n\n```py\ndef some_api(tx: Transaction = Depends(Transaction), \n one: ThingOne = Depends(ThingOne), \n two: ThingTwo = Depends(ThingTwo)):\n with tx:\n one.go()\n two.go()\n```\n\n```text\nTransaction\n```\n\n========================================\n\nComments:\n- You can do multiple transactions in a single request as long as it is not a problem for your business logic. Doing `flush()` doesn't do much. The changes are not persisted, just communicated with the database. If you need a transactional safety you need to make sure you are using `SELECT .. FOR UPDATE` correctly and doing a single transaction after you finished doing the updates. That is very safe but error prone. I'd say if your app won't see tons of requests where this kind of race condition is a real risk than you just ignore it and do `commit()` as you already have.\n- @JosephAsafGardin great to hear! If that's the case can you mark the answer as the accepted one? Cheers!\n- Thanks for sharing! I've been searching for a better way of doing this, and also how to do tests for these.","metadata":{"transformedAt":"2026-08-18T18:32:29.099Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":15,"totalLines":238,"estimatedTokens":1442}}102{"id":"stack-70383316","source":"stackoverflow","questionId":70383316,"title":"Pydantic constr vs Field args","tags":["python","fastapi","python-typing","pydantic"],"text":"Title: Pydantic constr vs Field args\nTags: python, fastapi, python-typing, pydantic\nSource: Stack Overflow\n\nQuestion:\nI wanted to know what is the difference between:\n\n```\nfrom pydantic import BaseModel, Field\n\nclass Person(BaseModel):\n name: str = Field(..., min_length=1)\n```\n\nAnd:\n\n```\nfrom pydantic import BaseModel, constr\n\nclass Person(BaseModel):\n name: constr(min_length=1)\n```\n\nBoth seem to perform the same validation (even raise the exact same exception info when `name` is an empty string). Is it just a matter of code style? Is one of them preferred over the other?\n\nAlso, if I wanted to include a list of nonempty strings as an attribute, which of these ways do you think would be better?:\n\n```\nfrom typing import List\nfrom pydantic import BaseModel, constr\n\nclass Person(BaseModel):\n languages: List[constr(min_length=1)]\n```\n\nOr:\n\n```\nfrom typing import List \nfrom pydantic import BaseModel, Field\n\nclass Person(BaseModel):\n languages: List[str]\n \n @validator('languages', each_item=True)\n def check_nonempty_strings(cls, v):\n if not v:\n raise ValueError('Empty string is not a valid language.')\n return v\n```\n\nEDIT:\nFWIW, I am using this for a FastAPI app.\n\nEDIT2:\nFor my 2nd question, I think the first alternative is better, as it includes the length requirement in the Schema (and so it's in the documentation)\n\n========================================\n\nTop Answer:\nThis link shows the methods that do and don't work for pydantic and mypy together: https://lyz-code.github.io/blue-book/coding/python/pydantic_types/#using-constrained-strings-in-list-attributes\n\nThe best option for my use case was to make a class that inherited from `pydantic.ConstrainedStr` as so:\n\n```\nimport pydantic\nfrom typing import List\n\n...\n\nclass Regex(pydantic.ConstrainedStr):\n regex = re.compile(\"^[0-9a-z_]*$\")\n\nclass Data(pydantic.BaseModel):\n regex: List[Regex]\n # regex: list[Regex] if you are on 3.9+\n```\n\n========================================\n\nCode:\n```text\nfrom pydantic import BaseModel, Field\n\nclass Person(BaseModel):\n name: str = Field(..., min_length=1)\n```\n\n```text\nfrom pydantic import BaseModel, constr\n\nclass Person(BaseModel):\n name: constr(min_length=1)\n```\n\n```text\nfrom typing import List\nfrom pydantic import BaseModel, constr\n\nclass Person(BaseModel):\n languages: List[constr(min_length=1)]\n```\n\n```text\nfrom typing import List \nfrom pydantic import BaseModel, Field\n\nclass Person(BaseModel):\n languages: List[str]\n \n @validator('languages', each_item=True)\n def check_nonempty_strings(cls, v):\n if not v:\n raise ValueError('Empty string is not a valid language.')\n return v\n```\n\n```text\nname\n```\n\n```py\nstrip_whitespace: bool = False: removes leading and trailing whitespace\n to_lower: bool = False: turns all characters to lowercase\n to_upper: bool = False: turns all characters to uppercase\n strict: bool = False: controls type coercion\n min_length: int = None: minimum length of the string\n max_length: int = None: maximum length of the string\n curtail_length: int = None: shrinks the string length to the set value when it is longer than the set value\n regex: str = None: regex to validate the string against\n```\n\n```py\nclass Voice(BaseModel):\n name: str = Field(None, alias='ActorName')\n language_code: str = None\n mood: str = None\n```\n\n```text\nclass Car(BaseModel):\n description: Union[constr(min_length=1, max_length=64), None] = Field(\n default=None,\n example=\"something\",\n description=\"Your car description\",\n )\n```\n\n```text\nField()\n```\n\n```py\nimport pydantic\nfrom typing import List\n\n...\n\nclass Regex(pydantic.ConstrainedStr):\n regex = re.compile(\"^[0-9a-z_]*$\")\n\nclass Data(pydantic.BaseModel):\n regex: List[Regex]\n # regex: list[Regex] if you are on 3.9+\n```\n\n```text\npydantic.ConstrainedStr\n```\n\n```text\nfrom pydantic import BaseModel, Field, FilePath, constr\nfrom typing import Union, Annotated\n\nContactConstr = constr(regex='\\d{3}-\\d{3}-\\d{4}')\nContactField = Annotated[str, Field(regex='\\d{3}-\\d{3}-\\d{4}')]\n\nclass Person(BaseModel):\n contact_with_constr: ContactConstr\n contact_with_field: ContactField\n contacts_with_constr: Union[ContactConstr, list[ContactConstr]]\n contacts_with_field: Union[ContactField, list[ContactField]] # yields incorrect schema\n\nprint(Person.schema_json(indent=2))\n```\n\n```text\n{\n \"title\": \"Person\",\n \"type\": \"object\",\n \"properties\": {\n \"contact_with_constr\": {\n \"title\": \"Contact With Constr\",\n \"pattern\": \"\\\\d{3}-\\\\d{3}-\\\\d{4}\",\n \"type\": \"string\"\n },\n \"contact_with_field\": {\n \"title\": \"Contact With Field\",\n \"pattern\": \"\\\\d{3}-\\\\d{3}-\\\\d{4}\",\n \"type\": \"string\"\n },\n \"contacts_with_constr\": {\n \"title\": \"Contacts With Constr\",\n \"anyOf\": [\n {\n \"type\": \"string\",\n \"pattern\": \"\\\\d{3}-\\\\d{3}-\\\\d{4}\"\n },\n {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\",\n \"pattern\": \"\\\\d{3}-\\\\d{3}-\\\\d{4}\"\n }\n }\n ]\n },\n \"contacts_with_field\": {\n \"title\": \"Contacts With Field\",\n \"anyOf\": [\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n }\n ]\n }\n },\n \"required\": [\n \"contact_with_constr\",\n \"contact_with_field\",\n \"contacts_with_constr\",\n \"contacts_with_field\"\n ]\n}\n```\n\n```text\npydantic 1.10.4\n```\n\n```text\npython 3.9\n```\n\n```text\nconstr\n```\n\n```text\nField\n```\n\n```text\ncontacts_with_field\n```\n\n```text\nxxx-xxx-xxxx\n```\n\n```text\nx\n```\n\n========================================\n\nComments:\n- github.com/pydantic/pydantic/issues/156\n- Thank you! About the second question, the problem with your solution is that it requires the list to have 1 item, and that is not what I wanted. I need to have a list which values must be non-empty strings. So these are valid: `[]`, `[\"english\", \"spanish\"]`; and this isn't: `[\"german\", \"\"]` . For this, I didn't found any solution to achieve it with `Field` other than using validators. But then that requirement is not auto-included in the docs.\n- mood: str = None, wrong, mood:str|None = None","metadata":{"transformedAt":"2026-08-18T18:32:29.099Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":20,"totalLines":275,"estimatedTokens":1553}}103{"id":"stack-68914523","source":"stackoverflow","questionId":68914523,"title":"FastAPI - Pydantic - Value Error Raises Internal Server Error","tags":["python","python-3.x","fastapi","pydantic"],"text":"Title: FastAPI - Pydantic - Value Error Raises Internal Server Error\nTags: python, python-3.x, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI am using FastAPI with Pydantic.\n\nMy problem - I need to raise ValueError using Pydantic\n\n```\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel, validator\nfrom fastapi import Depends, HTTPException\n\napp = FastAPI()\n\nclass RankInput(BaseModel):\n\n rank: int\n\n @validator('rank')\n def check_if_value_in_range(cls, v):\n \"\"\"\n check if input rank is within range\n \"\"\"\n if not 0 this piece of code gives `Internal Server Error` when a ValueError is raised\n\n```\nINFO: 127.0.0.1:59427 - \"GET /info/?rank=-1 HTTP/1.1\" 500 Internal Server Error\nERROR: Exception in ASGI application\nTraceback (most recent call last):\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/uvicorn/protocols/http/h11_impl.py\", line 396, in run_asgi\n result = await app(self.scope, self.receive, self.send)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/uvicorn/middleware/proxy_headers.py\", line 45, in __call__\n return await self.app(scope, receive, send)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/fastapi/applications.py\", line 199, in __call__\n await super().__call__(scope, receive, send)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/applications.py\", line 111, in __call__\n await self.middleware_stack(scope, receive, send)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/middleware/errors.py\", line 181, in __call__\n raise exc from None\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/middleware/errors.py\", line 159, in __call__\n await self.app(scope, receive, _send)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/exceptions.py\", line 82, in __call__\n raise exc from None\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/exceptions.py\", line 71, in __call__\n await self.app(scope, receive, sender)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/routing.py\", line 566, in __call__\n await route.handle(scope, receive, send)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/routing.py\", line 227, in handle\n await self.app(scope, receive, send)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/routing.py\", line 41, in app\n response = await func(request)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/fastapi/routing.py\", line 195, in app\n dependency_overrides_provider=dependency_overrides_provider,\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/fastapi/dependencies/utils.py\", line 550, in solve_dependencies\n solved = await run_in_threadpool(call, **sub_values)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/concurrency.py\", line 34, in run_in_threadpool\n return await loop.run_in_executor(None, func, *args)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/concurrent/futures/thread.py\", line 57, in run\n result = self.fn(*self.args, **self.kwargs)\n File \"pydantic/main.py\", line 400, in pydantic.main.BaseModel.__init__\npydantic.error_wrappers.ValidationError: 1 validation error for GetInput\nrank\n ValueError() takes no keyword arguments (type=type_error)\nERROR:uvicorn.error:Exception in ASGI application\nTraceback (most recent call last):\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/uvicorn/protocols/http/h11_impl.py\", line 396, in run_asgi\n result = await app(self.scope, self.receive, self.send)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/uvicorn/middleware/proxy_headers.py\", line 45, in __call__\n return await self.app(scope, receive, send)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/fastapi/applications.py\", line 199, in __call__\n await super().__call__(scope, receive, send)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/applications.py\", line 111, in __call__\n await self.middleware_stack(scope, receive, send)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/middleware/errors.py\", line 181, in __call__\n raise exc from None\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/middleware/errors.py\", line 159, in __call__\n await self.app(scope, receive, _send)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/exceptions.py\", line 82, in __call__\n raise exc from None\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/exceptions.py\", line 71, in __call__\n await self.app(scope, receive, sender)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/routing.py\", line 566, in __call__\n await route.handle(scope, receive, send)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/routing.py\", line 227, in handle\n await self.app(scope, receive, send)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/routing.py\", line 41, in app\n response = await func(request)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/fastapi/routing.py\", line 195, in app\n dependency_overrides_provider=dependency_overrides_provider,\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/fastapi/dependencies/utils.py\", line 550, in solve_dependencies\n solved = await run_in_threadpool(call, **sub_values)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/concurrency.py\", line 34, in run_in_threadpool\n return await loop.run_in_executor(None, func, *args)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/concurrent/futures/thread.py\", line 57, in run\n result = self.fn(*self.args, **self.kwargs)\n File \"pydantic/main.py\", line 400, in pydantic.main.BaseModel.__init__\npydantic.error_wrappers.ValidationError: 1 validation error for GetInput\nrank\n ValueError() takes no keyword arguments (type=type_error)\n```\n\nI also checked https://github.com/tiangolo/fastapi/issues/2180.\n\nBut I was not able to figure out a solution.\n\nWhat I need to do is Raise `ValueError` with a Custom Status Code.\n\nNote - I know I can get the Job Done by raising `HTTPException`.\n\nBut I am looking for a solution using `ValueError`\n\nCould you tell me where I am going wrong?\n\nHave Also Posted this Issue on Github - https://github.com/tiangolo/fastapi/issues/3761\n\n========================================\n\nTop Answer:\nPlease note that `pydantic` expects that validators raise a `ValueError`, `TypeError`, or `AssertionError` (see docs) which `pydantic` will convert into a `ValidationError`.\n\nFurther, as per FastAPI's documentation:\n\nWhen a request contains invalid data, FastAPI internally raises a `RequestValidationError`.\n\nand\n\n`RequestValidationError` is a sub-class of Pydantic's `ValidationError`.\n\nThe result of this is that a standard `Validation` error raised during `pydantic`'s Model validation will be translated into a `422 Unprocessable Entity`, and the response body will contain details on why the validation failed.\n\n(As a side note: `pydantic` comes with constrained types which allow to constrain basic datatypes without having to write explicit validators.)\n\nIf the above is not satisfactory and you'd like to change the behaviour, here's how I would approach it (see here for details on the `ValidationError` handling):\n\n```\nfrom fastapi import Depends, FastAPI, Request, status\nfrom fastapi.exceptions import RequestValidationError\nfrom fastapi.exception_handlers import request_validation_exception_handler\nfrom fastapi.responses import JSONResponse\nfrom pydantic import BaseModel, conint\n\nclass RankInput(BaseModel):\n # Constrained integer, must be greater than or equal to 0\n # and less than or equal to 1 million.\n rank: conint(ge=0, le=1_000_000)\n\nasync def rank_out_of_bound_handler(request: Request, exc: RequestValidationError):\n\n validation_errors = exc.errors()\n for err in validation_errors:\n # You could check for other things here as well, e.g. the error type.\n if \"rank\" in err[\"loc\"]:\n return JSONResponse(\n status_code=status.HTTP_400_BAD_REQUEST,\n content={\"message\": \"Rank must be in range [0, 1000000].\"}\n )\n\n # Default response in every other case.\n return await request_validation_exception_handler(request, exc)\n\ndef get_info_by_rank(rank):\n return rank\n\napp = FastAPI(\n exception_handlers={RequestValidationError: rank_out_of_bound_handler},\n)\n\n@app.get('/rank/{rank}')\nasync def get_rank(value: RankInput = Depends()):\n result = get_info_by_rank(value.rank)\n return result\n```\n\nA call to the endpoint now gives:\n\n```\n$ curl -i \"http://127.0.0.1:8000/rank/1\"\nHTTP/1.1 200 OK\ndate: Sat, 28 Aug 2021 20:47:58 GMT\nserver: uvicorn\ncontent-length: 1\ncontent-type: application/json\n\n1\n```\n\n```\n$ curl -i \"http://127.0.0.1:8000/rank/-1\"\nHTTP/1.1 400 Bad Request\ndate: Sat, 28 Aug 2021 20:48:24 GMT\nserver: uvicorn\ncontent-length: 49\ncontent-type: application/json\n\n{\"message\":\"Rank must be in range [0, 1000000].\"}\n```\n\n```\n$ curl -i \"http://127.0.0.1:8000/rank/1000001\"\nHTTP/1.1 400 Bad Request\ndate: Sat, 28 Aug 2021 20:48:51 GMT\nserver: uvicorn\ncontent-length: 49\ncontent-type: application/json\n\n{\"message\":\"Rank must be in range [0, 1000000].\"}\n```\n\nIf you were to add a different endpoint that uses the same model, the exception handler will automatically take care of this as well, e.g.:\n\n```\n@app.get('/other-rank/{rank}')\nasync def get_other_rank(value: RankInput = Depends()):\n result = get_info_by_rank(value.rank)\n return result\n```\n\n```\n$ curl -i \"http://127.0.0.1:8000/other-rank/-1\"\nHTTP/1.1 400 Bad Request\ndate: Sat, 28 Aug 2021 20:54:16 GMT\nserver: uvicorn\ncontent-length: 49\ncontent-type: application/json\n\n{\"message\":\"Rank must be in range [0, 1000000].\"}\n```\n\nIf this is not what you're looking for, could you explain why exactly you'd like to raise a `ValueError`?\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel, validator\nfrom fastapi import Depends, HTTPException\n\napp = FastAPI()\n\nclass RankInput(BaseModel):\n\n rank: int\n\n @validator('rank')\n def check_if_value_in_range(cls, v):\n \"\"\"\n check if input rank is within range\n \"\"\"\n if not 0 < v < 1000001:\n\n raise ValueError(\"Rank Value Must be within range (0,1000000)\")\n #raise HTTPException(status_code=400, detail=\"Rank Value Error\") - this works But I am looking for a solution using ValueError\n return v\n\ndef get_info_by_rank(rank):\n return rank\n\n@app.get('/rank/{rank}')\nasync def get_rank(value: RankInput = Depends()):\n result = get_info_by_rank(value.rank)\n return result\n```\n\n```text\nINFO: 127.0.0.1:59427 - \"GET /info/?rank=-1 HTTP/1.1\" 500 Internal Server Error\nERROR: Exception in ASGI application\nTraceback (most recent call last):\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/uvicorn/protocols/http/h11_impl.py\", line 396, in run_asgi\n result = await app(self.scope, self.receive, self.send)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/uvicorn/middleware/proxy_headers.py\", line 45, in __call__\n return await self.app(scope, receive, send)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/fastapi/applications.py\", line 199, in __call__\n await super().__call__(scope, receive, send)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/applications.py\", line 111, in __call__\n await self.middleware_stack(scope, receive, send)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/middleware/errors.py\", line 181, in __call__\n raise exc from None\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/middleware/errors.py\", line 159, in __call__\n await self.app(scope, receive, _send)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/exceptions.py\", line 82, in __call__\n raise exc from None\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/exceptions.py\", line 71, in __call__\n await self.app(scope, receive, sender)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/routing.py\", line 566, in __call__\n await route.handle(scope, receive, send)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/routing.py\", line 227, in handle\n await self.app(scope, receive, send)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/routing.py\", line 41, in app\n response = await func(request)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/fastapi/routing.py\", line 195, in app\n dependency_overrides_provider=dependency_overrides_provider,\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/fastapi/dependencies/utils.py\", line 550, in solve_dependencies\n solved = await run_in_threadpool(call, **sub_values)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/concurrency.py\", line 34, in run_in_threadpool\n return await loop.run_in_executor(None, func, *args)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/concurrent/futures/thread.py\", line 57, in run\n result = self.fn(*self.args, **self.kwargs)\n File \"pydantic/main.py\", line 400, in pydantic.main.BaseModel.__init__\npydantic.error_wrappers.ValidationError: 1 validation error for GetInput\nrank\n ValueError() takes no keyword arguments (type=type_error)\nERROR:uvicorn.error:Exception in ASGI application\nTraceback (most recent call last):\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/uvicorn/protocols/http/h11_impl.py\", line 396, in run_asgi\n result = await app(self.scope, self.receive, self.send)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/uvicorn/middleware/proxy_headers.py\", line 45, in __call__\n return await self.app(scope, receive, send)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/fastapi/applications.py\", line 199, in __call__\n await super().__call__(scope, receive, send)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/applications.py\", line 111, in __call__\n await self.middleware_stack(scope, receive, send)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/middleware/errors.py\", line 181, in __call__\n raise exc from None\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/middleware/errors.py\", line 159, in __call__\n await self.app(scope, receive, _send)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/exceptions.py\", line 82, in __call__\n raise exc from None\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/exceptions.py\", line 71, in __call__\n await self.app(scope, receive, sender)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/routing.py\", line 566, in __call__\n await route.handle(scope, receive, send)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/routing.py\", line 227, in handle\n await self.app(scope, receive, send)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/routing.py\", line 41, in app\n response = await func(request)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/fastapi/routing.py\", line 195, in app\n dependency_overrides_provider=dependency_overrides_provider,\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/fastapi/dependencies/utils.py\", line 550, in solve_dependencies\n solved = await run_in_threadpool(call, **sub_values)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/starlette/concurrency.py\", line 34, in run_in_threadpool\n return await loop.run_in_executor(None, func, *args)\n File \"/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/concurrent/futures/thread.py\", line 57, in run\n result = self.fn(*self.args, **self.kwargs)\n File \"pydantic/main.py\", line 400, in pydantic.main.BaseModel.__init__\npydantic.error_wrappers.ValidationError: 1 validation error for GetInput\nrank\n ValueError() takes no keyword arguments (type=type_error)\n```\n\n```text\nInternal Server Error\n```\n\n```text\nValueError\n```\n\n```text\nHTTPException\n```\n\n```text\nValueError\n```\n\n```text\nfrom fastapi import FastAPI, Request\nfrom fastapi.responses import JSONResponse\n\n\n@app.exception_handler(ValueError)\nasync def value_error_exception_handler(request: Request, exc: ValueError):\n return JSONResponse(\n status_code=400,\n content={\"message\": str(exc)},\n )\n```\n\n```text\n{\n \"message\": \"Value Must be within range (0,1000000)\"\n}\n```\n\n```text\nHTTPException\n```\n\n```text\nInternal Server Error\n```\n\n```text\nValueError\n```\n\n```py\nfrom fastapi import Depends, FastAPI, Request, status\nfrom fastapi.exceptions import RequestValidationError\nfrom fastapi.exception_handlers import request_validation_exception_handler\nfrom fastapi.responses import JSONResponse\nfrom pydantic import BaseModel, conint\n\nclass RankInput(BaseModel):\n # Constrained integer, must be greater than or equal to 0\n # and less than or equal to 1 million.\n rank: conint(ge=0, le=1_000_000)\n\nasync def rank_out_of_bound_handler(request: Request, exc: RequestValidationError):\n\n validation_errors = exc.errors()\n for err in validation_errors:\n # You could check for other things here as well, e.g. the error type.\n if \"rank\" in err[\"loc\"]:\n return JSONResponse(\n status_code=status.HTTP_400_BAD_REQUEST,\n content={\"message\": \"Rank must be in range [0, 1000000].\"}\n )\n\n # Default response in every other case.\n return await request_validation_exception_handler(request, exc)\n\ndef get_info_by_rank(rank):\n return rank\n\n\napp = FastAPI(\n exception_handlers={RequestValidationError: rank_out_of_bound_handler},\n)\n\n@app.get('/rank/{rank}')\nasync def get_rank(value: RankInput = Depends()):\n result = get_info_by_rank(value.rank)\n return result\n```\n\n```none\n$ curl -i \"http://127.0.0.1:8000/rank/1\"\nHTTP/1.1 200 OK\ndate: Sat, 28 Aug 2021 20:47:58 GMT\nserver: uvicorn\ncontent-length: 1\ncontent-type: application/json\n\n1\n```\n\n```none\n$ curl -i \"http://127.0.0.1:8000/rank/-1\"\nHTTP/1.1 400 Bad Request\ndate: Sat, 28 Aug 2021 20:48:24 GMT\nserver: uvicorn\ncontent-length: 49\ncontent-type: application/json\n\n{\"message\":\"Rank must be in range [0, 1000000].\"}\n```\n\n```none\n$ curl -i \"http://127.0.0.1:8000/rank/1000001\"\nHTTP/1.1 400 Bad Request\ndate: Sat, 28 Aug 2021 20:48:51 GMT\nserver: uvicorn\ncontent-length: 49\ncontent-type: application/json\n\n{\"message\":\"Rank must be in range [0, 1000000].\"}\n```\n\n```py\n@app.get('/other-rank/{rank}')\nasync def get_other_rank(value: RankInput = Depends()):\n result = get_info_by_rank(value.rank)\n return result\n```\n\n```none\n$ curl -i \"http://127.0.0.1:8000/other-rank/-1\"\nHTTP/1.1 400 Bad Request\ndate: Sat, 28 Aug 2021 20:54:16 GMT\nserver: uvicorn\ncontent-length: 49\ncontent-type: application/json\n\n{\"message\":\"Rank must be in range [0, 1000000].\"}\n```\n\n```text\npydantic\n```\n\n```text\nValueError\n```\n\n```text\nTypeError\n```\n\n```text\nAssertionError\n```\n\n```text\npydantic\n```\n\n```text\nValidationError\n```\n\n```text\nRequestValidationError\n```\n\n```text\nRequestValidationError\n```\n\n```text\nValidationError\n```\n\n```text\nValidation\n```\n\n```text\npydantic\n```\n\n```text\n422 Unprocessable Entity\n```\n\n```text\npydantic\n```\n\n```text\nValidationError\n```\n\n```text\nValueError\n```\n\n```text\nfrom pydantic.error_wrappers import ErrorWrapper\n\nclass RankInput(BaseModel):\n ...\n @classmethod\n def from_path(cls, *, rank):\n \"\"\"For use in Depends when extracting a model from the path. FastAPI doesn't\n automatically create a RequestValidationError from a ValidationError during\n Depends processing: https://github.com/tiangolo/fastapi/issues/1474\n \"\"\"\n try:\n return cls(rank=rank)\n except ValidationError as ex:\n raise RequestValidationError([ErrorWrapper(ex, (\"path\"))])\n\n\nasync def get_rank(value: RankInput = Depends(RankInput.from_path)):\n ...\n```\n\n```text\nErrorWrapper\n```\n\n```text\nValidationError\n```\n\n```text\nDepends()\n```\n\n```text\nRequestValidationError\n```\n\n```text\nValidationError\n```\n\n```text\nRequestValidationError\n```\n\n```text\nValueError\n```\n\n```text\nValidationError\n```\n\n```text\nJSONResponse\n```\n\n```text\nValueError\n```\n\n```text\nJSONResponse\n```\n\n```text\nRequestValidationError\n```\n\n========================================\n\nComments:\n- `ValueError` is one of the basic exception classes in Python. This doesn't have any functionality to handle the status code. (But, you can do something similar by inheriting the same class)\n- Raising the `ValueError` obviously cause the ***Internal Server Error***, I don't understand why would you want that\n- I was using HTTPException itself. I was 'asked' to use ValueError.\n- That is so weird because I expected this to be implanted within pydantic validation :S\n- Thank you for your Answer. what I am looking for is Something which can be used within the Models.\n- How is the model being used? Is it as a type hint in your route? Or are you using it in the body of a function (e.g. via parse_obj())? Can you an example by updating your question? If it’s in the body then you can catch the ValueError there and return a valid response (or raise a HTTPException), but otherwise there’s probably no solution as any Exception raised by the model will be raised to FastAPI and without an exception handler it will respond with a 500. You can’t return a response from a model, you can only do that from your route function, an exception handler, or some middleware.\n- Okay thanks, your Model is being used as a Dependency. The DI system would handle a HTTPException raised from the Model validator, but anything else will result in a 500 by design. see here If you want your app to respond in a custom way from a model without using HTTPException, the only way I'm aware of is to raise a custom exception and add a custom exception handler to the app that returns a custom response. You can't return the response directly from the model though.\n- That is so weird because I expected this to be implanted within pydantic validation :S\n- What exactly do you mean? What were you expecting to be part of Pydantic?\n- this is exactly what I needed; I needed to return a specific error code and message when there is a validation error, like missing fields.","metadata":{"transformedAt":"2026-08-18T18:32:29.099Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":45,"totalLines":622,"estimatedTokens":5928}}104{"id":"stack-68270330","source":"stackoverflow","questionId":68270330,"title":"How to return status code in response correctly?","tags":["fastapi","http-status-codes"],"text":"Title: How to return status code in response correctly?\nTags: fastapi, http-status-codes\nSource: Stack Overflow\n\nQuestion:\nSo I am learning FastAPI and I am trying to figure out how to return the status code correctly.\nI made an endpoint for uploading a file and I want to make a special response in case the file format is unsupported. It seems like I did everything according to the official documentation, but I am always getting `422 Unprocessable Entity` error.\n\nHere's my code:\n\n```\nfrom fastapi import FastAPI, File, UploadFile, status\nfrom fastapi.openapi.models import Response\n \napp = FastAPI()\n \n@app.post('/upload_file/', status_code=status.HTTP_200_OK)\nasync def upload_file(response: Response, file: UploadFile = File(...)):\n \"\"\"End point for uploading a file\"\"\"\n if file.content_type != \"application/pdf\":\n response.status_code = status.HTTP_415_UNSUPPORTED_MEDIA_TYPE\n return {f'File {file.filename} has unsupported extension type'}\n\n return {'filename': file.content_type}\n```\n\nThank you in advance!\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI, File, UploadFile, status\nfrom fastapi.openapi.models import Response\n \napp = FastAPI()\n \n@app.post('/upload_file/', status_code=status.HTTP_200_OK)\nasync def upload_file(response: Response, file: UploadFile = File(...)):\n \"\"\"End point for uploading a file\"\"\"\n if file.content_type != \"application/pdf\":\n response.status_code = status.HTTP_415_UNSUPPORTED_MEDIA_TYPE\n return {f'File {file.filename} has unsupported extension type'}\n\n return {'filename': file.content_type}\n```\n\n```text\n422 Unprocessable Entity\n```\n\n```py\nfrom fastapi import status, HTTPException\n\n...\n\nif file.content_type != \"application/pdf\":\n raise HTTPException(\n status_code=status.HTTP_415_UNSUPPORTED_MEDIA_TYPE,\n detail=f'File {file.filename} has unsupported extension type',\n )\n```\n\n========================================\n\nComments:\n- How can I serialize the status code when using HTTPException?. It only shows the detail\n- In the example above, the `status_code` argument to `HTTPException` is there to do that. The response will contain an HTTP header that specifies the status code associated with the response.","metadata":{"transformedAt":"2026-08-18T18:32:29.099Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":3,"totalLines":68,"estimatedTokens":561}}105{"id":"stack-64118680","source":"stackoverflow","questionId":64118680,"title":"reload flag with uvicorn: can we exclude certain code?","tags":["python","fastapi","uvicorn"],"text":"Title: reload flag with uvicorn: can we exclude certain code?\nTags: python, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nIs it somehow possible to exclude certain part of the code when reloading the scrip with `--reload` flag?\n\n```\nuvicorn main:app --reload\n```\n\nUse case: I have a model which takes a lot of time loading so I was wondering if there is a way to ignore that line of code when reloading. Or is it just impossible?\n\n========================================\n\nTop Answer:\nThe watchfiles library used for the uvicorn tries to check the excluded folders to see if it is a dir or not...in this case it will fail...\nhttps://github.com/encode/uvicorn/blob/master/uvicorn/supervisors/watchfilesreload.py#L27\n\nIn this meanwhile, using the variable `WATCHFILES_IGNORE_PERMISSION_DENIED=0` at least the error below stops:\n\n```\nFile \".../site-packages/watchfiles/main.py\", line 118, in watch\n with RustNotify(\n ^^^^^^^^^^^\nPermissionError: Permission denied (os error 13) about [\"../myproject/postgres_data\"]\n```\n\n========================================\n\nCode:\n```text\nuvicorn main:app --reload\n```\n\n```text\n--reload\n```\n\n```text\n--reload-include TEXT Set glob patterns to include while watching\n for files. Includes '*.py' by default, which\n can be overridden in reload-excludes.\n --reload-exclude TEXT Set glob patterns to exclude while watching\n for files. Includes '.*, .py[cod], .sw.*,\n ~*' by default, which can be overridden in\n reload-excludes.\n```\n\n```text\n--reload-dir TEXT Set reload directories explicitly, instead\n of using the current working directory.\n```\n\n```text\n--reload-dir\n```\n\n```text\n--reload-dir\n```\n\n```text\nFile \".../site-packages/watchfiles/main.py\", line 118, in watch\n with RustNotify(\n ^^^^^^^^^^^\nPermissionError: Permission denied (os error 13) about [\"../myproject/postgres_data\"]\n```\n\n```text\nWATCHFILES_IGNORE_PERMISSION_DENIED=0\n```\n\n========================================\n\nComments:\n- we just pushed github.com/encode/uvicorn/pull/820 which makes it possible\n- Could you advise on how to exclude asterik-symbol.json using this method while preserving the reload functionality? I tried: uvicorn main:app --reload-exclude 'asterik-symbol.json' however it generated this warning: WARNING: Current configuration will not reload as not all conditions are met, please refer to documentation. (Note: I typed asterik-symbol in place of asterik which wasn't displaying in the comment)\n- @STEMFabLab, for what it's worth, I have a similar issue. I hope to track/resolve it via github.com/benoitc/gunicorn/issues/2722.\n- @euri10, what does, \"No there is no way to exclude something,\" mean? What is the `--reload-exclude` option for?\n- The current working directory actually overides this value: github.com/encode/uvicorn/blob/…\n- This worked so well when I got permission denied in a compose directory and that prevented watchfiles and reload to work altogether. Had this annoying issue for a year. Many thanks for your answer, Roger!","metadata":{"transformedAt":"2026-08-18T18:32:29.099Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":8,"totalLines":82,"estimatedTokens":806}}106{"id":"stack-71171535","source":"stackoverflow","questionId":71171535,"title":"FastAPI - Unable to render Swagger in production","tags":["swagger","openapi","fastapi"],"text":"Title: FastAPI - Unable to render Swagger in production\nTags: swagger, openapi, fastapi\nSource: Stack Overflow\n\nQuestion:\nThis is my FastAPI `main.py` file.\n\n```\nfrom fastapi import FastAPI\nfrom project.config.settings import base as settings\n\napp = FastAPI(docs_url=f\"{settings.URL_ROOT}/{settings.DOCS_URL}\", redoc_url=None)\napp.openapi_version = \"3.0.0\"\n\n# some functions here\n```\n\nAnd I deployed this project to a server. But when I go to address of docs in my server, `1.2.3.4/url_root/docs_url`, it shows me following message:\n\n```\nUnable to render this definition\nThe provided definition does not specify a valid version field.\n\nPlease indicate a valid Swagger or OpenAPI version field.\nSupported version fields are swagger: \"2.0\" and those that match openapi: 3.0.n (for example, openapi: 3.0.0).\n```\n\nWhat's the problem and how can I solve it?\n\n**UPDATE:**\n\nFastAPI is behind Nginx. All of my endpoints are working correctly, but I cannot see docs.\n\n========================================\n\nTop Answer:\nI faced the same problem having a similar architecture: nginx proxying fastapi running on port `8000` through the `/api` path. I was able to solve the problem using the `root_path` parameter as stated in the documentation.\n\nMy final nginx site configuration looks something like:\n\n```\nlocation /api {\n# ...\n rewrite /api/(.*) /$1 break;\n proxy_buffering off;\n proxy_pass http://127.0.0.1:8000;\n# ...\n }\n```\n\nAnd my `main.py` file looks something like this when creating the FastAPI instance:\n\n```\napp = FastAPI(\n root_url=\"/api\"\n # some other params\n)\n```\n\nAfter this change, when I check the url on the local environment I get this screen:\n\nhttps://i.sstatic.net/KvA6s.png\n\nBut... when I check it on my web site I get the docs:\n\nhttps://i.sstatic.net/nsrmw.png\n\nI hope this helps!\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nfrom project.config.settings import base as settings\n\napp = FastAPI(docs_url=f\"{settings.URL_ROOT}/{settings.DOCS_URL}\", redoc_url=None)\napp.openapi_version = \"3.0.0\"\n\n# some functions here\n```\n\n```text\nUnable to render this definition\nThe provided definition does not specify a valid version field.\n\nPlease indicate a valid Swagger or OpenAPI version field.\nSupported version fields are swagger: \"2.0\" and those that match openapi: 3.0.n (for example, openapi: 3.0.0).\n```\n\n```text\nmain.py\n```\n\n```text\n1.2.3.4/url_root/docs_url\n```\n\n```text\napp = FastAPI(\n docs_url=f\"/url_root/docs_url\",\n openapi_url=\"/url_root/openapi.json\",\n redoc_url=None)\n```\n\n```text\nlocation /api {\n# ...\n rewrite /api/(.*) /$1 break;\n proxy_buffering off;\n proxy_pass http://127.0.0.1:8000;\n# ...\n }\n```\n\n```text\napp = FastAPI(\n root_url=\"/api\"\n # some other params\n)\n```\n\n```text\n8000\n```\n\n```text\n/api\n```\n\n```text\nroot_path\n```\n\n```text\nmain.py\n```\n\n========================================\n\nComments:\n- Please all the dependencies used for the project. FastAPI has inbuild support for Swagger. Also the full code or link where the code is available\n- could you find a solution for this?\n- @CFD No, I ignored this problem.","metadata":{"transformedAt":"2026-08-18T18:32:29.099Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":11,"totalLines":144,"estimatedTokens":795}}107{"id":"stack-69138537","source":"stackoverflow","questionId":69138537,"title":"uvicorn [fastapi] python run both HTTP and HTTPS","tags":["python-3.x","ssl","fastapi","uvicorn","http-redirect"],"text":"Title: uvicorn [fastapi] python run both HTTP and HTTPS\nTags: python-3.x, ssl, fastapi, uvicorn, http-redirect\nSource: Stack Overflow\n\nQuestion:\nI'm trying to run a fastapi app with SSL.\n\nI am running the app with uvicorn.\n\nI can run the server on port 80 with HTTP,\n\n```\nif __name__ == '__main__':\n uvicorn.run(\"main:app\", port=80, host='0.0.0.0', reload = True, reload_dirs = [\"html_files\"])\n```\n\nTo run the port with HTTPS, I do the following,\n\n```\nif __name__ == '__main__':\n uvicorn.run(\"main:app\", port=443, host='0.0.0.0', reload = True, reload_dirs = [\"html_files\"], ssl_keyfile=\"/etc/letsencrypt/live/my_domain/privkey.pem\", ssl_certfile=\"/etc/letsencrypt/live/my_domain/fullchain.pem\")\n```\n\nHow can I run both or simply integrate https redirect?\n\nN.B: This is a setup on a server where I don't want to use nginx, I know how to use nginx to implement https redirect.\n\n========================================\n\nTop Answer:\nRun a subprocess to return a redirect response from one port to another.\n\nmain.py:\n\n```\nif __name__ == '__main__':\n Popen(['python', '-m', 'https_redirect']) # Add this\n uvicorn.run(\n 'main:app', port=443, host='0.0.0.0',\n reload=True, reload_dirs=['html_files'],\n ssl_keyfile='/path/to/certificate-key.pem',\n ssl_certfile='/path/to/certificate.pem')\n```\n\nhttps_redirect.py:\n\n```\nimport uvicorn\nfrom fastapi import FastAPI\nfrom starlette.requests import Request\nfrom starlette.responses import RedirectResponse\n\napp = FastAPI()\n\n@app.route('/{_:path}')\nasync def https_redirect(request: Request):\n return RedirectResponse(request.url.replace(scheme='https'))\n\nif __name__ == '__main__':\n uvicorn.run('https_redirect:app', port=80, host='0.0.0.0')\n```\n\n========================================\n\nCode:\n```text\nif __name__ == '__main__':\n uvicorn.run(\"main:app\", port=80, host='0.0.0.0', reload = True, reload_dirs = [\"html_files\"])\n```\n\n```text\nif __name__ == '__main__':\n uvicorn.run(\"main:app\", port=443, host='0.0.0.0', reload = True, reload_dirs = [\"html_files\"], ssl_keyfile=\"/etc/letsencrypt/live/my_domain/privkey.pem\", ssl_certfile=\"/etc/letsencrypt/live/my_domain/fullchain.pem\")\n```\n\n```py\napp = FastAPI(docs_url=None, redoc_url=None, openapi_url=None)\n```\n\n```py\nif __name__ == \"__main__\":\n import subprocess\n subprocess.Popen(['python', '-m', 'https_redirect']) \n uvicorn.run(\n \"main:app\",\n ...\n )\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.middleware.httpsredirect import HTTPSRedirectMiddleware\nimport uvicorn\n\napp = FastAPI()\napp.add_middleware(HTTPSRedirectMiddleware)\n\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", port=80)\n```\n\n```py\nfrom fastapi import FastAPI\nimport uvicorn\n\napp = FastAPI()\n\n\n@app.get(\"/\")\nasync def main():\n return {\"message\": \"Hello World\"}\n\n\nif __name__ == \"__main__\":\n uvicorn.run(\n \"main:app\",\n host=\"0.0.0.0\",\n port=443,\n ssl_keyfile=\"./key.pem\",\n ssl_certfile=\"./cert.pem\",\n )\n```\n\n```py\nfrom fastapi import FastAPI\nfrom starlette.datastructures import URL\nfrom starlette.responses import RedirectResponse\nfrom starlette.types import ASGIApp, Receive, Scope, Send\nimport uvicorn\n\n\nclass HTTPSRedirectMiddleware:\n def __init__(self, app: ASGIApp) -> None:\n self.app = app\n\n async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:\n if scope[\"type\"] in (\"http\", \"websocket\") and scope[\"scheme\"] in (\"http\", \"ws\"):\n url = URL(scope=scope)\n redirect_scheme = {\"http\": \"https\", \"ws\": \"wss\"}[url.scheme]\n url = url.replace(scheme=redirect_scheme, port=8443)\n response = RedirectResponse(url, status_code=307)\n await response(scope, receive, send)\n else:\n await self.app(scope, receive, send)\n\n\napp = FastAPI()\napp.add_middleware(HTTPSRedirectMiddleware)\n \n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", port=8000) # HTTP port set to 8000\n```\n\n```py\n# same code implementation here as in \"Working Example 1\"\n# ...\n\n\nif __name__ == \"__main__\":\n uvicorn.run(\n \"main:app\",\n host=\"0.0.0.0\",\n port=8443, # HTTPS port set to 8443\n ssl_keyfile=\"./key.pem\",\n ssl_certfile=\"./cert.pem\",\n )\n```\n\n```text\nserver {\n listen 80 default_server;\n server_name _;\n return 301 https://$host$request_uri;\n}\n```\n\n```text\nserver {\n listen 80;\n server_name yourdomain.com;\n return 301 https://$host$request_uri;\n}\n\nserver {\n listen 443 ssl;\n server_name yourdomain.com;\n ssl_certificate /path/to/your/cert.pem;\n ssl_certificate_key /path/to/your/key.pem;\n \n location / {\n proxy_pass http://localhost:8000; # if you have the app running on port 8000\n }\n}\n```\n\n```text\nHTTPSRedirectMiddleware\n```\n\n```text\nhttps\n```\n\n```text\nwss\n```\n\n```text\nhttp\n```\n\n```text\nws\n```\n\n```text\nhttp://127.0.0.1\n```\n\n```text\nhttps://127.0.0.1\n```\n\n```text\nsubprocess\n```\n\n```text\nHTTPSRedirectMiddleware\n```\n\n```text\n80\n```\n\n```text\n443\n```\n\n```text\n8000\n```\n\n```text\nHTTPSRedirectMiddleware\n```\n\n```text\nHTTPSRedirectMiddleware\n```\n\n```text\nscheme\n```\n\n```text\nhttps\n```\n\n```text\nport\n```\n\n```text\nRedirectResponse\n```\n\n```text\nport\n```\n\n```text\n80\n```\n\n```text\n443\n```\n\n```text\n8000\n```\n\n```text\n8443\n```\n\n```text\nserver_name\n```\n\n```text\n_\n```\n\n```text\nhostname\n```\n\n```text\n301\n```\n\n```text\n443\n```\n\n```py\nif __name__ == '__main__':\n Popen(['python', '-m', 'https_redirect']) # Add this\n uvicorn.run(\n 'main:app', port=443, host='0.0.0.0',\n reload=True, reload_dirs=['html_files'],\n ssl_keyfile='/path/to/certificate-key.pem',\n ssl_certfile='/path/to/certificate.pem')\n```\n\n```py\nimport uvicorn\nfrom fastapi import FastAPI\nfrom starlette.requests import Request\nfrom starlette.responses import RedirectResponse\n\napp = FastAPI()\n\n\n@app.route('/{_:path}')\nasync def https_redirect(request: Request):\n return RedirectResponse(request.url.replace(scheme='https'))\n\nif __name__ == '__main__':\n uvicorn.run('https_redirect:app', port=80, host='0.0.0.0')\n```\n\n```text\nsudo iptables -t nat -L\nsudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 443 # 80 -> 443\n```\n\n========================================\n\nComments:\n- My ssl certificate is not in local machine, it's on heroku. But tried this to add and test in my local machine, which creates an error. Any suggestion would be appreciated.\n- Even with `HTTPSRedirectMiddleware` installed, I'm getting `The connection was reset` in Firefox and `curl: (52) Empty reply from server` with curl for HTTP requests. This is same behaviour as without the middleware. It makes sense to me, because Uvicorn says it is only listening for HTTPS on the port. How's it supposed to work?\n- Not working for me :/\n- @ArnoV I am afraid that *\"Not working...\"* is very abstract and vague, without stating what the case is, as well as any debugging details. I would also suggest you have a look at related answers **here** and **here**, which might help with the issue you are facing.\n- What I mean by \"not working\" is that when my user types \"example.com\" in the search bar they get a negative answer and they have to explicitly type \"HTTPS://example.com\"\n- While technically you can do port-level redirects, you will break HTTP applications. HTTP and HTTPS use different schemes and protocols. This answer should be deleted as bad advice for the question asked.","metadata":{"transformedAt":"2026-08-18T18:32:29.099Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":41,"totalLines":350,"estimatedTokens":1852}}108{"id":"stack-62986778","source":"stackoverflow","questionId":62986778,"title":"FastAPI handling and redirecting 404","tags":["python","http-status-code-404","fastapi"],"text":"Title: FastAPI handling and redirecting 404\nTags: python, http-status-code-404, fastapi\nSource: Stack Overflow\n\nQuestion:\nHow can i redirect a request with FastAPI if there is a HTTPException?\n\nIn Flask we can achieve that like this:\n\n```\n@app.errorhandler(404)\ndef handle_404(e):\n if request.path.startswith('/api'):\n return render_template('my_api_404.html'), 404\n else:\n return redirect(url_for('index'))\n```\n\nOr in Django we can use django.shortcuts:\n\n```\nfrom django.shortcuts import redirect\n\ndef view_404(request, exception=None):\n return redirect('/')\n```\n\nHow we can achieve that with FastAPI?\n\n========================================\n\nTop Answer:\nWe can achieve that by using FastAPI's **exception_handler**:\n\nIf you are in a hurry, you can use this:\n\n```\nfrom fastapi.responses import RedirectResponse\nfrom starlette.exceptions import HTTPException as StarletteHTTPException\n\n@app.exception_handler(StarletteHTTPException)\nasync def custom_http_exception_handler(request, exc):\n return RedirectResponse(\"/\")\n```\n\nBut more spesific approach, you can create your own Exception Handler(s):\n\n```\nclass UberSuperHandler(StarletteHTTPException):\n pass\n \ndef function_for_uber_super_handler(request, exc):\n return RedirectResponse(\"/\")\n\napp.add_exception_handler(UberSuperHandler, function_for_uber_super_handler)\n```\n\n========================================\n\nCode:\n```text\n@app.errorhandler(404)\ndef handle_404(e):\n if request.path.startswith('/api'):\n return render_template('my_api_404.html'), 404\n else:\n return redirect(url_for('index'))\n```\n\n```text\nfrom django.shortcuts import redirect\n\ndef view_404(request, exception=None):\n return redirect('/')\n```\n\n```text\nfrom fastapi.responses import RedirectResponse\n\n\n@app.exception_handler(404)\nasync def custom_404_handler(_, __):\n return RedirectResponse(\"/\")\n```\n\n```text\nfrom fastapi.templating import Jinja2Templates\nfrom fastapi.staticfiles import StaticFiles\n\ntemplates = Jinja2Templates(directory=\"templates\")\napp.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")\n\n@app.exception_handler(404)\nasync def custom_404_handler(request, __):\n return templates.TemplateResponse(\"404.html\", {\"request\": request})\n```\n\n```text\n@app.exception_handler(404)\nasync def custom_404_handler(_, __):\n return FileResponse('./path/to/404.html')\n```\n\n```text\nfrom fastapi.responses import HTMLResponse\n\nresponse_404 = \"\"\"\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <title>Not Found</title>\n</head>\n<body>\n <p>The file you requested was not found.</p>\n</body>\n</html>\n\"\"\"\n \n@app.exception_handler(404)\nasync def custom_404_handler(_, __):\n return HTMLResponse(response_404)\n```\n\n```text\nexception_handler\n```\n\n```text\nrequest\n```\n\n```text\nexception\n```\n\n```text\n_\n```\n\n```text\n__\n```\n\n```text\nfrom fastapi.responses import RedirectResponse\nfrom starlette.exceptions import HTTPException as StarletteHTTPException\n\n@app.exception_handler(StarletteHTTPException)\nasync def custom_http_exception_handler(request, exc):\n return RedirectResponse(\"/\")\n```\n\n```text\nclass UberSuperHandler(StarletteHTTPException):\n pass\n \ndef function_for_uber_super_handler(request, exc):\n return RedirectResponse(\"/\")\n\n\napp.add_exception_handler(UberSuperHandler, function_for_uber_super_handler)\n```\n\n```py\nfrom fastapi.responses import RedirectResponse\nfrom starlette.exceptions import HTTPException as StarletteHTTPException\n\napp.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")\n\ntemplates = Jinja2Templates(directory=\"templates\")\n\n@app.exception_handler(StarletteHTTPException)\nasync def custom_http_exception_handler(request, exc):\n return templates.TemplateResponse(\"404.html\", {\"request\": request})\n```\n\n```py\ntemplates = Jinja2Templates(directory=\"./public\")\n\nasync def not_found(request, exc):\n return templates.TemplateResponse(request, \"404.html\", status_code=exc.status_code)\n\nexceptions = {\n 404: not_found,\n}\n\napp = FastAPI(exception_handlers=exceptions)\n```\n\n```text\n404.html\n```\n\n```text\n./public\n```\n\n========================================\n\nComments:\n- Future readers might find this answer helpful as well.\n- The approach above has already been described in this answer in more detail.","metadata":{"transformedAt":"2026-08-18T18:32:29.099Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":17,"totalLines":202,"estimatedTokens":1056}}109{"id":"stack-65969601","source":"stackoverflow","questionId":65969601,"title":"How to define lists in python dot env file?","tags":["python","fastapi","pydantic","python-dotenv"],"text":"Title: How to define lists in python dot env file?\nTags: python, fastapi, pydantic, python-dotenv\nSource: Stack Overflow\n\nQuestion:\nIn Fast API documentation it is recommended to use .env to load the config. Only that it only supports string as far as I understand it.\n\n```\nfrom fastapi import FastAPI\nfrom pydantic import BaseSettings\n\nclass Settings(BaseSettings):\n api_tokens = []\n\n class Config:\n env_file = \".env\"\n\nsettings = Settings()\napp = FastAPI()\n```\n\nI usually change the API tokens every few months, by adding a new one to the list and after some time I remove the older ones. That gives the users enough time to upgrade to latest edition without any disruption. In the meanwhile both API tokens will be valid for some time.\n\nBut I can't define a list in the `.env` file.\n\n```\nAPI_TOKENS = abc123,abc321\n```\n\nAm I missing something?\n\nUPDATE:\n\nIt actually is possible.\nThe answer below is correct, however I still had to change the type like this:\n\n```\nclass Settings(BaseSettings):\n api_tokens: list\n```\n\n========================================\n\nTop Answer:\nYou can use json module to convert string variable to a list in python.\n\n.env file\n\n```\nLIST_VAR='[\"Foo\", \"bar\"]'\n```\n\nPython code\n\n```\nimport os\nimport json\nfrom dotenv import load_dotenv\nload_dotenv()\nlist_var = json.loads(os.environ['LIST_VAR'])\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nfrom pydantic import BaseSettings\n\n\nclass Settings(BaseSettings):\n api_tokens = []\n\n class Config:\n env_file = \".env\"\n\n\nsettings = Settings()\napp = FastAPI()\n```\n\n```text\nAPI_TOKENS = abc123,abc321\n```\n\n```text\nclass Settings(BaseSettings):\n api_tokens: list\n```\n\n```text\n.env\n```\n\n```text\nAPI_TOKENS = [\"abc123\",\"abc321\"]\n```\n\n```text\nLIST_VAR='[\"Foo\", \"bar\"]'\n```\n\n```text\nimport os\nimport json\nfrom dotenv import load_dotenv\nload_dotenv()\nlist_var = json.loads(os.environ['LIST_VAR'])\n```\n\n========================================\n\nComments:\n- Thanks, what do you put as type for `api_tokens = []` because this is still failing for me.\n- I didn't change any code at all. Changing `.env` file work for me, and it should. Because this is some kind of weird (oh!!) syntax of *dotenv* package\n- I added an update to the question how I solved it. Because if I leave the type as `str` I get this instead: `\"api_tokens\":\"[\\\"abc123\\\",\\\"abc321\\\"]\"`.\n- Just for those who are using nested Config this won't work, since there is a bug in pydantic github.com/pydantic/pydantic/issues/3971","metadata":{"transformedAt":"2026-08-18T18:32:29.100Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":7,"totalLines":117,"estimatedTokens":627}}110{"id":"stack-65059811","source":"stackoverflow","questionId":65059811,"title":"What does Depends with no parameter do?","tags":["python-3.x","fastapi"],"text":"Title: What does Depends with no parameter do?\nTags: python-3.x, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to implement JWT with fastapi.\nCurrently looking at the following libraries\nfastapi-users\nFastAPI JWT Auth\n\nIn both cases, I see Depends() in method parameter.\nWhat does Depends do when there is nothing in the parameter?\n\nhttps://github.com/frankie567/fastapi-users/blob/master/fastapi_users/router/auth.py\n\n```\n@router.post(\"/login\")\n async def login(\n response: Response, credentials: OAuth2PasswordRequestForm = Depends()\n ):\n```\n\nhttps://indominusbyte.github.io/fastapi-jwt-auth/usage/basic/\n\n```\n@app.post('/login')\ndef login(user: User, Authorize: AuthJWT = Depends()):\n```\n\nI undestand when there's a function inside the parameter but would you teach me what it does when there's no parameter with Depends?\n\n========================================\n\nTop Answer:\nIn both cases, I see Depends() in method parameter. What does Depends do when there is nothing in the parameter?\n\nIt's a great question.\n\nAssume you have the following code.\n\n```\nfrom fastapi import FastAPI, Depends\nfrom pydantic import BaseModel\nfrom typing import Optional\n\nclass Location(BaseModel):\n city: str\n country: str\n state: str\n\napp = FastAPI()\n\n@app.post(\"/withoutdepends\")\nasync def with_depends(location: Location):\n return location\n\n@app.post(\"/withdepends\")\nasync def with_depends(location: Location = Depends()):\n return lcoation\n```\n\nWe have the same `Location` model in two different endpoints, one uses `Depends` other one not.\n\n### What is the difference?\n\nSince FastAPI is based on OpenAPI specification, we can start discovering the difference from auto-generated Swagger's docs.\n\n### This is **without Depends**, it expects a Request Body.\n\n### This is **with Depends**, it expects them as Query parameters.\n\n### How this is useful and how it works?\n\nActually, this is it, it expects a `Callable` there.\n\nBut when you use a **Pydantic Model** with `Depends`, it actually creates a query parameter for parameter inside init `__init__` function.\n\nSo for example, this is the model we used above.\n\n```\nclass Location(BaseModel):\n city: str\n country: str\n state: str\n```\n\nIt becomes this with `Depends`.\n\n```\nclass Location(BaseModel):\n def __init__(self, city: str, country: str, state: str) -> None:\n ...\n```\n\nThen they will become query parameters. This is the OpenAPI schema for the `/withdepends` endpoint.\n\n```\n\"parameters\": [\n {\n \"required\":true,\n \"schema\":{\n \"title\":\"City\",\n \"type\":\"string\"\n },\n \"name\":\"city\",\n \"in\":\"query\"\n },\n {\n \"required\":true,\n \"schema\":{\n \"title\":\"Country\",\n \"type\":\"string\"\n },\n \"name\":\"country\",\n \"in\":\"query\"\n },\n {\n \"required\":true,\n \"schema\":{\n \"title\":\"State\",\n \"type\":\"string\"\n },\n \"name\":\"state\",\n \"in\":\"query\"\n }\n]\n```\n\nThis is the OpenAPI schema it created for `/withoutdepends` endpoint.\n\n```\n\"requestBody\": {\n \"content\":{\n \"application/json\":{\n \"schema\":{\n \"$ref\":\"#/components/schemas/Location\"\n }\n }\n },\n \"required\":true\n}\n```\n\n### Conclusion\n\nInstead of **request body**, you can create **query parameters** with the same model.\n\nPydantic models are very useful for the cases when you have +5 parameters. But it expects a **request body** by default. But OpenAPI specification doesn't allow request body in **GET** operations. As it says in the specification.\n\nGET, DELETE and HEAD are no longer allowed to have request body because it does not have defined semantics as per RFC 7231.\n\nSo by using `Depends` you are able to create query parameters for your **GET** endpoint, with the same model.\n\n========================================\n\nCode:\n```text\n@router.post(\"/login\")\n async def login(\n response: Response, credentials: OAuth2PasswordRequestForm = Depends()\n ):\n```\n\n```text\n@app.post('/login')\ndef login(user: User, Authorize: AuthJWT = Depends()):\n```\n\n```text\ncommons: CommonQueryParams = Depends(CommonQueryParams)\n```\n\n```text\ncommons: CommonQueryParams = Depends(CommonQueryParams)\n```\n\n```text\ncommons: CommonQueryParams = Depends()\n```\n\n```text\nDepends()\n```\n\n```text\nCommonQueryParams\n```\n\n```text\ndependency\n```\n\n```text\nDepends()\n```\n\n```text\nDepends()\n```\n\n```text\nDepends(CommonQueryParams)\n```\n\n```py\nfrom fastapi import FastAPI, Depends\nfrom pydantic import BaseModel\nfrom typing import Optional\n\n\nclass Location(BaseModel):\n city: str\n country: str\n state: str\n\n\napp = FastAPI()\n\n\n@app.post(\"/withoutdepends\")\nasync def with_depends(location: Location):\n return location\n\n\n@app.post(\"/withdepends\")\nasync def with_depends(location: Location = Depends()):\n return lcoation\n```\n\n```py\nclass Location(BaseModel):\n city: str\n country: str\n state: str\n```\n\n```py\nclass Location(BaseModel):\n def __init__(self, city: str, country: str, state: str) -> None:\n ...\n```\n\n```json\n\"parameters\": [\n {\n \"required\":true,\n \"schema\":{\n \"title\":\"City\",\n \"type\":\"string\"\n },\n \"name\":\"city\",\n \"in\":\"query\"\n },\n {\n \"required\":true,\n \"schema\":{\n \"title\":\"Country\",\n \"type\":\"string\"\n },\n \"name\":\"country\",\n \"in\":\"query\"\n },\n {\n \"required\":true,\n \"schema\":{\n \"title\":\"State\",\n \"type\":\"string\"\n },\n \"name\":\"state\",\n \"in\":\"query\"\n }\n]\n```\n\n```json\n\"requestBody\": {\n \"content\":{\n \"application/json\":{\n \"schema\":{\n \"$ref\":\"#/components/schemas/Location\"\n }\n }\n },\n \"required\":true\n}\n```\n\n```text\nLocation\n```\n\n```text\nDepends\n```\n\n```text\nCallable\n```\n\n```text\nDepends\n```\n\n```text\n__init__\n```\n\n```text\nDepends\n```\n\n```text\n/withdepends\n```\n\n```text\n/withoutdepends\n```\n\n```text\nDepends\n```\n\n========================================\n\nComments:\n- Where do you get Depends from? What do its docs say about the arguments it expects?\n- I'm reading this too @jonrsharpe because the docs are laid out as a couple of different levels of tutorial - there's no reference / index and topics are laid out and scattered all over the place. I can't find an example of `Depends()` in the tutorial. Have you read the docs and located where it discusses `Depends` with no parameters? Can you give us a link? - NVM! I've just read the accepted answer and now remember where the info on parameter-less `Depends` is hidden. Because it's a shortcut and actually performs as if there was a parameter it didn't come to mind.\n- OP doesn't want to know what `Depends` does in general, he wants to know specifically what `Depends()` does when it is given no parameters.\n- I think that this is the correct answer to the question asked\n- This is *so* useful when you are using a dependency and modifying the body type on the fly in the path operation function in order to support all fields optional for a PATCH operation! stackoverflow.com/questions/67699451/… Phew! It's so cool how FastAPI / Pydantic supports this in such a compact way. Also, you can do it just by *using* Pydantic. With Django almost every customisation requires you to dig under the sometimes undocumented cover and subclass and jiggery poke. So thankful for FastAPI. Not looking back at Django","metadata":{"transformedAt":"2026-08-18T18:32:29.100Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":25,"totalLines":331,"estimatedTokens":1800}}111{"id":"stack-66867814","source":"stackoverflow","questionId":66867814,"title":"FastAPI how to allow endpoint access for specific IP only?","tags":["fastapi"],"text":"Title: FastAPI how to allow endpoint access for specific IP only?\nTags: fastapi\nSource: Stack Overflow\n\nQuestion:\nHow to limit endpoint access only to specific IPs with FastAPI?\n\n========================================\n\nTop Answer:\nThe accepted answer makes use of the TrustedHostMiddleware but that can be easily spoofed using a reverse proxy, i.e. using NGINX or using any other technique. In my opinion, validating IP address in a custom middleware is more secure:\n\n```\nfrom fastapi import FastAPI, Request, status\nfrom fastapi.responses import JSONResponse\n\napp = FastAPI()\n\n# Whitelisted IPs\nWHITELISTED_IPS = []\n\n@app.middleware('http')\nasync def validate_ip(request: Request, call_next):\n # Get client IP\n ip = str(request.client.host)\n \n # Check if IP is allowed\n if ip not in WHITELISTED_IPS:\n data = {\n 'message': f'IP {ip} is not allowed to access this resource.'\n }\n return JSONResponse(status_code=status.HTTP_400_BAD_REQUEST, content=data)\n\n # Proceed if IP is allowed\n return await call_next(request)\n```\n\nI'd maintain a list of whitelisted IPs and then I'd compare the client IP to the list and will return a `400 Bad Request` error if the IP is not in the whitelisted IPs list.\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nfrom fastapi.middleware.trustedhost import TrustedHostMiddleware\n\napp = FastAPI()\n\napp.add_middleware(\n TrustedHostMiddleware, allowed_hosts=[\"example.com\",\"*.example.com\"] \n)\n\n\n@app.get(\"/\")\nasync def main():\n return {\"message\": \"Hello World\"}\n```\n\n```text\nallowed_hosts\n```\n\n```text\n*.example.com\n```\n\n```text\nallowed_hosts=[\"*\"]\n```\n\n```py\nfrom fastapi import FastAPI, Request, status\nfrom fastapi.responses import JSONResponse\n\n\napp = FastAPI()\n\n# Whitelisted IPs\nWHITELISTED_IPS = []\n\n@app.middleware('http')\nasync def validate_ip(request: Request, call_next):\n # Get client IP\n ip = str(request.client.host)\n \n # Check if IP is allowed\n if ip not in WHITELISTED_IPS:\n data = {\n 'message': f'IP {ip} is not allowed to access this resource.'\n }\n return JSONResponse(status_code=status.HTTP_400_BAD_REQUEST, content=data)\n\n # Proceed if IP is allowed\n return await call_next(request)\n```\n\n```text\n400 Bad Request\n```\n\n```text\nsudo ufw allow from IP proto tcp to any port PORT\n```\n\n========================================\n\nComments:\n- Future readers might find this answer helpful as well.\n- Note that if you're running behind a reverse proxy, `request.client.host` will always be the IP of the reverse proxy. In this case you need to get the client's IP from the `X-Forwarded-For` header. There's uvicorn's `ProxyHeaderMiddleware`, which does exactly that, given a list of trusted ips.\n- I agree. So much so that I created a solution to protect FastAPI apps. Check it out: github.com/rennf93/fastapi-guard\n- Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.","metadata":{"transformedAt":"2026-08-18T18:32:29.100Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":7,"totalLines":111,"estimatedTokens":782}}112{"id":"stack-62267292","source":"stackoverflow","questionId":62267292,"title":"FastAPI/Pydantic accept arbitrary post request body?","tags":["python","python-3.x","fastapi","pydantic","starlette"],"text":"Title: FastAPI/Pydantic accept arbitrary post request body?\nTags: python, python-3.x, fastapi, pydantic, starlette\nSource: Stack Overflow\n\nQuestion:\nI want to create a FastAPI endpoint that just accepts an arbitrary post request body and returns it.\n\nIf I send `{\"foo\" : \"bar\"}` , I want to get `{\"foo\" : \"bar\"}` back. But I also want to be able to send `{\"foo1\" : \"bar1\", \"foo2\" : \"bar2\"}` and get that back.\n\nI tried: \n\n```\nfrom fastapi import FastAPI\napp = FastAPI()\n\napp.post(\"/\")\nasync def handle(request: BaseModel):\n return request\n```\n\nBut that returns an empty dictionary, no matter what I send it.\n\nAny ideas?\n\n========================================\n\nTop Answer:\nYou can use type hint Dict[Any, Any] to tell FastAPI you're expecting any valid JSON:\n\n```\nfrom typing import Any, Dict\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.post(\"/\")\nasync def handle(request: Dict[Any, Any]):\n return request\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\napp = FastAPI()\n\napp.post(\"/\")\nasync def handle(request: BaseModel):\n return request\n```\n\n```text\n{\"foo\" : \"bar\"}\n```\n\n```text\n{\"foo\" : \"bar\"}\n```\n\n```text\n{\"foo1\" : \"bar1\", \"foo2\" : \"bar2\"}\n```\n\n```py\nfrom typing import Any, Dict, List, Union\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.post(\"/\")\nasync def handle(request: Union[List,Dict,Any]=None):\n return request\n```\n\n```py\nasync def handle(request: List | Dict | Any = None):\n```\n\n```text\n{\n```\n\n```text\n}\n```\n\n```text\ntrue\n```\n\n```text\nfalse\n```\n\n```text\n1.2\n```\n\n```text\nnull\n```\n\n```text\n\"text\"\n```\n\n```text\n[1,2,3]\n```\n\n```text\nAny\n```\n\n```text\n=None\n```\n\n```text\nnull\n```\n\n```text\nUnion\n```\n\n```py\nfrom typing import Any, Dict\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.post(\"/\")\nasync def handle(request: Dict[Any, Any]):\n return request\n```\n\n========================================\n\nComments:\n- Related answers can be found here, as well as here and here\n- shouldn't `Any=None` be enough? I mean, why isn't `List/Dict` covered in `Any`?\n- See the paragraph below the code example. That should answer your question.\n- Aah.. I missed that (for some reason)","metadata":{"transformedAt":"2026-08-18T18:32:29.100Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":19,"totalLines":145,"estimatedTokens":538}}113{"id":"stack-63833593","source":"stackoverflow","questionId":63833593,"title":"How to run FastAPI / Uvicorn in Google Colab?","tags":["python","google-colaboratory","fastapi","uvicorn"],"text":"Title: How to run FastAPI / Uvicorn in Google Colab?\nTags: python, google-colaboratory, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI am trying to run a \"local\" web app on Google Colab using FastAPI / Uvicorn like some of the Flask app sample code I've seen but cannot get it to work. Has anyone been able to do this? Appreciate it.\n\n### Installed FastAPI & Uvicorn successfully\n\n```\n!pip install FastAPI -q\n!pip install uvicorn -q\n```\n\n### Sample app\n\n```\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/\")\nasync def root():\n return {\"message\": \"Hello World\"}\n```\n\n### Run attempts\n\n```\n#attempt 1\nif __name__ == \"__main__\":\n uvicorn.run(\"/content/fastapi_002:app\", host=\"127.0.0.1\", port=5000, log_level=\"info\")\n```\n\n### \n\n```\n#attempt 2\n#uvicorn main:app --reload\n!uvicorn \"/content/fastapi_001.ipynb:app\" --reload\n```\n\n========================================\n\nTop Answer:\nA simpler approach without having to use ngrok or nest-asyncio:\n\n```\nfrom fastapi import FastAPI\nfrom uvicorn import Config, Server\n\napp = FastAPI()\n\n@app.get(\"/\")\nasync def root():\n return {\"message\": \"Hello World\"}\n\nconfig = Config(app)\nserver = Server(config=config)\nawait server.serve()\n```\n\nThis won't do any multi-processing or hot-reloading but gets the job done if you just want to quickly run the a simple ASGI app from Jupyter.\n\nThis can be achieved using Hypercorn as well.\n\n**EDIT**: The above works fine in local Jupyter, but since Colab still doesn't support top-level `await` statements (as of July 2022) you'd need to replace the last line of the snippet above with something like:\n\n```\nimport asyncio\nloop = asyncio.get_event_loop()\nloop.create_task(server.serve())\n```\n\n========================================\n\nCode:\n```text\n!pip install FastAPI -q\n!pip install uvicorn -q\n```\n\n```text\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n\n@app.get(\"/\")\nasync def root():\n return {\"message\": \"Hello World\"}\n```\n\n```text\n#attempt 1\nif __name__ == \"__main__\":\n uvicorn.run(\"/content/fastapi_002:app\", host=\"127.0.0.1\", port=5000, log_level=\"info\")\n```\n\n```text\n#attempt 2\n#uvicorn main:app --reload\n!uvicorn \"/content/fastapi_001.ipynb:app\" --reload\n```\n\n```text\n!pip install fastapi nest-asyncio pyngrok uvicorn\n```\n\n```text\nfrom fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware\n\napp = FastAPI()\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=['*'],\n allow_credentials=True,\n allow_methods=['*'],\n allow_headers=['*'],\n)\n\n@app.get('/')\nasync def root():\n return {'hello': 'world'}\n```\n\n```text\nimport nest_asyncio\nfrom pyngrok import ngrok\nimport uvicorn\n\nngrok_tunnel = ngrok.connect(8000)\nprint('Public URL:', ngrok_tunnel.public_url)\nnest_asyncio.apply()\nuvicorn.run(app, port=8000)\n```\n\n```py\nfrom fastapi import FastAPI\nfrom uvicorn import Config, Server\n\napp = FastAPI()\n\n@app.get(\"/\")\nasync def root():\n return {\"message\": \"Hello World\"}\n\nconfig = Config(app)\nserver = Server(config=config)\nawait server.serve()\n```\n\n```py\nimport asyncio\nloop = asyncio.get_event_loop()\nloop.create_task(server.serve())\n```\n\n```text\nawait\n```\n\n```text\nfrom fastapi import FastAPI\n from fastapi.middleware.cors import CORSMiddleware\n\n app = FastAPI()\n\n app.add_middleware(\n CORSMiddleware,\n allow_origins=['*'],\n allow_credentials=True,\n allow_methods=['*'],\n allow_headers=['*'],\n )\n\n @app.get('/')\n async def root():\n return {'hello': 'world'}\n```\n\n```text\n!pip install pyngrok\nimport nest_asyncio\nfrom pyngrok import ngrok\nimport uvicorn\n\n# Get your authtoken from https://dashboard.ngrok.com/get-started/your-authtoken\nauth_token = \"YOUR_AUTH_TOKEN\"\n\n# Set the authtoken\nngrok.set_auth_token(auth_token)\n\n# Connect to ngrok\nngrok_tunnel = ngrok.connect(8000)\n\n# Print the public URL\nprint('Public URL:', ngrok_tunnel.public_url)\n\n# Apply nest_asyncio\nnest_asyncio.apply()\n\n# Run the uvicorn server\nuvicorn.run(app, port=8000)\n```\n\n```py\nimport os, time, re\nfrom urllib.parse import urlparse\n\ndef start(url=\"http://localhost:8000\",max_attempts=5,initial_delay=1,out=\"tunnel.log\") -> Optional[str]:\n try:\n import google.colab\n\n # setup cloudflare tunnel: https://pkg.cloudflare.com/index.html\n installation_script = \"\"\"\n sudo mkdir -p --mode=0755 /usr/share/keyrings\n curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null\n echo 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared focal main' | sudo tee /etc/apt/sources.list.d/cloudflared.list\n sudo apt-get update && sudo apt-get install cloudflared\n \"\"\"\n if os.system(\"cloudflared --version\") != 0: os.system(installation_script)\n os.system(f\"nohup cloudflared tunnel --url {url} > {out} 2>&1 &\")\n time.sleep(5)\n attempt = 0\n delay = initial_delay\n\n while attempt < max_attempts:\n try:\n with open(out) as f:\n for l in f.read().split(\"\\n\"):\n log_entry = l\n url_pattern = r\"https?://[^\\s]*trycloudflare\\.com[^\\s]*\"\n url_match = re.search(url_pattern, log_entry)\n if url_match: return urlparse(url_match.group(0)).hostname\n raise ValueError(\"URL not found\")\n except:\n attempt += 1\n if attempt < max_attempts:\n time.sleep(delay)\n delay *= 2 # Exponential backoff\n else: return None\n except: return None\n```\n\n```text\nstart()\n```\n\n========================================\n\nComments:\n- Does this answer your question? How to run FastAPI application inside Jupyter?\n- Wow, very impressive. Are there any limitations to be aware of when running it like this? Perhaps I should run the server from one notebook and point to a .py file in my gdrive I'm updating as the server main? My use case is ML inference/prediction APIs I've got working locally on my laptop. Any insight would be appreciated! Thanks again.\n- Thanks for this, but what is the url when you run this? The accepted answer has a print statement - can you please one for this method?\n- Uvicorn defaults to serving on 127.0.0.1:8000. See github.com/encode/uvicorn/blob/master/uvicorn/config.py#L212‌​.","metadata":{"transformedAt":"2026-08-18T18:32:29.100Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":14,"totalLines":258,"estimatedTokens":1575}}114{"id":"stack-60844846","source":"stackoverflow","questionId":60844846,"title":"Read a body JSON list with FastAPI","tags":["python","json","fastapi","pydantic"],"text":"Title: Read a body JSON list with FastAPI\nTags: python, json, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nThe body of an HTTP PUT request is a JSON list - like this:\n\n```\n[item1, item2, item3, ...]\n```\n\nI can't change this. (If the root was a JSON object rather than a list there would be no problem.)\n\nUsing FastAPI, I seem to be unable to access this content in the normal way:\n\n```\n@router.put('/data')\ndef set_data(data: DataModel): # This doesn't work; how do I even declare DataModel?\n```\n\nI found the following workaround, which seems like a very ugly hack:\n\n```\nclass DataModel(BaseModel):\n __root__: List[str]\n\nfrom fastAPI import Request\n\n@router.put('/data')\nasync def set_data(request: Request): # Get the request object directly\n data = DataModel(__root__=await request.json())\n```\n\nThis surely can't be the 'approved' way to achieve this. I've scoured the documentation both of FastAPI and Pydantic. What am I missing?\n\n========================================\n\nTop Answer:\nLet's clarify. There are 3 types of arguments, parsed in FastAPI:\n\nURL argument `http:\\\\?=`\n\nURL Path argument `http:\\\\\\\\`\n\npayload argument (for POST/PATCH/PUT/DELETE)\n\nAppropriate function arguments formats in FastAPI:\n\n1.\n\n```\n@router.put('/data')\ndef set_data(key1: int)\n```\n\n- \n\n```\n@router.put('/{key2}/data')\ndef set_data(key2: int)\n```\n\n- \n\n```\nclass Item(BaseModel):\n name: str\n\n@router.put('/data')\ndef set_data(payload_data: Item)\n```\n\nAnd one can combine all of them:\n\n```\nclass Item(BaseModel):\n name: str\n\n@router.put('/{key1}/data')\ndef set_data(\n key1: int, # <-- PATH argument\n key2: str, # <-- URL argument (for key=value after '?')\n payload_data: Item # <-- payload {'name': 'Vasya'}\n):\n ...\n```\n\n========================================\n\nCode:\n```text\n[item1, item2, item3, ...]\n```\n\n```text\n@router.put('/data')\ndef set_data(data: DataModel): # This doesn't work; how do I even declare DataModel?\n```\n\n```text\nclass DataModel(BaseModel):\n __root__: List[str]\n\n\nfrom fastAPI import Request\n\n@router.put('/data')\nasync def set_data(request: Request): # Get the request object directly\n data = DataModel(__root__=await request.json())\n```\n\n```text\nfrom typing import List\nfrom pydantic import BaseModel\n\nclass Item(BaseModel):\n name: str\n\nclass ItemList(BaseModel):\n items: List[Item]\n\ndef process_item_list(items: ItemList):\n pass\n```\n\n```text\n{\"items\": [{\"name\": \"John\"}, {\"name\": \"Mary\"}]}\n```\n\n```text\nfrom typing import List\nfrom pydantic import BaseModel\n\nclass Item(BaseModel):\n name: str\n\ndef process_item_list(items: List[Item]):\n pass\n```\n\n```text\n[{\"name\": \"John\"}, {\"name\": \"Mary\"}]\n```\n\n```text\nfrom typing import List\n\ndef process_item_list(items: List[str]):\n pass\n```\n\n```text\n[\"John\", \"Mary\"]\n```\n\n```text\nBaseModel\n```\n\n```text\npydantic\n```\n\n```text\n@router.put('/data')\ndef set_data(key1: int)\n```\n\n```text\n@router.put('/{key2}/data')\ndef set_data(key2: int)\n```\n\n```text\nclass Item(BaseModel):\n name: str\n\n@router.put('/data')\ndef set_data(payload_data: Item)\n```\n\n```text\nclass Item(BaseModel):\n name: str\n\n@router.put('/{key1}/data')\ndef set_data(\n key1: int, # <-- PATH argument\n key2: str, # <-- URL argument (for key=value after '?')\n payload_data: Item # <-- payload {'name': 'Vasya'}\n):\n ...\n```\n\n```text\nhttp:\\\\<YOUR_PATH>?<key>=<value>\n```\n\n```text\nhttp:\\\\<PATH>\\<argument>\\<PATH>\n```\n\n========================================\n\nComments:\n- Future readers might find this answer helpful as well.\n- I thought I'd tried the above but obviously made some mistake along the way and ruled it out. Many thanks.\n- Why don't I just post the last option? Yes, that would seem better, but the API spec says that the entire list is rewritten.\n- Nah, that last heading was a question to myself - maybe it's poorly phrased, but I wanted to justify why I went all that way down ;)\n- i was trying too return an array without a name, as below; class ListItem(baseModel) List[Item] somehow it was working on print but cannot output . class ListItem(List[Item]) pass saved my life, thanks man\n- results in incorrect type `{items :{\"items\" :[\"name\" ] } }` which is incorrect. About to try what @bilen mentioned.\n- @AkshayHazari, my solution has three different options, you seem to have only picked/tried the first one. Go with the second option and you'll be fine (also see example outputs provided in my answer).\n- @jbndlr Can you explain how we can use the function while declaring the API , since it just asks for types or classes","metadata":{"transformedAt":"2026-08-18T18:32:29.100Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":17,"totalLines":213,"estimatedTokens":1125}}115{"id":"stack-63483246","source":"stackoverflow","questionId":63483246,"title":"How to call an api from another api in fastapi?","tags":["python","python-3.x","callback","fastapi","starlette"],"text":"Title: How to call an api from another api in fastapi?\nTags: python, python-3.x, callback, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nI was able to get the response of one API from another but unable to store it somewhere(in a file or something before returning the response)\n`response=RedirectResponse(url=\"/apiname/\")` (I want to access a post request with header and body)\n\nI want to store this response content without returning it.\n\nYes, if I return the function I will get the results but when I print it I don't find results.\nAlso, if I give post request then I get error Entity not found.\n\nI read the starlette and fastapi docs but couldn't get the workaround. The callbacks also didn't help.\n\n========================================\n\nTop Answer:\nI have the same problem & I needed to call the third-party API with **async** way\nSo I tried many ways & I came solution with **requests-async** library\nand it works for me.\n\n```\nimport http3\n\nclient = http3.AsyncClient()\n\nasync def call_api(url: str):\n\n r = await client.get(url)\n return r.text\n\n@app.get(\"/\")\nasync def root():\n ...\n result_1 = await call_api('url_1')\n result_2 = await call_api('url_2')\n ...\n```\n\nhttpx also you can use\nthis video he is using httpx\n\n========================================\n\nCode:\n```text\nresponse=RedirectResponse(url=\"/apiname/\")\n```\n\n```text\nimport requests\n\ndef test_function(request: Request, path_parameter: path_param):\n\n request_example = {\"test\" : \"in\"}\n host = request.client.host\n data_source_id = path_parameter.id\n\n get_test_url= f\"http://{host}/test/{id}/\"\n get_inp_url = f\"http://{host}/test/{id}/inp\"\n\n test_get_response = requests.get(get_test_url)\n inp_post_response = requests.post(get_inp_url , json=request_example)\n if inp_post_response .status_code == 200:\n print(json.loads(test_get_response.content.decode('utf-8')))\n```\n\n```text\nimport http3\n\nclient = http3.AsyncClient()\n\nasync def call_api(url: str):\n\n r = await client.get(url)\n return r.text\n\n@app.get(\"/\")\nasync def root():\n ...\n result_1 = await call_api('url_1')\n result_2 = await call_api('url_2')\n ...\n```\n\n========================================\n\nComments:\n- Related answers can be found here, as well as here and here\n- The docs discuss a different method here: fastapi.tiangolo.com/advanced/openapi-callbacks/… I like your answer b/c it keeps the call within the route that requires the call (e.g., for captcha-related verification this can be handy).","metadata":{"transformedAt":"2026-08-18T18:32:29.100Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":3,"totalLines":91,"estimatedTokens":625}}116{"id":"stack-67663970","source":"stackoverflow","questionId":67663970,"title":"Optimal way to initialize heavy services only once in FastAPI","tags":["python","initialization","singleton","global","fastapi"],"text":"Title: Optimal way to initialize heavy services only once in FastAPI\nTags: python, initialization, singleton, global, fastapi\nSource: Stack Overflow\n\nQuestion:\nThe FastAPI application I started working on, uses several services, which I want to initialize only once, when the application starts and then use the methods of this object in different places.\n\nIt can be a cloud service or any other heavy class.\n\nPossible ways is to do it with `Lazy loading` and with `Singlenton pattern`, but I am looking for better approach for FastAPI.\n\nAnother possible way, is to use `Depends` class and to cache it, but its usage makes sense only with route methods, not with other regular methods which are called from route methods.\n\nExample:\n\n```\nasync def common_parameters(q: Optional[str] = None, skip: int = 0, limit: int = 100):\n return {\"q\": q, \"skip\": skip, \"limit\": limit} \n \n\nasync def non_route_function(commons: dict = Depends(common_parameters)):\n print(commons) # returns `Depends(common_parameters)` \n \n\n@router.get('/test')\nasync def test_endpoint(commons: dict = Depends(common_parameters)):\n print(commons) # returns correct dict\n await non_route_function()\n return {'success': True}\n```\n\nThere can be also used `@app.on_event(\"startup\")` event to initialize heavy class there, but have no idea how to make this initialized object accessible from every place, without using `singleton`.\n\nAnother ugly way is also to save initialized objects into @app( and then get this app from requests, but then you have to pass `request` into each non-route function.\n\nAll of the ways I have described are either ugly, uncovenient, non-pythonic or worse practice, we also don't have here thread locals and proxy objects like in flask, so what is the best approach for such kind of problem I have described above?\n\nThanks!\n\n========================================\n\nTop Answer:\nI don't know any way which does not rely on a singleton variable. I think that's acceptable, as FastAPI also uses the `app` as a singleton.\n\nI'm reusing MatsLindh's answer but show how to use lifespan events for tying the expensive service lifetime to our app lifetime. That also enables async preparation and clean up.\nThe service also accesses the event loop within its `__init__.py` to initialize an asyncio lock.\n\nI'll not introduce an app-specific layer and use the `Annotated` helper to reduce boiler-plate.\n\n**foo/heavylifting.py**\n\nThe HeavyLifter is our expensive service, entirely unaware of FastAPI.\nIt requires async preparation and clean up meaning though `__init__()` is inexpensive.\n\n```\nimport asyncio\n\nclass HeavyLifter:\n def __init__(self, initial: int) -> None:\n self._initial = initial\n self._lock = asyncio.Lock()\n\n async def prepare(self) -> None:\n async with self._lock:\n await asyncio.sleep(self._initial)\n\n async def clean_up(self) -> None:\n async with self._lock:\n await asyncio.sleep(self._initial)\n \n def do_stuff(self) -> str:\n return \"we did stuff\"\n```\n\n**foo/app.py**\n\nNext to our `app` singleton, there is also a `heavy` singleton.\nHowever, we use lifespan events to initialize it within the event loop and prepare it asynchronously only during app startup, and similarly run clean up as the app is shutting down.\n\n```\nfrom contextlib import asynccontextmanager\nfrom fastapi import FastAPI, APIRouter\nfrom typing import AsyncGenerator\nfrom .heavylifting import HeavyLifter\n\nheavy: HeavyLifter\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:\n global heavy\n heavy = HeavyLifter(initial=3)\n try:\n await heavy.prepare()\n\n # Serve FastAPI app\n yield\n finally:\n await heavy.clean_up()\n\nfrom .views import api_router\n\napp = FastAPI(lifespan=lifespan)\napp.include_router(api_router)\n```\n\n**foo/dependencies.py**\n\nThis file contains simplified dependency definitions - but it could just as well be part of `app.py`.\n\nWith `Annotated` we define a type alias for reuse across dependent functions.\nThe singleton is loaded via an anonymous lambda function.\n\n```\nfrom fastapi import Depends\nfrom typing import Annotated, TypeAlias\nfrom . import app\nfrom .heavylifting import HeavyLifter\n\nHeavyLifterDep: TypeAlias = Annotated[HeavyLifter, Depends(lambda: app.heavy)]\n```\n\n`heavy` is accessed via the `app` module rather than imported directly, because it will only be defined once the FastAPI app has been started.\n\n**foo/views.py**\n\nFor our path operation function, we use the type alias prepared in dependencies and will get the persistent, heavy service object with full type checker support.\n\n```\nfrom fastapi import APIRouter, Depends\nfrom .dependencies import HeavyLifterDep\n\napi_router = APIRouter()\n\n@api_router.get('/')\nasync def index(heavy_lifter: HeavyLifterDep):\n return {'hello world': heavy_lifter.do_stuff()}\n```\n\nI was really surprised that FastAPI does not have a simpler, native way of having globally persistent dependencies.\nMaybe there is still a better way.\n\n========================================\n\nCode:\n```text\nasync def common_parameters(q: Optional[str] = None, skip: int = 0, limit: int = 100):\n return {\"q\": q, \"skip\": skip, \"limit\": limit} \n \n\nasync def non_route_function(commons: dict = Depends(common_parameters)):\n print(commons) # returns `Depends(common_parameters)` \n \n\n@router.get('/test')\nasync def test_endpoint(commons: dict = Depends(common_parameters)):\n print(commons) # returns correct dict\n await non_route_function()\n return {'success': True}\n```\n\n```text\nLazy loading\n```\n\n```text\nSinglenton pattern\n```\n\n```text\nDepends\n```\n\n```text\n@app.on_event(\"startup\")\n```\n\n```text\nsingleton\n```\n\n```text\nrequest\n```\n\n```py\nimport time\n\nclass HeavyLifter:\n def __init__(self, initial):\n self.initial = initial\n time.sleep(self.initial)\n \n def do_stuff(self):\n return 'we did stuff'\n```\n\n```py\nfrom fastapi import FastAPI, APIRouter\nfrom .heavylifting import HeavyLifter\n\nheavy = HeavyLifter(initial=3)\n\nfrom .views import api_router\n\napp = FastAPI()\napp.include_router(api_router)\n```\n\n```py\nclass HeavyService:\n def __init__(self, heavy):\n self.heavy = heavy\n \n def operation_that_requires_heavy(self):\n return self.heavy.do_stuff()\n \nclass OtherService:\n def __init__(self, heavy_service: HeavyService):\n self.heavy_service = heavy_service\n \n def other_operation(self):\n return self.heavy_service.operation_that_requires_heavy()\n```\n\n```py\nfrom .app import heavy\nfrom .services import HeavyService, OtherService\nfrom fastapi import Depends\n\nasync def get_heavy_service():\n return HeavyService(heavy=heavy)\n \nasync def get_other_service_that_uses_heavy(heavy_service: HeavyService = Depends(get_heavy_service)):\n return OtherService(heavy_service=heavy_service)\n```\n\n```py\nfrom fastapi import APIRouter, Depends\nfrom .services import OtherService\nfrom .app_services import get_other_service_that_uses_heavy\n\napi_router = APIRouter()\n\n@api_router.get('/')\nasync def index(other_service: OtherService = Depends(get_other_service_that_uses_heavy)):\n return {'hello world': other_service.other_operation()}\n```\n\n```py\nfrom fooweb.app import app\n\nif __name__ == '__main__':\n import uvicorn\n\n uvicorn.run('fooweb.app:app', host='0.0.0.0', port=7272, reload=True)\n```\n\n```text\nDepends\n```\n\n```text\nheavylifting/heavy.py\n```\n\n```text\nfrom .heavy import HeavyLifter\n```\n\n```text\n__init__.py\n```\n\n```text\nfoo\n```\n\n```text\nheavylifting\n```\n\n```text\nfoo/heavylifting\n```\n\n```text\nDepends\n```\n\n```text\napp.py\n```\n\n```py\nimport asyncio\n\nclass HeavyLifter:\n def __init__(self, initial: int) -> None:\n self._initial = initial\n self._lock = asyncio.Lock()\n\n async def prepare(self) -> None:\n async with self._lock:\n await asyncio.sleep(self._initial)\n\n async def clean_up(self) -> None:\n async with self._lock:\n await asyncio.sleep(self._initial)\n \n def do_stuff(self) -> str:\n return \"we did stuff\"\n```\n\n```py\nfrom contextlib import asynccontextmanager\nfrom fastapi import FastAPI, APIRouter\nfrom typing import AsyncGenerator\nfrom .heavylifting import HeavyLifter\n\nheavy: HeavyLifter\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:\n global heavy\n heavy = HeavyLifter(initial=3)\n try:\n await heavy.prepare()\n\n # Serve FastAPI app\n yield\n finally:\n await heavy.clean_up()\n\nfrom .views import api_router\n\napp = FastAPI(lifespan=lifespan)\napp.include_router(api_router)\n```\n\n```py\nfrom fastapi import Depends\nfrom typing import Annotated, TypeAlias\nfrom . import app\nfrom .heavylifting import HeavyLifter\n\nHeavyLifterDep: TypeAlias = Annotated[HeavyLifter, Depends(lambda: app.heavy)]\n```\n\n```py\nfrom fastapi import APIRouter, Depends\nfrom .dependencies import HeavyLifterDep\n\napi_router = APIRouter()\n\n@api_router.get('/')\nasync def index(heavy_lifter: HeavyLifterDep):\n return {'hello world': heavy_lifter.do_stuff()}\n```\n\n```text\napp\n```\n\n```text\n__init__.py\n```\n\n```text\nAnnotated\n```\n\n```text\n__init__()\n```\n\n```text\napp\n```\n\n```text\nheavy\n```\n\n```text\napp.py\n```\n\n```text\nAnnotated\n```\n\n```text\nheavy\n```\n\n```text\napp\n```\n\n========================================\n\nComments:\n- Any reason why you can't do something like `result_from_non_route_function = Depends(non_route_function)` in your route signature when you need access to the result? Additionally, you can wrap it in an lru_cache decorator (as shown with the config dependency in the FastAPI reference, iirc).\n- Thanks for your comment @MatsLindh, but what if route method calls second, and second method calls third, where we need that dependency? I have to pass `Depends` stuff on each function, it's super inconvenient for readability and maintenance. Also, it is not caching mechanism I am worrying about, it's about proper architectural solution on application side.\n- Well, then it depends on where you need the reference to your service. Some sort of dependency should be injected into your controller since you need to decide what action the controller should take. In that case you can inject the dependent service (if that dependency depends on something else) in the function you use to create the dependency - so that the service layer wraps the operations you want to perform on your data and exposes those relevant operations to your controller.\n- Thanks again @MatsLindh, understand what you mean, but Dependenices generally as the `Depends` class in Fastapi exists for completely different reasons, not to initialize heavy services, but to make your modules more abstrat dependents. I just mentioned what limits FastAPI Depends has, to emphasize that it doesn't fixes my problem. And my problem is not to use `Depends` with some weird ways, but to initialize heavy services conveniently.\n- I see; thanks for expanding. This is just my experience: In those cases we've usually initialized the heavy service in the same location as were we set up the `app` object - they're both relevant to the startup of the application. We then wrap it in a service class as necessary to hide away the actual import and implementation if we need to change it later, but so far this has worked fine for us. We then use this service class together with a `Depends` hierarchy that populates the relevant services and arguments as needed by the routes (the heavy class is initialized on application startup).\n- The heavy initialization itself would depend on the requirements of the module itself, but is usually done with a helper function in the module (of the heavy service) or as a class or static method on a helper class. I prefer to avoid Singletons as they're not testing friendly and imposes arbitrary limitations that might turn up as issues later (if we suddenly need to talk to two different instances of the same cloud service, for example).\n- Agree! @MatsLindh can you please show me an simple example of what you described? I mean the heavy class initialization and then service of this class. I just want to see how you accessing from service class on the initialized object which is in the same file as app. You can show me the code in `answer`, instead of `comment.\n- Sorry about the delay; I had to find some time to carve out a more complete example to show how I'd solve it. Seems to work fine with my examples and mirrors how I've been solving similar issues for certain backend services.\n- Thank you @MatsLindh so much for such a great example and comprehensive answer! it is more clear than to add extra params into `@app` and thne to try to fetch it in another place. You really helped me!\n- Declaring the `HeavyLifter` object as a module-level global is a bit icky. It will make it impossible to import the `app` module without doing all that heavyweight work. FastAPI startup and shutdown events are a little better, especially since they give you an opportunity to clean up gracefully when the application stops. (Not that they don't have their own ickiness.)\n- An alternative to startup and shutdown events is to use an async context manager that gets passed as the lifespan parameter to `FastAPI()` if your python version is recent enough. Note that that is the same page as the \"startup and shutdown events\" page in Maxpm's comment.\n- Also note that the FastAPI documentation is not versioned, and that `lifespan` parameter was only added two weeks ago.\n- What if the heavy service requires cleanup?\n- @foxtrotuniform6969 Then it depends on when that cleanup should run - whether it's at the end of each request, or when the server terminates\n- Sorry this might be wrong, but isn't this a circular import? app.py imports view.py imports dependencies.py imports app.py?\n- It is an unproblematic circular import: Python can deal with partially initialized modules. In this example, dependencies.py imports app.py but does not actually access app.py during its initialization. Hence, there is no actual dependency. Even moving up the views.py import in app.py to the top doesn't change that.","metadata":{"transformedAt":"2026-08-18T18:32:29.100Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":36,"totalLines":418,"estimatedTokens":3507}}117{"id":"stack-63264888","source":"stackoverflow","questionId":63264888,"title":"pydantic: Using property.getter decorator for a field with an alias","tags":["python","types","fastapi","pydantic"],"text":"Title: pydantic: Using property.getter decorator for a field with an alias\nTags: python, types, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\n*scroll all the way down for a tl;dr, I provide context which I think is important but is not directly relevant to the question asked*\n\n### A bit of context\n\nI'm in the making of an API for a webapp and some values are computed based on the values of others in a *pydantic* `BaseModel`. These are used for user validation, data serialization and definition of database (NoSQL) documents.\n\nSpecifically, I have nearly all resources inheriting from a `OwnedResource` class, which defines, amongst irrelevant other properties like creation/last-update dates:\n\n- `object_key` -- The key of the object using a nanoid of length 6 with a custom alphabet\n\n- `owner_key` -- This key references the user that owns that object -- a nanoid of length 10.\n\n- `_key` -- this one is where I'm bumping into some problems, and I'll explain why.\n\nSo arangodb -- the database I'm using -- imposes `_key` as the name of the property by which resources are identified.\n\nSince, in my webapp, all resources are only accessed by the users who created them, they can be identified in URLs with just the object's key (eg. `/subject/{object_key}`). However, as `_key` must be unique, I intend to construct the value of this field using `f\"{owner_key}/{object_key}\"`, to store the objects of every user in the database and potentially allow for cross-user resource sharing in the future.\n\nThe goal is to have the shortest **per-user** unique identifier, since the `owner_key` part of the full `_key` used to actually access and act upon the document stored in the database is always the same: the currently-logged-in user's `_key`.\n\n### My attempt\n\nMy thought was then to define the `_key` field as a `@property`-decorated function in the class. However, Pydantic does not seem to register those as model fields.\n\nMoreover, the attribute must actually be named `key` and use an alias (with `Field(... alias=\"_key\"`), as pydantic treats underscore-prefixed fields as internal and does not expose them.\n\nHere is the definition of `OwnedResource`:\n\n```\nclass OwnedResource(BaseModel):\n \"\"\"\n Base model for resources owned by users\n \"\"\"\n\n object_key: ObjectBareKey = nanoid.generate(ID_CHARSET, OBJECT_KEY_LEN)\n owner_key: UserKey\n updated_at: Optional[datetime] = None\n created_at: datetime = datetime.now()\n\n @property\n def key(self) -> ObjectKey:\n return objectkey(self.owner_key)\n\n class Config:\n fields = {\"key\": \"_key\"} # [1]\n```\n\n[1] Since Field(..., alias=\"...\") cannot be used, I use this property of the Config subclass (see pydantic's documentation)\n\nHowever, this does not work, as shown in the following example:\n\n```\n@router.post(\"/subjects/\")\ndef create_a_subject(subject: InSubject):\n print(subject.dict(by_alias=True))\n```\n\nwith `InSubject` defining properties proper to `Subject`, and `Subject` being an empty class inheriting from both `InSubject` and `OwnedResource`:\n\n```\nclass InSubject(BaseModel):\n name: str\n color: Color\n weight: Union[PositiveFloat, Literal[0]] = 1.0\n goal: Primantissa # This is just a float constrained in a [0, 1] range\n room: str\n\nclass Subject(InSubject, OwnedResource):\n pass\n```\n\nWhen I perform a `POST /subjects/`, the following is printed in the console:\n\n```\n{'name': 'string', 'color': Color('cyan', rgb=(0, 255, 255)), 'weight': 0, 'goal': 0.0, 'room': 'string'}\n```\n\nAs you can see, `_key` or `key` are nowhere to be seen.\n\nPlease ask for details and clarification, I tried to make this as easy to understand as possible, but I'm not sure if this is clear enough.\n\n### tl;dr\n\nA context-less and more generic example without insightful context:\n\nWith the following class:\n\n```\nfrom pydantic import BaseModel\n\nclass SomeClass(BaseModel):\n \n spam: str\n\n @property\n def eggs(self) -> str:\n return self.spam + \" bacon\"\n\n class Config:\n fields = {\"eggs\": \"_eggs\"}\n```\n\nI would like the following to be true:\n\n```\na = SomeClass(spam=\"I like\")\nd = a.dict(by_alias=True)\nd.get(\"_eggs\") == \"I like bacon\"\n```\n\n========================================\n\nTop Answer:\nPydantic does not support serializing properties, there is an issue on GitHub requesting this feature.\n\nBased on this comment by ludwig-weiss he suggests subclassing BaseModel and overriding the `dict` method to include the properties.\n\n```\nclass PropertyBaseModel(BaseModel):\n \"\"\"\n Workaround for serializing properties with pydantic until\n https://github.com/samuelcolvin/pydantic/issues/935\n is solved\n \"\"\"\n @classmethod\n def get_properties(cls):\n return [prop for prop in dir(cls) if isinstance(getattr(cls, prop), property) and prop not in (\"__values__\", \"fields\")]\n\n def dict(\n self,\n *,\n include: Union['AbstractSetIntStr', 'MappingIntStrAny'] = None,\n exclude: Union['AbstractSetIntStr', 'MappingIntStrAny'] = None,\n by_alias: bool = False,\n skip_defaults: bool = None,\n exclude_unset: bool = False,\n exclude_defaults: bool = False,\n exclude_none: bool = False,\n ) -> 'DictStrAny':\n attribs = super().dict(\n include=include,\n exclude=exclude,\n by_alias=by_alias,\n skip_defaults=skip_defaults,\n exclude_unset=exclude_unset,\n exclude_defaults=exclude_defaults,\n exclude_none=exclude_none\n )\n props = self.get_properties()\n # Include and exclude properties\n if include:\n props = [prop for prop in props if prop in include]\n if exclude:\n props = [prop for prop in props if prop not in exclude]\n\n # Update the attribute dict with the properties\n if props:\n attribs.update({prop: getattr(self, prop) for prop in props})\n\n return attribs\n```\n\n========================================\n\nCode:\n```py\nclass OwnedResource(BaseModel):\n \"\"\"\n Base model for resources owned by users\n \"\"\"\n\n object_key: ObjectBareKey = nanoid.generate(ID_CHARSET, OBJECT_KEY_LEN)\n owner_key: UserKey\n updated_at: Optional[datetime] = None\n created_at: datetime = datetime.now()\n\n @property\n def key(self) -> ObjectKey:\n return objectkey(self.owner_key)\n\n class Config:\n fields = {\"key\": \"_key\"} # [1]\n```\n\n```py\n@router.post(\"/subjects/\")\ndef create_a_subject(subject: InSubject):\n print(subject.dict(by_alias=True))\n```\n\n```py\nclass InSubject(BaseModel):\n name: str\n color: Color\n weight: Union[PositiveFloat, Literal[0]] = 1.0\n goal: Primantissa # This is just a float constrained in a [0, 1] range\n room: str\n\nclass Subject(InSubject, OwnedResource):\n pass\n```\n\n```py\n{'name': 'string', 'color': Color('cyan', rgb=(0, 255, 255)), 'weight': 0, 'goal': 0.0, 'room': 'string'}\n```\n\n```py\nfrom pydantic import BaseModel\n\nclass SomeClass(BaseModel):\n \n spam: str\n\n @property\n def eggs(self) -> str:\n return self.spam + \" bacon\"\n\n class Config:\n fields = {\"eggs\": \"_eggs\"}\n```\n\n```py\na = SomeClass(spam=\"I like\")\nd = a.dict(by_alias=True)\nd.get(\"_eggs\") == \"I like bacon\"\n```\n\n```text\nBaseModel\n```\n\n```text\nOwnedResource\n```\n\n```text\nobject_key\n```\n\n```text\nowner_key\n```\n\n```text\n_key\n```\n\n```text\n_key\n```\n\n```text\n/subject/{object_key}\n```\n\n```text\n_key\n```\n\n```text\nf\"{owner_key}/{object_key}\"\n```\n\n```text\nowner_key\n```\n\n```text\n_key\n```\n\n```text\n_key\n```\n\n```text\n_key\n```\n\n```text\n@property\n```\n\n```text\nkey\n```\n\n```text\nField(... alias=\"_key\"\n```\n\n```text\nOwnedResource\n```\n\n```text\nInSubject\n```\n\n```text\nSubject\n```\n\n```text\nSubject\n```\n\n```text\nInSubject\n```\n\n```text\nOwnedResource\n```\n\n```text\nPOST /subjects/\n```\n\n```text\n_key\n```\n\n```text\nkey\n```\n\n```py\nfrom pydantic import BaseModel, computed_field\n \nclass SomeClass(BaseModel):\n \n spam: str\n \n @computed_field\n @property\n def eggs(self) -> str:\n return self.spam + \" bacon\" \n\na = SomeClass(spam=\"I like\")\na.model_dump() # -> {'spam': 'I like', 'eggs': 'I like bacon'}\n```\n\n```py\nclass PropertyBaseModel(BaseModel):\n \"\"\"\n Workaround for serializing properties with pydantic until\n https://github.com/samuelcolvin/pydantic/issues/935\n is solved\n \"\"\"\n @classmethod\n def get_properties(cls):\n return [prop for prop in dir(cls) if isinstance(getattr(cls, prop), property) and prop not in (\"__values__\", \"fields\")]\n\n def dict(\n self,\n *,\n include: Union['AbstractSetIntStr', 'MappingIntStrAny'] = None,\n exclude: Union['AbstractSetIntStr', 'MappingIntStrAny'] = None,\n by_alias: bool = False,\n skip_defaults: bool = None,\n exclude_unset: bool = False,\n exclude_defaults: bool = False,\n exclude_none: bool = False,\n ) -> 'DictStrAny':\n attribs = super().dict(\n include=include,\n exclude=exclude,\n by_alias=by_alias,\n skip_defaults=skip_defaults,\n exclude_unset=exclude_unset,\n exclude_defaults=exclude_defaults,\n exclude_none=exclude_none\n )\n props = self.get_properties()\n # Include and exclude properties\n if include:\n props = [prop for prop in props if prop in include]\n if exclude:\n props = [prop for prop in props if prop not in exclude]\n\n # Update the attribute dict with the properties\n if props:\n attribs.update({prop: getattr(self, prop) for prop in props})\n\n return attribs\n```\n\n```text\ndict\n```\n\n```text\nfrom typing import Optional\nfrom pydantic import BaseModel, Field, validator\n\n\nclass SomeClass(BaseModel):\n\n spam: str\n eggs: Optional[str] = Field(alias=\"_eggs\")\n\n @validator(\"eggs\", always=True)\n def set_eggs(cls, v, values, **kwargs):\n \"\"\"Set the eggs field based upon a spam value.\"\"\"\n return v or values.get(\"spam\") + \" bacon\"\n\n\na = SomeClass(spam=\"I like\")\nmy_dictionary = a.dict(by_alias=True)\nprint(my_dictionary)\n> {'spam': 'I like', '_eggs': 'I like bacon'}\nprint(my_dictionary.get(\"_eggs\"))\n> \"I like bacon\"\n```\n\n```text\n_key\n```\n\n```text\nalways\n```\n\n```text\n_eggs\n```\n\n========================================\n\nComments:\n- Update: This is now supported in pydantic 2: github.com/pydantic/pydantic/blob/main/docs/usage/…\n- Update: the docs are now at docs.pydantic.dev/latest/usage/computed_fields","metadata":{"transformedAt":"2026-08-18T18:32:29.101Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":38,"totalLines":438,"estimatedTokens":2528}}118{"id":"stack-65102579","source":"stackoverflow","questionId":65102579,"title":"Send and receive file using Python: FastAPI and requests","tags":["python","python-3.x","python-requests","fastapi"],"text":"Title: Send and receive file using Python: FastAPI and requests\nTags: python, python-3.x, python-requests, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm trying to upload a file to a FastAPI server using requests.\n\nI've boiled the problem down to its simplest components.\n\nThe client using requests:\n\n```\nimport requests\n\nfiles = {'file': ('foo.txt', open('./foo.txt', 'rb'))}\nresponse = requests.post('http://127.0.0.1:8000/file', files=files)\nprint(response)\nprint(response.json())\n```\n\nThe server using fastapi:\n\n```\nfrom fastapi import FastAPI, File, UploadFile\nimport uvicorn\n\napp = FastAPI()\n\n@app.post('/file')\ndef _file_upload(my_file: UploadFile = File(...)):\n print(my_file)\n\nif __name__ == \"__main__\":\n uvicorn.run(\"main:app\", host=\"0.0.0.0\", port=8000, log_level=\"debug\")\n```\n\nPackages installed:\n\n- fastapi\n\n- python-multipart\n\n- uvicorn\n\n- requests\n\nClient Output:\n\n{'detail': [{'loc': ['query', 'my_file'], 'msg': 'field required', 'type': 'value_error.missing'}]}\n\nServer Output:\nINFO: 127.0.0.1:37520 - \"POST /file HTTP/1.1\" 422 Unprocessable Entity\n\nWhat am I missing here?\n\n========================================\n\nTop Answer:\nRemove the 'foo.txt' from your request.\n\nIt should look like\n\n```\nfiles = {'file': open('./foo.txt', 'rb')}\n```\n\n========================================\n\nCode:\n```py\nimport requests\n\nfiles = {'file': ('foo.txt', open('./foo.txt', 'rb'))}\nresponse = requests.post('http://127.0.0.1:8000/file', files=files)\nprint(response)\nprint(response.json())\n```\n\n```py\nfrom fastapi import FastAPI, File, UploadFile\nimport uvicorn\n\napp = FastAPI()\n\n@app.post('/file')\ndef _file_upload(my_file: UploadFile = File(...)):\n print(my_file)\n\nif __name__ == \"__main__\":\n uvicorn.run(\"main:app\", host=\"0.0.0.0\", port=8000, log_level=\"debug\")\n```\n\n```text\nimport requests\n\nurl = \"http://127.0.0.1:8000/file\"\nfiles = {'my_file': open('README.md', 'rb')}\nres = requests.post(url, files=files)\n```\n\n```text\nmy_file\n```\n\n```text\nfile\n```\n\n```text\nfiles = {'file': open('./foo.txt', 'rb')}\n```\n\n```text\nimage = {'file':(\"your_file_name.extension\", open(\"your_file_name.extension\", 'rb'))}\n\nresp = requests.post(url=\"your url\", files=image)\n```\n\n========================================\n\nComments:\n- the ('foo.txt', ... is to add a file-name to the post-request: requests.readthedocs.io/en/master/user/quickstart I tried it without, and get same result.","metadata":{"transformedAt":"2026-08-18T18:32:29.101Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":7,"totalLines":122,"estimatedTokens":595}}119{"id":"stack-73198957","source":"stackoverflow","questionId":73198957,"title":"How to exclude Optional unset values from a Pydantic model using FastAPI?","tags":["python","fastapi","pydantic","optional-parameters"],"text":"Title: How to exclude Optional unset values from a Pydantic model using FastAPI?\nTags: python, fastapi, pydantic, optional-parameters\nSource: Stack Overflow\n\nQuestion:\nI have this model:\n\n```\nclass Text(BaseModel):\n id: str\n text: str = None\n\nclass TextsRequest(BaseModel):\n data: list[Text]\n n_processes: Union[int, None]\n```\n\nSo, I want to be able to take requests like:\n\n```\n{\"data\": [\"id\": \"1\", \"text\": \"The text 1\"], \"n_processes\": 8}\n```\n\nand\n\n```\n{\"data\": [\"id\": \"1\", \"text\": \"The text 1\"]}.\n```\n\nRight now, in the second case I get:\n\n```\n{'data': [{'id': '1', 'text': 'The text 1'}], 'n_processes': None}\n```\n\nusing this code:\n\n```\napp = FastAPI()\n\n@app.post(\"/make_post/\", response_model_exclude_none=True)\nasync def create_graph(request: TextsRequest):\n input_data = jsonable_encoder(request)\n```\n\nSo how can I exclude `n_processes` here?\n\n========================================\n\nTop Answer:\nPydantic provides the following arguments for exporting models using the `model.dict(...)` method (**Update**: `model.dict(...)` has been deprecated and replaced by **`model.model_dump(...)`**). Those parameters are as follows:\n\n`exclude_unset`: whether fields which were not explicitly set when\ncreating the model should be excluded from the returned dictionary;\ndefault `False`\n\n`exclude_none`: whether fields which are equal to None should be\nexcluded from the returned dictionary; default `False`\n\nSince you are refering to excluding optional **unset** parameters, you can use the first method (i.e., `exclude_unset`). This is useful when one would like to exclude a parameter *only* if it has not been set to either some value or `None`.\n\nThe `exclude_none` argument, however, ignores that fact that an attribute may have been intentionally set to `None`, and hence, excludes it from the returned dictionary.\n\nExample:\n\n```\nfrom pydantic import BaseModel\nfrom typing import List, Union\n\nclass Text(BaseModel):\n id: str\n text: str = None\n\nclass TextsRequest(BaseModel):\n data: List[Text] # in Python 3.9+ you can use: data: list[Text]\n n_processes: Union[int, None] = None\n\nt = TextsRequest(**{'data': [{'id': '1', 'text': 'The text 1'}], 'n_processes': None})\nprint(t.model_dump(exclude_none=True))\n#> {'data': [{'id': '1', 'text': 'The text 1'}]}\n\nprint(t.model_dump(exclude_unset=True))\n#> {'data': [{'id': '1', 'text': 'The text 1'}], 'n_processes': None}\n```\n\n### Excluding `Unset` or `None` parameters from the response\n\nIf what you needed is excluding `Unset` or `None` parameters from the endpoint's response, without necessarily calling `model.dict(...)` (or, in Pydantic V2 `model.model_dump(...)`) inside the endpoint on your own, you could instead use the endpoint's *decorator* parameter `response_model_exclude_unset` or `response_model_exclude_none` (see the relevant documentation and related answers here and here). To achieve that, FastAPI, behind the scenes, uses the aforementioned `model.dict(...)` (or, in Pydantic V2 `model.model_dump(...)`) method with its `exclude_unset` or `exclude_none` parameter.\n\nExamples:\n\n```\n@app.post(\"/create\", response_model_exclude_unset=True)\nasync def create_graph(t: TextsRequest):\n return t\n```\n\nor\n\n```\n@app.post(\"/create\", response_model_exclude_none=True)\nasync def create_graph(t: TextsRequest):\n return t\n```\n\n### About Optional Parameters\n\nUsing `Union[int, None]` is the same as using `Optional[int]` (both are equivalent). The most important part, however, to make a parameter optional is the part `= None`.\n\nAs per FastAPI documentation (see admonition **Note** and **Info** in the link provided):\n\n**Note**\n\nFastAPI will know that the value of `q` is not required because of the\ndefault value `= None`.\n\nThe `Union` in `Union[str, None]` will allow your editor to give you\nbetter support and detect errors.\n\n**Info**\n\nHave in mind that the most important part to make a parameter optional\nis the part: `= None`, as it will use that `None` as the default value, and that way make the\nparameter **not required**.\n\nThe `Union[str, None]` part allows your editor to provide better\nsupport, **but it is not what tells FastAPI** that this parameter is\n**not required**.\n\nHence, regardless of the option you may choose to use, if it is not followed by the `= None` part, FastAPI won't know that the value of the parameter is *optional*, and hence, the user will **have to provide** some value for it. One can also check that through the auto-generated API docs at http://127.0.0.1:8000/docs, where the `parameter` or `request body` will appear as a **`Required`** field.\n\nFor example, any of the below would **require** the user to pass some `body` content in their request for the `TextsRequest` model:\n\n```\n@app.post(\"/upload\")\ndef upload(t: Union[TextsRequest, None]):\n pass\n\n@app.post(\"/upload\")\ndef upload(t: Optional[TextsRequest]):\n pass\n```\n\nIf, however, the above `TextsRequest` definitions were **succeeded by** `= None`, for example:\n\n```\n@app.post(\"/upload\")\ndef upload(t: Union[TextsRequest, None] = None):\n pass\n\n@app.post(\"/upload\")\ndef upload(t: Optional[TextsRequest] = None):\n pass\n \n@app.post(\"/upload\")\ndef upload(t: TextsRequest = None): # this should work as well\n pass\n```\n\nthe parameter (or body) would be **optional**, as `= None` would tell FastAPI that this parameter is **not required**.\n\n### In Python 3.10+\n\nThe good news is that in Python 3.10 and above, you don't have to worry about names like `Optional` and `Union`, as you can simply use the vertical bar `|` (also called bitwise or operator, but that meaning is not relevant here) to define an *optional* parameter (or simply, unions of types). **However**, the same rule applies to this option as well, i.e., you would still need to add the `= None` part, if you would like to make the parameter *optional* (as demonstrated in the example given below).\n\nExample:\n\n```\n@app.post(\"/upload\")\ndef upload(t: TextsRequest | None = None):\n pass\n```\n\n========================================\n\nCode:\n```text\nclass Text(BaseModel):\n id: str\n text: str = None\n\n\nclass TextsRequest(BaseModel):\n data: list[Text]\n n_processes: Union[int, None]\n```\n\n```text\n{\"data\": [\"id\": \"1\", \"text\": \"The text 1\"], \"n_processes\": 8}\n```\n\n```text\n{\"data\": [\"id\": \"1\", \"text\": \"The text 1\"]}.\n```\n\n```text\n{'data': [{'id': '1', 'text': 'The text 1'}], 'n_processes': None}\n```\n\n```text\napp = FastAPI()\n\n@app.post(\"/make_post/\", response_model_exclude_none=True)\nasync def create_graph(request: TextsRequest):\n input_data = jsonable_encoder(request)\n```\n\n```text\nn_processes\n```\n\n```text\nclass Text(BaseModel):\n id: str\n text: str = None\n\n\nclass TextsRequest(BaseModel):\n data: list[Text]\n n_processes: Optional[int]\n\n\nrequest = TextsRequest(**{\"data\": [{\"id\": \"1\", \"text\": \"The text 1\"}]})\nprint(request.dict(exclude_none=True))\n```\n\n```text\n{'data': [{'id': '1', 'text': 'The text 1'}]}\n```\n\n```text\nmodel.model_dump(...)\n```\n\n```text\nexclude_none\n```\n\n```text\nOptional[int]\n```\n\n```text\nUnion[int, None]\n```\n\n```py\nfrom pydantic import BaseModel\nfrom typing import List, Union\n\n\nclass Text(BaseModel):\n id: str\n text: str = None\n\n\nclass TextsRequest(BaseModel):\n data: List[Text] # in Python 3.9+ you can use: data: list[Text]\n n_processes: Union[int, None] = None\n\n\nt = TextsRequest(**{'data': [{'id': '1', 'text': 'The text 1'}], 'n_processes': None})\nprint(t.model_dump(exclude_none=True))\n#> {'data': [{'id': '1', 'text': 'The text 1'}]}\n\nprint(t.model_dump(exclude_unset=True))\n#> {'data': [{'id': '1', 'text': 'The text 1'}], 'n_processes': None}\n```\n\n```py\n@app.post(\"/create\", response_model_exclude_unset=True)\nasync def create_graph(t: TextsRequest):\n return t\n```\n\n```py\n@app.post(\"/create\", response_model_exclude_none=True)\nasync def create_graph(t: TextsRequest):\n return t\n```\n\n```py\n@app.post(\"/upload\")\ndef upload(t: Union[TextsRequest, None]):\n pass\n\n@app.post(\"/upload\")\ndef upload(t: Optional[TextsRequest]):\n pass\n```\n\n```py\n@app.post(\"/upload\")\ndef upload(t: Union[TextsRequest, None] = None):\n pass\n\n@app.post(\"/upload\")\ndef upload(t: Optional[TextsRequest] = None):\n pass\n \n@app.post(\"/upload\")\ndef upload(t: TextsRequest = None): # this should work as well\n pass\n```\n\n```py\n@app.post(\"/upload\")\ndef upload(t: TextsRequest | None = None):\n pass\n```\n\n```text\nmodel.dict(...)\n```\n\n```text\nmodel.dict(...)\n```\n\n```text\nmodel.model_dump(...)\n```\n\n```text\nexclude_unset\n```\n\n```text\nFalse\n```\n\n```text\nexclude_none\n```\n\n```text\nFalse\n```\n\n```text\nexclude_unset\n```\n\n```text\nNone\n```\n\n```text\nexclude_none\n```\n\n```text\nNone\n```\n\n```text\nUnset\n```\n\n```text\nNone\n```\n\n```text\nUnset\n```\n\n```text\nNone\n```\n\n```text\nmodel.dict(...)\n```\n\n```text\nmodel.model_dump(...)\n```\n\n```text\nresponse_model_exclude_unset\n```\n\n```text\nresponse_model_exclude_none\n```\n\n```text\nmodel.dict(...)\n```\n\n```text\nmodel.model_dump(...)\n```\n\n```text\nexclude_unset\n```\n\n```text\nexclude_none\n```\n\n```text\nUnion[int, None]\n```\n\n```text\nOptional[int]\n```\n\n```text\n= None\n```\n\n```text\nq\n```\n\n```text\n= None\n```\n\n```text\nUnion\n```\n\n```text\nUnion[str, None]\n```\n\n```text\n= None\n```\n\n```text\nNone\n```\n\n```text\nUnion[str, None]\n```\n\n```text\n= None\n```\n\n```text\nparameter\n```\n\n```text\nrequest body\n```\n\n```text\nRequired\n```\n\n```text\nbody\n```\n\n```text\nTextsRequest\n```\n\n```text\nTextsRequest\n```\n\n```text\n= None\n```\n\n```text\n= None\n```\n\n```text\nOptional\n```\n\n```text\nUnion\n```\n\n```text\n|\n```\n\n```text\n= None\n```\n\n```text\napp = FastAPI()\n\n@app.post(\"/make_post/\", response_model_exclude_unset=True)\nasync def create_graph(request: TextsRequest):\n input_data = jsonable_encoder(request)\n```\n\n```text\nresponse_model_exlclude_none\n```\n\n```text\nresponse_model_exclude_unset\n```\n\n========================================\n\nComments:\n- Would disagree with your last statement. Union is closer to python 3.10 syntax than Optional, but that’s just my opinion.\n- Pydantic >= 2.0 deprecates `model.dict()`. As Eapen Jose wrote, use `model_dump()`.\n- Is there a way to configure this behavior at the Model level? I tried putting `exclude_none = True` in the model Config but no dice.","metadata":{"transformedAt":"2026-08-18T18:32:29.101Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":67,"totalLines":517,"estimatedTokens":2513}}120{"id":"stack-77847983","source":"stackoverflow","questionId":77847983,"title":"Processing requests in FastAPI sequentially while staying responsive","tags":["python","concurrency","python-asyncio","fastapi"],"text":"Title: Processing requests in FastAPI sequentially while staying responsive\nTags: python, concurrency, python-asyncio, fastapi\nSource: Stack Overflow\n\nQuestion:\nMy server exposes an API for a resource-intensive rendering work. The job it does involves a GPU and as such the server can handle only a single request at a time. Clients should submit a job and receive `201` - ACCEPTED - as a response immediately after. The processing can take up to a minute and there can be a few dozens of requests scheduled.\n\nHere's what I came up with, boiled to a minimal reproducible example:\n\n```\nimport time\nimport asyncio\nfrom fastapi import FastAPI, status\n\napp = FastAPI()\nfifo_queue = asyncio.Queue()\n\nasync def process_requests():\n while True:\n name = await fifo_queue.get() # Wait for a request from the queue\n print(name)\n time.sleep(10) # A RESOURCE INTENSIVE JOB THAT BLOCKS THE THREAD\n fifo_queue.task_done() # Indicate that the request has been processed\n\n@app.on_event(\"startup\")\nasync def startup_event():\n asyncio.create_task(process_requests()) # Start the request processing task\n\n@app.get(\"/render\")\nasync def render(name):\n fifo_queue.put_nowait(name) # Add the request parameter to the queue\n return status.HTTP_201_CREATED # Return a 201 status code\n```\n\nThe problem with this approach is that the server does not stay responsive. After sending the first request it gets busy full time with it and does not respond as I have hoped.\n\n```\ncurl http://127.0.0.1:8000/render\\?name\\=001\n```\n\nIn this example simply replacing `time.sleep(10)` with `await asyncio.sleep(10)` solves the problem, but not in the real use case (though possibly offers a clue as for what I am doing incorrectly).\n\nAny ideas?\n\n========================================\n\nTop Answer:\nThe basic thing that I missed is that in asyncio one can't do anything blocking in a function marked async or it will freeze the event loop.\n\n**Solution**\n\nRun the process with the asyncio event loop `run_in_executor`. The method allows to run the code in a process pool and returns an awaitable. Since it runs in a separate process, the main loop stays responsive.\n\n```\nimport time\nimport asyncio\nfrom fastapi import FastAPI, status\nfrom functools import partial\nfrom concurrent.futures import ProcessPoolExecutor\n\napp = FastAPI()\nfifo_queue = asyncio.Queue()\n\ndef compute_intensive_func(name):\n print(name)\n time.sleep(10)\n return 43\n\nasync def process_requests():\n while True:\n name = await fifo_queue.get() # Wait for a request from the queue\n r = await asyncio.get_running_loop().run_in_executor(pool, partial(compute_intensive_func, name))\n fifo_queue.task_done() # Indicate that the request has been processed\n\n@app.on_event(\"startup\")\nasync def startup_event():\n asyncio.create_task(process_requests()) # Start the request processing task\n\n@app.get(\"/render\")\nasync def render(name):\n fifo_queue.put_nowait(name) # Add the request parameter to the queue\n return status.HTTP_201_CREATED # Return a 201 status code\n```\n\n========================================\n\nCode:\n```py\nimport time\nimport asyncio\nfrom fastapi import FastAPI, status\n\n\napp = FastAPI()\nfifo_queue = asyncio.Queue()\n\n\nasync def process_requests():\n while True:\n name = await fifo_queue.get() # Wait for a request from the queue\n print(name)\n time.sleep(10) # A RESOURCE INTENSIVE JOB THAT BLOCKS THE THREAD\n fifo_queue.task_done() # Indicate that the request has been processed\n\n\n@app.on_event(\"startup\")\nasync def startup_event():\n asyncio.create_task(process_requests()) # Start the request processing task\n\n\n@app.get(\"/render\")\nasync def render(name):\n fifo_queue.put_nowait(name) # Add the request parameter to the queue\n return status.HTTP_201_CREATED # Return a 201 status code\n```\n\n```text\ncurl http://127.0.0.1:8000/render\\?name\\=001\n```\n\n```text\n201\n```\n\n```text\ntime.sleep(10)\n```\n\n```text\nawait asyncio.sleep(10)\n```\n\n```py\nfrom fastapi import FastAPI, Request\nfrom fastapi.responses import JSONResponse\nfrom contextlib import asynccontextmanager\nfrom dataclasses import dataclass\nfrom concurrent.futures import ProcessPoolExecutor\nimport time\nimport asyncio\nimport uuid\n\n\n@dataclass\nclass Item:\n id: str\n name: str\n \n\n# Simulating a Computationally Intensive Task\ndef cpu_bound_task(item: Item):\n print(f\"Processing: {item.name}\")\n time.sleep(15)\n return 'ok'\n\n\nasync def process_requests(q: asyncio.Queue, pool: ProcessPoolExecutor):\n while True:\n item = await q.get() # Get a request from the queue\n loop = asyncio.get_running_loop()\n fake_db[item.id] = 'Processing...'\n r = await loop.run_in_executor(pool, cpu_bound_task, item)\n q.task_done() # tell the queue that the processing on the task is completed\n fake_db[item.id] = 'Done.'\n\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI):\n q = asyncio.Queue() # note that asyncio.Queue() is not thread safe\n pool = ProcessPoolExecutor()\n asyncio.create_task(process_requests(q, pool)) # Start the requests processing task\n yield {'q': q, 'pool': pool}\n pool.shutdown() # free any resources that the pool is using when the currently pending futures are done executing\n\n\nfake_db = {}\napp = FastAPI(lifespan=lifespan)\n\n\n@app.get(\"/add\")\nasync def add_task(request: Request, name: str):\n item_id = str(uuid.uuid4())\n item = Item(item_id, name)\n request.state.q.put_nowait(item) # Add request to the queue\n fake_db[item_id] = 'Pending...'\n return item_id\n \n\n@app.get(\"/status\")\nasync def check_status(item_id: str):\n if item_id in fake_db:\n return {'status': fake_db[item_id]}\n else:\n return JSONResponse(\"Item ID Not Found\", status_code=404)\n\n\nif __name__ == '__main__':\n import uvicorn\n uvicorn.run(app)\n```\n\n```py\nasync def process_requests(q: asyncio.Queue):\n while True:\n # ...\n with ProcessPoolExecutor() as pool:\n r = await loop.run_in_executor(pool, cpu_bound_task, item)\n # ...\n```\n\n```text\nasync def\n```\n\n```text\nasync def\n```\n\n```text\nProcessPool\n```\n\n```text\nawait\n```\n\n```text\nasyncio\n```\n\n```text\nloop.run_in_executor()\n```\n\n```text\nProcessPoolExecutor\n```\n\n```text\nif __name__ == '__main__'\n```\n\n```text\nlifespan\n```\n\n```text\nstartup\n```\n\n```text\nshutdown\n```\n\n```text\nprocess_requests\n```\n\n```text\nasyncio.Queue()\n```\n\n```text\nProcessPoolExecutor\n```\n\n```text\nrequest.state\n```\n\n```text\nProcessPoolExecutor\n```\n\n```text\nProcessPool\n```\n\n```text\ndict\n```\n\n```text\n/status\n```\n\n```text\nProcessPoolExecutor\n```\n\n```text\nProcessPoolExecutor\n```\n\n```text\nwith\n```\n\n```text\nimport time\nimport asyncio\nfrom fastapi import FastAPI, status\nfrom functools import partial\nfrom concurrent.futures import ProcessPoolExecutor\n\n\napp = FastAPI()\nfifo_queue = asyncio.Queue()\n\n\ndef compute_intensive_func(name):\n print(name)\n time.sleep(10)\n return 43\n\nasync def process_requests():\n while True:\n name = await fifo_queue.get() # Wait for a request from the queue\n r = await asyncio.get_running_loop().run_in_executor(pool, partial(compute_intensive_func, name))\n fifo_queue.task_done() # Indicate that the request has been processed\n\n\n@app.on_event(\"startup\")\nasync def startup_event():\n asyncio.create_task(process_requests()) # Start the request processing task\n\n\n@app.get(\"/render\")\nasync def render(name):\n fifo_queue.put_nowait(name) # Add the request parameter to the queue\n return status.HTTP_201_CREATED # Return a 201 status code\n```\n\n```text\nrun_in_executor\n```\n\n========================================\n\nComments:\n- for each request given to run, assign it some id and return the id to api call , save result in db or somewhere and then for that id ask the 3rd party to check status. doing current approach with multiple request your system will running full throtle\n- @sahasrara62 sure, that's what would normally happen, but I just wanted to keep things simple\n- check this out if this can help stackoverflow.com/questions/63967662/pool-of-async-tasks\n- Thanks, I was thinking that the `create_task` would actually start the thread. How would you approach this particular case? Simply create an extra function `fun()` to be called within `process_request` like this `asyncio.run(fun())`? Change anything else?\n- yes, I think you can just make whatever GPU function you have now an async function and run it in awaitable fashion.\n- When I try doing this, I get `asyncio.run() cannot be called from a running event loop` If I get the current event loop, but that gets me where I have started. If I make the resource-heavy `fun()` async and go with `await fun()` inside `process_requests()` I again get unresponsive server.\n- what is `pool` here?\n- Thanks for going the extra mile! It improves over my answer, hence accepting it. There's one bit that could be addressed: the `cpu_bound_task` should take `Item` as an argument, not just a string. Why it matters: making this change leads to this error: `TypeError: no default __reduce__ due to non-trivial __cinit__`. Could you address it? The problem seems to be with passing `request` within the `Item`. Removing fixes the problem, but I am curious if there's a way to make it work.\n- That was the idea, i.e., to pass the `Item` object as the argument. However, a `ProcessingPool` pickles the objects when it sends them to another process, and having the `request` object part of it would fail serialization - plus, not sure if it would make much sense to persist objects scuh as `request`. Regardless, in the example, the `request` object is not actually used by the CPU-bound task; if you think it would make it more clear to you, I could have it removed and pass the `Item` as an argument, and explain that any information the `request` holds could be passed as separate arguments.\n- I think simply removing request from the `Item` makes most sense in this example, IMO no need to explain how to pass more data. BTW, what would be the best way to mark that item is being processed, something like `fake_db[item_id] = 'Processing...'`. I tried that assignment in the `cpu_bound_task`, but the dict wasn't modified. I can't use an actual db in this case.\n- Updated. If you wouldn't like using some database storage or Key-Value cache, which would allow you to variables/objects among the various processes (as explained in this answer, each process, and uvicorn worker as well, has its own variables and memory; that is why you can't update the `dict` object within the separate process), you could simply update the value of the relevant key in `fake_db`, jsut before calling `run_in_executor` (shown in the example above).\n- Thanks! One word of explanation behind NOT reusing the `Pool` object: when we intentionally want to kill the process. My rendering uses library on occasions does not fully release resources, in particular memory on GPU. Since the process really needs all the memory, it sometimes leads to `CUDA: out of memory error`. Mentioning just in case someone ventures into similar waters.","metadata":{"transformedAt":"2026-08-18T18:32:29.101Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":31,"totalLines":352,"estimatedTokens":2755}}121{"id":"stack-64932222","source":"stackoverflow","questionId":64932222,"title":"When/Where to use Body/Path/Query/Field in FastAPI?","tags":["validation","metadata","fastapi"],"text":"Title: When/Where to use Body/Path/Query/Field in FastAPI?\nTags: validation, metadata, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm following the tutorial from FastAPI, and so far I have doubts about **When/Where to use Body/Path/Query/Field in FastAPI?** because all of them seem to work the same way, the tutorial uses vague explanations about their *distinction*, or am I missing something?\n\n**Bonus question**: Is `*` really useful? I've set/omitted it in the sample code of tutorial, but I don't see the difference.\n\n========================================\n\nCode:\n```text\n*\n```\n\n```text\nhttps://stackoverflow.com/questions/tagged/fastapi?sort=Newest&uqlId=26120\n```\n\n```py\nfrom enum import Enum\n\n\nclass SortTypes(str, Enum):\n newest: str = \"Newest\"\n unanswered: str = \"Unanswered\"\n active: str = \"Active\"\n bountied: str = \"Bountied\"\n\n\n@app.get(\"/questions/tagged/{tag}\")\nasync def get_questions_with_tags(tag: str, sort: SortTypes, uqlId: int):\n return ...\n```\n\n```text\n{\"name\": \"foo\"}\n```\n\n```text\n{\"Content-Type\": \"application/json\"}\n```\n\n```text\nJSONResponse\n```\n\n```text\nStreamingResponse\n```\n\n```text\nFileResponse\n```\n\n```text\nHTMLResponse\n```\n\n```text\nQuery\n```\n\n========================================\n\nComments:\n- Does this answer your question? When do I use path params vs. query params in a RESTful API?\n- Nop, but thanks for the post, it helps in some way.\n- Thanks @yagizcan-degirmenci, I understand better about queries and path parameters, and therefore QUERY, PATH, BODY, FIELD. I think you can complement your valuable explanation for **Body** with this call: `curl -X PUT \"http://127.0.0.1:8000/items4/345?q=holmes\" -H \"accept: application/json\" -H \"Content-Type: application/json\" -d \"{\\\"item\\\":{\\\"name\\\":\\\"string\\\",\\\"description\\\":\\\"string\\\",\\‌​\"price\\\":0,\\\"tax\\\":0‌​},\\\"user\\\":{\\\"userna‌​me\\\":\\\"string\\\",\\\"fu‌​ll_name\\\":\\\"string\\\"‌​},\\\"importance\\\":1}\"`\n- @ΟυιλιαμΑρκευα oh ofc, but the body can be any type, an image, a base64 encoded string, a JSON, or bytes object, etc. I will update my answer with a better explanation for the body. Thank you.\n- how to add a body parm into the endpoint definition too?","metadata":{"transformedAt":"2026-08-18T18:32:29.101Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":10,"totalLines":72,"estimatedTokens":558}}122{"id":"stack-64731890","source":"stackoverflow","questionId":64731890,"title":"FastAPI - Supporting multiple authentication dependencies","tags":["python","oauth","jwt","openapi","fastapi"],"text":"Title: FastAPI - Supporting multiple authentication dependencies\nTags: python, oauth, jwt, openapi, fastapi\nSource: Stack Overflow\n\nQuestion:\n### Problem\n\nI currently have JWT dependency named jwt which makes sure it passes JWT authentication stage before hitting the endpoint like this:\n\n`sample_endpoint.py`:\n\n```\nfrom fastapi import APIRouter, Depends, Request\nfrom JWTBearer import JWTBearer\nfrom jwt import jwks\n\nrouter = APIRouter()\n\njwt = JWTBearer(jwks)\n\n@router.get(\"/test_jwt\", dependencies=[Depends(jwt)])\nasync def test_endpoint(request: Request):\n return True\n```\n\nBelow is the JWT dependency which authenticate users using JWT (source: https://medium.com/datadriveninvestor/jwt-authentication-with-fastapi-and-aws-cognito-1333f7f2729e):\n\n`JWTBearer.py`\n\n```\nfrom typing import Dict, Optional, List\n\nfrom fastapi import HTTPException\nfrom fastapi.security import HTTPBearer, HTTPAuthorizationCredentials\nfrom jose import jwt, jwk, JWTError\nfrom jose.utils import base64url_decode\nfrom pydantic import BaseModel\nfrom starlette.requests import Request\nfrom starlette.status import HTTP_403_FORBIDDEN\n\nJWK = Dict[str, str]\n\nclass JWKS(BaseModel):\n keys: List[JWK]\n\nclass JWTAuthorizationCredentials(BaseModel):\n jwt_token: str\n header: Dict[str, str]\n claims: Dict[str, str]\n signature: str\n message: str\n\nclass JWTBearer(HTTPBearer):\n def __init__(self, jwks: JWKS, auto_error: bool = True):\n super().__init__(auto_error=auto_error)\n\n self.kid_to_jwk = {jwk[\"kid\"]: jwk for jwk in jwks.keys}\n\n def verify_jwk_token(self, jwt_credentials: JWTAuthorizationCredentials) -> bool:\n try:\n public_key = self.kid_to_jwk[jwt_credentials.header[\"kid\"]]\n except KeyError:\n raise HTTPException(\n status_code=HTTP_403_FORBIDDEN, detail=\"JWK public key not found\"\n )\n\n key = jwk.construct(public_key)\n decoded_signature = base64url_decode(jwt_credentials.signature.encode())\n\n return key.verify(jwt_credentials.message.encode(), decoded_signature)\n\n async def __call__(self, request: Request) -> Optional[JWTAuthorizationCredentials]:\n credentials: HTTPAuthorizationCredentials = await super().__call__(request)\n\n if credentials:\n if not credentials.scheme == \"Bearer\":\n raise HTTPException(\n status_code=HTTP_403_FORBIDDEN, detail=\"Wrong authentication method\"\n )\n\n jwt_token = credentials.credentials\n\n message, signature = jwt_token.rsplit(\".\", 1)\n\n try:\n jwt_credentials = JWTAuthorizationCredentials(\n jwt_token=jwt_token,\n header=jwt.get_unverified_header(jwt_token),\n claims=jwt.get_unverified_claims(jwt_token),\n signature=signature,\n message=message,\n )\n except JWTError:\n raise HTTPException(status_code=HTTP_403_FORBIDDEN, detail=\"JWK invalid\")\n\n if not self.verify_jwk_token(jwt_credentials):\n raise HTTPException(status_code=HTTP_403_FORBIDDEN, detail=\"JWK invalid\")\n\n return jwt_credentials\n```\n\n`jwt.py`:\n\n```\nimport os\n\nimport requests\nfrom dotenv import load_dotenv\nfrom fastapi import Depends, HTTPException\nfrom starlette.status import HTTP_403_FORBIDDEN\n\nfrom app.JWTBearer import JWKS, JWTBearer, JWTAuthorizationCredentials\n\nload_dotenv() # Automatically load environment variables from a '.env' file.\n\njwks = JWKS.parse_obj(\n requests.get(\n f\"https://cognito-idp.{os.environ.get('COGNITO_REGION')}.amazonaws.com/\"\n f\"{os.environ.get('COGNITO_POOL_ID')}/.well-known/jwks.json\"\n ).json()\n)\n\njwt = JWTBearer(jwks)\n\nasync def get_current_user(\n credentials: JWTAuthorizationCredentials = Depends(auth)\n) -> str:\n try:\n return credentials.claims[\"username\"]\n except KeyError:\n HTTPException(status_code=HTTP_403_FORBIDDEN, detail=\"Username missing\")\n```\n\n`api_key_dependency.py` (very simplified right now, it will be changed):\n\n```\nfrom fastapi import Security, FastAPI, HTTPException\nfrom fastapi.security.api_key import APIKeyHeader\n\nfrom starlette.status import HTTP_403_FORBIDDEN\n\nasync def get_api_key(\n api_key_header: str = Security(api_key_header)\n):\n API_KEY = ... getting API KEY logic ...\n\n if api_key_header == API_KEY:\n return True\n else:\n raise HTTPException(\n status_code=HTTP_403_FORBIDDEN, detail=\"Could not validate credentials\"\n )\n```\n\n### Question\n\nDepending on the situation, I would like to first check if it has API Key in the header, and if its present, use that to authenticate. Otherwise, I would like to use jwt dependency for authentication. I want to make sure that if either api-key authentication or jwt authentication passes, the user is authenticated. Would this be possible in FastAPI (i.e. having multiple dependencies and if one of them passes, authentication passed). Thank you!\n\n========================================\n\nTop Answer:\nThis worked for me (JWT or APIkey Auth). If both or one of the authentication method passes, the authentication passes.\n\n```\ndef jwt_auth(auth: HTTPAuthorizationCredentials = Depends(HTTPBearer(auto_error=False))):\n if not auth:\n return None\n ## validation logic\n return True\n\ndef key_auth(apikey_header=Depends(APIKeyHeader(name='X-API-Key', auto_error=False))):\n if not apikey_header:\n return None\n ## validation logic\n return True\n\nasync def jwt_or_key_auth(jwt_result=Depends(jwt_auth), key_result=Depends(key_auth)):\n if not (key_result or jwt_result):\n raise HTTPException(status_code=401, detail=\"Not authenticated\")\n\n@app.get(\"/\", dependencies=[Depends(jwt_or_key_auth)])\nasync def root():\n return {\"message\": \"Hello World\"}\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi import APIRouter, Depends, Request\nfrom JWTBearer import JWTBearer\nfrom jwt import jwks\n\nrouter = APIRouter()\n\njwt = JWTBearer(jwks)\n\n@router.get(\"/test_jwt\", dependencies=[Depends(jwt)])\nasync def test_endpoint(request: Request):\n return True\n```\n\n```text\nfrom typing import Dict, Optional, List\n\nfrom fastapi import HTTPException\nfrom fastapi.security import HTTPBearer, HTTPAuthorizationCredentials\nfrom jose import jwt, jwk, JWTError\nfrom jose.utils import base64url_decode\nfrom pydantic import BaseModel\nfrom starlette.requests import Request\nfrom starlette.status import HTTP_403_FORBIDDEN\n\nJWK = Dict[str, str]\n\n\nclass JWKS(BaseModel):\n keys: List[JWK]\n\n\nclass JWTAuthorizationCredentials(BaseModel):\n jwt_token: str\n header: Dict[str, str]\n claims: Dict[str, str]\n signature: str\n message: str\n\n\nclass JWTBearer(HTTPBearer):\n def __init__(self, jwks: JWKS, auto_error: bool = True):\n super().__init__(auto_error=auto_error)\n\n self.kid_to_jwk = {jwk[\"kid\"]: jwk for jwk in jwks.keys}\n\n def verify_jwk_token(self, jwt_credentials: JWTAuthorizationCredentials) -> bool:\n try:\n public_key = self.kid_to_jwk[jwt_credentials.header[\"kid\"]]\n except KeyError:\n raise HTTPException(\n status_code=HTTP_403_FORBIDDEN, detail=\"JWK public key not found\"\n )\n\n key = jwk.construct(public_key)\n decoded_signature = base64url_decode(jwt_credentials.signature.encode())\n\n return key.verify(jwt_credentials.message.encode(), decoded_signature)\n\n async def __call__(self, request: Request) -> Optional[JWTAuthorizationCredentials]:\n credentials: HTTPAuthorizationCredentials = await super().__call__(request)\n\n if credentials:\n if not credentials.scheme == \"Bearer\":\n raise HTTPException(\n status_code=HTTP_403_FORBIDDEN, detail=\"Wrong authentication method\"\n )\n\n jwt_token = credentials.credentials\n\n message, signature = jwt_token.rsplit(\".\", 1)\n\n try:\n jwt_credentials = JWTAuthorizationCredentials(\n jwt_token=jwt_token,\n header=jwt.get_unverified_header(jwt_token),\n claims=jwt.get_unverified_claims(jwt_token),\n signature=signature,\n message=message,\n )\n except JWTError:\n raise HTTPException(status_code=HTTP_403_FORBIDDEN, detail=\"JWK invalid\")\n\n if not self.verify_jwk_token(jwt_credentials):\n raise HTTPException(status_code=HTTP_403_FORBIDDEN, detail=\"JWK invalid\")\n\n return jwt_credentials\n```\n\n```text\nimport os\n\nimport requests\nfrom dotenv import load_dotenv\nfrom fastapi import Depends, HTTPException\nfrom starlette.status import HTTP_403_FORBIDDEN\n\nfrom app.JWTBearer import JWKS, JWTBearer, JWTAuthorizationCredentials\n\nload_dotenv() # Automatically load environment variables from a '.env' file.\n\njwks = JWKS.parse_obj(\n requests.get(\n f\"https://cognito-idp.{os.environ.get('COGNITO_REGION')}.amazonaws.com/\"\n f\"{os.environ.get('COGNITO_POOL_ID')}/.well-known/jwks.json\"\n ).json()\n)\n\njwt = JWTBearer(jwks)\n\n\nasync def get_current_user(\n credentials: JWTAuthorizationCredentials = Depends(auth)\n) -> str:\n try:\n return credentials.claims[\"username\"]\n except KeyError:\n HTTPException(status_code=HTTP_403_FORBIDDEN, detail=\"Username missing\")\n```\n\n```text\nfrom fastapi import Security, FastAPI, HTTPException\nfrom fastapi.security.api_key import APIKeyHeader\n\nfrom starlette.status import HTTP_403_FORBIDDEN\n\nasync def get_api_key(\n api_key_header: str = Security(api_key_header)\n):\n API_KEY = ... getting API KEY logic ...\n\n if api_key_header == API_KEY:\n return True\n else:\n raise HTTPException(\n status_code=HTTP_403_FORBIDDEN, detail=\"Could not validate credentials\"\n )\n```\n\n```text\nsample_endpoint.py\n```\n\n```text\nJWTBearer.py\n```\n\n```text\njwt.py\n```\n\n```text\napi_key_dependency.py\n```\n\n```text\nfrom fastapi import APIRouter, Depends, Request\nfrom check_auth import check\nfrom JWTBearer import JWTBearer\nfrom jwt import jwks\n\nrouter = APIRouter()\n\njwt = JWTBearer(jwks)\n\n@router.get(\"/test_jwt\", dependencies=[Depends(check)])\nasync def test_endpoint(request: Request):\n return True\n```\n\n```text\ndef key_auth(api_key=Header(None)):\n if not api_key:\n return None\n ... verification logic goes here ...\n\ndef jwt(authorization=Header(None)):\n if not authorization:\n return None\n ... verification logic goes here ... \n \nasync def check(key_result=Depends(jwt_auth), jwt_result=Depends(key_auth)):\n if not (key_result or jwt_result):\n raise Exception\n```\n\n```text\ndef jwt_auth(auth: HTTPAuthorizationCredentials = Depends(HTTPBearer(auto_error=False))):\n if not auth:\n return None\n ## validation logic\n return True\n\ndef key_auth(apikey_header=Depends(APIKeyHeader(name='X-API-Key', auto_error=False))):\n if not apikey_header:\n return None\n ## validation logic\n return True\n\nasync def jwt_or_key_auth(jwt_result=Depends(jwt_auth), key_result=Depends(key_auth)):\n if not (key_result or jwt_result):\n raise HTTPException(status_code=401, detail=\"Not authenticated\")\n\n\n@app.get(\"/\", dependencies=[Depends(jwt_or_key_auth)])\nasync def root():\n return {\"message\": \"Hello World\"}\n```\n\n========================================\n\nComments:\n- A simple solution could be to have a unique `Dependency` that performs the check and calls the correct authentication method (JWT or KEY). If you need to authenticate certain paths just with JWT, you can use directly that dependency (the same approach applies for only KEY authentication)\n- Thank you Isabi, just to clarify, what you mean is adding third dependency (which will be the only dependency for `sample_endpoint`) that performs the check and calls the correct authentication dependency (JWT dependency or Key dependency). Is this correct?\n- Yes, some sort of factory method\n- Could you provide a simple example where I can call other dependency inside the factory dependency? I researched a bit on how to do that, but wasnt able to find a good example on it. I've updated the post with sample dependency for api key validation.\n- I've tried creating factory dependency (class), having _*call_* method inside factory dependency, and created two separate functions inside the class (`check_api_key`, `check_jwt`). It looks like `def call_api_key(self, b = Depends(get_api_key)):` for example. But it doesn't seem to call respective dependency inside `check_api_key` or `check_jwt` key at all. Would you be able to provide some guidance here?\n- Thanks Isabi! I got up to this part, but wasn't able to call other dependencies inside the factory dependency. I'm not really sure if this is supported in FastAPI.\n- Probably it is due to the dependencies that the classes have. Maybe playing around with the request directly can allow you to access the keys\n- @louprogramming did you manage to solve your problem? If so, feel free to improve my answer (maybe write EDIT before your changes)\n- yeap, I ended up finding a workaround which was to move dependencies inside the factory dependency as two separate dependencies(methods). I was going to leave a comment on this, but didn't get a chance to do. I'll update it right now.\n- @louprogramming Could you maybe provide an example of this? I have done something similar (made another dependency which allows both auth schemes); but then i lose the authorization option in the open api spec (the lock is gone).\n- I actually think this is the better answer. One small improvement: use `Security()` instead of `Depends()` to get some added benefits like auth integration into the swagger UI","metadata":{"transformedAt":"2026-08-18T18:32:29.101Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":11,"totalLines":411,"estimatedTokens":3315}}123{"id":"stack-69641363","source":"stackoverflow","questionId":69641363,"title":"How to run FastAPI app on multiple ports?","tags":["python","docker","gunicorn","fastapi","uvicorn"],"text":"Title: How to run FastAPI app on multiple ports?\nTags: python, docker, gunicorn, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI have a FastAPI application that I am running on port 30000 using Uvicorn programmatically. Now I want to run the same application on port 8443 too. The same application needs to run on both these ports. How can I do this within the Python code?\n\nMinimum Reproducible code:\n\n```\nfrom fastapi import FastAPI\nimport uvicorn\n\napp = FastAPI()\n\n@app.get(\"/healthcheck/\")\ndef healthcheck():\n return 'Health - OK'\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", port=30000)\n```\n\nI want to something like\n\n```\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", ports=[30000,8443])\n```\n\nExplanation:\nMy application will be running on my organizations Azure Kubernetes Service. Apps running on port 30000 are reserved for Internal HTTP traffic and apps running on 8443 are mapped to 443 of Kubernetes Service to be exposed to external traffic.\n\nFurther Details:\nI will be creating a Docker Container out of this application and the idea is to include\n\n```\nCMD [\"python3\", \"app.py\"]\n```\n\nat the end to run the application. I am looking for a solution that would either provide a way to change the python code ( `uvicorn.run(app, host=\"0.0.0.0\", ports=[30000,8443])` ) or a change to the CMD command in the Dockerfile like This GitHub Issue Comment - `gunicorn -k uvicorn.workers.UvicornWorker -w 1 --bind ip1:port1 --bind ip2:port2 --bind ip3:port3`\n\n========================================\n\nTop Answer:\nIn my case, I used the same command above but with a small change. I needed to expose other routes on private port.\n\n```\napp = FastAPI()\napp2 = FastAPI()\n```\n\nThen, in the `run.sh` file, I have:\n\n```\nuvicorn app.main:app --reload --host 0.0.0.0 --port $PORT & uvicorn app.main:app2 --reload --host 0.0.0.0 --port $PORT_INTERNAL_APP\n```\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI\nimport uvicorn\n\napp = FastAPI()\n\n\n@app.get(\"/healthcheck/\")\ndef healthcheck():\n return 'Health - OK'\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", port=30000)\n```\n\n```py\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", ports=[30000,8443])\n```\n\n```sh\nCMD [\"python3\", \"app.py\"]\n```\n\n```text\nuvicorn.run(app, host=\"0.0.0.0\", ports=[30000,8443])\n```\n\n```text\ngunicorn -k uvicorn.workers.UvicornWorker -w 1 --bind ip1:port1 --bind ip2:port2 --bind ip3:port3\n```\n\n```text\nFROM python:3.7\nWORKDIR /app\nCOPY requirements.txt .\nRUN pip3 install -r requirements.txt\nCOPY . .\nENTRYPOINT ./docker-starter.sh\nEXPOSE 30000 8443\n```\n\n```text\ngunicorn -k uvicorn.workers.UvicornWorker -w 3 -b 0.0.0.0:30000 -t 360 --reload --access-logfile - app:app & gunicorn --access-logfile - -k --ca_certs ca_certs.txt uvicorn.workers.UvicornWorker -w 3 -b 0.0.0.0:8443 -t 360 --reload --access-logfile - app:app\n```\n\n```py\nfrom fastapi import FastAPI\nimport uvicorn\n\napp = FastAPI()\n\n\n@app.get(\"/healthcheck/\")\ndef healthcheck():\n return 'Health - OK'\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\")\n```\n\n```text\ndocker-starter.sh\n```\n\n```text\ndocker-compose.yml\nDockerfile\nmain.py\nrequirements.txt\n```\n\n```text\nfrom fastapi import FastAPI\nimport uvicorn\nimport os\n\napp = FastAPI()\n\n\n@app.get(\"/healthcheck/\")\ndef healthcheck():\n return 'Health - OK'\n\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", port=int(os.getenv('APP_PORT')))\n```\n\n```text\nFROM python:3.8-slim\n\nWORKDIR /usr/src/app\n\nCOPY requirements.txt .\nRUN pip install -r requirements.txt\n\nCOPY . .\n\nCMD [ \"python\", \"./main.py\" ]\n```\n\n```text\nversion: '2'\n\nservices:\n internal-app:\n image: internal-app\n environment:\n APP_PORT: \"3000\"\n build:\n context: .\n dockerfile: ./Dockerfile\n restart: unless-stopped\n network_mode: host\n\n external-app:\n image: external-app\n environment:\n APP_PORT: \"8443\"\n build:\n context: .\n dockerfile: ./Dockerfile\n restart: unless-stopped\n network_mode: host\n```\n\n```text\nuvicorn\nfastapi\n```\n\n```text\ndocker-compose up -d --build\n```\n\n```text\nuvicorn.run(app, host=\"0.0.0.0\", port=int(os.getenv('PORT')))\n```\n\n```text\nIngress > service 1 > deployment 1 with port 8443 > pods\n\nInternal traffic > service 2 > deployment 2 with port 30000 > pods\n```\n\n```text\napp = FastAPI()\napp2 = FastAPI()\n```\n\n```text\nuvicorn app.main:app --reload --host 0.0.0.0 --port $PORT & uvicorn app.main:app2 --reload --host 0.0.0.0 --port $PORT_INTERNAL_APP\n```\n\n```text\nrun.sh\n```\n\n========================================\n\nComments:\n- Does your application care which port the requests are received on? In other words, could the internal requests be forwarded to port 8443 via the load balancer so your container only has to expose on port?\n- Yes, it does. The problem is the load balancer is beyond our control since AKS is shared among different teams across the organization. So we will not be controlling the ILB.\n- I will try this out and accept the answer once I validate that it works for my use-case too.\n- I will try this out and accept the answer once I validate that it works for my use-case too.\n- This is beneficial in cases when a user wants to run two different applications. Good addition!","metadata":{"transformedAt":"2026-08-18T18:32:29.101Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":20,"totalLines":228,"estimatedTokens":1314}}124{"id":"stack-66680866","source":"stackoverflow","questionId":66680866,"title":"How to enable filtering on all fields of a model in FastAPI","tags":["python","rest","fastapi"],"text":"Title: How to enable filtering on all fields of a model in FastAPI\nTags: python, rest, fastapi\nSource: Stack Overflow\n\nQuestion:\nIn Django with the restframework, you can do this:\n\n```\nclass Item(models.Model):\n id = models.IntegerField()\n name = models.CharField(max_length=32)\n another_attribute = models.CharField(max_length=32)\n ...\n (more attributes)\n ...\n yet_another_attribute = models.CharField(max_length=32)\n\nclass ItemViewSet(viewsets.ReadOnlyModelViewSet):\n permission_classes = [IsAuthenticated]\n serializer_class = ItemSerializer\n filterset_fields = '__all__' # If I want to allow filtering, `filterset_fields = '__all__'` would allow me to do something like `api/item/?(attribute)=(value)` and allow me to filter on any attribute\n\nI'm going through the tutorial (https://fastapi.tiangolo.com/tutorial/sql-databases/#crud-utils) and it looks like there is a lot of manual filtering involved:\n\n```\nfrom fastapi_sqlalchemy import db\n\nclass Item(BaseModel):\n id: int\n name: str\n another_attribute: str\n ...\n (more attributes)\n ...\n yet_another_attribute: str\n\n# is it necessary to manually include all the fields I want to filter on as optional query parameters?\n@app.get(\"/items/\")\nasync def read_item(\n db: Session,\n id: Optional[int] = None,\n name: Optional[str] = None,\n another_attribute: Optional[str] = None,\n ...\n (more attributes)\n ...\n yet_another_attribute: Optional[str] = None\n):\n # and then I'd need to check if the query parameter has been specified, and if so, filter it.\n queryset = db.session.query(Item)\n if id:\n queryset = queryset.filter(Item.id == id)\n if name:\n queryset = queryset.filter(Item.name == name)\n if another_attribute:\n queryset = queryset.filter(Item.another_attribute == another_attribute)\n ...\n (repeat above pattern for more attributes)\n ...\n if yet_another_attribute:\n queryset = queryset.filter(Item.yet_another_attribute == yet_another_attribute)\n```\n\nWhat is the preferred way of implementing the above behaviour? Are there any packages that will save me from having to do a lot of manual filtering that will give me the same behaviour as conveniently as the Django Rest Framework viewsets?\n\nOr is manually including all the fields I want to filter on as optional query parameters, then checking for each parameter and then filtering if present the only way?\n\n========================================\n\nTop Answer:\nDefinitely, it's described in the docs.\nTry this, ellipsis marking the field as required.\n\n```\nid: Optional[int] = Header(...) # Header, path or any another place\n```\n\nSee https://fastapi.tiangolo.com/tutorial/query-params-str-validations/\n\n========================================\n\nCode:\n```text\nclass Item(models.Model):\n id = models.IntegerField()\n name = models.CharField(max_length=32)\n another_attribute = models.CharField(max_length=32)\n ...\n (more attributes)\n ...\n yet_another_attribute = models.CharField(max_length=32)\n\nclass ItemViewSet(viewsets.ReadOnlyModelViewSet):\n permission_classes = [IsAuthenticated]\n serializer_class = ItemSerializer\n filterset_fields = '__all__' # <- this enables filtering on all fields\n queryset = Item.objects.all()\n```\n\n```text\nfrom fastapi_sqlalchemy import db\n\nclass Item(BaseModel):\n id: int\n name: str\n another_attribute: str\n ...\n (more attributes)\n ...\n yet_another_attribute: str\n\n# is it necessary to manually include all the fields I want to filter on as optional query parameters?\n@app.get(\"/items/\")\nasync def read_item(\n db: Session,\n id: Optional[int] = None,\n name: Optional[str] = None,\n another_attribute: Optional[str] = None,\n ...\n (more attributes)\n ...\n yet_another_attribute: Optional[str] = None\n):\n # and then I'd need to check if the query parameter has been specified, and if so, filter it.\n queryset = db.session.query(Item)\n if id:\n queryset = queryset.filter(Item.id == id)\n if name:\n queryset = queryset.filter(Item.name == name)\n if another_attribute:\n queryset = queryset.filter(Item.another_attribute == another_attribute)\n ...\n (repeat above pattern for more attributes)\n ...\n if yet_another_attribute:\n queryset = queryset.filter(Item.yet_another_attribute == yet_another_attribute)\n```\n\n```text\nfilterset_fields = '__all__'\n```\n\n```text\napi/item/?(attribute)=(value)\n```\n\n```text\nfrom fastapi.params import Depends\n\n@app.get(\"/items/\")\nasync def read_item(item: Item = Depends()):\n pass\n```\n\n```text\n@app.get(\"/items/\")\nasync def read_item(\n db: Session,\n id: Optional[int] = None,\n name: Optional[str] = None,\n another_attribute: Optional[str] = None,\n ...\n (more attributes)\n ...\n yet_another_attribute: Optional[str] = None\n):\n params = locals().copy()\n ...\n for attr in [x for x in params if params[x] is not None]:\n query = query.filter(getattr(db_model.Item, attr).like(params[attr]))\n```\n\n```text\nid: Optional[int] = Header(...) # Header, path or any another place\n```\n\n========================================\n\nComments:\n- thanks, so it looks like I'd still need to add the above line (`(attribute) = Optional(type) = Query(None)` for every attribute invidaually. Is there a way to automatically set a query parameter for each attribute of the model?\n- @AG Yes, use schemas as input input fastapi.tiangolo.com/tutorial/response-model\n- The response model determines what gets returned, but I want to know if there is an easy way to filter on all attributes without manually adding it for each attribute\n- @AG Зlease read furtherю You can also use the same model (or another) as input: fastapi.tiangolo.com/tutorial/response-model/…","metadata":{"transformedAt":"2026-08-18T18:32:29.101Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":7,"totalLines":183,"estimatedTokens":1418}}125{"id":"stack-63721614","source":"stackoverflow","questionId":63721614,"title":"Unhashable type in FastAPI request","tags":["python","fastapi","pydantic"],"text":"Title: Unhashable type in FastAPI request\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI am writing a post-api using fastapi. The required request-format is:\n\n```\n{\n \"leadid\":LD123,\n \"parties\":[\n {\n \"uid\":123123,\n \"cust_name\":\"JOhn Doe\",\n }, ...]}\n```\n\nThe fastapi code in python is:\n\n```\nclass Customer(BaseModel):\n UID: str\n CustName: str\n\nclass PackageIn(BaseModel): \n lead_id: str\n parties: Set[Customer]\n # threshold: Optional[int] = 85\n\napp = FastAPI()\n\n@app.post('/')\nasync def nm_v2(package:PackageIn):\n return {\"resp\":\"Response\"}\n```\n\nWhen I visit the SwaggerUI to submit the response, the error is **\"422 Error: Unprocessable Entity\"**. Also, the SwaggerUI doc states\n\n```\n{\n \"detail\": [\n {\n \"loc\": [\n \"body\"\n ],\n \"msg\": \"unhashable type: 'Customer'\",\n \"type\": \"type_error\"\n }\n ]\n}\n```\n\nI do not know how to create this dict() structure for request payload without creating a separate pydantic based class called Customer. Pl tell me how to rectify the error.\n\n========================================\n\nTop Answer:\nafter\nhttps://github.com/pydantic/pydantic/pull/1881\nyou can add `frozen = True` to make yor object hashable (note instances will not be allowed to mutate)\n\n```\nclass Customer(BaseModel):\n UID: str\n CustName: str\n\n class Config:\n frozen = True\n```\n\n========================================\n\nCode:\n```text\n{\n \"leadid\":LD123,\n \"parties\":[\n {\n \"uid\":123123,\n \"cust_name\":\"JOhn Doe\",\n }, ...]}\n```\n\n```text\nclass Customer(BaseModel):\n UID: str\n CustName: str\n\nclass PackageIn(BaseModel): \n lead_id: str\n parties: Set[Customer]\n # threshold: Optional[int] = 85\n\napp = FastAPI()\n\n@app.post('/')\nasync def nm_v2(package:PackageIn):\n return {\"resp\":\"Response\"}\n```\n\n```text\n{\n \"detail\": [\n {\n \"loc\": [\n \"body\"\n ],\n \"msg\": \"unhashable type: 'Customer'\",\n \"type\": \"type_error\"\n }\n ]\n}\n```\n\n```py\nfrom pydantic import BaseModel\nfrom typing import Set\n\n\nclass MyBaseModel(BaseModel):\n def __hash__(self): # make hashable BaseModel subclass\n return hash((type(self),) + tuple(self.__dict__.values()))\n\n\nclass Customer(MyBaseModel): # Use hashable sublclass for your model\n UID: str\n CustName: str\n\n\nclass PackageIn(BaseModel):\n lead_id: str\n parties: Set[Customer]\n # threshold: Optional[int] = 85\n\ndata = {\n \"lead_id\": 'LD123',\n \"parties\": [\n {\n \"UID\": 123123,\n \"CustName\": \"JOhn Doe\",\n }]}\n\nPackageIn.parse_obj(data) # This part fastapi will make on post request, just for test\n\n> <PackageIn lead_id='LD123' parties={<Customer UID='123123' CustName='JOhn Doe'>}>\n```\n\n```text\nclass Customer(BaseModel):\n UID: str\n CustName: str\n\n class Config:\n frozen = True\n```\n\n```text\nfrozen = True\n```\n\n========================================\n\nComments:\n- `parties` is supposed to be a `list` of customers. You've defined it as a `set` of customers. Also, the names for the Customer attributes are wrong. `UID` != `uid`, uness case insensitive and `CustName` != `cust_name` unless it's doing translation. And `uid` should be an `int`, not a `str`.\n- The problem is with the `Set[Customer]`, normally pydantic model is not hashable so set is not able to check if given item already is in the collection.\n- Also, the value of leadid doesn't seem to be a string. It may cause problems. I suggest to wrap it into double quotes \", since the request will be in plain JSON, converted into python and then into a pydantic model. Though it may not be the root cause of the problem, just a suggestion\n- This is the answer I like most.\n- After switching from BaseModel to BaseSettings this becomes: class Customer(BaseModel): model_config = SettingsConfigDict(frozen=True) UID: str CustName: str","metadata":{"transformedAt":"2026-08-18T18:32:29.102Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":6,"totalLines":168,"estimatedTokens":943}}126{"id":"stack-58379889","source":"stackoverflow","questionId":58379889,"title":"FastAPI not behaving asynchronously","tags":["python-3.x","fastapi"],"text":"Title: FastAPI not behaving asynchronously\nTags: python-3.x, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm probably not understanding the asynchronous concept correctly in FastAPI.\n\nI'm accessing the root endpoint of the following app from two clients at the same time. I'd expect FastAPI to print `Started` twice in a row at the start of the execution:\n\n```\nfrom fastapi import FastAPI\nimport asyncio\n\napp = FastAPI()\n\n@app.get(\"/\")\nasync def read_root():\n print('Started')\n await asyncio.sleep(5)\n print('Finished')\n return {\"Hello\": \"World\"}\n```\n\nInstead I get the following, which looks very much non asynchronous:\n\n```\nStarted\nFinished\nINFO: ('127.0.0.1', 49655) - \"GET / HTTP/1.1\" 200\nStarted\nFinished\nINFO: ('127.0.0.1', 49655) - \"GET / HTTP/1.1\" 200\n```\n\nWhat am I missing?\n\n========================================\n\nTop Answer:\nI did the same experiment with Chrome browser and the result was the same as what was originally reported. The requests from two separate Chrome browsers were processed one after another (as if in serial).\n\n```\n@app.get(\"/test\")\nasync def test():\n r = {\"message\": \"Hello by /test api\"}\n r['timestamp'] = datetime.datetime.utcnow()\n await asyncio.sleep(10)\n return r\n```\n\n2 requests took 20 seconds (10 secs each) to finish whole process and this is obviously not a concurrent way!\n\nHowever, when I tried with `curl` as suggested in the answer, it was processed in parallel (!)\n\nI did the last experiment with 2 Firefox browsers and the result was also parallel execution.\n\nAnd finally, I was able to find the clue from the logs of FastAPI.\nWhen I try with 2 Chrome browsers, the source of the request (ip:port) were recorded identical\n\n```\nINFO: 10.10.62.106:54668 - \"GET /test HTTP/1.1\" 200 OK\nINFO: 10.10.62.106:54668 - \"GET /test HTTP/1.1\" 200 OK\n```\n\nHowever, if I try with Firefox, the source were different.\n\n```\nINFO: 10.10.62.106:54746 - \"GET /test HTTP/1.1\" 200 OK\nINFO: 10.10.62.106:54748 - \"GET /test HTTP/1.1\" 200 OK\n```\n\nFrom the log above, I can conclude that FastAPI (or uvicorn in front) handles requests only in parallel when the source address is different.\n\nPlease someone add comments on the above conclusion.\nThanks.\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nimport asyncio\n\napp = FastAPI()\n\n@app.get(\"/\")\nasync def read_root():\n print('Started')\n await asyncio.sleep(5)\n print('Finished')\n return {\"Hello\": \"World\"}\n```\n\n```text\nStarted\nFinished\nINFO: ('127.0.0.1', 49655) - \"GET / HTTP/1.1\" 200\nStarted\nFinished\nINFO: ('127.0.0.1', 49655) - \"GET / HTTP/1.1\" 200\n```\n\n```text\nStarted\n```\n\n```text\nfor n in {1..5}; do curl http://localhost:8000/ & ; done\n```\n\n```text\nasync def started():\n print(\"Started\")\n\n@app.get(\"/\")\nasync def read_root():\n await started()\n await asyncio.sleep(5)\n print('Finished')\n return {\"Hello\": \"World\"}\n```\n\n```text\n@app.get(\"/test\")\nasync def test():\n r = {\"message\": \"Hello by /test api\"}\n r['timestamp'] = datetime.datetime.utcnow()\n await asyncio.sleep(10)\n return r\n```\n\n```text\nINFO: 10.10.62.106:54668 - \"GET /test HTTP/1.1\" 200 OK\nINFO: 10.10.62.106:54668 - \"GET /test HTTP/1.1\" 200 OK\n```\n\n```text\nINFO: 10.10.62.106:54746 - \"GET /test HTTP/1.1\" 200 OK\nINFO: 10.10.62.106:54748 - \"GET /test HTTP/1.1\" 200 OK\n```\n\n```text\ncurl\n```\n\n========================================\n\nComments:\n- \" I'd expect FastAPI to print Started twice\". It is printed twice!\n- Good point, I edited the question to make it clearer\n- you think they are supposed to run on separate threads right but its not , imagine why ? You havent defined any asgi server , to maintain seprate threads , you shouuld use either uvicorn and for bigger app combine it with gunicorn\n- Ok I don't really understand why it would do it. FastApi is supposed to run every request in a separate Thread when using normal `def` functions. However from Chrome when open two tabs to run the same url it waits for one to finish and then executes another. It does not do that if I open two endpoints in two chrome tabs\n- @nilan-saha you need gunicorn/uvirocn\n- Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.\n- While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review","metadata":{"transformedAt":"2026-08-18T18:32:29.102Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":9,"totalLines":155,"estimatedTokens":1150}}127{"id":"stack-60089947","source":"stackoverflow","questionId":60089947,"title":"Creating Pydantic Model Schema with Dynamic Key","tags":["python","fastapi","pydantic"],"text":"Title: Creating Pydantic Model Schema with Dynamic Key\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI'm trying to implement Pydantic Schema Models for the following JSON.\n\n```\n{\n \"description\": \"Best Authors And Their Books\",\n \"authorInfo\":\n {\n \"KISHAN\":\n {\n \"numberOfBooks\": 10,\n \"bestBookIds\": [0, 2, 3, 7]\n },\n \"BALARAM\":\n {\n \"numberOfBooks\": 15,\n \"bestBookIds\": [10, 12, 14]\n },\n \"RAM\":\n {\n \"numberOfBooks\": 6,\n \"bestBookIds\": [3,5]\n\n }\n }\n}\n```\n\nHere are the schema objects in Pydantic\n\n```\nfrom typing import List, Type, Dict\nfrom pydantic import BaseModel\n\nclass AuthorBookDetails(BaseModel):\n numberOfBooks: int\n bestBookIds: List[int]\n\nclass AuthorInfoCreate(BaseModel):\n __root__: Dict[str, Type[AuthorBookDetails]] \n#pass\n\nclass ScreenCreate(BaseModel):\n description: str\n authorInfo: Type[AuthorInfoCreate]\n```\n\nI'm parsing the AuthorInfoCreate as follows:\n\n```\ny = AuthorBookDetails( numberOfBooks = 10, bestBookIds = [3,5])\nprint(y)\nprint(type(y))\n\nx = AuthorInfoCreate.parse_obj({\"RAM\" : y})\nprint(x)\n```\n\nI see the following error.\n\n```\nnumberOfBooks=10 bestBookIds=[3, 5]\n\nTraceback (most recent call last):\n\n File \"test.py\", line 44, in \n\n x = AuthorInfoCreate.parse_obj({\"RAM\": y})\n\n File \"C:\\sources\\rep-funds\\env\\lib\\site-packages\\pydantic\\main.py\", line 402, in parse_obj\n\n return cls(**obj)\n\n File \"C:\\sources\\rep-funds\\env\\lib\\site-packages\\pydantic\\main.py\", line 283, in __init__\n\n raise validation_error\n\npydantic.error_wrappers.ValidationError: 1 validation error for AuthorInfoCreate\n\n__root__ -> RAM\n\n subclass of AuthorBookDetails expected (type=type_error.subclass; expected_class=AuthorBookDetails)\n```\n\nI want to understand how can I change AuthorInfoCreate so that I have the json schema mentioned.\n\n========================================\n\nTop Answer:\nFor those with how to Initialize Pydantic classes, with the answer given by @SKhalymon,\n\n```\nfrom typing import List, Dict\nfrom pydantic import BaseModel\n\nclass AuthorBookDetails(BaseModel):\n numberOfBooks: int\n bestBookIds: List[int]\n\nclass AuthorInfoCreate(BaseModel):\n __root__: Dict[str, AuthorBookDetails]\n\nclass ScreenCreate(BaseModel):\n description: str\n authorInfo: AuthorInfoCreate\n\nkishan = AuthorBookDetails( numberOfBooks = 10, bestBookIds = [0, 2, 3, 7])\n\nbalram = AuthorBookDetails( numberOfBooks = 15, bestBookIds = [10, 12, 14])\n\nram = AuthorBookDetails( numberOfBooks = 6, bestBookIds = [3, 5])\n\naic = AuthorInfoCreate(__root__={\"KISHAN\": kishan, \"BALRAM\": balram, \"RAM\": ram})\n\nsc = ScreenCreate( description = \"Best Authors And Their Books\", authorInfo = aic)\n\nprint(sc.json())\n```\n\nOutput:\n\n```\n{\"description\": \"Best Authors And Their Books\", \"authorInfo\": {\"__root__\": {\"KISHAN\": {\"numberOfBooks\": 10, \"bestBookIds\": [0, 2, 3, 7]}, \"BALRAM\": {\"numberOfBooks\": 15, \"bestBookIds\": [10, 12, 14]}, \"RAM\": {\"numberOfBooks\": 6, \"bestBookIds\": [3, 5]}}}}\n```\n\n========================================\n\nCode:\n```text\n{\n \"description\": \"Best Authors And Their Books\",\n \"authorInfo\":\n {\n \"KISHAN\":\n {\n \"numberOfBooks\": 10,\n \"bestBookIds\": [0, 2, 3, 7]\n },\n \"BALARAM\":\n {\n \"numberOfBooks\": 15,\n \"bestBookIds\": [10, 12, 14]\n },\n \"RAM\":\n {\n \"numberOfBooks\": 6,\n \"bestBookIds\": [3,5]\n\n }\n }\n}\n```\n\n```text\nfrom typing import List, Type, Dict\nfrom pydantic import BaseModel\n\nclass AuthorBookDetails(BaseModel):\n numberOfBooks: int\n bestBookIds: List[int]\n\nclass AuthorInfoCreate(BaseModel):\n __root__: Dict[str, Type[AuthorBookDetails]] \n#pass\n\nclass ScreenCreate(BaseModel):\n description: str\n authorInfo: Type[AuthorInfoCreate]\n```\n\n```text\ny = AuthorBookDetails( numberOfBooks = 10, bestBookIds = [3,5])\nprint(y)\nprint(type(y))\n\nx = AuthorInfoCreate.parse_obj({\"RAM\" : y})\nprint(x)\n```\n\n```text\nnumberOfBooks=10 bestBookIds=[3, 5]\n\n<class '__main__.AuthorBookDetails'>\n\nTraceback (most recent call last):\n\n File \"test.py\", line 44, in <module>\n\n x = AuthorInfoCreate.parse_obj({\"RAM\": y})\n\n File \"C:\\sources\\rep-funds\\env\\lib\\site-packages\\pydantic\\main.py\", line 402, in parse_obj\n\n return cls(**obj)\n\n File \"C:\\sources\\rep-funds\\env\\lib\\site-packages\\pydantic\\main.py\", line 283, in __init__\n\n raise validation_error\n\npydantic.error_wrappers.ValidationError: 1 validation error for AuthorInfoCreate\n\n__root__ -> RAM\n\n subclass of AuthorBookDetails expected (type=type_error.subclass; expected_class=AuthorBookDetails)\n```\n\n```py\nfrom typing import List,Dict\nfrom pydantic import BaseModel\n\nclass AuthorBookDetails(BaseModel):\n numberOfBooks: int\n bestBookIds: List[int]\n\nclass AuthorInfoCreate(BaseModel):\n __root__: Dict[str, AuthorBookDetails]\n\nclass ScreenCreate(BaseModel):\n description: str\n authorInfo: AuthorInfoCreate\n```\n\n```py\nfrom typing import List, Dict\nfrom pydantic import BaseModel\n\nclass AuthorBookDetails(BaseModel):\n numberOfBooks: int\n bestBookIds: List[int]\n\nclass AuthorInfoCreate(BaseModel):\n __root__: Dict[str, AuthorBookDetails]\n\nclass ScreenCreate(BaseModel):\n description: str\n authorInfo: AuthorInfoCreate\n\n\n\nkishan = AuthorBookDetails( numberOfBooks = 10, bestBookIds = [0, 2, 3, 7])\n\nbalram = AuthorBookDetails( numberOfBooks = 15, bestBookIds = [10, 12, 14])\n\nram = AuthorBookDetails( numberOfBooks = 6, bestBookIds = [3, 5])\n\naic = AuthorInfoCreate(__root__={\"KISHAN\": kishan, \"BALRAM\": balram, \"RAM\": ram})\n\nsc = ScreenCreate( description = \"Best Authors And Their Books\", authorInfo = aic)\n\nprint(sc.json())\n```\n\n```text\n{\"description\": \"Best Authors And Their Books\", \"authorInfo\": {\"__root__\": {\"KISHAN\": {\"numberOfBooks\": 10, \"bestBookIds\": [0, 2, 3, 7]}, \"BALRAM\": {\"numberOfBooks\": 15, \"bestBookIds\": [10, 12, 14]}, \"RAM\": {\"numberOfBooks\": 6, \"bestBookIds\": [3, 5]}}}}\n```\n\n```text\nclass AuthorInfoCreate(BaseModel):\n __root__: Dict[str, AuthorBookDetails]\n```\n\n```text\nfrom typing import Any, Dict, List\n\nfrom pydantic import BaseModel as PydanticBaseModel\nfrom pydantic.utils import ROOT_KEY\n\n\nclass BaseModel(PydanticBaseModel):\n def __init__(__pydantic_self__, **data: Any) -> None:\n if __pydantic_self__.__custom_root_type__ and data.keys() != {ROOT_KEY}:\n data = {ROOT_KEY: data}\n super().__init__(**data)\n\n...\n...\n```\n\n```text\naic = AuthorInfoCreate(**{\"KISHAN\": kishan, \"BALRAM\": balram, \"RAM\": ram})\n```\n\n```text\n__root__\n```\n\n```text\nAuthorInfoCreate\n```\n\n```text\nfrom typing import List, Dict, Union\nfrom pydantic import BaseModel, RootModel\n\nclass AuthorBookDetails(BaseModel):\n numberOfBooks: int\n bestBookIds: List[int]\n\nclass AuthorInfoCreate(RootModel[Dict[str, Dict]]):\n root: Dict[str, AuthorBookDetails]\n\nclass ScreenCreate(BaseModel):\n description: str\n authorInfo: AuthorInfoCreate\n```\n\n========================================\n\nComments:\n- the unhashable type error is due to trying to create a set from a duct, nothing to do with pydantic.\n- I changed my question to see what exactly I was looking for. I want to understand how can I change AuthorInfoCreate so that I have the json schema mentioned.\n- @navule did you find the solution?\n- @SKhalymon not yet. May be I need to try with latest Pydantic documentation for and clue.\n- What If I want multiple dynamic key one using AuthorBookDetails as base model and once lets say AuthorDetails. I don't think we can bind both models to **root**, what would you do In that scenario\n- @Callmeashish I don't know how to do it with Pydantic, but you could check trafaret.readthedocs.io/en/latest/intro.html which allows doing much more than Pydantic in terms of validation.\n- Just want to point out that in the newer version fo Pydantic this will NOT work. You must now define a RootModel like below to handle dynamic keys. `__root__` will not work. ``` class SomeRootModel(RootModel): root: Dict[str, SomeSubDictModel]```","metadata":{"transformedAt":"2026-08-18T18:32:29.102Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":13,"totalLines":319,"estimatedTokens":1980}}128{"id":"stack-62894952","source":"stackoverflow","questionId":62894952,"title":"FastAPI gunicorn uvicorn access_log format customization","tags":["gunicorn","fastapi"],"text":"Title: FastAPI gunicorn uvicorn access_log format customization\nTags: gunicorn, fastapi\nSource: Stack Overflow\n\nQuestion:\nWe are using the https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker FastAPI and were able to customize our logging with a gunicorn logging file.\n\nHowever, we are not able to change the details of the %(message)s attribute as defined in the documentation access log - https://docs.gunicorn.org/en/stable/settings.html#accesslog.\n\nWe receive an error posted below, that the keys are unknown.\nA similar question has been asked before and received many upvotes.\ngunicorn log-config access_log_format\n\nWhat are we doing wrong?\n\n```\n#start.sh\n# Start Gunicorn\nexec gunicorn -k uvicorn.workers.UvicornWorker -c \"$GUNICORN_CONF\" \"$APP_MODULE\" --log-config \"/logging.conf\"\n```\n\n```\n[loggers]\nkeys=root, gunicorn.error, gunicorn.access,uvicorn.error,uvicorn.access\n\n[handlers]\nkeys=console, error_file, access_file, access_filegunicorn\n\n[formatters]\nkeys=generic, access, accessgunicorn\n\n[logger_root]\nlevel=INFO\nhandlers=console\npropagate=1\n\n[logger_gunicorn.error]\nlevel=INFO\nhandlers=error_file\npropagate=0\nqualname=gunicorn.error\n\n[logger_gunicorn.access]\nlevel=INFO\nhandlers=access_filegunicorn\npropagate=0\nqualname=gunicorn.access\n\n[logger_uvicorn.error]\nlevel=INFO\nhandlers=error_file\npropagate=0\nqualname=uvicorn.error\n\n[logger_uvicorn.access]\nlevel=INFO\nhandlers=access_file\npropagate=0\nqualname=uvicorn.access\n\n[handler_console]\nclass=StreamHandler\nformatter=generic\nargs=(sys.stdout, )\n\n[handler_error_file]\nclass=StreamHandler\nformatter=generic\nargs=(sys.stdout, )\n\n[handler_access_file]\nclass=StreamHandler\nformatter=access\nargs=(sys.stdout, )\n\n[handler_access_filegunicorn]\nclass=StreamHandler\nformatter=accessgunicorn\nargs=(sys.stdout, )\n\n[formatter_generic]\nformat=[%(levelname)s]: %(message)s\ndatefmt=%Y-%m-%dT%H:%M:%S\nclass=logging.Formatter\n\n[formatter_access]\nformat=[%(levelname)s]: %(message)s\ndatefmt=%Y-%m-%dT%H:%M:%S\nclass=logging.Formatter\n\n[formatter_accessgunicorn]\nformat=[%(levelname)s]: '{\"remote_ip\":\"%(h)s\",\"session_id\":\"%({X-Session-Id}i)s\",\"status\":\"%(s)s\",\"request_method\":\"%(m)s\",\"request_path\":\"%(U)s\",\"request_querystring\":\"%(q)s\",\"request_timetaken\":\"%(D)s\",\"response_length\":\"%(B)s\", \"remote_addr\": \"%(h)s\"}'\ndatefmt=%Y-%m-%dT%H:%M:%S\nclass=logging.Formatter\n```\n\n```\nMessage: '%s - \"%s %s HTTP/%s\" %d'\nArguments: ('213.3.14.24:53374', 'GET', '/v1/docs', '1.1', 200)\n--- Logging error ---\nTraceback (most recent call last):\n File \"/usr/local/lib/python3.7/logging/__init__.py\", line 1025, in emit\n msg = self.format(record)\n File \"/usr/local/lib/python3.7/logging/__init__.py\", line 869, in format\n return fmt.format(record)\n File \"/usr/local/lib/python3.7/logging/__init__.py\", line 611, in format\n s = self.formatMessage(record)\n File \"/usr/local/lib/python3.7/logging/__init__.py\", line 580, in formatMessage\n return self._style.format(record)\n File \"/usr/local/lib/python3.7/logging/__init__.py\", line 422, in format\n return self._fmt % record.__dict__\nKeyError: 'h'\nCall stack:\n File \"/usr/local/bin/gunicorn\", line 8, in \n sys.exit(run())\n File \"/usr/local/lib/python3.7/site-packages/gunicorn/app/wsgiapp.py\", line 58, in run\n WSGIApplication(\"%(prog)s [OPTIONS] [APP_MODULE]\").run()\n File \"/usr/local/lib/python3.7/site-packages/gunicorn/app/base.py\", line 228, in run\n super().run()\n File \"/usr/local/lib/python3.7/site-packages/gunicorn/app/base.py\", line 72, in run\n Arbiter(self).run()\n File \"/usr/local/lib/python3.7/site-packages/gunicorn/arbiter.py\", line 202, in run\n self.manage_workers()\n File \"/usr/local/lib/python3.7/site-packages/gunicorn/arbiter.py\", line 545, in manage_workers\n self.spawn_workers()\n File \"/usr/local/lib/python3.7/site-packages/gunicorn/arbiter.py\", line 616, in spawn_workers\n self.spawn_worker()\n File \"/usr/local/lib/python3.7/site-packages/gunicorn/arbiter.py\", line 583, in spawn_worker\n worker.init_process()\n File \"/usr/local/lib/python3.7/site-packages/uvicorn/workers.py\", line 61, in init_process\n super(UvicornWorker, self).init_process()\n File \"/usr/local/lib/python3.7/site-packages/gunicorn/workers/base.py\", line 140, in init_process\n self.run()\n File \"/usr/local/lib/python3.7/site-packages/uvicorn/workers.py\", line 70, in run\n loop.run_until_complete(server.serve(sockets=self.sockets))\n File \"/usr/local/lib/python3.7/site-packages/uvicorn/protocols/http/httptools_impl.py\", line 385, in run_asgi\n result = await app(self.scope, self.receive, self.send)\n File \"/usr/local/lib/python3.7/site-packages/uvicorn/middleware/proxy_headers.py\", line 45, in __call__\n return await self.app(scope, receive, send)\n File \"/usr/local/lib/python3.7/site-packages/fastapi/applications.py\", line 171, in __call__\n await super().__call__(scope, receive, send)\n File \"/usr/local/lib/python3.7/site-packages/starlette/applications.py\", line 102, in __call__\n await self.middleware_stack(scope, receive, send)\n File \"/usr/local/lib/python3.7/site-packages/starlette/middleware/errors.py\", line 159, in __call__\n await self.app(scope, receive, _send)\n File \"/usr/local/lib/python3.7/site-packages/starlette/middleware/cors.py\", line 78, in __call__\n await self.app(scope, receive, send)\n File \"/usr/local/lib/python3.7/site-packages/starlette/exceptions.py\", line 71, in __call__\n await self.app(scope, receive, sender)\n File \"/usr/local/lib/python3.7/site-packages/starlette/routing.py\", line 550, in __call__\n await route.handle(scope, receive, send)\n```\n\n========================================\n\nTop Answer:\nI found very useful information here https://github.com/tiangolo/fastapi/issues/1508\n\nI needed to add the request datetime , and the solution that I implemented was:\n\n```\n@app.on_event(\"startup\")\nasync def startup_event():\n logger = logging.getLogger(\"uvicorn.access\")\n console_formatter = uvicorn.logging.ColourizedFormatter(\n \"{asctime} {levelprefix} : {message}\",\n style=\"{\", use_colors=True)\n logger.handlers[0].setFormatter(console_formatter)\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n```\n\n========================================\n\nCode:\n```text\n#start.sh\n# Start Gunicorn\nexec gunicorn -k uvicorn.workers.UvicornWorker -c \"$GUNICORN_CONF\" \"$APP_MODULE\" --log-config \"/logging.conf\"\n```\n\n```text\n[loggers]\nkeys=root, gunicorn.error, gunicorn.access,uvicorn.error,uvicorn.access\n\n[handlers]\nkeys=console, error_file, access_file, access_filegunicorn\n\n[formatters]\nkeys=generic, access, accessgunicorn\n\n[logger_root]\nlevel=INFO\nhandlers=console\npropagate=1\n\n[logger_gunicorn.error]\nlevel=INFO\nhandlers=error_file\npropagate=0\nqualname=gunicorn.error\n\n[logger_gunicorn.access]\nlevel=INFO\nhandlers=access_filegunicorn\npropagate=0\nqualname=gunicorn.access\n\n[logger_uvicorn.error]\nlevel=INFO\nhandlers=error_file\npropagate=0\nqualname=uvicorn.error\n\n[logger_uvicorn.access]\nlevel=INFO\nhandlers=access_file\npropagate=0\nqualname=uvicorn.access\n\n[handler_console]\nclass=StreamHandler\nformatter=generic\nargs=(sys.stdout, )\n\n[handler_error_file]\nclass=StreamHandler\nformatter=generic\nargs=(sys.stdout, )\n\n[handler_access_file]\nclass=StreamHandler\nformatter=access\nargs=(sys.stdout, )\n\n[handler_access_filegunicorn]\nclass=StreamHandler\nformatter=accessgunicorn\nargs=(sys.stdout, )\n\n[formatter_generic]\nformat=[%(levelname)s]: %(message)s\ndatefmt=%Y-%m-%dT%H:%M:%S\nclass=logging.Formatter\n\n[formatter_access]\nformat=[%(levelname)s]: %(message)s\ndatefmt=%Y-%m-%dT%H:%M:%S\nclass=logging.Formatter\n\n[formatter_accessgunicorn]\nformat=[%(levelname)s]: '{\"remote_ip\":\"%(h)s\",\"session_id\":\"%({X-Session-Id}i)s\",\"status\":\"%(s)s\",\"request_method\":\"%(m)s\",\"request_path\":\"%(U)s\",\"request_querystring\":\"%(q)s\",\"request_timetaken\":\"%(D)s\",\"response_length\":\"%(B)s\", \"remote_addr\": \"%(h)s\"}'\ndatefmt=%Y-%m-%dT%H:%M:%S\nclass=logging.Formatter\n```\n\n```text\nMessage: '%s - \"%s %s HTTP/%s\" %d'\nArguments: ('213.3.14.24:53374', 'GET', '/v1/docs', '1.1', 200)\n--- Logging error ---\nTraceback (most recent call last):\n File \"/usr/local/lib/python3.7/logging/__init__.py\", line 1025, in emit\n msg = self.format(record)\n File \"/usr/local/lib/python3.7/logging/__init__.py\", line 869, in format\n return fmt.format(record)\n File \"/usr/local/lib/python3.7/logging/__init__.py\", line 611, in format\n s = self.formatMessage(record)\n File \"/usr/local/lib/python3.7/logging/__init__.py\", line 580, in formatMessage\n return self._style.format(record)\n File \"/usr/local/lib/python3.7/logging/__init__.py\", line 422, in format\n return self._fmt % record.__dict__\nKeyError: 'h'\nCall stack:\n File \"/usr/local/bin/gunicorn\", line 8, in <module>\n sys.exit(run())\n File \"/usr/local/lib/python3.7/site-packages/gunicorn/app/wsgiapp.py\", line 58, in run\n WSGIApplication(\"%(prog)s [OPTIONS] [APP_MODULE]\").run()\n File \"/usr/local/lib/python3.7/site-packages/gunicorn/app/base.py\", line 228, in run\n super().run()\n File \"/usr/local/lib/python3.7/site-packages/gunicorn/app/base.py\", line 72, in run\n Arbiter(self).run()\n File \"/usr/local/lib/python3.7/site-packages/gunicorn/arbiter.py\", line 202, in run\n self.manage_workers()\n File \"/usr/local/lib/python3.7/site-packages/gunicorn/arbiter.py\", line 545, in manage_workers\n self.spawn_workers()\n File \"/usr/local/lib/python3.7/site-packages/gunicorn/arbiter.py\", line 616, in spawn_workers\n self.spawn_worker()\n File \"/usr/local/lib/python3.7/site-packages/gunicorn/arbiter.py\", line 583, in spawn_worker\n worker.init_process()\n File \"/usr/local/lib/python3.7/site-packages/uvicorn/workers.py\", line 61, in init_process\n super(UvicornWorker, self).init_process()\n File \"/usr/local/lib/python3.7/site-packages/gunicorn/workers/base.py\", line 140, in init_process\n self.run()\n File \"/usr/local/lib/python3.7/site-packages/uvicorn/workers.py\", line 70, in run\n loop.run_until_complete(server.serve(sockets=self.sockets))\n File \"/usr/local/lib/python3.7/site-packages/uvicorn/protocols/http/httptools_impl.py\", line 385, in run_asgi\n result = await app(self.scope, self.receive, self.send)\n File \"/usr/local/lib/python3.7/site-packages/uvicorn/middleware/proxy_headers.py\", line 45, in __call__\n return await self.app(scope, receive, send)\n File \"/usr/local/lib/python3.7/site-packages/fastapi/applications.py\", line 171, in __call__\n await super().__call__(scope, receive, send)\n File \"/usr/local/lib/python3.7/site-packages/starlette/applications.py\", line 102, in __call__\n await self.middleware_stack(scope, receive, send)\n File \"/usr/local/lib/python3.7/site-packages/starlette/middleware/errors.py\", line 159, in __call__\n await self.app(scope, receive, _send)\n File \"/usr/local/lib/python3.7/site-packages/starlette/middleware/cors.py\", line 78, in __call__\n await self.app(scope, receive, send)\n File \"/usr/local/lib/python3.7/site-packages/starlette/exceptions.py\", line 71, in __call__\n await self.app(scope, receive, sender)\n File \"/usr/local/lib/python3.7/site-packages/starlette/routing.py\", line 550, in __call__\n await route.handle(scope, receive, send)\n```\n\n```text\n[loggers]\nkeys=root, gunicorn.error, gunicorn.access,uvicorn.error,uvicorn.access\n\n[handlers]\nkeys=console, error_file, access_file, accesscustom\n\n[formatters]\nkeys=generic, access, AccessFormatter\n\n[logger_root]\nlevel=INFO\nhandlers=console\npropagate=1\n\n[logger_gunicorn.error]\nlevel=INFO\nhandlers=error_file\npropagate=0\nqualname=gunicorn.error\n\n[logger_gunicorn.access]\nlevel=INFO\nhandlers=accesscustom\npropagate=0\nqualname=gunicorn.access\n\n[logger_uvicorn.error]\nlevel=INFO\nhandlers=error_file\npropagate=0\nqualname=uvicorn.error\n\n[logger_uvicorn.access]\nlevel=INFO\nhandlers=accesscustom\npropagate=0\nqualname=uvicorn.access\n\n[handler_console]\nclass=StreamHandler\nformatter=generic\nargs=(sys.stdout, )\n\n[handler_error_file]\nclass=StreamHandler\nformatter=generic\nargs=(sys.stdout, )\n\n[handler_access_file]\nclass=StreamHandler\nformatter=access\nargs=(sys.stdout, )\n\n[handler_accesscustom]\nclass=StreamHandler\nformatter=AccessFormatter\nargs=(sys.stdout, )\n\n[formatter_generic]\nformat=%(levelname)s: %(message)s\ndatefmt=%Y-%m-%dT%H:%M:%S\nclass=uvicorn.logging.DefaultFormatter\n\n[formatter_access]\nformat=%(levelname)s: %(message)s\ndatefmt=%Y-%m-%dT%H:%M:%S\nclass=customlogger.CustomFormatter\n\n[formatter_AccessFormatter]\nformat={\"event\":\"access_log\",\"ip\":\"%(h)s\",\"status\":\"%(s)s\",\"method\":\"%(m)s\",\"path\":\"%(U)s\",\"referer\":\"%(f)s\",\"x_session_id\":\"%(x-session-id)s\",\"x_google_id\":\"%(x-google-id)s\",\"x_server_time\":\"%(x-server-time)s\",\"agent\":\"%(a)s\"}\ndatefmt=%Y-%m-%dT%H:%M:%S\nclass=customlogger.CustomFormatter\n```\n\n```py\nimport base64\nimport binascii\nimport http\nimport logging\nimport os\nimport sys\nimport time\nfrom copy import copy\nfrom datetime import datetime\nfrom pprint import pprint\nimport click\n\nTRACE_LOG_LEVEL = 5\n\n\nclass ColourizedFormatter(logging.Formatter):\n \"\"\"\n A custom log formatter class that:\n * Outputs the LOG_LEVEL with an appropriate color.\n * If a log call includes an `extras={\"color_message\": ...}` it will be used\n for formatting the output, instead of the plain text message.\n \"\"\"\n\n level_name_colors = {\n TRACE_LOG_LEVEL: lambda level_name: click.style(str(level_name), fg=\"blue\"),\n logging.DEBUG: lambda level_name: click.style(str(level_name), fg=\"cyan\"),\n logging.INFO: lambda level_name: click.style(str(level_name), fg=\"green\"),\n logging.WARNING: lambda level_name: click.style(str(level_name), fg=\"yellow\"),\n logging.ERROR: lambda level_name: click.style(str(level_name), fg=\"red\"),\n logging.CRITICAL: lambda level_name: click.style(\n str(level_name), fg=\"bright_red\"\n ),\n }\n\n def __init__(self, fmt=None, datefmt=None, style=\"%\", use_colors=None):\n if use_colors in (True, False):\n self.use_colors = use_colors\n else:\n self.use_colors = sys.stdout.isatty()\n super().__init__(fmt=fmt, datefmt=datefmt, style=style)\n\n def color_level_name(self, level_name, level_no):\n default = lambda level_name: str(level_name)\n func = self.level_name_colors.get(level_no, default)\n return func(level_name)\n\n def should_use_colors(self):\n return True\n\n def formatMessage(self, record):\n recordcopy = copy(record)\n levelname = recordcopy.levelname\n seperator = \" \" * (8 - len(recordcopy.levelname))\n if self.use_colors:\n levelname = self.color_level_name(levelname, recordcopy.levelno)\n if \"color_message\" in recordcopy.__dict__:\n recordcopy.msg = recordcopy.__dict__[\"color_message\"]\n recordcopy.__dict__[\"message\"] = recordcopy.getMessage()\n recordcopy.__dict__[\"levelprefix\"] = levelname + \":\" + seperator\n return super().formatMessage(recordcopy)\n\n\nclass DefaultFormatter(ColourizedFormatter):\n def should_use_colors(self):\n return sys.stderr.isatty()\n\n\nclass AccessFormatter(ColourizedFormatter):\n status_code_colours = {\n 1: lambda code: click.style(str(code), fg=\"bright_white\"),\n 2: lambda code: click.style(str(code), fg=\"green\"),\n 3: lambda code: click.style(str(code), fg=\"yellow\"),\n 4: lambda code: click.style(str(code), fg=\"red\"),\n 5: lambda code: click.style(str(code), fg=\"bright_red\"),\n }\n\n def get_client_addr(self, scope):\n client = scope.get(\"client\")\n if not client:\n return \"\"\n return \"%s:%d\" % (client[0], client[1])\n\n def get_path(self, scope):\n return scope.get(\"root_path\", \"\") + scope[\"path\"]\n\n def get_full_path(self, scope):\n path = scope.get(\"root_path\", \"\") + scope[\"path\"]\n query_string = scope.get(\"query_string\", b\"\").decode(\"ascii\")\n if query_string:\n return path + \"?\" + query_string\n return path\n\n def get_status_code(self, record):\n status_code = record.__dict__[\"status_code\"]\n try:\n status_phrase = http.HTTPStatus(status_code).phrase\n except ValueError:\n status_phrase = \"\"\n status_and_phrase = \"%s %s\" % (status_code, status_phrase)\n\n if self.use_colors:\n default = lambda code: status_and_phrase\n func = self.status_code_colours.get(status_code // 100, default)\n return func(status_and_phrase)\n return status_and_phrase\n\n def formatMessage(self, record):\n recordcopy = copy(record)\n scope = recordcopy.__dict__[\"scope\"]\n method = scope[\"method\"]\n path = self.get_path(scope)\n full_path = self.get_full_path(scope)\n client_addr = self.get_client_addr(scope)\n status_code = self.get_status_code(recordcopy)\n http_version = scope[\"http_version\"]\n request_line = \"%s %s HTTP/%s\" % (method, full_path, http_version)\n if self.use_colors:\n request_line = click.style(request_line, bold=True)\n recordcopy.__dict__.update(\n {\n \"method\": method,\n \"path\": path,\n \"full_path\": full_path,\n \"client_addr\": client_addr,\n \"request_line\": request_line,\n \"status_code\": status_code,\n \"http_version\": http_version,\n }\n )\n return super().formatMessage(recordcopy)\n\n\nclass SafeAtoms(dict):\n\n def __init__(self, atoms):\n dict.__init__(self)\n for key, value in atoms.items():\n if isinstance(value, str):\n self[key] = value.replace('\"', '\\\\\"')\n else:\n self[key] = value\n\n def __getitem__(self, k):\n if k.startswith(\"{\"):\n kl = k.lower()\n if kl in self:\n return super().__getitem__(kl)\n else:\n return \"-\"\n if k in self:\n return super().__getitem__(k)\n else:\n return '-'\n\n\nclass CustomFormatter(AccessFormatter):\n atoms_wrapper_class = SafeAtoms\n\n def now(self):\n \"\"\" return date in Apache Common Log Format \"\"\"\n return time.strftime('[%d/%b/%Y:%H:%M:%S %z]')\n\n def _get_user(self, environ):\n user = None\n http_auth = environ.get(\"HTTP_AUTHORIZATION\")\n if http_auth and http_auth.lower().startswith('basic'):\n auth = http_auth.split(\" \", 1)\n if len(auth) == 2:\n try:\n # b64decode doesn't accept unicode in Python < 3.3\n # so we need to convert it to a byte string\n auth = base64.b64decode(auth[1].strip().encode('utf-8'))\n # b64decode returns a byte string\n auth = auth.decode('utf-8')\n auth = auth.split(\":\", 1)\n except (TypeError, binascii.Error, UnicodeDecodeError) as exc:\n self.debug(\"Couldn't get username: %s\", exc)\n return user\n if len(auth) == 2:\n user = auth[0]\n return user\n\n def atoms(self, environ, request_time, scope, statuscode, created):\n headers = dict(scope.get('headers',[('-','-')]))\n response_headers = dict(scope.get('response_headers',[('-','-')]))\n atoms = {\n 'h': scope.get(\"client\", ('-', ''))[0],\n 'l': '-',\n 's': statuscode,\n 'u': self._get_user(environ) or '-',\n 't': created,\n 'm': str(scope.get(\"method\", \"-\")),\n 'U': scope.get(\"path\", \"-\"),\n 'q': scope.get(\"query_string\", \"-\").decode(\"utf-8\"),\n 'H': str(scope.get(\"type\", \"-\")),\n 'f': headers.get(b\"referer\", b\"-\").decode(\"utf-8\"),\n 'a': headers.get(b\"user-agent\", b\"-\").decode(\"utf-8\"),\n 'x-session-id': headers.get(b\"x-session-id\", b\"-\").decode(\"utf-8\"),\n 'x-google-id': headers.get(b\"x-google-id\", b\"-\").decode(\"utf-8\"), \n 'x-server-time': response_headers.get(b\"x-server-time\", b\"\").decode(\"utf-8\"), \n 'p': \"<%s>\" % os.getpid()\n }\n\n return atoms\n\n def formatMessage(self, record):\n recordcopy = copy(record)\n scope = recordcopy.__dict__[\"scope\"]\n #pprint(vars(recordcopy))\n safe_atoms = self.atoms_wrapper_class(\n self.atoms(os.environ, datetime.now(), scope, recordcopy.status_code, recordcopy.created)\n )\n recordcopy.__dict__.update(safe_atoms)\n\n # pprint(vars(os.environ))\n return super().formatMessage(recordcopy)\n```\n\n```py\n@app.on_event(\"startup\")\nasync def startup_event():\n logger = logging.getLogger(\"uvicorn.access\")\n console_formatter = uvicorn.logging.ColourizedFormatter(\n \"{asctime} {levelprefix} : {message}\",\n style=\"{\", use_colors=True)\n logger.handlers[0].setFormatter(console_formatter)\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n```\n\n```py\n>>> from pprint import pprint\n>>> import uvicorn.config\n>>> pprint(uvicorn.config.LOGGING_CONFIG)\n\n{'disable_existing_loggers': False,\n 'formatters': {'access': {'()': 'uvicorn.logging.AccessFormatter',\n 'fmt': '%(levelprefix)s %(client_addr)s - '\n '\"%(request_line)s\" %(status_code)s'},\n 'default': {'()': 'uvicorn.logging.DefaultFormatter',\n 'fmt': '%(levelprefix)s %(message)s',\n 'use_colors': None}},\n 'handlers': {'access': {'class': 'logging.StreamHandler',\n 'formatter': 'access',\n 'stream': 'ext://sys.stdout'},\n 'default': {'class': 'logging.StreamHandler',\n 'formatter': 'default',\n 'stream': 'ext://sys.stderr'}},\n 'loggers': {'uvicorn': {'handlers': ['default'], 'level': 'INFO'},\n 'uvicorn.access': {'handlers': ['access'],\n 'level': 'INFO',\n 'propagate': False},\n 'uvicorn.error': {'level': 'INFO'}},\n 'version': 1}\n```\n\n```py\nimport logging\n\nLOGGER_NAME = \"myapp\"\n\nlog_config = {\n \"version\": 1,\n \"disable_existing_loggers\": False,\n \"formatters\": {\n 'access': {\n '()': 'uvicorn.logging.AccessFormatter',\n 'fmt': '%(levelprefix)s %(asctime)s - %(client_addr)s - \"%(request_line)s\" %(status_code)s',\n \"datefmt\": \"%Y-%m-%d %H:%M:%S\",\n \"use_colors\": True\n },\n \"default\": {\n \"()\": \"uvicorn.logging.DefaultFormatter\",\n \"fmt\": \"%(levelprefix)s %(asctime)s - %(message)s\",\n \"datefmt\": \"%Y-%m-%d %H:%M:%S\",\n \"use_colors\": True\n },\n },\n \"handlers\": {\n 'access': {\n 'class': 'logging.StreamHandler',\n 'formatter': 'access',\n 'stream': 'ext://sys.stdout'\n },\n \"default\": {\n \"formatter\": \"default\",\n \"class\": \"logging.StreamHandler\",\n \"stream\": \"ext://sys.stderr\",\n },\n },\n \"loggers\": {\n LOGGER_NAME: {\n \"handlers\": [\"default\"],\n \"level\": \"DEBUG\",\n \"propagate\": False\n },\n \"uvicorn\": {\n \"handlers\": [\"default\"],\n \"level\": \"DEBUG\",\n \"propagate\": True\n },\n 'uvicorn.access': {\n 'handlers': ['access'],\n 'level': 'INFO',\n 'propagate': False\n },\n 'uvicorn.error': {\n 'level': 'INFO',\n 'propagate': False\n }\n },\n}\n\n\ndef get_logger():\n return logging.getLogger(LOGGER_NAME)\n```\n\n```py\nlogging.config.dictConfig(log_config)\n```\n\n```py\nlogger = get_logger()\nlogger.info(\"Hello World!\")\n```\n\n```text\nmain.py\n```\n\n```text\napp = FastAPI(...)\n```\n\n========================================\n\nComments:\n- Can you explain what extra data you are trying to log?\n- its this line: format=[%(levelname)s]: '{\"remote_ip\":\"%(h)s\",\"session_id\":\"%({X-Session-Id}i)s\",\"st‌​atus\":\"%(s)s\",\"reque‌​st_method\":\"%(m)s\",\"‌​request_path\":\"%(U)s‌​\",\"request_querystri‌​ng\":\"%(q)s\",\"request‌​_timetaken\":\"%(D)s\",‌​\"response_length\":\"%‌​(B)s\", \"remote_addr\": \"%(h)s\"}' , i think its self-explanatory and follows the gunicorn doucmentation\n- @ArakkalAbu It seems that the docs.gunicorn.org/en/stable/settings.html#access-log-format setting does not work when set via --access-logformat STRING, so I tried to define it in a logging config file. However there are a lot of wrappers involved - see here github.com/aio-libs/aiohttp/issues/705\n- seems like gunicorn issue\n- @ArakkalAbu yes i also believe it is some kind of a bug. I even tried adding \"access_log_format = ...\" to the log config but this didnt help\n- Have you tried common python logger formats? instead of `gunicorn`'s? Something like `'%(asctime)s - %(message)s'` ?\n- @user670186 the `gunicorn.access` logger is only used by the Gunicorn worker classes. Uvicorn workers don't use it at all, instead they use `uvicorn.access`. So any Gunicorn config for access logging will have no effect by default. You need to configure the `uvicorn.access` logger instead, e.g. in one of the Gunicorn server hooks that runs in the worker upon startup.\n- Future readers might find this answer helpful as well.\n- Are you also using a middleware so you can give the scope?\n- This is the way! Note to the reader: you can further extend this by creating a custom Formatter class (extending logger.Formatter), implement format method how you like it and then reference your custom formatted class in this JSON.","metadata":{"transformedAt":"2026-08-18T18:32:29.102Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":12,"totalLines":739,"estimatedTokens":6394}}129{"id":"stack-70584730","source":"stackoverflow","questionId":70584730,"title":"How to use a reserved keyword in pydantic model","tags":["python","fastapi","pydantic"],"text":"Title: How to use a reserved keyword in pydantic model\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI need to create a schema but it has a column called *global*, and when I try to write this, I got an error.\n\n```\nclass User(BaseModel):\n\n id:int\n global:bool\n```\n\nI try to use another name, but gives another error when try to save in db.\n\n========================================\n\nTop Answer:\nTo add to the answer above, you can also dump/serialize your model with the correct field name by implementing a custom serializer. For example, like this\n\n```\nclass User(BaseModel):\n id: int\n global_: bool = Field(..., alias='global')\n model_config = ConfigDict(populate_by_name=True)\n\n @pyd.model_serializer(mode='wrap')\n def serializer(self, default_serializer: pyd.SerializerFunctionWrapHandler) -> Dict[str, Any]:\n serialized_self = default_serializer(self)\n serialized_self['global'] = serialized_self['_global']\n del serialized_self['_global']\n return serialized_self\n```\n\nNow `user.model_dump()` and `user.model_dump_json()` should produce the correct result.\n\n========================================\n\nCode:\n```text\nclass User(BaseModel):\n\n id:int\n global:bool\n```\n\n```text\nclass User(BaseModel):\n id: int\n global_: bool\n\n class Config:\n fields = {\n 'global_': 'global'\n }\n```\n\n```text\nclass User(BaseModel):\n id: int\n global_: bool = Field(..., alias='global')\n```\n\n```text\nuser = User(id=1, global=False)\n\n> Traceback (most recent call last):\n> (...)\n> File \"<input>\", line 1\n> User(id=1, global=False)\n> ^^^^^^\n> SyntaxError: invalid syntax\n\nuser = User(**{'id': 1, 'global': False})\n```\n\n```text\nclass User(BaseModel):\n id: int\n global_: bool = Field(..., alias='global')\n\n class Config:\n allow_population_by_field_name = True\n```\n\n```text\nclass User(BaseModel):\n id: int\n global_: bool = Field(..., alias='global')\n model_config = ConfigDict(populate_by_name=True)\n\n\nuser1 = User(**{'id': 1, 'global': False})\nuser2 = User(id=1, global_=False)\nassert user1 == user2\n```\n\n```text\nuser.dict() # for pydantic v1\nuser.model_dump() # for pydantic v2\n> {'id': 1, 'global_': False}\n```\n\n```text\nuser.dict(by_alias=True) # for pydantic v1\nuser.model_dump(by_alias=True) # for pydantic v2\n> {'id': 1, 'global': False}\n```\n\n```text\nUser(id=1, global=False)\n```\n\n```text\nallow_population_by_field_name = True\n```\n\n```text\npopulate_by_name=True\n```\n\n```text\nglobal\n```\n\n```text\nglobal_\n```\n\n```text\nclass User(BaseModel):\n id: int\n global_: bool = Field(..., alias='global')\n model_config = ConfigDict(populate_by_name=True)\n\n @pyd.model_serializer(mode='wrap')\n def serializer(self, default_serializer: pyd.SerializerFunctionWrapHandler) -> Dict[str, Any]:\n serialized_self = default_serializer(self)\n serialized_self['global'] = serialized_self['_global']\n del serialized_self['_global']\n return serialized_self\n```\n\n```text\nuser.model_dump()\n```\n\n```text\nuser.model_dump_json()\n```\n\n========================================\n\nComments:\n- `global` is a reserved keyword for a reason. Find another name.\n- Something like `is_global` would be more clear anyway. Why does it have to be called `global`? Surely there's a way to map python variable names to SQL column names without them needing to be identical.\n- Keep in mind that `global` may not be an invalid column name, but it is *syntactically* invalid in a `class` statement like this, so you would need to find another way to add the column to your model.\n- As an analogous example, something like `foo.global = 5` would be a syntax error, but `setattr(foo, \"global\", 5)` is perfectly legal.\n- i know that is a reserved keyword man (but i need to use the same name of tables column), because of that i made the question , but the solution given by mx0 work`s fine for me, thank you all guys.\n- \"Just use another name\" is rather obtuse. Sometimes we need to parse data from external sources and APIs (e.g. webhooks sent to us) and we don't have any control over their naming conventions.\n- What are the actual errors? Exact error message?\n- @Theberzi But external data sources can, or at least *should*, never dictate **how you name your class attributes** (your local variables, effectively). Any data model that requires you to store an arbitrary piece of data under a **specific** arbitrary name is broken, that's an unworkable restriction, because all languages have *some* syntax rules. Fortunately the pydantic designers provided an out that makes their (still ugly) model *slightly* less broken, by allowing adjustments to the name mapping via `Config.fields`.\n- (And Python has fewer restrictions than most languages, in this regard. Like, it's totally legal to use `property` or `id` or `list` as member names in your class, even though in theory those are all built-in commands or type names. Relatively few of Python's built-in names are restricted from being overridden if you really *want* to. The only ones that are totally off limits are the 35 keywords.)\n- I wonder, why it's not possible (not working) to use `global_` as parameter name when creating a new class with reserved keywords...\n- @machin It is possible by adding `allow_population_by_field_name = True` to `Config` class\n- @mX0 could you elaborate on the last point that you mentioned? I did not get why we need \"User(**{'id': 1, 'global': False})\" or \"user.dict(by_alias=True)\" after we actually defined our schema using one of the two methods that you explained.\n- @sara passing `global` as a named argument is impossible in Python, regardless of what your class definition is.\n- @Sara ad1. `global` is a reserved keyword *everywhere*, you can't use it that way. ad2. you need it for dumping schema with the same fields names as was the input\n- TypeError: Field.__init__() got an unexpected keyword argument 'alias'\n- @RavinderPayal That's strange; `pydantic.Field()` definitely takes an `alias` argument. Perhaps you're somehow using something named `Field` from a different package, maybe?\n- I don't remember exactly but I guess you were right about pointing this out. Putting it here just to not add to the confusion of whoever refers to this thread for help\n- TypeError: Field.__init__() got an unexpected keyword argument 'alias'","metadata":{"transformedAt":"2026-08-18T18:32:29.102Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":16,"totalLines":173,"estimatedTokens":1579}}130{"id":"stack-69673518","source":"stackoverflow","questionId":69673518,"title":"return pydantic model with field names instead of alias as fastapi response","tags":["python","fastapi","pydantic"],"text":"Title: return pydantic model with field names instead of alias as fastapi response\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI am trying to return my model with the defined field names instead of its aliases.\n\n```\nclass FooModel(BaseModel):\n foo: str = Field(..., alias=\"bar\")\n\n@app.get(\"/\") -> FooModel:\n return FooModel(**{\"bar\": \"baz\"})\n```\n\nThe response will be `{\"bar\": \"baz\"}` while I want `{\"foo\": \"baz\"}`. I know it's somewhat possible when using the `dict` method of the model, but it doesn't feel right and messes up the typing of the request handler.\n\n```\n@app.get(\"/\") -> FooModel:\n return FooModel(**{\"bar\": \"baz\"}).dict(by_alias=False)\n```\n\nI feel like it should be possible to set this in the config class, but I can't find the right option.\n\n========================================\n\nCode:\n```py\nclass FooModel(BaseModel):\n foo: str = Field(..., alias=\"bar\")\n\n@app.get(\"/\") -> FooModel:\n return FooModel(**{\"bar\": \"baz\"})\n```\n\n```py\n@app.get(\"/\") -> FooModel:\n return FooModel(**{\"bar\": \"baz\"}).dict(by_alias=False)\n```\n\n```text\n{\"bar\": \"baz\"}\n```\n\n```text\n{\"foo\": \"baz\"}\n```\n\n```text\ndict\n```\n\n```text\n@app.get(\"/model\", response_model=Model, response_model_by_alias=False)\ndef read_model():\n return Model(alias=\"Foo\")\n```\n\n```text\nresponse_model_by_alias=False\n```\n\n========================================\n\nComments:\n- Ok thanks. Do you know how to make the docs show the the same fields? At the moment they show the alias as response and as schema which isnt great.\n- I’m afraid this is impossible. According to that solution is to create another output model.\n- alright. Now thinking about and experimenting with it, Isn't your example flawed in that it will serialize and validate the data twice? Should we not just return a dict from the handler, since fastapi will take the return value and stick it into the provided model class?\n- fastapi, will check what type is returned. So it wont serialize twice. github.com/tiangolo/fastapi/blob/…","metadata":{"transformedAt":"2026-08-18T18:32:29.102Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":7,"totalLines":69,"estimatedTokens":502}}131{"id":"stack-62152885","source":"stackoverflow","questionId":62152885,"title":"pydantic BaseModel not found in Fastapi","tags":["python","python-3.x","fastapi","pydantic"],"text":"Title: pydantic BaseModel not found in Fastapi\nTags: python, python-3.x, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI have python3 3.6.9 on Kubuntu 18.04. I have installed fastapi using `pip3 install fastapi`. I'm trying to test drive the framework through its official documentation and I'm in the relational database section of its guide.\n\nIn `schemas.py`:\n\n```\nfrom typing import List\n\nfrom pydantic import BaseModel\n\nclass VerseBase(BaseModel):\n AyahText: str\n NormalText: str\n\nclass Verse(VerseBase):\n id: int\n\n class Config:\n orm_mode = True\n```\n\nVS code highlights an error in `from pydantic import BaseModel` and it tells that: `No name 'BaseModel' in module 'pydantic'`. Additionally, when I try to run `uvicorn main:app reload` I have gotten the following error:\n\n```\nFile \"./main.py\", line 6, in \n from . import crud, models, schemas\nImportError: attempted relative import with no known parent package\n```\n\nI have tried to renstall `pydantic` using `pip3` but it tells me that:\n\n```\nRequirement already satisfied: dataclasses>=0.6; python_version < \"3.7\" in ./.local/lib/python3.6/site-packages (from pydantic) (0.7)\n```\n\n========================================\n\nTop Answer:\nThis is a common problem with binary/C extensions. For further details, check here: (Pylint & C extensions)\n\nTo fix it, you need to add the following to .pylintrc file (You can add this file to your current project folder if you like)\n\n```\n[MASTER]\nextension-pkg-allow-list=pydantic\n```\n\nNote that switching to mypy (as suggested by another answer here) is *not* the right approach since pylint & mypy are two different things (the former is a *linter* while the latter is sort of a *type checker*)\n\n========================================\n\nCode:\n```text\nfrom typing import List\n\nfrom pydantic import BaseModel\n\nclass VerseBase(BaseModel):\n AyahText: str\n NormalText: str\n\nclass Verse(VerseBase):\n id: int\n\n class Config:\n orm_mode = True\n```\n\n```text\nFile \"./main.py\", line 6, in <module>\n from . import crud, models, schemas\nImportError: attempted relative import with no known parent package\n```\n\n```text\nRequirement already satisfied: dataclasses>=0.6; python_version < \"3.7\" in ./.local/lib/python3.6/site-packages (from pydantic) (0.7)\n```\n\n```text\npip3 install fastapi\n```\n\n```text\nschemas.py\n```\n\n```text\nfrom pydantic import BaseModel\n```\n\n```text\nNo name 'BaseModel' in module 'pydantic'\n```\n\n```text\nuvicorn main:app reload\n```\n\n```text\npydantic\n```\n\n```text\npip3\n```\n\n```text\n__init__.py\n```\n\n```text\nfrom app.module.main import app\n```\n\n```text\npylint\n```\n\n```text\npylint\n```\n\n```text\nmypy\n```\n\n```text\npip install mypy\n```\n\n```text\nCtrl+Shift+P\n```\n\n```text\nPython: Select Linter\n```\n\n```text\nmypy\n```\n\n```text\n[MASTER]\nextension-pkg-allow-list=pydantic\n```\n\n```text\nextension-pkg-allow-list=pydantic\n```\n\n```text\npylint --generate-rcfile > .pylintrc\n```\n\n```text\nextension-pkg-allow-list\n```\n\n```text\npydantic\n```\n\n```text\n=\n```\n\n```text\nextension-pkg-allow-list=\n```\n\n```text\n[tool.pylint.main]\nextension-pkg-allow-list = [\"pydantic\"]\n```\n\n```text\n.pylintrc\n```\n\n```text\npyproject.toml\n```\n\n========================================\n\nComments:\n- I have noticed something, when importing it from the project's root, the import works as regarded in the tutorial, but if I have tried to run it from the `myprojectRoot/db`, I have to modify the import statements\n- Without the folder structure it's not easy for me to provide an answer, but that's how python imports work (or at least I understand for your project structure)\n- And in `.pylintrc`, you can use `extension-pkg-allow-list=pydantic`, see documentation","metadata":{"transformedAt":"2026-08-18T18:32:29.102Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":29,"totalLines":194,"estimatedTokens":912}}132{"id":"stack-62705219","source":"stackoverflow","questionId":62705219,"title":"In Python's FastAPI autogenerated OpenAPI/Swagger documentation page, how can I add more error http status codes?","tags":["fastapi"],"text":"Title: In Python's FastAPI autogenerated OpenAPI/Swagger documentation page, how can I add more error http status codes?\nTags: fastapi\nSource: Stack Overflow\n\nQuestion:\nFastAPI generates automatic swagger/openapi documentation.\n\nIn the tutorial at https://fastapi.tiangolo.com/tutorial/response-status-code there's an example\n\n```\nfrom fastapi import FastAPI\napp = FastAPI()\n\n@app.post(\"/items/\", status_code=201)\nasync def create_item(name: str):\n return {\"name\": name}\n```\n\nIf you run this, the .../docs page shows two http response options:\n\nStatus Code 201 for success and Status Code 422 for Validation error\n\nThe above tutorial shows a picture of this pagehttps://i.sstatic.net/mA6nY.png)\n\nI would like to document more responde status_code descriptions in the docs, for example\ncode 403, \"Forbidden\"\n\nWhile I can run exceptions like this in code\n\n```\nraise HTTPException(status_code=403, detail=\"Forbidden\")\n```\n\nI have not found a way to describe them in the autogenerated docs.\n\nAny idea how to do that?\n\n========================================\n\nTop Answer:\nThe previous answer example shows somewhat limited information in the Swagger UI. However, the link is what you need.\nJust note that you do not `raise HTTPException` but `return JSONResponse` to get more information in the Swagger UI interface.\nHere the full example:\n\n```\nfrom fastapi import FastAPI\nfrom fastapi.responses import JSONResponse\nfrom pydantic import BaseModel\n\nclass Item(BaseModel):\n id: str\n value: str\n\nclass Message(BaseModel):\n message: str\n\napp = FastAPI()\n\n@app.get(\"/items/{item_id}\", response_model=Item, responses={404: {\"model\": Message}})\nasync def read_item(item_id: str):\n if item_id == \"foo\":\n return {\"id\": \"foo\", \"value\": \"there goes my hero\"}\n return JSONResponse(status_code=404, content={\"message\": \"Item not found\"})\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\napp = FastAPI()\n\n@app.post(\"/items/\", status_code=201)\nasync def create_item(name: str):\n return {\"name\": name}\n```\n\n```text\nraise HTTPException(status_code=403, detail=\"Forbidden\")\n```\n\n```text\nfrom pydantic import BaseModel\n# Define your models here like\nclass model200(BaseModel):\n message: str = \"\"\n \n@api.get(\"/my-route/\", responses={200: {\"response\": model200}, 404: {\"response\": model404}, 500: {\"response\": model500}})\n async def api_route():\n return \"I'm a wonderful route\"\n```\n\n```text\nfrom fastapi import FastAPI\nfrom fastapi.responses import JSONResponse\nfrom pydantic import BaseModel\n\n\nclass Item(BaseModel):\n id: str\n value: str\n\n\nclass Message(BaseModel):\n message: str\n\n\napp = FastAPI()\n\n\n@app.get(\"/items/{item_id}\", response_model=Item, responses={404: {\"model\": Message}})\nasync def read_item(item_id: str):\n if item_id == \"foo\":\n return {\"id\": \"foo\", \"value\": \"there goes my hero\"}\n return JSONResponse(status_code=404, content={\"message\": \"Item not found\"})\n```\n\n```text\nraise HTTPException\n```\n\n```text\nreturn JSONResponse\n```\n\n```text\n@api.get(\"/my-route/\", responses={404: {}, 500: {}})\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.102Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":7,"totalLines":128,"estimatedTokens":767}}133{"id":"stack-70300675","source":"stackoverflow","questionId":70300675,"title":"FastAPI, uvicorn.run() always create 3 instances, but I want it 1 instance","tags":["python","fastapi","uvicorn"],"text":"Title: FastAPI, uvicorn.run() always create 3 instances, but I want it 1 instance\nTags: python, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI run FastAPI at PyCharm IDE and it always run 3 workers.\nI don't know why, but, the last instance created is being accessed on every API call.\n\nCould anyone can help how can I get single running worker?\n\nCode:\n\n```\nimport uvicorn\nfrom fastapi import FastAPI\nfrom fastapi.templating import Jinja2Templates\nfrom starlette.middleware.cors import CORSMiddleware\n\napp = FastAPI()\napp.add_middleware(CORSMiddleware,\n allow_origins=[\"*\"],\n allow_methods=[\"*\"],\n allow_headers=[\"*\"])\nprint(f\"main.py with :{app}\")\n\n@app.get('/')\ndef home():\n return \"Hello\"\n\nif __name__ == \"__main__\":\n uvicorn.run(\"main:app\", host=\"0.0.0.0\", port=8000, reload=False, log_level=\"debug\", debug=True,\n workers=1, limit_concurrency=1, limit_max_requests=1)\n```\n\nConsole output:\n\n```\n/Users/user/.pyenv/versions/3.7.10/bin/python /Users/user/github/my-project/backend/main.py\nmain.py with :\nINFO: Will watch for changes in these directories: ['/Users/user/github/my-project/backend']\nINFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)\nINFO: Started reloader process [96259] using statreload\nmain.py with :\nmain.py with :\nINFO: Started server process [96261]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\n```\n\n========================================\n\nCode:\n```text\nimport uvicorn\nfrom fastapi import FastAPI\nfrom fastapi.templating import Jinja2Templates\nfrom starlette.middleware.cors import CORSMiddleware\n\napp = FastAPI()\napp.add_middleware(CORSMiddleware,\n allow_origins=[\"*\"],\n allow_methods=[\"*\"],\n allow_headers=[\"*\"])\nprint(f\"main.py with :{app}\")\n\n\n@app.get('/')\ndef home():\n return \"Hello\"\n\n\nif __name__ == \"__main__\":\n uvicorn.run(\"main:app\", host=\"0.0.0.0\", port=8000, reload=False, log_level=\"debug\", debug=True,\n workers=1, limit_concurrency=1, limit_max_requests=1)\n```\n\n```text\n/Users/user/.pyenv/versions/3.7.10/bin/python /Users/user/github/my-project/backend/main.py\nmain.py with :<fastapi.applications.FastAPI object at 0x102b35d50>\nINFO: Will watch for changes in these directories: ['/Users/user/github/my-project/backend']\nINFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)\nINFO: Started reloader process [96259] using statreload\nmain.py with :<fastapi.applications.FastAPI object at 0x10daadf50>\nmain.py with :<fastapi.applications.FastAPI object at 0x1106bfe50>\nINFO: Started server process [96261]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\n```\n\n```text\nimport uvicorn\n\nif __name__ == \"__main__\":\n uvicorn.run(\"main:app\", host=\"0.0.0.0\", port=8000, reload=False, log_level=\"debug\", debug=True,\n workers=1, limit_concurrency=1, limit_max_requests=1)\n```\n\n```text\nuvicorn main:app --host=0.0.0.0 --port=8000 --log-level=debug --limit-max-requests=1 --limit-concurrency=1\n```\n\n```text\nFastAPI\n```\n\n```text\n0x102b35d50\n```\n\n```text\n0x10daadf50\n```\n\n```text\n0x1106bfe50\n```\n\n```text\nFastAPI\n```\n\n```text\nmain.py\n```\n\n```text\nFastAPI\n```\n\n```text\n__main__\n```\n\n```text\nuvicorn\n```\n\n```text\nmain:app\n```\n\n```text\nmain.py\n```\n\n```text\nFastAPI\n```\n\n```text\ndebug=True\n```\n\n```text\nFastAPI\n```\n\n```text\nrun.py\n```\n\n========================================\n\nComments:\n- Hi @John, why do you say that there are always 3 workers ? I don't see anything in the log. With multiple workers you would have a repetition of the last 3 \"INFO\"\n- Hi @Emmanuel-Lin, `main.py` was created and I thought it is because of 3 workers are running\n- Is it thread then? Do you know how to make it to be called only one time? If I run command `uvicorn main:app --workers 1` then it only called one time though.\n- What do you mean by \"`main.py` was created \" ? I believe your configuration is already running on one single worker\n- Instances of `FastAPI()` were created 3 times as shown in the log.\n- FYI, someone may get errors when including `debug=True` and `limit_concurrency=1`. For a simple `hello world` it's better to not have extra params.\n- There is also the 3rd option: initialize `app` within `if __name__ != \"__main__\":` (that is an equivalent of `else` branch from the example).\n- Another solution is to start uvicorn part like this: `uvicorn.run(app, host=\"0.0.0.0\", port=8000)`","metadata":{"transformedAt":"2026-08-18T18:32:29.102Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":19,"totalLines":172,"estimatedTokens":1104}}134{"id":"stack-65505710","source":"stackoverflow","questionId":65505710,"title":"why is my fastapi or uvicorn getting shutdown?","tags":["python","fastapi","multilabel-classification","uvicorn","simpletransformers"],"text":"Title: why is my fastapi or uvicorn getting shutdown?\nTags: python, fastapi, multilabel-classification, uvicorn, simpletransformers\nSource: Stack Overflow\n\nQuestion:\nI am trying to run a service that uses simple transformers Roberta model to do classification. the inferencing script/function itself is working as expected when tested. when i include that with fast api its shutting down the server.\n\n```\nuvicorn==0.11.8\nfastapi==0.61.1\nsimpletransformers==0.51.6\ncmd : uvicorn --host 0.0.0.0 --port 5000 src.main:app\n```\n\n```\n@app.get(\"/article_classify\")\ndef classification(text:str):\n \"\"\"function to classify article using a deep learning model.\n Returns:\n [type]: [description]\n \"\"\"\n\n _,_,result = inference(text)\n return result\n```\n\nerror :\n\n```\nINFO: Started server process [8262]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\nINFO: Uvicorn running on http://0.0.0.0:5000 (Press CTRL+C to quit)\nINFO: 127.0.0.1:36454 - \"GET / HTTP/1.1\" 200 OK\nINFO: 127.0.0.1:36454 - \"GET /favicon.ico HTTP/1.1\" 404 Not Found\nINFO: 127.0.0.1:36454 - \"GET /docs HTTP/1.1\" 200 OK\nINFO: 127.0.0.1:36454 - \"GET /openapi.json HTTP/1.1\" 200 OK\nbefore\n100%|████████████████████████████████████████████████████████████████████████████| 1/1 [00:00inferencing script :\n\n```\nmodel_name = \"checkpoint-3380-epoch-20\"\nmodel = MultiLabelClassificationModel(\"roberta\",\"src/outputs/\"+model_name)\ndef inference(input_text,model_name=\"checkpoint-3380-epoch-20\"):\n \"\"\"Function to run inverence on one sample text\"\"\"\n #model = MultiLabelClassificationModel(\"roberta\",\"src/outputs/\"+model_name)\n all_tags =[]\n if isinstance(input_text,str):\n print(\"before\")\n result ,output = model.predict([input_text])\n print(result)\n tags=[]\n for idx,each in enumerate(result[0]):\n if each==1:\n tags.append(classes[idx])\n all_tags.append(tags)\n elif isinstance(input_text,list):\n result ,output = model.predict(input_text)\n tags=[]\n for res in result : \n for idx,each in enumerate(res):\n if each==1:\n tags.append(classes[idx])\n all_tags.append(tags)\n\n return result,output,all_tags\n```\n\nupdate: tried with flask and the service is working but when adding uvicorn on top of flask its getting stuck in a loop of restart.\n\n========================================\n\nTop Answer:\nAlthough the accepted solution works, I would like to suggest a less hacky solution that uses `uvicorn` workers instead.\n\nYou may want to try adding `--workers 4` to your `CMD` so that it reads:\n\n```\nuvicorn --host 0.0.0.0 --port 5000 --workers 4 src.main:app\n```\n\n========================================\n\nCode:\n```text\nuvicorn==0.11.8\nfastapi==0.61.1\nsimpletransformers==0.51.6\ncmd : uvicorn --host 0.0.0.0 --port 5000 src.main:app\n```\n\n```text\n@app.get(\"/article_classify\")\ndef classification(text:str):\n \"\"\"function to classify article using a deep learning model.\n Returns:\n [type]: [description]\n \"\"\"\n\n _,_,result = inference(text)\n return result\n```\n\n```text\nINFO: Started server process [8262]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\nINFO: Uvicorn running on http://0.0.0.0:5000 (Press CTRL+C to quit)\nINFO: 127.0.0.1:36454 - \"GET / HTTP/1.1\" 200 OK\nINFO: 127.0.0.1:36454 - \"GET /favicon.ico HTTP/1.1\" 404 Not Found\nINFO: 127.0.0.1:36454 - \"GET /docs HTTP/1.1\" 200 OK\nINFO: 127.0.0.1:36454 - \"GET /openapi.json HTTP/1.1\" 200 OK\nbefore\n100%|████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 17.85it/s]\nINFO: Shutting down\nINFO: Finished server process [8262]\n```\n\n```text\nmodel_name = \"checkpoint-3380-epoch-20\"\nmodel = MultiLabelClassificationModel(\"roberta\",\"src/outputs/\"+model_name)\ndef inference(input_text,model_name=\"checkpoint-3380-epoch-20\"):\n \"\"\"Function to run inverence on one sample text\"\"\"\n #model = MultiLabelClassificationModel(\"roberta\",\"src/outputs/\"+model_name)\n all_tags =[]\n if isinstance(input_text,str):\n print(\"before\")\n result ,output = model.predict([input_text])\n print(result)\n tags=[]\n for idx,each in enumerate(result[0]):\n if each==1:\n tags.append(classes[idx])\n all_tags.append(tags)\n elif isinstance(input_text,list):\n result ,output = model.predict(input_text)\n tags=[]\n for res in result : \n for idx,each in enumerate(res):\n if each==1:\n tags.append(classes[idx])\n all_tags.append(tags)\n\n return result,output,all_tags\n```\n\n```text\nfrom multiprocessing import set_start_method\nfrom multiprocessing import Process, Manager\ntry:\n set_start_method('spawn')\nexcept RuntimeError:\n pass\n@app.get(\"/article_classify\")\ndef classification(text:str):\n \"\"\"function to classify article using a deep learning model.\n Returns:\n [type]: [description]\n \"\"\"\n manager = Manager()\n\n return_result = manager.dict()\n # as the inference is failing \n p = Process(target = inference,args=(text,return_result,))\n p.start()\n p.join()\n # print(return_result)\n result = return_result['all_tags']\n return result\n```\n\n```py\nimport logging\n\n@app.get(\"/article_classify\")\ndef classification(text:str):\n \"\"\"function to classify article using a deep learning model.\n Returns:\n [type]: [description]\n \"\"\"\n try:\n _,_,result = inference(text)\n except:\n logging.exception(\"something bad happened\") # automatically print exception info\n\n return result\n```\n\n```text\ntry-except\n```\n\n```text\ntimeout_notify=30\n```\n\n```bash\nuvicorn --host 0.0.0.0 --port 5000 --workers 4 src.main:app\n```\n\n```text\nuvicorn\n```\n\n```text\n--workers 4\n```\n\n```text\nCMD\n```\n\n```text\nUploadFile\n```\n\n========================================\n\nComments:\n- It looks like it stops exactly at (or right after) processing the line `result ,output = model.predict([input_text])`. You could try debugging from there, putting the line of code within a `try-catch` block.\n- there is no error/exception that is coming up, that was the issue to start of with.\n- great find. Tried every combination with other processes running in the same instance. Tested also with set_start_method('fork') but set_start_method('spawn') did the trick and seems stable now. Thanks\n- And at the end there someone says you also need `\"use_multiprocessing_for_evaluation\":False` which was necessary for me to work with FastAPI.\n- thanks. It worked truly, though I'm running uvicorn in my main method. So it can be replaced to `uvicorn.run(\"src.main:app\", host=\"0.0.0.0\", port=5050, workers=4)`. but I wonder why this solution works.","metadata":{"transformedAt":"2026-08-18T18:32:29.103Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":13,"totalLines":224,"estimatedTokens":1656}}135{"id":"stack-71546126","source":"stackoverflow","questionId":71546126,"title":"Python Pydantic Error: TypeError: __init__() takes exactly 1 positional argument (2 given)","tags":["python","fastapi","pydantic"],"text":"Title: Python Pydantic Error: TypeError: __init__() takes exactly 1 positional argument (2 given)\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\ni am currenty working on a python fastapi project for university. Every time i run my authorization dependencies i get the following error:\n\n```\nERROR: Exception in ASGI application\nTraceback (most recent call last):\n File \"C:\\Python39\\lib\\site-packages\\uvicorn\\protocols\\http\\h11_impl.py\", line 366, in run_asgi\n result = await app(self.scope, self.receive, self.send)\n File \"C:\\Python39\\lib\\site-packages\\uvicorn\\middleware\\proxy_headers.py\", line 75, in __call__\n return await self.app(scope, receive, send)\n File \"C:\\Python39\\lib\\site-packages\\fastapi\\applications.py\", line 208, in __call__\n await super().__call__(scope, receive, send)\n File \"C:\\Python39\\lib\\site-packages\\starlette\\applications.py\", line 112, in __call__\n await self.middleware_stack(scope, receive, send)\n File \"C:\\Python39\\lib\\site-packages\\starlette\\middleware\\errors.py\", line 181, in __call__\n raise exc\n File \"C:\\Python39\\lib\\site-packages\\starlette\\middleware\\errors.py\", line 159, in __call__\n await self.app(scope, receive, _send)\n File \"C:\\Python39\\lib\\site-packages\\starlette\\exceptions.py\", line 82, in __call__\n raise exc\n File \"C:\\Python39\\lib\\site-packages\\starlette\\exceptions.py\", line 71, in __call__\n await self.app(scope, receive, sender)\n File \"C:\\Python39\\lib\\site-packages\\starlette\\routing.py\", line 656, in __call__\n await route.handle(scope, receive, send)\n File \"C:\\Python39\\lib\\site-packages\\starlette\\routing.py\", line 259, in handle\n await self.app(scope, receive, send)\n File \"C:\\Python39\\lib\\site-packages\\starlette\\routing.py\", line 61, in app\n response = await func(request)\n File \"C:\\Python39\\lib\\site-packages\\fastapi\\routing.py\", line 216, in app\n solved_result = await solve_dependencies(\n File \"C:\\Python39\\lib\\site-packages\\fastapi\\dependencies\\utils.py\", line 496, in solve_dependencies\n solved_result = await solve_dependencies(\n File \"C:\\Python39\\lib\\site-packages\\fastapi\\dependencies\\utils.py\", line 525, in solve_dependencies\n solved = await call(**sub_values)\n File \"e:\\Dev\\Ottomize\\Ottomize\\backend\\app\\auth_handler.py\", line 60, in get_current_user\n token_data = schemas.TokenData(username)\n File \"pydantic\\main.py\", line 322, in pydantic.main.BaseModel.__init__\nTypeError: __init__() takes exactly 1 positional argument (2 given)\n```\n\nHere is my relevant code:\n\nFAST API Endpoint:\n\n```\n@app.get(\"/user/current/info/\", response_model=schemas.User)\nasync def user_info(current_user: schemas.User = Depends(auth_handler.get_current_active_user)):\n return current_user\n```\n\nUsed functions in my auth_handler.py:\n\n```\nfrom fastapi.security import OAuth2PasswordBearer\nfrom jose import JWTError, jwt\nfrom passlib.context import CryptContext\nfrom datetime import datetime, timedelta\nfrom typing import Optional\n\nfrom fastapi import Depends, HTTPException, status\nfrom . import crud, schemas, config, database\n\noauth2_scheme = OAuth2PasswordBearer(tokenUrl=\"token\")\npwd_context = CryptContext(schemes=[\"bcrypt\"], deprecated=\"auto\")\n\n#gets user out of db\n def get_user(username: str):\n db = database.SessionLocal()\n return crud.get_user_by_username(db, username)\n\n#gets current user\nasync def get_current_user(token: str = Depends(oauth2_scheme)):\n credentials_exception = HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Could not validate credentials\",\n headers={\"WWW-Authenticate\": \"Bearer\"},\n )\n try:\n payload = jwt.decode(token, config.SECRET_KEY, algorithms=[config.ALGORITHM])\n username: str = payload.get(\"sub\")\n if username is None:\n raise credentials_exception\n token_data = schemas.TokenData(username)\n except JWTError:\n raise credentials_exception\n user = get_user(token_data.username)\n if user is None:\n raise credentials_exception\n return user\n\n#gets current user if active\nasync def get_current_active_user(current_user: schemas.User = Depends(get_current_user)):\n if current_user.disabled:\n raise HTTPException(status_code=400, detail=\"Inactive user\")\n return current_user\n```\n\nUsed functions in my crud.py:\n\n```\ndef get_user_by_username(db: Session, username: str):\n return db.query(models.User).filter(models.User.username == username).first()\n```\n\nUsed sqlalchemy models:\n\n```\nfrom sqlalchemy import Boolean, Column, ForeignKey, Integer, String\nfrom sqlalchemy.orm import relationship\n\nfrom .database import Base\n\nclass User(Base):\n __tablename__ = \"user\"\n\n id = Column(Integer, primary_key=True, index=True)\n username = Column(String(100), unique=True, index=True)\n mail = Column(String(100), unique=True, index=True)\n hashed_password = Column(String(100))\n is_active = Column(Boolean, default=True)\n\n permissions = relationship(\"Permission\", back_populates=\"user\")\n\nclass Permission(Base):\n __tablename__ = \"permission\"\n\n id = Column(Integer, primary_key=True, index=True)\n name = Column(String(100))\n user_id = Column(Integer, ForeignKey(\"user.id\"))\n \n user = relationship(\"User\", back_populates=\"permissions\")\n```\n\nUsed pydantic models:\n\n```\nfrom typing import List, Optional\nfrom pydantic import BaseModel\n\n#Define Datatype Token \nclass Token(BaseModel):\n access_token: str\n token_type: str\n\n#Define Datatype TokenData \nclass TokenData(BaseModel):\n username: str\n\n class Config:\n orm_mode = True\n\n#Define Datatype User \nclass User(BaseModel):\n id: int\n username: str\n mail: str\n is_active: Optional[bool]\n permissions: List[Permission] = []\n\n class Config:\n orm_mode = True\n```\n\nI am really new to fastapi and python in general and would really appreciate help!\n\n========================================\n\nTop Answer:\nIn my case I used `response_class` instead of `response_model` decorator. It was silly mistake by vscode code suggestion. So just check it in the decorator and change it to `response_model`.\n\nHope this helps\n\n========================================\n\nCode:\n```text\nERROR: Exception in ASGI application\nTraceback (most recent call last):\n File \"C:\\Python39\\lib\\site-packages\\uvicorn\\protocols\\http\\h11_impl.py\", line 366, in run_asgi\n result = await app(self.scope, self.receive, self.send)\n File \"C:\\Python39\\lib\\site-packages\\uvicorn\\middleware\\proxy_headers.py\", line 75, in __call__\n return await self.app(scope, receive, send)\n File \"C:\\Python39\\lib\\site-packages\\fastapi\\applications.py\", line 208, in __call__\n await super().__call__(scope, receive, send)\n File \"C:\\Python39\\lib\\site-packages\\starlette\\applications.py\", line 112, in __call__\n await self.middleware_stack(scope, receive, send)\n File \"C:\\Python39\\lib\\site-packages\\starlette\\middleware\\errors.py\", line 181, in __call__\n raise exc\n File \"C:\\Python39\\lib\\site-packages\\starlette\\middleware\\errors.py\", line 159, in __call__\n await self.app(scope, receive, _send)\n File \"C:\\Python39\\lib\\site-packages\\starlette\\exceptions.py\", line 82, in __call__\n raise exc\n File \"C:\\Python39\\lib\\site-packages\\starlette\\exceptions.py\", line 71, in __call__\n await self.app(scope, receive, sender)\n File \"C:\\Python39\\lib\\site-packages\\starlette\\routing.py\", line 656, in __call__\n await route.handle(scope, receive, send)\n File \"C:\\Python39\\lib\\site-packages\\starlette\\routing.py\", line 259, in handle\n await self.app(scope, receive, send)\n File \"C:\\Python39\\lib\\site-packages\\starlette\\routing.py\", line 61, in app\n response = await func(request)\n File \"C:\\Python39\\lib\\site-packages\\fastapi\\routing.py\", line 216, in app\n solved_result = await solve_dependencies(\n File \"C:\\Python39\\lib\\site-packages\\fastapi\\dependencies\\utils.py\", line 496, in solve_dependencies\n solved_result = await solve_dependencies(\n File \"C:\\Python39\\lib\\site-packages\\fastapi\\dependencies\\utils.py\", line 525, in solve_dependencies\n solved = await call(**sub_values)\n File \"e:\\Dev\\Ottomize\\Ottomize\\backend\\app\\auth_handler.py\", line 60, in get_current_user\n token_data = schemas.TokenData(username)\n File \"pydantic\\main.py\", line 322, in pydantic.main.BaseModel.__init__\nTypeError: __init__() takes exactly 1 positional argument (2 given)\n```\n\n```text\n@app.get(\"/user/current/info/\", response_model=schemas.User)\nasync def user_info(current_user: schemas.User = Depends(auth_handler.get_current_active_user)):\n return current_user\n```\n\n```text\nfrom fastapi.security import OAuth2PasswordBearer\nfrom jose import JWTError, jwt\nfrom passlib.context import CryptContext\nfrom datetime import datetime, timedelta\nfrom typing import Optional\n\n\nfrom fastapi import Depends, HTTPException, status\nfrom . import crud, schemas, config, database\n\noauth2_scheme = OAuth2PasswordBearer(tokenUrl=\"token\")\npwd_context = CryptContext(schemes=[\"bcrypt\"], deprecated=\"auto\")\n\n#gets user out of db\n def get_user(username: str):\n db = database.SessionLocal()\n return crud.get_user_by_username(db, username)\n\n#gets current user\nasync def get_current_user(token: str = Depends(oauth2_scheme)):\n credentials_exception = HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Could not validate credentials\",\n headers={\"WWW-Authenticate\": \"Bearer\"},\n )\n try:\n payload = jwt.decode(token, config.SECRET_KEY, algorithms=[config.ALGORITHM])\n username: str = payload.get(\"sub\")\n if username is None:\n raise credentials_exception\n token_data = schemas.TokenData(username)\n except JWTError:\n raise credentials_exception\n user = get_user(token_data.username)\n if user is None:\n raise credentials_exception\n return user\n\n#gets current user if active\nasync def get_current_active_user(current_user: schemas.User = Depends(get_current_user)):\n if current_user.disabled:\n raise HTTPException(status_code=400, detail=\"Inactive user\")\n return current_user\n```\n\n```text\ndef get_user_by_username(db: Session, username: str):\n return db.query(models.User).filter(models.User.username == username).first()\n```\n\n```text\nfrom sqlalchemy import Boolean, Column, ForeignKey, Integer, String\nfrom sqlalchemy.orm import relationship\n\nfrom .database import Base\n\nclass User(Base):\n __tablename__ = \"user\"\n\n id = Column(Integer, primary_key=True, index=True)\n username = Column(String(100), unique=True, index=True)\n mail = Column(String(100), unique=True, index=True)\n hashed_password = Column(String(100))\n is_active = Column(Boolean, default=True)\n\n permissions = relationship(\"Permission\", back_populates=\"user\")\n\nclass Permission(Base):\n __tablename__ = \"permission\"\n\n id = Column(Integer, primary_key=True, index=True)\n name = Column(String(100))\n user_id = Column(Integer, ForeignKey(\"user.id\"))\n \n user = relationship(\"User\", back_populates=\"permissions\")\n```\n\n```text\nfrom typing import List, Optional\nfrom pydantic import BaseModel\n\n#Define Datatype Token \nclass Token(BaseModel):\n access_token: str\n token_type: str\n\n#Define Datatype TokenData \nclass TokenData(BaseModel):\n username: str\n\n class Config:\n orm_mode = True\n\n\n#Define Datatype User \nclass User(BaseModel):\n id: int\n username: str\n mail: str\n is_active: Optional[bool]\n permissions: List[Permission] = []\n\n class Config:\n orm_mode = True\n```\n\n```text\ntoken_data = schemas.TokenData(username=username)\n```\n\n```text\nusername\n```\n\n```text\nusername\n```\n\n```text\nresponse_class\n```\n\n```text\nresponse_model\n```\n\n```text\nresponse_model\n```\n\n========================================\n\nComments:\n- So it looks like Pydantic has implicit keyword only constructor? No positional arguments.\n- Having positional arguments would be very prone to errors, since you can't really assume that the sequence of fields in the class remains constant. Do you expect the behaviour to change if you have `username` defined before `name` and just change which field comes first in the class definition? That opens up the possibility of weird and strange bugs (and how would you handle fields with defaults among fields without defaults? In that case all fields with defaults would have to be defined last in your class).\n- Could anyone point to me which part of Pydantic documentation website pydantic-docs.helpmanual.io/usage/models specifies that we need to provide keyword to its `BaseModel` constructor?\n- @hunterex Sorry, I can't give you a reference to the manual (not all negatives and reasons are present in a manual). You can refer to this issue on the Pydantic repository for some of the reasoning from Pydantic's author: github.com/samuelcolvin/pydantic/issues/116 - if you don't need `BaseModel` (but since you asked explicitly about that, I can't really be sure), you could use a dataclass: pydantic-docs.helpmanual.io/usage/dataclasses (or you could just write a helper initializer that takes positional arguments).\n- This was the same problem with my code. I just changed the `response_class` to `response_model` yikes this is confusing at times.","metadata":{"transformedAt":"2026-08-18T18:32:29.103Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":12,"totalLines":361,"estimatedTokens":3231}}136{"id":"stack-76674272","source":"stackoverflow","questionId":76674272,"title":"Pydantic BaseSettings cant find .env when running commands from different places","tags":["python","fastapi","pydantic","alembic"],"text":"Title: Pydantic BaseSettings cant find .env when running commands from different places\nTags: python, fastapi, pydantic, alembic\nSource: Stack Overflow\n\nQuestion:\nSo, Im trying to setup Alembic with FastAPI and Im having a problem with Pydantic's BaseSettings, I get a validation error (variables not found) because it doesnt find the .env file (?)\n\nIt can be solved by changing `env_file = \".env\"` to `env_file = \"../.env\"` in the `BaseSettings` `class Config` but that makes the error happen when running main.py, I tried setting it as an absolute path with `env_file = os.path.abspath(\"../../.env\")` but that didnt work.\n\nWhat should I do?\n\nconfig.py:\n\n```\nimport os\nfrom functools import lru_cache\n\nfrom pydantic_settings import BaseSettings\n\nabs_path_env = os.path.abspath(\"../../.env\")\n\nclass Settings(BaseSettings):\n APP_NAME: str = \"AppName\"\n SQLALCHEMY_URL: str\n ENVIRONMENT: str\n\n class Config:\n env_file = \".env\" # Works with uvicorn run command from my-app/project/\n # env_file = \"../.env\" Works with alembic command from my-app/alembic\n # env_file = abs_path_env\n\n@lru_cache()\ndef get_settings():\n return Settings()\n```\n\nProject folders:\n\n```\nmy-app\n├── alembic\n│ ├── versions\n│ ├── alembic.ini\n│ ├── env.py\n│ ├── README\n│ └── script.py.mako\n├── project\n│ ├── core\n│ │ ├── __init__.py\n│ │ └── config.py\n│ └── __init__.py\n├── __init__.py\n├── .env\n└── main.py\n```\n\n========================================\n\nTop Answer:\nYou should say the version of libraries that you are currently using.\nIn the case you are using pydantic2, this way of specifying the config file (and other config) has been deprecated, and then, lately, completely removed.\n\nhttps://docs.pydantic.dev/2.1/usage/model_config/\n\nhttps://docs.pydantic.dev/2.7/usage/model_config/\n\nUnluckly there is no warnings and the \"class Config\" is ignored silently.\nAs per other answer, you have to use simply\n\n```\nmodel_config = SettingsConfigDict(env_file='customfile.env')\n```\n\ninstead of the nested class \"Config\".\n\n========================================\n\nCode:\n```text\nimport os\nfrom functools import lru_cache\n\nfrom pydantic_settings import BaseSettings\n\nabs_path_env = os.path.abspath(\"../../.env\")\n\n\nclass Settings(BaseSettings):\n APP_NAME: str = \"AppName\"\n SQLALCHEMY_URL: str\n ENVIRONMENT: str\n\n class Config:\n env_file = \".env\" # Works with uvicorn run command from my-app/project/\n # env_file = \"../.env\" Works with alembic command from my-app/alembic\n # env_file = abs_path_env\n\n@lru_cache()\ndef get_settings():\n return Settings()\n```\n\n```text\nmy-app\n├── alembic\n│ ├── versions\n│ ├── alembic.ini\n│ ├── env.py\n│ ├── README\n│ └── script.py.mako\n├── project\n│ ├── core\n│ │ ├── __init__.py\n│ │ └── config.py\n│ └── __init__.py\n├── __init__.py\n├── .env\n└── main.py\n```\n\n```text\nenv_file = \".env\"\n```\n\n```text\nenv_file = \"../.env\"\n```\n\n```text\nBaseSettings\n```\n\n```text\nclass Config\n```\n\n```text\nenv_file = os.path.abspath(\"../../.env\")\n```\n\n```text\nimport os\n\nfrom pydantic_settings import BaseSettings, SettingsConfigDict\n\n\nDOTENV = os.path.join(os.path.dirname(__file__), \".env\")\n\n\nclass Settings(BaseSettings):\n pg_dsn: str\n pg_pool_min_size: int\n pg_pool_max_size: int\n pg_pool_max_queries: int\n pg_pool_max_intactive_conn_lifetime: int\n\n model_config = SettingsConfigDict(env_file=DOTENV)\n```\n\n```text\n.env\n```\n\n```text\n.env\n```\n\n```text\nsettings.py\n```\n\n```text\n.env\n```\n\n```text\nos.path.join(os.path.dirname(__file__), \".env\")\n```\n\n```text\n.env\n```\n\n```text\nsettings.py\n```\n\n```text\nSettings\n```\n\n```text\n.dotenv\n```\n\n```text\nfrom pydantic_settings import BaseSettings, SettingsConfigDict\nfrom dotenv import find_dotenv, load_dotenv\n\nload_dotenv(find_dotenv(\".env\"))\n\nclass Config(BaseSettings):\n ...\n \n model_config = SettingsConfigDict(case_sensitive=True)\n```\n\n```text\npydantic 2.4.2\n```\n\n```text\nconfig.py\n```\n\n```text\npython-dotenv\n```\n\n```text\nload_env\n```\n\n```text\nfind_dotenv\n```\n\n```text\n.env\n```\n\n```text\nconfig.py\n```\n\n```text\nmodel_config = SettingsConfigDict(env_file='customfile.env')\n```\n\n```text\nfrom pydantic_settings import BaseSettings\nfrom dotenv import find_dotenv, load_dotenv\n\n\nload_dotenv(find_dotenv(\"../../../.env\"))\n\nclass Settings(BaseSettings):\n server_host: str = '127.0.0.1'\n server_port: int = 5001\n db_url: str\n\n class Config:\n env_file = '.env'\n\nsettings = Settings()\n```\n\n```text\nfind_dotenv()\n```\n\n========================================\n\nComments:\n- The path is relative to the location of the working dir not the file itself. To make `.env` work you should just start all programs from `my-app`\n- Keep in mind that this means that you will load dotenv file every time this config.py is imported\n- thank you for the solution. it was the problem for me as well\n- Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.","metadata":{"transformedAt":"2026-08-18T18:32:29.103Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":28,"totalLines":268,"estimatedTokens":1266}}137{"id":"stack-73664830","source":"stackoverflow","questionId":73664830,"title":"Pydantic object has no attribute '__fields_set__' error","tags":["python","fastapi","pydantic"],"text":"Title: Pydantic object has no attribute '__fields_set__' error\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI'm working with FastAPI to create a really simple dummy API. For it I was playing around with enums to define the require body for a post request and simulating a DB call from the API method to a dummy method.\n\nTo have the proper body request on my endpoint, Im using Pydantic's BaseModel on the class definition but for some reason I get this error\n\n```\nFile \"pydantic/main.py\", line 406, in pydantic.main.BaseModel.__setattr__ \nAttributeError: 'MagicItem' object has no attribute '__fields_set__'\n```\n\nI'm not sure what's the problem, here is my code that generate all this:\n\nhttps://i.sstatic.net/zAgyN.png\n\nhttps://i.sstatic.net/kvkpf.png\n\nhttps://i.sstatic.net/tNID0.png\n\nI'm kinda lost right now cuz I don't see the error in such a simple code.\n\n========================================\n\nTop Answer:\nNot a full-fledged solution, but if you are having a similar problem and @daniil-fajnberg's solution doesn't fix it for you, **make sure that you are not accessing the `self` object before calling `super()`**\n\nThis will fail:\n\n```\nclass MagicItem(BaseModel):\n name: str\n damage: Damage\n foo: Any # None:\n self.foo = foo # Whereas this is what worked for me:\n\n```\nclass MagicItem(BaseModel):\n name: str\n damage: Damage\n foo: Any # None:\n super().__init__(name=name, damage=damage)\n self.foo = foo # <---- ✓ after super()!\n```\n\n========================================\n\nCode:\n```text\nFile \"pydantic/main.py\", line 406, in pydantic.main.BaseModel.__setattr__ \nAttributeError: 'MagicItem' object has no attribute '__fields_set__'\n```\n\n```py\nsuper().__init__(...)\n```\n\n```py\nclass MagicItem(BaseModel):\n name: str\n damage: Damage\n\n def __init__(self, name: str, damage: Damage) -> None:\n super().__init__(name=name, damage=damage)\n```\n\n```text\nBaseModel.__init__\n```\n\n```text\nMagicItem\n```\n\n```text\n__fields_set__\n```\n\n```text\n__init__\n```\n\n```text\nMagicItem\n```\n\n```py\nclass MagicItem(BaseModel):\n name: str\n damage: Damage\n foo: Any # <---- an extra property\n\n def __init__(self, name: str, damage: Damage, foo: Any) -> None:\n self.foo = foo # <---- x before super()!\n super().__init__(name=name, damage=damage)\n```\n\n```py\nclass MagicItem(BaseModel):\n name: str\n damage: Damage\n foo: Any # <---- an extra property\n\n def __init__(self, name: str, damage: Damage, foo: Any) -> None:\n super().__init__(name=name, damage=damage)\n self.foo = foo # <---- ✓ after super()!\n```\n\n```text\nself\n```\n\n```text\nsuper()\n```\n\n========================================\n\nComments:\n- Can you replace screenshots of your code with actual code blocks? This will allow better accessibility for those visiting the site.","metadata":{"transformedAt":"2026-08-18T18:32:29.103Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":12,"totalLines":122,"estimatedTokens":699}}138{"id":"stack-60778279","source":"stackoverflow","questionId":60778279,"title":"FastAPI middleware peeking into responses","tags":["python","fastapi","starlette"],"text":"Title: FastAPI middleware peeking into responses\nTags: python, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nI try to write a simple middleware for FastAPI peeking into response bodies.\n\nIn this example I just log the body content:\n\n```\napp = FastAPI()\n\n@app.middleware(\"http\")\nasync def log_request(request, call_next):\n logger.info(f'{request.method} {request.url}')\n response = await call_next(request)\n logger.info(f'Status code: {response.status_code}')\n async for line in response.body_iterator:\n logger.info(f' {line}')\n return response\n```\n\nHowever it looks like I \"consume\" the body this way, resulting in this exception:\n\n```\n...\n File \".../python3.7/site-packages/starlette/middleware/base.py\", line 26, in __call__\n await response(scope, receive, send)\n File \".../python3.7/site-packages/starlette/responses.py\", line 201, in __call__\n await send({\"type\": \"http.response.body\", \"body\": b\"\", \"more_body\": False})\n File \".../python3.7/site-packages/starlette/middleware/errors.py\", line 156, in _send\n await send(message)\n File \".../python3.7/site-packages/uvicorn/protocols/http/httptools_impl.py\", line 515, in send\n raise RuntimeError(\"Response content shorter than Content-Length\")\nRuntimeError: Response content shorter than Content-Length\n```\n\nTrying to look into the response object I couldn't see any other way to read its content. What is the correct way to do it?\n\n========================================\n\nTop Answer:\nI know this is a relatively old post now, but I recently ran into this problem and came up with a solution:\n\n**Middleware Code**\n\n```\nfrom starlette.middleware.base import BaseHTTPMiddleware\nfrom starlette.requests import Request\nimport json\nfrom .async_iterator_wrapper import async_iterator_wrapper as aiwrap\n\nclass some_middleware(BaseHTTPMiddleware):\n async def dispatch(self, request:Request, call_next:RequestResponseEndpoint):\n # --------------------------\n # DO WHATEVER YOU TO DO HERE\n #---------------------------\n \n response = await call_next(request)\n\n # Consuming FastAPI response and grabbing body here\n resp_body = [section async for section in response.__dict__['body_iterator']]\n # Repairing FastAPI response\n response.__setattr__('body_iterator', aiwrap(resp_body)\n\n # Formatting response body for logging\n try:\n resp_body = json.loads(resp_body[0].decode())\n except:\n resp_body = str(resp_body)\n```\n\n**async_iterator_wrapper Code** *from*\nTypeError from Python 3 async for loop\n\n```\nclass async_iterator_wrapper:\n def __init__(self, obj):\n self._it = iter(obj)\n def __aiter__(self):\n return self\n async def __anext__(self):\n try:\n value = next(self._it)\n except StopIteration:\n raise StopAsyncIteration\n return value\n```\n\nI really hope this can help someone! I found this very helpful for logging.\n\nBig thanks to @Eddified for the aiwrap class\n\n========================================\n\nCode:\n```py\napp = FastAPI()\n\n@app.middleware(\"http\")\nasync def log_request(request, call_next):\n logger.info(f'{request.method} {request.url}')\n response = await call_next(request)\n logger.info(f'Status code: {response.status_code}')\n async for line in response.body_iterator:\n logger.info(f' {line}')\n return response\n```\n\n```text\n...\n File \".../python3.7/site-packages/starlette/middleware/base.py\", line 26, in __call__\n await response(scope, receive, send)\n File \".../python3.7/site-packages/starlette/responses.py\", line 201, in __call__\n await send({\"type\": \"http.response.body\", \"body\": b\"\", \"more_body\": False})\n File \".../python3.7/site-packages/starlette/middleware/errors.py\", line 156, in _send\n await send(message)\n File \".../python3.7/site-packages/uvicorn/protocols/http/httptools_impl.py\", line 515, in send\n raise RuntimeError(\"Response content shorter than Content-Length\")\nRuntimeError: Response content shorter than Content-Length\n```\n\n```py\napp = FastAPI()\n\n@app.middleware(\"http\")\nasync def log_request(request, call_next):\n logger.info(f'{request.method} {request.url}')\n response = await call_next(request)\n logger.info(f'Status code: {response.status_code}')\n body = b\"\"\n async for chunk in response.body_iterator:\n body += chunk\n # do something with body ...\n return Response(\n content=body,\n status_code=response.status_code,\n headers=dict(response.headers),\n media_type=response.media_type\n )\n```\n\n```text\nfrom starlette.middleware.base import BaseHTTPMiddleware\nfrom starlette.requests import Request\nimport json\nfrom .async_iterator_wrapper import async_iterator_wrapper as aiwrap\n\nclass some_middleware(BaseHTTPMiddleware):\n async def dispatch(self, request:Request, call_next:RequestResponseEndpoint):\n # --------------------------\n # DO WHATEVER YOU TO DO HERE\n #---------------------------\n \n response = await call_next(request)\n\n # Consuming FastAPI response and grabbing body here\n resp_body = [section async for section in response.__dict__['body_iterator']]\n # Repairing FastAPI response\n response.__setattr__('body_iterator', aiwrap(resp_body)\n\n # Formatting response body for logging\n try:\n resp_body = json.loads(resp_body[0].decode())\n except:\n resp_body = str(resp_body)\n```\n\n```text\nclass async_iterator_wrapper:\n def __init__(self, obj):\n self._it = iter(obj)\n def __aiter__(self):\n return self\n async def __anext__(self):\n try:\n value = next(self._it)\n except StopIteration:\n raise StopAsyncIteration\n return value\n```\n\n```py\nclass CustomAPIRoute(APIRoute):\n def get_route_handler(self):\n app = super().get_route_handler()\n return wrapper(app)\n\ndef wrapper(func):\n async def _app(request):\n response = await func(request)\n\n print(vars(request), vars(response))\n\n return response\n return _app\n\nrouter = APIRouter(route_class=CustomAPIRoute)\n```\n\n```text\nresponse = await func(request)\n```\n\n```text\ntry: except HTTPException as e\n```\n\n```py\nfrom fastapi import BackgroundTasks, FastAPI\nfrom starlette.requests import Request\n\napp = FastAPI()\n\nasync def log_request(request, response):\n logger.info(f'{request.method} {request.url}')\n logger.info(f\"{response['message']}\")\n\n\n@app.post(\"/dummy-endpoint/\")\nasync def send_notification(request: Request, background_tasks: BackgroundTasks):\n my_response = {\"message\": \"Notification sent in the background\"}\n background_tasks.add_task(log_request, request=request, response=my_response)\n return my_response\n```\n\n```text\nrequest\n```\n\n```text\nresponse\n```\n\n========================================\n\nComments:\n- also related : github.com/tiangolo/fastapi/issues/954\n- If you make changes to response body, be sure to modify header's content-length, otherwise you'll get error saying content length is different from header's content-length\n- While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review\n- Good point, solved.","metadata":{"transformedAt":"2026-08-18T18:32:29.103Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":11,"totalLines":241,"estimatedTokens":1781}}139{"id":"stack-62898917","source":"stackoverflow","questionId":62898917,"title":"Running fastapi app using uvicorn on ubuntu server","tags":["gunicorn","fastapi","uvicorn"],"text":"Title: Running fastapi app using uvicorn on ubuntu server\nTags: gunicorn, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI am dealing with the project deposition made on FastAPI to a remote ubuntu server. I'll try to run the project from terminal (using SSH connection) by the command\n\n```\ngunicorn -k uvicorn.workers.UvicornWorker main:app\n```\n\nThe output is\n\n```\ngunicorn -k uvicorn.workers.UvicornWorker main:app\n[2020-07-14 15:24:28 +0000] [23102] [INFO] Starting gunicorn 20.0.4\n[2020-07-14 15:24:28 +0000] [23102] [INFO] Listening at: http://127.0.0.1:8000 (23102)\n[2020-07-14 15:24:28 +0000] [23102] [INFO] Using worker: uvicorn.workers.UvicornWorker\n[2020-07-14 15:24:28 +0000] [23104] [INFO] Booting worker with pid: 23104\n[2020-07-14 15:24:28 +0000] [23104] [INFO] Started server process [23104]\n[2020-07-14 15:24:28 +0000] [23104] [INFO] Waiting for application startup.\n[2020-07-14 15:24:28 +0000] [23104] [INFO] Application startup complete.\n```\n\nBut I need the project to be available at the IP address of the server. If I try smth like\n\n```\nuvicorn main:app --host 66.226.247.55 --port 8000\n```\n\nI get\n\n```\nINFO: Started server process [23308]\nINFO: Waiting for application startup.\nINFO: Connected to database postgresql://recognition:********@localhost:5432/reco\nINFO: Application startup complete.\nERROR: [Errno 99] error while attempting to bind on address ('66.226.247.55', 8000): cannot assign requested address\nINFO: Waiting for application shutdown.\nINFO: Disconnected from database postgresql://recognition:********@localhost:5432/reco\nINFO: Application shutdown complete.\n```\n\nWhere 66.226.247.55 - external IP adress from google cloud platform instances\nHow do I start a project so that it can be accessed via IP?\n\n========================================\n\nTop Answer:\nIf you're using nginx server\n\ncreate a file in /etc/nginx/sites-enabled/\ncreate file touch fastapi_nginx\ncopy code into file and adjust accordingly\n\n\r\n\r\n\n```\nserver{\n listen 80;\n server_name \"your public ip\";\n location / {\n proxy_pass http://127.0.0.1:8000; #localhost\n }\n\n}\n```\n\n\r\n\r\n\r\n\nThis should reroute to your public ip\n\n========================================\n\nCode:\n```text\ngunicorn -k uvicorn.workers.UvicornWorker main:app\n```\n\n```text\ngunicorn -k uvicorn.workers.UvicornWorker main:app\n[2020-07-14 15:24:28 +0000] [23102] [INFO] Starting gunicorn 20.0.4\n[2020-07-14 15:24:28 +0000] [23102] [INFO] Listening at: http://127.0.0.1:8000 (23102)\n[2020-07-14 15:24:28 +0000] [23102] [INFO] Using worker: uvicorn.workers.UvicornWorker\n[2020-07-14 15:24:28 +0000] [23104] [INFO] Booting worker with pid: 23104\n[2020-07-14 15:24:28 +0000] [23104] [INFO] Started server process [23104]\n[2020-07-14 15:24:28 +0000] [23104] [INFO] Waiting for application startup.\n[2020-07-14 15:24:28 +0000] [23104] [INFO] Application startup complete.\n```\n\n```text\nuvicorn main:app --host 66.226.247.55 --port 8000\n```\n\n```text\nINFO: Started server process [23308]\nINFO: Waiting for application startup.\nINFO: Connected to database postgresql://recognition:********@localhost:5432/reco\nINFO: Application startup complete.\nERROR: [Errno 99] error while attempting to bind on address ('66.226.247.55', 8000): cannot assign requested address\nINFO: Waiting for application shutdown.\nINFO: Disconnected from database postgresql://recognition:********@localhost:5432/reco\nINFO: Application shutdown complete.\n```\n\n```text\nuvicorn main:app --host 0.0.0.0 --port 8000\n```\n\n```text\n--host\n```\n\n```text\nhttp://66.226.247.55:8000\n```\n\n```html\nserver{\n listen 80;\n server_name \"your public ip\";\n location / {\n proxy_pass http://127.0.0.1:8000; #localhost\n }\n\n}\n```\n\n========================================\n\nComments:\n- This problem should apply on virtual server such as Digital Ocean, Vultr and Linode. The proposed solution works well.\n- Of course, I don't run the command from my local machine. My project is cloned to GCP and I run the command from the GC console.\n- There's no mistake now. `INFO: Application startup complete. INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)` But I still can't get a response when I contact the IP address. Is there any other nuance?\n- Probably you didn't open your port 8000 of your GCP yet.\n- Allowed port 8000 using ufw `sudo ufw allow 8000`\n- I am not a pro in GCP or DevOps, But, you can try running something else in your GCP (say python HTTP server) and can check whether it is publically available or not.\n- Thank you, I'll try to do the same on digitalocean. Maybe there's a problem with GCP.\n- Thanks.. This works well on Vultr VPS as expected.","metadata":{"transformedAt":"2026-08-18T18:32:29.103Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":8,"totalLines":142,"estimatedTokens":1161}}140{"id":"stack-69021077","source":"stackoverflow","questionId":69021077,"title":"Start an async background daemon in a Python FastAPI app","tags":["python","async-await","python-asyncio","fastapi"],"text":"Title: Start an async background daemon in a Python FastAPI app\nTags: python, async-await, python-asyncio, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm building an async backend for an analytics system using FastAPI. The thing is it has to: a) listen for API calls and be available at all times; b) periodically perform a data-gathering task (parsing data and saving it into the DB).\n\nI wrote this function to act as a daemon:\n\n```\nasync def start_metering_daemon(self) -> None:\n \"\"\"sets a never ending task for metering\"\"\"\n while True:\n delay: int = self._get_delay() # delay in seconds until next execution\n await asyncio.sleep(delay)\n await self.gather_meterings() # perfom data gathering\n```\n\nWhat I'm trying to achieve is so that when app starts it also adds this daemon function into the main event loop and execute it when it has time. However, I haven't been able to find a suitable solution which is adequate to the scale of the task (adding Celery and similar stuff is an overkill).\n\nI have tried following ways to achieve this but none of them worked:\n\n```\n@app.on_event(\"startup\")\nasync def startup_event() -> None:\n \"\"\"tasks to do at server startup\"\"\"\n await Gatherer().start_metering_daemon()\n```\n\nResult: server can't start up since the thread is blocked\n\n```\n@app.on_event(\"startup\")\nasync def startup_event() -> None:\n \"\"\"tasks to do at server startup\"\"\"\n fastapi.BackgroundTasks().add_task(Gatherer().start_metering_daemon)\n```\n\nResult: task is never executed as observed in logs\n\n```\n@app.on_event(\"startup\")\nasync def startup_event() -> None:\n \"\"\"tasks to do at server startup\"\"\"\n fastapi.BackgroundTasks().add_task(asyncio.run, Gatherer().start_metering_daemon())\n```\n\nResult: same as previous one\n\n```\n@app.on_event(\"startup\")\nasync def startup_event() -> None:\n \"\"\"tasks to do at server startup\"\"\"\n threading.Thread(target=asyncio.run, args=(Gatherer().start_metering_daemon(),)).start()\n```\n\nResult: this one works but a) makes no sence; b) spawns N identical threads for N Uvicorn workers which all write same data N times into the DB.\n\nI am out of solutions by now. I am pretty sure there must be a solution to my problem since is looks pretty trivial to me but I couldn't find one.\n\nIf you want more context here is the repo of the project I reffer to.\n\n========================================\n\nCode:\n```text\nasync def start_metering_daemon(self) -> None:\n \"\"\"sets a never ending task for metering\"\"\"\n while True:\n delay: int = self._get_delay() # delay in seconds until next execution\n await asyncio.sleep(delay)\n await self.gather_meterings() # perfom data gathering\n```\n\n```text\n@app.on_event(\"startup\")\nasync def startup_event() -> None:\n \"\"\"tasks to do at server startup\"\"\"\n await Gatherer().start_metering_daemon()\n```\n\n```text\n@app.on_event(\"startup\")\nasync def startup_event() -> None:\n \"\"\"tasks to do at server startup\"\"\"\n fastapi.BackgroundTasks().add_task(Gatherer().start_metering_daemon)\n```\n\n```text\n@app.on_event(\"startup\")\nasync def startup_event() -> None:\n \"\"\"tasks to do at server startup\"\"\"\n fastapi.BackgroundTasks().add_task(asyncio.run, Gatherer().start_metering_daemon())\n```\n\n```text\n@app.on_event(\"startup\")\nasync def startup_event() -> None:\n \"\"\"tasks to do at server startup\"\"\"\n threading.Thread(target=asyncio.run, args=(Gatherer().start_metering_daemon(),)).start()\n```\n\n```text\n@app.on_event(\"startup\")\nasync def startup_event() -> None:\n \"\"\"tasks to do at server startup\"\"\"\n asyncio.create_task(Gatherer().start_metering_daemon())\n```\n\n========================================\n\nComments:\n- If run the task every a given time is a option for you, you can try `rq`. While you need to install redis and the main objective of the library is work with queues, here there are examples of scheduling tasks: python-rq.org/docs/scheduling\n- can someone explain why background task solution doesn’t work but async io create task does ?\n- @toing from Starlette docs: \"A background task should be attached to a response, and will run only once the response has been sent\" so If there is no http request-response Background task won't run.\n- did you find a solution for this? Can we access the worker id somehow, and stop the tasks prematurely on all but one?\n- This is not working :( when you have other async operations within that function, it still throws: [2021-09-10 21:00:56 +0000] [1330] [CRITICAL] WORKER TIMEOUT (pid:1337) [2021-09-10 21:00:56 +0000] [1330] [WARNING] Worker with pid 1337 was terminated due to signal 6","metadata":{"transformedAt":"2026-08-18T18:32:29.103Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":6,"totalLines":117,"estimatedTokens":1139}}141{"id":"stack-66747059","source":"stackoverflow","questionId":66747059,"title":"Request context in FastAPI?","tags":["python","fastapi"],"text":"Title: Request context in FastAPI?\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nIn Flask, the request is available to any function that's down the call-path, so it doesn't have to be passed explicitly.\n\nIs there anything similar in FastAPI?\n\nBasically, I want to allow, within the same app, a request to be \"real\" or \"dummy\", where the dummy will not actually carry out some actions, just emit them (yes, I know that checking it down the stack is not nice, but I don't have control over all the code).\n\nlet's say I have\n\n```\n@app.post(\"/someurl\")\ndef my_response():\n func1()\n\ndef func1():\n func2()\n\ndef func2():\n # access some part of the request\n```\n\nI.e. where I don't need to pass the request as a param all the way down to func2.\n\nIn Flask, I'd just access the request directly, but I don't know how to do it in FastAPI.\nFor example, in Flask I could do\n\n```\ndef func2():\n x = request.my_variable\n # do somethinh with x\n```\n\nRequest here is local to the specific URL call, so if there are two concurrent execution of the func2 (with whatever URL), they will get the correct request.\n\n========================================\n\nTop Answer:\nI provided an answer that may be of help, here. It leverages ContextVars and Starlette middleware (used in FastAPI) to make request object information globally available. It doesn't make the *entire* request object globally available -- but if you have some specific data you need from the request object, this solution may help!\n\n========================================\n\nCode:\n```text\n@app.post(\"/someurl\")\ndef my_response():\n func1()\n\ndef func1():\n func2()\n\ndef func2():\n # access some part of the request\n```\n\n```text\ndef func2():\n x = request.my_variable\n # do somethinh with x\n```\n\n```py\nfrom fastapi import FastAPI, Request\n\n\napp = FastAPI()\n\n\n@app.get(\"/items/{item_id}\")\n\ndef read_root(item_id: str, request: Request):\n\n client_host = request.client.host\n\n return {\"client_host\": client_host, \"item_id\": item_id}\n```\n\n========================================\n\nComments:\n- It might be helpful to provide the `flask` code for clarity.\n- You could use class based handlers, like in django.(of course we have implement them by ourselves)\n- I know I can access the request directly, but in Flask I can access it anywhere in the call stack w/o passing it explicitly as a parameter i.e. flask.palletsprojects.com/en/1.1.x/reqcontext I've updated the question to make this explicit.\n- This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post. - From Review","metadata":{"transformedAt":"2026-08-18T18:32:29.103Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":3,"totalLines":87,"estimatedTokens":650}}142{"id":"stack-63471960","source":"stackoverflow","questionId":63471960,"title":"gunicorn uvicorn worker.py how to honor limit_concurrency setting","tags":["concurrency","gunicorn","fastapi","uvicorn","concurrency-limits"],"text":"Title: gunicorn uvicorn worker.py how to honor limit_concurrency setting\nTags: concurrency, gunicorn, fastapi, uvicorn, concurrency-limits\nSource: Stack Overflow\n\nQuestion:\nFastAPI uses gunicorn to launch uvicorn workers as described in https://www.uvicorn.org/settings/\n\nHowever gunicorn does not allow to launch uvicorn with custom settings as also mentiond in https://github.com/encode/uvicorn/issues/343\n\nThe issue suggested to override the config_kwargs in the source file like https://github.com/encode/uvicorn/blob/master/uvicorn/workers.py\n\nWe tried it but uvicorn is not honoring the setting `limit_concurrency` in multiple uvicorn files in the source:\n\nhttps://github.com/encode/uvicorn/blob/master/uvicorn/workers.py\n\n```\n# fail\n\n config_kwargs = {\n \"app\": None,\n \"log_config\": None,\n \"timeout_keep_alive\": self.cfg.keepalive,\n \"timeout_notify\": self.timeout,\n \"callback_notify\": self.callback_notify,\n \"limit_max_requests\": self.max_requests, \"limit_concurrency\": 10000,\n \"forwarded_allow_ips\": self.cfg.forwarded_allow_ips,\n }\n```\n\nhttps://github.com/encode/uvicorn/blob/master/uvicorn/main.py\n\n```\n# fail\n\n kwargs = {\n \"app\": app,\n \"host\": host,\n \"port\": port,\n \"uds\": uds,\n \"fd\": fd,\n \"loop\": loop,\n \"http\": http,\n \"ws\": ws,\n \"lifespan\": lifespan,\n \"env_file\": env_file,\n \"log_config\": LOGGING_CONFIG if log_config is None else log_config,\n \"log_level\": log_level,\n \"access_log\": access_log,\n \"interface\": interface,\n \"debug\": debug,\n \"reload\": reload,\n \"reload_dirs\": reload_dirs if reload_dirs else None,\n \"workers\": workers,\n \"proxy_headers\": proxy_headers,\n \"forwarded_allow_ips\": forwarded_allow_ips,\n \"root_path\": root_path,\n \"limit_concurrency\": 10000,\n \"backlog\": backlog,\n \"limit_max_requests\": limit_max_requests,\n \"timeout_keep_alive\": timeout_keep_alive,\n \"ssl_keyfile\": ssl_keyfile,\n \"ssl_certfile\": ssl_certfile,\n \"ssl_version\": ssl_version,\n \"ssl_cert_reqs\": ssl_cert_reqs,\n \"ssl_ca_certs\": ssl_ca_certs,\n \"ssl_ciphers\": ssl_ciphers,\n \"headers\": list([header.split(\":\") for header in headers]),\n \"use_colors\": use_colors,\n }\n```\n\nHow can uvicorn be forced to honor this setting? We are still getting 503 errors from the FastAPI\n\n-------UPDATE-----------\nthe gunicorn setting `--worker-connections 1000` still causes 503 when making 100 parallel requests that are distributed to many workers.\n\nHowever, I believe it is a bit more complicated issue: our API endpoint does a lot of heavy workload, usually takses 5 seconds to complete.\n\nStress test with 2 cores, 2 workers:\n\n- A. 100+ concurrent requests, endpoint heavy load --worker-connections 1\n\n- B. 100+ concurrent requests, endpoint heavy load --worker-connections 1000\n\n- C. 100+ concurrent requests, endpoint low load --worker-connections 1\n\n- D. 100+ concurrent requests, endpoint low load --worker-connections 1000\n\nBoth experiments A und B yielded 503 responses, so assuming the worker-connections setting does work, too many simulatenous connections seem to not cause our 503 errors.\n\nWe are puzzled about this behavior, because we expect gunicorn/uvicorn to queue the work and not throw 503 errors.\n\n========================================\n\nCode:\n```text\n# fail\n\n config_kwargs = {\n \"app\": None,\n \"log_config\": None,\n \"timeout_keep_alive\": self.cfg.keepalive,\n \"timeout_notify\": self.timeout,\n \"callback_notify\": self.callback_notify,\n \"limit_max_requests\": self.max_requests, \"limit_concurrency\": 10000,\n \"forwarded_allow_ips\": self.cfg.forwarded_allow_ips,\n }\n```\n\n```text\n# fail\n\n kwargs = {\n \"app\": app,\n \"host\": host,\n \"port\": port,\n \"uds\": uds,\n \"fd\": fd,\n \"loop\": loop,\n \"http\": http,\n \"ws\": ws,\n \"lifespan\": lifespan,\n \"env_file\": env_file,\n \"log_config\": LOGGING_CONFIG if log_config is None else log_config,\n \"log_level\": log_level,\n \"access_log\": access_log,\n \"interface\": interface,\n \"debug\": debug,\n \"reload\": reload,\n \"reload_dirs\": reload_dirs if reload_dirs else None,\n \"workers\": workers,\n \"proxy_headers\": proxy_headers,\n \"forwarded_allow_ips\": forwarded_allow_ips,\n \"root_path\": root_path,\n \"limit_concurrency\": 10000,\n \"backlog\": backlog,\n \"limit_max_requests\": limit_max_requests,\n \"timeout_keep_alive\": timeout_keep_alive,\n \"ssl_keyfile\": ssl_keyfile,\n \"ssl_certfile\": ssl_certfile,\n \"ssl_version\": ssl_version,\n \"ssl_cert_reqs\": ssl_cert_reqs,\n \"ssl_ca_certs\": ssl_ca_certs,\n \"ssl_ciphers\": ssl_ciphers,\n \"headers\": list([header.split(\":\") for header in headers]),\n \"use_colors\": use_colors,\n }\n```\n\n```text\nlimit_concurrency\n```\n\n```text\n--worker-connections 1000\n```\n\n```text\nuvicorn --limit-concurrency 100 application:demo_app\n```\n\n```text\ngunicorn --worker-connections 100 -k uvicorn.workers.UvicornWorker application:demo_app\n```\n\n```text\nfrom uvicorn.workers import UvicornWorker\n\n\nclass CustomUvicornWorker(UvicornWorker):\n CONFIG_KWARGS = {\n \"loop\": \"uvloop\",\n \"http\": \"httptools\",\n \"limit_concurrency\": 100\n }\n```\n\n```text\ngunicorn -k path.to.custom_worker.CustomUvicornWorker application:demo_app\n```\n\n```text\nworker-connections\n```\n\n```text\nlimit-concurrency\n```\n\n```text\nlimit-concurrency\n```\n\n```text\nlimit_concurrency\n```\n\n```text\nuvicorn.workers.UvicornWorker\n```\n\n```text\nCustomUvicornWorker\n```\n\n```text\ngunicorn\n```\n\n```text\nself.config.limit_concurrency\n```\n\n```text\nCustomUvicornWorker\n```\n\n========================================\n\nComments:\n- Very interested to know whether you resolved your 503 errors in the end, if so what combination of concurrency and backlog settings did you find worked best?\n- thanks for this! the gunicorn --worker-connections 1000 did not have any impact, I am still getting the 503 when I make many parallel requests. However our API endpoint does a lot of heavy workload, usually takses 5 seconds to complete. Yet we must do stress tests do see what happens if 100 customers do this request at the same time. This behavior with 503 response happens\n- I am not sure why that happe d to you, but, you can try three solutions. 1st, 2nd and combination of 1st and 2nd.\n- Yeah, I am not sure, if the 503 is due to concurrent connections, or other resource overload. I will also try the CustomUvicornWorker approach and test it\n- did you resolve this?\n- For gunicorn with uvicorn class worker-connections has no affect per documentation docs.gunicorn.org/en/stable/settings.html#worker-connections The maximum number of simultaneous clients. This setting only affects the gthread, eventlet and gevent worker types.","metadata":{"transformedAt":"2026-08-18T18:32:29.103Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":17,"totalLines":226,"estimatedTokens":1683}}143{"id":"stack-67806077","source":"stackoverflow","questionId":67806077,"title":"FastAPI: How to specify possible values for a field in Pydantic's Basemodel?","tags":["python","fastapi","pydantic"],"text":"Title: FastAPI: How to specify possible values for a field in Pydantic's Basemodel?\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI have a model like :\n\n```\n# Imports\nfrom pydantic import BaseModel\n\n# Data Models\nclass MyModel(BaseModel):\n a: str\n b: str\n c: str\n\n@app.post('/endpoint_to_post')\nasync def post_log(my_model: MyModel):\n```\n\nI want to specify some constraint on this model.\nIndeed, I need a ***possible values*** constraint on the field **C** of the model **MyModel**.\n\nLike:\n\n```\n# Imports\nfrom pydantic import BaseModel\n\n# Data Models\nclass MyModel(BaseModel):\n a: str\n b: str\n c: str in ['possible_value_1', 'possible_value_2']\n```\n\nThank for your help :)\n\n========================================\n\nTop Answer:\nYou can use enum from Python stdlib:\n\n```\nfrom enum import Enum\nfrom pydantic import BaseModel\n\nclass CEnum(Enum):\n VALUE_1 = 'possible_value_1'\n VALUE_2 = 'possible_value_2'\n\n# Data Models\nclass MyModel(BaseModel):\n a: str\n b: str\n c: CEnum\n```\n\nPydantic will automatically convert any string matching the enum value to the correct enum instance and will raise `ValidationError` if it doesn't match anything. You can combine it with `Optional` or `Union` from Python's `typing` to either make this field optional or to allow other types as well (the first matching type from all types passed to `Union` will be used by Pydantic, so you can create a \"catch-all\" scenario using `Union[CEnum, str]`).\n\n========================================\n\nCode:\n```py\n# Imports\nfrom pydantic import BaseModel\n\n# Data Models\nclass MyModel(BaseModel):\n a: str\n b: str\n c: str\n\n@app.post('/endpoint_to_post')\nasync def post_log(my_model: MyModel):\n```\n\n```py\n# Imports\nfrom pydantic import BaseModel\n\n# Data Models\nclass MyModel(BaseModel):\n a: str\n b: str\n c: str in ['possible_value_1', 'possible_value_2']\n```\n\n```py\nfrom pydantic import BaseModel\nfrom typing import Literal\n\n# Data Models\nclass MyModel(BaseModel):\n a: str\n b: str\n c: Literal['possible_value_1', 'possible_value_2']\n```\n\n```text\nLiteral\n```\n\n```text\nfrom enum import Enum\nfrom pydantic import BaseModel\n\n\nclass CEnum(Enum):\n VALUE_1 = 'possible_value_1'\n VALUE_2 = 'possible_value_2'\n\n\n# Data Models\nclass MyModel(BaseModel):\n a: str\n b: str\n c: CEnum\n```\n\n```text\nValidationError\n```\n\n```text\nOptional\n```\n\n```text\nUnion\n```\n\n```text\ntyping\n```\n\n```text\nUnion\n```\n\n```text\nUnion[CEnum, str]\n```\n\n```py\n# Imports\nfrom pydantic import BaseModel, validator\n\n# Data Models\nclass MyModel(BaseModel):\n a: str\n b: str\n c: str # in ['possible_value_1', 'possible_value_2']\n\n @validator('c')\n def c_match(cls, v):\n if not v in ['possible_value_1', 'possible_value_2']:\n raise ValueError('c must be in [possible_value_1, possible_value_2]')\n return v\n```\n\n========================================\n\nComments:\n- Does this answer your question? How to require predefined string values in python pydantic basemodels?\n- I didn't try it, but seems a good solution. Thank!\n- Does this answer your question? How to add drop down menu to Swagger UI autodocs based on BaseModel using FastAPI?\n- Thank for your answer :) I found another soltuion using pydantic.validator (and an unique model) if you want to check\n- This is much flexible.\n- This works but you will get an Enum after deserialization. If you *need it to be string* after deserialization, `Literal` is more appropriate as answered here stackoverflow.com/a/74113892/14052910.\n- ConfigDict has a flag `use_enum_values = True` for this case docs.pydantic.dev/latest/api/config/…\n- Is there can way where I can validate from a external list?\n- @SwapnilMasurekar external list means a list with unknown items? if you cant specify the full list of options in advance it is not a type. just check in a `@validator` if the param is as expected","metadata":{"transformedAt":"2026-08-18T18:32:29.103Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":12,"totalLines":174,"estimatedTokens":968}}144{"id":"stack-68095483","source":"stackoverflow","questionId":68095483,"title":"What is the maximum size of upload file we can receive in FastAPI?","tags":["python","http","backend","server-side","fastapi"],"text":"Title: What is the maximum size of upload file we can receive in FastAPI?\nTags: python, http, backend, server-side, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to figure out the maximum file size, my client can upload , so that my python fastapi server can handle it without any problem.\n\n========================================\n\nCode:\n```py\nclass Request(HTTPConnection):\n ...\n async def stream(self) -> typing.AsyncGenerator[bytes, None]:\n if hasattr(self, \"_body\"):\n yield self._body\n yield b\"\"\n return\n\n if self._stream_consumed:\n raise RuntimeError(\"Stream consumed\")\n\n self._stream_consumed = True\n while True:\n message = await self._receive()\n if message[\"type\"] == \"http.request\":\n body = message.get(\"body\", b\"\")\n if body:\n yield body\n if not message.get(\"more_body\", False):\n break\n elif message[\"type\"] == \"http.disconnect\":\n self._is_disconnected = True\n raise ClientDisconnect()\n yield b\"\"\n\n async def body(self) -> bytes:\n if not hasattr(self, \"_body\"):\n chunks = []\n async for chunk in self.stream():\n chunks.append(chunk)\n self._body = b\"\".join(chunks)\n return self._body\n```\n\n```text\nclient_max_body_size\n```\n\n```text\nLimitRequestBody\n```\n\n```text\n--limit-request-line\n```\n\n```text\n--limit-request-fields\n```\n\n```text\n--limit-request-field_size\n```\n\n========================================\n\nComments:\n- As far as I can tell, there is no actual limit: github.com/encode/starlette/issues/890 - see github.com/tiangolo/fastapi/issues/362 for how to implement a limit based on the `Content-Length` header\n- thanks for answering, aren't there any http payload size limitations also?\n- If you're thinking of POST size, that's discussed in those tickets - but it would depend on whether you're serving requests through FastAPI/Starlette directly on the web, or if it goes through nginx or similar first. Any part of the chain may introduce limitations on the size allowed.\n- Please have a look at this answer on how to read the request body in chunks using `.stream()`, and hence, enforce body/file size limits in your application.","metadata":{"transformedAt":"2026-08-18T18:32:29.103Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":6,"totalLines":72,"estimatedTokens":588}}145{"id":"stack-68156262","source":"stackoverflow","questionId":68156262,"title":"How to set environment variable based on development or production in FastAPI?","tags":["python","environment-variables","development-environment","production-environment","fastapi"],"text":"Title: How to set environment variable based on development or production in FastAPI?\nTags: python, environment-variables, development-environment, production-environment, fastapi\nSource: Stack Overflow\n\nQuestion:\nI want to have different environment variables based on development and production\nbut i can't seem to find anything related to this topic for FastAPI.\n\nIs it possible that i can have .env, .env.local, .env.prod to have different environment variables\n\n========================================\n\nTop Answer:\nAn alternative approach could be to use the Pydantic Settings:\nhttps://pydantic-docs.helpmanual.io/usage/settings/\n\nThere is also a bit about that in the FastAPI docs, but personally I choose not to 'integrate' the nice Pydantic Settings that way.\nhttps://fastapi.tiangolo.com/advanced/settings/\n\n========================================\n\nCode:\n```text\nheroku config:set SOME_CONFIG_I_NEED=value for production\n```\n\n```text\npip install python-dotenv\n```\n\n```text\n# Development settings\nSOME_CONFIG_I_NEED=value for development\n```\n\n```text\nfrom dotenv import load_dotenv\n\nload_dotenv() # take environment variables from .env.\n\nSOME_CONFIG_I_NEED = os.environ.get(\"SOME_CONFIG_I_NEED\")\n\nprint(SOME_CONFIG_I_NEED) # This will print \"value for development\" when running on local, and will print \"value for production\" when running in Heroku.\n```\n\n```text\nheroku config\n```\n\n```text\npython-dotenv\n```\n\n```text\n.env\n```\n\n========================================\n\nComments:\n- Hi thanks for the reply. Can i use env variables like the following example; FOO=myenvvar BAR=${FOO}.mysecondvar on heroku config vars?\n- @AhmetK I edited my answer with an example.\n- Remember to upvote and mark it as the answer for your question if it helped.\n- i have another question from your example can i have a environment variable like the following; ( MY_ENV = ${GITHUB_USERNAME}something )\n- You want to append something to the value?\n- docs.pydantic.dev/latest/concepts/pydantic_settings the link above is not working, here is the working link","metadata":{"transformedAt":"2026-08-18T18:32:29.104Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":7,"totalLines":66,"estimatedTokens":512}}146{"id":"stack-69492265","source":"stackoverflow","questionId":69492265,"title":"FastAPI, SQLAlchemy, pytest, unable to get 100% coverage, it doesn't properly collected","tags":["python","sqlalchemy","python-asyncio","fastapi","pytest-asyncio"],"text":"Title: FastAPI, SQLAlchemy, pytest, unable to get 100% coverage, it doesn't properly collected\nTags: python, sqlalchemy, python-asyncio, fastapi, pytest-asyncio\nSource: Stack Overflow\n\nQuestion:\nI'm trying to build `FastAPI` application fully covered with test using `python 3.9`\nFor this purpose I've chosen stack:\nFastAPI, uvicorn, SQLAlchemy, asyncpg, pytest (+ async, cov plugins), coverage and httpx AsyncClient\n\nHere is my minimal requirements.txt\n\nAll tests run smoothly and I get the expected results.\nBut I've faced the problem, coverage doesn't properly collected. It breaks after a first `await` keyword, when coroutine returns control back to the event loop\n\nHere is a minimal set on how to reproduce this behavior (it's also available on a GitHub).\n\nAppliaction code `main.py`:\n\n```\nimport sqlalchemy as sa\nfrom fastapi import FastAPI\nfrom sqlalchemy.ext.asyncio import AsyncSession, create_async_engine\nfrom starlette.requests import Request\n\napp = FastAPI()\nDATABASE_URL = 'sqlite+aiosqlite://?cache=shared'\n\n@app.on_event('startup')\nasync def startup_event():\n engine = create_async_engine(DATABASE_URL, future=True)\n app.state.session = AsyncSession(engine, expire_on_commit=False)\n app.state.engine = engine\n\n@app.on_event('shutdown')\nasync def shutdown_event():\n await app.state.session.close()\n\n@app.get('/', name=\"home\")\nasync def get_home(request: Request):\n res = await request.app.state.session.execute(sa.text('SELECT 1'))\n # after this line coverage breaks\n row = res.first()\n assert str(row[0]) == '1'\n return {\"message\": \"OK\"}\n```\n\ntest setup `conftest.py` looks like this:\n\n```\nimport asyncio\n\nimport pytest\nfrom asgi_lifespan import LifespanManager\nfrom httpx import AsyncClient\n\n@pytest.fixture(scope='session')\nasync def get_app():\n from main import app\n async with LifespanManager(app):\n yield app\n\n@pytest.fixture(scope='session')\nasync def get_client(get_app):\n async with AsyncClient(app=get_app, base_url=\"http://testserver\") as client:\n yield client\n\n@pytest.fixture(scope=\"session\")\ndef event_loop():\n loop = asyncio.new_event_loop()\n yield loop\n loop.close()\n```\n\ntest is simple as it is (just check status code is 200) `test_main.py`:\n\n```\nimport pytest\nfrom starlette import status\n\n@pytest.mark.asyncio\nasync def test_view_health_check_200_ok(get_client):\n res = await get_client.get('/')\n assert res.status_code == status.HTTP_200_OK\n```\n\n```\npytest -vv --cov=. --cov-report term-missing --cov-report html\n```\n\nAs a result coverage I get:\n\n```\nName Stmts Miss Cover Missing\n--------------------------------------------\nconftest.py 18 0 100%\nmain.py 20 3 85% 26-28\ntest_main.py 6 0 100%\n--------------------------------------------\nTOTAL 44 3 93%\n```\n\nhttps://i.sstatic.net/KvKRh.png\n\n- Example code above uses `aiosqlite` instead of `asyncpg` but coverage failure also reproduces persistently\n\n- I've concluded this problem is with `SQLAlchemy`, because this example with `asyncpg` without using the `SQLAlchemy` works like charm\n\n========================================\n\nTop Answer:\nThat is what helped me:\n\nYou can add coverage concurrency `greenlet` settings into your configs `setup.cfg` or `.coveragerc` file:\n\n```\n[coverage:run]\nbranch = True\nconcurrency =\n greenlet\n thread\n```\n\n========================================\n\nCode:\n```py\nimport sqlalchemy as sa\nfrom fastapi import FastAPI\nfrom sqlalchemy.ext.asyncio import AsyncSession, create_async_engine\nfrom starlette.requests import Request\n\napp = FastAPI()\nDATABASE_URL = 'sqlite+aiosqlite://?cache=shared'\n\n\n@app.on_event('startup')\nasync def startup_event():\n engine = create_async_engine(DATABASE_URL, future=True)\n app.state.session = AsyncSession(engine, expire_on_commit=False)\n app.state.engine = engine\n\n\n@app.on_event('shutdown')\nasync def shutdown_event():\n await app.state.session.close()\n\n\n@app.get('/', name=\"home\")\nasync def get_home(request: Request):\n res = await request.app.state.session.execute(sa.text('SELECT 1'))\n # after this line coverage breaks\n row = res.first()\n assert str(row[0]) == '1'\n return {\"message\": \"OK\"}\n```\n\n```py\nimport asyncio\n\nimport pytest\nfrom asgi_lifespan import LifespanManager\nfrom httpx import AsyncClient\n\n\n@pytest.fixture(scope='session')\nasync def get_app():\n from main import app\n async with LifespanManager(app):\n yield app\n\n\n@pytest.fixture(scope='session')\nasync def get_client(get_app):\n async with AsyncClient(app=get_app, base_url=\"http://testserver\") as client:\n yield client\n\n\n@pytest.fixture(scope=\"session\")\ndef event_loop():\n loop = asyncio.new_event_loop()\n yield loop\n loop.close()\n```\n\n```py\nimport pytest\nfrom starlette import status\n\n\n@pytest.mark.asyncio\nasync def test_view_health_check_200_ok(get_client):\n res = await get_client.get('/')\n assert res.status_code == status.HTTP_200_OK\n```\n\n```sh\npytest -vv --cov=. --cov-report term-missing --cov-report html\n```\n\n```text\nName Stmts Miss Cover Missing\n--------------------------------------------\nconftest.py 18 0 100%\nmain.py 20 3 85% 26-28\ntest_main.py 6 0 100%\n--------------------------------------------\nTOTAL 44 3 93%\n```\n\n```text\nFastAPI\n```\n\n```text\npython 3.9\n```\n\n```text\nawait\n```\n\n```text\nmain.py\n```\n\n```text\nconftest.py\n```\n\n```text\ntest_main.py\n```\n\n```text\naiosqlite\n```\n\n```text\nasyncpg\n```\n\n```text\nSQLAlchemy\n```\n\n```text\nasyncpg\n```\n\n```text\nSQLAlchemy\n```\n\n```text\n--concurrency==greenlet\n```\n\n```text\n[coverage:run]\nbranch = True\nconcurrency =\n greenlet\n thread\n```\n\n```text\ngreenlet\n```\n\n```text\nsetup.cfg\n```\n\n```text\n.coveragerc\n```\n\n========================================\n\nComments:\n- I owe you one! It worked!","metadata":{"transformedAt":"2026-08-18T18:32:29.104Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":21,"totalLines":281,"estimatedTokens":1430}}147{"id":"stack-61497145","source":"stackoverflow","questionId":61497145,"title":"Pydantic model for array of jsons","tags":["python","fastapi","pydantic"],"text":"Title: Pydantic model for array of jsons\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI am using FastAPI to write a web service. It is good and fast.\n\nFastAPI is using pydantic models to validate input and output data, everything is good but when I want to declare a nested model for array of jsons like below:\n\n```\n[\n {\n \"name\": \"name1\",\n \"family\": \"family1\"\n },\n {\n \"name\": \"name2\",\n \"family\": \"family2\"\n }\n]\n```\n\nI get empty response.\n\nI think there is a problem with my model which is:\n\n```\nclass Test(BaseModel):\n name: str\n family: str\n class Config:\n orm_mode = True\n\nclass Tests(BaseModel):\n List[Test]\n class Config:\n orm_mode = True\n```\n\nSo, my question is how should I write a model for array of jsons?\n\n========================================\n\nTop Answer:\nOne thing that I was able to achieve with Pydantic V2 that plays nicely in OpenAPI is importing from RootModel instead of BaseModel:\n\n```\nclass Test(BaseModel):\n name: str\n family: str\n class Config:\n orm_mode = True\n\nclass Tests(RootModel[List[Test]]):\n pass\n```\n\nbut as highlighted above, this is not strictly necessary.\n\n========================================\n\nCode:\n```text\n[\n {\n \"name\": \"name1\",\n \"family\": \"family1\"\n },\n {\n \"name\": \"name2\",\n \"family\": \"family2\"\n }\n]\n```\n\n```text\nclass Test(BaseModel):\n name: str\n family: str\n class Config:\n orm_mode = True\n\nclass Tests(BaseModel):\n List[Test]\n class Config:\n orm_mode = True\n```\n\n```py\n@app.get(\"/tests\", response_model=list[Test])\n```\n\n```py\nfrom typing import List\n\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\n\n\nexisting_tests = [\n {\n \"name\": \"name1\",\n \"family\": \"family1\"\n },\n {\n \"name\": \"name2\",\n \"family\": \"family2\"\n }\n]\n\n\nclass Test(BaseModel):\n name: str\n family: str\n\n class Config:\n orm_mode = True\n\n\napp = FastAPI()\n\n\n@app.get(\"/tests\", response_model=List[Test])\nasync def fetch_tests():\n return existing_tests\n\n\n@app.post(\"/tests\")\nasync def submit_tests(new_tests: List[Test]):\n print(new_tests)\n```\n\n```py\nTests = List[Test]\n\n@app.get(\"/tests\", response_model=Tests)\nasync def fetch_tests():\n return existing_tests\n\n@app.post(\"/tests\")\nasync def submit_tests(new_tests: Tests):\n print(new_tests)\n```\n\n```text\nlist\n```\n\n```text\nList\n```\n\n```text\ntyping\n```\n\n```text\nList[]\n```\n\n```text\ntyping\n```\n\n```text\nBaseModel\n```\n\n```text\nList[Test]\n```\n\n```text\nTest\n```\n\n```text\nTest\n```\n\n```text\nList[Test]\n```\n\n```text\nclass Test(BaseModel):\n name: str\n family: str\n class Config:\n orm_mode = True\n\nclass Tests(RootModel[List[Test]]):\n pass\n```\n\n========================================\n\nComments:\n- Notice you have \"orm_mode = True\" , most likely you are experiencing a problem with you ORM and not with your Pydantic models... can't say much more because you have not provided details or your ORM.\n- If you are POSTing json data, fastapi will try to convert it automatically to a pydantic model. Otherwise, you may simply declare a field as an array, as you did in Tests. Have you tried removing the \"class Config: orm_mode = True\" piece of code?\n- this is awesome! hadn't seen much good docs on how to return lists with FastAPI which seems like a super common use case.\n- This gives me a warning in PyCharm: `Expected type 'Optional[type]', got 'GenericAlias' instead`, but works.\n- @A.Rabus I get warning too. Should we use the **typing** `List`, or **Python 3.9** `list`?","metadata":{"transformedAt":"2026-08-18T18:32:29.104Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":16,"totalLines":203,"estimatedTokens":874}}148{"id":"stack-62351462","source":"stackoverflow","questionId":62351462,"title":"FastAPI app running locally but not in Docker container","tags":["python","docker","fastapi","facebook-prophet"],"text":"Title: FastAPI app running locally but not in Docker container\nTags: python, docker, fastapi, facebook-prophet\nSource: Stack Overflow\n\nQuestion:\nI have a FastAPI app that is working as expected when running locally, however, I get an 'Internal Server Error' when I try to run in a Docker container. Here's the code for my app:\n\n```\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\nimport pandas as pd\nfrom fbprophet import Prophet\n\nclass Data(BaseModel):\n length: int\n ds: list\n y: list\n model: str\n changepoint: float = 0.5\n daily: bool = False\n weekly: bool = False\n annual: bool = False\n upper: float = None\n lower: float = 0.0\n national_holidays: str = None\n\napp = FastAPI()\n\n@app.post(\"/predict/\")\nasync def create_item(data: Data):\n\n # Create df from base model\n df = pd.DataFrame(list(zip(data.ds, data.y)), columns =['ds', 'y'])\n\n # Add the cap and floor to df for logistic model\n if data.model == \"logistic\":\n df['y'] = 10 - df['y']\n df['cap'] = data.upper\n df['floor'] = data.lower\n\n # make basic prediction\n m = Prophet(growth=data.model,\n changepoint_prior_scale=data.changepoint,\n weekly_seasonality=data.weekly,\n daily_seasonality=data.daily,\n yearly_seasonality=data.annual\n )\n\n # Add national holidays\n if data.national_holidays is not None:\n m.add_country_holidays(country_name=data.national_holidays)\n\n # Fit data frame\n m.fit(df)\n\n # Create data frame for future\n future = m.make_future_dataframe(periods=data.length)\n\n # Add the cap and floor to future for logistic model\n if data.model == \"logistic\":\n future['cap'] = 6\n future['floor'] = 1.5\n\n # forecast\n forecast = m.predict(future)\n\n # Print values\n print(list(forecast[['ds']].values))\n\n # Return results\n # {'ds': forecast[['ds']], 'yhat': forecast[['yhat']], 'yhat_lower': forecast[['yhat_lower']], 'yhat_upper': forecast[['yhat_upper']] }\n return [forecast[['ds']], forecast[['yhat']], forecast[['yhat_lower']], forecast[['yhat_upper']]]\n```\n\nWhich is working locally with `uvicorn main:app`, but not when I build using this Dockerfile:\n\n```\nFROM tiangolo/uvicorn-gunicorn-fastapi:python3.7\nCOPY ./app /app\nRUN pip install -r requirements.txt\n```\n\nand start with\n\n```\ndocker run -d --name mycontainer -p 8000:80 myimage\n```\n\nI'm seeing `Internal Server Error` in Postman. Is there something wrong with my dockerfile or docker commands? Or else how do I debug this?\n\n========================================\n\nTop Answer:\nThere are a number of possible issues here.\n\nWhen running in a container, you need to tell Uvicorn to not care about the incoming host IP with option `--host 0.0.0.0`\n\nYou have not specified the command executed when the image runs. Best to make this clear in the dockerfile e.g. `CMD [\"uvicorn\", \"main:app\", \"--host\", \"0.0.0.0\", \"--port\", \"8000\"]`\n\nMake sure when you run the image you map the ports correctly. From what you have given you are expecting the service in the container to be listening on port 80, that is OK but the default for uvicorn is 8000 (see point 2 for explicitly setting port).\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\nimport pandas as pd\nfrom fbprophet import Prophet\n\nclass Data(BaseModel):\n length: int\n ds: list\n y: list\n model: str\n changepoint: float = 0.5\n daily: bool = False\n weekly: bool = False\n annual: bool = False\n upper: float = None\n lower: float = 0.0\n national_holidays: str = None\n\napp = FastAPI()\n\n@app.post(\"/predict/\")\nasync def create_item(data: Data):\n\n # Create df from base model\n df = pd.DataFrame(list(zip(data.ds, data.y)), columns =['ds', 'y'])\n\n # Add the cap and floor to df for logistic model\n if data.model == \"logistic\":\n df['y'] = 10 - df['y']\n df['cap'] = data.upper\n df['floor'] = data.lower\n\n # make basic prediction\n m = Prophet(growth=data.model,\n changepoint_prior_scale=data.changepoint,\n weekly_seasonality=data.weekly,\n daily_seasonality=data.daily,\n yearly_seasonality=data.annual\n )\n\n # Add national holidays\n if data.national_holidays is not None:\n m.add_country_holidays(country_name=data.national_holidays)\n\n # Fit data frame\n m.fit(df)\n\n # Create data frame for future\n future = m.make_future_dataframe(periods=data.length)\n\n # Add the cap and floor to future for logistic model\n if data.model == \"logistic\":\n future['cap'] = 6\n future['floor'] = 1.5\n\n # forecast\n forecast = m.predict(future)\n\n # Print values\n print(list(forecast[['ds']].values))\n\n # Return results\n # {'ds': forecast[['ds']], 'yhat': forecast[['yhat']], 'yhat_lower': forecast[['yhat_lower']], 'yhat_upper': forecast[['yhat_upper']] }\n return [forecast[['ds']], forecast[['yhat']], forecast[['yhat_lower']], forecast[['yhat_upper']]]\n```\n\n```text\nFROM tiangolo/uvicorn-gunicorn-fastapi:python3.7\nCOPY ./app /app\nRUN pip install -r requirements.txt\n```\n\n```text\ndocker run -d --name mycontainer -p 8000:80 myimage\n```\n\n```text\nuvicorn main:app\n```\n\n```text\nInternal Server Error\n```\n\n```text\n-d\n```\n\n```text\n--host 0.0.0.0\n```\n\n```text\nCMD [\"uvicorn\", \"main:app\", \"--host\", \"0.0.0.0\", \"--port\", \"8000\"]\n```\n\n```text\ncommand: uvicorn main:app --host 0.0.0.0 --port 8000\n```\n\n```text\n--port 8000\n```\n\n```py\nuvicorn.run(\n \"exg_platform.web.application:get_app\",\n workers=settings.workers_count,\n host=\"0.0.0.0\", # Bind to all interfaces\n port=settings.port,\n reload=settings.reload,\n log_level=settings.log_level.lower(),\n factory=True,\n)\n```\n\n```text\nsettings.host\n```\n\n```text\nsettings.host\n```\n\n```text\n127.0.0.1\n```\n\n```text\n127.0.0.1\n```\n\n```text\nlocalhost\n```\n\n```text\n127.0.0.1\n```\n\n```text\n127.0.0.1\n```\n\n```text\nsettings.host\n```\n\n```text\n0.0.0.0\n```\n\n```text\nsettings.host\n```\n\n```text\n0.0.0.0\n```\n\n========================================\n\nComments:\n- Check the log of the Docker container!\n- The second point helped me thanks!","metadata":{"transformedAt":"2026-08-18T18:32:29.104Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":22,"totalLines":270,"estimatedTokens":1500}}149{"id":"stack-71400788","source":"stackoverflow","questionId":71400788,"title":"FastAPI - Add description for path parameter in swagger","tags":["fastapi"],"text":"Title: FastAPI - Add description for path parameter in swagger\nTags: fastapi\nSource: Stack Overflow\n\nQuestion:\nImagine there is an app like that:\n\n```\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/items/{item_id}\")\nasync def read_item(item_id: int):\n return {\"item_id\": item_id}\n```\n\nHow could one add description for path parameter `item_id` in swagger?\n\n========================================\n\nTop Answer:\nLike this\n\n```\n@app.get(\"/items/{item_id}\")\nasync def read_item(item_id: int):\n \"\"\"\n item_id: Your item ID description will be here\n \"\"\"\n return {\"item_id\": item_id}\n```\n\nswagger doc\nhttps://i.sstatic.net/OQLeS.png\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n\n@app.get(\"/items/{item_id}\")\nasync def read_item(item_id: int):\n return {\"item_id\": item_id}\n```\n\n```text\nitem_id\n```\n\n```text\nitem_id: int = Path(..., description=\"An id representing an item\")\n```\n\n```text\ndescription\n```\n\n```text\n...\n```\n\n```text\n...\n```\n\n```text\nPath\n```\n\n```py\n@app.get(\"/items/{item_id}\")\nasync def read_item(item_id: int):\n \"\"\"\n item_id: Your item ID description will be here\n \"\"\"\n return {\"item_id\": item_id}\n```\n\n========================================\n\nComments:\n- Does `item_id: int = Path(..., description=\"An id representing an item\")` do what you're looking for?\n- @MatsLindh, yes) Please post it as answer. I will accept it.\n- This is not specific to the parameter item_id but to the function\n- obviously, it is just as an example.\n- I tried this and got an error that said path parameters cannot have default values, so try removing the default value if this doesn't work for you.\n- Ah, yes, that was made an error in the latest FastAPI release. Remove it if you're using 0.95+ (iirc.)","metadata":{"transformedAt":"2026-08-18T18:32:29.104Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":8,"totalLines":92,"estimatedTokens":444}}150{"id":"stack-71203579","source":"stackoverflow","questionId":71203579,"title":"How to return a csv file/Pandas DataFrame in JSON format using FastAPI?","tags":["python","pandas","dataframe","csv","fastapi"],"text":"Title: How to return a csv file/Pandas DataFrame in JSON format using FastAPI?\nTags: python, pandas, dataframe, csv, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have a `.csv` file that I would like to render in a FastAPI app. I only managed to render the `.csv` file in JSON format as follows:\n\n```\ndef transform_question_format(csv_file_name):\n\n json_file_name = f\"{csv_file_name[:-4]}.json\"\n\n # transforms the csv file into json file\n pd.read_csv(csv_file_name ,sep=\",\").to_json(json_file_name)\n\n with open(json_file_name, \"r\") as f:\n json_data = json.load(f)\n\n return json_data\n\n@app.get(\"/questions\")\ndef load_questions():\n\n question_json = transform_question_format(question_csv_filename)\n\n return question_json\n```\n\nWhen I tried returning directly `pd.read_csv(csv_file_name ,sep=\",\").to_json(json_file_name)`, it works, as it returns a string.\n\nHow should I proceed? I believe this is not the good way to do it.\n\n========================================\n\nTop Answer:\nWith the `DataFrame.to_dict()` method, not all Pandas datatypes are serializable by the `json` package:\n\n```\ndf = pd.DataFrame({\n \"TrainID\": [\"T001\", \"T002\", \"T003\"],\n \"Route\": [\"Amsterdam - Utrecht\", \"Rotterdam - Den Haag\", \"Eindhoven - Tilburg\"],\n \"DepartureTime\": [\n pd.Timestamp(\"2022-03-09 08:00:00\"),\n pd.Timestamp(\"2022-03-09 09:15:00\"),\n pd.Timestamp(\"2022-03-09 10:30:00\"),\n ],\n \"ArrivalTime\": [\n pd.Timestamp(\"2022-03-09 09:00:00\"),\n pd.Timestamp(\"2022-03-09 09:45:00\"),\n pd.Timestamp(\"2022-03-09 11:00:00\"),\n ],\n \"Status\": [\"On Time\", \"Delayed\", \"Cancelled\"],\n})\n\njson.dumps(df.to_dict(orient=\"records\"))\n```\n\nTypeError: Object of type Timestamp is not JSON serializable\n\nI have a `DataFrameJSONResponse` class to use the `pandas.DataFrame.to_json` instead of the `json.dumps`:\n\n```\nfrom fastapi.responses import Response\nfrom typing import Any\n\nclass DataFrameJSONResponse(Response):\n media_type = \"application/json\"\n\n def render(self, content: Any) -> bytes:\n return content.to_json(orient=\"records\", date_format='iso').encode(\"utf-8\")\n\n@app.get(\"/test\", response_class=DataFrameJSONResponse)\nasync def test_dataframe():\n df = pd.DataFrame(\n {\n \"TrainID\": [\"T001\", \"T002\", \"T003\"],\n \"Route\": [\n \"Amsterdam - Utrecht\",\n \"Rotterdam - Den Haag\",\n \"Eindhoven - Tilburg\",\n ],\n \"DepartureTime\": [\n pd.Timestamp(\"2022-03-09 08:00:00\"),\n pd.Timestamp(\"2022-03-09 09:15:00\"),\n pd.Timestamp(\"2022-03-09 10:30:00\"),\n ],\n \"ArrivalTime\": [\n pd.Timestamp(\"2022-03-09 09:00:00\"),\n pd.Timestamp(\"2022-03-09 09:45:00\"),\n pd.Timestamp(\"2022-03-09 11:00:00\"),\n ],\n \"Status\": [\"On Time\", \"Delayed\", \"Cancelled\"],\n }\n )\n\n return DataFrameJSONResponse(df)\n```\n\n========================================\n\nCode:\n```text\ndef transform_question_format(csv_file_name):\n\n json_file_name = f\"{csv_file_name[:-4]}.json\"\n\n # transforms the csv file into json file\n pd.read_csv(csv_file_name ,sep=\",\").to_json(json_file_name)\n\n with open(json_file_name, \"r\") as f:\n json_data = json.load(f)\n\n return json_data\n\n@app.get(\"/questions\")\ndef load_questions():\n\n question_json = transform_question_format(question_csv_filename)\n\n return question_json\n```\n\n```text\n.csv\n```\n\n```text\n.csv\n```\n\n```text\npd.read_csv(csv_file_name ,sep=\",\").to_json(json_file_name)\n```\n\n```py\nfrom fastapi import FastAPI\nimport pandas as pd\nimport json\n\napp = FastAPI()\ndf = pd.read_csv(\"file.csv\")\n\ndef parse_csv(df):\n res = df.to_json(orient=\"records\")\n parsed = json.loads(res)\n return parsed\n \n@app.get(\"/questions\")\ndef load_questions():\n return parse_csv(df)\n```\n\n```py\n@app.get(\"/questions\")\ndef load_questions():\n return df.to_dict(orient=\"records\")\n```\n\n```py\nfrom fastapi import Response\n\n@app.get(\"/questions\")\ndef load_questions():\n return Response(df.to_json(orient=\"records\"), media_type=\"application/json\")\n```\n\n```py\n@app.get(\"/questions\")\ndef load_questions():\n return df.to_string()\n```\n\n```py\nfrom fastapi.responses import HTMLResponse\n\n@app.get(\"/questions\")\ndef load_questions():\n return HTMLResponse(content=df.to_html(), status_code=200)\n```\n\n```py\nfrom fastapi.responses import FileResponse\n\n@app.get(\"/questions\")\ndef load_questions():\n return FileResponse(path=\"file.csv\", filename=\"file.csv\")\n```\n\n```text\n.csv\n```\n\n```text\nJSON\n```\n\n```text\ndict\n```\n\n```text\norient\n```\n\n```text\n.to_json()\n```\n\n```text\n.to_dict()\n```\n\n```text\ndict\n```\n\n```text\ndf.to_json()\n```\n\n```text\ndict\n```\n\n```text\njson.loads()\n```\n\n```text\n.to_dict()\n```\n\n```text\ndict\n```\n\n```text\nJSON\n```\n\n```text\njson.dumps()\n```\n\n```text\njsonable_encoder\n```\n\n```text\nJSONResponse\n```\n\n```text\n.to_json()\n```\n\n```text\nJSON\n```\n\n```text\nResponse\n```\n\n```text\nstring\n```\n\n```text\n.to_string()\n```\n\n```text\nHTML\n```\n\n```text\n.to_html()\n```\n\n```text\nfile\n```\n\n```text\nFileResponse\n```\n\n```text\nimport jsonpickle.ext.pandas as jsonpickle_pandas\nfrom jsonpickle.pickler import Pickler\n\njsonpickle_pandas.register_handlers()\n\n@app.post(\"/question\")\ndef answer_question():\n df = pd.DataFrame(...)\n p = Pickler()\n # convert the dataframe to a json-compatible dictionary\n response = p.flatten(df)\n # let FastAPI do the json conversion\n return response\n```\n\n```text\nfrom jsonpickle.unpickler import Unpickler\nimport jsonpickle.ext.pandas as jsonpickle_pandas\njsonpickle_pandas.register_handlers()\n\nresponse = requests.post(\"http://localhost:8000/question/\")\nres = response.json()\n\nu = Unpickler()\ndf = u.restore(res)\n```\n\n```py\ndf = pd.DataFrame({\n \"TrainID\": [\"T001\", \"T002\", \"T003\"],\n \"Route\": [\"Amsterdam - Utrecht\", \"Rotterdam - Den Haag\", \"Eindhoven - Tilburg\"],\n \"DepartureTime\": [\n pd.Timestamp(\"2022-03-09 08:00:00\"),\n pd.Timestamp(\"2022-03-09 09:15:00\"),\n pd.Timestamp(\"2022-03-09 10:30:00\"),\n ],\n \"ArrivalTime\": [\n pd.Timestamp(\"2022-03-09 09:00:00\"),\n pd.Timestamp(\"2022-03-09 09:45:00\"),\n pd.Timestamp(\"2022-03-09 11:00:00\"),\n ],\n \"Status\": [\"On Time\", \"Delayed\", \"Cancelled\"],\n})\n\njson.dumps(df.to_dict(orient=\"records\"))\n```\n\n```py\nfrom fastapi.responses import Response\nfrom typing import Any\n\nclass DataFrameJSONResponse(Response):\n media_type = \"application/json\"\n\n def render(self, content: Any) -> bytes:\n return content.to_json(orient=\"records\", date_format='iso').encode(\"utf-8\")\n\n\n@app.get(\"/test\", response_class=DataFrameJSONResponse)\nasync def test_dataframe():\n df = pd.DataFrame(\n {\n \"TrainID\": [\"T001\", \"T002\", \"T003\"],\n \"Route\": [\n \"Amsterdam - Utrecht\",\n \"Rotterdam - Den Haag\",\n \"Eindhoven - Tilburg\",\n ],\n \"DepartureTime\": [\n pd.Timestamp(\"2022-03-09 08:00:00\"),\n pd.Timestamp(\"2022-03-09 09:15:00\"),\n pd.Timestamp(\"2022-03-09 10:30:00\"),\n ],\n \"ArrivalTime\": [\n pd.Timestamp(\"2022-03-09 09:00:00\"),\n pd.Timestamp(\"2022-03-09 09:45:00\"),\n pd.Timestamp(\"2022-03-09 11:00:00\"),\n ],\n \"Status\": [\"On Time\", \"Delayed\", \"Cancelled\"],\n }\n )\n\n return DataFrameJSONResponse(df)\n```\n\n```text\nDataFrame.to_dict()\n```\n\n```text\njson\n```\n\n```text\nDataFrameJSONResponse\n```\n\n```text\npandas.DataFrame.to_json\n```\n\n```text\njson.dumps\n```\n\n========================================\n\nComments:\n- When you say `render` - what do you mean? In general, FastAPI returns data as JSON. If you want to have a different response format, you can use one of the built-in custom response formats, or create your own: fastapi.tiangolo.com/advanced/custom-response\n- Maybe check this stackoverflow.com/questions/32911336/…, but so far it seems good\n- I am ok with JSON output but problem is that i need this intermediate step of creating an output JSON file and then load it. Obviously i cannot import csv, transform and load in one step. thanks for the links. It clarifies a bit the process.\n- If you don't give a filename to `to_json` a JSON string is returned directly. You can then pair this with `return Response(content=json_str, media_type=\"application/json\")` to return the string directly from FastAPI with a JSON header. Would that work? (you can also give a File-like object and get output written to that, so something like `StringIO` should work as well)\n- You can avoid json dump/load sequence by just calling `DataFrame.to_dict()` instead.\n- @Chris by the way i saw you updated with `async`, and of course i have seen this into the documentation. In such a case would it be to allow several users to query the API at the same time ?\n- @pac You could also have a look at this answer, if it helps clarify things about `async` for you.\n- to_csv is a string. anyway to get that to an array easily (which includes the header on the first row)\n- Option 1, Update 2 is the best way to do it - If the DataFrame contains any np.nan values, to_dict will cause the JSON conversion to fail in FastAPI","metadata":{"transformedAt":"2026-08-18T18:32:29.104Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":44,"totalLines":406,"estimatedTokens":2230}}151{"id":"stack-77134535","source":"stackoverflow","questionId":77134535,"title":"Migrate PostgresDsn.build from pydentic v1 to pydantic v2","tags":["python","sqlalchemy","fastapi","pydantic"],"text":"Title: Migrate PostgresDsn.build from pydentic v1 to pydantic v2\nTags: python, sqlalchemy, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI have simple Config class from FastAPI tutorial. But it seems like it uses old pydantic version. I run my code with pydantic v2 version and get a several errors. I fix almost all of them, but the last one I cannot fix yet. This is part of code which does not work:\n\n```\nfrom pydantic import AnyHttpUrl, HttpUrl, PostgresDsn, field_validator\nfrom pydantic_settings import BaseSettings\nfrom pydantic_core.core_schema import FieldValidationInfo\n\nload_dotenv()\n\nclass Settings(BaseSettings):\n ...\n POSTGRES_SERVER: str = 'localhost:5432'\n POSTGRES_USER: str = os.getenv('POSTGRES_USER')\n POSTGRES_PASSWORD: str = os.getenv('POSTGRES_PASSWORD')\n POSTGRES_DB: str = os.getenv('POSTGRES_DB')\n SQLALCHEMY_DATABASE_URI: Optional[PostgresDsn] = None\n\n @field_validator(\"SQLALCHEMY_DATABASE_URI\", mode='before')\n @classmethod\n def assemble_db_connection(cls, v: Optional[str], info: FieldValidationInfo) -> Any:\n if isinstance(v, str):\n return v\n postgres_dsn = PostgresDsn.build(\n scheme=\"postgresql\",\n username=info.data.get(\"POSTGRES_USER\"),\n password=info.data.get(\"POSTGRES_PASSWORD\"),\n host=info.data.get(\"POSTGRES_SERVER\"),\n path=f\"{info.data.get('POSTGRES_DB') or ''}\",\n )\n return str(postgres_dsn)\n```\n\nThat is the error which I get:\n\n```\nsqlalchemy.exc.ArgumentError: Expected string or URL object, got MultiHostUrl('postgresql://user:password@localhost:5432/database')\n```\n\nI check a lot of places, but cannot find how I can fix that, it looks like `build` method pass data to the sqlalchemy `create_engine` method as a `MultiHostUrl` instance instead of string. How should I properly migrate this code to use pydantic v2?\n\n**UPDATE**\n\nI have fixed that issue by changing typing for `SQLALCHEMY_DATABASE_URI: Optional[PostgresDsn] = None` to `SQLALCHEMY_DATABASE_URI: Optional[str] = None`.\nBecause pydantic makes auto conversion of result for some reason. But I am not sure if that approach is the right one, maybe there are better way to do that?\n\n========================================\n\nTop Answer:\nI had the same problem and eventually came up with the following migration:\n\n### Pydantic V1:\n\n```\nfrom pydantic import BaseSettings, PostgresDsn, validator\n\nclass Settings(BaseSettings):\n POSTGRES_SERVER: Optional[str]\n POSTGRES_USER: Optional[str]\n POSTGRES_PASSWORD: Optional[str]\n POSTGRES_DB: Optional[str]\n SQLALCHEMY_DATABASE_URI: Union[Optional[PostgresDsn], Optional[str]] = None\n\n @validator(\"SQLALCHEMY_DATABASE_URI\", pre=True)\n def assemble_db_connection(cls, v: Optional[str], values: Dict[str, Any]) -> Any:\n if isinstance(v, str):\n print(\"Loading SQLALCHEMY_DATABASE_URI from docker.env file ...\")\n return v\n print(\"Creating SQLALCHEMY_DATABASE_URI from .env file ...\")\n return PostgresDsn.build(\n scheme=\"postgresql\",\n user=values.get(\"POSTGRES_USER\"),\n password=values.get(\"POSTGRES_PASSWORD\"),\n host=values.get(\"POSTGRES_SERVER\"),\n path=f\"/{values.get('POSTGRES_DB') or ''}\",\n )\n\n class Config:\n env_file = \".env\"\n case_sensitive = True\n```\n\n### Pydantic V2:\n\n```\nfrom pydantic import PostgresDsn, field_validator, ValidationInfo\nfrom pydantic_settings import BaseSettings, SettingsConfigDict\n\nclass Settings(BaseSettings):\n model_config = SettingsConfigDict(env_file=\".env\", case_sensitive=True)\n\n POSTGRES_SERVER: Optional[str] = None\n POSTGRES_USER: Optional[str] = None\n POSTGRES_PASSWORD: Optional[str] = None\n POSTGRES_DB: Optional[str] = None\n SQLALCHEMY_DATABASE_URI: Union[Optional[PostgresDsn], Optional[str]] = None\n\n @field_validator(\"SQLALCHEMY_DATABASE_URI\", mode=\"before\")\n @classmethod\n def assemble_db_connection(cls, v: Optional[str], values: ValidationInfo) -> Any:\n if isinstance(v, str):\n print(\"Loading SQLALCHEMY_DATABASE_URI from .docker.env file ...\")\n return v\n print(\"Creating SQLALCHEMY_DATABASE_URI from .env file ...\")\n return PostgresDsn.build(\n scheme=\"postgresql\",\n username=values.data.get(\"POSTGRES_USER\"),\n password=values.data.get(\"POSTGRES_PASSWORD\"),\n host=values.data.get(\"POSTGRES_SERVER\"),\n path=f\"{values.data.get('POSTGRES_DB') or ''}\",\n )\n```\n\nAlso, for calling the `settings` instance objects you need casting to string in V2:\n\n```\nsettings.SQLALCHEMY_DATABASE_URI.unicode_string()\n# or\nf\"{settings.SQLALCHEMY_DATABASE_URI}\n```\n\n========================================\n\nCode:\n```text\nfrom pydantic import AnyHttpUrl, HttpUrl, PostgresDsn, field_validator\nfrom pydantic_settings import BaseSettings\nfrom pydantic_core.core_schema import FieldValidationInfo\n\nload_dotenv()\n\n\nclass Settings(BaseSettings):\n ...\n POSTGRES_SERVER: str = 'localhost:5432'\n POSTGRES_USER: str = os.getenv('POSTGRES_USER')\n POSTGRES_PASSWORD: str = os.getenv('POSTGRES_PASSWORD')\n POSTGRES_DB: str = os.getenv('POSTGRES_DB')\n SQLALCHEMY_DATABASE_URI: Optional[PostgresDsn] = None\n\n @field_validator(\"SQLALCHEMY_DATABASE_URI\", mode='before')\n @classmethod\n def assemble_db_connection(cls, v: Optional[str], info: FieldValidationInfo) -> Any:\n if isinstance(v, str):\n return v\n postgres_dsn = PostgresDsn.build(\n scheme=\"postgresql\",\n username=info.data.get(\"POSTGRES_USER\"),\n password=info.data.get(\"POSTGRES_PASSWORD\"),\n host=info.data.get(\"POSTGRES_SERVER\"),\n path=f\"{info.data.get('POSTGRES_DB') or ''}\",\n )\n return str(postgres_dsn)\n```\n\n```text\nsqlalchemy.exc.ArgumentError: Expected string or URL object, got MultiHostUrl('postgresql://user:password@localhost:5432/database')\n```\n\n```text\nbuild\n```\n\n```text\ncreate_engine\n```\n\n```text\nMultiHostUrl\n```\n\n```text\nSQLALCHEMY_DATABASE_URI: Optional[PostgresDsn] = None\n```\n\n```text\nSQLALCHEMY_DATABASE_URI: Optional[str] = None\n```\n\n```text\nfrom sqlalchemy.ext.asyncio import create_async_engine\n\ncreate_async_engine(settings.POSTGRES_URI.unicode_string())\n```\n\n```text\nunicode_string()\n```\n\n```text\nURI\n```\n\n```py\nfrom pydantic import Field\nfrom pydantic_settings import BaseSettings, SettingsConfigDict\n\n\nclass Settings(BaseSettings):\n model_config = SettingsConfigDict(env_prefix='POSTGRES_', case_sensitive=False)\n\n server: str = Field(default='localhost:5432')\n user: str = 'xxx'\n password: str = 'xxx'\n db: str = 'xxx'\n user: str = 'xxx'\n\n sqlalchemy_database_uri: Optional[PostgresDsn]\n\n\n @field_validator(\"SQLALCHEMY_DATABASE_URI\", mode='after')\n def assemble_db_connection(cls, v: Optional[Union[PostgresDsn, str]], info: FieldValidationInfo) -> PostgresDsn:\n if isinstance(v, (str, PostgresDsn)):\n return v\n else:\n return PostgresDsn(\n scheme=\"postgresql\",\n username=cls.user,\n password=cls.password,\n host=cls.server,\n path=cls.db,\n )\n```\n\n```text\nprefix\n```\n\n```text\nafter\n```\n\n```py\nfrom sqlalchemy.ext.asyncio import create_async_engine\n\ncreate_async_engine(str(settings.POSTGRES_URI))\n```\n\n```py\nfrom pydantic import BaseSettings, PostgresDsn, validator\n\n\nclass Settings(BaseSettings):\n POSTGRES_SERVER: Optional[str]\n POSTGRES_USER: Optional[str]\n POSTGRES_PASSWORD: Optional[str]\n POSTGRES_DB: Optional[str]\n SQLALCHEMY_DATABASE_URI: Union[Optional[PostgresDsn], Optional[str]] = None\n\n @validator(\"SQLALCHEMY_DATABASE_URI\", pre=True)\n def assemble_db_connection(cls, v: Optional[str], values: Dict[str, Any]) -> Any:\n if isinstance(v, str):\n print(\"Loading SQLALCHEMY_DATABASE_URI from docker.env file ...\")\n return v\n print(\"Creating SQLALCHEMY_DATABASE_URI from .env file ...\")\n return PostgresDsn.build(\n scheme=\"postgresql\",\n user=values.get(\"POSTGRES_USER\"),\n password=values.get(\"POSTGRES_PASSWORD\"),\n host=values.get(\"POSTGRES_SERVER\"),\n path=f\"/{values.get('POSTGRES_DB') or ''}\",\n )\n\n class Config:\n env_file = \".env\"\n case_sensitive = True\n```\n\n```py\nfrom pydantic import PostgresDsn, field_validator, ValidationInfo\nfrom pydantic_settings import BaseSettings, SettingsConfigDict\n\n\nclass Settings(BaseSettings):\n model_config = SettingsConfigDict(env_file=\".env\", case_sensitive=True)\n\n POSTGRES_SERVER: Optional[str] = None\n POSTGRES_USER: Optional[str] = None\n POSTGRES_PASSWORD: Optional[str] = None\n POSTGRES_DB: Optional[str] = None\n SQLALCHEMY_DATABASE_URI: Union[Optional[PostgresDsn], Optional[str]] = None\n\n @field_validator(\"SQLALCHEMY_DATABASE_URI\", mode=\"before\")\n @classmethod\n def assemble_db_connection(cls, v: Optional[str], values: ValidationInfo) -> Any:\n if isinstance(v, str):\n print(\"Loading SQLALCHEMY_DATABASE_URI from .docker.env file ...\")\n return v\n print(\"Creating SQLALCHEMY_DATABASE_URI from .env file ...\")\n return PostgresDsn.build(\n scheme=\"postgresql\",\n username=values.data.get(\"POSTGRES_USER\"),\n password=values.data.get(\"POSTGRES_PASSWORD\"),\n host=values.data.get(\"POSTGRES_SERVER\"),\n path=f\"{values.data.get('POSTGRES_DB') or ''}\",\n )\n```\n\n```py\nsettings.SQLALCHEMY_DATABASE_URI.unicode_string()\n# or\nf\"{settings.SQLALCHEMY_DATABASE_URI}\n```\n\n```text\nsettings\n```\n\n```text\nfrom typing import Optional\nfrom pydantic import PostgresDsn, field_validator, ValidationInfo\nfrom pydantic_settings import BaseSettings\n\n\nclass Settings(BaseSettings):\n POSTGRES_HOST: str\n POSTGRES_USER: str\n POSTGRES_PASSWORD: str\n POSTGRES_DB: str\n SQLALCHEMY_DATABASE_URI: Optional[str] = None\n\n @field_validator(\"SQLALCHEMY_DATABASE_URI\", mode=\"before\")\n @classmethod\n def assemble_db_uri(cls, field_value, info: ValidationInfo) -> str:\n if isinstance(field_value, str):\n return field_value\n return PostgresDsn.build(\n scheme=\"postgresql+psycopg2\",\n username=info.data.get(\"POSTGRES_USER\"),\n password=info.data.get(\"POSTGRES_PASSWORD\"),\n host=info.data.get(\"POSTGRES_HOST\"),\n path=info.data.get(\"POSTGRES_DB\") or \"\",\n ).unicode_string()\n```\n\n```text\nfrom typing import Any, Dict, Optional\nfrom pydantic import BaseSettings, PostgresDsn, validator\n\n\nclass Settings(BaseSettings):\n POSTGRES_HOST: str\n POSTGRES_USER: str\n POSTGRES_PASSWORD: str\n POSTGRES_DB: str\n SQLALCHEMY_DATABASE_URI: Optional[PostgresDsn] = None\n\n @validator(\"SQLALCHEMY_DATABASE_URI\", pre=True)\n def assemble_db_connection(cls, v: Optional[str], values: Dict[str, Any]) -> Any:\n if isinstance(v, str):\n return v\n return PostgresDsn.build(\n scheme=\"postgresql+psycopg2\",\n user=values.get(\"POSTGRES_USER\"),\n password=values.get(\"POSTGRES_PASSWORD\"),\n host=values.get(\"POSTGRES_HOST\"),\n path=f\"/{values.get('POSTGRES_DB') or ''}\",\n )\n```\n\n```text\n> diff -u pydantic_v1.py pydantic_v2.py\n\n--- pydantic_v1.py\n+++ pydantic_v2.py\n@@ -1,5 +1,6 @@\n-from typing import Any, Dict, Optional\n-from pydantic import BaseSettings, PostgresDsn, validator\n+from typing import Optional\n+from pydantic import PostgresDsn, field_validator, ValidationInfo\n+from pydantic_settings import BaseSettings\n \n \n class Settings(BaseSettings):\n@@ -7,16 +8,17 @@\n POSTGRES_USER: str\n POSTGRES_PASSWORD: str\n POSTGRES_DB: str\n- SQLALCHEMY_DATABASE_URI: Optional[PostgresDsn] = None\n+ SQLALCHEMY_DATABASE_URI: Optional[str] = None\n \n- @validator(\"SQLALCHEMY_DATABASE_URI\", pre=True)\n- def assemble_db_connection(cls, v: Optional[str], values: Dict[str, Any]) -> Any:\n- if isinstance(v, str):\n- return v\n+ @field_validator(\"SQLALCHEMY_DATABASE_URI\", mode=\"before\")\n+ @classmethod\n+ def assemble_db_uri(cls, field_value, info: ValidationInfo) -> str:\n+ if isinstance(field_value, str):\n+ return field_value\n return PostgresDsn.build(\n scheme=\"postgresql+psycopg2\",\n- user=values.get(\"POSTGRES_USER\"),\n- password=values.get(\"POSTGRES_PASSWORD\"),\n- host=values.get(\"POSTGRES_HOST\"),\n- path=f\"/{values.get('POSTGRES_DB') or ''}\",\n- )\n+ username=info.data.get(\"POSTGRES_USER\"),\n+ password=info.data.get(\"POSTGRES_PASSWORD\"),\n+ host=info.data.get(\"POSTGRES_HOST\"),\n+ path=info.data.get(\"POSTGRES_DB\") or \"\",\n+ ).unicode_string()\n```\n\n========================================\n\nComments:\n- In which line of the code does this error occur?\n- @HenriqueAndrade, after debugging I realised that error in postgres_dsn = PostgresDsn.build line. I found a fix, but I am not sure that its the best way to fix that\n- Maybe this library can help you: github.com/pydantic/bump-pydantic to migrate your code from Pydantic 1 to Pydantic 2 more easily\n- I have a preference to use `computed_field` provided by pydantic v2, there's no need to do an extra validation on the db `uri` if we already validated uri build arguments. Am I missing something ?\n- That works too! @farch (Lemme update my answer)\n- The example is not working, I guess you have forgotten a return statement for the assemble_db_connection function\n- Instead of `username=values.data.get(\"POSTGRES_USER\")` this works as well: `username=values.data[\"POSTGRES_USER\"]`","metadata":{"transformedAt":"2026-08-18T18:32:29.104Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":21,"totalLines":418,"estimatedTokens":3346}}152{"id":"stack-70891687","source":"stackoverflow","questionId":70891687,"title":"How do I get my FastAPI application's console log in JSON format with a different structure and different fields?","tags":["python","logging","fastapi","uvicorn"],"text":"Title: How do I get my FastAPI application's console log in JSON format with a different structure and different fields?\nTags: python, logging, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI have a FastAPI application where I would like to get the default logs written to STDOUT with the following data in JSON format:\n\n**App logs should look like this:**\n\n```\n{\n \"XYZ\": {\n \"log\": {\n \"level\": \"info\",\n \"type\": \"app\",\n \"timestamp\": \"2022-01-16T08:30:08.181Z\",\n \"file\": \"api/predictor/predict.py\",\n \"line\": 34,\n \"threadId\": 435454,\n \"message\": \"API Server started on port 8080 (development)\"\n }\n }\n}\n```\n\n**Access logs should look like this:**\n\n```\n{\n \"XYZ\": {\n \"log\": {\n \"level\": \"info\",\n \"type\": \"access\",\n \"timestamp\": \"2022-01-16T08:30:08.181Z\",\n \"message\": \"GET /app/health 200 6ms\"\n },\n \"req\": {\n \"url\": \"/app/health\",\n \"headers\": {\n \"host\": \"localhost:8080\",\n \"user-agent\": \"curl/7.68.0\",\n \"accept\": \"*/*\"\n },\n \"method\": \"GET\",\n \"httpVersion\": \"1.1\",\n \"originalUrl\": \"/app/health\",\n \"query\": {}\n },\n \"res\": {\n \"statusCode\": 200,\n \"body\": {\n \"statusCode\": 200,\n \"status\": \"OK\"\n }\n }\n }\n}\n```\n\n**What I've tried:**\n\nI tried using the `json-logging` package for this. Using this example, I'm able to access the request logs in JSON and change the structure. But, I'm unable to find how to access and change the app logs.\n\n**Current output logs structure:**\n\n```\n{\"written_at\": \"2022-01-28T09:31:38.686Z\", \"written_ts\": 1643362298686910000, \"msg\": \n\"Started server process [12919]\", \"type\": \"log\", \"logger\": \"uvicorn.error\", \"thread\": \n\"MainThread\", \"level\": \"INFO\", \"module\": \"server\", \"line_no\": 82, \"correlation_id\": \n\"-\"}\n\n{\"written_at\": \"2022-01-28T09:31:38.739Z\", \"written_ts\": 1643362298739838000, \"msg\": \n\"Started server process [12919]\", \"type\": \"log\", \"logger\": \"uvicorn.error\", \"thread\": \n\"MainThread\", \"level\": \"INFO\", \"module\": \"server\", \"line_no\": 82, \"correlation_id\": \n\"-\"}\n\n{\"written_at\": \"2022-01-28T09:31:38.739Z\", \"written_ts\": 1643362298739951000, \"msg\": \n\"Waiting for application startup.\", \"type\": \"log\", \"logger\": \"uvicorn.error\", \n\"thread\": \"MainThread\", \"level\": \"INFO\", \"module\": \"on\", \"line_no\": 45, \n\"correlation_id\": \"-\"}\n```\n\n========================================\n\nCode:\n```text\n{\n \"XYZ\": {\n \"log\": {\n \"level\": \"info\",\n \"type\": \"app\",\n \"timestamp\": \"2022-01-16T08:30:08.181Z\",\n \"file\": \"api/predictor/predict.py\",\n \"line\": 34,\n \"threadId\": 435454,\n \"message\": \"API Server started on port 8080 (development)\"\n }\n }\n}\n```\n\n```text\n{\n \"XYZ\": {\n \"log\": {\n \"level\": \"info\",\n \"type\": \"access\",\n \"timestamp\": \"2022-01-16T08:30:08.181Z\",\n \"message\": \"GET /app/health 200 6ms\"\n },\n \"req\": {\n \"url\": \"/app/health\",\n \"headers\": {\n \"host\": \"localhost:8080\",\n \"user-agent\": \"curl/7.68.0\",\n \"accept\": \"*/*\"\n },\n \"method\": \"GET\",\n \"httpVersion\": \"1.1\",\n \"originalUrl\": \"/app/health\",\n \"query\": {}\n },\n \"res\": {\n \"statusCode\": 200,\n \"body\": {\n \"statusCode\": 200,\n \"status\": \"OK\"\n }\n }\n }\n}\n```\n\n```text\n{\"written_at\": \"2022-01-28T09:31:38.686Z\", \"written_ts\": 1643362298686910000, \"msg\": \n\"Started server process [12919]\", \"type\": \"log\", \"logger\": \"uvicorn.error\", \"thread\": \n\"MainThread\", \"level\": \"INFO\", \"module\": \"server\", \"line_no\": 82, \"correlation_id\": \n\"-\"}\n\n{\"written_at\": \"2022-01-28T09:31:38.739Z\", \"written_ts\": 1643362298739838000, \"msg\": \n\"Started server process [12919]\", \"type\": \"log\", \"logger\": \"uvicorn.error\", \"thread\": \n\"MainThread\", \"level\": \"INFO\", \"module\": \"server\", \"line_no\": 82, \"correlation_id\": \n\"-\"}\n\n{\"written_at\": \"2022-01-28T09:31:38.739Z\", \"written_ts\": 1643362298739951000, \"msg\": \n\"Waiting for application startup.\", \"type\": \"log\", \"logger\": \"uvicorn.error\", \n\"thread\": \"MainThread\", \"level\": \"INFO\", \"module\": \"on\", \"line_no\": 45, \n\"correlation_id\": \"-\"}\n```\n\n```text\njson-logging\n```\n\n```py\nimport logging, sys\n\n\ndef get_file_handler(formatter, filename=\"info.log\", maxBytes=1024*1024, backupCount=3):\n file_handler = logging.handlers.RotatingFileHandler(filename, maxBytes, backupCount)\n file_handler.setLevel(logging.DEBUG)\n file_handler.setFormatter(formatter)\n return file_handler\n\n\ndef get_stream_handler(formatter):\n stream_handler = logging.StreamHandler(sys.stdout)\n stream_handler.setLevel(logging.DEBUG)\n stream_handler.setFormatter(formatter)\n return stream_handler\n\n\ndef get_logger(name, formatter):\n logger = logging.getLogger(name)\n logger.setLevel(logging.DEBUG)\n logger.addHandler(get_file_handler(formatter))\n logger.addHandler(get_stream_handler(formatter))\n return logger\n```\n\n```py\nimport logging, json\n\n\nclass CustomJSONFormatter(logging.Formatter):\n def __init__(self, fmt):\n logging.Formatter.__init__(self, fmt)\n\n def format(self, record):\n logging.Formatter.format(self, record)\n return json.dumps(get_log(record), indent=2)\n\n\ndef get_log(record):\n d = {\n \"time\": record.asctime,\n \"process_name\": record.processName,\n \"process_id\": record.process,\n \"thread_name\": record.threadName,\n \"thread_id\": record.thread,\n \"level\": record.levelname,\n \"logger_name\": record.name,\n \"pathname\": record.pathname,\n #'filename': record.filename,\n \"line\": record.lineno,\n \"message\": record.message,\n }\n\n if hasattr(record, \"extra_info\"):\n d[\"req\"] = record.extra_info[\"req\"]\n d[\"res\"] = record.extra_info[\"res\"]\n\n return d\n```\n\n```py\nfrom fastapi import FastAPI, Request, Response\nfrom starlette.background import BackgroundTask\nfrom app_logger_formatter import CustomJSONFormatter\nfrom http import HTTPStatus\nimport app_logger\nimport uvicorn\n\n\napp = FastAPI()\nformatter = CustomJSONFormatter('%(asctime)s')\nlogger = app_logger.get_logger(__name__, formatter)\nstatus_reasons = {x.value:x.name for x in list(HTTPStatus)}\n\n\ndef get_extra_info(request: Request, response: Response):\n return {\n \"req\": {\n \"url\": request.url.path,\n \"headers\": {\n \"host\": request.headers[\"host\"],\n \"user-agent\": request.headers[\"user-agent\"],\n \"accept\": request.headers[\"accept\"],\n },\n \"method\": request.method,\n \"http_version\": request.scope[\"http_version\"],\n \"original_url\": request.url.path,\n \"query\": {},\n },\n \"res\": {\n \"status_code\": response.status_code,\n \"status\": status_reasons.get(response.status_code),\n }\n }\n\n\ndef write_log_data(request, response):\n logger.info(\n request.method + \" \" + request.url.path,\n extra={\"extra_info\": get_extra_info(request, response)}\n )\n\n\n@app.middleware(\"http\")\nasync def log_request(request: Request, call_next):\n response = await call_next(request)\n response.background = BackgroundTask(write_log_data, request, response)\n return response\n\n\n@app.get(\"/\")\nasync def foo(request: Request):\n return \"success\"\n\n\nif __name__ == '__main__':\n logger.info(\"Server is listening...\")\n uvicorn.run(app, host='0.0.0.0', port=8000)\n```\n\n```json\n{\n \"time\": \"2024-10-27 12:15:00,115\",\n \"process_name\": \"MainProcess\",\n \"process_id\": 1937,\n \"thread_name\": \"MainThread\",\n \"thread_id\": 1495,\n \"level\": \"INFO\",\n \"logger_name\": \"__main__\",\n \"pathname\": \"C:\\\\...\",\n \"line\": 56,\n \"message\": \"Server started listening on port: 8000\"\n}\n{\n \"time\": \"2024-10-27 12:15:10,335\",\n \"process_name\": \"MainProcess\",\n \"process_id\": 1937,\n \"thread_name\": \"AnyIO worker thread\",\n \"thread_id\": 1712,\n \"level\": \"INFO\",\n \"logger_name\": \"__main__\",\n \"pathname\": \"C:\\\\...\",\n \"line\": 37,\n \"message\": \"GET /docs\",\n \"req\": {\n \"url\": \"/docs\",\n \"headers\": {\n \"host\": \"127.0.0.1:8000\",\n \"user-agent\": \"Mozilla...\",\n \"accept\": \"text/html,application/xhtml+xml...\"\n },\n \"method\": \"GET\",\n \"http_version\": \"1.1\",\n \"original_url\": \"/docs\",\n \"query\": {}\n },\n \"res\": {\n \"status_code\": 200,\n \"status\": \"OK\"\n }\n}\n```\n\n```text\nFormatter\n```\n\n```text\nextra\n```\n\n```text\nurl\n```\n\n```text\nheaders\n```\n\n```text\njson.dumps()\n```\n\n```text\nindent\n```\n\n```text\norjson\n```\n\n```text\nlogger.info('sample log message')\n```\n\n```text\nlogger.info('sample log message', extra={'extra_info': get_extra_info(request, response)})\n```\n\n```text\nRequest\n```\n\n```text\nResponse\n```\n\n```text\nget_extra_info()\n```\n\n```text\nMiddleware\n```\n\n```text\nrequest\n```\n\n```text\nresponse\n```\n\n```text\nBackgroundTask\n```\n\n```text\nwrite_log_data()\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\nanyio\n```\n\n```text\nawait\n```\n\n```text\n\"thread_name\": \"AnyIO worker thread\"\n```\n\n```text\n/docs\n```\n\n```text\nLogRecord\n```\n\n```text\nasctime\n```\n\n```text\nlevelname\n```\n\n```text\nRotatingFileHandler\n```\n\n```text\nget_logger()\n```\n\n```text\nRequest\n```\n\n```text\nResponse\n```\n\n```text\nuvicorn\n```\n\n```text\nlogger\n```\n\n```text\nlifespan\n```\n\n```text\nlogger\n```\n\n```text\nAPIRouter\n```\n\n========================================\n\nComments:\n- Great answer @Chris, thank you! One question: how can I return the request query and response content inside the json?\n- @SinkThor Please have a look at this answer and this answer.\n- Response works perfectly, however the request_body always comes empty event though I send params as a query argument (i.e. /api/resource?parameter=value )\n- @SinkThor If there is no body in the request you sent, this is normal. Request body refers to data sent by the client in the *body*, as shown here, here and here. You should expect to see query parameters in the URL, which you can retrieve similar to this answer, as well as this answer and this answer.\n- Very nice solution, question: how to response body to those logs ? Tried multiple options like those from here: stackoverflow.com/questions/71882419/… but can not make it working\n- @user2913139 Please have a look at this answer as well.\n- This is stellar, plug and play with a FastAPI service.\n- Could you explain the `call_next` parameter you added to the middleware function?\n- @Jhirschibar Please have a look at the relevant documentation","metadata":{"transformedAt":"2026-08-18T18:32:29.104Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":43,"totalLines":470,"estimatedTokens":2526}}153{"id":"stack-70172127","source":"stackoverflow","questionId":70172127,"title":"How to generate a UUID field with FastAPI, SQLalchemy, and SQLModel","tags":["python","postgresql","sqlalchemy","fastapi","sqlmodel"],"text":"Title: How to generate a UUID field with FastAPI, SQLalchemy, and SQLModel\nTags: python, postgresql, sqlalchemy, fastapi, sqlmodel\nSource: Stack Overflow\n\nQuestion:\nI'm struggling to get the syntax to create a UUID field when creating a model in my FastAPI application. I'm using SQLModel.\n\nSo basically, my models.py file looks like this:\n\n```\nfrom datetime import datetime\nfrom typing import Optional\nimport uuid\n\nfrom sqlalchemy import Column, DateTime\nfrom sqlalchemy.dialects import postgresql as psql\nfrom sqlmodel import SQLModel, Field\n\nclass ModelBase(SQLModel):\n \"\"\"\n Base class for database models.\n \"\"\"\n id: Optional[int] = Field(default=None, primary_key=True)\n created_at: datetime = Field(sa_column=Column(DateTime(timezone=True), default=datetime.utcnow))\n updated_at: datetime = Field(sa_column=Column(DateTime(timezone=True),\n onupdate=datetime.utcnow, default=datetime.utcnow))\n\nclass UUIDModelBase(ModelBase, table=True):\n \"\"\"\n Base class for UUID-based models.\n \"\"\"\n uuid: uuid.UUID = Field(sa_column=Column(psql.UUID(as_uuid=True)), default=uuid.uuid4)\n```\n\nThe above errors out with\n\n```\nAttributeError: 'FieldInfo' object has no attribute 'UUID'\n```\n\nI also tried\n\n```\nid: uuid.UUID = Column(psql.UUID(as_uuid=True), default=uuid.uuid4)\nTypeError: Boolean value of this clause is not defined\n```\n\nAlso\n\n```\nuuid: uuid.UUID = Column(psql.UUID(as_uuid=True), default=uuid.uuid4)\nAttributeError: Neither 'Column' object nor 'Comparator' object has an attribute 'UUID'\n```\n\nand\n\n```\nuuid: uuid.UUID = Field(default_factory=uuid.uuid4, index=True, nullable=False)\n AttributeError: 'FieldInfo' object has no attribute 'UUID'\n```\n\nYou get the idea. The errors are not helping me, I just need the right syntax.\n\nIn this case, I'm not actually looking to use UUID as a primary key. And as you can tell from the imports, I'm using postgreSQL. The database is based on a postgres:12 docker image.\n\n========================================\n\nCode:\n```py\nfrom datetime import datetime\nfrom typing import Optional\nimport uuid\n\nfrom sqlalchemy import Column, DateTime\nfrom sqlalchemy.dialects import postgresql as psql\nfrom sqlmodel import SQLModel, Field\n\n\nclass ModelBase(SQLModel):\n \"\"\"\n Base class for database models.\n \"\"\"\n id: Optional[int] = Field(default=None, primary_key=True)\n created_at: datetime = Field(sa_column=Column(DateTime(timezone=True), default=datetime.utcnow))\n updated_at: datetime = Field(sa_column=Column(DateTime(timezone=True),\n onupdate=datetime.utcnow, default=datetime.utcnow))\n\n\nclass UUIDModelBase(ModelBase, table=True):\n \"\"\"\n Base class for UUID-based models.\n \"\"\"\n uuid: uuid.UUID = Field(sa_column=Column(psql.UUID(as_uuid=True)), default=uuid.uuid4)\n```\n\n```text\nAttributeError: 'FieldInfo' object has no attribute 'UUID'\n```\n\n```py\nid: uuid.UUID = Column(psql.UUID(as_uuid=True), default=uuid.uuid4)\nTypeError: Boolean value of this clause is not defined\n```\n\n```py\nuuid: uuid.UUID = Column(psql.UUID(as_uuid=True), default=uuid.uuid4)\nAttributeError: Neither 'Column' object nor 'Comparator' object has an attribute 'UUID'\n```\n\n```py\nuuid: uuid.UUID = Field(default_factory=uuid.uuid4, index=True, nullable=False)\n AttributeError: 'FieldInfo' object has no attribute 'UUID'\n```\n\n```py\nimport uuid as uuid_pkg\n\nfrom sqlalchemy import Field\nfrom sqlmodel import Field\n\nclass UUIDModelBase(ModelBase):\n \"\"\"\n Base class for UUID-based models.\n \"\"\"\n uuid: uuid_pkg.UUID = Field(\n default_factory=uuid_pkg.uuid4,\n primary_key=True,\n index=True,\n nullable=False,\n )\n```\n\n```text\nUUID\n```\n\n```text\nuuid\n```\n\n========================================\n\nComments:\n- Nice! That was it :)\n- PostgreSQL v13+ also supports `gen_random_uuid()` so you can have `server_default=\"gen_random_uuid()\"`. Before this was available only as a PostgreSQL extension.\n- postgresql.org/docs/13/functions-uuid.html\n- tried this one to fix issue described here, but it didn't work. any ideas?\n- How to use uuid7?\n- @MikkoOhtamaa The correct syntax is `server_default=sa.text(\"gen_random_uuid()\")`","metadata":{"transformedAt":"2026-08-18T18:32:29.104Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":8,"totalLines":149,"estimatedTokens":1030}}154{"id":"stack-76268799","source":"stackoverflow","questionId":76268799,"title":"How should I declare enums in SQLAlchemy using mapped_column (to enable type hinting)?","tags":["python","postgresql","sqlalchemy","fastapi"],"text":"Title: How should I declare enums in SQLAlchemy using mapped_column (to enable type hinting)?\nTags: python, postgresql, sqlalchemy, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to use `Enums` in SQLAlchemy 2.0 with `mapped_column`. So far I have the following code (taken from another question):\n\n```\nfrom sqlalchemy.dialects.postgresql import ENUM as pgEnum\nimport enum\n\nclass CampaignStatus(str, enum.Enum):\n activated = \"activated\"\n deactivated = \"deactivated\"\n\nCampaignStatusType: pgEnum = pgEnum(\n CampaignStatus,\n name=\"campaignstatus\",\n create_constraint=True,\n metadata=Base.metadata,\n validate_strings=True,\n)\n\nclass Campaign(Base):\n __tablename__ = \"campaign\"\n\n id: Mapped[UUID] = mapped_column(primary_key=True, default=uuid4)\n created_at: Mapped[dt.datetime] = mapped_column(default=dt.datetime.now)\n status: Mapped[CampaignStatusType] = mapped_column(nullable=False)\n```\n\nHowever, that gives the following error upon the construction of the `Campaign` class itself.\n\n```\nTraceback (most recent call last):\n File \"\", line 27, in \n class Campaign(Base):\n...\nAttributeError: 'ENUM' object has no attribute '__mro__'\n```\n\nAny hint about how to make this work?\n\nThe response from ENUM type in SQLAlchemy with PostgreSQL does not apply as I am using version 2 of SQLAlchemy and those answers did not use `mapped_column` or `Mapped` types. Also, removing `str` from `CampaignStatus` does not help.\n\n========================================\n\nCode:\n```py\nfrom sqlalchemy.dialects.postgresql import ENUM as pgEnum\nimport enum\n\nclass CampaignStatus(str, enum.Enum):\n activated = \"activated\"\n deactivated = \"deactivated\"\n\nCampaignStatusType: pgEnum = pgEnum(\n CampaignStatus,\n name=\"campaignstatus\",\n create_constraint=True,\n metadata=Base.metadata,\n validate_strings=True,\n)\n\nclass Campaign(Base):\n __tablename__ = \"campaign\"\n\n id: Mapped[UUID] = mapped_column(primary_key=True, default=uuid4)\n created_at: Mapped[dt.datetime] = mapped_column(default=dt.datetime.now)\n status: Mapped[CampaignStatusType] = mapped_column(nullable=False)\n```\n\n```text\nTraceback (most recent call last):\n File \"<stdin>\", line 27, in <module>\n class Campaign(Base):\n...\nAttributeError: 'ENUM' object has no attribute '__mro__'\n```\n\n```text\nEnums\n```\n\n```text\nmapped_column\n```\n\n```text\nCampaign\n```\n\n```text\nmapped_column\n```\n\n```text\nMapped\n```\n\n```text\nstr\n```\n\n```text\nCampaignStatus\n```\n\n```py\nstatus = mapped_column(CampaignStatusType, nullable=False)\n```\n\n```py\n# don't do this erroneous example despite it does run\n status: Mapped[sqlalchemy.dialects.postgresql.ENUM] = mapped_column(\n CampaignStatusType,\n nullable=False,\n )\n```\n\n```py\nfrom typing import Literal\nfrom typing import get_args\nfrom sqlalchemy import Enum\nfrom sqlalchemy.orm import DeclarativeBase\nfrom sqlalchemy.orm import Mapped\nfrom sqlalchemy.orm import mapped_column\n\nCampaignStatus = Literal[\"activated\", \"deactivated\"]\n\nclass Base(DeclarativeBase):\n pass\n\nclass Campaign(Base):\n __tablename__ = \"campaign\"\n id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)\n status: Mapped[CampaignStatus] = mapped_column(Enum(\n *get_args(CampaignStatus),\n name=\"campaignstatus\",\n create_constraint=True,\n validate_strings=True,\n ))\n```\n\n```py\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.orm import sessionmaker\n\ndef main():\n engine = create_engine('postgresql://postgres@localhost/postgres')\n Base.metadata.create_all(engine)\n Session = sessionmaker(bind=engine)\n session = Session()\n session.add(Campaign(status='activated'))\n session.add(Campaign(status='deactivated'))\n session.commit()\n\n s = 'some_unvalidated_string'\n try:\n session.add(Campaign(status=s))\n session.commit()\n except Exception:\n print(\"failed to insert with %r\" % s)\n\nif __name__ == '__main__':\n main()\n```\n\n```text\npostgres=# select * from campaign;\n id | status \n----+-------------\n 1 | activated\n 2 | deactivated\n(2 rows)\n```\n\n```text\npostgres=# \\dt campaign;\n Table \"public.campaign\"\n Column | Type | Collation | Nullable | Default \n--------+----------------+-----------+----------+--------------------------------------\n id | integer | | not null | nextval('campaign_id_seq'::regclass)\n status | campaignstatus | | not null | \nIndexes:\n \"campaign_pkey\" PRIMARY KEY, btree (id)\n\npostgres=# \\dT+ campaignstatus;\n List of data types\n Schema | Name | Internal name | Size | Elements | Owner | Access privileges | Description \n--------+----------------+----------------+------+-------------+----------+-------------------+-------------\n public | campaignstatus | campaignstatus | 4 | activated +| postgres | | \n | | | | deactivated | | | \n(1 row)\n```\n\n```text\npostgres=# drop type campaignstatus;\nERROR: cannot drop type campaignstatus because other objects depend on it\nDETAIL: column status of table campaign depends on type campaignstatus\nHINT: Use DROP ... CASCADE to drop the dependent objects too.\n```\n\n```text\n__mro__\n```\n\n```text\nAttributeError\n```\n\n```text\nCampaignStatusType\n```\n\n```text\nsqlalchemy.dialects.postgresql.ENUM\n```\n\n```text\npyright\n```\n\n```text\nMapped[CampaignStatusType]\n```\n\n```text\nstatus\n```\n\n```text\nMapped[CampaignStatus]\n```\n\n```text\npyright\n```\n\n```text\nMapped\n```\n\n```text\nsqlalchemy.dialects.postgresql.ENUM\n```\n\n```text\npgEnum\n```\n\n```text\nCampaignStatusType\n```\n\n```text\nsqlalchemy.Enum\n```\n\n```text\nmetadata=Base.metadata\n```\n\n```text\ntyping.get_args\n```\n\n```text\nCampaignStatus\n```\n\n```text\nEnum\n```\n\n```text\nfailed to insert with 'some_unvalidated_string'\n```\n\n```text\npyright\n```\n\n```text\npyright\n```\n\n```text\nMapped\n```\n\n```text\npsql\n```\n\n```text\ncampaign\n```\n\n========================================\n\nComments:\n- Moreover `class CampaignStatus(str, enum.Enum): ...` will not work because this is mixing two different classes with different metaclass - you shouldn't try inherit from two completely unrelated classes unless you know exactly what you are doing. Just do `class CampaignStatus(enum.Enum): ...`\n- Thanks but I have just added str because on another SO question someone mentioned that made it work for him, which is not my case. Even removing str does not help\n- I had to set up your environment manually (as you didn't provide a complete `Traceback`); it took time to deduce that `status: Mapped[CampaignStatusType] = mapped_column(nullable=False)` being the cause - changing this to the previous method of defining columns `status = sqlalchemy.Column(CampaignStatusType, nullable=False)` (e.g. from the linked duplicate) still works. In any case with the clarification I reopened the question.\n- Sorry I have been traveling and I have not been able to test this thoroughly but so far it builds ok. In a couple of days I will try to test the execution and come back to let you know if it is ok\n- Sorry for the late reply but I did not forget about your help. I have managed to find time to test this properly and indeed it seems to work. Again thank you for the help and great explanation. Have a great day!","metadata":{"transformedAt":"2026-08-18T18:32:29.104Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":40,"totalLines":307,"estimatedTokens":1834}}155{"id":"stack-74346565","source":"stackoverflow","questionId":74346565,"title":"FastAPI - \"TypeError: issubclass() arg 1 must be a class\" with modular imports","tags":["python","sqlalchemy","fastapi","pydantic","sqlmodel"],"text":"Title: FastAPI - \"TypeError: issubclass() arg 1 must be a class\" with modular imports\nTags: python, sqlalchemy, fastapi, pydantic, sqlmodel\nSource: Stack Overflow\n\nQuestion:\nWhen working with modular imports with FastAPI and SQLModel, I am getting the following error if I open /docs:\n\n**TypeError: issubclass() arg 1 must be a class**\n\n- Python 3.10.6\n\n- pydantic 1.10.2\n\n- fastapi 0.85.2\n\n- sqlmodel 0.0.8\n\n- macOS 12.6\n\nHere is a reproducible example.\n\n**user.py**\n\n```\nfrom typing import List, TYPE_CHECKING, Optional\nfrom sqlmodel import SQLModel, Field\n\nif TYPE_CHECKING:\n from item import Item\n\nclass User(SQLModel):\n id: int = Field(default=None, primary_key=True)\n age: Optional[int]\n bought_items: List[\"Item\"] = []\n```\n\n**item.py**\n\n```\nfrom sqlmodel import SQLModel, Field\n\nclass Item(SQLModel):\n id: int = Field(default=None, primary_key=True)\n price: float\n name: str\n```\n\n**main.py**\n\n```\nfrom fastapi import FastAPI\n\nfrom user import User\n\napp = FastAPI()\n\n@app.get(\"/\", response_model=User)\ndef main():\n return {\"message\": \"working just fine\"}\n```\n\nI followed along the tutorial from sqlmodel https://sqlmodel.tiangolo.com/tutorial/code-structure/#make-circular-imports-work.\nIf I would put the models in the same file, it all works fine. As my actual models are quite complex, I need to rely on the modular imports though.\n\nTraceback:\n\n```\nTraceback (most recent call last):\n File \"/Users/felix/opt/anaconda3/envs/fastapi_test/lib/python3.10/site-packages/fastapi/utils.py\", line 45, in get_model_definitions\n m_schema, m_definitions, m_nested_models = model_process_schema(\n File \"pydantic/schema.py\", line 580, in pydantic.schema.model_process_schema\n File \"pydantic/schema.py\", line 621, in pydantic.schema.model_type_schema\n File \"pydantic/schema.py\", line 254, in pydantic.schema.field_schema\n File \"pydantic/schema.py\", line 461, in pydantic.schema.field_type_schema\n File \"pydantic/schema.py\", line 847, in pydantic.schema.field_singleton_schema\n File \"pydantic/schema.py\", line 698, in pydantic.schema.field_singleton_sub_fields_schema\n File \"pydantic/schema.py\", line 526, in pydantic.schema.field_type_schema\n File \"pydantic/schema.py\", line 921, in pydantic.schema.field_singleton_schema\n File \"/Users/felix/opt/anaconda3/envs/fastapi_test/lib/python3.10/abc.py\", line 123, in __subclasscheck__\n return _abc_subclasscheck(cls, subclass)\nTypeError: issubclass() arg 1 must be a class\n```\n\n========================================\n\nTop Answer:\nFor anyone ending up here who (just like me) got the same error but couldn't resolve it using the solution above, my script looked like this. It seems that `SQLModel` relies on the `pydantic.BaseModel` so this solution also applies here.\n\n```\nfrom pydantic import BaseModel\n\nclass Model(BaseModel):\n values: list[int, ...]\n\nclass SubModel(Model):\n values = list[int, int, int]\n```\n\nIt took me a long time to realize what my mistake was, but in `SubModel` I used `=` (assignment) whereas I should have used `:` (type hint).\n\nThe strangest thing was that it did work in a docker container (Linux) but not locally (Windows). Also, mypy did not pick up on this.\n\n========================================\n\nCode:\n```text\nfrom typing import List, TYPE_CHECKING, Optional\nfrom sqlmodel import SQLModel, Field\n\nif TYPE_CHECKING:\n from item import Item\n\nclass User(SQLModel):\n id: int = Field(default=None, primary_key=True)\n age: Optional[int]\n bought_items: List[\"Item\"] = []\n```\n\n```text\nfrom sqlmodel import SQLModel, Field\n\nclass Item(SQLModel):\n id: int = Field(default=None, primary_key=True)\n price: float\n name: str\n```\n\n```text\nfrom fastapi import FastAPI\n\nfrom user import User\n\napp = FastAPI()\n\n@app.get(\"/\", response_model=User)\ndef main():\n return {\"message\": \"working just fine\"}\n```\n\n```text\nTraceback (most recent call last):\n File \"/Users/felix/opt/anaconda3/envs/fastapi_test/lib/python3.10/site-packages/fastapi/utils.py\", line 45, in get_model_definitions\n m_schema, m_definitions, m_nested_models = model_process_schema(\n File \"pydantic/schema.py\", line 580, in pydantic.schema.model_process_schema\n File \"pydantic/schema.py\", line 621, in pydantic.schema.model_type_schema\n File \"pydantic/schema.py\", line 254, in pydantic.schema.field_schema\n File \"pydantic/schema.py\", line 461, in pydantic.schema.field_type_schema\n File \"pydantic/schema.py\", line 847, in pydantic.schema.field_singleton_schema\n File \"pydantic/schema.py\", line 698, in pydantic.schema.field_singleton_sub_fields_schema\n File \"pydantic/schema.py\", line 526, in pydantic.schema.field_type_schema\n File \"pydantic/schema.py\", line 921, in pydantic.schema.field_singleton_schema\n File \"/Users/felix/opt/anaconda3/envs/fastapi_test/lib/python3.10/abc.py\", line 123, in __subclasscheck__\n return _abc_subclasscheck(cls, subclass)\nTypeError: issubclass() arg 1 must be a class\n```\n\n```py\nfrom sqlmodel import SQLModel, Field\n\nfrom .user import User\n\nclass Item(SQLModel):\n id: int = Field(default=None, primary_key=True)\n price: float\n name: str\n\nUser.update_forward_refs(Item=Item)\n```\n\n```py\nfrom fastapi import FastAPI\n\nfrom .user import User\nfrom . import item\n\napi = FastAPI()\n\n@api.get(\"/\", response_model=User)\ndef main():\n return {\"message\": \"working just fine\"}\n```\n\n```text\nUser.update_forward_refs(Item=Item)\n```\n\n```text\npydantic.schema\n```\n\n```text\nfield_singleton_schema\n```\n\n```text\nissubclass(field_type, BaseModel)\n```\n\n```text\nfield_type\n```\n\n```text\ntype\n```\n\n```text\nUser\n```\n\n```text\nbought_items\n```\n\n```text\nList\n```\n\n```text\nItem\n```\n\n```text\nItem\n```\n\n```text\nissubclass\n```\n\n```text\nupdate_forward_refs\n```\n\n```text\nItem\n```\n\n```text\nItem\n```\n\n```text\nUser\n```\n\n```text\nitem\n```\n\n```text\nItem\n```\n\n```text\nitem\n```\n\n```text\nmain\n```\n\n```text\n__init__.py\n```\n\n```text\nUser.update_forward_refs\n```\n\n```text\nItem\n```\n\n```text\nItem\n```\n\n```text\nusers\n```\n\n```text\nlist[User]\n```\n\n```text\nUser\n```\n\n```text\nTYPE_CHECKING\n```\n\n```text\nfrom .item import Item\n```\n\n```text\nuser.py\n```\n\n```text\nbought_items: list[Item]\n```\n\n```text\nupdate_forward_refs\n```\n\n```text\nItem\n```\n\n```py\nfrom pydantic import BaseModel\n\nclass Model(BaseModel):\n values: list[int, ...]\n\nclass SubModel(Model):\n values = list[int, int, int]\n```\n\n```text\nSQLModel\n```\n\n```text\npydantic.BaseModel\n```\n\n```text\nSubModel\n```\n\n```text\n=\n```\n\n```text\n:\n```\n\n```text\nfrom __future__ import annotations\n```\n\n```text\npip uninstall flexget thinc spacy\npip install langchain -U\n```\n\n========================================\n\nComments:\n- Please post the compete traceback!\n- Typing forward references (type hints as strings) are finicky in Python. Try typing `bought_items: \"List[Item]\"` instead\n- this doesn't solve the issues.\n- In my similar case, updating to Python 3.11 solved the issue.\n- Hi Daniil, thanks for the great explanation. You were right, I actually do have some circular dependencies, thus the need for the type_checking. I was aware of the update_forward_refs function, but didn't fully understood the concept behind it.","metadata":{"transformedAt":"2026-08-18T18:32:29.105Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":47,"totalLines":361,"estimatedTokens":1756}}156{"id":"stack-64057445","source":"stackoverflow","questionId":64057445,"title":"FastAPI post does not recognize my parameter","tags":["python","curl","fastapi","http-status-code-422"],"text":"Title: FastAPI post does not recognize my parameter\nTags: python, curl, fastapi, http-status-code-422\nSource: Stack Overflow\n\nQuestion:\nI am usually using Tornado, and trying to migrate to FastAPI.\n\nLet's say, I have a very basic API as follows:\n\n```\n@app.post(\"/add_data\")\nasync def add_data(data):\n return data\n```\n\nWhen I am running the following Curl request:\n`curl http://127.0.0.1:8000/add_data -d 'data=Hello'`\n\nI am getting the following error:\n\n`{\"detail\":[{\"loc\":[\"query\",\"data\"],\"msg\":\"field required\",\"type\":\"value_error.missing\"}]}`\n\nSo I am sure I am missing something very basic, but I do not know what that might be.\n\n========================================\n\nTop Answer:\nIn your case, you passing a form data to your endpoint. To process it, you need to install python-multipart via pip and rewrite your function a little:\n\n```\nfrom fastapi import FastAPI, Form\n\napp = FastAPI()\n\n@app.post('/add_data')\nasync def process_message(data: str = Form(...)):\n return data\n```\n\nIf you need json data, check Arakkal Abu's answer.\n\n========================================\n\nCode:\n```py\n@app.post(\"/add_data\")\nasync def add_data(data):\n return data\n```\n\n```text\ncurl http://127.0.0.1:8000/add_data -d 'data=Hello'\n```\n\n```text\n{\"detail\":[{\"loc\":[\"query\",\"data\"],\"msg\":\"field required\",\"type\":\"value_error.missing\"}]}\n```\n\n```text\nfrom pydantic import BaseModel\n\n\nclass Payload(BaseModel):\n data: str = \"\"\n\n\n@app.post(\"/add_data\")\nasync def add_data(payload: Payload = None):\n return payload\n```\n\n```text\ncurl -X POST \"http://0.0.0.0:6022/add_data\" -d '{\"data\":\"Hello\"}'\n```\n\n```py\nfrom fastapi import FastAPI, Form\n\napp = FastAPI()\n\n@app.post('/add_data')\nasync def process_message(data: str = Form(...)):\n return data\n```\n\n```text\nfrom fastapi import Body\n\n@app.post(\"/add_data\")\nasync def add_data(data: str = Body()):\n return data\n```\n\n```text\nBody()\n```\n\n```text\ndata: str = Body()\n```\n\n========================================\n\nComments:\n- Future readers might find this answer and this answer helpful as well.\n- Thank you it works! I am however a bit confused why I need to define a BaseModel for post API but not get.\n- In your get request, the data are being sent as ***query parameters*** whereas here as ***payload***\n- And you don't have to hard-code input parameters (such as `data` field in `Payload`), see how to pass and receive any dict or JSON, without having to predefine its keys: stackoverflow.com/a/70879659/9962007","metadata":{"transformedAt":"2026-08-18T18:32:29.105Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":9,"totalLines":108,"estimatedTokens":615}}157{"id":"stack-70123888","source":"stackoverflow","questionId":70123888,"title":"Using `async def` vs `def` in FastAPI and testing blocking calls","tags":["python-asyncio","fastapi","uvicorn"],"text":"Title: Using `async def` vs `def` in FastAPI and testing blocking calls\nTags: python-asyncio, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\n### `tl;dr`\n\n- Which of the options below is the correct workflow in `fastapi`?\n\n- How does one programatically test whether a call is truly blocking (other than manually from browser)? Is there a *stress testing* extension to `uvicorn` or `fastapi`?\n\nI have a number of endpoints in `fastapi` server (using `uvicorn` at the moment) that have long blocking calls to regular sync Python code. Despite the documentation (https://fastapi.tiangolo.com/async/) I am still unclear whether I should be using exclusively `def`, `async def` or mixing for my functions.\n\nAs far as I understand it, I have three options, assuming:\n\n```\ndef some_long_running_sync_function():\n ...\n```\n\n### Option 1 - consistently use `def` only for endpoints\n\n```\n@app.get(\"route/to/endpoint\")\ndef endpoint_1:\n some_long_running_sync_function()\n\n@app.post(\"route/to/another/endpoint\")\ndef endpoint_2:\n ...\n```\n\n### Option 2 - consistently use `async def` only and run blocking sync code in executor\n\n```\nimport asyncio\n\n@app.get(\"route/to/endpoint\")\nasync def endpoint_1:\n loop = asyncio.get_event_loop()\n await loop.run_in_executor(None, some_long_running_sync_function)\n\n@app.post(\"route/to/another/endpoint\")\nasync def endpoint_2:\n ...\n```\n\n### Option 3 - mix and match `def` and `async def` based on underlying calls\n\n```\nimport asyncio\n\n@app.get(\"route/to/endpoint\")\ndef endpoint_1:\n # endpoint is calling to sync code that cannot be awaited\n some_long_running_sync_function()\n\n@app.post(\"route/to/another/endpoint\")\nasync def endpoint_2:\n # this code can be awaited so I can use async\n ...\n```\n\n========================================\n\nCode:\n```py\ndef some_long_running_sync_function():\n ...\n```\n\n```py\n@app.get(\"route/to/endpoint\")\ndef endpoint_1:\n some_long_running_sync_function()\n\n\n@app.post(\"route/to/another/endpoint\")\ndef endpoint_2:\n ...\n```\n\n```py\nimport asyncio\n\n\n@app.get(\"route/to/endpoint\")\nasync def endpoint_1:\n loop = asyncio.get_event_loop()\n await loop.run_in_executor(None, some_long_running_sync_function)\n\n\n@app.post(\"route/to/another/endpoint\")\nasync def endpoint_2:\n ...\n```\n\n```py\nimport asyncio\n\n\n@app.get(\"route/to/endpoint\")\ndef endpoint_1:\n # endpoint is calling to sync code that cannot be awaited\n some_long_running_sync_function()\n\n\n@app.post(\"route/to/another/endpoint\")\nasync def endpoint_2:\n # this code can be awaited so I can use async\n ...\n```\n\n```text\ntl;dr\n```\n\n```text\nfastapi\n```\n\n```text\nuvicorn\n```\n\n```text\nfastapi\n```\n\n```text\nfastapi\n```\n\n```text\nuvicorn\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\nawait\n```\n\n```text\ndef\n```\n\n```text\nasync\n```\n\n```text\ndef\n```\n\n```text\ndef\n```\n\n```text\nasyncio.get_running_loop()\n```\n\n```text\nasync def\n```\n\n```text\nbackgroundtasks\n```\n\n========================================\n\nComments:\n- Thank you for the answer @thisisalsomypassword - I fully agree with Option 1 defeating the purpose of `fastapi`. Now with Options 2-3 is the only difference whether the entire endpoint runs in a separate executor (Option 3) or that only long-running tasks run in a separately declared executor (Option 2) - essentially facading over sync and treating it as async (with `await` from the executor)?\n- Yes, I think that‘s basically it. As you said, the executor is „separately declared“. So the details of how your work is sent to a thread are of course a bit different. If there is nothing else IO-bound going on in `endpoint_1` in „Option 2“, I wouldn‘t declare it as `async def`.","metadata":{"transformedAt":"2026-08-18T18:32:29.105Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":24,"totalLines":198,"estimatedTokens":919}}158{"id":"stack-60765317","source":"stackoverflow","questionId":60765317,"title":"How to create an OpenAPI schema for an UploadFile in FastAPI?","tags":["python","openapi","fastapi"],"text":"Title: How to create an OpenAPI schema for an UploadFile in FastAPI?\nTags: python, openapi, fastapi\nSource: Stack Overflow\n\nQuestion:\nFastAPI automatically generates a schema in the OpenAPI spec for `UploadFile` parameters.\n\nFor example, this code:\n\n```\nfrom fastapi import FastAPI, File, UploadFile\n\napp = FastAPI()\n\n@app.post(\"/uploadfile/\")\nasync def create_upload_file(file: UploadFile = File(..., description=\"The file\")):\n return {\"filename\": file.filename}\n```\n\nwill generate this schema under `components:schemas` in the OpenAPI spec:\n\n```\n{\n \"Body_create_upload_file_uploadfile__post\": {\n \"title\": \"Body_create_upload_file_uploadfile__post\",\n \"required\":[\"file\"],\n \"type\":\"object\",\n \"properties\":{\n \"file\": {\"title\": \"File\", \"type\": \"string\", \"description\": \"The file\",\"format\":\"binary\"}\n }\n }\n}\n```\n\nHow can I explicitly specify the schema for UploadFiles (or at least its name)?\n\nI have read FastAPIs docs and searched the issue tracker but found nothing.\n\n========================================\n\nTop Answer:\nI answered this over on FastAPI#1442, but just in case someone else stumbles upon this question here is a copy-and-paste from the post linked above:\n\nAfter some investigation this is possible, but it requires some monkey patching. Using the example given here, the solution looks like so:\n\n```\nfrom fastapi import FastAPI, File, UploadFile\nfrom typing import Callable\n\napp = FastAPI()\n\n@app.post(\"/files/\")\nasync def create_file(file: bytes = File(...)):\n return {\"file_size\": len(file)}\n\n@app.post(\"/uploadfile/\")\nasync def create_upload_file(file: UploadFile = File(...)):\n return {\"filename\": file.filename}\n\ndef update_schema_name(app: FastAPI, function: Callable, name: str) -> None:\n \"\"\"\n Updates the Pydantic schema name for a FastAPI function that takes\n in a fastapi.UploadFile = File(...) or bytes = File(...).\n\n This is a known issue that was reported on FastAPI#1442 in which\n the schema for file upload routes were auto-generated with no\n customization options. This renames the auto-generated schema to\n something more useful and clear.\n\n Args:\n app: The FastAPI application to modify.\n function: The function object to modify.\n name: The new name of the schema.\n \"\"\"\n for route in app.routes:\n if route.endpoint is function:\n route.body_field.type_.__name__ = name\n break\n\nupdate_schema_name(app, create_file, \"CreateFileSchema\")\nupdate_schema_name(app, create_upload_file, \"CreateUploadSchema\")\n```\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI, File, UploadFile\n\napp = FastAPI()\n\n\n@app.post(\"/uploadfile/\")\nasync def create_upload_file(file: UploadFile = File(..., description=\"The file\")):\n return {\"filename\": file.filename}\n```\n\n```text\n{\n \"Body_create_upload_file_uploadfile__post\": {\n \"title\": \"Body_create_upload_file_uploadfile__post\",\n \"required\":[\"file\"],\n \"type\":\"object\",\n \"properties\":{\n \"file\": {\"title\": \"File\", \"type\": \"string\", \"description\": \"The file\",\"format\":\"binary\"}\n }\n }\n}\n```\n\n```text\nUploadFile\n```\n\n```text\ncomponents:schemas\n```\n\n```py\nfrom fastapi import FastAPI, File, UploadFile\nfrom fastapi.openapi.utils import get_openapi\n\n\napp = FastAPI()\n\n\n@app.post(\"/uploadfile/\")\nasync def create_upload_file(file1: UploadFile = File(...), file2: UploadFile = File(...)):\n pass\n\n\ndef custom_openapi():\n if app.openapi_schema:\n return app.openapi_schema\n openapi_schema = get_openapi(\n title=\"Custom title\",\n version=\"2.5.0\",\n description=\"This is a very custom OpenAPI schema\",\n routes=app.routes,\n )\n # Move autogenerated Body_ schemas, see https://github.com/tiangolo/fastapi/issues/1442\n for path in openapi_schema[\"paths\"].values():\n for method_data in path.values():\n if \"requestBody\" in method_data:\n for content_type, content in method_data[\"requestBody\"][\"content\"].items():\n if content_type == \"multipart/form-data\":\n schema_name = content[\"schema\"][\"$ref\"].lstrip(\"#/components/schemas/\")\n schema_data = openapi_schema[\"components\"][\"schemas\"].pop(schema_name)\n content[\"schema\"] = schema_data\n app.openapi_schema = openapi_schema\n return app.openapi_schema\n\napp.openapi = custom_openapi\n```\n\n```py\nfrom fastapi import FastAPI, File, UploadFile\nfrom typing import Callable\n\napp = FastAPI()\n\n@app.post(\"/files/\")\nasync def create_file(file: bytes = File(...)):\n return {\"file_size\": len(file)}\n\n@app.post(\"/uploadfile/\")\nasync def create_upload_file(file: UploadFile = File(...)):\n return {\"filename\": file.filename}\n\ndef update_schema_name(app: FastAPI, function: Callable, name: str) -> None:\n \"\"\"\n Updates the Pydantic schema name for a FastAPI function that takes\n in a fastapi.UploadFile = File(...) or bytes = File(...).\n\n This is a known issue that was reported on FastAPI#1442 in which\n the schema for file upload routes were auto-generated with no\n customization options. This renames the auto-generated schema to\n something more useful and clear.\n\n Args:\n app: The FastAPI application to modify.\n function: The function object to modify.\n name: The new name of the schema.\n \"\"\"\n for route in app.routes:\n if route.endpoint is function:\n route.body_field.type_.__name__ = name\n break\n\nupdate_schema_name(app, create_file, \"CreateFileSchema\")\nupdate_schema_name(app, create_upload_file, \"CreateUploadSchema\")\n```\n\n========================================\n\nComments:\n- Have you found anything about this?\n- No, unfortunately not.\n- This is a known limitation of FastAPI, see this issue on GitHub: github.com/tiangolo/fastapi/issues/1442","metadata":{"transformedAt":"2026-08-18T18:32:29.105Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":6,"totalLines":199,"estimatedTokens":1443}}159{"id":"stack-77025354","source":"stackoverflow","questionId":77025354,"title":"With Pydantic V2 and model_validate, how can I create a \"computed field\" from an attribute of an ORM model that IS NOT part of the Pydantic model","tags":["python","fastapi","pydantic"],"text":"Title: With Pydantic V2 and model_validate, how can I create a \"computed field\" from an attribute of an ORM model that IS NOT part of the Pydantic model\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nThis context here is that I am using FastAPI and have a `response_model` defined for each of the paths. The endpoint code returns a SQLAlchemy ORM instance which is then passed, I believe, to `model_validate`. The `response_model` is a Pydantic model that filters out many of the ORM model attributes (internal ids and etc...) and performs some transformations and adds some `computed_field`s. This all works just fine so long as all the attributes you need are part of the Pydantic model. Seems like `__pydantic_context__` along with `model_config = ConfigDict(from_attributes=True, extra='allow')` would be a great way to hold on to some of the extra attributes from the ORM model and use them to compute new fields, however, it seems that when `model_validate` is used to create the instance that `__pydantic_context__` remains empty. Is there some trick to getting this behavior in a clean way?\n\nI have a way to make this work, but it involves dynamically adding new attributes to my ORM model, which leaves me with a bad feeling and a big `FIXME` in my code.\n\nHere is some code to illustrate the problem. Note that the second test case fails.\n\n```\nfrom typing import Any\nfrom pydantic import BaseModel, ConfigDict, computed_field, model_validator\n\nclass Foo:\n\n def __init__(self):\n self.original_thing = \"foo\"\n\nclass WishThisWorked(BaseModel):\n \"\"\"\n __pydantic_extra__ does not pick up the additional attributes when model_validate is used to instantiate\n \"\"\"\n model_config = ConfigDict(from_attributes=True, extra='allow')\n\n @computed_field\n @property\n def computed_thing(self) -> str:\n try:\n return self.__pydantic_extra__[\"original_thing\"] + \"_computed\"\n except Exception as e:\n print(e)\n\n return None\n\nmodel = WishThisWorked(original_thing=\"bar\")\nprint(f'WishThisWorked (original_thing=\"bar\") worked: {model.computed_thing == \"bar_computed\"}')\n\n# this is the case that I actually want to work\nmodel_orm = WishThisWorked.model_validate(Foo())\nprint(f'WishThisWorked model_validate(Foo()) worked: {model.computed_thing == \"foo_computed\"}')\n\nclass WorksButKludgy(BaseModel):\n \"\"\"\n I don't like having to modify the instance passed to model_validate\n \"\"\"\n model_config = ConfigDict(from_attributes=True)\n\n computed_thing: str\n\n @model_validator(mode=\"before\")\n @classmethod\n def _set_fields(cls, values: Any) -> Any:\n if type(values) is Foo:\n # This is REALLY gross\n values.computed_thing = values.original_thing + \"_computed\"\n elif type(values) is dict:\n values[\"computed_thing\"] = values[\"original_thing\"] + \"_computed\"\n return values\n\nprint(f'WorksButKludgy (original_thing=\"bar\") worked: {model.computed_thing == \"bar_computed\"}')\nmodel = WorksButKludgy(original_thing=\"bar\")\n\nmodel_orm = WorksButKludgy.model_validate(Foo())\nprint(f'WorksButKludgy model_validate(Foo()) worked: {model_orm.computed_thing == \"foo_computed\"}')```\n```\n\n========================================\n\nCode:\n```py\nfrom typing import Any\nfrom pydantic import BaseModel, ConfigDict, computed_field, model_validator\n\n\nclass Foo:\n\n def __init__(self):\n self.original_thing = \"foo\"\n\n\nclass WishThisWorked(BaseModel):\n \"\"\"\n __pydantic_extra__ does not pick up the additional attributes when model_validate is used to instantiate\n \"\"\"\n model_config = ConfigDict(from_attributes=True, extra='allow')\n\n @computed_field\n @property\n def computed_thing(self) -> str:\n try:\n return self.__pydantic_extra__[\"original_thing\"] + \"_computed\"\n except Exception as e:\n print(e)\n\n return None\n\n\nmodel = WishThisWorked(original_thing=\"bar\")\nprint(f'WishThisWorked (original_thing=\"bar\") worked: {model.computed_thing == \"bar_computed\"}')\n\n# this is the case that I actually want to work\nmodel_orm = WishThisWorked.model_validate(Foo())\nprint(f'WishThisWorked model_validate(Foo()) worked: {model.computed_thing == \"foo_computed\"}')\n\n\nclass WorksButKludgy(BaseModel):\n \"\"\"\n I don't like having to modify the instance passed to model_validate\n \"\"\"\n model_config = ConfigDict(from_attributes=True)\n\n computed_thing: str\n\n @model_validator(mode=\"before\")\n @classmethod\n def _set_fields(cls, values: Any) -> Any:\n if type(values) is Foo:\n # This is REALLY gross\n values.computed_thing = values.original_thing + \"_computed\"\n elif type(values) is dict:\n values[\"computed_thing\"] = values[\"original_thing\"] + \"_computed\"\n return values\n\n\nprint(f'WorksButKludgy (original_thing=\"bar\") worked: {model.computed_thing == \"bar_computed\"}')\nmodel = WorksButKludgy(original_thing=\"bar\")\n\nmodel_orm = WorksButKludgy.model_validate(Foo())\nprint(f'WorksButKludgy model_validate(Foo()) worked: {model_orm.computed_thing == \"foo_computed\"}')```\n```\n\n```text\nresponse_model\n```\n\n```text\nmodel_validate\n```\n\n```text\nresponse_model\n```\n\n```text\ncomputed_field\n```\n\n```text\n__pydantic_context__\n```\n\n```text\nmodel_config = ConfigDict(from_attributes=True, extra='allow')\n```\n\n```text\nmodel_validate\n```\n\n```text\n__pydantic_context__\n```\n\n```text\nFIXME\n```\n\n```text\nfrom pydantic import BaseModel, Field, property, computed_field, ConfigDict\nfrom sqlalchemy.orm import declaritive_base\nfrom sqlalchemy import Column, Integer, String\n\nSqlBase = declaritive_base()\n\nclass SqlModel(SqlBase):\n ID = Column(Integer)\n Name = Column(String)\n\n\nclass SqlSchema(BaseModel):\n model_config = ConfigDict(from_attributes=True)\n ID: int = Field(exclude=True)\n Name: str = Field(...)\n\n @computed_field\n @property\n def id_name(self) -> str:\n return f'{self.ID}_{self.Name}'\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.105Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":11,"totalLines":191,"estimatedTokens":1450}}160{"id":"stack-60238433","source":"stackoverflow","questionId":60238433,"title":"What is the meaning of pydantic models(schemas) in Python while building an API with FastAPI","tags":["python","postgresql","sqlalchemy","fastapi"],"text":"Title: What is the meaning of pydantic models(schemas) in Python while building an API with FastAPI\nTags: python, postgresql, sqlalchemy, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am new at python, and I am trying to build an API with FastAPI.\nIt's working so far, I connected with postgres db, I made post/get/ request and everything is working, but I don't have good understanding why we define the schemas like this, why do we have to create an \n\nclass UserBase(BaseModel)\n\nclass UserCreate(UserBase)\n\nclass User(UserBase)\n\nI will post the source code, for all the files, and if you guys could help me to get a good understanding over this,it would really help me so much, because I've got an assignement for tomorrow.\n\nschemas.py\n\n```\nfrom typing import List\nfrom pydantic import BaseModel\n\n##BOOKING\nclass BookingBase(BaseModel):\n name:str\n description:str = None\n\nclass BookingCreate(BookingBase):\n pass\n\nclass Booking(BookingBase):\n id:int\n user_id:int\n\n class Config:\n orm_mode = True\n\n##USER\nclass UserBase(BaseModel):\n email: str\n\nclass UserCreate(UserBase):\n password: str\n\nclass User(UserBase):\n id: int\n is_active: bool\n bookings: List[Booking] = []\n\n class Config:\n orm_mode = True\n```\n\nmodels.py\n\n```\nfrom .database import Base\nfrom sqlalchemy import Boolean, Column, ForeignKey, Integer, String,DateTime\nfrom sqlalchemy.sql import func\nfrom sqlalchemy.orm import relationship\n\nclass User(Base):\n __tablename__ = \"users\"\n\n id = Column(Integer, primary_key=True,index=True)\n email = Column(String, unique=True, index= True)\n hashed_password = Column(String)\n is_active = Column(Boolean,default=True)\n\n bookings = relationship(\"Booking\", back_populates=\"owner\")\n\nclass Booking(Base):\n __tablename__ = \"bookings\"\n\n id=Column(Integer,primary_key=True,index=True)\n name = Column(String,index=True)\n description = Column(String, index=True)\n created_date = Column(DateTime, server_default=func.now())\n user_id = Column(Integer,ForeignKey(\"users.id\"))\n\n owner = relationship(\"User\",back_populates=\"bookings\")\n```\n\ncrud.py\n\n```\nfrom . import models,schemas\nfrom sqlalchemy.orm import Session\n\ndef get_user(db:Session,user_id:int):\n return db.query(models.User).filter(models.User.id == user_id).first()\n\ndef fetch_user_by_email(db:Session,email:str):\n return db.query(models.User).filter(models.User.email == email).first()\n\ndef get_all_users(db: Session, skip: int = 0, limit: int = 100):\n return db.query(models.User).offset(skip).limit(limit).all()\n\ndef get_bookings(db:Session,skip:int=0,limit:int=100):\n return db.query(models.Booking).offset(skip).limit(limit).all()\n\ndef create_new_user(db:Session,user:schemas.UserCreate):\n testing_hashed = user.password + \"test\"\n db_user = models.User(email=user.email,hashed_password=testing_hashed)\n db.add(db_user)\n db.commit()\n db.refresh(db_user)\n return db_user\n\ndef create_user_booking(db: Session, booking: schemas.BookingCreate, user_id: int):\n db_item = models.Booking(**booking.dict(), user_id=user_id)\n db.add(db_item)\n db.commit()\n db.refresh(db_item)\n return db_item\n```\n\ndatabase.py\n\n```\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import sessionmaker\n\n# SQLALCHEMY_DATABASE_URL = \"sqlite:///./test.db\"\nSQLALCHEMY_DATABASE_URL = \"postgresql://postgres:root@localhost/meetingbookerdb\"\n\n##Creating the SQLAlchemy ORM engine..>> above we have imported create_engine method from sqlalchemy\n##Since we are using Postgres we dont need anything else\n\ncreate_engine\n\nengine = create_engine(\n SQLALCHEMY_DATABASE_URL\n)\n\n#Creating SessionLocal class which will be database session on the request..\n\nSessionLocal = sessionmaker(autocommit=False,autoflush=False,bind=engine)\n\n## Creating the base clase, using the declerative_base() method which returns a class.\n## Later we will need this Base Class to create each of the database models\n\nBase = declarative_base()\n```\n\nand main.py\n\n```\nfrom typing import List\n\nfrom fastapi import Depends, FastAPI, HTTPException\nfrom sqlalchemy.orm import Session\n\nfrom .app import crud, models, schemas\nfrom .app.database import SessionLocal, engine\n\nmodels.Base.metadata.create_all(bind=engine)\n\napp = FastAPI()\n\n# Dependency\ndef get_db():\n try:\n db = SessionLocal()\n yield db\n finally:\n db.close()\n\n@app.post(\"/users/\", response_model=schemas.User)\ndef create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):\n db_user = crud.fetch_user_by_email(db, email=user.email)\n if db_user:\n raise HTTPException(status_code=400, detail=\"Email already registered\")\n return crud.create_new_user(db=db, user=user)\n\n@app.get(\"/users/\", response_model=List[schemas.User])\ndef read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):\n users = crud.get_all_users(db, skip=skip, limit=limit)\n return users\n\n@app.get(\"/users/{user_id}\", response_model=schemas.User)\ndef read_user(user_id: int, db: Session = Depends(get_db)):\n db_user = crud.get_user(db, user_id=user_id)\n if db_user is None:\n raise HTTPException(status_code=404, detail=\"User not found\")\n return db_user\n\n@app.post(\"/users/{user_id}/bookings/\", response_model=schemas.Booking)\ndef create_booking_for_user(\n user_id: int,booking: schemas.BookingCreate, db: Session = Depends(get_db)\n):\n return crud.create_user_booking(db=db, booking=booking, user_id=user_id)\n\n@app.get(\"/bookings/\", response_model=List[schemas.Booking])\ndef read_bookings(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):\n bookings = crud.get_bookings(db, skip=skip, limit=limit)\n return bookings\n```\n\nThe question is, why do we have to create these schemas like that, Okay I get it the first one UserBase has to be for validation with pydantic, but what about the other two, can someone give me a good explaination..\n\nThank you.\n\n========================================\n\nCode:\n```text\nfrom typing import List\nfrom pydantic import BaseModel\n\n##BOOKING\nclass BookingBase(BaseModel):\n name:str\n description:str = None\n\nclass BookingCreate(BookingBase):\n pass\n\nclass Booking(BookingBase):\n id:int\n user_id:int\n\n class Config:\n orm_mode = True\n\n##USER\nclass UserBase(BaseModel):\n email: str\n\nclass UserCreate(UserBase):\n password: str\n\nclass User(UserBase):\n id: int\n is_active: bool\n bookings: List[Booking] = []\n\n class Config:\n orm_mode = True\n```\n\n```text\nfrom .database import Base\nfrom sqlalchemy import Boolean, Column, ForeignKey, Integer, String,DateTime\nfrom sqlalchemy.sql import func\nfrom sqlalchemy.orm import relationship\n\nclass User(Base):\n __tablename__ = \"users\"\n\n id = Column(Integer, primary_key=True,index=True)\n email = Column(String, unique=True, index= True)\n hashed_password = Column(String)\n is_active = Column(Boolean,default=True)\n\n bookings = relationship(\"Booking\", back_populates=\"owner\")\n\nclass Booking(Base):\n __tablename__ = \"bookings\"\n\n id=Column(Integer,primary_key=True,index=True)\n name = Column(String,index=True)\n description = Column(String, index=True)\n created_date = Column(DateTime, server_default=func.now())\n user_id = Column(Integer,ForeignKey(\"users.id\"))\n\n owner = relationship(\"User\",back_populates=\"bookings\")\n```\n\n```text\nfrom . import models,schemas\nfrom sqlalchemy.orm import Session\n\ndef get_user(db:Session,user_id:int):\n return db.query(models.User).filter(models.User.id == user_id).first()\n\ndef fetch_user_by_email(db:Session,email:str):\n return db.query(models.User).filter(models.User.email == email).first()\n\ndef get_all_users(db: Session, skip: int = 0, limit: int = 100):\n return db.query(models.User).offset(skip).limit(limit).all()\n\n\ndef get_bookings(db:Session,skip:int=0,limit:int=100):\n return db.query(models.Booking).offset(skip).limit(limit).all()\n\ndef create_new_user(db:Session,user:schemas.UserCreate):\n testing_hashed = user.password + \"test\"\n db_user = models.User(email=user.email,hashed_password=testing_hashed)\n db.add(db_user)\n db.commit()\n db.refresh(db_user)\n return db_user\n\n\ndef create_user_booking(db: Session, booking: schemas.BookingCreate, user_id: int):\n db_item = models.Booking(**booking.dict(), user_id=user_id)\n db.add(db_item)\n db.commit()\n db.refresh(db_item)\n return db_item\n```\n\n```text\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import sessionmaker\n\n\n# SQLALCHEMY_DATABASE_URL = \"sqlite:///./test.db\"\nSQLALCHEMY_DATABASE_URL = \"postgresql://postgres:root@localhost/meetingbookerdb\"\n\n##Creating the SQLAlchemy ORM engine..>> above we have imported create_engine method from sqlalchemy\n##Since we are using Postgres we dont need anything else\n\ncreate_engine\n\nengine = create_engine(\n SQLALCHEMY_DATABASE_URL\n)\n\n#Creating SessionLocal class which will be database session on the request..\n\nSessionLocal = sessionmaker(autocommit=False,autoflush=False,bind=engine)\n\n## Creating the base clase, using the declerative_base() method which returns a class.\n## Later we will need this Base Class to create each of the database models\n\nBase = declarative_base()\n```\n\n```text\nfrom typing import List\n\nfrom fastapi import Depends, FastAPI, HTTPException\nfrom sqlalchemy.orm import Session\n\nfrom .app import crud, models, schemas\nfrom .app.database import SessionLocal, engine\n\nmodels.Base.metadata.create_all(bind=engine)\n\n\napp = FastAPI()\n\n\n# Dependency\ndef get_db():\n try:\n db = SessionLocal()\n yield db\n finally:\n db.close()\n\n\n@app.post(\"/users/\", response_model=schemas.User)\ndef create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):\n db_user = crud.fetch_user_by_email(db, email=user.email)\n if db_user:\n raise HTTPException(status_code=400, detail=\"Email already registered\")\n return crud.create_new_user(db=db, user=user)\n\n\n@app.get(\"/users/\", response_model=List[schemas.User])\ndef read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):\n users = crud.get_all_users(db, skip=skip, limit=limit)\n return users\n\n\n@app.get(\"/users/{user_id}\", response_model=schemas.User)\ndef read_user(user_id: int, db: Session = Depends(get_db)):\n db_user = crud.get_user(db, user_id=user_id)\n if db_user is None:\n raise HTTPException(status_code=404, detail=\"User not found\")\n return db_user\n\n\n@app.post(\"/users/{user_id}/bookings/\", response_model=schemas.Booking)\ndef create_booking_for_user(\n user_id: int,booking: schemas.BookingCreate, db: Session = Depends(get_db)\n):\n return crud.create_user_booking(db=db, booking=booking, user_id=user_id)\n\n\n@app.get(\"/bookings/\", response_model=List[schemas.Booking])\ndef read_bookings(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):\n bookings = crud.get_bookings(db, skip=skip, limit=limit)\n return bookings\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.105Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":390,"estimatedTokens":2699}}161{"id":"stack-70773879","source":"stackoverflow","questionId":70773879,"title":"fastapi (starlette) RedirectResponse redirect to post instead get method","tags":["python","http-redirect","fastapi","starlette"],"text":"Title: fastapi (starlette) RedirectResponse redirect to post instead get method\nTags: python, http-redirect, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nI have encountered strange redirect behaviour after returning a RedirectResponse object\n\n**events.py**\n\n```\nrouter = APIRouter()\n\n@router.post('/create', response_model=EventBase)\nasync def event_create(\n request: Request,\n user_id: str = Depends(get_current_user),\n service: EventsService = Depends(),\n form: EventForm = Depends(EventForm.as_form)\n):\n event = await service.post(\n ...\n )\n redirect_url = request.url_for('get_event', **{'pk': event['id']})\n return RedirectResponse(redirect_url)\n\n@router.get('/{pk}', response_model=EventSingle)\nasync def get_event(\n request: Request,\n pk: int,\n service: EventsService = Depends()\n):\n ....some logic....\n return templates.TemplateResponse(\n 'event.html',\n context=\n {\n ...\n }\n )\n```\n\n**routers.py**\n\n```\napi_router = APIRouter()\n\n...\napi_router.include_router(events.router, prefix=\"/event\")\n```\n\nthis code returns the result\n\n```\n127.0.0.1:37772 - \"POST /event/22 HTTP/1.1\" 405 Method Not Allowed\n```\n\nOK, I see that for some reason a POST request is called instead of a GET request. I search for an explanation and find that the RedirectResponse object defaults to code 307 and calls POST link\n\nI the advice and add a status\n\n```\nredirect_url = request.url_for('get_event', **{'pk': event['id']}, status_code=status.HTTP_302_FOUND)\n```\n\nAnd get\n\n```\nstarlette.routing.NoMatchFound\n```\n\nfor the experiment, I'm changing `@router.get('/{pk}', response_model=EventSingle)` to `@router.post('/{pk}', response_model=EventSingle)`\n\nand the redirect completes successfully, but the post request doesn't suit me here. What am I doing wrong?\n\n**UPD**\n\nhtml form for running **event/create** logic\n\n**base.html**\n\n```\n\n...\n\n```\n\n**base_view.py**\n\n```\n@router.get('/', response_class=HTMLResponse)\nasync def main_page(request: Request,\n activity_service: ActivityService = Depends()):\n activity = await activity_service.get()\n return templates.TemplateResponse('base.html', context={'request': request,\n 'activities': activity})\n```\n\n========================================\n\nTop Answer:\nThe error you mention here is raised because you are trying to access the `event_create` endpoint via http://127.0.0.1:8000/event/create, for instance. However, since `event_create` route handles `POST` requests, your request ends up in the `get_event` endpoint (and raises a `value is not a valid integer` error, since you are passing a string instead of integer), as **when you type a URL in the address bar of your browser, it performs a `GET` request**.\n\nThus, you need an HTML ``, for example, to submit a `POST` request to the `event_create` endpoint. Below is a working example, which you can use to access the HTML `` at `http://127.0.0.1:8000/event/` (adjust the port number as desired) to send a `POST` request, which will then trigger the `RedirectResponse`.\n\nAs @tiangolo mentioned here, when performing a `RedirectResponse` from a `POST` request route to a `GET` request route, the **response status code has to change** to `303 See Other`. For instance:\n\n```\nreturn RedirectResponse(redirect_url, status_code=status.HTTP_303_SEE_OTHER)\n```\n\n### Working Example:\n\n```\nfrom fastapi import APIRouter, FastAPI, Request, status\nfrom fastapi.responses import RedirectResponse, HTMLResponse\n\nrouter = APIRouter()\n\n# This endpoint can be accessed at http://127.0.0.1:8000/event/\n@router.get('/', response_class=HTMLResponse)\ndef event_create_form(request: Request):\n return \"\"\"\n \n \n \n\n### Create an event\n\n \n \n \n \n \n \"\"\"\n \n@router.post('/create')\ndef event_create(request: Request):\n event = {\"id\": 1}\n redirect_url = request.url_for('get_event', **{'pk': event['id']})\n return RedirectResponse(redirect_url, status_code=status.HTTP_303_SEE_OTHER) \n\n@router.get('/{pk}')\ndef get_event(request: Request, pk: int):\n return {\"pk\": pk}\n\napp = FastAPI()\napp.include_router(router, prefix=\"/event\")\n```\n\n========================================\n\nCode:\n```text\nrouter = APIRouter()\n\n@router.post('/create', response_model=EventBase)\nasync def event_create(\n request: Request,\n user_id: str = Depends(get_current_user),\n service: EventsService = Depends(),\n form: EventForm = Depends(EventForm.as_form)\n):\n event = await service.post(\n ...\n )\n redirect_url = request.url_for('get_event', **{'pk': event['id']})\n return RedirectResponse(redirect_url)\n\n\n@router.get('/{pk}', response_model=EventSingle)\nasync def get_event(\n request: Request,\n pk: int,\n service: EventsService = Depends()\n):\n ....some logic....\n return templates.TemplateResponse(\n 'event.html',\n context=\n {\n ...\n }\n )\n```\n\n```text\napi_router = APIRouter()\n\n...\napi_router.include_router(events.router, prefix=\"/event\")\n```\n\n```text\n127.0.0.1:37772 - \"POST /event/22 HTTP/1.1\" 405 Method Not Allowed\n```\n\n```text\nredirect_url = request.url_for('get_event', **{'pk': event['id']}, status_code=status.HTTP_302_FOUND)\n```\n\n```text\nstarlette.routing.NoMatchFound\n```\n\n```text\n<form action=\"{{ url_for('event_create')}}\" method=\"POST\">\n...\n</form>\n```\n\n```text\n@router.get('/', response_class=HTMLResponse)\nasync def main_page(request: Request,\n activity_service: ActivityService = Depends()):\n activity = await activity_service.get()\n return templates.TemplateResponse('base.html', context={'request': request,\n 'activities': activity})\n```\n\n```text\n@router.get('/{pk}', response_model=EventSingle)\n```\n\n```text\n@router.post('/{pk}', response_model=EventSingle)\n```\n\n```text\n# ...\n return RedirectResponse(redirect_url, status_code=303)\n```\n\n```text\nfrom fastapi import FastAPI, APIRouter, Request\nfrom fastapi.responses import RedirectResponse, HTMLResponse\n\n\nrouter = APIRouter()\n\n@router.get('/form')\ndef form():\n return HTMLResponse(\"\"\"\n <html>\n <form action=\"/event/create\" method=\"POST\">\n <button>Send request</button>\n </form>\n </html>\n \"\"\")\n\n@router.post('/create')\nasync def event_create(\n request: Request\n):\n event = {\"id\": 123}\n redirect_url = request.url_for('get_event', **{'pk': event['id']})\n return RedirectResponse(redirect_url, status_code=303)\n\n\n@router.get('/{pk}')\nasync def get_event(\n request: Request,\n pk: int,\n):\n return f'<html>oi pk={pk}</html>'\n\napp = FastAPI(title='Test API')\n\napp.include_router(router, prefix=\"/event\")\n```\n\n```text\nuvicorn --reload --host 0.0.0.0 --port 3000 example:app\n```\n\n```text\n303\n```\n\n```text\n307\n```\n\n```text\npip install fastapi uvicorn\n```\n\n```py\nreturn RedirectResponse(redirect_url, status_code=status.HTTP_303_SEE_OTHER)\n```\n\n```py\nfrom fastapi import APIRouter, FastAPI, Request, status\nfrom fastapi.responses import RedirectResponse, HTMLResponse\n\nrouter = APIRouter()\n\n# This endpoint can be accessed at http://127.0.0.1:8000/event/\n@router.get('/', response_class=HTMLResponse)\ndef event_create_form(request: Request):\n return \"\"\"\n <html>\n <body>\n <h1>Create an event</h1>\n <form method=\"POST\" action=\"/event/create\">\n <input type=\"submit\" value=\"Create Event\">\n </form>\n </body>\n </html>\n \"\"\"\n \n@router.post('/create')\ndef event_create(request: Request):\n event = {\"id\": 1}\n redirect_url = request.url_for('get_event', **{'pk': event['id']})\n return RedirectResponse(redirect_url, status_code=status.HTTP_303_SEE_OTHER) \n\n@router.get('/{pk}')\ndef get_event(request: Request, pk: int):\n return {\"pk\": pk}\n\n\napp = FastAPI()\napp.include_router(router, prefix=\"/event\")\n```\n\n```text\nevent_create\n```\n\n```text\nevent_create\n```\n\n```text\nPOST\n```\n\n```text\nget_event\n```\n\n```text\nvalue is not a valid integer\n```\n\n```text\nGET\n```\n\n```text\n<form>\n```\n\n```text\nPOST\n```\n\n```text\nevent_create\n```\n\n```text\n<form>\n```\n\n```text\nhttp://127.0.0.1:8000/event/\n```\n\n```text\nPOST\n```\n\n```text\nRedirectResponse\n```\n\n```text\nRedirectResponse\n```\n\n```text\nPOST\n```\n\n```text\nGET\n```\n\n```text\n303 See Other\n```\n\n========================================\n\nComments:\n- Please have a look here if it helps.\n- with `status_code=status.HTTP_303_SEE_OTHER` same result `starlette.routing.NoMatchFound`\n- I should add that a standard html button form is used to run the code, but I don't think it matters. What other information might be useful?\n- I definitely don't understand from the suggested answers how I can make my code work. I'm running the logic to create an event via an html form, just like in the answers. I've added it to the question description.\n- Or are you telling me that the logic in my code is correct and I need to look for the problem somewhere else rather than RedirectResponse ?\n- @Jekson One difference from your code to my example is that you're passing the `status_code` to `url_for` instead of adding it to the `RedirectResponse`, that's probably why you're getting the `NoMatchFound`: it'strying to match a route with a parameter `status_code` and not finding it.\n- @EliasDorneles that's the point! I was very inattentive, incorrect syntax was the cause of the problem.\n- with `status_code=303` same result `starlette.routing.NoMatchFound`\n- Well, your problem is probably elsewhere. Here is a working example: gist.github.com/eliasdorneles/6b2afd81cfc15ad4084d3da620bef7‌​3f (instructions how to run in the comments)\n- I try and got `{\"detail\":[{\"loc\":[\"path\",\"pk\"],\"msg\":\"value is not a valid integer\",\"type\":\"type_error.integer\"}]}` . is that what you mean? But my code works if I change the get to post in the rout as I wrote above\n- @Jekson ah sorry, i had made a mistake in the instructions, you need to point your browser to localhost:3000/event/form -- and not localhost:3000/event/create (which will do a GET request that will fail because it will try to match against `/event/{pk}`, that's the error you saw)\n- @Jekson and indeed, the redirect in your code will work if you change the `GET /event/{pk}` into `POST /event/{pk}` -- but is that a good idea? IMO, it would be hurting your API design, just because of an annoyance of the framework...\n- This way `localhost:3000/event/form` al work correct","metadata":{"transformedAt":"2026-08-18T18:32:29.105Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":34,"totalLines":409,"estimatedTokens":2578}}162{"id":"stack-63949240","source":"stackoverflow","questionId":63949240,"title":"Python global variable in FastAPI not working as normal","tags":["python","python-3.x","docker","fastapi","uvicorn"],"text":"Title: Python global variable in FastAPI not working as normal\nTags: python, python-3.x, docker, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI have a simple FastAPI demo app which achieve a function:\nget different response json by calling a post api named `changeResponse`.\nThe `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 changes after i just call `changeResponse` once, when i build this on docker.The code is as follows:\n\n```\nfrom typing import Optional\nfrom fastapi import FastAPI\nfrom util import read_json\nimport enum\n\napp = FastAPI()\n\ntype = \"00\"\n \n@app.post(\"/changeResponse\")\nasync def handle_change_download_response(param:Optional[str]):\n global type\n type = param\n print(\"type is \"+type)\n return {\"success\":\"true\"}\n\n@app.post(\"/download\")\nasync def handle_download(param:Optional[str]):\n print(\"get download param: \"+param)\n if legalDownload(param):\n print(\"type is \"+type)\n return read_json.readDownloadSuccessRes(type)\n else:\n return read_json.readDownloadFailRes()\n\ndef legalDownload(data:str)->bool:\n return True\n```\n\nthe dockerfile is as follows:\n\n```\nFROM tiangolo/uvicorn-gunicorn-fastapi:python3.7\n\nCOPY ./app /app\n```\n\nwhat i except:\ncall `changeResponse` param is 7, get response for 7,\ncall `changeResponse` param is 8, get response for 8.\nwhat i get:\ncall `changeResponse` param is 7, get reponse for 7, call `changeReponse` 8, sometime the response is 7, sometime is 8, impossible to predict\n\n========================================\n\nTop Answer:\nHad the same issue and got is fixed without changing the workers.\n\n```\napp = FastAPI()\n\napp.type = \"00\"\n```\n\nWhich I think is the best option.\n\nRef with many thanks : fastapi/issues/592\n\n========================================\n\nCode:\n```py\nfrom typing import Optional\nfrom fastapi import FastAPI\nfrom util import read_json\nimport enum\n\napp = FastAPI()\n\ntype = \"00\"\n \n@app.post(\"/changeResponse\")\nasync def handle_change_download_response(param:Optional[str]):\n global type\n type = param\n print(\"type is \"+type)\n return {\"success\":\"true\"}\n\n@app.post(\"/download\")\nasync def handle_download(param:Optional[str]):\n print(\"get download param: \"+param)\n if legalDownload(param):\n print(\"type is \"+type)\n return read_json.readDownloadSuccessRes(type)\n else:\n return read_json.readDownloadFailRes()\n\ndef legalDownload(data:str)->bool:\n return True\n```\n\n```text\nFROM tiangolo/uvicorn-gunicorn-fastapi:python3.7\n\nCOPY ./app /app\n```\n\n```text\nchangeResponse\n```\n\n```text\nchangeResponse\n```\n\n```text\nchangeResponse\n```\n\n```text\nchangeResponse\n```\n\n```text\nchangeResponse\n```\n\n```text\nchangeResponse\n```\n\n```text\nchangeReponse\n```\n\n```text\ndocker run -d -p 80:80 -e WEB_CONCURRENCY=\"2\" myimage\n```\n\n```text\ntiangolo/uvicorn-gunicorn-fastapi\n```\n\n```text\ndefault_web_concurrency = workers_per_core * cores\n```\n\n```text\napp = FastAPI()\n\napp.type = \"00\"\n```\n\n========================================\n\nComments:\n- how did you send the data to the URL? I mean the parameter?\n- http://*.*.*.*/changeResponse?param=00 and use post method\n- i want to figure out how it happends ?\n- Future readers might find this answer helpful as well.\n- thanks,you are right, i solved this problem by set max_workers=1 when run docker image.\n- Can you elaborate on what this do ? I can't find any answer that refers to this on the GitHub issue you linked.","metadata":{"transformedAt":"2026-08-18T18:32:29.105Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":13,"totalLines":162,"estimatedTokens":876}}163{"id":"stack-66390509","source":"stackoverflow","questionId":66390509,"title":"How to set FastAPI version to allow HTTP specifying version in accept header?","tags":["http","fastapi","api-versioning"],"text":"Title: How to set FastAPI version to allow HTTP specifying version in accept header?\nTags: http, fastapi, api-versioning\nSource: Stack Overflow\n\nQuestion:\nI am working on a project that requires to version FastAPI endpoints. We want to version the endpoint through HTTP accept header, for example:\n\n```\nheaders={'Accept': 'application/json;version=1.0.1'}, \nheaders={'Accept': 'application/json;version=1.0.2'}\n```\n\nSetting up the api version like this seem not work:\n\n```\napp = FastAPI(\n version=version,\n title=\"A title\",\n description=\"Some description.\",\n )\n```\n\nDoes anyone know what else I need to do with this ?\n\n========================================\n\nTop Answer:\nTry api versioning for fastapi web applications\n\n### Installation\n\n`pip install fastapi-versioning`\n\n### Examples\n\n```\nfrom fastapi import FastAPI\nfrom fastapi_versioning import VersionedFastAPI, version\n\napp = FastAPI(title=\"My App\")\n\n@app.get(\"/greet\")\n@version(1, 0)\ndef greet_with_hello():\n return \"Hello\"\n\n@app.get(\"/greet\")\n@version(1, 1)\ndef greet_with_hi():\n return \"Hi\"\n\napp = VersionedFastAPI(app)\n```\n\nthis will generate two endpoints:\n\n```\n/v1_0/greet\n/v1_1/greet\n```\n\nas well as:\n\n```\n/docs\n/v1_0/docs\n/v1_1/docs\n/v1_0/openapi.json\n/v1_1/openapi.json\n```\n\nThere's also the possibility of adding a set of additional endpoints that\nredirect the most recent API version. To do that make the argument\n`enable_latest` true:\n\n```\napp = VersionedFastAPI(app, enable_latest=True)\n```\n\nthis will generate the following additional endpoints:\n\n```\n/latest/greet\n/latest/docs\n/latest/openapi.json\n```\n\nIn this example, `/latest` endpoints will reflect the same data as `/v1.1`.\n\nTry it out:\n\n```\npip install pipenv\npipenv install --dev\npipenv run uvicorn example.annotation.app:app\n# pipenv run uvicorn example.folder_name.app:app\n```\n\n### Usage without minor version\n\n```\nfrom fastapi import FastAPI\nfrom fastapi_versioning import VersionedFastAPI, version\n\napp = FastAPI(title='My App')\n\n@app.get('/greet')\n@version(1)\ndef greet():\n return 'Hello'\n\n@app.get('/greet')\n@version(2)\ndef greet():\n return 'Hi'\n\napp = VersionedFastAPI(app,\n version_format='{major}',\n prefix_format='/v{major}')\n```\n\nthis will generate two endpoints:\n\n```\n/v1/greet\n/v2/greet\n```\n\nas well as:\n\n```\n/docs\n/v1/docs\n/v2/docs\n/v1/openapi.json\n/v2/openapi.json\n```\n\n### Extra FastAPI constructor arguments\n\nIt's important to note that only the `title` from the original FastAPI will be\nprovided to the VersionedAPI app. If you have any middleware, event handlers\netc these arguments will also need to be provided to the VersionedAPI function\ncall, as in the example below\n\n```\nfrom fastapi import FastAPI, Request\nfrom fastapi_versioning import VersionedFastAPI, version\nfrom starlette.middleware import Middleware\nfrom starlette.middleware.sessions import SessionMiddleware\n\napp = FastAPI(\n title='My App',\n description='Greet uses with a nice message',\n middleware=[\n Middleware(SessionMiddleware, secret_key='mysecretkey')\n ]\n)\n\n@app.get('/greet')\n@version(1)\ndef greet(request: Request):\n request.session['last_version_used'] = 1\n return 'Hello'\n\n@app.get('/greet')\n@version(2)\ndef greet(request: Request):\n request.session['last_version_used'] = 2\n return 'Hi'\n\n@app.get('/version')\ndef last_version(request: Request):\n return f'Your last greeting was sent from version {request.session[\"last_version_used\"]}'\n\napp = VersionedFastAPI(app,\n version_format='{major}',\n prefix_format='/v{major}',\n description='Greet users with a nice message',\n middleware=[\n Middleware(SessionMiddleware, secret_key='mysecretkey')\n ]\n)\n```\n\n========================================\n\nCode:\n```text\nheaders={'Accept': 'application/json;version=1.0.1'}, \nheaders={'Accept': 'application/json;version=1.0.2'}\n```\n\n```py\napp = FastAPI(\n version=version,\n title=\"A title\",\n description=\"Some description.\",\n )\n```\n\n```text\nfrom fastapi import FastAPI\n\napp = FastAPI()\nv1 = FastAPI()\n\n@v1.get(\"/app/\")\ndef read_main():\n return {\"message\": \"Hello World from api v1\"}\n\nv2 = FastAPI()\n\n@v2.get(\"/app/\")\ndef read_sub():\n return {\"message\": \"Hello World from api v2\"}\n\napp.mount(\"/api/v1\", v1)\napp.mount(\"/api/v2\", v2)\n```\n\n```text\nfrom starlette.requests import Request\n\nfrom fastapi import FastAPI\napp = FastAPI()\n\n@app.post(\"/hyper_mega_fast_service\")\ndef fast_service(request: Request, ):\n\n aceept = request.headers.get('Accept')\n\n value = great_fuction_to_get_version_from_header(aceept)\n if value == '1.0.1': \n \"Do something\"\n \n if value == '1.0.2': \n \"Do something\"\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi_versioning import VersionedFastAPI, version\n\napp = FastAPI(title=\"My App\")\n\n\n@app.get(\"/greet\")\n@version(1, 0)\ndef greet_with_hello():\n return \"Hello\"\n\n\n@app.get(\"/greet\")\n@version(1, 1)\ndef greet_with_hi():\n return \"Hi\"\n\n\napp = VersionedFastAPI(app)\n```\n\n```text\n/v1_0/greet\n/v1_1/greet\n```\n\n```text\n/docs\n/v1_0/docs\n/v1_1/docs\n/v1_0/openapi.json\n/v1_1/openapi.json\n```\n\n```py\napp = VersionedFastAPI(app, enable_latest=True)\n```\n\n```text\n/latest/greet\n/latest/docs\n/latest/openapi.json\n```\n\n```sh\npip install pipenv\npipenv install --dev\npipenv run uvicorn example.annotation.app:app\n# pipenv run uvicorn example.folder_name.app:app\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi_versioning import VersionedFastAPI, version\n\napp = FastAPI(title='My App')\n\n@app.get('/greet')\n@version(1)\ndef greet():\n return 'Hello'\n\n@app.get('/greet')\n@version(2)\ndef greet():\n return 'Hi'\n\napp = VersionedFastAPI(app,\n version_format='{major}',\n prefix_format='/v{major}')\n```\n\n```text\n/v1/greet\n/v2/greet\n```\n\n```text\n/docs\n/v1/docs\n/v2/docs\n/v1/openapi.json\n/v2/openapi.json\n```\n\n```py\nfrom fastapi import FastAPI, Request\nfrom fastapi_versioning import VersionedFastAPI, version\nfrom starlette.middleware import Middleware\nfrom starlette.middleware.sessions import SessionMiddleware\n\napp = FastAPI(\n title='My App',\n description='Greet uses with a nice message',\n middleware=[\n Middleware(SessionMiddleware, secret_key='mysecretkey')\n ]\n)\n\n@app.get('/greet')\n@version(1)\ndef greet(request: Request):\n request.session['last_version_used'] = 1\n return 'Hello'\n\n@app.get('/greet')\n@version(2)\ndef greet(request: Request):\n request.session['last_version_used'] = 2\n return 'Hi'\n\n@app.get('/version')\ndef last_version(request: Request):\n return f'Your last greeting was sent from version {request.session[\"last_version_used\"]}'\n\napp = VersionedFastAPI(app,\n version_format='{major}',\n prefix_format='/v{major}',\n description='Greet users with a nice message',\n middleware=[\n Middleware(SessionMiddleware, secret_key='mysecretkey')\n ]\n)\n```\n\n```text\npip install fastapi-versioning\n```\n\n```text\nenable_latest\n```\n\n```text\n/latest\n```\n\n```text\n/v1.1\n```\n\n```text\ntitle\n```\n\n```py\nimport fastapi\n\nfrom fast_version import VersionedAPIRouter, init_fastapi_versioning\n\n\nVERSION_HEADER: str = \"application/vnd.some.name+json\"\nROUTER_OBJ = VersionedAPIRouter()\n\n\n@ROUTER_OBJ.get(\"/test/\")\nasync def test_get() -> dict:\n return {\"version\": (1, 0)}\n\n\n@ROUTER_OBJ.get(\"/test/\")\n@ROUTER_OBJ.set_api_version((2, 0))\nasync def test_get_v2() -> dict:\n return {\"version\": (2, 0)}\n\n\napp = fastapi.FastAPI()\napp.include_router(ROUTER_OBJ)\ninit_fastapi_versioning(app=app, vendor_media_type=VERSION_HEADER)\n```\n\n```text\n# call 1.0 version\ncurl -X 'GET' 'https://test.ru/test/' -H 'accept: application/vnd.some.name+json; version=1.0'\n\ncurl -X 'GET' 'https://test.ru/test/' -H 'accept: application/vnd.some.name+json'\n\ncurl -X 'GET' 'https://test.ru/test/'\n\n# call 2.0 version\ncurl -X 'GET' 'https://test.ru/test/' -H 'accept: application/vnd.some.name+json; version=2.0'\n```\n\n========================================\n\nComments:\n- I think `version` parameter is for docs only. Maybe try with Response headers for your responses.\n- Future readers should find this answer helpful as well.\n- Another approach could be to add a middleware to identify the version in header then redirect the request to service you want\n- There is also github.com/alexschimpf/fastapi-versionizer","metadata":{"transformedAt":"2026-08-18T18:32:29.106Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":21,"totalLines":431,"estimatedTokens":2033}}164{"id":"stack-63847205","source":"stackoverflow","questionId":63847205,"title":"FastAPI websocket ping/pong timeout","tags":["websocket","fastapi","uvicorn","starlette"],"text":"Title: FastAPI websocket ping/pong timeout\nTags: websocket, fastapi, uvicorn, starlette\nSource: Stack Overflow\n\nQuestion:\nI am using FastAPI with `@app.websocket` to listen for incoming websockets. How does FastAPI (or Starlette or Uvicorn underneath) do ping/pong heartbeats? Is this configurable? I cannot find it in the documentation at all.\n\n```\nfrom fastapi import FastAPI, WebSocket\n\napp = FastAPI()\n\n@app.websocket(\"/\")\ndef ws(websocket: WebSocket):\n pass\n```\n\n`fastapi` uses `starlette`, and under the hood it seems to use `websockets`. `websockets.connect` by default uses a `ping_interval` and `ping_timeout` of 20 seconds, but I can't tell if that is used in FastAPI.\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI, WebSocket\n\napp = FastAPI()\n\n@app.websocket(\"/\")\ndef ws(websocket: WebSocket):\n pass\n```\n\n```text\n@app.websocket\n```\n\n```text\nfastapi\n```\n\n```text\nstarlette\n```\n\n```text\nwebsockets\n```\n\n```text\nwebsockets.connect\n```\n\n```text\nping_interval\n```\n\n```text\nping_timeout\n```\n\n```text\n--ws-ping-interval <float>\n```\n\n```text\nwebsockets\n```\n\n```text\n--ws-ping-timeout <float>\n```\n\n```text\nwebsockets\n```\n\n========================================\n\nComments:\n- the ping pong happens in uvicorn, and there's no current way to configure those values, there's an open issue here : github.com/encode/uvicorn/issues/245 , PR welcome !\n- @euri10 Thanks for the pointer. I'm glad to know it uses the same 20 second defaults. I would love to do a PR, but right now I still don't understand the internals well enough to know how to pass that. I'll keep digging, thanks for the encouragement.\n- @euri10 Just saw github.com/encode/uvicorn/pull/1048. Thank you so much, that is perfect. If you want to turn this into an answer, I'll gladly accept it and give you the internet points :)\n- haha thanks for the reminder ! I added an answer that reflects current usage !\n- Is there a way to do this programmatically in the code? Somewhere in await websocket.accept()\n- @Sayanc2000 When running uvicorn, you can pass them to the `run` method, e.g. `uvicorn.run('app:app', ws_ping_interval=300, ws_ping_timeout=300)`\n- `uvicorn main:app --ws-ping-timeout 2.0` expected to terminate WS in 2 sec but not working for me. Its 32s\n- Have you tried also setting `--ws`? link to highlight I think this is for idle connections attack prevention, not ping/pong flood attack.","metadata":{"transformedAt":"2026-08-18T18:32:29.106Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":12,"totalLines":87,"estimatedTokens":602}}165{"id":"stack-70783994","source":"stackoverflow","questionId":70783994,"title":"Reload routes in FastAPI during runtime","tags":["python","fastapi","uvicorn"],"text":"Title: Reload routes in FastAPI during runtime\nTags: python, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI have a FastAPI app in which routes are dynamically generated based on an DB config.\n\nHowever, once the routes are defined and the app running, if the config changes, there seems to be no way to reload the config so that the routes could reflect the config.\nThe only solution I have for now is manually restart the asgi app by restarting uvicorn.\n\nIs there any way to fully regenerate routes without stopping the app, that could ideally be called from an URL ?\n\n========================================\n\nCode:\n```py\nimport fastapi\n\napp = fastapi.FastAPI()\n\n\n@app.get(\"/add\")\nasync def add(name: str):\n async def dynamic_controller():\n return f\"dynamic: {name}\"\n app.add_api_route(f\"/dyn/{name}\", dynamic_controller, methods=[\"GET\"])\n return \"ok\"\n\n\ndef route_matches(route, name):\n return route.path_format == f\"/dyn/{name}\"\n\n\n@app.get(\"/remove\")\nasync def remove(name: str):\n for i, r in enumerate(app.router.routes):\n if route_matches(r, name):\n del app.router.routes[i]\n return \"ok\"\n return \"not found\"\n```\n\n```text\n$ curl 127.0.0.1:8000/dyn/test\n{\"detail\":\"Not Found\"}\n$ curl 127.0.0.1:8000/add?name=test\n\"ok\"\n$ curl 127.0.0.1:8000/dyn/test\n\"dynamic: test\"\n$ curl 127.0.0.1:8000/add?name=test2\n\"ok\"\n$ curl 127.0.0.1:8000/dyn/test2\n\"dynamic: test2\"\n$ curl 127.0.0.1:8000/remove?name=test\n\"ok\"\n$ curl 127.0.0.1:8000/dyn/test\n{\"detail\":\"Not Found\"}\n$ curl 127.0.0.1:8000/dyn/test2\n\"dynamic: test2\"\n```\n\n```text\nFastAPI\n```\n\n```text\nadd_api_route\n```\n\n```text\nRouter\n```\n\n========================================\n\nComments:\n- Did you find an answer to this?\n- @RobH Unfortunately not. The only way I managed to work around is using variable path parameters and manually check their values inside the controlers, but this removes all the benefits of FastAPI towards data checking with Pydantic model since routes are collapsed into a generic one with no type checking.\n- Yep. I dug through the source code and found that there's no editing of existing routes. :(\n- Future readers might find this answer helpful as well.\n- That's an unexcpected answer, and it seems to fit what I was looking for. It's quite surprising that `add_api_route` is no documented at all ; dynamic routes seem to be such a valued feature!\n- How do you \"invalidate the cache of the OpenAPI endpoint.\"? And is it possible to do dynamically add a GraphQL endpoint in a similar way (using Graphene)?\n- @JayjayJay To invalidate the cache and reload the new app specs: `app.openapi_schema = None; app.setup()`","metadata":{"transformedAt":"2026-08-18T18:32:29.106Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":83,"estimatedTokens":661}}166{"id":"stack-63854588","source":"stackoverflow","questionId":63854588,"title":"Test with FastAPI TestClient returns 422 status code","tags":["python","fastapi"],"text":"Title: Test with FastAPI TestClient returns 422 status code\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI try to test an endpoint with the `TestClient` from FastAPI (which is the Scarlett TestClient basically).\n\nThe response code is always 422 Unprocessable Entity.\n\nThis is my current Code:\n\n```\nfrom typing import Dict, Optional\n\nfrom fastapi import APIRouter\nfrom pydantic import BaseModel\n\nrouter = APIRouter()\n\nclass CreateRequest(BaseModel):\n number: int\n ttl: Optional[float] = None\n\n@router.post(\"/create\")\nasync def create_users(body: CreateRequest) -> Dict:\n return {\n \"msg\": f\"{body.number} Users are created\"\n }\n```\n\nAs you can see I'm also passing the `application/json` header to the client to avoid a potential error.\n\nAnd this is my Test:\n\n```\nfrom fastapi.testclient import TestClient\nfrom metusa import app\n\ndef test_create_50_users():\n client = TestClient(app)\n client.headers[\"Content-Type\"] = \"application/json\"\n\n body = {\n \"number\": 50,\n \"ttl\": 2.0\n }\n response = client.post('/v1/users/create', data=body)\n\n assert response.status_code == 200\n assert response.json() == {\"msg\": \"50 Users created\"}\n```\n\nI also found this error message in the Response Object\n\n```\nb'{\"detail\":[{\"loc\":[\"body\",0],\"msg\":\"Expecting value: line 1 column 1 (char 0)\",\"type\":\"value_error.jsondecode\",\"ctx\":{\"msg\":\"Expecting value\",\"doc\":\"number=50&ttl=2.0\",\"pos\":0,\"lineno\":1,\"colno\":1}}]}'\n```\n\nThank you for your support and time!\n\n========================================\n\nCode:\n```py\nfrom typing import Dict, Optional\n\nfrom fastapi import APIRouter\nfrom pydantic import BaseModel\n\nrouter = APIRouter()\n\n\nclass CreateRequest(BaseModel):\n number: int\n ttl: Optional[float] = None\n\n\n@router.post(\"/create\")\nasync def create_users(body: CreateRequest) -> Dict:\n return {\n \"msg\": f\"{body.number} Users are created\"\n }\n```\n\n```py\nfrom fastapi.testclient import TestClient\nfrom metusa import app\n\n\ndef test_create_50_users():\n client = TestClient(app)\n client.headers[\"Content-Type\"] = \"application/json\"\n\n body = {\n \"number\": 50,\n \"ttl\": 2.0\n }\n response = client.post('/v1/users/create', data=body)\n\n assert response.status_code == 200\n assert response.json() == {\"msg\": \"50 Users created\"}\n```\n\n```text\nb'{\"detail\":[{\"loc\":[\"body\",0],\"msg\":\"Expecting value: line 1 column 1 (char 0)\",\"type\":\"value_error.jsondecode\",\"ctx\":{\"msg\":\"Expecting value\",\"doc\":\"number=50&ttl=2.0\",\"pos\":0,\"lineno\":1,\"colno\":1}}]}'\n```\n\n```text\nTestClient\n```\n\n```text\napplication/json\n```\n\n```py\ndef test_create_50_users():\n client = TestClient(router)\n\n body = {\n \"number\": 50,\n \"ttl\": 2.0\n }\n response = client.post('/create', json=body)\n```\n\n```py\ndef test_create_50_users():\n client = TestClient(router)\n client.headers[\"Content-Type\"] = \"application/json\"\n\n body = {\n \"number\": 50,\n \"ttl\": 2.0\n }\n response = client.post('/create', data=json.dumps(body))\n```\n\n```text\njson\n```\n\n```text\ndata\n```\n\n```text\ndata\n```\n\n```text\njson.dumps\n```\n\n========================================\n\nComments:\n- Yes, the `data=json.dumps(body)` was key to fixing my issue. I used `data=body` and received the `Unprocessable Entity` error, too.\n- idk, both don't work for me\n- ok, my fault. The answer is correct.","metadata":{"transformedAt":"2026-08-18T18:32:29.106Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":11,"totalLines":160,"estimatedTokens":824}}167{"id":"stack-63248112","source":"stackoverflow","questionId":63248112,"title":"How to implement OAuth to FastAPI with client ID & Secret","tags":["python","oauth-2.0","fastapi"],"text":"Title: How to implement OAuth to FastAPI with client ID & Secret\nTags: python, oauth-2.0, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have followed the docs about Oauth2 but it does not describe the proccess to add client id and secret\n\nhttps://fastapi.tiangolo.com/advanced/security/oauth2-scopes/\n\nand what this does\n\n```\nclass UserInDB(User):\n hashed_password: str\n```\n\nfrom the original example\n\n========================================\n\nCode:\n```text\nclass UserInDB(User):\n hashed_password: str\n```\n\n```text\ngrant_type: str = Form(None, regex=\"password\"),\nusername: str = Form(...),\npassword: str = Form(...),\nscope: str = Form(\"\"),\nclient_id: Optional[str] = Form(None),\nclient_secret: Optional[str] = Form(None),\n```\n\n```text\nfrom authlib.integrations.starlette_client import OAuth\nfrom starlette.config import Config\n\nconfig = Config('.env') # read config from .env file\noauth = OAuth(config)\noauth.register(\n name='google',\n server_metadata_url='https://accounts.google.com/.well-known/openid-configuration',\n client_kwargs={\n 'scope': 'openid email profile'\n }\n)\n```\n\n```text\nfrom fastapi import FastAPI, Request\nfrom starlette.middleware.sessions import SessionMiddleware\n\napp = FastAPI()\napp.add_middleware(SessionMiddleware, secret_key=\"secret-string\")\n```\n\n```text\n@app.route('/login')\nasync def login(request: Request):\n redirect_uri = request.url_for('auth')\n return await oauth.google.authorize_redirect(request, redirect_uri\n```\n\n```text\n@app.route('/auth')\nasync def auth(request: Request):\n token = await oauth.google.authorize_access_token(request)\n user = await oauth.google.parse_id_token(request, token)\n return user\n```\n\n```text\nOAuth2PasswordRequestForm\n```\n\n```text\nclient_id\n```\n\n```text\nclient_secret\n```\n\n```text\nauthlib\n```\n\n```text\nserver_metadata_url\n```\n\n```text\nserver_metadata_url\n```\n\n```text\nrequest.session\n```\n\n```text\n/login\n```\n\n```text\nredirect_uri\n```\n\n```text\nrequest.url_for('auth')\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.106Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":16,"totalLines":112,"estimatedTokens":493}}168{"id":"stack-76129550","source":"stackoverflow","questionId":76129550,"title":"How to make case insensitive choices using Python's enum and FastAPI?","tags":["python","enums","fastapi","pydantic"],"text":"Title: How to make case insensitive choices using Python's enum and FastAPI?\nTags: python, enums, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI have this application:\n\n```\nimport enum\nfrom typing import Annotated, Literal\n\nimport uvicorn\nfrom fastapi import FastAPI, Query, Depends\nfrom pydantic import BaseModel\n\napp = FastAPI()\n\nclass MyEnum(enum.Enum):\n ab = \"ab\"\n cd = \"cd\"\n\nclass MyInput(BaseModel):\n q: Annotated[MyEnum, Query(...)]\n\n@app.get(\"/\")\ndef test(inp: MyInput = Depends()):\n return \"Hello world\"\n\ndef main():\n uvicorn.run(\"run:app\", host=\"0.0.0.0\", reload=True, port=8001)\n\nif __name__ == \"__main__\":\n main()\n```\n\n`curl http://127.0.0.1:8001/?q=ab` or `curl http://127.0.0.1:8001/?q=cd` returns \"Hello World\"\n\nBut any of these\n\n- `curl http://127.0.0.1:8001/?q=aB`\n\n- `curl http://127.0.0.1:8001/?q=AB`\n\n- `curl http://127.0.0.1:8001/?q=Cd`\n\n- etc\n\nreturns `422Unprocessable Entity` which makes sense.\n\nHow can I make this validation case insensitive?\n\n========================================\n\nTop Answer:\nI really like the accepted answer's suggestion, however it can be a little bit simplified (and generalised):\n\n```\nfrom enum import Enum\nfrom typing import Any\n\nclass CaseInsensitiveEnum(str, Enum):\n @classmethod\n def _missing_(cls, value: Any):\n if isinstance(value, str):\n value = value.lower()\n\n for member in cls:\n if member.lower() == value:\n return member\n return None\n\nclass MyEnum(CaseInsensitiveEnum):\n ab = 'ab'\n cd = 'cd'\n```\n\n`member.lower()` would not be required when all `MyEnum` values will be defined as lowercase\n\n@update: I applied @NeilG suggestions from the comment below.\n\n========================================\n\nCode:\n```py\nimport enum\nfrom typing import Annotated, Literal\n\nimport uvicorn\nfrom fastapi import FastAPI, Query, Depends\nfrom pydantic import BaseModel\n\napp = FastAPI()\n\n\nclass MyEnum(enum.Enum):\n ab = \"ab\"\n cd = \"cd\"\n\n\nclass MyInput(BaseModel):\n q: Annotated[MyEnum, Query(...)]\n\n\n@app.get(\"/\")\ndef test(inp: MyInput = Depends()):\n return \"Hello world\"\n\n\ndef main():\n uvicorn.run(\"run:app\", host=\"0.0.0.0\", reload=True, port=8001)\n\n\nif __name__ == \"__main__\":\n main()\n```\n\n```text\ncurl http://127.0.0.1:8001/?q=ab\n```\n\n```text\ncurl http://127.0.0.1:8001/?q=cd\n```\n\n```text\ncurl http://127.0.0.1:8001/?q=aB\n```\n\n```text\ncurl http://127.0.0.1:8001/?q=AB\n```\n\n```text\ncurl http://127.0.0.1:8001/?q=Cd\n```\n\n```text\n422Unprocessable Entity\n```\n\n```py\nfrom enum import Enum\n\nclass MyEnum(str, Enum):\n ab = 'ab'\n cd = 'cd'\n \n @classmethod\n def _missing_(cls, value):\n value = value.lower()\n for member in cls:\n if member.lower() == value:\n return member\n return None\n```\n\n```py\nfrom fastapi import FastAPI\nfrom enum import Enum\n\n\napp = FastAPI()\n\n\nclass CaseInsensitiveEnum(str, Enum):\n @classmethod\n def _missing_(cls, value):\n value = value.lower()\n for member in cls:\n if member.lower() == value:\n return member\n return None\n \n\nclass MyEnum(CaseInsensitiveEnum):\n ab = 'aB'\n cd = 'Cd'\n\n\n@app.get(\"/\")\ndef main(q: MyEnum):\n return q\n```\n\n```py\nfrom fastapi import Query, Depends\nfrom pydantic import BaseModel\n\n...\n\nclass MyInput(BaseModel):\n q: MyEnum = Query(...)\n\n\n@app.get(\"/\")\ndef main(inp: MyInput = Depends()):\n return inp.q\n```\n\n```text\nhttp://127.0.0.1:8000/?q=ab\nhttp://127.0.0.1:8000/?q=aB\nhttp://127.0.0.1:8000/?q=cD\nhttp://127.0.0.1:8000/?q=CD\n...\n```\n\n```py\nfrom enum import StrEnum, auto\n\nclass MyEnum(StrEnum): \n AB = auto()\n CD = auto()\n \n @classmethod\n def _missing_(cls, value):\n value = value.lower()\n for member in cls:\n if member == value:\n return member\n return None\n```\n\n```text\nenum\n```\n\n```text\nEnum\n```\n\n```text\n_missing_\n```\n\n```text\ncls\n```\n\n```text\nvalue\n```\n\n```text\nstr\n```\n\n```text\nclass MyEnum(str, Enum)\n```\n\n```text\nstr\n```\n\n```text\n==\n```\n\n```text\n.value\n```\n\n```text\nif member.lower() == value\n```\n\n```text\nclass MyEnum(Enum)\n```\n\n```text\nstr\n```\n\n```text\n.value\n```\n\n```text\nif member.value.lower() == value\n```\n\n```text\nlower()\n```\n\n```text\nmember.lower()\n```\n\n```text\nab = 'aB'\n```\n\n```text\ncd = 'Cd'\n```\n\n```text\nif member == value\n```\n\n```text\nlower()\n```\n\n```text\nEnum\n```\n\n```text\nBaseModel\n```\n\n```text\nStrEnum\n```\n\n```text\nauto()\n```\n\n```py\nfrom enum import Enum\nfrom typing import Any\n\n\nclass CaseInsensitiveEnum(str, Enum):\n @classmethod\n def _missing_(cls, value: Any):\n if isinstance(value, str):\n value = value.lower()\n\n for member in cls:\n if member.lower() == value:\n return member\n return None\n\n\nclass MyEnum(CaseInsensitiveEnum):\n ab = 'ab'\n cd = 'cd'\n```\n\n```text\nmember.lower()\n```\n\n```text\nMyEnum\n```\n\n```py\nclass CaseInsensitiveEnum(str, Enum):\n @classmethod\n def _missing_(cls, value: str):\n return cls.__members__.get(value.upper(), None)\n```\n\n```py\nclass AccountType(str, Enum):\n CHECKING = \"Checking\"\n SAVINGS = \"Saving\"\n\n @classmethod\n def _missing_(cls, value: str):\n # for case insensitive input mapping\n return cls.__members__.get(value.upper(), None)\n```\n\n```text\nn\n```\n\n```text\nimport enum\nimport typing\n\n_StrEnumT = typing.TypeVar(\"_StrEnumT\", bound=type[enum.StrEnum])\n\ndef case_insensitive(enum_t: _StrEnumT) -> _StrEnumT:\n lowercase_members_mapping = {member.lower(): member for member in enum_t}\n assert len(lowercase_members_mapping) == len(\n enum_t,\n ), f\"enum {enum_t.__name__} is case sensitive\"\n\n def _missing_(_cls: typing.Any, value: object) -> typing.Any:\n if not isinstance(value, str):\n raise ValueError(\n f\"Invalid value - expected a string, got: {repr(value)}\",\n )\n member = lowercase_members_mapping.get(value.lower())\n if member is None:\n raise ValueError(\n f\"Invalid {enum_t.__name__}: {repr(value)}\",\n )\n return member\n\n enum_t._missing_ = classmethod(_missing_)\n\n return enum_t\n```\n\n```text\n@case_insensitive\nclass MyEnum(enum.StrEnum):\n ab = \"ab\"\n cd = \"cd\"\n```\n\n========================================\n\nComments:\n- Validating enums by name discussion: https://github.com/pydantic/pydantic/discussions/2980 and custom validators for enums discussion: https://github.com/pydantic/pydantic/discussions/6466\n- great. it works. there is a small problem with your answer. If the original vlaues are uppercase or are not lowercase it won't work. maybe you should change it to `def _missing_(cls, value): for member in cls: if member.value.lower() == value.lower(): return member`\n- Did not use `.lower()` on `member.value`, as the original code posted in the question used lower case letters for the member values and would be easy for people to figure out and adjust it to their case. But, anyways, thanks for pointing it out - it has now changed. Also, I would not suggest using `== value.lower()`, as shown in your comment above, but rather convert the value to lowercase outside the `for loop`, as otherwise, you would unnecessarily call `.lower()` funcion for every enum member in the loop.\n- another suggestion. changing the class to `MyEnum(str, enum.Enum)`\n- It's been changed to `(str, Enum)`, but wouldn't be that necessary to do so, as the example above uses the `value` attribute on each enum member to compare the value to a string. However, by doing so, you could also use `if member.lower() == value` instead. Thus, it might prove convenient when it comes to comparing values inside the endpoint as well, as you would not have to use the `value` attribute. Additionally, if any enum members of `MyEnum` class contained values that were not of `str` type (e.g., numbers, dates), they would automatically be converted to `str`.\n- if you are inheriting from str, you should not do `member.value.lower()`. you should do `member.lower()`\n- This works when a string is passed as an argument to MyEnum class but doesn't work with `==`. The fix is to override `__eq__` like this: `def __eq__(self, other: str) -> bool: other = other.lower(); return super().__eq__(other).` You may also want to add a check that `other` is a string. `isinstance(other, str)`.\n- Note that upper case enum values are preferred from a Python style standards point of view as they equate with constants.\n- Why not use `__members__` instead of a `for member in cls` loop?\n- I found `mypy` reports `error: Argument 1 of \"_missing_\" is incompatible with supertype \"Enum\"; supertype defines the argument type as \"object\" [override]`. I didn't check but presumably the library has no typing. To suppress the error you can remove the `str` type for the `value` argument and instead of `value.lower()` use `str(value).lower()`.\n- Thanks for reporting. I updated the answer by applying your suggestions.\n- How is this generalized, beside the `if isinstance(value, str)`? Note this `value: Any` prevents type checkers from detecting mistakes such as `CaseInsensitiveEnum(42)`.\n- It's generalized by extracting it to the base class, making it reusable by multiple enums definitions without repetitions. And that's the reason why I chose Any for annotation. In the end, there are different use cases and we should always implement a solution that best serves to achieve the final goal. That is why SO questions have multiple answers with different ranks. Some answers are better than others, but sometimes lower-ranked answers are better suitable for the developer, who is looking for some inspiration :) Regards!\n- I can't see anything wrong with this, and it does seem more efficient. Note that the docs show iteration over the class as in the accepted answer. I'm not sure if iterating over the class may be more future proof or have other protections.\n- @NeilG the difference between using `__members__` and iterating of the class is that the former includes aliases, while the latter does not (aliases are entries that their value with a previous one).","metadata":{"transformedAt":"2026-08-18T18:32:29.106Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":45,"totalLines":429,"estimatedTokens":2515}}169{"id":"stack-64115628","source":"stackoverflow","questionId":64115628,"title":"Get starlette request body in the middleware context","tags":["python","http","middleware","fastapi","starlette"],"text":"Title: Get starlette request body in the middleware context\nTags: python, http, middleware, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nI have such middleware\n\n```\nclass RequestContext(BaseHTTPMiddleware):\n async def dispatch(self, request: Request, call_next: RequestResponseEndpoint):\n request_id = request_ctx.set(str(uuid4())) # generate uuid to request\n body = await request.body()\n if body:\n logger.info(...) # log request with body\n else:\n logger.info(...) # log request without body\n \n response = await call_next(request)\n response.headers['X-Request-ID'] = request_ctx.get()\n logger.info(\"%s\" % (response.status_code))\n request_ctx.reset(request_id)\n\n return response\n```\n\nSo the line `body = await request.body()` freezes all requests that have body and I have 504 from all of them. How can I safely read the request body in this context? I just want to log request parameters.\n\n========================================\n\nTop Answer:\nYou can do this safely with a generic ASGI middleware:\n\n```\nfrom typing import Iterable, List, Protocol, Generator\n\nimport pytest\n\nfrom starlette.responses import Response\nfrom starlette.testclient import TestClient\nfrom starlette.types import ASGIApp, Scope, Send, Receive, Message\n\nclass Logger(Protocol):\n def info(self, message: str) -> None:\n ...\n\nclass BodyLoggingMiddleware:\n def __init__(\n self,\n app: ASGIApp,\n logger: Logger,\n ) -> None:\n self.app = app\n self.logger = logger\n\n async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:\n if scope[\"type\"] != \"http\":\n await self.app(scope, receive, send)\n return\n \n done = False\n chunks: \"List[bytes]\" = []\n\n async def wrapped_receive() -> Message:\n nonlocal done\n message = await receive()\n if message[\"type\"] == \"http.disconnect\":\n done = True\n return message\n body = message.get(\"body\", b\"\")\n more_body = message.get(\"more_body\", False)\n if not more_body:\n done = True\n chunks.append(body)\n return message\n try:\n await self.app(scope, wrapped_receive, send)\n finally:\n while not done:\n await wrapped_receive()\n self.logger.info(b\"\".join(chunks).decode()) # or somethin\n\nasync def consume_body_app(scope: Scope, receive: Receive, send: Send) -> None:\n done = False\n while not done:\n msg = await receive()\n done = \"more_body\" not in msg\n await Response()(scope, receive, send)\n\nasync def consume_partial_body_app(scope: Scope, receive: Receive, send: Send) -> None:\n await receive()\n await Response()(scope, receive, send)\n\nclass TestException(Exception):\n pass\n\nasync def consume_body_and_error_app(scope: Scope, receive: Receive, send: Send) -> None:\n done = False\n while not done:\n msg = await receive()\n done = \"more_body\" not in msg\n raise TestException\n\nasync def consume_partial_body_and_error_app(scope: Scope, receive: Receive, send: Send) -> None:\n await receive()\n raise TestException\n\nclass TestLogger:\n def __init__(self, recorder: List[str]) -> None:\n self.recorder = recorder\n \n def info(self, message: str) -> None:\n self.recorder.append(message)\n\n@pytest.mark.parametrize(\n \"chunks, expected_logs\", [\n ([b\"foo\", b\" \", b\"bar\", b\" \", \"baz\"], [\"foo bar baz\"]),\n ]\n)\n@pytest.mark.parametrize(\n \"app\",\n [consume_body_app, consume_partial_body_app]\n)\ndef test_body_logging_middleware_no_errors(chunks: Iterable[bytes], expected_logs: Iterable[str], app: ASGIApp) -> None:\n logs: List[str] = []\n client = TestClient(BodyLoggingMiddleware(app, TestLogger(logs)))\n\n def chunk_gen() -> Generator[bytes, None, None]:\n yield from iter(chunks)\n\n resp = client.get(\"/\", data=chunk_gen())\n assert resp.status_code == 200\n assert logs == expected_logs\n\n@pytest.mark.parametrize(\n \"chunks, expected_logs\", [\n ([b\"foo\", b\" \", b\"bar\", b\" \", \"baz\"], [\"foo bar baz\"]),\n ]\n)\n@pytest.mark.parametrize(\n \"app\",\n [consume_body_and_error_app, consume_partial_body_and_error_app]\n)\ndef test_body_logging_middleware_with_errors(chunks: Iterable[bytes], expected_logs: Iterable[str], app: ASGIApp) -> None:\n logs: List[str] = []\n client = TestClient(BodyLoggingMiddleware(app, TestLogger(logs)))\n\n def chunk_gen() -> Generator[bytes, None, None]:\n yield from iter(chunks)\n\n with pytest.raises(TestException):\n client.get(\"/\", data=chunk_gen())\n assert logs == expected_logs\n\nif __name__ == \"__main__\":\n import os\n pytest.main(args=[os.path.abspath(__file__)])\n```\n\n========================================\n\nCode:\n```text\nclass RequestContext(BaseHTTPMiddleware):\n async def dispatch(self, request: Request, call_next: RequestResponseEndpoint):\n request_id = request_ctx.set(str(uuid4())) # generate uuid to request\n body = await request.body()\n if body:\n logger.info(...) # log request with body\n else:\n logger.info(...) # log request without body\n \n response = await call_next(request)\n response.headers['X-Request-ID'] = request_ctx.get()\n logger.info(\"%s\" % (response.status_code))\n request_ctx.reset(request_id)\n\n return response\n```\n\n```text\nbody = await request.body()\n```\n\n```text\nfrom fastapi import APIRouter, FastAPI, Request, Response, Body\nfrom fastapi.routing import APIRoute\n\nfrom typing import Callable, List\nfrom uuid import uuid4\n\n\nclass ContextIncludedRoute(APIRoute):\n def get_route_handler(self) -> Callable:\n original_route_handler = super().get_route_handler()\n\n async def custom_route_handler(request: Request) -> Response:\n request_id = str(uuid4())\n response: Response = await original_route_handler(request)\n\n if await request.body():\n print(await request.body())\n\n response.headers[\"Request-ID\"] = request_id\n return response\n\n return custom_route_handler\n\n\napp = FastAPI()\nrouter = APIRouter(route_class=ContextIncludedRoute)\n\n\n@router.post(\"/context\")\nasync def non_default_router(bod: List[str] = Body(...)):\n return bod\n\n\napp.include_router(router)\n```\n\n```text\nb'[\"string\"]'\nINFO: 127.0.0.1:49784 - \"POST /context HTTP/1.1\" 200 OK\n```\n\n```text\nfrom starlette.middleware.base import BaseHTTPMiddleware\nfrom starlette.requests import Request\nimport json\nfrom .async_iterator_wrapper import async_iterator_wrapper as aiwrap\n\nclass some_middleware(BaseHTTPMiddleware):\n async def dispatch(self, request:Request, call_next:RequestResponseEndpoint):\n # --------------------------\n # DO WHATEVER YOU TO DO HERE\n #---------------------------\n \n response = await call_next(request)\n\n # Consuming FastAPI response and grabbing body here\n resp_body = [section async for section in response.__dict__['body_iterator']]\n # Repairing FastAPI response\n response.__setattr__('body_iterator', aiwrap(resp_body)\n\n # Formatting response body for logging\n try:\n resp_body = json.loads(resp_body[0].decode())\n except:\n resp_body = str(resp_body)\n```\n\n```text\nclass async_iterator_wrapper:\n def __init__(self, obj):\n self._it = iter(obj)\n def __aiter__(self):\n return self\n async def __anext__(self):\n try:\n value = next(self._it)\n except StopIteration:\n raise StopAsyncIteration\n return value\n```\n\n```text\nclass CopyRequestMiddleware(BaseHTTPMiddleware):\n async def dispatch(self, request: Request, call_next):\n request_body = await request.json()\n request.state.body = request_body\n\n response = await call_next(request)\n return response\n\nclass LogRequestMiddleware(BaseHTTPMiddleware):\n async def dispatch(self, request: Request, call_next):\n # Since it'll be loaded after CopyRequestMiddleware it can access request.state.body.\n request_body = request.state.body\n print(request_body)\n \n response = await call_next(request)\n return response\n```\n\n```text\nrequest_body = request.state.body\n```\n\n```text\nawait request.json()\n```\n\n```text\nawait request.json()\n```\n\n```py\nfrom typing import Callable, Awaitable\n\nfrom starlette.middleware.base import BaseHTTPMiddleware\nfrom starlette.requests import Request\nfrom starlette.responses import StreamingResponse\nfrom starlette.concurrency import iterate_in_threadpool\n\nclass LogStatsMiddleware(BaseHTTPMiddleware):\n async def dispatch( # type: ignore\n self, request: Request, call_next: Callable[[Request], Awaitable[StreamingResponse]],\n ) -> Response:\n response = await call_next(request)\n response_body = [section async for section in response.body_iterator]\n response.body_iterator = iterate_in_threadpool(iter(response_body))\n logging.info(f\"response_body={response_body[0].decode()}\")\n return response\n\ndef init_app(app):\n app.add_middleware(LogStatsMiddleware)\n```\n\n```text\niterate_in_threadpool\n```\n\n```text\nstarlette.responses.StreamingResponse\n```\n\n```text\nclass MyRequestLoggingRoute(APIRoute):\n def get_route_handler(self) -> Callable:\n original_route_handler = super().get_route_handler()\n\n async def custom_route_handler(request: Request) -> Response:\n body = await request.body()\n if body:\n logger.info(...) # log request with body\n else:\n logger.info(...) # log request without body\n try:\n\n return await original_route_handler(request)\n except RequestValidationError as exc:\n detail = {\"errors\": exc.errors(), \"body\": body.decode()}\n raise HTTPException(status_code=422, detail=detail)\n\n return custom_route_handler\n```\n\n```text\nfastapi.APIRouter\n```\n\n```py\nfrom typing import Iterable, List, Protocol, Generator\n\nimport pytest\n\nfrom starlette.responses import Response\nfrom starlette.testclient import TestClient\nfrom starlette.types import ASGIApp, Scope, Send, Receive, Message\n\n\nclass Logger(Protocol):\n def info(self, message: str) -> None:\n ...\n\n\nclass BodyLoggingMiddleware:\n def __init__(\n self,\n app: ASGIApp,\n logger: Logger,\n ) -> None:\n self.app = app\n self.logger = logger\n\n async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:\n if scope[\"type\"] != \"http\":\n await self.app(scope, receive, send)\n return\n \n done = False\n chunks: \"List[bytes]\" = []\n\n async def wrapped_receive() -> Message:\n nonlocal done\n message = await receive()\n if message[\"type\"] == \"http.disconnect\":\n done = True\n return message\n body = message.get(\"body\", b\"\")\n more_body = message.get(\"more_body\", False)\n if not more_body:\n done = True\n chunks.append(body)\n return message\n try:\n await self.app(scope, wrapped_receive, send)\n finally:\n while not done:\n await wrapped_receive()\n self.logger.info(b\"\".join(chunks).decode()) # or somethin\n\n\nasync def consume_body_app(scope: Scope, receive: Receive, send: Send) -> None:\n done = False\n while not done:\n msg = await receive()\n done = \"more_body\" not in msg\n await Response()(scope, receive, send)\n\n\nasync def consume_partial_body_app(scope: Scope, receive: Receive, send: Send) -> None:\n await receive()\n await Response()(scope, receive, send)\n\n\nclass TestException(Exception):\n pass\n\n\nasync def consume_body_and_error_app(scope: Scope, receive: Receive, send: Send) -> None:\n done = False\n while not done:\n msg = await receive()\n done = \"more_body\" not in msg\n raise TestException\n\n\nasync def consume_partial_body_and_error_app(scope: Scope, receive: Receive, send: Send) -> None:\n await receive()\n raise TestException\n\n\nclass TestLogger:\n def __init__(self, recorder: List[str]) -> None:\n self.recorder = recorder\n \n def info(self, message: str) -> None:\n self.recorder.append(message)\n\n\n@pytest.mark.parametrize(\n \"chunks, expected_logs\", [\n ([b\"foo\", b\" \", b\"bar\", b\" \", \"baz\"], [\"foo bar baz\"]),\n ]\n)\n@pytest.mark.parametrize(\n \"app\",\n [consume_body_app, consume_partial_body_app]\n)\ndef test_body_logging_middleware_no_errors(chunks: Iterable[bytes], expected_logs: Iterable[str], app: ASGIApp) -> None:\n logs: List[str] = []\n client = TestClient(BodyLoggingMiddleware(app, TestLogger(logs)))\n\n def chunk_gen() -> Generator[bytes, None, None]:\n yield from iter(chunks)\n\n resp = client.get(\"/\", data=chunk_gen())\n assert resp.status_code == 200\n assert logs == expected_logs\n\n\n@pytest.mark.parametrize(\n \"chunks, expected_logs\", [\n ([b\"foo\", b\" \", b\"bar\", b\" \", \"baz\"], [\"foo bar baz\"]),\n ]\n)\n@pytest.mark.parametrize(\n \"app\",\n [consume_body_and_error_app, consume_partial_body_and_error_app]\n)\ndef test_body_logging_middleware_with_errors(chunks: Iterable[bytes], expected_logs: Iterable[str], app: ASGIApp) -> None:\n logs: List[str] = []\n client = TestClient(BodyLoggingMiddleware(app, TestLogger(logs)))\n\n def chunk_gen() -> Generator[bytes, None, None]:\n yield from iter(chunks)\n\n with pytest.raises(TestException):\n client.get(\"/\", data=chunk_gen())\n assert logs == expected_logs\n\n\nif __name__ == \"__main__\":\n import os\n pytest.main(args=[os.path.abspath(__file__)])\n```\n\n```text\nclass LogRequestsMiddleware:\ndef __init__(self, app:ASGIApp) -> None:\n self.app = app\n\nasync def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:\n receive_cached_ = await receive()\n async def receive_cached():\n return receive_cached_\n request = Request(scope, receive = receive_cached)\n \n # do what you need here\n\n await self.app(scope, receive_cached, send)\n\napp.add_middleware(LogRequestsMiddleware)\n```\n\n========================================\n\nComments:\n- Did your issue resolved or any feedback?\n- @YagizcanDegirmenci im having hard time to check. Ill respond once ill check it.\n- Please have a look at this related answer as well.\n- @Chris I wonder if it's correct to close a question as a duplicate of another one asked a year later?\n- I don't know what made you think it won't work if it is not async. But it will work properly.\n- See also medium.com/gradiant-talks/… for tips on using loguru contexts with request_id tracking.\n- I was implementing using a Middleware, but this method is easier, it's possible to get the response body in a simpler way than in the Middleware: response_body = json.loads(response.body.decode()) And it's possible too to get the original function name: print(req.scope.get(\"endpoint\").__name__)\n- Thanks. This works for me. The explanation is on point as well!","metadata":{"transformedAt":"2026-08-18T18:32:29.106Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":17,"totalLines":517,"estimatedTokens":3674}}170{"id":"stack-75289130","source":"stackoverflow","questionId":75289130,"title":"Flatten nested Pydantic model","tags":["python","fastapi","pydantic"],"text":"Title: Flatten nested Pydantic model\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\n```\nfrom typing import Union\nfrom pydantic import BaseModel, Field\n\nclass Category(BaseModel):\n name: str = Field(alias=\"name\")\n\nclass OrderItems(BaseModel):\n name: str = Field(alias=\"name\")\n category: Category = Field(alias=\"category\")\n unit: Union[str, None] = Field(alias=\"unit\")\n quantity: int = Field(alias=\"quantity\")\n```\n\nWhen instantiated like this:\n\n```\nOrderItems(**{'name': 'Test','category':{'name': 'Test Cat'}, 'unit': 'kg', 'quantity': 10})\n```\n\nIt returns data like this:\n\n```\nOrderItems(name='Test', category=Category(name='Test Cat'), unit='kg', quantity=10)\n```\n\nBut I want the output like this:\n\n```\nOrderItems(name='Test', category='Test Cat', unit='kg', quantity=10)\n```\n\nHow can I achieve this?\n\n========================================\n\nTop Answer:\nYou can now use `AliasPath` to access nested fields (`pydantic>=2.0`):\n\n```\nfrom pydantic import BaseModel, Field, AliasPath\n\nclass FooFlat(BaseModel):\n a: str\n b: float\n foo_x: bool = Field(validation_alias=AliasPath(\"foo\", \"x\"))\n foo_y: str = Field(validation_alias=AliasPath(\"foo\", \"y\"))\n foo_z: int = Field(validation_alias=AliasPath(\"foo\", \"z\"))\n\ndata = {\"a\": \"spam\", \"b\": 3.14, \"foo\": {\"x\": True, \"y\": \".\", \"z\": 0}}\nprint(FooFlat(**data)) # FooFlat(a='spam', b=3.14, x=True, y='.', z=0)\n```\n\n========================================\n\nCode:\n```py\nfrom typing import Union\nfrom pydantic import BaseModel, Field\n\n\nclass Category(BaseModel):\n name: str = Field(alias=\"name\")\n\n\nclass OrderItems(BaseModel):\n name: str = Field(alias=\"name\")\n category: Category = Field(alias=\"category\")\n unit: Union[str, None] = Field(alias=\"unit\")\n quantity: int = Field(alias=\"quantity\")\n```\n\n```py\nOrderItems(**{'name': 'Test','category':{'name': 'Test Cat'}, 'unit': 'kg', 'quantity': 10})\n```\n\n```py\nOrderItems(name='Test', category=Category(name='Test Cat'), unit='kg', quantity=10)\n```\n\n```py\nOrderItems(name='Test', category='Test Cat', unit='kg', quantity=10)\n```\n\n```py\nfrom pydantic import BaseModel\n\n\nclass Foo(BaseModel):\n x: bool\n y: str\n z: int\n\n\nclass _BarBase(BaseModel):\n a: str\n b: float\n\n class Config:\n orm_mode = True\n\n\nclass BarNested(_BarBase):\n foo: Foo\n\n\nclass BarFlat(_BarBase):\n foo_x: bool\n foo_y: str\n```\n\n```py\nfrom pydantic import BaseModel, root_validator\nfrom pydantic.utils import GetterDict\n\n...\n\nclass BarFlat(_BarBase):\n foo_x: bool\n foo_y: str\n\n @root_validator(pre=True)\n def flatten_foo(cls, values: GetterDict) -> GetterDict | dict[str, object]:\n foo = values.get(\"foo\")\n if foo is None:\n return values\n # Assume `foo` must ba valid `Foo` data:\n foo = Foo.validate(foo)\n return {\n \"foo_x\": foo.x,\n \"foo_y\": foo.y,\n } | dict(values)\n```\n\n```py\ntest_dict = {\"a\": \"spam\", \"b\": 3.14, \"foo\": {\"x\": True, \"y\": \".\", \"z\": 0}}\ntest_orm = BarNested(a=\"eggs\", b=-1, foo=Foo(x=False, y=\"..\", z=1))\ntest_flat = '{\"a\": \"beans\", \"b\": 0, \"foo_x\": true, \"foo_y\": \"\"}'\nbar1 = BarFlat.parse_obj(test_dict)\nbar2 = BarFlat.from_orm(test_orm)\nbar3 = BarFlat.parse_raw(test_flat)\nprint(bar1.json(indent=4))\nprint(bar2.json(indent=4))\nprint(bar3.json(indent=4))\n```\n\n```json\n{\n \"a\": \"spam\",\n \"b\": 3.14,\n \"foo_x\": true,\n \"foo_y\": \".\"\n}\n```\n\n```json\n{\n \"a\": \"eggs\",\n \"b\": -1.0,\n \"foo_x\": false,\n \"foo_y\": \"..\"\n}\n```\n\n```json\n{\n \"a\": \"beans\",\n \"b\": 0.0,\n \"foo_x\": true,\n \"foo_y\": \"\"\n}\n```\n\n```py\nfrom pydantic import BaseModel, validator\n\n\nclass Category(BaseModel):\n name: str\n\n\nclass OrderItemBase(BaseModel):\n name: str\n unit: str | None\n quantity: int\n\n\nclass OrderItemCreate(OrderItemBase):\n category: Category\n\n\nclass OrderItemResponse(OrderItemBase):\n category: str\n\n @validator(\"category\", pre=True)\n def handle_category_model(cls, v: object) -> object:\n if isinstance(v, Category):\n return v.name\n if isinstance(v, dict) and \"name\" in v:\n return v[\"name\"]\n return v\n```\n\n```py\nif __name__ == \"__main__\":\n insert_data = '{\"name\": \"foo\", \"category\": {\"name\": \"bar\"}, \"quantity\": 1}'\n insert_obj = OrderItemCreate.parse_raw(insert_data)\n print(insert_obj.json(indent=2))\n ... # insert into DB\n response_obj = OrderItemResponse.parse_obj(insert_obj.dict())\n print(response_obj.json(indent=2))\n```\n\n```json\n{\n \"name\": \"foo\",\n \"unit\": null,\n \"quantity\": 1,\n \"category\": {\n \"name\": \"bar\"\n }\n}\n```\n\n```json\n{\n \"name\": \"foo\",\n \"unit\": null,\n \"quantity\": 1,\n \"category\": \"bar\"\n}\n```\n\n```text\nBarFlat\n```\n\n```text\nfoo\n```\n\n```text\nBarNested\n```\n\n```text\nfoo_x\n```\n\n```text\nfoo_y\n```\n\n```text\nx\n```\n\n```text\ny\n```\n\n```text\nFoo\n```\n\n```text\nz\n```\n\n```text\nroot_validator\n```\n\n```text\npre=True\n```\n\n```text\nfoo\n```\n\n```text\nFoo\n```\n\n```text\nx\n```\n\n```text\ny\n```\n\n```text\nfoo_x\n```\n\n```text\nfoo_y\n```\n\n```text\npre=True\n```\n\n```text\nGetterDict\n```\n\n```text\nfoo_x\n```\n\n```text\nfoo_y\n```\n\n```text\ndict\n```\n\n```text\nBarNested\n```\n\n```text\nBarFlat\n```\n\n```text\nfoo\n```\n\n```text\nfoo\n```\n\n```text\nvalues\n```\n\n```text\nExtra.forbid\n```\n\n```text\nGetterDict\n```\n\n```text\ndict\n```\n\n```text\npop\n```\n\n```text\n\"foo\"\n```\n\n```text\nget\n```\n\n```text\nCategory\n```\n\n```text\ncategory\n```\n\n```text\npre=True\n```\n\n```text\nCategory\n```\n\n```text\ndict\n```\n\n```text\ncategory\n```\n\n```text\nFastAPI\n```\n\n```text\nmyCategory = Category(name=\"test cat\")\nOrderItems(\n name=\"test\",\n category=myCategory.name,\n unit=\"kg\",\n quantity=10)\n```\n\n```text\nclass Category(BaseModel):\n name: str = Field(alias=\"name\")\n\n\nclass OrderItems(BaseModel):\n name: str = Field(alias=\"name\")\n category: Category = Field(alias=\"category\")\n unit: Union[str, None] = Field(alias=\"unit\")\n quantity: int = Field(alias=\"quantity\")\n \n def json(self, *args, **kwargs) -> str:\n self.__dict__.update({'category': self.__dict__['category'].name})\n return super().json(*args, **kwargs)\n \nc = Category(name='Dranks')\nm = OrderItems(name='sodie', category=c, unit='can', quantity=1)\nm.json()\n```\n\n```text\n'{\"name\": \"sodie\", \"category\": \"Dranks\", \"unit\": \"can\", \"quantity\": 1}'\n```\n\n```text\nclass Category(BaseModel):\n name: str = Field(alias=\"name\")\n\n\nclass OrderItems(BaseModel):\n name: str = Field(alias=\"name\")\n category: Category = Field(alias=\"category\")\n unit: Union[str, None] = Field(alias=\"unit\")\n quantity: int = Field(alias=\"quantity\")\n \nc = Category(name='Dranks')\nm = OrderItems(name='sodie', category=c, unit='can', quantity=1)\n\nr = m.dict()\nr['category'] = r['category']['name']\n```\n\n```text\nfrom pydantic import BaseModel, model_validator\nfrom pydantic.v1.utils import GetterDict\n\nclass Foo(BaseModel):\n x: bool\n y: str\n z: int\n\nclass _BarBase(BaseModel):\n a: str\n b: float\n\n class Config:\n from_attributes = True\n\nclass BarNested(_BarBase):\n foo: Foo\n\nclass BarFlat(_BarBase):\n foo_x: bool\n foo_y: str\n\n @model_validator(mode=\"before\")\n def flatten_foo(cls, values: GetterDict):\n foo = values.get(\"foo\")\n if foo is None:\n return values\n foo = Foo.model_validate(foo)\n\n result = {\n \"foo_x\": foo.x,\n \"foo_y\": foo.y,\n }\n result.update(values)\n return result\n\ndata = {\"a\": \"spam\", \"b\": 3.14, \"foo\": {\"x\": True, \"y\": \".\", \"z\": 0}}\n\nprint(BarFlat(**data))\n```\n\n```text\npydantic>=2.0\n```\n\n```py\nfrom pydantic import BaseModel, Field, AliasPath\n\nclass FooFlat(BaseModel):\n a: str\n b: float\n foo_x: bool = Field(validation_alias=AliasPath(\"foo\", \"x\"))\n foo_y: str = Field(validation_alias=AliasPath(\"foo\", \"y\"))\n foo_z: int = Field(validation_alias=AliasPath(\"foo\", \"z\"))\n\ndata = {\"a\": \"spam\", \"b\": 3.14, \"foo\": {\"x\": True, \"y\": \".\", \"z\": 0}}\nprint(FooFlat(**data)) # FooFlat(a='spam', b=3.14, x=True, y='.', z=0)\n```\n\n```text\nAliasPath\n```\n\n```text\npydantic>=2.0\n```\n\n========================================\n\nComments:\n- How are you returning data and getting JSON?\n- `cursor = order_collection.find() return [OrderItems(**item) async for item in cursor]`\n- What do you need the `Category` model for then? Why not just define `category: str` and initialize it with the value `\"Test Cat\"` right away?\n- I need to insert category data like model\n- Then you should probably have a different model for *inserting* than the one you use for *responding*. That is the usual FastAPI practice anyway. In the *response* model you could define `category: str` and use a a regular validator with `pre=True` to handle the dictionary.\n- Category table has more data, I only show here name. Like slug, image and other stuffs\n- Your first way is nice. I already using this way. I was finding any better way like built in method to achieve this type of output. I also tried for root_validator\n- The only other 'option' i saw was maybe using github.com/Maydmor/pydantic-computed that is just the name, and exclude=True the actual category field.\n- The first is a very bad idea for a multitude of reasons. You are circumventing a lot of inner machinery that makes Pydantic models useful by going directly via `__dict__`, you are destroying the purpose of the type annotation, you are setting data that will not conform to the JSON schema returned by the model, .... The second is viable of course, but I wonder why you would not just override the `dict` method to do that and then override `json` to call `dict`.\n- much more sane than my answer\n- @daniil-fajnberg without pre it also works fine. I think I need without pre. Request need to validate as pydantic model\n- @Daniil Fjanberg, very nice! However, how could this work if you would like to flatten two additional attributes from the `Category` class, (e.g. `attr1` and `attr2`). How would the response model look like and do we need separate validators for each attribute (so one for `category (name)`, `attr1` and `attr2`?\n- @MrNetherlands As I said, *you* should define how you want your response model to look. Once you do that, the rest becomes just a matter of *\"how can we make our data look like this?\"* If you had `Category` with `attr1` and `attr2` and wanted to have a response with fields like `category_attr1` and `category_attr2` for example, you could define a `root_validator` to grab the `category` object and assign its attribute values accordingly.\n- Thanks, `root_validator` seems indeed the way to go. However, within the validation function the `values` argument is of class `GetterDict` which does not allow value assigment `values[\"attr1\"] = values[\"category\"].attr1` yields: `'GetterDict' object does not support item assignment (type=type_error)`\n- @MrNetherlands Yes, you are right, that needs to be handled a bit differently than with a regular `dict`. This is not documented (because Pydantic v2 comes soon anyway). I updated my answer to present a more generalized solution first.","metadata":{"transformedAt":"2026-08-18T18:32:29.106Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":63,"totalLines":535,"estimatedTokens":2733}}171{"id":"stack-73721736","source":"stackoverflow","questionId":73721736,"title":"What is the proper way to make downstream HTTP requests inside of Uvicorn/FastAPI?","tags":["python","python-requests","fastapi","starlette","httpx"],"text":"Title: What is the proper way to make downstream HTTP requests inside of Uvicorn/FastAPI?\nTags: python, python-requests, fastapi, starlette, httpx\nSource: Stack Overflow\n\nQuestion:\nI have an API endpoint (FastAPI / Uvicorn). Among other things, it makes a request to yet another API for information. When I load my API with multiple concurrent requests, I begin to receive the following error:\n\n```\nh11._util.LocalProtocolError: can't handle event type ConnectionClosed when role=SERVER and state=SEND_RESPONSE\n```\n\nIn a normal environment, I would take advantage of `request.session`, but I understand it not to be fully thread safe.\n\nThus, what is the proper approach to using requests within a framework such as FastAPI, where multiple threads would be using the `requests` library at the same time?\n\n========================================\n\nTop Answer:\nThe core issue is that the HTTP client's lifecycle must be extended until the connection closes. As soon as any **Response** object is returned, objects based on the view function's lifecycle, including those managed by FastAPI's dependency injection, will be immediately destroyed.\n\nAdditionally, there's a hidden pitfall: in the event of an exception, such as an unexpected disconnection with the client, the **BackgroundTask** of **Response** will not be executed.\n\nI'm a FastAPI beginner, having just started with it yesterday. However, after a simple tracing of the workflow and referencing the implementation of **FileResponse**, I wrote the following code. Based on my quick tests (with fastapi == 0.116.1 and uvicorn == 0.35.0), I haven't found any issues so far. Another reason I didn't use **StreamingResponse** is that I dislike chunked encoding, it loses file size information. I want users to be able to see the download progress when downloading large files.\n\n```\nimport httpx\nfrom fastapi import FastAPI, HTTPException, Request\nfrom fastapi.responses import Response\n\napp = FastAPI()\n\nclass RelayResponse(Response):\n chunk_size = 64 * 1024\n\n def __init__(self, request, url):\n self.request = request\n self.url = url\n self.background = None\n self.init_headers()\n\n async def _handle_target_response(self, response, send):\n if response.status_code not in (200, 206):\n raise HTTPException(\n status_code=500,\n detail=f'Target URL returned HTTP {response.status_code}'\n )\n\n # Chunked transfer encoding is not supported.\n response_body_len = response.headers.get('Content-Length')\n if not response_body_len:\n raise HTTPException(\n status_code=500,\n detail='Target URL did not return a body length'\n )\n\n self.headers.setdefault('Content-Length', response_body_len)\n response_body_len = int(response_body_len)\n\n content_type = response.headers.get(\n 'Content-Type', 'application/octet-stream')\n self.headers.setdefault('Content-Type', content_type)\n\n for header_name in ('ETag', 'Last-Modified',\n 'Accept-Ranges', 'Content-Range',\n 'Content-Disposition'):\n header_value = response.headers.get(header_name)\n if header_value:\n self.headers.setdefault(header_name, header_value)\n\n await send({\n 'type': 'http.response.start',\n 'status': response.status_code,\n 'headers': self.raw_headers\n })\n\n length_sent = 0\n async for chunk in response.aiter_bytes(self.chunk_size):\n length_sent += len(chunk)\n more_body = length_sent != response_body_len\n await send({\n 'type': 'http.response.body',\n 'body': chunk,\n 'more_body': more_body\n })\n\n async def _handle(self, send):\n request_headers = {}\n for name in ('Accept', 'User-Agent', 'Range',\n 'If-Range', 'If-Match', 'If-Modified-Since'):\n value = self.request.headers.get(name)\n if value:\n request_headers[name] = value\n\n async with httpx.AsyncClient(http2=True) as client:\n async with client.stream(\n 'GET',\n self.url,\n headers=request_headers,\n follow_redirects=True\n ) as response:\n await self._handle_target_response(response, send)\n\n async def __call__(self, scope, receive, send):\n try:\n return await self._handle(send)\n except httpx.HTTPError as e:\n raise HTTPException(\n status_code=500, detail=f'Remote HTTP error: {e}')\n except Exception as e:\n raise HTTPException(\n status_code=500, detail=f'Unexpected error: {e}')\n\n# http://127.0.0.1:8000/relay/https://httpbin.org/get?msg=hello\n@app.get('/relay/{url_path:path}')\nasync def relay(request: Request, url_path: str):\n target_url = f'{url_path}?{request.url.query}'\n return RelayResponse(request, target_url)\n```\n\n========================================\n\nCode:\n```text\nh11._util.LocalProtocolError: can't handle event type ConnectionClosed when role=SERVER and state=SEND_RESPONSE\n```\n\n```text\nrequest.session\n```\n\n```text\nrequests\n```\n\n```py\nfrom fastapi import FastAPI\nfrom starlette.background import BackgroundTask\nfrom fastapi.responses import StreamingResponse\nimport httpx\n\n\napp = FastAPI()\n\n\n@app.on_event(\"startup\")\nasync def startup_event():\n app.state.client = httpx.AsyncClient()\n\n\n@app.on_event('shutdown')\nasync def shutdown_event():\n await app.state.client.aclose()\n\n\n@app.get('/')\nasync def home():\n client = app.state.client\n req = client.build_request('GET', 'https://www.example.com/')\n r = await client.send(req, stream=True)\n return StreamingResponse(r.aiter_raw(), background=BackgroundTask(r.aclose))\n```\n\n```py\nfrom fastapi import FastAPI, Request\nfrom contextlib import asynccontextmanager\nfrom fastapi.responses import StreamingResponse\nfrom starlette.background import BackgroundTask\nimport httpx\n\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI):\n # Initialize the Client on startup and add it to the state\n async with httpx.AsyncClient() as client:\n yield {'client': client}\n # The Client closes on shutdown \n\n\napp = FastAPI(lifespan=lifespan)\n\n\n@app.get('/')\nasync def home(request: Request):\n client = request.state.client\n req = client.build_request('GET', 'https://www.example.com')\n r = await client.send(req, stream=True)\n return StreamingResponse(r.aiter_raw(), background=BackgroundTask(r.aclose))\n```\n\n```py\n@app.get('/')\nasync def home(request: Request):\n client = request.state.client\n req = client.build_request('GET', 'https://www.example.com')\n r = await client.send(req, stream=True)\n \n async def gen():\n async for chunk in r.aiter_raw():\n yield chunk\n await r.aclose()\n \n return StreamingResponse(gen())\n```\n\n```py\nfrom fastapi import Response\nfrom fastapi.responses import PlainTextResponse\n\n@app.get('/')\nasync def home(request: Request):\n client = request.state.client\n req = client.build_request('GET', 'https://www.example.com')\n r = await client.send(req)\n content_type = r.headers.get('content-type')\n \n if content_type == 'application/json':\n return r.json()\n elif content_type == 'text/plain':\n return PlainTextResponse(content=r.text)\n else:\n return Response(content=r.content)\n```\n\n```py\nfrom fastapi import Request, Depends\nimport httpx\n# ...\n\n\nasync def get_client(request: Request) -> httpx.AsyncClient:\n return request.state.client\n \n \n@app.get('/')\nasync def home(client: httpx.AsyncClient = Depends(get_client)):\n req = client.build_request('GET', 'https://www.example.com')\n # ...\n```\n\n```py\nlimits = httpx.Limits(max_keepalive_connections=5, max_connections=10)\nclient = httpx.Client(limits=limits)\n```\n\n```text\nrequests\n```\n\n```text\nhttpx\n```\n\n```text\nasync\n```\n\n```text\nhttpx\n```\n\n```text\nasync\n```\n\n```text\nTestClient\n```\n\n```text\nrequests\n```\n\n```text\nhttpx\n```\n\n```text\nhttpx\n```\n\n```text\nhttpx.AsyncClient()\n```\n\n```text\nrequests.Session()\n```\n\n```text\nheaders\n```\n\n```text\nproxies\n```\n\n```text\ntimeout\n```\n\n```text\ncookies\n```\n\n```text\nClient\n```\n\n```text\nawait client.aclose()\n```\n\n```text\nshutdown\n```\n\n```text\nstartup\n```\n\n```text\nshutdown\n```\n\n```text\nlifespan\n```\n\n```text\nhttpx\n```\n\n```text\nlifespan\n```\n\n```text\nhttpx\n```\n\n```text\nlifespan\n```\n\n```text\nstate\n```\n\n```text\nstate\n```\n\n```text\nrequest.state\n```\n\n```text\nasync\n```\n\n```text\nhttpx\n```\n\n```text\naiter_bytes()\n```\n\n```text\naiter_text()\n```\n\n```text\naiter_lines()\n```\n\n```text\naiter_raw()\n```\n\n```text\nmedia_type\n```\n\n```text\nStreamingResponse\n```\n\n```text\nmedia_type=r.headers['content-type']\n```\n\n```text\nmedia_type\n```\n\n```text\ntext/plain\n```\n\n```text\nStreamingResponse\n```\n\n```text\nhttpx\n```\n\n```text\nr.json()\n```\n\n```text\nPlainTextResponse\n```\n\n```text\nResponse\n```\n\n```text\nclient\n```\n\n```text\nasync\n```\n\n```text\nhttpx\n```\n\n```text\nasync def\n```\n\n```text\ndef\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\nHTTPX\n```\n\n```text\nlimits\n```\n\n```text\nClient\n```\n\n```py\nimport httpx\nfrom fastapi import FastAPI, HTTPException, Request\nfrom fastapi.responses import Response\n\napp = FastAPI()\n\n\nclass RelayResponse(Response):\n chunk_size = 64 * 1024\n\n def __init__(self, request, url):\n self.request = request\n self.url = url\n self.background = None\n self.init_headers()\n\n async def _handle_target_response(self, response, send):\n if response.status_code not in (200, 206):\n raise HTTPException(\n status_code=500,\n detail=f'Target URL returned HTTP {response.status_code}'\n )\n\n # Chunked transfer encoding is not supported.\n response_body_len = response.headers.get('Content-Length')\n if not response_body_len:\n raise HTTPException(\n status_code=500,\n detail='Target URL did not return a body length'\n )\n\n self.headers.setdefault('Content-Length', response_body_len)\n response_body_len = int(response_body_len)\n\n content_type = response.headers.get(\n 'Content-Type', 'application/octet-stream')\n self.headers.setdefault('Content-Type', content_type)\n\n for header_name in ('ETag', 'Last-Modified',\n 'Accept-Ranges', 'Content-Range',\n 'Content-Disposition'):\n header_value = response.headers.get(header_name)\n if header_value:\n self.headers.setdefault(header_name, header_value)\n\n await send({\n 'type': 'http.response.start',\n 'status': response.status_code,\n 'headers': self.raw_headers\n })\n\n length_sent = 0\n async for chunk in response.aiter_bytes(self.chunk_size):\n length_sent += len(chunk)\n more_body = length_sent != response_body_len\n await send({\n 'type': 'http.response.body',\n 'body': chunk,\n 'more_body': more_body\n })\n\n async def _handle(self, send):\n request_headers = {}\n for name in ('Accept', 'User-Agent', 'Range',\n 'If-Range', 'If-Match', 'If-Modified-Since'):\n value = self.request.headers.get(name)\n if value:\n request_headers[name] = value\n\n async with httpx.AsyncClient(http2=True) as client:\n async with client.stream(\n 'GET',\n self.url,\n headers=request_headers,\n follow_redirects=True\n ) as response:\n await self._handle_target_response(response, send)\n\n async def __call__(self, scope, receive, send):\n try:\n return await self._handle(send)\n except httpx.HTTPError as e:\n raise HTTPException(\n status_code=500, detail=f'Remote HTTP error: {e}')\n except Exception as e:\n raise HTTPException(\n status_code=500, detail=f'Unexpected error: {e}')\n\n\n# http://127.0.0.1:8000/relay/https://httpbin.org/get?msg=hello\n@app.get('/relay/{url_path:path}')\nasync def relay(request: Request, url_path: str):\n target_url = f'{url_path}?{request.url.query}'\n return RelayResponse(request, target_url)\n```\n\n========================================\n\nComments:\n- Thank you for the advice. I will try it out right away. If it does the trick, I'll mark this as the answer.\n- Thank you for your detailed answer! I have understood \"startup-shutdown\" event, and from fastapi's tutorial, I can realize that fastapi put objects that should be shared during lifespan in a dict `ml_models`, when you need to use it, you can just get it from the dict. But I can't quite understand your example in lifespan about yielding a dict and getting `client` from `response.state`. I read the document of starllete but it is almost the same as your example, is there any more detailed explanation about this?\n- actually what I'd like to ask is, if I don't use request as parameter, instead I use query or body, how to use lifespan as your example? or I can only use lifespan as fastapi's example to use a dict?\n- @ChuangMen The `request` parameter can be used along with any other parameter","metadata":{"transformedAt":"2026-08-18T18:32:29.107Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":64,"totalLines":564,"estimatedTokens":3193}}172{"id":"stack-73155460","source":"stackoverflow","questionId":73155460,"title":"How to get the cookies from an HTTP request using FastAPI?","tags":["python","http","cookies","fastapi","starlette"],"text":"Title: How to get the cookies from an HTTP request using FastAPI?\nTags: python, http, cookies, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nIs it possible to get the cookies when someone hits the API? I need to read the cookies for each request.\n\n```\n@app.get(\"/\")\nasync def root(text: str, sessionKey: str = Header(None)):\n print(sessionKey)\n return {\"message\": text+\" returned\"}\n\nif __name__ == \"__main__\":\n uvicorn.run(\"main:app\", host=\"0.0.0.0\", port=5001 ,reload=True)\n```\n\n========================================\n\nTop Answer:\n### Option 1\n\nUse the `Request` object to get the cookie you wish, as described in Starlette documentation.\n\n```\nfrom fastapi import Request\n\n@app.get('/')\nasync def root(request: Request):\n return request.cookies.get('sessionKey')\n```\n\n### Option 2\n\nUse the `Cookie` parameter, as described in FastAPI documentation. On a side note, the example below defines the cookie parameter as *optional*, using the type `Union[str, None]`; however, there are other ways doing that as well (e.g., `str | None` in Python 3.10+)—have a look at this answer and this answer for more details.\n\n```\nfrom fastapi import Cookie\nfrom typing import Union\n\n@app.get('/')\nasync def root(sessionKey: Union[str, None] = Cookie(None)):\n return sessionKey\n```\n\n========================================\n\nCode:\n```text\n@app.get(\"/\")\nasync def root(text: str, sessionKey: str = Header(None)):\n print(sessionKey)\n return {\"message\": text+\" returned\"}\n\nif __name__ == \"__main__\":\n uvicorn.run(\"main:app\", host=\"0.0.0.0\", port=5001 ,reload=True)\n```\n\n```py\nfrom fastapi import Cookie\n\n@app.get(\"/\")\nasync def root(text: str, sessionKey: str = Header(None), cookie_param: int | None = Cookie(None)):\n print(cookie_param)\n return {\"message\": f\"{text} returned\"}\n```\n\n```py\nfrom fastapi import Request\n\n@app.get('/')\nasync def root(request: Request):\n return request.cookies.get('sessionKey')\n```\n\n```py\nfrom fastapi import Cookie\nfrom typing import Union\n\n@app.get('/')\nasync def root(sessionKey: Union[str, None] = Cookie(None)):\n return sessionKey\n```\n\n```text\nRequest\n```\n\n```text\nCookie\n```\n\n```text\nUnion[str, None]\n```\n\n```text\nstr | None\n```\n\n========================================\n\nComments:\n- Keep in mind that the variable name 'sessionkey' in option 2 must be equal to the cookie key name.","metadata":{"transformedAt":"2026-08-18T18:32:29.107Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":8,"totalLines":104,"estimatedTokens":583}}173{"id":"stack-69166262","source":"stackoverflow","questionId":69166262,"title":"FastAPI - adding route prefix to TestClient","tags":["python","fastapi","starlette"],"text":"Title: FastAPI - adding route prefix to TestClient\nTags: python, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nI have a FastAPI app with a route prefix as `/api/v1`.\n\nWhen I run the test it throws `404`. I see this is because the `TestClient` is not able to find the route at `/ping`, and works perfectly when the route in the test case is changed to `/api/v1/ping`.\n\nIs there a way in which I can avoid changing all the routes in all the test functions as per the prefix? This seems to be cumbersome as there are many test cases, and also because I dont want to have a hard-coded dependency of the route prefix in my test cases. Is there a way in which I can configure the prefix in the `TestClient` just as we did in `app`, and simply mention the route just as mentioned in the `routes.py`?\n\n**routes.py**\n\n```\nfrom fastapi import APIRouter\n\nrouter = APIRouter()\n\n@router.get(\"/ping\")\nasync def ping_check():\n return {\"msg\": \"pong\"}\n```\n\n**main.py**\n\n```\nfrom fastapi import FastAPI\nfrom routes import router\n\napp = FastAPI()\napp.include_router(prefix=\"/api/v1\")\n```\n\nIn the test file I have:\n\n**test.py**\n\n```\nfrom main import app\nfrom fastapi.testclient import TestClient\n\nclient = TestClient(app)\n\ndef test_ping():\n response = client.get(\"/ping\")\n assert response.status_code == 200\n assert response.json() == {\"msg\": \"pong\"}\n```\n\n========================================\n\nTop Answer:\nHad to cast @Shod's answer to str for it to work on FastAPI 0.104\n\n```\nclient = TestClient(app)\nclient.base_url = str(client.base_url) + settings.api_prefix # adding prefix\nclient.base_url = str(client.base_url).rstrip(\"/\") + \"/\" # making sure we have 1 and only 1 `/`\n```\n\n========================================\n\nCode:\n```py\nfrom fastapi import APIRouter\n\nrouter = APIRouter()\n\n@router.get(\"/ping\")\nasync def ping_check():\n return {\"msg\": \"pong\"}\n```\n\n```py\nfrom fastapi import FastAPI\nfrom routes import router\n\napp = FastAPI()\napp.include_router(prefix=\"/api/v1\")\n```\n\n```py\nfrom main import app\nfrom fastapi.testclient import TestClient\n\nclient = TestClient(app)\n\ndef test_ping():\n response = client.get(\"/ping\")\n assert response.status_code == 200\n assert response.json() == {\"msg\": \"pong\"}\n```\n\n```text\n/api/v1\n```\n\n```text\n404\n```\n\n```text\nTestClient\n```\n\n```text\n/ping\n```\n\n```text\n/api/v1/ping\n```\n\n```text\nTestClient\n```\n\n```text\napp\n```\n\n```text\nroutes.py\n```\n\n```py\nfrom main import app, ROUTE_PREFIX\nfrom fastapi.testclient import TestClient\n\nclient = TestClient(app)\nclient.base_url += ROUTE_PREFIX # adding prefix\nclient.base_url = client.base_url.rstrip(\"/\") + \"/\" # making sure we have 1 and only 1 `/`\n\ndef test_ping():\n response = client.get(\"ping\") # notice the path no more begins with a `/`\n assert response.status_code == 200\n assert response.json() == {\"msg\": \"pong\"}\n```\n\n```text\nTestClient\n```\n\n```text\nbase_url\n```\n\n```text\nurljoin\n```\n\n```text\npath\n```\n\n```text\nbase_url\n```\n\n```text\nurl = urljoin(self.base_url, url)\n```\n\n```text\nurljoin\n```\n\n```text\nbase_url\n```\n\n```text\n/\n```\n\n```text\npath\n```\n\n```text\n/\n```\n\n```text\nfrom fastapi import FastAPI, APIRouter\nfrom fastapi.testclient import TestClient\n\napp = FastAPI()\nrouter = APIRouter(prefix=\"/sample\")\n\napp.include_router(router)\n\n@router.post(\"/s1\")\ndef read_main():\n return {\"msg\": \"Hello World\"}\n\nclient = TestClient(router)\nclient.base_url += \"/sample\"\nclient.base_url = client.base_url.rstrip(\"/\") + \"/\"\n\ndef test_main():\n response = client.post(\"s1\")\n assert response.status_code == 200\n assert response.json() == {\"msg\": \"Hello World\"}\n```\n\n```text\nclient = TestClient(app)\nclient.base_url = str(client.base_url) + settings.api_prefix # adding prefix\nclient.base_url = str(client.base_url).rstrip(\"/\") + \"/\" # making sure we have 1 and only 1 `/`\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.107Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":25,"totalLines":211,"estimatedTokens":945}}174{"id":"stack-76142431","source":"stackoverflow","questionId":76142431,"title":"How to run another application within the same running event loop?","tags":["python-3.x","python-asyncio","fastapi","python-telegram-bot","event-loop"],"text":"Title: How to run another application within the same running event loop?\nTags: python-3.x, python-asyncio, fastapi, python-telegram-bot, event-loop\nSource: Stack Overflow\n\nQuestion:\nI want my FastAPI app to have access to always actual `bot_data` of python-telegram-bot.\nI need that so when i call some endpoint in FastAPI could, for example, send messages to all chats, stored somewere in `bot_data`.\n\nAs i understand the problem: `bot.run_polling()` and `uvicorn.run(...)` launch two independent async loops. And i need to run them in one.\n\n***UPD-1:***\n\nThanks to @MatsLindh I created next function which i pass to **main** block, but it works **inconsistent**. Some times bot.run_polling() (gets correct loop and everything works, but other times and breaks with error that there are different loops):\n\n```\nimport asyncio\nfrom uvicorn import Config, Server\n# --snip--\ndef run(app: FastAPI, bot:Application):\n # using get_event_loop leads to:\n # RuntimeError: Cannot close a running event loop\n # I guess it is because bot.run_polling()\n # calls loop.run_until_complete() different tasks\n # loop = asyncio.get_event_loop()\n loop = asyncio.new_event_loop()\n server = Server(Config(app=app, port=9001))\n loop.create_task(server.serve())\n\n t = Thread(target=loop.run_forever)\n t.start()\n\n bot.run_polling()\n\n t.join()\n# --snip--\nif __name__ == \"__main__\":\n# --snip--\n run(f_app, bot_app)\n```\n\nAlso i know I could decompose `bot.run_polling()` into several separate calls that are agregated inside, but I am sure it should work with just that shortuct funcion.\n\n**Initial**\n\nMy simplified setup looks like below.\n\nInitially I tried to run not with threads but with `multiprocessing.Proccess`, however in that way my `bot_data` was always empty - i assumed it is because bot data not shared between processes so whole thing must be in one process. And here I am failing in to run all these stuff in one async loop.\n\n```\n# main.py\n# python3.10\n# pip install fastapi[all] python-telegram-bot\nfrom threading import Thread\n\nimport uvicorn\nfrom telegram.ext import Application, ApplicationBuilder, PicklePersistence\nfrom fastapi import FastAPI, Request\n\nBOT_TOKEN = \"telegram-bot-token\"\nMY_CHAT = 123456\n\nclass MyApp(FastAPI):\n def add_bot(self, bot_app: Application):\n self.bot_app = bot_app\n\nasync def post_init(app: Application):\n app.bot_data[\"key\"] = 42\n\nf_app = MyApp()\n\n@f_app.get(\"/\")\nasync def test(request: Request):\n app: MyApp = request.app\n bot_app: Application = app.bot_app\n val = bot_app.bot_data.get('key')\n print(f\"{val=}\")\n await bot_app.bot.send_message(MY_CHAT, f\"Should be 42: {val}\")\n\nif __name__ == \"__main__\":\n pers = PicklePersistence(\"storage\")\n bot_app = ApplicationBuilder().token(BOT_TOKEN).post_init(post_init).persistence(pers).build()\n f_app.add_bot(bot_app)\n\n t1 = Thread(target=uvicorn.run, args=(f_app,), kwargs={\"port\": 9001})\n t1.start()\n\n # --- Launching polling in main thread causes\n # telegram.error.NetworkError: Unknown error in HTTP implementation:\n # RuntimeError(' is bound to a different event loop')\n # message is sent and value is correct, BUT app breaks and return 500\n # bot_app.run_polling()\n\n # --- Launching polling in separate thread causes\n # RuntimeError: There is no current event loop in thread 'Thread-2 (run_polling)'.\n # t2 = Thread(target=bot_app.run_polling)\n # t2.start()\n\n # --- Launching with asyncio causes:\n # ValueError: a coroutine was expected, got <bound method Application.run_polling ...\n # import asyncio\n # t2 = Thread(target=asyncio.run, args=(bot_app.run_polling,))\n # t2.start()\n\n t1.join()\n```\n\n========================================\n\nCode:\n```py\nimport asyncio\nfrom uvicorn import Config, Server\n# --snip--\ndef run(app: FastAPI, bot:Application):\n # using get_event_loop leads to:\n # RuntimeError: Cannot close a running event loop\n # I guess it is because bot.run_polling()\n # calls loop.run_until_complete() different tasks\n # loop = asyncio.get_event_loop()\n loop = asyncio.new_event_loop()\n server = Server(Config(app=app, port=9001))\n loop.create_task(server.serve())\n\n t = Thread(target=loop.run_forever)\n t.start()\n\n bot.run_polling()\n\n t.join()\n# --snip--\nif __name__ == \"__main__\":\n# --snip--\n run(f_app, bot_app)\n```\n\n```py\n# main.py\n# python3.10\n# pip install fastapi[all] python-telegram-bot\nfrom threading import Thread\n\nimport uvicorn\nfrom telegram.ext import Application, ApplicationBuilder, PicklePersistence\nfrom fastapi import FastAPI, Request\n\nBOT_TOKEN = \"telegram-bot-token\"\nMY_CHAT = 123456\n\nclass MyApp(FastAPI):\n def add_bot(self, bot_app: Application):\n self.bot_app = bot_app\n\nasync def post_init(app: Application):\n app.bot_data[\"key\"] = 42\n\nf_app = MyApp()\n\n@f_app.get(\"/\")\nasync def test(request: Request):\n app: MyApp = request.app\n bot_app: Application = app.bot_app\n val = bot_app.bot_data.get('key')\n print(f\"{val=}\")\n await bot_app.bot.send_message(MY_CHAT, f\"Should be 42: {val}\")\n\n\nif __name__ == \"__main__\":\n pers = PicklePersistence(\"storage\")\n bot_app = ApplicationBuilder().token(BOT_TOKEN).post_init(post_init).persistence(pers).build()\n f_app.add_bot(bot_app)\n\n t1 = Thread(target=uvicorn.run, args=(f_app,), kwargs={\"port\": 9001})\n t1.start()\n\n # --- Launching polling in main thread causes\n # telegram.error.NetworkError: Unknown error in HTTP implementation:\n # RuntimeError('<asyncio.locks.Event object at 0x7f2764e6fd00 [unset]> is bound to a different event loop')\n # message is sent and value is correct, BUT app breaks and return 500\n # bot_app.run_polling()\n\n # --- Launching polling in separate thread causes\n # RuntimeError: There is no current event loop in thread 'Thread-2 (run_polling)'.\n # t2 = Thread(target=bot_app.run_polling)\n # t2.start()\n\n # --- Launching with asyncio causes:\n # ValueError: a coroutine was expected, got <bound method Application.run_polling ...\n # import asyncio\n # t2 = Thread(target=asyncio.run, args=(bot_app.run_polling,))\n # t2.start()\n\n t1.join()\n```\n\n```text\nbot_data\n```\n\n```text\nbot_data\n```\n\n```text\nbot.run_polling()\n```\n\n```text\nuvicorn.run(...)\n```\n\n```text\nbot.run_polling()\n```\n\n```text\nmultiprocessing.Proccess\n```\n\n```text\nbot_data\n```\n\n```text\n> RuntimeError: Cannot run the event loop while another loop is running\n> RuntimeError: asyncio.run() cannot be called from a running event loop\n> RuntimeError: This event loop is already running\n```\n\n```py\nimport asyncio\n\nasync def go():\n counter = 0\n while True:\n counter += 1\n print(counter)\n await asyncio.sleep(1)\n\n \ndef run():\n asyncio.run(go())\n```\n\n```py\nfrom fastapi import FastAPI\nimport printing_app\nimport asyncio\nimport uvicorn\n\napp = FastAPI()\n\n\n@app.get('/')\ndef main():\n return 'Hello World!'\n \n\ndef start_uvicorn(loop):\n config = uvicorn.Config(app, loop=loop)\n server = uvicorn.Server(config)\n loop.run_until_complete(server.serve())\n \n\ndef start_printing_app(loop):\n loop.create_task(printing_app.go()) # pass go() (coroutine), not run() \n\n \nif __name__ == '__main__':\n loop = asyncio.new_event_loop()\n asyncio.set_event_loop(loop)\n start_printing_app(loop)\n start_uvicorn(loop)\n```\n\n```py\nfrom fastapi import FastAPI\nfrom contextlib import asynccontextmanager\nimport asyncio\nimport printing_app\nimport uvicorn\n\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI):\n asyncio.create_task(printing_app.go())\n # Alternatively:\n #loop = asyncio.get_running_loop()\n #loop.create_task(printing_app.go())\n yield\n\n\napp = FastAPI(lifespan=lifespan)\n\n\n@app.get('/')\ndef main():\n return 'Hello World!'\n \n\nif __name__ == '__main__':\n uvicorn.run(app)\n```\n\n```py\nfrom fastapi import FastAPI\nimport asyncio\nimport printing_app\nimport uvicorn\n\napp = FastAPI()\n\n\n@app.get('/')\ndef main():\n return 'Hello World!'\n\n \nasync def main():\n # start printing app\n asyncio.create_task(printing_app.go())\n \n # start uvicorn server\n config = uvicorn.Config(app)\n server = uvicorn.Server(config)\n await server.serve()\n \n \nif __name__ == '__main__':\n asyncio.run(main())\n```\n\n```py\nfrom fastapi import FastAPI\nimport asyncio\nimport uvicorn\n\napp = FastAPI()\n\n\n@app.get('/')\ndef main():\n return 'Hello World!'\n \n\nasync def main():\n config = uvicorn.Config(app, host='0.0.0.0', port=8000)\n server = uvicorn.Server(config)\n \n application = .... # initialize your telegram-bot app\n \n # Run application and webserver together\n async with application:\n await application.start()\n await server.serve()\n await application.stop()\n\n\nif __name__ == '__main__':\n asyncio.run(main())\n```\n\n```py\nfrom fastapi import FastAPI\nfrom contextlib import asynccontextmanager\nimport uvicorn\n\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI):\n application = .... # initialize your telegram-bot app\n await application.start()\n yield\n await application.stop()\n\n \napp = FastAPI(lifespan=lifespan)\n\n\n@app.get('/')\ndef main():\n return 'Hello World!'\n\n \nif __name__ == '__main__':\n uvicorn.run(app)\n```\n\n```text\nuvicorn.run()\n```\n\n```text\nasyncio.run()\n```\n\n```text\nuvicorn\n```\n\n```text\nasyncio.run()\n```\n\n```text\nloop.run_until_complete()\n```\n\n```text\nuvicorn.Server.serve()\n```\n\n```text\nuvicorn\n```\n\n```text\nasync\n```\n\n```text\nConfig\n```\n\n```text\nhost\n```\n\n```text\nport\n```\n\n```text\nasyncio.new_event_loop()\n```\n\n```text\nasyncio.set_event_loop()\n```\n\n```text\nloop.create_task()\n```\n\n```text\nasync def\n```\n\n```text\nasyncio.run()\n```\n\n```text\nprinting_app.py\n```\n\n```text\ngo()\n```\n\n```text\nawait\n```\n\n```text\nasync for\n```\n\n```text\nasync with\n```\n\n```text\nawait\n```\n\n```text\nloop.run_until_complete()\n```\n\n```text\nuvicorn.Server.serve()\n```\n\n```text\nloop.run_until_complete()\n```\n\n```text\nTask\n```\n\n```text\nloop.create_task()\n```\n\n```text\nasyncio.new_event_loop()\n```\n\n```text\nasyncio.set_event_loop()\n```\n\n```text\nloop.run_until_complete()\n```\n\n```text\nasyncio.run()\n```\n\n```text\nRunner\n```\n\n```text\nrun()\n```\n\n```text\ncreate_task()\n```\n\n```text\nloop.run_forever()\n```\n\n```text\nstop()\n```\n\n```text\nloop.run_until_complete()\n```\n\n```text\nuvicorn.run(app)\n```\n\n```text\nstartup\n```\n\n```text\nasyncio.create_task()\n```\n\n```text\nasyncio.get_running_loop()\n```\n\n```text\nasyncio.get_running_loop()\n```\n\n```text\ncreate_task()\n```\n\n```text\nasyncio.run()\n```\n\n```text\nasync\n```\n\n```text\nasyncio.create_task()\n```\n\n```text\nawait server.serve()\n```\n\n```text\nCTRL + C\n```\n\n```text\nnest_asyncio\n```\n\n```text\nasyncio\n```\n\n```text\nApplication.run_polling()\n```\n\n```text\nrun_polling()\n```\n\n```text\nrun_polling()\n```\n\n========================================\n\nComments:\n- Have you seen github.com/encode/uvicorn/issues/706 ?\n- Does this answer your question? FastAPI python: How to run a thread in the background?\n- This might also help.\n- Thank you. That is indeed comprehensive answer. Before your answer i came to solution one, but still have struggle with finishing program correctly. Your examples definitely will help me + I have no idea about \"lifespan events\" and i look into that to.","metadata":{"transformedAt":"2026-08-18T18:32:29.107Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":69,"totalLines":606,"estimatedTokens":2774}}175{"id":"stack-61163024","source":"stackoverflow","questionId":61163024,"title":"Return multiple files from fastapi","tags":["python","fastapi","starlette"],"text":"Title: Return multiple files from fastapi\nTags: python, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nUsing fastapi, I can't figure out how to send multiple files as a response. For example, to send a single file, I'll use something like this\n\n```\nfrom fastapi import FastAPI, Response\n\napp = FastAPI()\n\n@app.get(\"/image_from_id/\")\nasync def image_from_id(image_id: int):\n\n # Get image from the database\n img = ...\n return Response(content=img, media_type=\"application/png\")\n```\n\nHowever, I'm not sure what it looks like to send a list of images. Ideally, I'd like to do something like this:\n\n```\n@app.get(\"/images_from_ids/\")\nasync def image_from_id(image_ids: List[int]):\n\n # Get a list of images from the database\n images = ...\n return Response(content=images, media_type=\"multipart/form-data\")\n```\n\nHowever, this returns the error\n\n```\ndef render(self, content: typing.Any) -> bytes:\n if content is None:\n return b\"\"\n if isinstance(content, bytes):\n return content\n> return content.encode(self.charset)\nE AttributeError: 'list' object has no attribute 'encode'\n```\n\n========================================\n\nTop Answer:\nI've got some problems with @kia's answer on Python3 and latest fastapi so here is a fix that I got working it includes BytesIO instead of Stringio, fixes for response attribute and removal of top level archive folder\n\n```\nimport os\nimport zipfile\nimport io\n\ndef zipfiles(filenames):\n zip_filename = \"archive.zip\"\n\n s = io.BytesIO()\n zf = zipfile.ZipFile(s, \"w\")\n\n for fpath in filenames:\n # Calculate path for file in zip\n fdir, fname = os.path.split(fpath)\n\n # Add file, at correct path\n zf.write(fpath, fname)\n\n # Must close zip for all contents to be written\n zf.close()\n\n # Grab ZIP file from in-memory, make response with correct MIME-type\n resp = Response(s.getvalue(), media_type=\"application/x-zip-compressed\", headers={\n 'Content-Disposition': f'attachment;filename={zip_filename}'\n })\n\n return resp\n\n@app.get(\"/image_from_id/\")\nasync def image_from_id(image_id: int):\n\n # Get image from the database\n img = ...\n return zipfiles(img)\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI, Response\n\napp = FastAPI()\n\n@app.get(\"/image_from_id/\")\nasync def image_from_id(image_id: int):\n\n # Get image from the database\n img = ...\n return Response(content=img, media_type=\"application/png\")\n```\n\n```text\n@app.get(\"/images_from_ids/\")\nasync def image_from_id(image_ids: List[int]):\n\n # Get a list of images from the database\n images = ...\n return Response(content=images, media_type=\"multipart/form-data\")\n```\n\n```text\ndef render(self, content: typing.Any) -> bytes:\n if content is None:\n return b\"\"\n if isinstance(content, bytes):\n return content\n> return content.encode(self.charset)\nE AttributeError: 'list' object has no attribute 'encode'\n```\n\n```text\nimport os\nimport zipfile\nimport StringIO\n\n\ndef zipfiles(filenames):\n zip_subdir = \"archive\"\n zip_filename = \"%s.zip\" % zip_subdir\n\n # Open StringIO to grab in-memory ZIP contents\n s = StringIO.StringIO()\n # The zip compressor\n zf = zipfile.ZipFile(s, \"w\")\n\n for fpath in filenames:\n # Calculate path for file in zip\n fdir, fname = os.path.split(fpath)\n zip_path = os.path.join(zip_subdir, fname)\n\n # Add file, at correct path\n zf.write(fpath, zip_path)\n\n # Must close zip for all contents to be written\n zf.close()\n\n # Grab ZIP file from in-memory, make response with correct MIME-type\n resp = Response(s.getvalue(), mimetype = \"application/x-zip-compressed\")\n # ..and correct content-disposition\n resp['Content-Disposition'] = 'attachment; filename=%s' % zip_filename\n\n return resp\n\n\n@app.get(\"/image_from_id/\")\nasync def image_from_id(image_id: int):\n\n # Get image from the database\n img = ...\n return zipfiles(img)\n```\n\n```text\nimport os\nimport zipfile\nimport io\n\n\ndef zipfiles(filenames):\n zip_filename = \"archive.zip\"\n\n s = io.BytesIO()\n zf = zipfile.ZipFile(s, \"w\")\n\n for fpath in filenames:\n # Calculate path for file in zip\n fdir, fname = os.path.split(fpath)\n\n # Add file, at correct path\n zf.write(fpath, fname)\n\n # Must close zip for all contents to be written\n zf.close()\n\n # Grab ZIP file from in-memory, make response with correct MIME-type\n resp = Response(s.getvalue(), media_type=\"application/x-zip-compressed\", headers={\n 'Content-Disposition': f'attachment;filename={zip_filename}'\n })\n\n return resp\n\n@app.get(\"/image_from_id/\")\nasync def image_from_id(image_id: int):\n\n # Get image from the database\n img = ...\n return zipfiles(img)\n```\n\n```text\nimport os\nimport zipfile\nimport io\nfrom fastapi.responses import StreamingResponse\n\nzip_subdir = \"/some_local_path/of_files_to_compress\"\n\ndef zipfile(filenames):\n zip_io = io.BytesIO()\n with zipfile.ZipFile(zip_io, mode='w', compression=zipfile.ZIP_DEFLATED) as temp_zip:\n for fpath in filenames:\n # Calculate path for file in zip\n fdir, fname = os.path.split(fpath)\n zip_path = os.path.join(zip_subdir, fname)\n # Add file, at correct path\n temp_zip.write(fpath, zip_path)\n return StreamingResponse(\n iter([zip_io.getvalue()]), \n media_type=\"application/x-zip-compressed\", \n headers = { \"Content-Disposition\": f\"attachment; filename=images.zip\"}\n )\n```\n\n```text\nStreamingResponse\n```\n\n========================================\n\nComments:\n- Not sure, but if `content` is a type of `List` then loop content: `for c in content: c.encode() ...`\n- @felipsmartins the objects in the list are bytes already, running `img.encode()` on them doesn't work `'bytes' object has no attribute 'encode'`\n- Hi @kia, and thank you for the answer! Stack Overflow discourages single link answers (and it may get downvoted as a result). The answer would be improved if you could provide a small example that shows how to use `aiofiles` in this particular context.\n- Hi @Hooked and @kia, unless I'm missing something, zipping files as in your example is a blocking IO operation that might mess the asynchronous event loop under the hood. Consider either making a synchronous handler (remove the `async` in the definition of `image_for_id`, or consider running the `zipfiles` function under the control of a `TheadPoolExecutor` as in this example : docs.python.org/3/library/…\n- @glenfant Can you please tell me why **\"a blocking IO operation might mess the asynchronous event loop under the hood\"**? thank you.\n- please correct to `temp_zip.write(fpath, zip_path)`\n- also zip_subdir = \"archive\" here","metadata":{"transformedAt":"2026-08-18T18:32:29.107Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":7,"totalLines":236,"estimatedTokens":1675}}176{"id":"stack-66185920","source":"stackoverflow","questionId":66185920,"title":"Pydantic model with field names that have non-alphanumeric characters","tags":["python","json","fastapi","pydantic"],"text":"Title: Pydantic model with field names that have non-alphanumeric characters\nTags: python, json, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI'm using FastAPI and want to build a pydantic model for the following request data json:\n\n```\n{\n \"gas(euro/MWh)\": 13.4,\n \"kerosine(euro/MWh)\": 50.8,\n \"co2(euro/ton)\": 20,\n \"wind(%)\": 60\n }\n```\n\nI defined the model like this:\n\n```\nclass Fuels(BaseModel):\n gas(euro/MWh): float\n kerosine(euro/MWh): float\n co2(euro/ton): int\n wind(%): int\n```\n\nWhich naturally gives a `SyntaxError: invalid syntax` for `wind(%)`.\n\nSo how can I define a pydantic model for a json that has non-alphanumeric characters in its keys?\n\n========================================\n\nCode:\n```json\n{\n \"gas(euro/MWh)\": 13.4,\n \"kerosine(euro/MWh)\": 50.8,\n \"co2(euro/ton)\": 20,\n \"wind(%)\": 60\n }\n```\n\n```py\nclass Fuels(BaseModel):\n gas(euro/MWh): float\n kerosine(euro/MWh): float\n co2(euro/ton): int\n wind(%): int\n```\n\n```text\nSyntaxError: invalid syntax\n```\n\n```text\nwind(%)\n```\n\n```py\nfrom pydantic import BaseModel, Field\n\n\nclass Fuels(BaseModel):\n gas: float = Field(..., alias=\"gas(euro/MWh)\")\n kerosine: float = Field(..., alias=\"kerosine(euro/MWh)\") \n co2: int = Field(..., alias=\"co2(euro/ton)\")\n wind: int = Field(..., alias=\"wind(%)\")\n```\n\n```text\nField\n```\n\n========================================\n\nComments:\n- How can I get class' field name from alias name? Is it possible? gas(euro/MWh) -> gas\n- I am also in a need of something similar. But when i try to use this way, i am getting the issue: ValueError: [TypeError(\"'FieldInfo' object is not iterable\"), TypeError('vars() argument must have **dict** attribute')]","metadata":{"transformedAt":"2026-08-18T18:32:29.107Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":6,"totalLines":78,"estimatedTokens":421}}177{"id":"stack-77935269","source":"stackoverflow","questionId":77935269,"title":"Performance results differ between run_in_threadpool() and run_in_executor() in FastAPI","tags":["python","python-asyncio","fastapi","starlette","apachebench"],"text":"Title: Performance results differ between run_in_threadpool() and run_in_executor() in FastAPI\nTags: python, python-asyncio, fastapi, starlette, apachebench\nSource: Stack Overflow\n\nQuestion:\nHere's a minimal reproducible example of my FastAPI app. I have a strange behavior and I'm not sure I understand the reason.\n\nI'm using ApacheBench (`ab`) to send multiple requests as follows:\n\n```\nab -n 1000 -c 50 -H 'accept: application/json' -H 'x-data-origin: source' 'http://localhost:8001/test/async'\n```\n\n**FastAPI app**\n\n```\nimport time\nimport asyncio\nimport enum\nfrom typing import Any\n\nfrom fastapi import FastAPI, Path, Body\nfrom starlette.concurrency import run_in_threadpool\n\napp = FastAPI()\nloop = asyncio.get_running_loop()\ndef sync_func() -> None:\n time.sleep(3)\n print(\"sync func\")\n\nasync def sync_async_with_fastapi_thread() -> None:\n await run_in_threadpool( time.sleep, 3)\n print(\"sync async with fastapi thread\")\n\nasync def sync_async_func() -> None:\n await loop.run_in_executor(None, time.sleep, 3)\n\nasync def async_func() -> Any:\n await asyncio.sleep(3)\n print(\"async func\")\n\n@app.get(\"/test/sync\")\ndef test_sync() -> None:\n sync_func()\n print(\"sync\")\n\n@app.get(\"/test/async\")\nasync def test_async() -> None:\n await async_func()\n print(\"async\")\n\n@app.get(\"/test/sync_async\")\nasync def test_sync_async() -> None:\n await sync_async_func()\n print(\"sync async\")\n\n@app.get(\"/test/sync_async_fastapi\")\nasync def test_sync_async_with_fastapi_thread() -> None:\n await sync_async_with_fastapi_thread()\n print(\"sync async with fastapi thread\")\n```\n\nHere's the ApacheBench results:\n\n**async with (asyncio.sleep)** :\n*Concurrency Level: 50\n\n- Time taken for tests: 63.528 seconds\n\n- Complete requests: 1000\n\n- Failed requests: 0\n\n- Total transferred: 128000 bytes\n\n- HTML transferred: 4000 bytes\n\n- Requests per second: 15.74 [#/sec] (mean)\n\n- **Time per request: 3176.407 [ms] (mean)**\nTime per request: 63.528 [ms] (mean, across all concurrent requests)\nTransfer rate: 1.97 [Kbytes/sec] received*\n\n**sync (with time.sleep):**\nConcurrency Level: 50\n\n- *Time taken for tests: 78.615 seconds\n\n- Complete requests: 1000\n\n- Failed requests: 0\n\n- Total transferred: 128000 bytes\n\n- HTML transferred: 4000 bytes\n\n- Requests per second: 12.72 [#/sec] (mean)\n\n- **Time per request: 3930.751 [ms] (mean)**\nTime per request: 78.615 [ms] (mean, across all concurrent requests)\nTransfer rate: 1.59 [Kbytes/sec] received*\n\n**sync_async (time sleep with run_in_executor) :** *Concurrency Level: 50\n\n- Time taken for tests: 256.201 seconds\n\n- Complete requests: 1000\n\n- Failed requests: 0\n\n- Total transferred: 128000 bytes\n\n- HTML transferred: 4000 bytes\n\n- Requests per second: 3.90 [#/sec] (mean)\n\n- **Time per request: 12810.038 [ms] (mean)**\nTime per request: 256.201 [ms] (mean, across all concurrent requests)\nTransfer rate: 0.49 [Kbytes/sec] received*\n\n**sync_async_fastapi (time sleep with run_in threadpool):**\n*Concurrency Level: 50\n\n- Time taken for tests: 78.877 seconds\n\n- Complete requests: 1000\n\n- Failed requests: 0\n\n- Total transferred: 128000 bytes\n\n- HTML transferred: 4000 bytes\n\n- Requests per second: 12.68 [#/sec] (mean)\n\n- **Time per request: 3943.841 [ms] (mean)**\nTime per request: 78.877 [ms] (mean, across all concurrent requests)\nTransfer rate: 1.58 [Kbytes/sec] received*\n\nIn conclusion, I'm experiencing a surprising disparity in results; especially, when using `run_in_executor`, where I'm encountering significantly higher average times (12 seconds). I don't understand this outcome.\n\n--- EDIT ---\n**After AKX answer.**\n\n```\nHere the code working as expected: \nimport time\nimport asyncio\nfrom anyio import to_thread\n\nto_thread.current_default_thread_limiter().total_tokens = 200\nloop = asyncio.get_running_loop()\nexecutor = ThreadPoolExecutor(max_workers=100)\ndef sync_func() -> None:\n time.sleep(3)\n print(\"sync func\")\n\nasync def sync_async_with_fastapi_thread() -> None:\n await run_in_threadpool( time.sleep, 3)\n print(\"sync async with fastapi thread\")\n\nasync def sync_async_func() -> None:\n await loop.run_in_executor(executor, time.sleep, 3)\n\nasync def async_func() -> Any:\n await asyncio.sleep(3)\n print(\"async func\")\n\n@app.get(\"/test/sync\")\ndef test_sync() -> None:\n sync_func()\n print(\"sync\")\n\n@app.get(\"/test/async\")\nasync def test_async() -> None:\n await async_func()\n print(\"async\")\n\n@app.get(\"/test/sync_async\")\nasync def test_sync_async() -> None:\n await sync_async_func()\n print(\"sync async\")\n\n@app.get(\"/test/sync_async_fastapi\")\nasync def test_sync_async_with_fastapi_thread() -> None:\n await sync_async_with_fastapi_thread()\n print(\"sync async with fastapi thread\")\n```\n\n========================================\n\nTop Answer:\n`starlette.concurrency.run_in_threadpool` uses `anyio.to_thread.run_sync()` under the hood.\n\nBy default, the concurrency there is limited to 40, so 50 concurrent requests will starve the threadpool; you can increase that limit with\n\n```\nfrom anyio import to_thread\n\nto_thread.current_default_thread_limiter().total_tokens = 200\n```\n\nSimilarly, `run_in_executor` uses a default `ThreadPoolExecutor` if you don't pass in one; the default worker count for the default executor is `min(32, os.cpu_count() + 4)`, so depending on your configuration, that too may be way too little.\n\n========================================\n\nCode:\n```text\nab -n 1000 -c 50 -H 'accept: application/json' -H 'x-data-origin: source' 'http://localhost:8001/test/async'\n```\n\n```text\nimport time\nimport asyncio\nimport enum\nfrom typing import Any\n\nfrom fastapi import FastAPI, Path, Body\nfrom starlette.concurrency import run_in_threadpool\n\napp = FastAPI()\nloop = asyncio.get_running_loop()\ndef sync_func() -> None:\n time.sleep(3)\n print(\"sync func\")\n\nasync def sync_async_with_fastapi_thread() -> None:\n await run_in_threadpool( time.sleep, 3)\n print(\"sync async with fastapi thread\")\n\nasync def sync_async_func() -> None:\n await loop.run_in_executor(None, time.sleep, 3)\n\nasync def async_func() -> Any:\n await asyncio.sleep(3)\n print(\"async func\")\n\n@app.get(\"/test/sync\")\ndef test_sync() -> None:\n sync_func()\n print(\"sync\")\n\n@app.get(\"/test/async\")\nasync def test_async() -> None:\n await async_func()\n print(\"async\")\n\n@app.get(\"/test/sync_async\")\nasync def test_sync_async() -> None:\n await sync_async_func()\n print(\"sync async\")\n\n@app.get(\"/test/sync_async_fastapi\")\nasync def test_sync_async_with_fastapi_thread() -> None:\n await sync_async_with_fastapi_thread()\n print(\"sync async with fastapi thread\")\n```\n\n```text\nHere the code working as expected: \nimport time\nimport asyncio\nfrom anyio import to_thread\n\nto_thread.current_default_thread_limiter().total_tokens = 200\nloop = asyncio.get_running_loop()\nexecutor = ThreadPoolExecutor(max_workers=100)\ndef sync_func() -> None:\n time.sleep(3)\n print(\"sync func\")\n\nasync def sync_async_with_fastapi_thread() -> None:\n await run_in_threadpool( time.sleep, 3)\n print(\"sync async with fastapi thread\")\n\nasync def sync_async_func() -> None:\n await loop.run_in_executor(executor, time.sleep, 3)\n\nasync def async_func() -> Any:\n await asyncio.sleep(3)\n print(\"async func\")\n\n@app.get(\"/test/sync\")\ndef test_sync() -> None:\n sync_func()\n print(\"sync\")\n\n@app.get(\"/test/async\")\nasync def test_async() -> None:\n await async_func()\n print(\"async\")\n\n@app.get(\"/test/sync_async\")\nasync def test_sync_async() -> None:\n await sync_async_func()\n print(\"sync async\")\n\n@app.get(\"/test/sync_async_fastapi\")\nasync def test_sync_async_with_fastapi_thread() -> None:\n await sync_async_with_fastapi_thread()\n print(\"sync async with fastapi thread\")\n```\n\n```text\nab\n```\n\n```text\nrun_in_executor\n```\n\n```py\nasync def run_in_threadpool(\n func: typing.Callable[P, T], *args: P.args, **kwargs: P.kwargs\n) -> T:\n if kwargs: # pragma: no cover\n # run_sync doesn't accept 'kwargs', so bind them in here\n func = functools.partial(func, **kwargs)\n return await anyio.to_thread.run_sync(func, *args)\n```\n\n```text\nfrom anyio import to_thread\n\nasync def foo():\n # Set the maximum number of worker threads to 60\n to_thread.current_default_thread_limiter().total_tokens = 60\n```\n\n```py\nfrom anyio.lowlevel import RunVar\nfrom anyio import CapacityLimiter\n\nRunVar(\"_default_thread_limiter\").set(CapacityLimiter(60))\n```\n\n```py\nfrom fastapi import FastAPI\nfrom contextlib import asynccontextmanager\nfrom anyio import to_thread\nimport time\n\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI): \n to_thread.current_default_thread_limiter().total_tokens = 60\n yield\n\n\napp = FastAPI(lifespan=lifespan)\n\n\n@app.get(\"/sync\")\ndef test_sync() -> None:\n time.sleep(3)\n print(\"sync\")\n\n\n@app.get('/get_available_threads')\nasync def get_available_threads():\n return to_thread.current_default_thread_limiter().available_tokens\n```\n\n```text\nab -n 1000 -c 50 \"http://localhost:8000/sync\"\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.concurrency import run_in_threadpool\nfrom contextlib import asynccontextmanager\nfrom anyio import to_thread\nimport time\n\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI): \n to_thread.current_default_thread_limiter().total_tokens = 60\n yield\n\n\napp = FastAPI(lifespan=lifespan)\n\n\n@app.get(\"/sync_async_run_in_tp\")\nasync def test_sync_async_with_run_in_threadpool() -> None:\n await run_in_threadpool(time.sleep, 3)\n print(\"sync_async using FastAPI's run_in_threadpool\")\n\n\n@app.get('/get_available_threads')\nasync def get_available_threads():\n return to_thread.current_default_thread_limiter().available_tokens\n```\n\n```text\nab -n 1000 -c 50 \"http://localhost:8000/sync_async_run_in_tp\"\n```\n\n```py\nimport concurrent.futures\n\n# create a thread pool with the default number of worker threads\npool = concurrent.futures.ThreadPoolExecutor()\n\n# report the number of worker threads chosen by default\n# Note: `_max_workers` is a protected variable and may change in the future\nprint(pool._max_workers)\n```\n\n```py\nimport concurrent.futures\nimport asyncio\n\nloop = asyncio.get_running_loop()\nwith concurrent.futures.ThreadPoolExecutor(max_workers=1) as pool:\n await loop.run_in_executor(pool, time.sleep, 3)\n```\n\n```py\nfrom fastapi import FastAPI, Request\nfrom contextlib import asynccontextmanager\nimport concurrent.futures\nimport threading\nimport asyncio\nimport time\n\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI): \n pool = concurrent.futures.ThreadPoolExecutor(max_workers=60)\n yield {'pool': pool}\n pool.shutdown()\n\n\napp = FastAPI(lifespan=lifespan)\n\n\n@app.get(\"/sync_async\")\nasync def test_sync_async(request: Request) -> None:\n loop = asyncio.get_running_loop()\n await loop.run_in_executor(request.state.pool, time.sleep, 3) \n print(\"sync_async\")\n\n\n@app.get('/get_active_threads')\nasync def get_active_threads():\n return threading.active_count()\n```\n\n```text\nab -n 1000 -c 50 \"http://localhost:8000/sync_async\"\n```\n\n```text\nrun_in_threadpool()\n```\n\n```text\nrun_in_threadpool()\n```\n\n```text\nrun_in_threadpool()\n```\n\n```text\nanyio.to_thread.run_sync()\n```\n\n```text\nrun_in_threadpool()\n```\n\n```text\nanyio.to_thread.run_sync()\n```\n\n```text\nAsyncIOBackend.run_sync_in_worker_thread()\n```\n\n```text\nawait\n```\n\n```text\nresult = await run_in_threadpool(...)\n```\n\n```text\nrun_in_threadpool()\n```\n\n```text\n40\n```\n\n```text\nto_thread.run_sync()\n```\n\n```text\nlimiter\n```\n\n```text\n40\n```\n\n```text\nasyncio\n```\n\n```text\nconcurrency\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\n40\n```\n\n```text\nAsyncIOBackend.current_default_thread_limiter()\n```\n\n```text\nCapacityLimiter\n```\n\n```text\n50\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\nrun_in_threadpool()\n```\n\n```text\ndef\n```\n\n```text\nStreamingResponse\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\nUploadFile\n```\n\n```text\nasync\n```\n\n```text\nawait file.read()\n```\n\n```text\nawait file.close()\n```\n\n```text\ndef\n```\n\n```text\nrun_in_threadpool()\n```\n\n```text\nlifespan\n```\n\n```text\n/sync\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\nawait\n```\n\n```text\n1000\n```\n\n```text\n50\n```\n\n```text\n-n\n```\n\n```text\n-c\n```\n\n```text\n/get_available_threads\n```\n\n```text\nhttp://localhost:8000/get_available_threads\n```\n\n```text\n60\n```\n\n```text\n200\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\nrun_in_threadpool()\n```\n\n```text\ndef\n```\n\n```text\ndef\n```\n\n```text\nawait\n```\n\n```text\nasync def\n```\n\n```text\nrun_in_threadpool()\n```\n\n```text\nawait\n```\n\n```text\ntime.sleep()\n```\n\n```text\nloop.run_in_executor()\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nasyncio\n```\n\n```text\nloop.run_in_executor()\n```\n\n```text\nasyncio.get_running_loop()\n```\n\n```text\nNone\n```\n\n```text\nexecutor\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nloop.run_in_executor()\n```\n\n```text\nNone\n```\n\n```text\nexecutor\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nawait loop.run_in_executor(None, time.sleep, 3)\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nloop.run_in_executor()\n```\n\n```text\nexecutor\n```\n\n```text\nNone\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nloop.run_in_executor()\n```\n\n```text\nawait loop.run_in_executor(None, ...)\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nmax_workers\n```\n\n```text\nNone\n```\n\n```text\nmin(32, os.cpu_count() + 4)\n```\n\n```text\nmin(32, (os.process_cpu_count() or 1) + 4)\n```\n\n```text\nos.cpu_count()\n```\n\n```text\nos.process_cpu_count()\n```\n\n```text\nmax_workers\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nawait loop.run_in_executor(None, time.sleep, 3)\n```\n\n```text\nsync_async_func()\n```\n\n```text\n/test/sync_async\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\n/test/sync_async\n```\n\n```text\nawait loop.run_in_executor(None, time.sleep, 3)\n```\n\n```text\nrun_in_threadpool()\n```\n\n```text\n40\n```\n\n```text\n50\n```\n\n```text\nrun_in_threadpool()\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nwith\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nProcessPoolExecutor\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\n/get_active_threads\n```\n\n```text\nhttp://localhost:8000/get_active_threads\n```\n\n```text\n50\n```\n\n```text\n51\n```\n\n```text\nmax_workers\n```\n\n```text\n60\n```\n\n```text\n50\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nmax_workers=100\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nasync\n```\n\n```text\nawait\n```\n\n```text\nasync\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\nrun_in_threadpool()\n```\n\n```text\nawait\n```\n\n```text\nasync def\n```\n\n```text\nasyncio\n```\n\n```text\nloop.run_in_executor()\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nawait\n```\n\n```text\nloop.run_in_executor()\n```\n\n```text\nProcessPoolExecutor\n```\n\n```text\nif __name__ == '__main__'\n```\n\n```text\nBackgroundTasks\n```\n\n```text\nasync def\n```\n\n```text\ndef\n```\n\n```text\nrun_in_threadpool()\n```\n\n```text\nawait\n```\n\n```text\nasync def\n```\n\n```text\nBackgroundTasks\n```\n\n```text\nasyncio.create_task()\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nAsyncIO\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nfrom anyio import to_thread\n\nto_thread.current_default_thread_limiter().total_tokens = 200\n```\n\n```text\nstarlette.concurrency.run_in_threadpool\n```\n\n```text\nanyio.to_thread.run_sync()\n```\n\n```text\nrun_in_executor\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nmin(32, os.cpu_count() + 4)\n```\n\n```py\nfrom fastapi import FastAPI\nfrom anyio.to_thread import get_asynclib\n\napp = FastAPI()\n@app.on_event(\"startup\")\ndef startup():\n print(\"starting app ... \")\n get_asynclib().current_default_thread_limiter().total_tokens = 100\n print('default _default_thread_limiter', get_asynclib().current_default_thread_limiter().total_tokens)\n```\n\n```text\nfrom starlette.concurrency import run_in_threadpool\n\n@app.post(\"/blocking\")\nasync def create_flow():\n await run_in_threadpool(sub_task, t=100)\n\ndef sub_task(t=1):\n import subprocess\n cmd = f'echo sleeping...; sleep {t}'\n stdout, stderr = subprocess.Popen(cmd, shell=True).communicate()\n```\n\n```text\n# start the web app\nstarting app ... \ndefault _default_thread_limiter 3\n# start call use `cURL`.\ncall sync ..\nsleeping ...\ncall sync ..\nsleeping ...\ncall sync ..\nsleeping ...\n# The first three execute normally, the rest are suspended\ncall sync ..\ncall sync ..\n# Exceed concurrency limit(5) for `uvicorn`.\nExceeded concurrency limit.\nExceeded concurrency limit.\n...\n```\n\n```text\n--limit-concurrency 100\n```\n\n```text\nuvicorn\n```\n\n```text\ndefault_thread_limiter.total_tokens\n```\n\n```text\nrun_in_threadpool\n```\n\n```text\nrun_in_threadpool(func, *args, limiter=get_asynclib().CapacityLimiter(10))\n```\n\n```text\n--limit-concurrency\n```\n\n```text\n5\n```\n\n```text\ndefault_thread_limiter.total_tokens\n```\n\n```text\n6\n```\n\n========================================\n\nComments:\n- Great! Indeed, that's it. Thank you very much. However, I have (two)questions about the basic setup for FastAPI, and how it handles asynchronous requests by default. Also, in the context of an application (running on cloud run) where I'll be using run_executor or run_in_threadpool specifically for API calls (like Google) that don't inherently support async, how do I evaluate the maximum number of workers for ThreadpoolExecutor and the maximum concurrency for run_in_threadpool?\n- There's no simple answer to \"maximum number of workers\" – if you have 4 cores, each workers gets allocated to a core and all of your workers happen to be using 100% of that core all the time, your machine is already starved. However, that's not generally the case.\n- One thing seems surprising to me. Why do I not get the same result between the /async route and run_in_threadpool without changing the thread limiter? FastAPI uses Starlette; shouldn't we expect the same result?\n- This morning, I conducted some tests regarding background tasks and observed the results I obtained. I performed two simple tests: one involving a synchronous route with an asynchronous background task, and the other involving a synchronous route with a synchronous background task. The first result for 500 requests averaged 3.3 seconds, while the result for the synchronous route with the synchronous task averaged 5.8 seconds. Does that seem coherent to you? A synchronous task means that the function invoked by the task is either synchronous using time.sleep or asynchronous using asyncio.sleep.\n- Despite the last statement in your comment, it does. This is because a background task has nothing to do with the endpoint itself. Please have a look at a recent comment on a related question.\n- There is probably an element that I didn't understand in the comment you linked me. I understood that the background task has nothing to do with the endpoint, and that in this case, FastAPI will handle both the background task and the endpoint in the same way regarding async def and def. Therefore, I should have the same result.\n- The `async def` background task, in your former test, will run directly in the event loop, while the `def` background task, in your latter test, will run in a separate thread from the external threadpool (which will then be `await`ed).\n- @Chris: your answers on fastapi are one of the best resources out there, this has been a huge help to my co-founder and I. I wish I could find a way to thank you, keep up the great work on stackoverflow!","metadata":{"transformedAt":"2026-08-18T18:32:29.107Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":182,"totalLines":1164,"estimatedTokens":4833}}178{"id":"stack-70874423","source":"stackoverflow","questionId":70874423,"title":"FastAPI: \" ImportError: attempted relative import with no known parent package\"","tags":["python","python-3.x","swagger-ui","fastapi"],"text":"Title: FastAPI: \" ImportError: attempted relative import with no known parent package\"\nTags: python, python-3.x, swagger-ui, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am new to FastAPI and I've been having this problem with importing my other files.\n\nI get the error:\n\n```\nfrom . import schemas\nImportError: attempted relative import with no known parent package\n```\n\nFor context, the file I am importing from is a Folder called Blog. I saw certain StackOverflow answers saying that instead of `from . import schemas` I should write `from Blog import schemas`. And even though their solution is right and I don't get any errors while running the python program, When I try running FastAPI using uvicorn, I get this error and my localhost page doesn't load.\n\n```\nFile \"./main.py\", line 2, in \nfrom Blog import schemas\nModuleNotFoundError: No module named 'Blog'\n```\n\nThe file structure looks like this:\nhttps://i.sstatic.net/I640A.png\n\nThe code to the main file looks like this:\n\n```\nfrom fastapi import FastAPI\nfrom Blog import schemas, models\nfrom database import engine\n\napp = FastAPI()\n\nmodels.Base.metadata.create_all(engine)\n\n@app.post('/blog')\ndef create(request: schemas.Blog):\n return request\n```\n\nschemas.py\n\n```\nfrom pydantic import BaseModel\n\nclass Blog(BaseModel):\n title: str\n body: str\n```\n\ndatabase.py\n\n```\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import sessionmaker\n\nSQLALCHAMY_DATABASE_URL = 'sqlite:///./blog.db'\n\nengine = create_engine(SQLALCHAMY_DATABASE_URL, connect_args={\"check_same_thread\": False})\n\nSessionLocal = sessionmaker(bind=engine, autocommit=False, autoflush=False)\n\nBase = declarative_base()\n```\n\nmodels.py\n\n```\nfrom sqlalchemy import *\nfrom database import Base\n\nclass Blog(Base):\n __tablename__ = 'blogs'\n id = Column(Integer, primary_key=True, index=True)\n title = Column(String)\n body = Column(String)\n```\n\nThe SwaggerUI is not loading either.\n\nAny help would be greatly appreciated! :)\n\n========================================\n\nTop Answer:\nYou can also run your app from the folder above. For example if you use uvicorn, you can do\n\n```\nuvicorn folder.main:app --reload\n```\n\ninstead of\n\n```\nuvicorn main:app --reload\n```\n\nthen you can keep the dot.\n\n========================================\n\nCode:\n```py\nfrom . import schemas\nImportError: attempted relative import with no known parent package\n```\n\n```text\nFile \"./main.py\", line 2, in <module>\nfrom Blog import schemas\nModuleNotFoundError: No module named 'Blog'\n```\n\n```text\nfrom fastapi import FastAPI\nfrom Blog import schemas, models\nfrom database import engine\n\napp = FastAPI()\n\nmodels.Base.metadata.create_all(engine)\n\n\n@app.post('/blog')\ndef create(request: schemas.Blog):\n return request\n```\n\n```text\nfrom pydantic import BaseModel\n\n\nclass Blog(BaseModel):\n title: str\n body: str\n```\n\n```text\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import sessionmaker\n\nSQLALCHAMY_DATABASE_URL = 'sqlite:///./blog.db'\n\nengine = create_engine(SQLALCHAMY_DATABASE_URL, connect_args={\"check_same_thread\": False})\n\nSessionLocal = sessionmaker(bind=engine, autocommit=False, autoflush=False)\n\nBase = declarative_base()\n```\n\n```text\nfrom sqlalchemy import *\nfrom database import Base\n\n\nclass Blog(Base):\n __tablename__ = 'blogs'\n id = Column(Integer, primary_key=True, index=True)\n title = Column(String)\n body = Column(String)\n```\n\n```text\nfrom . import schemas\n```\n\n```text\nfrom Blog import schemas\n```\n\n```py\nimport schemas, models\n```\n\n```text\nschemas.py\n```\n\n```text\nmodels.py\n```\n\n```text\nmain.py\n```\n\n```text\nfrom Blog import schemas, models\n```\n\n```text\nfrom models import User\n## instead of \n# from .models import User\n```\n\n```text\nuvicorn folder.main:app --reload\n```\n\n```text\nuvicorn main:app --reload\n```\n\n```text\nuvicorn\n```\n\n```text\nmain.py\n```\n\n```text\nmain.py\n```\n\n```text\nuvicorn parent_folder.child_folder.main:app --reload\n```\n\n```text\nuvicorn Blog.main:app --reload\n```\n\n========================================\n\nComments:\n- Hi Chris, I've already done all of those as mentioned above. I am still getting the same error **ModuleNotFoundError: No module named 'Blog'**\n- @Chris I've edited my question and posted all the code along with the file structure there.\n- Why would he run `[...] main:app`?? The syntax of FastAPI is the same has importing in a regular Python module. \"from main import app\" is equal to this part \" main:app \". So what you 're stating would only work if he had a module named \"app\" and the FastApi object is main. fastapi.tiangolo.com/deployment/manually\n- because this is the syntax for running uvicorn from the command line? not sure I understand what you mean. This is shown even in the website you link\n- The first part of my comment was supposed to say \"why would he run `[...] app:main` \". Look at the syntax you have suggested. It is incorrect. OP has a module \"main.py\" which contins the variable \"app\". Your suggestion is proposing he has a module \"app.py\" with the variable \"main\"\n- oh you're right, sharp eye, I'll edit the answer.","metadata":{"transformedAt":"2026-08-18T18:32:29.107Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":21,"totalLines":236,"estimatedTokens":1284}}179{"id":"stack-75998227","source":"stackoverflow","questionId":75998227,"title":"How to define query parameters using Pydantic model in FastAPI?","tags":["python","fastapi","openapi","pydantic"],"text":"Title: How to define query parameters using Pydantic model in FastAPI?\nTags: python, fastapi, openapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI am trying to have an endpoint like `/services?status=New`\n\n`status` is going to be either `New` or `Old`\n\nHere is my code:\n\n```\nfrom fastapi import APIRouter, Depends\nfrom pydantic import BaseModel\nfrom enum import Enum\n\nrouter = APIRouter()\n\nclass ServiceStatusEnum(str, Enum):\n new = \"New\"\n old = \"Old\"\n\nclass ServiceStatusQueryParam(BaseModel):\n status: ServiceStatusEnum\n\n@router.get(\"/services\")\ndef get_services(\n status: ServiceStatusQueryParam = Query(..., title=\"Services\", description=\"my desc\"),\n):\n pass #my code for handling this route.....\n```\n\nThe result is that I get an error that seems to be relevant to this issue here\n\nThe error says `AssertionError: Param: status can only be a request body, using Body()`\n\nThen I found another solution explained here.\n\nSo, my code will be like this:\n\n```\nfrom fastapi import APIRouter, Depends\nfrom pydantic import BaseModel\nfrom enum import Enum\n\nrouter = APIRouter()\n\nclass ServiceStatusEnum(str, Enum):\n new = \"New\"\n old = \"Old\"\n\nclass ServicesQueryParam(BaseModel):\n status: ServiceStatusEnum\n\n@router.get(\"/services\")\ndef get_services(\n q: ServicesQueryParam = Depends(),\n):\n pass #my code for handling this route.....\n```\n\nIt is working (and I don't understand why) - but the question is how and where do I add the description and title?\n\n========================================\n\nCode:\n```py\nfrom fastapi import APIRouter, Depends\nfrom pydantic import BaseModel\nfrom enum import Enum\n\nrouter = APIRouter()\n\nclass ServiceStatusEnum(str, Enum):\n new = \"New\"\n old = \"Old\"\n\n\nclass ServiceStatusQueryParam(BaseModel):\n status: ServiceStatusEnum\n\n\n@router.get(\"/services\")\ndef get_services(\n status: ServiceStatusQueryParam = Query(..., title=\"Services\", description=\"my desc\"),\n):\n pass #my code for handling this route.....\n```\n\n```py\nfrom fastapi import APIRouter, Depends\nfrom pydantic import BaseModel\nfrom enum import Enum\n\nrouter = APIRouter()\n\nclass ServiceStatusEnum(str, Enum):\n new = \"New\"\n old = \"Old\"\n\n\nclass ServicesQueryParam(BaseModel):\n status: ServiceStatusEnum\n\n\n@router.get(\"/services\")\ndef get_services(\n q: ServicesQueryParam = Depends(),\n):\n pass #my code for handling this route.....\n```\n\n```text\n/services?status=New\n```\n\n```text\nstatus\n```\n\n```text\nNew\n```\n\n```text\nOld\n```\n\n```text\nAssertionError: Param: status can only be a request body, using Body()\n```\n\n```py\nfrom fastapi import FastAPI, Depends, Query, HTTPException\nfrom pydantic import BaseModel, Field, validator\nfrom typing import List, Optional, Literal\nfrom enum import Enum\n\napp = FastAPI()\n\nclass Status(str, Enum):\n new = 'New'\n old = 'Old'\n\n\nclass ServiceStatus(BaseModel):\n status: Optional[Status] = Field (Query(None, description='Select service status'))\n msg: Optional[str] = Field (Query(None, description='Type something'))\n choice: Literal['a', 'b', 'c', 'd'] = Field (Query(..., description='Choose something'))\n comments: List[str] = Field (Query(..., description='Add some comments'))\n \n @validator('choice')\n def check_choice(cls, v):\n if v == 'b': \n raise HTTPException(status_code=422, detail='Wrong choice')\n return v\n\n@app.get('/status')\ndef main(status: ServiceStatus = Depends()):\n return status\n```\n\n```py\nfrom typing import Annotated, Literal\nfrom fastapi import FastAPI, Query\nfrom pydantic import BaseModel, Field\n\napp = FastAPI()\n\n\nclass FilterParams(BaseModel):\n limit: int = Field(100, gt=0, le=100)\n offset: int = Field(0, ge=0)\n order_by: Literal[\"created_at\", \"updated_at\"] = \"created_at\"\n tags: list[str] = []\n\n\n@app.get(\"/items\")\nasync def read_items(filter_query: Annotated[FilterParams, Query()]):\n return filter_query\n```\n\n```text\nDepends()\n```\n\n```text\ndescription\n```\n\n```text\ntitle\n```\n\n```text\nQuery()\n```\n\n```text\nField()\n```\n\n```text\nLiteral\n```\n\n```text\nEnum\n```\n\n```text\nList\n```\n\n```text\nQuery()\n```\n\n```text\nField()\n```\n\n```text\n@validator\n```\n\n```text\nBaseModel\n```\n\n```text\nValueError\n```\n\n```text\nInternal Server Error\n```\n\n```text\nHTTPException\n```\n\n```text\nValueError\n```\n\n```text\n@validator\n```\n\n```text\nQuery\n```\n\n```text\nQuery\n```\n\n```text\nOptional\n```\n\n```text\nNone\n```\n\n```text\nQuery\n```\n\n```text\ntyping\n```\n\n```text\n@validator\n```\n\n```text\n@validator\n```\n\n```text\n@field_validator\n```\n\n```text\nQuery\n```\n\n```text\nQuery\n```\n\n```text\nHeader\n```\n\n```text\nCookie\n```\n\n========================================\n\nComments:\n- I don't understand the purpose of `ServiceStatusQueryParam`. Why not just annotate the `status` parameter of your route directly with `ServiceStatusEnum`. That will work. Do you *really* need an entire JSON object in a URL query parameter? Seems super cringe to me.\n- I dont clearly understand the difference bc I am new to fastapi but you seem right. I tested and it is working\n- The way you had it in your first code snippet, the URL query parameter would *theoretically* have to be `?status={\"status\":\"New\"}` or something to that effect because you set the type of the `status` query parameter to be your `ServiceStatusQueryParam` model, which in turn serializes to a JSON object. Whereas you just want your query to be `?status=New`, so essentially of type string, but constrained to the enum members.\n- what if I wanted to do some validation on the string? how would I do this?\n- for example, now that you provided this example, I am wondering if I should include `Path` and `Body` in the `ServiceStatus` class as well or not\n- if we had `services/{service_id}`, would you add `service_id: str = Field (Path(..., description=''))` under`class ServiceStatus(BaseModel)` as well or not?\n- Please have a look at this answer, as well as this answer and this answer (you may also find this helpful as well). Please make sure to read the linked answers above, as well as any references included, thoroughly.\n- What if I wanted to make the status choices case-insensitive?\n- To future readers: To make `enum` values case insensitive, please have a look at this answer\n- Omg this has wasted so much of my time... Thought it was a much more complicated bug and couldn't figure it out. Thanks for posting this!\n- Note that when using that method the descriptions don't show up in the OpenAPI docs. (Unless I did it wrong?)","metadata":{"transformedAt":"2026-08-18T18:32:29.107Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":39,"totalLines":316,"estimatedTokens":1597}}180{"id":"stack-70802407","source":"stackoverflow","questionId":70802407,"title":"How to make FastAPI server available from outside local network?","tags":["network-programming","fastapi"],"text":"Title: How to make FastAPI server available from outside local network?\nTags: network-programming, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm developing a small API using FastAPI for the first time.\nI'm using `uvicorn` to run the app.\n\nWhen I use:\n\n```\n$ uvicorn main:app --host 0.0.0.0\n```\n\nI can access the app from inside my network (by using my public IP), but not from the outside. I've already checked the firewall, and even tried fully disabling it, however, without any effect. I just want to be able to showcase the app to outside people. How can I make that happen ?\n\n========================================\n\nTop Answer:\nCreate inbound rule from windows defender firewall for the port you are using in FastAPI.\n\n========================================\n\nCode:\n```bash\n$ uvicorn main:app --host 0.0.0.0\n```\n\n```text\nuvicorn\n```\n\n========================================\n\nComments:\n- You may find this answer and this answer helpful\n- Which would you recommend ? Is there a particular reason why I can't get it to work with the standard `uvicorn` ?\n- I have used only ngrok, but I figure expose is similar. As for a particular reason why: what you want to do is technically possible, sure, but it's just not a best practice and you probably have something on your network setup preventing you from it. Anyway, it's not a good idea to change your firewall and network configuration creating a security breach, just for something you want to do temporarily to showcase your app.\n- As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.","metadata":{"transformedAt":"2026-08-18T18:32:29.107Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":2,"totalLines":39,"estimatedTokens":433}}181{"id":"stack-71146740","source":"stackoverflow","questionId":71146740,"title":"FastAPI create auth for all endpoints","tags":["python","fastapi"],"text":"Title: FastAPI create auth for all endpoints\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI followed this documentation to setup up a single user:\nhttps://fastapi.tiangolo.com/advanced/security/http-basic-auth/\n\nBut I only get prompted for user/pass for that one end point, \"/users/me\".\n\nHow do I ensure that all endpoints are behind auth?\n\n========================================\n\nCode:\n```text\nsecurity = HTTPBasic()\n\napp = FastAPI(dependencies=[Depends(security)])\n```\n\n```text\nunauthenticated_router = APIRouter()\nauthenticated_router = APIRouter(dependencies=[Depends(security)])\n```\n\n```text\nAPIRouter\n```\n\n```text\n.include_router\n```\n\n```text\napp\n```\n\n========================================\n\nComments:\n- How does it know what credentials should be used?\n- You handle that yourself in the method you've added your security dependency to. In the example given in fastapi.tiangolo.com/advanced/security/http-basic-auth - this is the `HTTPBasicCredentials` object these days. This example only shows how to use the dependency across all nodes, in reality you'd make your own function that depends on this dependency and then verify the username/password there.\n- I have created a function `def authenticate(cred: HTTPBasicCredentials = Depends(security))` which checks if username and passwords are correct, but this function gets triggered only when I trigger endpoint. My endpoint looks like this now: `def get_status(authenticated: bool = Depends(authenticate)):`. This requires me to add `authenticated: bool = Depends(authenticate)` parameter to every endpoint, is there a way so I wouldn't need to do that and authentication would be required for every endpoint?\n- Do what I've described in this answer? That's the way to do exactly that. If you have a new question, add relevant details *to a new question* and why this doesn't solve what you're looking to do. It's hard to provide relevant details and code in comments, but in this case, replace `security` with `authenticate` above. Instead of returning `false` in your authentication point, raise an httpexception with 401/403 as its status code - that will terminated the request. If you want to still be able to check for authentication and not require it in certain endpoints, wrap the dependency\n- in another dependency: `def require_authentication(authenticated: bool = Depends(authenticate)): if not authenticated: raise HTTPException(status_code=401)` or something similar.\n- Thanks! I didn't realise that I need to use `FastAPI(logger=logger, dependencies=[Depends(authenticate)])` instead of `FastAPI(logger=logger, dependencies=[Depends(security)])`\n- I tried `FastAPI(dependencies=[Depends(get_current_active_user)]`, function in the docs tutorial to implement the auth to all path, but its not working. @vekeras\n- @curiouscheese Please create a new question with all the relevant details if you have a question; comments to an existing answer isn't the place to raise new issues.\n- I had a similar workflow where I needed to also access the `current_user` in my route and this helped me.","metadata":{"transformedAt":"2026-08-18T18:32:29.108Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":50,"estimatedTokens":769}}182{"id":"stack-65627453","source":"stackoverflow","questionId":65627453,"title":"How to set the file multiple file upload field as an Optional field in FastAPI","tags":["python-3.x","fastapi"],"text":"Title: How to set the file multiple file upload field as an Optional field in FastAPI\nTags: python-3.x, fastapi\nSource: Stack Overflow\n\nQuestion:\n```\nfrom typing import List\n\nfrom fastapi import FastAPI, File, UploadFile\nfrom fastapi.responses import HTMLResponse\n\napp = FastAPI()\n\n@app.post(\"/files/\")\nasync def create_files(files: List[bytes] = File(...)):\n return {\"file_sizes\": [len(file) for file in files]}\n\n@app.post(\"/uploadfiles/\")\nasync def create_upload_files(files: List[UploadFile] = File(...)):\n return {\"filenames\": [file.filename for file in files]}\n```\n\nI am required to get the multiple file upload field as an Optional one\nThe documentation has the above mentioned code but it has no details on how to make the \"FileUpload\" field as an optional field.\n\n========================================\n\nTop Answer:\nthis worked for me\n\n```\n@app.post(\"/uploadfiles/\")\ndef create_upload_files(\n files: List[Union[UploadFile, None]] = File(None)\n):\n return {\"filenames\": [file.filename for file in files]}\n```\n\n========================================\n\nCode:\n```text\nfrom typing import List\n\nfrom fastapi import FastAPI, File, UploadFile\nfrom fastapi.responses import HTMLResponse\n\napp = FastAPI()\n\n\n@app.post(\"/files/\")\nasync def create_files(files: List[bytes] = File(...)):\n return {\"file_sizes\": [len(file) for file in files]}\n\n\n@app.post(\"/uploadfiles/\")\nasync def create_upload_files(files: List[UploadFile] = File(...)):\n return {\"filenames\": [file.filename for file in files]}\n```\n\n```py\nfrom typing import Optional\n\nfiles: Optional[List[bytes]] = File(None)\n```\n\n```py\nfiles: List[bytes] = File(...)\n```\n\n```py\nfrom typing import List, Optional\n\nfrom fastapi import FastAPI, File, UploadFile\nfrom fastapi.responses import HTMLResponse\n\napp = FastAPI()\n\n\n@app.post(\"/files/\")\nasync def create_files(files: Optional[List[bytes]] = File(None)):\n return {\"file_sizes\": [len(file) for file in files]}\n\n\n@app.post(\"/uploadfiles/\")\nasync def create_upload_files(files: Optional[List[UploadFile]] = File(None)):\n return {\"filenames\": [file.filename for file in files]}\n```\n\n```text\nNone\n```\n\n```text\n...\n```\n\n```text\nOptional\n```\n\n```text\nOptional\n```\n\n```text\n@app.post(\"/uploadfiles/\")\ndef create_upload_files(\n files: List[Union[UploadFile, None]] = File(None)\n):\n return {\"filenames\": [file.filename for file in files]}\n```\n\n```text\n@app.post(\"/api/v1/email\")\nasync def send_email_with_files(\n email_to: str = Form(...),\n recipient_name: str = Form(default=\"\"),\n subject: str = Form(...),\n text: str = Form(...),\n files: list[UploadFile] | list = File(default_factory=list),\n):\n # swagger sends an empty string\n files = [file for file in files if file and not isinstance(file, str)]\n return {\"filenames\": [file.filename for file in files]}\n```\n\n========================================\n\nComments:\n- You can find more (recent) details about optional parameters in this answer.\n- Have a look at this answer and this answer on how to upload multiple files in FastAPI.","metadata":{"transformedAt":"2026-08-18T18:32:29.108Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":10,"totalLines":132,"estimatedTokens":759}}183{"id":"stack-66427332","source":"stackoverflow","questionId":66427332,"title":"Caching results in an async environment","tags":["python","caching","python-asyncio","fastapi","nest-asyncio"],"text":"Title: Caching results in an async environment\nTags: python, caching, python-asyncio, fastapi, nest-asyncio\nSource: Stack Overflow\n\nQuestion:\nI am working in a FastAPI endpoint that make a I/O bound operation, which is async for efficiency. However, it takes time, so I would like to cache the results to reuse it for a period of time.\n\nI currently I have this:\n\n```\nfrom fastapi import FastAPI\nimport asyncio\n\napp = FastAPI()\n\nasync def _get_expensive_resource(key) -> None:\n await asyncio.sleep(2)\n return True\n\n@app.get('/')\nasync def get(key):\n return await _get_expensive_resource(key)\n\nif __name__ == \"__main__\":\n import uvicorn\n uvicorn.run(\"test:app\")\n```\n\nI am trying to use the `cachetools` package to cache the results and I have tried something like the following:\n\n```\nimport asyncio\nfrom cachetools import TTLCache\nfrom fastapi import FastAPI\n \napp = FastAPI()\n\nasync def _get_expensive_resource(key) -> None:\n await asyncio.sleep(2)\n return True\n\nclass ResourceCache(TTLCache):\n def __missing__(self, key):\n loop = asyncio.get_event_loop()\n resource = loop.run_until_complete(_get_expensive_resource(key))\n self[key] = resource\n return resource\n\nresource_cache = ResourceCache(124, 300)\n\n@app.get('/')\nasync def get(key: str):\n return resource_cache[key]\n\nif __name__ == \"__main__\":\n import uvicorn\n uvicorn.run(\"test2:app\")\n```\n\nHowever, this fails, because, as far as I understand, the `__missing__` method is sync and you can't call async from sync from async. The error is:\n\n```\nRuntimeError: this event loop is already running.\n```\n\nSimilar error happen if I use plain asyncio instead of uvloop.\n\nFor the asyncio event loop, I have tried using `nest_asyncio` package, but it does not patch `uvloop` and also, even when using it with asyncio, it seems like the service freezes after using it the first time.\n\nDo you have any idea how could I acomplish this?\n\n========================================\n\nTop Answer:\nHere is an example of how to cache a FastAPI call using the `cachetools` library with the same async function above without any custom class needed:\n\n```\nfrom fastapi import FastAPI\nfrom cachetools import TTLCache\nimport asyncio\n\napp = FastAPI()\n\n# Create a cache with a maximum size of 100 entries and a TTL of 60 seconds\ncache = TTLCache(maxsize=100, ttl=60)\n\nasync def _get_expensive_resource(key) -> None:\n await asyncio.sleep(5)\n return True\n\n@app.get(\"/{key}\")\nasync def get(key):\n # Check if the result is already in the cache\n result = cache.get(key)\n if result is not None:\n print(f\"Found it in cache for key {key}\")\n return result\n\n result = await _get_expensive_resource(key)\n\n # Store the result in the cache\n cache[key] = result\n\n return result\n\nif __name__ == \"__main__\":\n import uvicorn\n uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n```\n\nThe first time the route is called, the result is computed and stored in the cache. Subsequent calls to the route within the next 60 seconds will return the cached result without recomputing it.\n\nThen I called it locally from my terminal\n\n```\ncurl http://localhost:8000/mykey\n```\n\nFirst call took 5 seconds and within the first minute all the calls I executed got an immediate response.\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI\nimport asyncio\n\napp = FastAPI()\n\nasync def _get_expensive_resource(key) -> None:\n await asyncio.sleep(2)\n return True\n\n@app.get('/')\nasync def get(key):\n return await _get_expensive_resource(key)\n\nif __name__ == \"__main__\":\n import uvicorn\n uvicorn.run(\"test:app\")\n```\n\n```py\nimport asyncio\nfrom cachetools import TTLCache\nfrom fastapi import FastAPI\n \napp = FastAPI()\n\nasync def _get_expensive_resource(key) -> None:\n await asyncio.sleep(2)\n return True\n\nclass ResourceCache(TTLCache):\n def __missing__(self, key):\n loop = asyncio.get_event_loop()\n resource = loop.run_until_complete(_get_expensive_resource(key))\n self[key] = resource\n return resource\n\nresource_cache = ResourceCache(124, 300)\n\n@app.get('/')\nasync def get(key: str):\n return resource_cache[key]\n\nif __name__ == \"__main__\":\n import uvicorn\n uvicorn.run(\"test2:app\")\n```\n\n```text\nRuntimeError: this event loop is already running.\n```\n\n```text\ncachetools\n```\n\n```text\n__missing__\n```\n\n```text\nnest_asyncio\n```\n\n```text\nuvloop\n```\n\n```py\nclass ResourceCache(TTLCache):\n def __missing__(self, key) -> asyncio.Task:\n # Create a task \n resource_future = asyncio.create_task(_get_expensive_resource(key))\n self[key] = resource_future\n return resource_future\n```\n\n```py\n@app.get(\"/\")\nasync def get(key:str) -> bool:\n return await resource_cache[key]\n```\n\n```text\nTTLCache\n```\n\n```text\n__missing__\n```\n\n```text\nawait\n```\n\n```text\nfrom fastapi import FastAPI\nfrom cachetools import TTLCache\nimport asyncio\n\napp = FastAPI()\n\n# Create a cache with a maximum size of 100 entries and a TTL of 60 seconds\ncache = TTLCache(maxsize=100, ttl=60)\n\n\nasync def _get_expensive_resource(key) -> None:\n await asyncio.sleep(5)\n return True\n\n\n@app.get(\"/{key}\")\nasync def get(key):\n # Check if the result is already in the cache\n result = cache.get(key)\n if result is not None:\n print(f\"Found it in cache for key {key}\")\n return result\n\n result = await _get_expensive_resource(key)\n\n # Store the result in the cache\n cache[key] = result\n\n return result\n\n\nif __name__ == \"__main__\":\n import uvicorn\n uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n```\n\n```text\ncurl http://localhost:8000/mykey\n```\n\n```text\ncachetools\n```\n\n========================================\n\nComments:\n- Look at `fastapi-cache` github.com/long2ice/fastapi-cache\n- That looks interesting, but its not a general purpose cache method for caching the results of `_get_expensive_resource`, it only caches the endpoint, but what if I use this resource in various endpoints across the app? (in fact, I do). So I don't think I can use that.\n- How is this working exactly if the `get` function takes in a `key` argument however it's not defined in the decorator? e.g fastapi.tiangolo.com/tutorial/path-params\n- Hi @AntonioGomezAlvarado in this case, key is a query parameter, not a path parameter.\n- That looks interesting, Antonio. Note however, this is not caching `_get_expensive_resource` across all endpoints, if this function is called in multiple points in the app, each endpoint definition must check the cache first, leading to code duplication.\n- Thanks Nicolas, the idea here is to stick to `fastapi` \"jargon\" without using directly `asyncio`. Actually it can be added as a dependency in the main router e.g `api_router = APIRouter(dependencies=[Depends(verify_cache)])` were `verify_cache` is defined as `def verify_cache(request: Request):` and does the same as above. Just that it does it for all incoming requests (`Request` is imported from `fastapi` module)\n- I was wondering if we could use this method by connecting it to a cache (like, say, Redis).\n- @BruceWayne yes its possible. You would have to use an `async` client to communicate with Redis though","metadata":{"transformedAt":"2026-08-18T18:32:29.108Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":15,"totalLines":274,"estimatedTokens":1768}}184{"id":"stack-63324327","source":"stackoverflow","questionId":63324327,"title":"Write a CSV file asynchronously in Python","tags":["python","csv","async-await","python-asyncio","fastapi"],"text":"Title: Write a CSV file asynchronously in Python\nTags: python, csv, async-await, python-asyncio, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am writing a CSV file with the following function:\n\n```\nimport csv\nimport os\nimport aiofiles\n\nasync def write_extract_file(output_filename: str, csv_list: list):\n \"\"\"\n Write the extracted content into the file\n \"\"\"\n try:\n async with aiofiles.open(output_filename, \"w+\") as csv_file:\n writer = csv.DictWriter(csv_file, fieldnames=columns.keys())\n writer.writeheader()\n writer.writerows(csv_list)\n except FileNotFoundError:\n print(\"Output file not present\", output_filename)\n print(\"Current dir: \", os.getcwd())\n raise FileNotFoundError\n```\n\nHowever, as there is no await allowed over `writerows` method, there are no rows being written into the CSV file.\n\nHow to resolve this issue? Is there any workaround available?\n\nThank you.\n\nEntire code can be found here.\n\n========================================\n\nTop Answer:\nYou can use aiocsv. Here is a quick example of writing a row to a CSV file asynchronously:\n\n```\nimport asyncio\nimport aiofiles\nfrom aiocsv import AsyncWriter\n\nasync def main():\n async with aiofiles.open('your-path.csv', 'w') as f:\n writer = AsyncWriter(f)\n await writer.writerow(['name', 'age'])\n await writer.writerow(['John', 25])\n\nasyncio.run(main())\n```\n\nFor more examples : https://pypi.org/project/aiocsv/\n\n========================================\n\nCode:\n```py\nimport csv\nimport os\nimport aiofiles\n\n\nasync def write_extract_file(output_filename: str, csv_list: list):\n \"\"\"\n Write the extracted content into the file\n \"\"\"\n try:\n async with aiofiles.open(output_filename, \"w+\") as csv_file:\n writer = csv.DictWriter(csv_file, fieldnames=columns.keys())\n writer.writeheader()\n writer.writerows(csv_list)\n except FileNotFoundError:\n print(\"Output file not present\", output_filename)\n print(\"Current dir: \", os.getcwd())\n raise FileNotFoundError\n```\n\n```text\nwriterows\n```\n\n```text\ndef write_extract_file(output_filename: str, csv_list: list):\n \"\"\"\n Write the extracted content into the file\n \"\"\"\n try:\n with open(output_filename, \"w+\") as csv_file:\n writer = csv.DictWriter(csv_file, fieldnames=columns.keys())\n writer.writeheader()\n writer.writerows(csv_list)\n except FileNotFoundError:\n print(\"Output file not present\", output_filename)\n print(\"Current dir: \", os.getcwd())\n raise FileNotFoundError\n\n\nasync def main():\n loop = asyncio.get_running_loop()\n await loop.run_in_executor(None, write_extract_file, 'test.csv', csv_list)\n```\n\n```text\naiofiles\n```\n\n```text\ncsv\n```\n\n```text\nloop.run_in_executor\n```\n\n```text\nimport aiofiles\n\nasync def write_extract_file(\n output_filename: str, csv_list: list\n):\n\n cols = columns.keys()\n\n async with aiofiles.open(output_filename, mode='w+') as f_out:\n\n await f_out.write(','.join(cols)+'\\n')\n\n for data in csv_list:\n\n line = []\n\n for c in cols:\n line.append(str(data[c]) if c in data else '')\n\n line = ','.join(line) + '\\n'\n \n await f_out.write(line)\n```\n\n```text\nimport asyncio\nimport aiofiles\nfrom aiocsv import AsyncWriter\n\nasync def main():\n async with aiofiles.open('your-path.csv', 'w') as f:\n writer = AsyncWriter(f)\n await writer.writerow(['name', 'age'])\n await writer.writerow(['John', 25])\n\nasyncio.run(main())\n```\n\n========================================\n\nComments:\n- note that using async io for local files tends to be slower than synchronous io. you're probably off just using a sync (i.e. non-async) method and wrapping in `loop.run_in_executor` so that the async code can interact with it nicely\n- note that this runs `write_extract_file` synchronously. you need to use `await loop.run_in_executor(None, write_extract_file, 'test.csv', csv_list)` to actually run it asynchronously\n- The problem with this approach is if you need to perform async operations in the middle of writing the csv\n- @royce3 exactly! If I liverage one coroutine for collecting data and another for converting data into a pandas dataframe after some preprocessing and then write to csv, then it will cause problems.\n- This code doesn't handle a lot of the logic that the csv module is performing, like quoting columns that have commas in them for example.","metadata":{"transformedAt":"2026-08-18T18:32:29.108Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":8,"totalLines":164,"estimatedTokens":1105}}185{"id":"stack-64493872","source":"stackoverflow","questionId":64493872,"title":"How do I serve a React-built front-end on a FastAPI backend?","tags":["reactjs","fastapi","react-fullstack"],"text":"Title: How do I serve a React-built front-end on a FastAPI backend?\nTags: reactjs, fastapi, react-fullstack\nSource: Stack Overflow\n\nQuestion:\nI've tried to mount the frontend to `/` with `app.mount`, but this invalidates all of my `/api` routes. I've also tried the following code to mount the folders in `/static` to their respective routes and serving the `index.html` file on `/`:\n\n```\n@app.get(\"/\")\ndef index():\n project_path = Path(__file__).parent.resolve()\n frontend_root = project_path / \"client/build\"\n return FileResponse(str(frontend_root) + '/index.html', media_type='text/html')\n\nstatic_root = project_path / \"client/build/static\"\napp.mount(\"/static\", StaticFiles(directory=static_root), name=\"static\")\n```\n\nThis mostly works, but files contained in the `client/build` folder aren't mounted and are thus inaccessible. I know that Node.js has a way of serving the front-end page with relative paths with `res.sendFile(\"index.html\", { root: </path/to/static/folder });`. Is there an equivalent function for doing this in FastAPI?\n\n========================================\n\nTop Answer:\nUpdate to the answer by Ricardo,\n\nAt some point `starlette.staticfiles.StaticFiles` started raising `HTTPException` instead of PlaintText 404 response, so for hosting SPA, I guess new version of code should look like this:\n\n```\nfrom fastapi import HTTPException\nfrom starlette.exceptions import HTTPException as StarletteHTTPException\n\n# ... \n\nclass SPAStaticFiles(StaticFiles):\n async def get_response(self, path: str, scope):\n try:\n return await super().get_response(path, scope)\n except (HTTPException, StarletteHTTPException) as ex:\n if ex.status_code == 404:\n return await super().get_response(\"index.html\", scope)\n else:\n raise ex\n\napp.mount(\"/\", SPAStaticFiles(directory=\"dist\", html=True), name=\"spa-static-files\")\n```\n\n========================================\n\nCode:\n```text\n@app.get(\"/\")\ndef index():\n project_path = Path(__file__).parent.resolve()\n frontend_root = project_path / \"client/build\"\n return FileResponse(str(frontend_root) + '/index.html', media_type='text/html')\n\nstatic_root = project_path / \"client/build/static\"\napp.mount(\"/static\", StaticFiles(directory=static_root), name=\"static\")\n```\n\n```text\n/\n```\n\n```text\napp.mount\n```\n\n```text\n/api\n```\n\n```text\n/static\n```\n\n```text\nindex.html\n```\n\n```text\n/\n```\n\n```text\nclient/build\n```\n\n```text\nres.sendFile(\"index.html\", { root: </path/to/static/folder });\n```\n\n```py\nfrom fastapi.staticfiles import StaticFiles\n\nclass SPAStaticFiles(StaticFiles):\nasync def get_response(self, path: str, scope):\n response = await super().get_response(path, scope)\n if response.status_code == 404:\n response = await super().get_response('.', scope)\n return response\n\napp.mount('/my-spa/', SPAStaticFiles(directory='folder', html=True), name='whatever')\n```\n\n```py\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", port=5000)\n```\n\n```py\nfrom fastapi import FastAPI\n```\n\n```text\nnpm run build\n```\n\n```text\nfolder\n```\n\n```text\nnpm run build\n```\n\n```text\nyarn run build\n```\n\n```text\ndist\n```\n\n```text\ndist\n```\n\n```text\nfolder\n```\n\n```text\nhttp://localhost:5000/my-spa/\n```\n\n```text\n],\n \"development\": [\n \"last 1 chrome version\",\n \"last 1 firefox version\",\n \"last 1 safari version\"\n ]\n },\n \"proxy\": \"http://localhost:8000\"\n}\n```\n\n```py\nfrom fastapi import HTTPException\nfrom starlette.exceptions import HTTPException as StarletteHTTPException\n\n# ... \n\nclass SPAStaticFiles(StaticFiles):\n async def get_response(self, path: str, scope):\n try:\n return await super().get_response(path, scope)\n except (HTTPException, StarletteHTTPException) as ex:\n if ex.status_code == 404:\n return await super().get_response(\"index.html\", scope)\n else:\n raise ex\n\n\napp.mount(\"/\", SPAStaticFiles(directory=\"dist\", html=True), name=\"spa-static-files\")\n```\n\n```text\nstarlette.staticfiles.StaticFiles\n```\n\n```text\nHTTPException\n```\n\n========================================\n\nComments:\n- Read this code where `FastAPI` and `React` are served from a single server. The gist is - you need a process running React and a process running FastAPI and a proxy server (nginx in this example) that routes calls.\n- I found your answer very helpful, I will also say I ended up just doing what was suggested here. stackoverflow.com/a/68488252/3538107. thanks for the help!\n- This is amazingly in-depth, however unfortunately I'm getting ` TypeError: 'NoneType' object is not callable` I believe on `if response.status_code == 404:` , but only for actualy 404s. Very weird, looking into it.\n- Hi Caleb. As I said, I posted this answer first of all to help *you*. Please contact me on LinkedIn (link on my StackOverflow profile) and let's take it from there. We could have a zoom or something. No, this is not a paid service!\n- did FastAPI's api change? We had to wrap `await super().get_response(path, scope)` into a `try` block, and moved `return await super().get_response('./index.html', scope)` into an `except` block\n- This should be marked as accepted, Ricardo's answer is no longer up-to-date in 2023. @Mike Chaliy Could you please add the import statement `from starlette.exceptions import HTTPException` to your sample? There are two more sources for the `HTTPException` class available in the scope if you're using FastAPI and this is the one that `StaticFiles` actually throws.","metadata":{"transformedAt":"2026-08-18T18:32:29.108Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":24,"totalLines":195,"estimatedTokens":1361}}186{"id":"stack-65636962","source":"stackoverflow","questionId":65636962,"title":"loading models in FastAPI projects at startup","tags":["deployment","fastapi"],"text":"Title: loading models in FastAPI projects at startup\nTags: deployment, fastapi\nSource: Stack Overflow\n\nQuestion:\nso I'm currently working on a FastAPI project that serves multiple NLP services. To do so I want to provide different models from spacy as well as huggingface.\n\nSince those **models are quite big** the inference time when **loading the models for each post request is quite long**. My idea is to **load all the models on FastAPI startup (in the app/main.py)**, however, I'm not sure, whether this is a good choice/idea or if there a some drawbacks to this approach since the models will be in the cache(?). (Info: I want to dockerize the project and deploy it on a virtual machine afterwards)\n\nSo far I wasn't able to find any guidance on the internet, so I hope to get a good answer here :)\n\nThanks in advance!\n\n========================================\n\nCode:\n```py\ngunicorn --workers 2 --preload --worker-class=uvicorn.workers.UvicornWorker my_app:app\n```\n\n```text\ngunicorn\n```\n\n```text\nuvicorn\n```\n\n```text\ngunicorn\n```\n\n```text\n--preload\n```\n\n```text\n--preload\n```\n\n========================================\n\nComments:\n- Hey Yagiz, thanks for your answer - so instead of loading the models in the \"main.py\" I should stick to my current code and just start the app with gunicorn and the --preload flag set? **FYI: Currently I load the models with a custom class that is called when an POST request is made.** p.s. I can't give upvotes yet :(\n- Hey, i think you can use singleton approach. Declare the model once in your `main.py`. Then use that, it will load the model once in the memory, as far as i understand you are creating a new class instance for every request which means you are loading that model in the memory for every request, right?\n- exactly! I'll change my code according to your recommendation - thanks alot! :)\n- @YagizDegirmenci: can you please verify if I am understanding this right? If we use the `--preload` flag, the main gunicorn thread loads the application on bootup, and then when the workers get forked, they get a copy of the application? If that is the case, would the application loaded by the workers the same memory space? Are there any caveats to this approach that I need to be aware of? Thank you.\n- @coczor Did you try the singleton approach? How did you make the model objects available via API router?","metadata":{"transformedAt":"2026-08-18T18:32:29.108Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":6,"totalLines":48,"estimatedTokens":589}}187{"id":"stack-73076517","source":"stackoverflow","questionId":73076517,"title":"How to send RedirectResponse from a POST to a GET route in FastAPI?","tags":["python","http-redirect","fastapi","httpresponse","starlette"],"text":"Title: How to send RedirectResponse from a POST to a GET route in FastAPI?\nTags: python, http-redirect, fastapi, httpresponse, starlette\nSource: Stack Overflow\n\nQuestion:\nI want to send data from `app.post()` to `app.get()` using `RedirectResponse`.\n\n```\n@app.get('/', response_class=HTMLResponse, name='homepage')\nasync def get_main_data(request: Request,\n msg: Optional[str] = None,\n result: Optional[str] = None):\n if msg:\n response = templates.TemplateResponse('home.html', {'request': request, 'msg': msg})\n elif result:\n response = templates.TemplateResponse('home.html', {'request': request, 'result': result})\n else:\n response = templates.TemplateResponse('home.html', {'request': request})\n return response\n```\n\n```\n@app.post('/', response_model=FormData, name='homepage_post')\nasync def post_main_data(request: Request,\n file: FormData = Depends(FormData.as_form)):\n if condition:\n ......\n ......\n\n return RedirectResponse(request.url_for('homepage', **{'result': str(trans)}), status_code=status.HTTP_302_FOUND)\n\n return RedirectResponse(request.url_for('homepage', **{'msg': str(err)}), status_code=status.HTTP_302_FOUND)\n```\n\n- How do I send `result` or `msg` via `RedirectResponse`, `url_for()` to `app.get()`?\n\n- Is there a way to hide the data in the URL either as `path parameter` or `query parameter`? How do I achieve this?\n\nI am getting the error `starlette.routing.NoMatchFound: No route exists for name \"homepage\" and params \"result\".` when trying this way.\n\n**Update:**\n\nI tried the below:\n\n```\nreturn RedirectResponse(app.url_path_for(name='homepage')\n + '?result=' + str(trans),\n status_code=status.HTTP_303_SEE_OTHER)\n```\n\nThe above works, but it works by sending the param as `query` param, i.e., the URL looks like this `localhost:8000/?result=hello`. Is there any way to do the same thing but without showing it in the URL?\n\n========================================\n\nCode:\n```py\n@app.get('/', response_class=HTMLResponse, name='homepage')\nasync def get_main_data(request: Request,\n msg: Optional[str] = None,\n result: Optional[str] = None):\n if msg:\n response = templates.TemplateResponse('home.html', {'request': request, 'msg': msg})\n elif result:\n response = templates.TemplateResponse('home.html', {'request': request, 'result': result})\n else:\n response = templates.TemplateResponse('home.html', {'request': request})\n return response\n```\n\n```py\n@app.post('/', response_model=FormData, name='homepage_post')\nasync def post_main_data(request: Request,\n file: FormData = Depends(FormData.as_form)):\n if condition:\n ......\n ......\n\n return RedirectResponse(request.url_for('homepage', **{'result': str(trans)}), status_code=status.HTTP_302_FOUND)\n\n return RedirectResponse(request.url_for('homepage', **{'msg': str(err)}), status_code=status.HTTP_302_FOUND)\n```\n\n```py\nreturn RedirectResponse(app.url_path_for(name='homepage')\n + '?result=' + str(trans),\n status_code=status.HTTP_303_SEE_OTHER)\n```\n\n```text\napp.post()\n```\n\n```text\napp.get()\n```\n\n```text\nRedirectResponse\n```\n\n```text\nresult\n```\n\n```text\nmsg\n```\n\n```text\nRedirectResponse\n```\n\n```text\nurl_for()\n```\n\n```text\napp.get()\n```\n\n```text\npath parameter\n```\n\n```text\nquery parameter\n```\n\n```text\nstarlette.routing.NoMatchFound: No route exists for name \"homepage\" and params \"result\".\n```\n\n```text\nquery\n```\n\n```text\nlocalhost:8000/?result=hello\n```\n\n```py\nreturn RedirectResponse(redirect_url, status_code=status.HTTP_303_SEE_OTHER)\n```\n\n```py\nfrom fastapi import FastAPI, Request, status\nfrom fastapi.responses import RedirectResponse, HTMLResponse\nfrom typing import Optional\nimport urllib\n\napp = FastAPI()\n\nclass CustomURLProcessor:\n def __init__(self): \n self.path = \"\" \n self.request = None\n\n def url_for(self, request: Request, name: str, **params: str):\n self.path = request.url_for(name, **params)\n self.request = request\n return self\n \n def include_query_params(self, **params: str):\n parsed = list(urllib.parse.urlparse(self.path))\n parsed[4] = urllib.parse.urlencode(params)\n return urllib.parse.urlunparse(parsed)\n \n\n@app.get('/', response_class=HTMLResponse)\ndef event_msg(request: Request, msg: Optional[str] = None):\n if msg:\n html_content = \"\"\"\n <html>\n <head>\n <script>\n window.history.pushState('', '', \"/\");\n </script>\n </head>\n <body>\n <h1>\"\"\" + msg + \"\"\"</h1>\n </body>\n </html>\n \"\"\"\n return HTMLResponse(content=html_content, status_code=200)\n else:\n html_content = \"\"\"\n <html>\n <body>\n <h1>Create an event</h1>\n <form method=\"POST\" action=\"/\">\n <input type=\"submit\" value=\"Create Event\">\n </form>\n </body>\n </html>\n \"\"\"\n return HTMLResponse(content=html_content, status_code=200)\n\n@app.post('/')\ndef event_create(request: Request):\n redirect_url = CustomURLProcessor().url_for(request, 'event_msg').include_query_params(msg=\"Succesfully created!\")\n return RedirectResponse(redirect_url, status_code=status.HTTP_303_SEE_OTHER)\n```\n\n```py\nfrom starlette.datastructures import URL\n\nredirect_url = URL(request.url_for('event_msg')).include_query_params(msg=\"Succesfully created!\")\n```\n\n```py\nredirect_url = request.url_for('event_msg').include_query_params(msg=\"Succesfully created!\")\n```\n\n```text\nRedirectResponse\n```\n\n```text\nPOST\n```\n\n```text\nGET\n```\n\n```text\n303 See Other\n```\n\n```text\nstarlette.routing.NoMatchFound\n```\n\n```text\nrequest.url_for()\n```\n\n```text\npath\n```\n\n```text\nquery\n```\n\n```text\nmsg\n```\n\n```text\nresult\n```\n\n```text\nquery\n```\n\n```text\nCustomURLProcessor\n```\n\n```text\npath\n```\n\n```text\nquery\n```\n\n```text\nurl_for()\n```\n\n```text\npath\n```\n\n```text\nquery\n```\n\n```text\nhistory.pushState()\n```\n\n```text\nhistory.replaceState()\n```\n\n```text\nTemplateResponse\n```\n\n```text\nHTMLResponse\n```\n\n```text\nurl_for()\n```\n\n```text\nstarlette.datastructures.URL\n```\n\n```text\ninclude_query_params\n```\n\n```text\nrequest.url_for()\n```\n\n```text\nstarlette.datastructures.URL\n```\n\n========================================\n\nComments:\n- Please have a look at the answers here and here (you should rather use the method's name in `request.url_for()`, i.e., `get_main_data`). As for hiding the data in the URL, please take a look at this answer.\n- I tried. I am getting the same error in both cases. Using a `router` as well. Tried with `get_main_data` also, same result\n- Thanks for the reply. Yes, I tried a similar approach.","metadata":{"transformedAt":"2026-08-18T18:32:29.108Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":46,"totalLines":323,"estimatedTokens":1688}}188{"id":"stack-61948723","source":"stackoverflow","questionId":61948723,"title":"How to extend a Pydantic object and change some fields' type?","tags":["python","python-3.x","fastapi","pydantic"],"text":"Title: How to extend a Pydantic object and change some fields' type?\nTags: python, python-3.x, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nThere are two similar pydantic object like that. The only difference is some fields are optionally.\nHow can I just define the fields in one object and extend into another one?\n\n```\nclass ProjectCreateObject(BaseModel):\n project_id: str\n project_name: str\n project_type: ProjectTypeEnum\n depot: str\n system: str\n ...\n\nclass ProjectPatchObject(ProjectCreateObject):\n project_id: str\n project_name: Optional[str]\n project_type: Optional[ProjectTypeEnum]\n depot: Optional[str]\n system: Optional[str]\n ...\n```\n\n========================================\n\nTop Answer:\nYou've pretty much answered it yourself. Unless there's something more to the question.\n\n```\nfrom typing import Optional\nfrom pydantic import BaseModel\n\nclass ProjectCreateObject(BaseModel):\n project_id: str\n project_name: str\n project_type: str\n depot: str\n system: str\n\nclass ProjectPatchObject(ProjectCreateObject):\n project_name: Optional[str]\n project_type: Optional[str]\n depot: Optional[str]\n system: Optional[str]\n\nif __name__ == \"__main__\":\n p = ProjectCreateObject(\n project_id=\"id\",\n project_name=\"name\",\n project_type=\"type\",\n depot=\"depot\",\n system=\"system\",\n )\n print(p)\n\n c = ProjectPatchObject(project_id=\"id\", depot=\"newdepot\")\n print(c)\n```\n\nRunning this gives:\n\n```\nproject_id='id' project_name='name' project_type='type' depot='depot' system='system'\nproject_id='id' project_name=None project_type=None depot='newdepot' system=None\n```\n\nAnother way to look at it is to define the base as optional and then create a validator to check when all required:\n\n```\nfrom pydantic import BaseModel, root_validator, MissingError\n\nclass ProjectPatchObject(BaseModel):\n project_id: str\n project_name: Optional[str]\n project_type: Optional[str]\n depot: Optional[str]\n system: Optional[str]\n\nclass ProjectCreateObject(ProjectPatchObject):\n @root_validator\n def check(cls, values):\n for k, v in values.items():\n if v is None:\n raise MissingError()\n return values\n```\n\n========================================\n\nCode:\n```text\nclass ProjectCreateObject(BaseModel):\n project_id: str\n project_name: str\n project_type: ProjectTypeEnum\n depot: str\n system: str\n ...\n\nclass ProjectPatchObject(ProjectCreateObject):\n project_id: str\n project_name: Optional[str]\n project_type: Optional[ProjectTypeEnum]\n depot: Optional[str]\n system: Optional[str]\n ...\n```\n\n```text\nclass ProjectCreateObject(BaseModel):\n project_id: str\n project_name: str\n project_type: ProjectTypeEnum\n depot: str\n system: str\n ...\n\n def __init_subclass__(cls, optional_fields=(), **kwargs):\n \"\"\"\n allow some fields of subclass turn into optional\n \"\"\"\n super().__init_subclass__(**kwargs)\n for field in optional_fields:\n cls.__fields__[field].outer_type_ = Optional\n cls.__fields__[field].required = False\n\n_patch_fields = ProjectCreateObject.__fields__.keys() - {'project_id'}\n\nclass ProjectPatchObject(ProjectCreateObject, optional_fields=_patch_fields):\n pass\n```\n\n```text\n__init__subclass__\n```\n\n```text\nfrom typing import Optional\nfrom pydantic import BaseModel\n\n\nclass ProjectCreateObject(BaseModel):\n project_id: str\n project_name: str\n project_type: str\n depot: str\n system: str\n\n\nclass ProjectPatchObject(ProjectCreateObject):\n project_name: Optional[str]\n project_type: Optional[str]\n depot: Optional[str]\n system: Optional[str]\n\n\nif __name__ == \"__main__\":\n p = ProjectCreateObject(\n project_id=\"id\",\n project_name=\"name\",\n project_type=\"type\",\n depot=\"depot\",\n system=\"system\",\n )\n print(p)\n\n c = ProjectPatchObject(project_id=\"id\", depot=\"newdepot\")\n print(c)\n```\n\n```text\nproject_id='id' project_name='name' project_type='type' depot='depot' system='system'\nproject_id='id' project_name=None project_type=None depot='newdepot' system=None\n```\n\n```text\nfrom pydantic import BaseModel, root_validator, MissingError\n\nclass ProjectPatchObject(BaseModel):\n project_id: str\n project_name: Optional[str]\n project_type: Optional[str]\n depot: Optional[str]\n system: Optional[str]\n\n\nclass ProjectCreateObject(ProjectPatchObject):\n @root_validator\n def check(cls, values):\n for k, v in values.items():\n if v is None:\n raise MissingError()\n return values\n```\n\n```text\nclass AllOptional(pydantic.main.ModelMetaclass):\n def __new__(self, name, bases, namespaces, **kwargs):\n annotations = namespaces.get('__annotations__', {})\n for base in bases:\n annotations.update(base.__annotations__)\n for field in annotations:\n if not field.startswith('__') and field != 'project_id':\n annotations[field] = Optional[annotations[field]]\n namespaces['__annotations__'] = annotations\n return super().__new__(self, name, bases, namespaces, **kwargs)\n```\n\n```text\nclass ProjectPatchObject(ProjectCreateObject, metaclass=AllOptional):\n ...\n```\n\n========================================\n\nComments:\n- An alternative would be to simply keep the two classes. The requirements are different, so it is also an argument to **not** try to make one object out of this. This can help to reduce cognitive overload and fulfills the single responsibility principle.\n- Yes, it works. but I don't want to define the optional fields twice ( in fact, there are lots of fields). Can I change the fileds to optional by batch or some easy way? Thank you.\n- By batch you'd still have to specify which fields are going to be optional, unless you want to make all fields optional? I've also edited to add another idea.\n- I have a new idea and post in my answer.\n- This works well if you just want to add some fields without changing the types of the existing fields. Then there will be no duplication, and no use of dunder methods.\n- The `for` loop won't run if `optional_fields` is falsey, so you can drop the extra if","metadata":{"transformedAt":"2026-08-18T18:32:29.108Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":8,"totalLines":225,"estimatedTokens":1521}}189{"id":"stack-63400683","source":"stackoverflow","questionId":63400683,"title":"Python Logging with loguru- log request params on Fastapi app","tags":["python","logging","fastapi","uvicorn"],"text":"Title: Python Logging with loguru- log request params on Fastapi app\nTags: python, logging, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI have a fastapi application and I want to log every request made on it. I'm trying to use loguru and uvicorn for this, but I don't know how to print the headers and request params (if have one) associated with each request.\n\nI want something like this:\n\n```\nINFO 2020-08-13 13:36:33.494 uvicorn.protocols.http.h11_impl:send - 127.0.0.1:52660 - \"GET \n/url1/url2/ HTTP/1.1\" 400 params={\"some\": value, \"some1\":value}\n```\n\nIs there a way ? thanks for your help.\n\nHere some links:\n\nloguru uvicorn fastapi\n\n========================================\n\nCode:\n```text\nINFO 2020-08-13 13:36:33.494 uvicorn.protocols.http.h11_impl:send - 127.0.0.1:52660 - \"GET \n/url1/url2/ HTTP/1.1\" 400 params={\"some\": value, \"some1\":value}\n```\n\n```py\nimport sys\n\nimport uvicorn\n\nfrom fastapi import FastAPI, Request, APIRouter, Depends\nfrom loguru import logger\nfrom starlette.routing import Match\n\nlogger.remove()\nlogger.add(sys.stdout, colorize=True, format=\"<green>{time:HH:mm:ss}</green> | {level} | <level>{message}</level>\")\napp = FastAPI()\n\nrouter = APIRouter()\n\n\nasync def logging_dependency(request: Request):\n logger.debug(f\"{request.method} {request.url}\")\n logger.debug(\"Params:\")\n for name, value in request.path_params.items():\n logger.debug(f\"\\t{name}: {value}\")\n logger.debug(\"Headers:\")\n for name, value in request.headers.items():\n logger.debug(f\"\\t{name}: {value}\")\n\n\n@router.get(\"/{param1}/{param2}\")\nasync def path_operation(param1: str, param2: str):\n return {'param1': param1, 'param2': param2}\n\napp.include_router(router, dependencies=[Depends(logging_dependency)])\n\nif __name__ == \"__main__\":\n uvicorn.run(\"app:app\", host=\"localhost\", port=8001)\n```\n\n```py\nimport sys\n\nimport uvicorn\n\nfrom fastapi import FastAPI, Request\nfrom loguru import logger\nfrom starlette.routing import Match\n\nlogger.remove()\nlogger.add(sys.stdout, colorize=True, format=\"<green>{time:HH:mm:ss}</green> | {level} | <level>{message}</level>\")\napp = FastAPI()\n\n\n@app.middleware(\"http\")\nasync def log_middle(request: Request, call_next):\n logger.debug(f\"{request.method} {request.url}\")\n routes = request.app.router.routes\n logger.debug(\"Params:\")\n for route in routes:\n match, scope = route.matches(request)\n if match == Match.FULL:\n for name, value in scope[\"path_params\"].items():\n logger.debug(f\"\\t{name}: {value}\")\n logger.debug(\"Headers:\")\n for name, value in request.headers.items():\n logger.debug(f\"\\t{name}: {value}\")\n\n response = await call_next(request)\n return response\n\n\n@app.get(\"/{param1}/{param2}\")\nasync def path_operation(param1: str, param2: str):\n return {'param1': param1, 'param2': param2}\n\n\nif __name__ == \"__main__\":\n uvicorn.run(\"app:app\", host=\"localhost\", port=8001)\n```\n\n```bash\n16:06:43 | DEBUG | GET http://localhost:8001/admin/home\n16:06:43 | DEBUG | Params:\n16:06:43 | DEBUG | param1: admin\n16:06:43 | DEBUG | param2: home\n16:06:43 | DEBUG | Headers:\n16:06:43 | DEBUG | host: localhost:8001\n16:06:43 | DEBUG | user-agent: curl/7.64.0\n16:06:43 | DEBUG | accept: */*\n```\n\n```text\ncurl http://localhost:8001/admin/home\n```\n\n========================================\n\nComments:\n- A dependency could also be used, so that URL paths can be logged independently or together\n- Thank you!! this really help me to solve the problem!!...I just have one question...I replace sys.stdout for \"log/access.log\" to save into a file...but the format looks really bad...any idea ? thank you again !!\n- You can make your own format loguru.readthedocs.io/en/stable/api/logger.html\n- @AlexNoname I know...this is what I mean...character error prnt.sc/tzqx95\n- Try to disable colorize=False\n- do you think this middleware solution will eliminate this issue **Awaiting request body in middleware blocks the application**? see: github.com/tiangolo/fastapi/issues/394#issuecomment-51305197‌​7, I used the **dependency** example with the router where I need to capture `request_body = await request.json()` but I didn't try to use **middleware** solution due to the issue mentioned above.","metadata":{"transformedAt":"2026-08-18T18:32:29.108Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":129,"estimatedTokens":1059}}190{"id":"stack-70219200","source":"stackoverflow","questionId":70219200,"title":"Python FastAPI base path control","tags":["python","fastapi"],"text":"Title: Python FastAPI base path control\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nWhen I use FastAPI , how can I sepcify a base path for the web-service?\n\nTo put it another way - are there arguments to the FastAPI object that can set the end-point and any others I define, to a different root path?\n\nFor example , if I had the code with the spurious argument `root` below, it would attach my `/my_path` end-point to `/my_server_path/my_path` ?\n\n```\nfrom fastapi import FastAPI, Request\n\napp = FastAPI(debug = True, root = 'my_server_path') \n\n@app.get(\"/my_path\")\ndef service( request : Request ):\n return { \"message\" : \"my_path\" }\n```\n\n========================================\n\nTop Answer:\nFrom documentation, if you are using a reverse proxy then you could achieve the same with\n\n`uvicorn main:app --root-path /api/v1`\n\nreference https://fastapi.tiangolo.com/advanced/behind-a-proxy/?h=prefix#testing-locally-with-traefik\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI, Request\n\napp = FastAPI(debug = True, root = 'my_server_path') \n\n@app.get(\"/my_path\")\ndef service( request : Request ):\n return { \"message\" : \"my_path\" }\n```\n\n```text\nroot\n```\n\n```text\n/my_path\n```\n\n```text\n/my_server_path/my_path\n```\n\n```py\nfrom fastapi import APIRouter, FastAPI\n\napp = FastAPI()\n\nprefix_router = APIRouter(prefix=\"/my_server_path\")\n\n# Add the paths to the router instead\n@prefix_router.get(\"/my_path\")\ndef service( request : Request ):\n return { \"message\" : \"my_path\" }\n\n# Now add the router to the app\napp.include_router(prefix_router)\n```\n\n```text\nAPIRouter\n```\n\n```text\n/\n```\n\n```text\napp\n```\n\n```text\napp.include_router(prefix=\"/my_server_path\")\n```\n\n```text\nuvicorn main:app --root-path /api/v1\n```\n\n========================================\n\nComments:\n- I can get something similar to work by wrapping the path argument in a function which prepends the base URI e.g. `@app.get( make_path(\"/my_path\")` where `make_path` just prepends a string like `def make_path( x : str ) -> str: return \"/my_server_path\" + x`\n- This doesn't work with my recent FastAPI version.\n- What version are you using?\n- if you have a separate python file that you want to route to '\"/\" , how would you do that. APIRouter does not accept \"/\" as a prefix\n- doesn't seem to help","metadata":{"transformedAt":"2026-08-18T18:32:29.108Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":10,"totalLines":99,"estimatedTokens":578}}191{"id":"stack-68016155","source":"stackoverflow","questionId":68016155,"title":"How to include non-pydantic classes in fastapi responses?","tags":["python","fastapi","pydantic"],"text":"Title: How to include non-pydantic classes in fastapi responses?\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI want to include a custom class into a route's response. I'm mostly using nested `pydantic.BaseModel`s in my application, so it would be nice to return the whole thing without writing a translation from the internal data representation to what the route returns.\n\nAs long as *everything* inherits from `pydantic.BaseModel` this is trivial, but I'm using a class `Foo` in my backend which can't do that, and I can't subclass it for this purpose either. Can I somehow duck type that class's definition in a way that `fastapi` accepts it? What I have right now is essentially this:\n\n**main.py**\n\n```\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\n\napp = FastAPI()\n\nclass Foo:\n \"\"\"Foo holds data and can't inherit from `pydantic.BaseModel`.\"\"\"\n def __init__(self, x: int):\n self.x = x\n\nclass Response(BaseModel):\n foo: Foo\n # plus some more stuff that doesn't matter right now because it works\n\n@app.get(\"/\", response_model=Response)\ndef root():\n return Response(foo=Foo(1))\n\nif __name__ == '__main__':\n import uvicorn\n uvicorn.run(\"main:app\") # RuntimeError\n```\n\n========================================\n\nTop Answer:\nHere is a full implementation using a subclass with validators and extra schema:\n\n```\nfrom psycopg2.extras import DateTimeTZRange as DateTimeTZRangeBase\nfrom sqlalchemy.dialects.postgresql import TSTZRANGE\nfrom sqlmodel import (\n Column,\n Field,\n Identity,\n SQLModel,\n)\n\nfrom pydantic.json import ENCODERS_BY_TYPE\n\nENCODERS_BY_TYPE |= {DateTimeTZRangeBase: str}\n\nclass DateTimeTZRange(DateTimeTZRangeBase):\n @classmethod\n def __get_validators__(cls):\n yield cls.validate\n\n @classmethod\n def validate(cls, v):\n if isinstance(v, str):\n lower = v.split(\", \")[0][1:].strip().strip()\n upper = v.split(\", \")[1][:-1].strip().strip()\n bounds = v[:1] + v[-1:]\n return DateTimeTZRange(lower, upper, bounds)\n elif isinstance(v, DateTimeTZRangeBase):\n return v\n raise TypeError(\"Type must be string or DateTimeTZRange\")\n\n @classmethod\n def __modify_schema__(cls, field_schema):\n field_schema.update(type=\"string\", example=\"[2022,01,01, 2022,02,02)\")\n\nclass EventBase(SQLModel):\n __tablename__ = \"event\"\n timestamp_range: DateTimeTZRange = Field(\n sa_column=Column(\n TSTZRANGE(),\n nullable=False,\n ),\n )\n\nclass Event(EventBase, table=True):\n id: int | None = Field(\n default=None,\n sa_column_args=(Identity(always=True),),\n primary_key=True,\n nullable=False,\n )\n```\n\nas per @Arne 's solution you need to add your own validators and schema if the Type you are using has `__slots__` and basically no way to get out a `dict`.\n\nLink to Github issue: https://github.com/tiangolo/sqlmodel/issues/235#issuecomment-1162063590\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\n\napp = FastAPI()\n\n\nclass Foo:\n \"\"\"Foo holds data and can't inherit from `pydantic.BaseModel`.\"\"\"\n def __init__(self, x: int):\n self.x = x\n\n\nclass Response(BaseModel):\n foo: Foo\n # plus some more stuff that doesn't matter right now because it works\n\n\n@app.get(\"/\", response_model=Response)\ndef root():\n return Response(foo=Foo(1))\n\n\nif __name__ == '__main__':\n import uvicorn\n uvicorn.run(\"main:app\") # RuntimeError\n```\n\n```text\npydantic.BaseModel\n```\n\n```text\npydantic.BaseModel\n```\n\n```text\nFoo\n```\n\n```text\nfastapi\n```\n\n```py\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel, BaseConfig, create_model\n\napp = FastAPI()\nBaseConfig.arbitrary_types_allowed = True # change #1\n\n\nclass Foo:\n \"\"\"Foo holds data and can't inherit from `pydantic.BaseModel`.\"\"\" \n def __init__(self, x: int):\n self.x = x\n\n __pydantic_model__ = create_model(\"Foo\", x=(int, ...)) # change #2\n\n\nclass Response(BaseModel):\n foo: Foo\n\n\n@app.get(\"/\", response_model=Response)\ndef root():\n return Response(foo=Foo(1))\n\n\nif __name__ == '__main__':\n import uvicorn\n uvicorn.run(\"main:app\") # works\n```\n\n```text\npydantic\n```\n\n```text\nfastapi\n```\n\n```text\npydantic\n```\n\n```text\nvars()\n```\n\n```text\nproperty\n```\n\n```text\n__slots__\n```\n\n```text\nBaseModel\n```\n\n```text\nFoo\n```\n\n```text\nfastapi\n```\n\n```text\nResponse\n```\n\n```text\nConfig.json_encoders\n```\n\n```py\nfrom psycopg2.extras import DateTimeTZRange as DateTimeTZRangeBase\nfrom sqlalchemy.dialects.postgresql import TSTZRANGE\nfrom sqlmodel import (\n Column,\n Field,\n Identity,\n SQLModel,\n)\n\nfrom pydantic.json import ENCODERS_BY_TYPE\n\nENCODERS_BY_TYPE |= {DateTimeTZRangeBase: str}\n\n\nclass DateTimeTZRange(DateTimeTZRangeBase):\n @classmethod\n def __get_validators__(cls):\n yield cls.validate\n\n @classmethod\n def validate(cls, v):\n if isinstance(v, str):\n lower = v.split(\", \")[0][1:].strip().strip()\n upper = v.split(\", \")[1][:-1].strip().strip()\n bounds = v[:1] + v[-1:]\n return DateTimeTZRange(lower, upper, bounds)\n elif isinstance(v, DateTimeTZRangeBase):\n return v\n raise TypeError(\"Type must be string or DateTimeTZRange\")\n\n @classmethod\n def __modify_schema__(cls, field_schema):\n field_schema.update(type=\"string\", example=\"[2022,01,01, 2022,02,02)\")\n\n\nclass EventBase(SQLModel):\n __tablename__ = \"event\"\n timestamp_range: DateTimeTZRange = Field(\n sa_column=Column(\n TSTZRANGE(),\n nullable=False,\n ),\n )\n\n\nclass Event(EventBase, table=True):\n id: int | None = Field(\n default=None,\n sa_column_args=(Identity(always=True),),\n primary_key=True,\n nullable=False,\n )\n```\n\n```text\n__slots__\n```\n\n```text\ndict\n```\n\n========================================\n\nComments:\n- You could use `BaseConfig.arbitrary_types_allowed = True` - see fastapi issue 2382\n- Doing that leads to a valid pydantic class, but you'll still get runtime errors both when trying to get a response as well when trying to render the OpenAPI pages, because fastapi doesn't know how to turn a `Foo` instance into json. And since you need to add validators to do that, when you're done you don't need to allow arbitrary types any more because then it's well defined.\n- Actually, the server won't even start: `fastapi.exceptions.FastAPIError: Invalid args for response field! Hint: check that is a valid pydantic field type`\n- Declared global in the main app file (`BaseConfig.arbitrary_types_allowed = True`) the server starts fine for me and returns `foo: x: 1`(minimal example on localhost) - the API definition fails for me as well.. - I just commented because I stumbled over the issue which seems to talk about the same problem...\n- You're right, I wonder why setting arbitrary types globally is so different from setting it on the `Response` class. I'll simplify my answer\n- can you please help with example of Config.json_encoders usage. For example if type was `psycopg2.extras.DateTimeTZRange`\n- In fact, only this line was enough: `BaseConfig.arbitrary_types_allowed = True`\n- If you wind up on this answer, you probably need to simply enable the ORM mode, and map your Pydantic classes to the ORM classes: docs.pydantic.dev/usage/models/…","metadata":{"transformedAt":"2026-08-18T18:32:29.109Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":20,"totalLines":291,"estimatedTokens":1798}}192{"id":"stack-75040507","source":"stackoverflow","questionId":75040507,"title":"How to access FastAPI backend from a different machine/IP on the same local network?","tags":["python","next.js","localhost","ip","fastapi"],"text":"Title: How to access FastAPI backend from a different machine/IP on the same local network?\nTags: python, next.js, localhost, ip, fastapi\nSource: Stack Overflow\n\nQuestion:\nBoth the FastAPI backend and the Next.js frontend are running on `localost`. On the same computer, the frontend makes API calls using `fetch` without any issues. However, on a different computer on the **same** network, e.g., `192.168.x.x`, the frontend runs, but its API calls are no longer working.\n\nI have tried using a proxy as next.js but that still does not work.\n\nFrontend:\n\n```\nexport default function People({setPerson}:PeopleProps) {\n const fetcher = async (url:string) => await axios.get(url).then((res) => res.data);\n const { data, error, isLoading } = useSWR(`${process.env.NEXT_PUBLIC_API}/people`, fetcher);\n if (error) return \"Failed to load...\";\n return (\n <>\n {isLoading? \"Loading...\" :data.map((person: Person) =>\n {person.name} )}\n \n )\n }\n```\n\nThe Next.js app loads the `env.local` file at startup, which contains:\n`NEXT_PUBLIC_API=http://locahost:20002`\n\nBackend:\n\n```\nrom typing import List\nfrom fastapi import APIRouter, Depends\nfrom ..utils.db import get_session as db\nfrom sqlmodel import Session, select\nfrom ..schemas.person import Person, PersonRead\nrouter = APIRouter()\n\n@router.get(\"/people\", response_model = List[PersonRead])\nasync def get_people(sess: Session = Depends(db)):\n res = sess.exec(select(Person)).all()\n return res\n```\n\nThe frontend runs with: `npm run dev`, and outputs\n\n```\nready - started server on 0.0.0.0:3000, url: http://localhost:3000\n```\n\nThe backend runs with: `uvicorn hogar_api.main:app --port=20002 --host=0.0.0.0 --reload`, and outputs:\n\n```\nINFO: Uvicorn running on http://0.0.0.0:20002 (Press CTRL+C to quit)\n```\n\nWhen I open the browser on `http://localhost:3000` *on the same machine* the list of `Person` is displayed on the screen.\n\nWhen I open the browser on `http://192.168.x.x:3000` *on another machine on the same* network, I get the \"Failed to Load...\" message.\n\nWhen I open the FastAPI swagger docs on either machine, the documentation is displayed correctly and all the endpoints work as expected.\n\nCORS look like this:\n\n```\nfrom fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware\n\napp = FastAPI()\n\norigins = [\n \"http://localhost:3000\",\n]\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=origins,\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n```\n\n========================================\n\nTop Answer:\nThis problem stonewalled me for days - I'm using fastapi/uvicorn on Mac, in Python 3.9.\n\nWhen setting the uvicorn host to 0.0.0.0, after startup I checked and found that it only binds to TCP 127.0.0.1:\n\n```\nsudo lsof -PiTCP -sTCP:LISTEN\n```\n\nSo I dug into the uvicorn code, the solution was in this file:\n/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/uvicorn/config.py\n\nSimply change this:\nsock.bind((self.host, self.port))\nto this:\nsock.bind(('0.0.0.0', self.port))\n\nAfter this change I restarted uvicorn and I can access the page from any machine on my network.\n\nHope this helps someone!\n\n========================================\n\nCode:\n```js\nexport default function People({setPerson}:PeopleProps) {\n const fetcher = async (url:string) => await axios.get(url).then((res) => res.data);\n const { data, error, isLoading } = useSWR(`${process.env.NEXT_PUBLIC_API}/people`, fetcher);\n if (error) return <div>\"Failed to load...\"</div>;\n return (\n <>\n {isLoading? \"Loading...\" :data.map((person: Person) =>\n <div key={person.id}> {person.name} </div>)}\n </> \n )\n }\n```\n\n```py\nrom typing import List\nfrom fastapi import APIRouter, Depends\nfrom ..utils.db import get_session as db\nfrom sqlmodel import Session, select\nfrom ..schemas.person import Person, PersonRead\nrouter = APIRouter()\n\n@router.get(\"/people\", response_model = List[PersonRead])\nasync def get_people(sess: Session = Depends(db)):\n res = sess.exec(select(Person)).all()\n return res\n```\n\n```text\nready - started server on 0.0.0.0:3000, url: http://localhost:3000\n```\n\n```text\nINFO: Uvicorn running on http://0.0.0.0:20002 (Press CTRL+C to quit)\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware\n\napp = FastAPI()\n\norigins = [\n \"http://localhost:3000\",\n]\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=origins,\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n```\n\n```text\nlocalost\n```\n\n```text\nfetch\n```\n\n```text\n192.168.x.x\n```\n\n```text\nenv.local\n```\n\n```text\nNEXT_PUBLIC_API=http://locahost:20002\n```\n\n```text\nnpm run dev\n```\n\n```text\nuvicorn hogar_api.main:app --port=20002 --host=0.0.0.0 --reload\n```\n\n```text\nhttp://localhost:3000\n```\n\n```text\nPerson\n```\n\n```text\nhttp://192.168.x.x:3000\n```\n\n```py\nuvicorn main:app --host 0.0.0.0 --port 8000\n```\n\n```py\nif __name__ == '__main__':\n uvicorn.run(app, host='0.0.0.0', port=8000)\n```\n\n```py\norigins = ['http://localhost:3000','http://192.168.178.23:3000']\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=origins,\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n```\n\n```js\nfetch('http://192.168.178.23:8000/people', {...\n```\n\n```js\nfetch('http://localhost:8000/people', {...\n```\n\n```js\nfetch('http://127.0.0.1:8000/people', {...\n```\n\n```text\nhost\n```\n\n```text\n0.0.0.0\n```\n\n```text\nhost\n```\n\n```text\n0.0.0.0\n```\n\n```text\n0.0.0.0\n```\n\n```text\nhost\n```\n\n```text\n192.168.10.2\n```\n\n```text\n10.1.2.5\n```\n\n```text\nhost\n```\n\n```text\n0.0.0.0\n```\n\n```text\n0.0.0.0\n```\n\n```text\nhttp://0.0.0.0:8000\n```\n\n```text\nhttp://192.168.10.2:8000\n```\n\n```text\nhttp://127.0.0.1:8000\n```\n\n```text\nhttp://localhost:8000\n```\n\n```text\nport\n```\n\n```text\nport\n```\n\n```text\nfetch\n```\n\n```text\nport\n```\n\n```text\n192.168.178.23:8000\n```\n\n```text\nJinja2Templates\n```\n\n```text\nhttp://192.168.178.23:8000/\n```\n\n```text\nfetch\n```\n\n```text\nport\n```\n\n```text\nfetch('/people', {...\n```\n\n```text\n127.0.0.1\n```\n\n```text\nlocalhost\n```\n\n```text\nhttp://127.0.0.1:8000/\n```\n\n```text\nfetch\n```\n\n```text\nAccess to fetch at [...] from origin [...] has been blocked by CORS policy...\n```\n\n```text\norigin\n```\n\n```text\norigin\n```\n\n```text\nsudo lsof -PiTCP -sTCP:LISTEN\n```\n\n========================================\n\nComments:\n- Have you properly configured CORS on server side, as described here and here?\n- I updated the text to reflect the process.env content. And CORS should not be an issue since I configured them like the FastAPI docs suggest. I will consider the links you refer to as well.\n- Unfortunately, I can’t open the console on the other machine. I tried with my phone as well and it is also giving an error. True that I need to print the error instead of what I have here.\n- Exactly, that is the problem: the frontend only sees “localhost” even if I connect from 192.168.x.x…\n- Still no luck. I configured CORS with the new origin: `http://192.168.178.23:3000` and enabled an `error.message` display on the screen. On my phone browser, I go to `http://192.168.178.23:3000` and see \"Failed to load... Network Error\"\n- OK. Finally, the trick was adding the new domain to the CORS list of origins AND using that same domain as the address for fetching, ie, loading it in the `env.local` file for the frontend to use\n- @HenryThornton You can find client-server working examples here, as well as here and here\n- for Expo you can do something like this to get the IP of the host machine: `const debuggerHost = Constants.expoConfig?.hostUri;`\n- seems this is no longer needed fortunately!","metadata":{"transformedAt":"2026-08-18T18:32:29.109Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":54,"totalLines":381,"estimatedTokens":1893}}193{"id":"stack-72883838","source":"stackoverflow","questionId":72883838,"title":"Can't connect PostgreSQL database to FastAPI","tags":["python","postgresql","fastapi"],"text":"Title: Can't connect PostgreSQL database to FastAPI\nTags: python, postgresql, fastapi\nSource: Stack Overflow\n\nQuestion:\nSo, hi. Everything works with SQLite, but when I try to add PostgreSQL according to the user's guide on FastAPI, nothing works and I get:\n\n`sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) invalid dsn: invalid connection option \"check_same_thread\"`\n\nMy `database.py` is:\n\n```\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import sessionmaker\n\n#SQLALCHEMY_DATABASE_URL = \"sqlite:///./sql_app.db\"\nSQLALCHEMY_DATABASE_URL = \"postgresql://user:password@postgresserver/db\"\n\nengine = create_engine(\n SQLALCHEMY_DATABASE_URL, connect_args={\"check_same_thread\": False}\n)\nSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)\n\nBase = declarative_base()\n```\n\n========================================\n\nTop Answer:\nSQLAlchemy needs a little bit different dsn. To make sure, use PostgresDsn from pydantic.\n\n```\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.orm import sessionmaker\nfrom pydantic import PostgresDsn\n\nSQLALCHEMY_DATABASE_URI = PostgresDsn.build(\n scheme=\"postgresql\",\n user=\"POSTGRES_USER\",\n password=\"POSTGRES_PASSWORD\",\n host=\"POSTGRES_SERVER\",\n path=f\"/{'POSTGRES_DB' or ''}\",\n)\nengine = create_engine(\n SQLALCHEMY_DATABASE_URI,\n pool_pre_ping=True,\n)\nSessionLocal = sessionmaker(\n autocommit=False,\n autoflush=False,\n bind=engine\n)\ntry:\n db = SessionLocal()\n db.execute(\"SELECT 1\")\nexcept Exception as e:\n raise e\n```\n\n========================================\n\nCode:\n```py\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import sessionmaker\n\n#SQLALCHEMY_DATABASE_URL = \"sqlite:///./sql_app.db\"\nSQLALCHEMY_DATABASE_URL = \"postgresql://user:password@postgresserver/db\"\n\nengine = create_engine(\n SQLALCHEMY_DATABASE_URL, connect_args={\"check_same_thread\": False}\n)\nSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)\n\nBase = declarative_base()\n```\n\n```text\nsqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) invalid dsn: invalid connection option \"check_same_thread\"\n```\n\n```text\ndatabase.py\n```\n\n```text\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import sessionmaker\n\nSQLALCHEMY_DATABASE_URL = \"postgresql://user:password@postgresserver/db\"\n\nengine = create_engine(SQLALCHEMY_DATABASE_URL)\nSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)\n\nBase = declarative_base()\n```\n\n```text\ncheck_same_thread\n```\n\n```text\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.orm import sessionmaker\nfrom pydantic import PostgresDsn\n\nSQLALCHEMY_DATABASE_URI = PostgresDsn.build(\n scheme=\"postgresql\",\n user=\"POSTGRES_USER\",\n password=\"POSTGRES_PASSWORD\",\n host=\"POSTGRES_SERVER\",\n path=f\"/{'POSTGRES_DB' or ''}\",\n)\nengine = create_engine(\n SQLALCHEMY_DATABASE_URI,\n pool_pre_ping=True,\n)\nSessionLocal = sessionmaker(\n autocommit=False,\n autoflush=False,\n bind=engine\n)\ntry:\n db = SessionLocal()\n db.execute(\"SELECT 1\")\nexcept Exception as e:\n raise e\n```\n\n========================================\n\nComments:\n- Thanks for reply! Unfortunately still doesn't work\n- Now it is `sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) could not translate host name \"postgres\" to address: Temporary failure in name resolution`","metadata":{"transformedAt":"2026-08-18T18:32:29.109Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":6,"totalLines":136,"estimatedTokens":861}}194{"id":"stack-73081130","source":"stackoverflow","questionId":73081130,"title":"Python FASTAPI shedule task","tags":["python","fastapi","schedule"],"text":"Title: Python FASTAPI shedule task\nTags: python, fastapi, schedule\nSource: Stack Overflow\n\nQuestion:\nI want to write a task that will only run once a day at 3:30 p.m. with Python FASTAPI. How can I do it?\n\nI tried this but it works all the time.\n\n```\nschedule.every().day.at(\"15:30:00\").do(job2)\n\nwhile True:\n schedule.run_all()\n```\n\n========================================\n\nTop Answer:\nHere is how you can do it with Rocketry. Rocketry is a statement-based scheduler and it integrates well with FastAPI.\n\nLet's say you have a `scheduler.py`. This is where you put your tasks. Content of this file:\n\n```\nfrom rocketry import Rocketry\nfrom rocketry.conds import daily\n\napp = Rocketry()\n\n# Create some tasks:\n\n@app.task(daily.after(\"15:30\"))\ndef do_things():\n ...\n```\n\nThen the FastAPI app, let's call this `api.py`:\n\n```\nfrom fastapi import FastAPI\nfrom scheduler import app as app_rocketry\n\napp = FastAPI()\nsession = app_rocketry.session\n\n# Create some routes:\n\n@app.get(\"/my-route\")\nasync def get_tasks():\n # We can modify/read the Rocketry's runtime session\n return session.tasks\n\n@app.post(\"/my-route\")\nasync def manipulate_session():\n for task in session.tasks:\n ...\n```\n\nAnd then the `main.py` which combines these two and runs them both:\n\n```\nimport asyncio\nimport uvicorn\n\nfrom api import app as app_fastapi\nfrom scheduler import app as app_rocketry\n\nclass Server(uvicorn.Server):\n \"\"\"Customized uvicorn.Server\n\n Uvicorn server overrides signals and we need to include\n Rocketry to the signals.\"\"\"\n def handle_exit(self, sig: int, frame) -> None:\n app_rocketry.session.shut_down()\n return super().handle_exit(sig, frame)\n\nasync def main():\n \"Run scheduler and the API\"\n server = Server(config=uvicorn.Config(app_fastapi, workers=1, loop=\"asyncio\"))\n\n api = asyncio.create_task(server.serve())\n sched = asyncio.create_task(app_rocketry.serve())\n\n await asyncio.wait([sched, api])\n\nif __name__ == \"__main__\":\n asyncio.run(main())\n```\n\nThe two applications can seamlessly communicate with each other. I also made a template which you can just clone: https://github.com/Miksus/rocketry-with-fastapi\n\nRelevant links:\n\n- Documentation\n\n- Source code\n\n========================================\n\nCode:\n```text\nschedule.every().day.at(\"15:30:00\").do(job2)\n\nwhile True:\n schedule.run_all()\n```\n\n```py\nimport schedule\nimport time\n\ndef job():\n print(\"I'm working...\")\n\nschedule.every().day.at(\"15:30:00\").do(job)\n\nwhile True:\n schedule.run_pending()\n```\n\n```text\nschedule.run_all()\n```\n\n```text\nschedule.run_pending()\n```\n\n```text\nfrom rocketry import Rocketry\nfrom rocketry.conds import daily\n\napp = Rocketry()\n\n# Create some tasks:\n\n@app.task(daily.after(\"15:30\"))\ndef do_things():\n ...\n```\n\n```text\nfrom fastapi import FastAPI\nfrom scheduler import app as app_rocketry\n\napp = FastAPI()\nsession = app_rocketry.session\n\n# Create some routes:\n\n@app.get(\"/my-route\")\nasync def get_tasks():\n # We can modify/read the Rocketry's runtime session\n return session.tasks\n\n@app.post(\"/my-route\")\nasync def manipulate_session():\n for task in session.tasks:\n ...\n```\n\n```text\nimport asyncio\nimport uvicorn\n\nfrom api import app as app_fastapi\nfrom scheduler import app as app_rocketry\n\nclass Server(uvicorn.Server):\n \"\"\"Customized uvicorn.Server\n\n Uvicorn server overrides signals and we need to include\n Rocketry to the signals.\"\"\"\n def handle_exit(self, sig: int, frame) -> None:\n app_rocketry.session.shut_down()\n return super().handle_exit(sig, frame)\n\n\nasync def main():\n \"Run scheduler and the API\"\n server = Server(config=uvicorn.Config(app_fastapi, workers=1, loop=\"asyncio\"))\n\n api = asyncio.create_task(server.serve())\n sched = asyncio.create_task(app_rocketry.serve())\n\n await asyncio.wait([sched, api])\n\nif __name__ == \"__main__\":\n asyncio.run(main())\n```\n\n```text\nscheduler.py\n```\n\n```text\napi.py\n```\n\n```text\nmain.py\n```\n\n========================================\n\nComments:\n- Can you had more code so we can run a complete test ?\n- `pip install schedule` Also run this before starting the server.\n- Sadly, Rocketry seems to be a dead project now. It has a dependency conflict with Pydantic 2, which many FastAPI users would already be using.","metadata":{"transformedAt":"2026-08-18T18:32:29.109Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":10,"totalLines":209,"estimatedTokens":1053}}195{"id":"stack-76886257","source":"stackoverflow","questionId":76886257,"title":"How to validate access token from AzureAD in python?","tags":["python","jwt","single-sign-on","fastapi","azure-ad-msal"],"text":"Title: How to validate access token from AzureAD in python?\nTags: python, jwt, single-sign-on, fastapi, azure-ad-msal\nSource: Stack Overflow\n\nQuestion:\nWhat is the recommended way to validate the access token in backend? Any library that handles it?\n\nAnother team has implemented the frontend they send the access token in the Bearer attributed in the header.\n\nI found https://github.com/odwyersoftware/azure-ad-verify-token but it has only 17 Stars. I thought microsoft should have support for it in MSAL (https://github.com/AzureAD/microsoft-authentication-library-for-python) but seems not.\n\nAny suggestions on how to implement it in a secure way? Or any good libs that handles the validation.\n\nI have tried write the code my self but I get problems but worried its not secured and the code got messy. Also tried above lib but should like to have some more popular so its not a security risk.\n\n========================================\n\nTop Answer:\nWe can further simplify the @justin-tanner's code by using PyJWKClient:\n\n```\nimport jwt\nfrom jwt import PyJWKClient\n\ndef token_is_valid(tenant_id, audience, token):\n jwks_url = f\"https://login.microsoftonline.com/{tenant_id}/discovery/v2.0/keys\"\n issuer_url = f\"https://login.microsoftonline.com/{tenant_id}/v2.0\"\n jwks_client = PyJWKClient(\n jwks_url,\n )\n signing_key = jwks_client.get_signing_key_from_jwt(token)\n return jwt.decode(\n token,\n signing_key.key,\n verify=True,\n algorithms=[\"RS256\"],\n audience=audience,\n issuer=issuer_url,\n )\n```\n\n========================================\n\nCode:\n```text\nimport jwt\nimport base64\nfrom cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicNumbers\nfrom cryptography.hazmat.backends import default_backend\nfrom cryptography.hazmat.primitives import serialization\nimport json\nfrom urllib.request import urlopen\n\ndef token_is_valid(tenant_id, client_id, token):\n jwks_url = f\"https://login.microsoftonline.com/{tenant_id}/discovery/v2.0/keys\"\n issuer_url = f\"https://sts.windows.net/{tenant_id}/\"\n audience = f\"api://{client_id}\"\n\n jwks = json.loads(urlopen(jwks_url).read())\n unverified_header = jwt.get_unverified_header(token)\n rsa_key = find_rsa_key(jwks, unverified_header)\n public_key = rsa_pem_from_jwk(rsa_key)\n\n return jwt.decode(\n token,\n public_key,\n verify=True,\n algorithms=[\"RS256\"],\n audience=audience,\n issuer=issuer_url\n )\n\ndef find_rsa_key(jwks, unverified_header):\n for key in jwks[\"keys\"]:\n if key[\"kid\"] == unverified_header[\"kid\"]:\n return {\n \"kty\": key[\"kty\"],\n \"kid\": key[\"kid\"],\n \"use\": key[\"use\"],\n \"n\": key[\"n\"],\n \"e\": key[\"e\"]\n }\n\ndef ensure_bytes(key):\n if isinstance(key, str):\n key = key.encode('utf-8')\n return key\n\n\ndef decode_value(val):\n decoded = base64.urlsafe_b64decode(ensure_bytes(val) + b'==')\n return int.from_bytes(decoded, 'big')\n\n\ndef rsa_pem_from_jwk(jwk):\n return RSAPublicNumbers(\n n=decode_value(jwk['n']),\n e=decode_value(jwk['e'])\n ).public_key(default_backend()).public_bytes(\n encoding=serialization.Encoding.PEM,\n format=serialization.PublicFormat.SubjectPublicKeyInfo\n )\n```\n\n```text\nPyJWT\n```\n\n```text\ncryptography\n```\n\n```text\nissuer_url\n```\n\n```text\naudience\n```\n\n```text\nimport time\nimport jwt\nimport base64\nfrom cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicNumbers\nfrom cryptography.hazmat.backends import default_backend\nfrom cryptography.hazmat.primitives import serialization\nimport json\nfrom urllib.request import urlopen\n\n\nclass OAuth2TokenValidation:\n\n def __init__(self, tenant_id, client_id):\n self.jwks_url = f\"https://login.microsoftonline.com/{tenant_id}/discovery/v2.0/keys\"\n self.issuer_url = f\"https://sts.windows.net/{tenant_id}/\"\n self.audience = f\"api://{client_id}\"\n\n self.jwks = json.loads(urlopen(self.jwks_url).read())\n self.last_jwks_public_key_update = time.time()\n\n def validate_token_and_decode_it(self, token):\n \"\"\"\n :param token: the jwt token to validate\n :return: the decoded token if valid, else raises an exception\n \"\"\"\n\n try:\n unverified_header = jwt.get_unverified_header(token)\n except Exception as e:\n raise Exception(f\"Unable to decode authorization token headers: {e}\")\n\n try:\n rsa_key = OAuth2TokenValidation.find_rsa_key(self.jwks, unverified_header)\n public_key = OAuth2TokenValidation.rsa_pem_from_jwk(rsa_key)\n\n return jwt.decode(\n token,\n public_key,\n verify=True,\n algorithms=[\"RS256\"],\n audience=self.audience,\n issuer=self.issuer_url\n )\n\n except jwt.ExpiredSignatureError:\n raise Exception(\"Token has expired\")\n except jwt.InvalidTokenError:\n raise Exception(\"Invalid token\")\n except Exception as e:\n # update the public key if not fresh and try again\n if int(time.time() - self.last_jwks_public_key_update) > 60:\n self.jwks = json.loads(urlopen(self.jwks_url).read())\n self.last_jwks_public_key_update = time.time()\n return self.validate_token_and_decode_it(token)\n else:\n print(f\"Error validating token: {e}\")\n\n @staticmethod\n def find_rsa_key(jwks, unverified_header):\n for key in jwks[\"keys\"]:\n if key[\"kid\"] == unverified_header[\"kid\"]:\n return {\n \"kty\": key[\"kty\"],\n \"kid\": key[\"kid\"],\n \"use\": key[\"use\"],\n \"n\": key[\"n\"],\n \"e\": key[\"e\"]\n }\n\n @staticmethod\n def ensure_bytes(key):\n if isinstance(key, str):\n key = key.encode('utf-8')\n return key\n\n @staticmethod\n def decode_value(val):\n decoded = base64.urlsafe_b64decode(OAuth2TokenValidation.ensure_bytes(val) + b'==')\n return int.from_bytes(decoded, 'big')\n\n @staticmethod\n def rsa_pem_from_jwk(jwk):\n return RSAPublicNumbers(\n n=OAuth2TokenValidation.decode_value(jwk['n']),\n e=OAuth2TokenValidation.decode_value(jwk['e'])\n ).public_key(default_backend()).public_bytes(\n encoding=serialization.Encoding.PEM,\n format=serialization.PublicFormat.SubjectPublicKeyInfo\n )\n```\n\n```py\nimport jwt\nfrom jwt import PyJWKClient\n\n\ndef token_is_valid(tenant_id, audience, token):\n jwks_url = f\"https://login.microsoftonline.com/{tenant_id}/discovery/v2.0/keys\"\n issuer_url = f\"https://login.microsoftonline.com/{tenant_id}/v2.0\"\n jwks_client = PyJWKClient(\n jwks_url,\n )\n signing_key = jwks_client.get_signing_key_from_jwt(token)\n return jwt.decode(\n token,\n signing_key.key,\n verify=True,\n algorithms=[\"RS256\"],\n audience=audience,\n issuer=issuer_url,\n )\n```\n\n```text\nimport jwt\nfrom jwt import PyJWKClient\nfrom typing import Any\nfrom app.config import ENTRA_TENANT_ID, ENTRA_CLIENT_ID\n\n\ndef token_is_valid(token: str) -> Any:\n tenant_id = ENTRA_TENANT_ID\n audience = f\"api://{ENTRA_CLIENT_ID}\"\n jwks_url = f\"https://login.microsoftonline.com/{tenant_id}/discovery/v2.0/keys\"\n issuer_url = f\"https://sts.windows.net/{tenant_id}/\"\n jwks_client = PyJWKClient(\n jwks_url,\n )\n signing_key = jwks_client.get_signing_key_from_jwt(token=token)\n return jwt.decode(\n token,\n signing_key.key,\n verify=True,\n algorithms=[\"RS256\"],\n audience=audience,\n issuer=issuer_url,\n )\n```\n\n========================================\n\nComments:\n- Notice an open issue asking to better define the usage with a **scope**, and my comment there github.com/Azure-Samples/…\n- Notice the API Audience is equal to the client id and can just be replaced.\n- With these 2 lines it works with an id token instead of an access token ` issuer_url = f\"login.microsoftonline.com{tenant_id}/v2.0\" audience = f\"{client_id}\"`. If I produce the access token with github.com/AzureAD/microsoft-authentication-library-for-js/t‌​ree/… I see this problem stackoverflow.com/questions/74886417/…\n- I have also tested that, if I define app roles in app registration and assign them to users/groups via Enterprise apps blade, I can find the scopes/claims in the roles of the JWT token, validated - as per my comment above - from the **id** token, **not** the access token. Hence, afaics, the id tokens work for both authentication and authorization in the web api.\n- @Giulio Interesting, I've updated my answer to reflect you experience, I kept trying different values for `issuer_url` and `audience` until something worked on my end.\n- I think I found at least two weaknesses. 1. you should add a throw here ``` print(f\"Error validating token: {e}\") raise Exception(\"Error validating token\") ``` 2. you should add a throw here ``` if not rsa_key: raise Exception(\"No matching JWK key for token header kid\") ```\n- also: please mention which jwt library to use because it is not clear from the import","metadata":{"transformedAt":"2026-08-18T18:32:29.109Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":8,"totalLines":270,"estimatedTokens":2310}}196{"id":"stack-74206034","source":"stackoverflow","questionId":74206034,"title":"How do Uvicorn workers work, and how many do I need for a slim machine?","tags":["python","fastapi","worker","uvicorn","asgi"],"text":"Title: How do Uvicorn workers work, and how many do I need for a slim machine?\nTags: python, fastapi, worker, uvicorn, asgi\nSource: Stack Overflow\n\nQuestion:\nThe application I deploy is FastAPI with Uvicorn under K8s.\nWhile trying to understand how I want to Dockerize the application I understood I want to implement Uvicorn without Gunicorn and to add a system of scale up/down by the load of the requests the application is getting.\nI did a lot of load testing and discovered that with the default of 1 Uvicorn worker I'm getting 3.5 RPS, while changing the workers to 8 I can get easly 22 RPS (didn't check for more since its great results for me).\n\nNow what I was expecting regarding the resources is that the CPU that I will have to provide will be with a limit of 8 (I assume every worker works on one process and thread), but I saw only increase in the memory usage, but barley in the CPU. maybe its because the app don't use that much CPU but indeed its possible for it to use more than 1 CPU? so far it didn't used more than one CPU.\n\nHow do Uvicorn workers work? How should I calculate how many workers I need for the app? I didn't find any useful information.\n\nAgain, my goal is to keep a slim machine of 1 cpu, with Autoscaling system.\nhttps://i.sstatic.net/BYZUL.png\n\nhttps://i.sstatic.net/W72vu.png\n\n========================================\n\nTop Answer:\nIn concert with @plunker's answer, if we were instead using synchronous workers with gunicorn (or indeed Apache with modperl or myriad others) the processes timeshare the CPU(s) between them, and each request would be handled one after another as the OS is able to schedule them. The individual process handling a single request blocks the CPU until it has finished and all pending I/O has finished. In this scenario you need precisely as many CPUs as you desire your workers to handle simultaneous requests. With one CPU and any number of workers your case is limited to 3.5 requests per second. Any excess requests are buffered by the control thread up to some limit (e.g. 1000 pending requests).\n\nIf we have asynchronous workers, as soon as an `await` call is made the worker can put the request to sleep and allow the CPU to take up another thread. When the awaited event occurs (e.g. DB responds with data), the thread is requeued. As such an async worker and CPU are unblocked whenever `await` is executed, rather than when the worker completes the request handling.\n\nNetwork requests occur in the domain of milliseconds, whereas the CPU is operating in the domain of nanoseconds, so a single request to a DB or disk can block a CPU for potentially millions of operations.\n\nOutside of substantial processing happening in your worker (generally a bad idea for availability), a single CPU might address all workers' processing demands before the first DB request is answered. That may explain your 8x performance increase over a single worker.\n\n**How many workers can you run on one CPU?**\n\nA contemporary virtualised CPU may have 4-8GB available to it, and memory usage scales linearly with the number of workers after the first. Allowing for growth of a worker over its lifespan as well as leaving some memory for disk caching leads me to recommend not allocating more than 50% of the available memory. This is application specific.\n\nThere are overheads associated with the control thread dispatching traffic, expiring and respawning workers. You might weigh it like another worker in the worst case.\n\nFinally we must consider the weakest part of the system. It might be a database shared with other apps, it might be network bandwidth. Overloading a database can be much more harmful to service quality than limiting throughput via a suboptimal number of workers.\n\nThese combined unknowns make it hard to name a number, as it varies so widely by application and environment. Tools like Apache Benchmark (ab) can be useful for smoking out performance limitations in parallel requests.\n\nYou may wish to have a fixed number of async workers per container in order to squeeze bang-for-buck out of one CPU, but I cannot comment on the relative efficiencies of context switching between containers versus between async worker threads.\n\n========================================\n\nCode:\n```text\n--workers\n```\n\n```text\nmultiprocessing\n```\n\n```text\nawait\n```\n\n```text\nawait\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.109Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":4,"totalLines":59,"estimatedTokens":1086}}197{"id":"stack-74445292","source":"stackoverflow","questionId":74445292,"title":"JWT set did not contain any usable keys","tags":["fastapi","auth0","okta"],"text":"Title: JWT set did not contain any usable keys\nTags: fastapi, auth0, okta\nSource: Stack Overflow\n\nQuestion:\nWhile setting up Auth0 authentication with our okta application from fastapi, we received the following error,\n\n```\njwt.exceptions.PyJWKSetError: The JWK Set did not contain any usable keys\n```\n\nWe followed guidelines as detailed in the following link for the implementation of the fast api authorization with auth0.\n\nhttps://auth0.com/blog/build-and-secure-fastapi-server-with-auth0/\n\nThe following code is used to verify the created token. The given error appears in the first try block of the verify function.\n\n```\nclass VerifyToken():\n\"\"\"Does all the token verification using PyJWT\"\"\"\ndef __init__(self, token):\n self.token = token\n self.config = set_up()\n print(self.config)\n # This gets the JWKS from a given URL and does processing so you can\n # use any of the keys available\n jwks_url = f'https://{self.config[\"DOMAIN\"]}/.well-known/jwks.json'\n self.jwks_client = jwt.PyJWKClient(jwks_url)\ndef verify(self):\n # This gets the 'kid' from the passed token\n try:\n self.signing_key = self.jwks_client.get_signing_key_from_jwt(\n self.token\n ).key\n except jwt.exceptions.PyJWKClientError as error:\n print(error)\n return {\"status\": \"error\", \"msg\": error.__str__()}\n except jwt.exceptions.DecodeError as error:\n return {\"status\": \"error\", \"msg\": error.__str__()}\n try:\n print(self.config)\n payload = jwt.decode(\n self.token,\n self.signing_key,\n algorithms=self.config[\"ALGORITHMS\"],\n audience=self.config[\"API_AUDIENCE\"],\n issuer=self.config[\"ISSUER\"],\n options={\"verify_exp\": False}\n )\n except Exception as e:\n return {\"status\": \"error\", \"message\": str(e)}\n return payload\n```\n\n========================================\n\nCode:\n```text\njwt.exceptions.PyJWKSetError: The JWK Set did not contain any usable keys\n```\n\n```text\nclass VerifyToken():\n\"\"\"Does all the token verification using PyJWT\"\"\"\ndef __init__(self, token):\n self.token = token\n self.config = set_up()\n print(self.config)\n # This gets the JWKS from a given URL and does processing so you can\n # use any of the keys available\n jwks_url = f'https://{self.config[\"DOMAIN\"]}/.well-known/jwks.json'\n self.jwks_client = jwt.PyJWKClient(jwks_url)\ndef verify(self):\n # This gets the 'kid' from the passed token\n try:\n self.signing_key = self.jwks_client.get_signing_key_from_jwt(\n self.token\n ).key\n except jwt.exceptions.PyJWKClientError as error:\n print(error)\n return {\"status\": \"error\", \"msg\": error.__str__()}\n except jwt.exceptions.DecodeError as error:\n return {\"status\": \"error\", \"msg\": error.__str__()}\n try:\n print(self.config)\n payload = jwt.decode(\n self.token,\n self.signing_key,\n algorithms=self.config[\"ALGORITHMS\"],\n audience=self.config[\"API_AUDIENCE\"],\n issuer=self.config[\"ISSUER\"],\n options={\"verify_exp\": False}\n )\n except Exception as e:\n return {\"status\": \"error\", \"message\": str(e)}\n return payload\n```\n\n```text\npip install pyjwt[crypto]\n```\n\n========================================\n\nComments:\n- Most likely, The *jwks_url* URL is invalid and does not return a JSON object with a `keys` entry.\n- I wish jwt.PyJWKClient could throw a much friendlier exception with a message that you crypto is required.","metadata":{"transformedAt":"2026-08-18T18:32:29.109Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":3,"totalLines":107,"estimatedTokens":843}}198{"id":"stack-65591630","source":"stackoverflow","questionId":65591630,"title":"FastAPI as a Windows service","tags":["python","windows-services","fastapi","nssm","uvicorn"],"text":"Title: FastAPI as a Windows service\nTags: python, windows-services, fastapi, nssm, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI am trying to run FastAPI as a windows service.Couldn't find any documentation or any article to run Uvicorn as a Window's service.\nI tried using NSSM as well but my windows service stops.\n\n========================================\n\nTop Answer:\nExpanding a bit on the other answer, there are a few different ways to run FastAPI as a Windows Service (which generalizes to being able to run any Python app as a Windows Service). The most common ways I have found are:\n\n- Use NSSM\n\n- Use one of the officially documented techniques here.\n\nAfter trying a few of them out, I found NSSM to be by far the easiest and most effective method. Basic steps below:\n\n- Add a `__main__` entry point to your FastAPI app that will be called by the Windows Service. The FastAPI deployment guide has helpful info on the various parameters. You probably want to tweak your \"workers\" variable based on expected load. Example (assumes your main FastAPI file is named `main.py`):\n\n```\nif __name__ == \"__main__\":\n uvicorn.run(\"main:app\", host=\"127.0.0.1\", port=8000, workers=4)\n```\n\nInstall Python on the Windows machine if it isn't already there. Also download nssm.exe\n\nTest out your app on the Windows box by running `py main.py`. If it starts up and runs then you are good to deploy as a windows service.\n\nCreate the service using nssm:\n\n```\nnssm install main.py \nnssm set AppDirectory \nnssm set Description \nnssm start \n```\n\nIf all is well then it should be up and running. A few other commenters above have issues with the app starting, which is likely because the AppDirectory was not set so the files could not be found.\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nimport uvicorn\n\napp = FastAPI()\n\n\n@app.get(\"/\")\ndef read_root():\n return {\"Hello\": \"World\"}\n\nif __name__ == \"__main__\":\n uvicorn.run(\"main:app\", host=\"127.0.0.1\", port=5000, log_level=\"info\")\n```\n\n```text\nnssm.exe install \"FastAPIWindowsService\" \"C:\\Scripts\\FastAPIWindowsService\\venv\\Scripts\\python.exe\" \"C:\\Scripts\\FastAPIWindowsService\\src\\main.py\"\n```\n\n```text\ncall venv\\Scripts\\activate.bat\ncall python src\\main.py\n```\n\n```text\nuvicorn main:app --reload\n```\n\n```text\nuvicorn.run(app, **config)\n```\n\n```text\nnssm install\n```\n\n```text\nrun_app.bat\n```\n\n```text\nnssm install\n```\n\n```py\nif __name__ == \"__main__\":\n uvicorn.run(\"main:app\", host=\"127.0.0.1\", port=8000, workers=4)\n```\n\n```text\nnssm install <windows service name> <python.exe path> main.py \nnssm set <windows service name> AppDirectory <root directory of app> \nnssm set <windows service name> Description <app description>\nnssm start <windows service name>\n```\n\n```text\n__main__\n```\n\n```text\nmain.py\n```\n\n```text\npy main.py\n```\n\n```none\nif __name__ == '__main__':\n multiprocessing.freeze_support() # For Windows support\n uvicorn.run(app, host=\"0.0.0.0\", port=8000, reload=False, workers=1)\n```\n\n```text\npyinstaller\n```\n\n```text\npyinstaller\n```\n\n```text\nuvicorn\n```\n\n```text\nmultiprocessing.freeze_support()\n```\n\n```text\npyinstaller path/to/main.py --collect-submodules application --onefile --name <filename>\n```\n\n```text\n./build\n```\n\n```text\n./dist\n```\n\n```text\n./dist\n```\n\n```text\nnssm install <ServiceName>\n```\n\n========================================\n\nComments:\n- Welcome to StackOverflow. Others may be able to help you better if you can include example code of what you are trying to accomplish and what you expect the result to be. See stackoverflow.com/help/how-to-ask for additional guidance.\n- On start of the service I got this error pup-up message: \"Windows could not start the 'servicename' on Local Computer. For more info, review the System Event Log. In the System Event Log it says: \"The service terminated unexpectedly. The system cannot find the path specified\". However, I run nssm edit 'servicename' and see the path is there.\n- this service is created, but never starts\n- what if I have a virtual environment, will this still work?\n- @sffgsfgs I've updated my answer to better reflect this: my go-to method for using a virtual environment with NSSM is to use a bat-file to activate and run my script.\n- Within the bat I had to run Python as \"call venv\\Scripts\\python.exe myApp.py\"","metadata":{"transformedAt":"2026-08-18T18:32:29.109Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":23,"totalLines":163,"estimatedTokens":1075}}199{"id":"stack-68181782","source":"stackoverflow","questionId":68181782,"title":"How to run FastAPI on apache2?","tags":["python-3.x","apache2","gunicorn","fastapi","asgi"],"text":"Title: How to run FastAPI on apache2?\nTags: python-3.x, apache2, gunicorn, fastapi, asgi\nSource: Stack Overflow\n\nQuestion:\nI've developed a FastAPI app that will act as a wrapper that receives SMS requests and call the SMS API to send SMS and now I'm ready to deploy it. This is the code:\n\n```\nimport logging\n\nimport uvicorn\nfrom fastapi import FastAPI, HTTPException\nfrom pydantic import BaseModel\nfrom fastapi.middleware.trustedhost import TrustedHostMiddleware\n\nimport verifier\n\nlogging.basicConfig(\n format='%(asctime)s - %(funcName)s - %(levelname)s - %(message)s',\n level=logging.INFO\n)\n\n# get logger\nlogger = logging.getLogger(__name__)\n\nbot_verifier = None\n\nclass DataForBot(BaseModel):\n number: str\n msg_txt: str\n\ndef get_application():\n app = FastAPI(title='bot_wrapper', version=\"1.0.0\")\n\n return app\n\napp = get_application()\n\n@app.on_event(\"startup\")\nasync def startup_event():\n global bot_verifier\n try:\n bot_verifier = await verifier.Verifier.create()\n except Exception as e:\n logger.error(f\"exception occured during bot creation -- {e}\", exc_info=True)\n\n@app.post('/telegram_sender/')\nasync def send_telegram_msg(data_for_bot: DataForBot):\n global bot_verifier\n if not bot_verifier:\n bot_verifier = await verifier.Verifier.create()\n else:\n dict_data = data_for_bot.dict()\n try:\n if await bot_verifier.send_via_telegram(dict_data):\n return {'status': \"success\", 'data': data_for_bot}\n else:\n raise HTTPException(status_code=404, detail=\"unable to send via telegram, perhaps user has not started the bot\")\n except Exception as e:\n logger.error(f\"{e}\", exc_info=True)\n raise HTTPException(status_code=500, detail=\"Something went wrong, please contact server admin\")\n```\n\nI want to deploy it on apache, as it is the only thing I can get my hand onto in my country. I'm using Python 3.8.9 with FastAPI 0.65.2 and apache/2.4.29, but for the life of me I can't get it to work. I've written an apache conf file and enabled that as such:\n\n```\n\n ServerName gargarsa.sms.local\n ServerAdmin webmaster@localhost\n ServerAlias gargarsa.sms.local\n \n DocumentRoot /var/www/verify_bot_api/\n ServerAlias gargarsa.sms.local\n\n \n Order deny,allow\n Allow from all\n \n\n ErrorLog ${APACHE_LOG_DIR}/gargarsa.sms.local-error.log\n LogLevel debug\n CustomLog ${APACHE_LOG_DIR}/gargarsa.sms.local-access.log combined\n\n```\n\nbut no avail.\n\nI tried running gunicorn via a screen session but I couldn't access it either.\n\nI tried running it programmatically as such but no avail:\n\n```\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n```\n\nI understand this is a very broad way to ask, but I'm truly stumped.\n\nHow do I run an API built using FastAPI on Apache2?\n\nThank you for your assistance.\n\n========================================\n\nTop Answer:\nForget everything. Here is a simple guide.\n\nAssuming there is your virtual env called `venv`. And we have apache installed in place on linux.\n\nRestart Apache for a fresh start\n\n```\nsudo systemctl restart apache2\n```\n\n### **1. Create a Systemd Service for Uvicorn**\n\nYou need Uvicorn to keep running in the background. Set up a **Systemd service** to manage your FastAPI app:\n\nCreate a new service file:\n\n```\nsudo nano /etc/systemd/system/fastapi.service\n```\n\nAdd the following configuration (adjust paths as necessary):\n\n```\n[Unit]\nDescription=FastAPI hosted application\nAfter=network.target\n\n[Service]\n# User and group for running the service\nUser=root\nGroup=root\n\n# Working directory of your FastAPI project\nWorkingDirectory=/path/to/fastapi/app\n\n# Activate the virtual environment\nEnvironment=\"PATH=/path/to/venv/bin\"\n\n# Start the FastAPI application with Uvicorn\nExecStart=/path/to/venv/bin/uvicorn api:app --host 0.0.0.0 --port 1234 --workers 9\n\n# Graceful reload and stop commands\nExecReload=/bin/kill -s HUP $MAINPID\nExecStop=/bin/kill -s TERM $MAINPID\n\n# Restart policy and security\nRestart=always\nPrivateTmp=true\n\n[Install]\nWantedBy=multi-user.target\n```\n\nReload Systemd and start your service:\n\n```\nsudo systemctl daemon-reload\nsudo systemctl start fastapi.service\nsudo systemctl enable fastapi.service\n```\n\nVerify that Uvicorn is running:\n\n```\nsudo systemctl status fastapi.service\n```\n\n### **2. Configure Apache**\n\nCreate a new Apache configuration file for your FastAPI app:\n\n```\nsudo nano /etc/apache2/sites-available/fastapi.conf\n```\n\nAdd the following content:\n\n```\n\n ServerName yourdomain.com\n ServerAdmin your_email@domain.com\n\n ProxyPreserveHost On\n ProxyPass / http://127.0.0.1:8000/\n ProxyPassReverse / http://127.0.0.1:8000/\n\n ErrorLog ${APACHE_LOG_DIR}/fastapi-error.log\n CustomLog ${APACHE_LOG_DIR}/fastapi-access.log combined\n\n```\n\n- Replace `yourdomain.com` with your domain name (or leave as `localhost` for testing).\n\n- This configuration proxies requests from Apache (port 80) to Uvicorn (port 8000).\n\nEnable the site and reload Apache:\n\n```\nsudo a2ensite fastapi.conf\nsudo systemctl reload apache2\n```\n\n### **3. Test Your Deployment**\n\n- Open your browser and navigate to your server’s IP address or domain (e.g., `http://yourdomain.com` or `http://127.0.0.1`).\n\n- You should see your FastAPI app responding!\n\nThis is more than enough!!\n\n========================================\n\nCode:\n```py\nimport logging\n\nimport uvicorn\nfrom fastapi import FastAPI, HTTPException\nfrom pydantic import BaseModel\nfrom fastapi.middleware.trustedhost import TrustedHostMiddleware\n\nimport verifier\n\nlogging.basicConfig(\n format='%(asctime)s - %(funcName)s - %(levelname)s - %(message)s',\n level=logging.INFO\n)\n\n# get logger\nlogger = logging.getLogger(__name__)\n\n\nbot_verifier = None\n\n\nclass DataForBot(BaseModel):\n number: str\n msg_txt: str\n\n\ndef get_application():\n app = FastAPI(title='bot_wrapper', version=\"1.0.0\")\n\n return app\n\n\napp = get_application()\n\n\n@app.on_event(\"startup\")\nasync def startup_event():\n global bot_verifier\n try:\n bot_verifier = await verifier.Verifier.create()\n except Exception as e:\n logger.error(f\"exception occured during bot creation -- {e}\", exc_info=True)\n\n\n@app.post('/telegram_sender/')\nasync def send_telegram_msg(data_for_bot: DataForBot):\n global bot_verifier\n if not bot_verifier:\n bot_verifier = await verifier.Verifier.create()\n else:\n dict_data = data_for_bot.dict()\n try:\n if await bot_verifier.send_via_telegram(dict_data):\n return {'status': \"success\", 'data': data_for_bot}\n else:\n raise HTTPException(status_code=404, detail=\"unable to send via telegram, perhaps user has not started the bot\")\n except Exception as e:\n logger.error(f\"{e}\", exc_info=True)\n raise HTTPException(status_code=500, detail=\"Something went wrong, please contact server admin\")\n```\n\n```none\n<VirtualHost *:80>\n ServerName gargarsa.sms.local\n ServerAdmin webmaster@localhost\n ServerAlias gargarsa.sms.local\n \n DocumentRoot /var/www/verify_bot_api/\n ServerAlias gargarsa.sms.local\n\n <Directory /var/www/verify_bot_api/src/app/>\n Order deny,allow\n Allow from all\n </Directory>\n\n ErrorLog ${APACHE_LOG_DIR}/gargarsa.sms.local-error.log\n LogLevel debug\n CustomLog ${APACHE_LOG_DIR}/gargarsa.sms.local-access.log combined\n</VirtualHost>\n```\n\n```py\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n```\n\n```text\n<VirtualHost *:80>\n # The ServerName directive sets the request scheme, hostname and port that\n # the server uses to identify itself. This is used when creating\n # redirection URLs. In the context of virtual hosts, the ServerName\n # specifies what hostname must appear in the request's Host: header to\n # match this virtual host. For the default virtual host (this file) this\n # value is not decisive as it is used as a last resort host regardless.\n # However, you must set it for any further virtual host explicitly.\n #ServerName www.example.com\n\n ServerName server-name\n ServerAdmin webmaster@localhost\n ServerAlias server-alias\n \n #DocumentRoot /document/root/\n\n <Proxy *>\n AuthType none\n AuthBasicAuthoritative Off\n SetEnv proxy-chain-auth On\n Order allow,deny\n Allow from all\n </Proxy>\n\n ProxyPass / http://127.0.0.1:port/\n ProxyPassReverse / http://127.0.0.1:port/\n #ProxyPass /api http://127.0.0.1:port/api\n #ProxyPassReverse /api http://127.0.0.1:port/api\n\n <Directory /document/root/>\n Order deny,allow\n Allow from all\n </Directory>\n\n # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,\n # error, crit, alert, emerg.\n # It is also possible to configure the loglevel for particular\n # modules, e.g.\n #LogLevel info ssl:warn\n\n ErrorLog ${APACHE_LOG_DIR}/server-error.log\n LogLevel debug\n CustomLog ${APACHE_LOG_DIR}/server-access.log combined\n\n # For most configuration files from conf-available/, which are\n # enabled or disabled at a global level, it is possible to\n # include a line for only one particular virtual host. For example the\n # following line enables the CGI configuration for this host only\n # after it has been globally disabled with \"a2disconf\".\n #Include conf-available/serve-cgi-bin.conf\n</VirtualHost>\n```\n\n```py\ngunicorn api:app -w 1 -k uvicorn.workers.UvicornWorker -b \"127.0.0.1:port\"\n```\n\n```bash\nsudo systemctl restart apache2\n```\n\n```bash\nsudo nano /etc/systemd/system/fastapi.service\n```\n\n```ini\n[Unit]\nDescription=FastAPI hosted application\nAfter=network.target\n\n[Service]\n# User and group for running the service\nUser=root\nGroup=root\n\n# Working directory of your FastAPI project\nWorkingDirectory=/path/to/fastapi/app\n\n# Activate the virtual environment\nEnvironment=\"PATH=/path/to/venv/bin\"\n\n# Start the FastAPI application with Uvicorn\nExecStart=/path/to/venv/bin/uvicorn api:app --host 0.0.0.0 --port 1234 --workers 9\n\n# Graceful reload and stop commands\nExecReload=/bin/kill -s HUP $MAINPID\nExecStop=/bin/kill -s TERM $MAINPID\n\n# Restart policy and security\nRestart=always\nPrivateTmp=true\n\n[Install]\nWantedBy=multi-user.target\n```\n\n```bash\nsudo systemctl daemon-reload\nsudo systemctl start fastapi.service\nsudo systemctl enable fastapi.service\n```\n\n```bash\nsudo systemctl status fastapi.service\n```\n\n```bash\nsudo nano /etc/apache2/sites-available/fastapi.conf\n```\n\n```none\n<VirtualHost *:80>\n ServerName yourdomain.com\n ServerAdmin your_email@domain.com\n\n ProxyPreserveHost On\n ProxyPass / http://127.0.0.1:8000/\n ProxyPassReverse / http://127.0.0.1:8000/\n\n ErrorLog ${APACHE_LOG_DIR}/fastapi-error.log\n CustomLog ${APACHE_LOG_DIR}/fastapi-access.log combined\n</VirtualHost>\n```\n\n```bash\nsudo a2ensite fastapi.conf\nsudo systemctl reload apache2\n```\n\n```text\nvenv\n```\n\n```text\nyourdomain.com\n```\n\n```text\nlocalhost\n```\n\n```text\nhttp://yourdomain.com\n```\n\n```text\nhttp://127.0.0.1\n```\n\n========================================\n\nComments:\n- Someone can help me with this error? !!! !!! WARNING: configuration file should have a valid Python extension. !!!\n- @MESABO without seeing your code, I can only guess. Perhaps it can't find the python path? or it can't find your virtual environment?\n- @MESABO and it's best to ask your own question instead of commenting on another\n- Most recent archived reference: web.archive.org/web/20221226034523/https://www.vioan.eu/blog‌​/…\n- Can you please explain this? I understand that FastAPI will not run on WSGI servers and only run on ASGI servers. What I dont understand is what you wrote about gunicorn, how it run FastAPI\n- thanks bro but you gotta remember that was more than 3 years ago.\n- :) Helps anyways!","metadata":{"transformedAt":"2026-08-18T18:32:29.109Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":18,"totalLines":465,"estimatedTokens":2904}}200{"id":"stack-70302056","source":"stackoverflow","questionId":70302056,"title":"Define a Pydantic (nested) model","tags":["python","json","fastapi","pydantic"],"text":"Title: Define a Pydantic (nested) model\nTags: python, json, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nIf I use GET (given an id) I get a JSON like:\n\n```\n{\n \"data\": {\n \"id\": \"81\",\n \"ks\": {\n \"k1\": 25,\n \"k2\": 5\n },\n \"items\": [\n {\n \"id\": 1,\n \"name\": \"John\",\n \"surname\": \"Smith\"\n },\n {\n \"id\": 2,\n \"name\": \"Jane\",\n \"surname\": \"Doe\"\n }\n ]\n },\n \"server-time\": \"2021-12-09 14:18:40\"\n}\n```\n\nwith the particular case (if id does not exist):\n\n```\n{\n \"data\": {\n \"id\": -1,\n \"ks\": \"\",\n \"items\": []\n },\n \"server-time\": \"2021-12-10 09:35:22\"\n}\n```\n\nI would like to create a Pydantic model for managing this data structure (I mean to formally define these objects).\nWhat is the smartest way to manage this data structure by creating classes (possibly nested)?\n\n========================================\n\nTop Answer:\nI recommend going through the official tutorial for an in-depth look at how the framework handles data model creation and validation with pydantic.\n\nTo answer your question:\n\n```\nfrom datetime import datetime\nfrom typing import List\nfrom pydantic import BaseModel\n\nclass K(BaseModel):\n k1: int\n k2: int\n\nclass Item(BaseModel):\n id: int\n name: str\n surname: str\n\nclass DataModel(BaseModel):\n id: int = -1\n ks: K = None\n items: List[Item] = []\n server_time: datetime = datetime.now()\n```\n\n========================================\n\nCode:\n```text\n{\n \"data\": {\n \"id\": \"81\",\n \"ks\": {\n \"k1\": 25,\n \"k2\": 5\n },\n \"items\": [\n {\n \"id\": 1,\n \"name\": \"John\",\n \"surname\": \"Smith\"\n },\n {\n \"id\": 2,\n \"name\": \"Jane\",\n \"surname\": \"Doe\"\n }\n ]\n },\n \"server-time\": \"2021-12-09 14:18:40\"\n}\n```\n\n```text\n{\n \"data\": {\n \"id\": -1,\n \"ks\": \"\",\n \"items\": []\n },\n \"server-time\": \"2021-12-10 09:35:22\"\n}\n```\n\n```py\nfrom __future__ import annotations\n\nfrom dataclasses import dataclass\nfrom datetime import datetime\n\nfrom dataclass_wizard import fromdict\n\n\n@dataclass\nclass Something:\n data: Data\n # or simply:\n # server_time: str\n server_time: datetime\n\n\n@dataclass\nclass Data:\n id: int\n ks: dict[str, int]\n items: list[Person]\n\n\n@dataclass\nclass Person:\n id: int\n name: str\n surname: str\n\n\n# note: data is defined in the OP above\ninput_data = ...\n\nprint(fromdict(Something, input_data))\n```\n\n```text\nSomething(data=Data(id=81, ks={'k1': 25, 'k2': 5}, items=[Person(id=1, name='John', surname='Smith'), Person(id=2, name='Jane', surname='Doe')]), server_time=datetime.datetime(2021, 12, 9, 14, 18, 40))\n```\n\n```text\npydantic\n```\n\n```text\ndataclass-wizard\n```\n\n```text\nserver-time\n```\n\n```py\nfrom typing import List\nfrom pydantic import BaseModel\n\nclass Data(BaseModel):\n id: int\n ks: str\n items: List[str]\n\nclass Something(BaseModel):\n data: Data\n # you can replace it by a pydantic time type that fit your need\n server_time: str = Field(alias=\"server-time\")\n```\n\n```text\nfrom pydantic import BaseModel\n\nclass User(BaseModel):\n id: int\n name = \"Jane Doe\"\n```\n\n```text\nfrom datetime import datetime\nfrom typing import List\nfrom pydantic import BaseModel\n\n\nclass K(BaseModel):\n k1: int\n k2: int\n\n\nclass Item(BaseModel):\n id: int\n name: str\n surname: str\n\n\nclass DataModel(BaseModel):\n id: int = -1\n ks: K = None\n items: List[Item] = []\n server_time: datetime = datetime.now()\n```\n\n========================================\n\nComments:\n- The question was not asking for *any* kind of Pydantic model. The question had a specific sample input that required *nested* Pydantic models.\n- So does `input_data` exactly match the first JSON I defined in my question? To get a JSON from a object `Something` and vice versa should we use `asdict()` and `fromdict()` respectively?\n- @LJG Yes thats correct, the `input_data` should match the JSON from above. I noted that your JSON data in this case can be defined simply as a `dict` object. To get a JSON string, if that is the intention, you would have to call `json.dumps` on the `asdict` result, however if it is more convenient, you can subclass from the JSONWizard mixin class as mentioned in docs, and then can simply use the `to_json()` method to directly convert an instance to a JSON string.\n- Take into account that, as defined, the `server_time` default value is a fixed value shared between all instances of the `DataModel` class. If you expect each instance to be given a new `datetime.now()` value when you create it without an explicit `server_time` value, you have to use `server_time: datetime = Field(default_factory=datetime.now)` here.\n- Unpopular opinion, but the flexibility for this doesn't look good. I feel like TypeScript's Zod has better DX and flexibility for defining nested objects like this. Wondering if Python has a similar library.","metadata":{"transformedAt":"2026-08-18T18:32:29.109Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":10,"totalLines":223,"estimatedTokens":1222}}201{"id":"stack-73141350","source":"stackoverflow","questionId":73141350,"title":"Override global dependency for certain endpoints in FastAPI","tags":["python","authentication","fastapi"],"text":"Title: Override global dependency for certain endpoints in FastAPI\nTags: python, authentication, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have a FastAPI server that communicates with a web app. My web app also has 2 types of users, Users (non-admins) and Admins. I added a global dependency to FastAPI to verify the user. I want the verify dependency to only allow Admins to access endpoints by default, and have some decorator (or something similar) to allow non-admins to access certain routes. This way, no one accidentally creates a public route that is supposed to be only for admins.\n\n```\ndef verify_token(request: Request):\n # make sure the user's auth token is valid\n # retrieve the user's details from the database\n # make sure user is Admin, otherwise throw HTTP exception\n return True\n \n app = FastAPI(\n title=\"My App\",\n dependencies=[Depends(verify_token)]\n )\n \n @app.get(/admins_only)\n def admins_only():\n # this works well!\n return {'result': 2}\n \n @app.get(/non_admin_route)\n def non_admin_route():\n # this doesn't work because verify_token\n # only allows admins by default, but it should\n # be accessible to non admins\n return {'result': 1}\n```\n\n========================================\n\nCode:\n```text\ndef verify_token(request: Request):\n # make sure the user's auth token is valid\n # retrieve the user's details from the database\n # make sure user is Admin, otherwise throw HTTP exception\n return True\n \n app = FastAPI(\n title=\"My App\",\n dependencies=[Depends(verify_token)]\n )\n \n @app.get(/admins_only)\n def admins_only():\n # this works well!\n return {'result': 2}\n \n @app.get(/non_admin_route)\n def non_admin_route():\n # this doesn't work because verify_token\n # only allows admins by default, but it should\n # be accessible to non admins\n return {'result': 1}\n```\n\n```py\nfrom fastapi import APIRouter, FastAPI, Request, Depends\n\ndef verify_token(request: Request):\n # make sure the user's auth token is valid\n # retrieve the user's details from the database\n # make sure user is Admin, otherwise throw HTTP exception\n return True\n \napp = FastAPI(\n title=\"My App\",\n )\n \nonly_admin_router = APIRouter(\n tags=[\"forAdmins\"],\n dependencies=[Depends(verify_token)]\n)\n\nall_users_router = APIRouter(tags=\"forEverybody\")\n\n@only_admin_router.get(\"/admins_only\")\ndef admins_only():\n # this will only work if verify doesn't raise.\n return {'result': 2}\n \n@all_users_router.get(\"/non_admin_route\")\ndef non_admin_route():\n #this will work for all users, verify will not be called.\n return {'result': 1}\n\napp.include_router(only_admin_router)\napp.include_router(all_users_router)\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.109Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":2,"totalLines":93,"estimatedTokens":694}}202{"id":"stack-61872923","source":"stackoverflow","questionId":61872923,"title":"supporting both form and json encoded bodys with FastAPI","tags":["python","http","fastapi"],"text":"Title: supporting both form and json encoded bodys with FastAPI\nTags: python, http, fastapi\nSource: Stack Overflow\n\nQuestion:\nI've been using FastAPI to create an HTTP based API. It currently supports JSON encoded parameters, but I'd also like to support `form-urlencoded` (and ideally even `form-data`) parameters at the same URL.\n\nFollowing on Nikita's answer I can get separate urls working with:\n\n```\nfrom typing import Optional\nfrom fastapi import FastAPI, Body, Form, Depends\nfrom pydantic import BaseModel\n\nclass MyItem(BaseModel):\n id: Optional[int] = None\n txt: str\n\n @classmethod\n def as_form(cls, id: Optional[int] = Form(None), txt: str = Form(...)) -> 'MyItem':\n return cls(id=id, txt=txt)\n\napp = FastAPI()\n\n@app.post(\"/form\")\nasync def form_endpoint(item: MyItem = Depends(MyItem.as_form)):\n print(\"got item =\", repr(item))\n return \"ok\"\n\n@app.post(\"/json\")\nasync def json_endpoint(item: MyItem = Body(...)):\n print(\"got item =\", repr(item))\n return \"ok\"\n```\n\nand I can test these using `curl` by doing:\n\n```\ncurl -X POST \"http://localhost:8000/form\" -d 'txt=test'\n```\n\nand\n\n```\ncurl -sS -X POST \"http://localhost:8000/json\" -H \"Content-Type: application/json\" -d '{\"txt\":\"test\"}'\n```\n\nIt seems like it would be nicer to have a single URL that accepts both content-types and have the model parsed out appropriately. But the above code currently fails with either:\n\n```\n{\"detail\":[{\"loc\":[\"body\",\"txt\"],\"msg\":\"field required\",\"type\":\"value_error.missing\"}]}\n```\n\nor\n\n```\n{\"detail\":\"There was an error parsing the body\"}\n```\n\nif I post to the \"wrong\" endpoint, e.g. form encoding posted to `/json`. \n\nFor bonus points; I'd also like to support `form-data` encoded parameters as it seems related (my `txt` can get rather long in practice), but might need to turn it into another question if it's sufficiently different.\n\n========================================\n\nCode:\n```text\nfrom typing import Optional\nfrom fastapi import FastAPI, Body, Form, Depends\nfrom pydantic import BaseModel\n\nclass MyItem(BaseModel):\n id: Optional[int] = None\n txt: str\n\n @classmethod\n def as_form(cls, id: Optional[int] = Form(None), txt: str = Form(...)) -> 'MyItem':\n return cls(id=id, txt=txt)\n\napp = FastAPI()\n\n@app.post(\"/form\")\nasync def form_endpoint(item: MyItem = Depends(MyItem.as_form)):\n print(\"got item =\", repr(item))\n return \"ok\"\n\n@app.post(\"/json\")\nasync def json_endpoint(item: MyItem = Body(...)):\n print(\"got item =\", repr(item))\n return \"ok\"\n```\n\n```sh\ncurl -X POST \"http://localhost:8000/form\" -d 'txt=test'\n```\n\n```sh\ncurl -sS -X POST \"http://localhost:8000/json\" -H \"Content-Type: application/json\" -d '{\"txt\":\"test\"}'\n```\n\n```text\n{\"detail\":[{\"loc\":[\"body\",\"txt\"],\"msg\":\"field required\",\"type\":\"value_error.missing\"}]}\n```\n\n```text\n{\"detail\":\"There was an error parsing the body\"}\n```\n\n```text\nform-urlencoded\n```\n\n```text\nform-data\n```\n\n```text\ncurl\n```\n\n```text\n/json\n```\n\n```text\nform-data\n```\n\n```text\ntxt\n```\n\n```py\n@app.post('/')\nasync def route(req: Request) -> Response:\n if req.headers['Content-Type'] == 'application/json':\n item = MyItem(** await req.json())\n elif req.headers['Content-Type'] == 'multipart/form-data':\n item = MyItem(** await req.form())\n elif req.headers['Content-Type'] == 'application/x-www-form-urlencoded':\n item = MyItem(** await req.form())\n return Response(content=item.json())\n```\n\n========================================\n\nComments:\n- Better to use `req.headers['Content-Type'].startswith('application/json')` to check, and raise exception if later parse fails. Because your clients may send requests with Content-Type like `\"application/json;charset=UTF-8 \"` or `\"multipart/form-data; boundary=----xxxxxxx\"`.","metadata":{"transformedAt":"2026-08-18T18:32:29.110Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":12,"totalLines":148,"estimatedTokens":934}}203{"id":"stack-71470236","source":"stackoverflow","questionId":71470236,"title":"POST request response 422 error {'detail': [{'loc': ['body'], 'msg': 'value is not a valid dict', 'type': 'type_error.dict'}]}","tags":["python","http-post","fastapi","pydantic","http-status-code-422"],"text":"Title: POST request response 422 error {'detail': [{'loc': ['body'], 'msg': 'value is not a valid dict', 'type': 'type_error.dict'}]}\nTags: python, http-post, fastapi, pydantic, http-status-code-422\nSource: Stack Overflow\n\nQuestion:\nMy `POST` request continues to fail with `422` response, even though valid `JSON` is being sent. I am trying to create a web app that receives an uploaded text file with various genetic markers and sends it to the tensorflow model to make a cancer survival prediction. The link to the github project can be found here.\n\nHere is the `POST` request:\n\n```\ndf_json = dataframe.to_json(orient='records')\n prediction = requests.post('http://backend:8080/prediction/', json=json.loads(df_json), headers={\"Content-Type\": \"application/json\"})\n```\n\nAnd here is the pydantic model along with the API endpoint:\n\n```\nclass Userdata(BaseModel):\nRPPA_HSPA1A : float\nRPPA_XIAP : float\nRPPA_CASP7 : float\nRPPA_ERBB3 :float\nRPPA_SMAD1 : float\nRPPA_SYK : float\nRPPA_STAT5A : float\nRPPA_CD20 : float\nRPPA_AKT1_Akt :float\nRPPA_BAD : float\nRPPA_PARP1 : float\nRPPA_MSH2 : float\nRPPA_MSH6 : float\nRPPA_ACACA : float\nRPPA_COL6A1 : float\nRPPA_PTCH1 : float\nRPPA_AKT1 : float\nRPPA_CDKN1B : float\nRPPA_GATA3 : float\nRPPA_MAPT : float\nRPPA_TGM2 : float\nRPPA_CCNE1 : float\nRPPA_INPP4B : float\nRPPA_ACACA_ACC1 : float\nRPPA_RPS6 : float\nRPPA_VASP : float\nRPPA_CDH1 : float\nRPPA_EIF4EBP1 : float\nRPPA_CTNNB1 : float\nRPPA_XBP1 : float\nRPPA_EIF4EBP1_4E : float\nRPPA_PCNA : float\nRPPA_SRC : float\nRPPA_TP53BP1 : float\nRPPA_MAP2K1 : float\nRPPA_RAF1 : float\nRPPA_MET : float\nRPPA_TP53 : float\nRPPA_YAP1 : float\nRPPA_MAPK8 : float\nRPPA_CDKN1B_p27 : float\nRPPA_FRAP1 : float\nRPPA_RAD50 : float\nRPPA_CCNE2 : float\nRPPA_SNAI2 : float\nRPPA_PRKCA_PKC : float\nRPPA_PGR : float\nRPPA_ASNS : float\nRPPA_BID : float\nRPPA_CHEK2 : float\nRPPA_BCL2L1 : float\nRPPA_RPS6 : float\nRPPA_EGFR : float\nRPPA_PIK3CA : float\nRPPA_BCL2L11 : float\nRPPA_GSK3A : float\nRPPA_DVL3 : float\nRPPA_CCND1 : float\nRPPA_RAB11A : float\nRPPA_SRC_Src_pY416 :float\nRPPA_BCL2L111 : float\nRPPA_ATM : float\nRPPA_NOTCH1 : float\nRPPA_C12ORF5 : float\nRPPA_MAPK9 : float\nRPPA_FN1 : float\nRPPA_GSK3A_GSK3B : float\nRPPA_CDKN1B_p27_pT198 : float\nRPPA_MAP2K1_MEK1 : float\nRPPA_CASP8 : float\nRPPA_PAI : float\nRPPA_CHEK1 : float\nRPPA_STK11 : float\nRPPA_AKT1S1 : float\nRPPA_WWTR1 : float\nRPPA_CDKN1A : float\nRPPA_KDR : float\nRPPA_CHEK2_2 : float\nRPPA_EGFR_pY1173 : float\nRPPA_EGFR_pY992 : float\nRPPA_IGF1R : float\nRPPA_YWHAE : float\nRPPA_RPS6KA1 : float\nRPPA_TSC2 : float\nRPPA_CDC2 : float\nRPPA_EEF2 : float\nRPPA_NCOA3 : float\nRPPA_FRAP1 : float\nRPPA_AR : float\nRPPA_GAB2 : float\nRPPA_YBX1 : float\nRPPA_ESR1 : float\nRPPA_RAD51 : float\nRPPA_SMAD4 : float\nRPPA_CDH3 : float\nRPPA_CDH2 : float\nRPPA_FOXO3 : float\nRPPA_ERBB2_HER : float\nRPPA_BECN1 : float\nRPPA_CASP9 : float\nRPPA_SETD2 : float\nRPPA_SRC_Src_mv : float\nRPPA_GSK3A_alpha : float\nRPPA_YAP1_pS127 : float\nRPPA_PRKCA_alpha : float\nRPPA_PRKAA1 : float\nRPPA_RAF1_pS338 : float\nRPPA_MYC : float\nRPPA_PRKAA1_AMPK : float\nRPPA_ERRFI1_MIG : float\nRPPA_EIF4EBP1_2 : float\nRPPA_STAT3 : float\nRPPA_AKT1_AKT2_AKT3 : float\nRPPA_NF2 : float\nRPPA_PECAM1 : float\nRPPA_BAK1 : float\nRPPA_IRS1 : float\nRPPA_PTK2 : float\nRPPA_ERBB3_2 : float\nRPPA_FOXO3_a : float\nRPPA_RB1_Rb : float\nRPPA_MAPK14_p38 : float\nRPPA_NFKB1 : float\nRPPA_CHEK1_Chk1 : float\nRPPA_LCK : float\nRPPA_XRCC5 : float\nRPPA_PARK7 : float\nRPPA_DIABLO : float\nRPPA_CTNNA1 : float\nRPPA_ESR1_ER : float\nRPPA_IGFBP2 : float\nRPPA_STMN1 : float\nRPPA_WWTR1_TAZ : float\nRPPA_CASP3 : float\nRPPA_JUN : float\nRPPA_CCNB1 : float\nRPPA_CLDN7 : float\nRPPA_PXN : float\nRPPA_RPS6KB1_p : float\nRPPA_KIT : float\nRPPA_CAV1 : float\nRPPA_PTEN : float\nRPPA_BAX : float\nRPPA_SMAD3 : float\nRPPA_ERBB2 : float\nRPPA_MET_c : float\nRPPA_ERCC1 : float\nRPPA_MAPK14 : float\nRPPA_BIRC2 : float\nRPPA_PIK3R1 : float\nRPPA_BCL2 : float\nRPPA_PEA : float\nRPPA_EEF2K : float\nRPPA_RPS6KB1_p70 : float\nRPPA_MRE11A : float\nRPPA_KRAS : float\nRPPA_ARID1A : float\nRPPA_YBX1_yb : float\nRPPA_NOTCH3 : float\nRPPA_EIF4EBP1_3 : float\nRPPA_XRCC1 : float\nRPPA_ANXA1 : float\nRPPA_CD49 : float\nRPPA_SHC1 : float\nRPPA_PDK1 : float\nRPPA_EIF4E : float\nRPPA_MAPK1_MAPK3 : float\nRPPA_PTGS2 : float\nRPPA_PRKCA : float\nRPPA_EGFR_egfr : float\nRPPA_RAB25 : float\nRPPA_RB1 : float\nRPPA_MAPK1 : float\nRPPA_TFF1 : float\n \nclass config:\n orm_mode = True\n \n@app.post(\"/prediction/\")\nasync def create_item(userdata: Userdata):\n df = pd.DataFrame(userdata)\n y = model.predict(df)\n y = [0 if val < 0.5 else 1 for val in y]\n if y == 1:\n survival = 'You will survive.'\n if y == 0:\n survival = 'You will not survive.'\n return {'Prediction': survival}\n```\n\n========================================\n\nTop Answer:\nI am getting the same issue in my least-cost feed formulation API, but I was trying to get results in postman and call API from React Native, I solved it by finding the headers in my request, previously `Content-Type` was set to some `plain text`, we need to tell that `Content-Type` is an `application/json`, and then it was giving response correctly\n\n========================================\n\nCode:\n```text\ndf_json = dataframe.to_json(orient='records')\n prediction = requests.post('http://backend:8080/prediction/', json=json.loads(df_json), headers={\"Content-Type\": \"application/json\"})\n```\n\n```text\nclass Userdata(BaseModel):\nRPPA_HSPA1A : float\nRPPA_XIAP : float\nRPPA_CASP7 : float\nRPPA_ERBB3 :float\nRPPA_SMAD1 : float\nRPPA_SYK : float\nRPPA_STAT5A : float\nRPPA_CD20 : float\nRPPA_AKT1_Akt :float\nRPPA_BAD : float\nRPPA_PARP1 : float\nRPPA_MSH2 : float\nRPPA_MSH6 : float\nRPPA_ACACA : float\nRPPA_COL6A1 : float\nRPPA_PTCH1 : float\nRPPA_AKT1 : float\nRPPA_CDKN1B : float\nRPPA_GATA3 : float\nRPPA_MAPT : float\nRPPA_TGM2 : float\nRPPA_CCNE1 : float\nRPPA_INPP4B : float\nRPPA_ACACA_ACC1 : float\nRPPA_RPS6 : float\nRPPA_VASP : float\nRPPA_CDH1 : float\nRPPA_EIF4EBP1 : float\nRPPA_CTNNB1 : float\nRPPA_XBP1 : float\nRPPA_EIF4EBP1_4E : float\nRPPA_PCNA : float\nRPPA_SRC : float\nRPPA_TP53BP1 : float\nRPPA_MAP2K1 : float\nRPPA_RAF1 : float\nRPPA_MET : float\nRPPA_TP53 : float\nRPPA_YAP1 : float\nRPPA_MAPK8 : float\nRPPA_CDKN1B_p27 : float\nRPPA_FRAP1 : float\nRPPA_RAD50 : float\nRPPA_CCNE2 : float\nRPPA_SNAI2 : float\nRPPA_PRKCA_PKC : float\nRPPA_PGR : float\nRPPA_ASNS : float\nRPPA_BID : float\nRPPA_CHEK2 : float\nRPPA_BCL2L1 : float\nRPPA_RPS6 : float\nRPPA_EGFR : float\nRPPA_PIK3CA : float\nRPPA_BCL2L11 : float\nRPPA_GSK3A : float\nRPPA_DVL3 : float\nRPPA_CCND1 : float\nRPPA_RAB11A : float\nRPPA_SRC_Src_pY416 :float\nRPPA_BCL2L111 : float\nRPPA_ATM : float\nRPPA_NOTCH1 : float\nRPPA_C12ORF5 : float\nRPPA_MAPK9 : float\nRPPA_FN1 : float\nRPPA_GSK3A_GSK3B : float\nRPPA_CDKN1B_p27_pT198 : float\nRPPA_MAP2K1_MEK1 : float\nRPPA_CASP8 : float\nRPPA_PAI : float\nRPPA_CHEK1 : float\nRPPA_STK11 : float\nRPPA_AKT1S1 : float\nRPPA_WWTR1 : float\nRPPA_CDKN1A : float\nRPPA_KDR : float\nRPPA_CHEK2_2 : float\nRPPA_EGFR_pY1173 : float\nRPPA_EGFR_pY992 : float\nRPPA_IGF1R : float\nRPPA_YWHAE : float\nRPPA_RPS6KA1 : float\nRPPA_TSC2 : float\nRPPA_CDC2 : float\nRPPA_EEF2 : float\nRPPA_NCOA3 : float\nRPPA_FRAP1 : float\nRPPA_AR : float\nRPPA_GAB2 : float\nRPPA_YBX1 : float\nRPPA_ESR1 : float\nRPPA_RAD51 : float\nRPPA_SMAD4 : float\nRPPA_CDH3 : float\nRPPA_CDH2 : float\nRPPA_FOXO3 : float\nRPPA_ERBB2_HER : float\nRPPA_BECN1 : float\nRPPA_CASP9 : float\nRPPA_SETD2 : float\nRPPA_SRC_Src_mv : float\nRPPA_GSK3A_alpha : float\nRPPA_YAP1_pS127 : float\nRPPA_PRKCA_alpha : float\nRPPA_PRKAA1 : float\nRPPA_RAF1_pS338 : float\nRPPA_MYC : float\nRPPA_PRKAA1_AMPK : float\nRPPA_ERRFI1_MIG : float\nRPPA_EIF4EBP1_2 : float\nRPPA_STAT3 : float\nRPPA_AKT1_AKT2_AKT3 : float\nRPPA_NF2 : float\nRPPA_PECAM1 : float\nRPPA_BAK1 : float\nRPPA_IRS1 : float\nRPPA_PTK2 : float\nRPPA_ERBB3_2 : float\nRPPA_FOXO3_a : float\nRPPA_RB1_Rb : float\nRPPA_MAPK14_p38 : float\nRPPA_NFKB1 : float\nRPPA_CHEK1_Chk1 : float\nRPPA_LCK : float\nRPPA_XRCC5 : float\nRPPA_PARK7 : float\nRPPA_DIABLO : float\nRPPA_CTNNA1 : float\nRPPA_ESR1_ER : float\nRPPA_IGFBP2 : float\nRPPA_STMN1 : float\nRPPA_WWTR1_TAZ : float\nRPPA_CASP3 : float\nRPPA_JUN : float\nRPPA_CCNB1 : float\nRPPA_CLDN7 : float\nRPPA_PXN : float\nRPPA_RPS6KB1_p : float\nRPPA_KIT : float\nRPPA_CAV1 : float\nRPPA_PTEN : float\nRPPA_BAX : float\nRPPA_SMAD3 : float\nRPPA_ERBB2 : float\nRPPA_MET_c : float\nRPPA_ERCC1 : float\nRPPA_MAPK14 : float\nRPPA_BIRC2 : float\nRPPA_PIK3R1 : float\nRPPA_BCL2 : float\nRPPA_PEA : float\nRPPA_EEF2K : float\nRPPA_RPS6KB1_p70 : float\nRPPA_MRE11A : float\nRPPA_KRAS : float\nRPPA_ARID1A : float\nRPPA_YBX1_yb : float\nRPPA_NOTCH3 : float\nRPPA_EIF4EBP1_3 : float\nRPPA_XRCC1 : float\nRPPA_ANXA1 : float\nRPPA_CD49 : float\nRPPA_SHC1 : float\nRPPA_PDK1 : float\nRPPA_EIF4E : float\nRPPA_MAPK1_MAPK3 : float\nRPPA_PTGS2 : float\nRPPA_PRKCA : float\nRPPA_EGFR_egfr : float\nRPPA_RAB25 : float\nRPPA_RB1 : float\nRPPA_MAPK1 : float\nRPPA_TFF1 : float\n \nclass config:\n orm_mode = True\n \n@app.post(\"/prediction/\")\nasync def create_item(userdata: Userdata):\n df = pd.DataFrame(userdata)\n y = model.predict(df)\n y = [0 if val < 0.5 else 1 for val in y]\n if y == 1:\n survival = 'You will survive.'\n if y == 0:\n survival = 'You will not survive.'\n return {'Prediction': survival}\n```\n\n```text\nPOST\n```\n\n```text\n422\n```\n\n```text\nJSON\n```\n\n```text\nPOST\n```\n\n```text\ndata = dataframe.to_dict(orient='records')\npayload = data[0]\nprediction = requests.post('<URL_HERE>', json=payload)\n```\n\n```text\ndf_json = dataframe.to_json(orient='records')\npayload = df_json.strip(\"[]\")\nprediction = requests.post('<URL_HERE>', data=payload, headers={\"Content-Type\": \"application/json\"})\n```\n\n```text\nrequests\n```\n\n```text\nJSON\n```\n\n```text\njson\n```\n\n```text\njson={\"RPPA_HSPA1A\":30,\"RPPA_XIAP\":-0.902044768}\n```\n\n```text\nrequests\n```\n\n```text\nJSON\n```\n\n```text\nContent-Type\n```\n\n```text\napplication/json\n```\n\n```text\nto_json()\n```\n\n```text\ndf_json\n```\n\n```text\nJSON\n```\n\n```text\ntype(df_json)\n```\n\n```text\nto_dict()\n```\n\n```text\norient='records'\n```\n\n```text\nlist\n```\n\n```text\ndict\n```\n\n```text\nlist\n```\n\n```text\nto_json()\n```\n\n```text\ndata\n```\n\n```text\nrecords\n```\n\n```text\nlist\n```\n\n```text\nContent-Type\n```\n\n```text\napplication/json\n```\n\n```text\nContent-Type\n```\n\n```text\nplain text\n```\n\n```text\nContent-Type\n```\n\n```text\napplication/json\n```\n\n========================================\n\nComments:\n- Your json fails somehow. What about changing the json parameter to: `json.dumps(json.loads(df_json))`\n- @stuck still receiving the same error using json.dumps. The json is properly formatted, I don't believe that is the problem.\n- Thanks this solved my issue!\n- I'm having another issue now that the json is being passed, I'm trying to figure how to convert the pydantic model to a pandas dataframe to input into my tensorflow model. I'm now receiving a 500 response internal server error\n- For those using postman to make the request, select JSON from the drop-down as default is text\n- @ShirishBajpai Please have a look at this answer and this answer, if you are using Postman.","metadata":{"transformedAt":"2026-08-18T18:32:29.110Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":35,"totalLines":558,"estimatedTokens":2723}}204{"id":"stack-72534575","source":"stackoverflow","questionId":72534575,"title":"FastAPI FileResponse cannot find file in TempDirectory","tags":["python","fastapi"],"text":"Title: FastAPI FileResponse cannot find file in TempDirectory\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm trying to write an endpoint that just accepts an image and attempts to convert it into another format, by running a command on the system. Then I return the converted file. It's slow and oh-so-simple, and I don't have to store files anywhere, except temporarily.\n\nI'd like all the file-writing to happen in a temporary directory, so it gets cleaned up.\n\nThe route works fine if the output file is *not* in the temporary directory. But if I try to put the output file in the temporary directory, the FileResponse can't find it, and requests fail.\n\n`RuntimeError: File at path /tmp/tmpp5x_p4n9/out.jpg does not exist.`\n\nIs there something going on related to the asynchronous nature of FastApi that FileResponse can't wait for the subprocess to create the file its making? Can I make it wait? (removing `async` from the route does not help).\n\n```\n@app.post(\"/heic\")\nasync def heic(img: UploadFile):\n with TemporaryDirectory() as dir:\n inname = os.path.join(dir, \"img.heic\")\n f = open(inname,\"wb\")\n f.write(img.file.read())\n f.flush()\n\n # setting outname in the temp dir fails!\n # outname = os.path.join(dir, 'out.jpg')\n\n outname = os.path.join('out.jpg')\n\n cmd = f\"oiiotool {f.name} -o {outname}\"\n process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)\n process.wait()\n return FileResponse(outname, headers={'Content-Disposition':'attachment; filename=response.csv'})\n```\n\nThank you for any insights!\n\n========================================\n\nTop Answer:\nHere's an alternative approach by creating a new `FileResponseWithCleanup` class that extends the `FileResponse` class.\n\nSimply create a permanent file, and add the file you want to delete after returning to the `cleanup_path` prop.\n\n```\nclass FileResponseWithCleanup(FileResponse):\ndef __init__(self, *args, **kwargs):\n self.cleanup_path = kwargs.pop(\"cleanup_path\", None)\n super().__init__(*args, **kwargs)\n\nasync def __call__(self, scope, receive, send):\n try:\n await super().__call__(scope, receive, send)\n finally:\n if self.cleanup_path and os.path.exists(self.cleanup_path):\n os.remove(self.cleanup_path)\n\n@app.post(\"/upload\")\nasync def upload_file(file: UploadFile = File(...)):\n # Create a temporary file to save the uploaded file\n with tempfile.NamedTemporaryFile(delete=False, suffix=\".tmp\") as temp_file:\n temp_file.write(await file.read())\n temp_file_path = temp_file.name\n\n # Copy the temporary file to a more permanent location\n permanent_file_path = f\"static/{Path(file.filename).stem}_uploaded.tmp\"\n shutil.copyfile(temp_file_path, permanent_file_path)\n\n # Return the file with cleanup after response\n return FileResponseWithCleanup(\n path=permanent_file_path,\n media_type=\"application/octet-stream\",\n filename=file.filename,\n cleanup_path=permanent_file_path,\n )\n```\n\n========================================\n\nCode:\n```text\n@app.post(\"/heic\")\nasync def heic(img: UploadFile):\n with TemporaryDirectory() as dir:\n inname = os.path.join(dir, \"img.heic\")\n f = open(inname,\"wb\")\n f.write(img.file.read())\n f.flush()\n\n # setting outname in the temp dir fails!\n # outname = os.path.join(dir, 'out.jpg')\n\n outname = os.path.join('out.jpg')\n\n cmd = f\"oiiotool {f.name} -o {outname}\"\n process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)\n process.wait()\n return FileResponse(outname, headers={'Content-Disposition':'attachment; filename=response.csv'})\n```\n\n```text\nRuntimeError: File at path /tmp/tmpp5x_p4n9/out.jpg does not exist.\n```\n\n```text\nasync\n```\n\n```text\nasync def get_temp_dir():\n dir = TemporaryDirectory()\n try:\n yield dir.name\n finally:\n del dir\n```\n\n```text\n@app.post(\"/heic\")\nasync def heic(imgfile: UploadFile = File(...), dir=Depends(get_temp_dir)):\n inname = os.path.join(dir, \"img.heic\")\n f = open(inname,\"wb\")\n f.write(imgfile.file.read())\n f.flush()\n\n outname = os.path.join(dir, 'out.jpg')\n cmd = f\"oiiotool {f.name} -o {outname}\"\n process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)\n process.wait()\n return FileResponse(inname, headers={'Content-Disposition':'attachment; filename=response.csv'})\n```\n\n```text\nclass FileResponseWithCleanup(FileResponse):\ndef __init__(self, *args, **kwargs):\n self.cleanup_path = kwargs.pop(\"cleanup_path\", None)\n super().__init__(*args, **kwargs)\n\nasync def __call__(self, scope, receive, send):\n try:\n await super().__call__(scope, receive, send)\n finally:\n if self.cleanup_path and os.path.exists(self.cleanup_path):\n os.remove(self.cleanup_path)\n\n@app.post(\"/upload\")\nasync def upload_file(file: UploadFile = File(...)):\n # Create a temporary file to save the uploaded file\n with tempfile.NamedTemporaryFile(delete=False, suffix=\".tmp\") as temp_file:\n temp_file.write(await file.read())\n temp_file_path = temp_file.name\n\n # Copy the temporary file to a more permanent location\n permanent_file_path = f\"static/{Path(file.filename).stem}_uploaded.tmp\"\n shutil.copyfile(temp_file_path, permanent_file_path)\n\n # Return the file with cleanup after response\n return FileResponseWithCleanup(\n path=permanent_file_path,\n media_type=\"application/octet-stream\",\n filename=file.filename,\n cleanup_path=permanent_file_path,\n )\n```\n\n```text\nFileResponseWithCleanup\n```\n\n```text\nFileResponse\n```\n\n```text\ncleanup_path\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.110Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":9,"totalLines":176,"estimatedTokens":1383}}205{"id":"stack-76328904","source":"stackoverflow","questionId":76328904,"title":"Is there a difference between Starlette/FastAPI Background Tasks and simply using multiprocessing in Python?","tags":["python","multiprocessing","python-asyncio","fastapi"],"text":"Title: Is there a difference between Starlette/FastAPI Background Tasks and simply using multiprocessing in Python?\nTags: python, multiprocessing, python-asyncio, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am looking for different ways to queue up functions that will do things like copy files, scrape websites, and manipulate files (tasks that will take considerable time). I am using FastAPI as a backend API, and I came across FastAPI's background task documentation as well as Starlette's background task documentation and I fail to understand why I couldn't just use multiprocessing.\n\nThis is what I do currently using Multiprocessing and it works fine.\n\n```\nfrom multiprocessing import Process\nfrom fastapi import FastAPI, File, UploadFile\napp = FastAPI()\n\ndef handleFileUpload(file):\n print(file)\n #handle uploading file here\n\n@app.post(\"/uploadFileToS3\")\nasync def uploadToS3(bucket: str, file: UploadFile = File(...)):\n uploadProcess = Process(target=handleFileUpload, args(file))\n uploadProcess.start()\n return {\n \"message\": \"Data has been queued for upload. You will be notified when it is ready.\"\n \"status\": \"OK\"\n }\n```\n\nIf this works why would FastAPI Background Tasks exist if I can do it just as simply as using Multiprocessing? My only guess is that it has to do with scaling? It may work for myself just testing, but I know that multiprocessing has to do with the number of cores a system has. I may be completely missing the point of multiprocessing. Please help me understand. Thanks.\n\n========================================\n\nTop Answer:\nMultiprocessing Process enables you to make full use of available hardware resources, such as multiple CPU cores. By distributing workload across processes, you can take advantage of parallelism and achieve faster execution times.\n\nThe BackgroundTask feature in FastAPI is useful when you want to execute certain functions or methods asynchronously in the background while handling HTTP requests. It allows you to schedule and perform tasks that might take longer to complete or involve I/O operations without blocking the API response. It is useful to use on I/O bound tasks or Periodic/Scheduled Tasks.\n\nHowever, you can use both together to achieve parallelism and asynchronous execution of tasks in a FastAPI application.\n\n```\ndef handleFileUpload(file: UploadFile) -> None:\n print(file)\n\ndef check_worker_status(p: Process) -> None:\n while p.is_alive():\n print('Worker is still running...')\n time.sleep(5)\n p.terminate()\n print('Worker terminated')\n\n@router.post(\"/uploadFileToS3\")\nasync def uploadToS3(background_task: BackgroundTasks, bucket: str, file: UploadFile = File(...)) -> dict:\n uploadProcess = Process(target=handleFileUpload, args=(file,))\n uploadProcess.start()\n background_task.add_task(check_worker_status, uploadProcess)\n return {\"message\": \"File uploaded successfully\"}\n```\n\nThe join() method of the multiprocessing.Process class is used to block the calling process until the process whose join() method is called terminates. If you want to avoid blocking the calling process, you can use the is_alive() method of the multiprocessing.Process class to check if the process is still running and then terminate it using the terminate() method of the same class.\n\n========================================\n\nCode:\n```text\nfrom multiprocessing import Process\nfrom fastapi import FastAPI, File, UploadFile\napp = FastAPI()\n\ndef handleFileUpload(file):\n print(file)\n #handle uploading file here\n\n@app.post(\"/uploadFileToS3\")\nasync def uploadToS3(bucket: str, file: UploadFile = File(...)):\n uploadProcess = Process(target=handleFileUpload, args(file))\n uploadProcess.start()\n return {\n \"message\": \"Data has been queued for upload. You will be notified when it is ready.\"\n \"status\": \"OK\"\n }\n```\n\n```text\nBackgroundTasks\n```\n\n```text\nBackgroundTasks\n```\n\n```text\njoin\n```\n\n```text\nBackgroundTasks\n```\n\n```text\n__call__\n```\n\n```text\nawait\n```\n\n```text\nasync\n```\n\n```text\nanyio.to_thread.run_sync\n```\n\n```text\nBackgroundTasks\n```\n\n```text\nBackgroundTasks\n```\n\n```text\nBackgroundTasks\n```\n\n```text\nasyncio.create_task\n```\n\n```text\nawait\n```\n\n```text\ndef handleFileUpload(file: UploadFile) -> None:\n print(file)\n\ndef check_worker_status(p: Process) -> None:\n while p.is_alive():\n print('Worker is still running...')\n time.sleep(5)\n p.terminate()\n print('Worker terminated')\n\n@router.post(\"/uploadFileToS3\")\nasync def uploadToS3(background_task: BackgroundTasks, bucket: str, file: UploadFile = File(...)) -> dict:\n uploadProcess = Process(target=handleFileUpload, args=(file,))\n uploadProcess.start()\n background_task.add_task(check_worker_status, uploadProcess)\n return {\"message\": \"File uploaded successfully\"}\n```\n\n========================================\n\nComments:\n- In addition to @Daniil's answer below, you might find this answer and this answer helpful as well\n- This makes a lot more sense to me now, thanks. Ill do more research into multiprocessing, because I don't want to wait for the process to complete at all, which is why I never did the .join().\n- This seems like something I would have to do to avoid .join()\n- I just edited the answer example, please have a look.\n- I ended up joining the process inside of the background_task, it worked out fine. Thanks","metadata":{"transformedAt":"2026-08-18T18:32:29.110Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":15,"totalLines":161,"estimatedTokens":1329}}206{"id":"stack-77920123","source":"stackoverflow","questionId":77920123,"title":"Using starlette TestClient causes an AttributeError : '_UnixSelectorEventLoop' object has no attribute '_compute_internal_coro'","tags":["python","pycharm","python-asyncio","fastapi","starlette"],"text":"Title: Using starlette TestClient causes an AttributeError : '_UnixSelectorEventLoop' object has no attribute '_compute_internal_coro'\nTags: python, pycharm, python-asyncio, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nUsing FastAPI : `0.101.1`\n\nI run this `test_read_aynsc` and it pass.\n\n```\n# app.py\nfrom fastapi import FastAPI\n\napp = FastAPI()\napp.get(\"/\")\ndef read_root():\n return {\"Hello\": \"World\"}\n\n# conftest.py\n\nimport pytest\nfrom typing import Generator\nfrom fastapi.testclient import TestClient\n\nfrom server import app\n@pytest.fixture(scope=\"session\")\ndef client() -> Generator:\n with TestClient(app) as c:\n yield c\n\n# test_root.py\n\ndef test_read_aynsc(client):\n response = client.get(\"/item\")\n```\n\nHowever, executing this test in DEBUG mode (in pycharm) will cause an error. Here is the Traceback :\n\n```\ntest setup failed\ncls = \nfunc = .run_portal at 0x1555c51b0>\nargs = (), kwargs = {}, options = {}\n\n @classmethod\n def run(\n cls,\n func: Callable[[Unpack[PosArgsT]], Awaitable[T_Retval]],\n args: tuple[Unpack[PosArgsT]],\n kwargs: dict[str, Any],\n options: dict[str, Any],\n ) -> T_Retval:\n @wraps(func)\n async def wrapper() -> T_Retval:\n task = cast(asyncio.Task, current_task())\n task.set_name(get_callable_name(func))\n _task_states[task] = TaskState(None, None)\n \n try:\n return await func(*args)\n finally:\n del _task_states[task]\n \n debug = options.get(\"debug\", False)\n loop_factory = options.get(\"loop_factory\", None)\n if loop_factory is None and options.get(\"use_uvloop\", False):\n import uvloop\n \n loop_factory = uvloop.new_event_loop\n \n with Runner(debug=debug, loop_factory=loop_factory) as runner:\n> return runner.run(wrapper())\n\n../../../Library/Caches/pypoetry/virtualenvs/kms-backend-F9vGicV3-py3.10/lib/python3.10/site-packages/anyio/_backends/_asyncio.py:1991: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n../../../Library/Caches/pypoetry/virtualenvs/kms-backend-F9vGicV3-py3.10/lib/python3.10/site-packages/anyio/_backends/_asyncio.py:193: in run\n return self._loop.run_until_complete(task)\n../../../Library/Application Support/JetBrains/Toolbox/apps/PyCharm-P/ch-0/233.13763.11/PyCharm.app/Contents/plugins/python/helpers-pro/pydevd_asyncio/pydevd_nest_asyncio.py:202: in run_until_complete\n self._run_once()\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = \n\n def _run_once(self):\n \"\"\"\n Simplified re-implementation of asyncio's _run_once that\n runs handles as they become ready.\n \"\"\"\n ready = self._ready\n scheduled = self._scheduled\n while scheduled and scheduled[0]._cancelled:\n heappop(scheduled)\n \n timeout = (\n 0 if ready or self._stopping\n else min(max(\n scheduled[0]._when - self.time(), 0), 86400) if scheduled\n else None)\n event_list = self._selector.select(timeout)\n self._process_events(event_list)\n \n end_time = self.time() + self._clock_resolution\n while scheduled and scheduled[0]._when if self._compute_internal_coro:\nE AttributeError: '_UnixSelectorEventLoop' object has no attribute '_compute_internal_coro'\n\n../../../Library/Application Support/JetBrains/Toolbox/apps/PyCharm-P/ch-0/233.13763.11/PyCharm.app/Contents/plugins/python/helpers-pro/pydevd_asyncio/pydevd_nest_asyncio.py:236: AttributeError\n\nDuring handling of the above exception, another exception occurred:\n\n @pytest.fixture(scope=\"session\")\n def client() -> Generator:\n> with TestClient(app) as c:\n\ntests/fixtures/common/http_client_app.py:10: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n../../../Library/Caches/pypoetry/virtualenvs/kms-backend-F9vGicV3-py3.10/lib/python3.10/site-packages/starlette/testclient.py:730: in __enter__\n self.portal = portal = stack.enter_context(\n../../../.pyenv/versions/3.10.12/lib/python3.10/contextlib.py:492: in enter_context\n result = _cm_type.__enter__(cm)\n../../../.pyenv/versions/3.10.12/lib/python3.10/contextlib.py:135: in __enter__\n return next(self.gen)\n../../../Library/Caches/pypoetry/virtualenvs/kms-backend-F9vGicV3-py3.10/lib/python3.10/site-packages/anyio/from_thread.py:454: in start_blocking_portal\n run_future.result()\n../../../.pyenv/versions/3.10.12/lib/python3.10/concurrent/futures/_base.py:451: in result\n return self.__get_result()\n../../../.pyenv/versions/3.10.12/lib/python3.10/concurrent/futures/_base.py:403: in __get_result\n raise self._exception\n../../../.pyenv/versions/3.10.12/lib/python3.10/concurrent/futures/thread.py:58: in run\n result = self.fn(*self.args, **self.kwargs)\n../../../Library/Caches/pypoetry/virtualenvs/kms-backend-F9vGicV3-py3.10/lib/python3.10/site-packages/anyio/_core/_eventloop.py:73: in run\n return async_backend.run(func, args, {}, backend_options)\n../../../Library/Caches/pypoetry/virtualenvs/kms-backend-F9vGicV3-py3.10/lib/python3.10/site-packages/anyio/_backends/_asyncio.py:1990: in run\n with Runner(debug=debug, loop_factory=loop_factory) as runner:\n../../../Library/Caches/pypoetry/virtualenvs/kms-backend-F9vGicV3-py3.10/lib/python3.10/site-packages/anyio/_backends/_asyncio.py:133: in __exit__\n self.close()\n../../../Library/Caches/pypoetry/virtualenvs/kms-backend-F9vGicV3-py3.10/lib/python3.10/site-packages/anyio/_backends/_asyncio.py:141: in close\n _cancel_all_tasks(loop)\n../../../Library/Caches/pypoetry/virtualenvs/kms-backend-F9vGicV3-py3.10/lib/python3.10/site-packages/anyio/_backends/_asyncio.py:243: in _cancel_all_tasks\n loop.run_until_complete(tasks.gather(*to_cancel, return_exceptions=True))\n../../../Library/Application Support/JetBrains/Toolbox/apps/PyCharm-P/ch-0/233.13763.11/PyCharm.app/Contents/plugins/python/helpers-pro/pydevd_asyncio/pydevd_nest_asyncio.py:202: in run_until_complete\n self._run_once()\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = \n\n def _run_once(self):\n \"\"\"\n Simplified re-implementation of asyncio's _run_once that\n runs handles as they become ready.\n \"\"\"\n ready = self._ready\n scheduled = self._scheduled\n while scheduled and scheduled[0]._cancelled:\n heappop(scheduled)\n \n timeout = (\n 0 if ready or self._stopping\n else min(max(\n scheduled[0]._when - self.time(), 0), 86400) if scheduled\n else None)\n event_list = self._selector.select(timeout)\n self._process_events(event_list)\n \n end_time = self.time() + self._clock_resolution\n while scheduled and scheduled[0]._when if self._compute_internal_coro:\nE AttributeError: '_UnixSelectorEventLoop' object has no attribute '_compute_internal_coro'\n```\n\nI am not sure to understand what causes the error\nSince I can see the `_UnixSelectorEventLoop`, I need to precise that my operating system is MacOS M1.\n\n========================================\n\nCode:\n```py\n# app.py\nfrom fastapi import FastAPI\n\n\napp = FastAPI()\napp.get(\"/\")\ndef read_root():\n return {\"Hello\": \"World\"}\n\n# conftest.py\n\nimport pytest\nfrom typing import Generator\nfrom fastapi.testclient import TestClient\n\nfrom server import app\n@pytest.fixture(scope=\"session\")\ndef client() -> Generator:\n with TestClient(app) as c:\n yield c\n\n# test_root.py\n\ndef test_read_aynsc(client):\n response = client.get(\"/item\")\n```\n\n```bash\ntest setup failed\ncls = <class 'anyio._backends._asyncio.AsyncIOBackend'>\nfunc = <function start_blocking_portal.<locals>.run_portal at 0x1555c51b0>\nargs = (), kwargs = {}, options = {}\n\n @classmethod\n def run(\n cls,\n func: Callable[[Unpack[PosArgsT]], Awaitable[T_Retval]],\n args: tuple[Unpack[PosArgsT]],\n kwargs: dict[str, Any],\n options: dict[str, Any],\n ) -> T_Retval:\n @wraps(func)\n async def wrapper() -> T_Retval:\n task = cast(asyncio.Task, current_task())\n task.set_name(get_callable_name(func))\n _task_states[task] = TaskState(None, None)\n \n try:\n return await func(*args)\n finally:\n del _task_states[task]\n \n debug = options.get(\"debug\", False)\n loop_factory = options.get(\"loop_factory\", None)\n if loop_factory is None and options.get(\"use_uvloop\", False):\n import uvloop\n \n loop_factory = uvloop.new_event_loop\n \n with Runner(debug=debug, loop_factory=loop_factory) as runner:\n> return runner.run(wrapper())\n\n../../../Library/Caches/pypoetry/virtualenvs/kms-backend-F9vGicV3-py3.10/lib/python3.10/site-packages/anyio/_backends/_asyncio.py:1991: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n../../../Library/Caches/pypoetry/virtualenvs/kms-backend-F9vGicV3-py3.10/lib/python3.10/site-packages/anyio/_backends/_asyncio.py:193: in run\n return self._loop.run_until_complete(task)\n../../../Library/Application Support/JetBrains/Toolbox/apps/PyCharm-P/ch-0/233.13763.11/PyCharm.app/Contents/plugins/python/helpers-pro/pydevd_asyncio/pydevd_nest_asyncio.py:202: in run_until_complete\n self._run_once()\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = <_UnixSelectorEventLoop running=False closed=True debug=False>\n\n def _run_once(self):\n \"\"\"\n Simplified re-implementation of asyncio's _run_once that\n runs handles as they become ready.\n \"\"\"\n ready = self._ready\n scheduled = self._scheduled\n while scheduled and scheduled[0]._cancelled:\n heappop(scheduled)\n \n timeout = (\n 0 if ready or self._stopping\n else min(max(\n scheduled[0]._when - self.time(), 0), 86400) if scheduled\n else None)\n event_list = self._selector.select(timeout)\n self._process_events(event_list)\n \n end_time = self.time() + self._clock_resolution\n while scheduled and scheduled[0]._when < end_time:\n handle = heappop(scheduled)\n ready.append(handle)\n \n> if self._compute_internal_coro:\nE AttributeError: '_UnixSelectorEventLoop' object has no attribute '_compute_internal_coro'\n\n../../../Library/Application Support/JetBrains/Toolbox/apps/PyCharm-P/ch-0/233.13763.11/PyCharm.app/Contents/plugins/python/helpers-pro/pydevd_asyncio/pydevd_nest_asyncio.py:236: AttributeError\n\nDuring handling of the above exception, another exception occurred:\n\n @pytest.fixture(scope=\"session\")\n def client() -> Generator:\n> with TestClient(app) as c:\n\ntests/fixtures/common/http_client_app.py:10: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n../../../Library/Caches/pypoetry/virtualenvs/kms-backend-F9vGicV3-py3.10/lib/python3.10/site-packages/starlette/testclient.py:730: in __enter__\n self.portal = portal = stack.enter_context(\n../../../.pyenv/versions/3.10.12/lib/python3.10/contextlib.py:492: in enter_context\n result = _cm_type.__enter__(cm)\n../../../.pyenv/versions/3.10.12/lib/python3.10/contextlib.py:135: in __enter__\n return next(self.gen)\n../../../Library/Caches/pypoetry/virtualenvs/kms-backend-F9vGicV3-py3.10/lib/python3.10/site-packages/anyio/from_thread.py:454: in start_blocking_portal\n run_future.result()\n../../../.pyenv/versions/3.10.12/lib/python3.10/concurrent/futures/_base.py:451: in result\n return self.__get_result()\n../../../.pyenv/versions/3.10.12/lib/python3.10/concurrent/futures/_base.py:403: in __get_result\n raise self._exception\n../../../.pyenv/versions/3.10.12/lib/python3.10/concurrent/futures/thread.py:58: in run\n result = self.fn(*self.args, **self.kwargs)\n../../../Library/Caches/pypoetry/virtualenvs/kms-backend-F9vGicV3-py3.10/lib/python3.10/site-packages/anyio/_core/_eventloop.py:73: in run\n return async_backend.run(func, args, {}, backend_options)\n../../../Library/Caches/pypoetry/virtualenvs/kms-backend-F9vGicV3-py3.10/lib/python3.10/site-packages/anyio/_backends/_asyncio.py:1990: in run\n with Runner(debug=debug, loop_factory=loop_factory) as runner:\n../../../Library/Caches/pypoetry/virtualenvs/kms-backend-F9vGicV3-py3.10/lib/python3.10/site-packages/anyio/_backends/_asyncio.py:133: in __exit__\n self.close()\n../../../Library/Caches/pypoetry/virtualenvs/kms-backend-F9vGicV3-py3.10/lib/python3.10/site-packages/anyio/_backends/_asyncio.py:141: in close\n _cancel_all_tasks(loop)\n../../../Library/Caches/pypoetry/virtualenvs/kms-backend-F9vGicV3-py3.10/lib/python3.10/site-packages/anyio/_backends/_asyncio.py:243: in _cancel_all_tasks\n loop.run_until_complete(tasks.gather(*to_cancel, return_exceptions=True))\n../../../Library/Application Support/JetBrains/Toolbox/apps/PyCharm-P/ch-0/233.13763.11/PyCharm.app/Contents/plugins/python/helpers-pro/pydevd_asyncio/pydevd_nest_asyncio.py:202: in run_until_complete\n self._run_once()\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = <_UnixSelectorEventLoop running=False closed=True debug=False>\n\n def _run_once(self):\n \"\"\"\n Simplified re-implementation of asyncio's _run_once that\n runs handles as they become ready.\n \"\"\"\n ready = self._ready\n scheduled = self._scheduled\n while scheduled and scheduled[0]._cancelled:\n heappop(scheduled)\n \n timeout = (\n 0 if ready or self._stopping\n else min(max(\n scheduled[0]._when - self.time(), 0), 86400) if scheduled\n else None)\n event_list = self._selector.select(timeout)\n self._process_events(event_list)\n \n end_time = self.time() + self._clock_resolution\n while scheduled and scheduled[0]._when < end_time:\n handle = heappop(scheduled)\n ready.append(handle)\n \n> if self._compute_internal_coro:\nE AttributeError: '_UnixSelectorEventLoop' object has no attribute '_compute_internal_coro'\n```\n\n```text\n0.101.1\n```\n\n```text\ntest_read_aynsc\n```\n\n```text\n_UnixSelectorEventLoop\n```\n\n```py\nTestClient(app, backend_options={'loop_factory': asyncio.new_event_loop})\n```\n\n```text\nasyncio.new_event_loop()\n```\n\n```text\n~/Applications/PyCharm Professional Edition.app/Contents/plugins/python/helpers-pro/pydevd_asyncio/pydevd_nest_asyncio.py:169\n```\n\n```text\nasyncio.events.new_event_loop()\n```\n\n```text\nnew_event_loop\n```\n\n```text\npython.debug.asyncio.repl\n```\n\n========================================\n\nComments:\n- In version 2023.3.4 fix was applied","metadata":{"transformedAt":"2026-08-18T18:32:29.110Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":11,"totalLines":380,"estimatedTokens":3555}}207{"id":"stack-70772733","source":"stackoverflow","questionId":70772733,"title":"How to POST a JSON having a single body parameter in FastAPI?","tags":["python","json","request","fastapi"],"text":"Title: How to POST a JSON having a single body parameter in FastAPI?\nTags: python, json, request, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have a file called `main.py` in which I put a `POST` call with only one input parameter (integer). Simplified code is given below:\n\n```\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.post(\"/do_something/\")\nasync def do_something(process_id: int):\n # some code\n return {\"process_id\": process_id}\n```\n\nNow, if I run the code for the test, saved in the file `test_main.py`, that is:\n\n```\nfrom fastapi.testclient import TestClient\nfrom main import app\n\nclient = TestClient(app)\n\ndef test_do_something():\n response = client.post(\n \"/do_something/\",\n json={\n \"process_id\": 16\n }\n )\n return response.json()\n\nprint(test_do_something())\n```\n\nI get:\n\n```\n{'detail': [{'loc': ['query', 'process_id'], 'msg': 'field required', 'type': 'value_error.missing'}]}\n```\n\nI can't figure out what the mistake is. It is necessary that it remains a `POST` call.\n\n========================================\n\nTop Answer:\nIf you want to pass a query parameter in a post request, you can do so by passing it as `params=`. In this case, we define the endpoint exactly as in the OP. A working code:\n\n```\nfrom fastapi import FastAPI\nfrom fastapi.testclient import TestClient\n\napp = FastAPI()\n\n@app.post(\"/do_something/\")\nasync def do_something(process_id: int): # \nAnother option is to change how we extract data in the endpoint. Instead of type-hinting for an integer, type hint for a dictionary and get the response_id from the received dict. In this case, we make the post request exactly as in the OP. A working code:\n\n```\nfrom fastapi import FastAPI\nfrom fastapi.testclient import TestClient\n\napp = FastAPI()\n\n@app.post(\"/do_something/\")\nasync def do_something(item: dict[str, int]): # Of course, we can replace `dict[str, int]` above with a `TypedDict` sub-class as well.\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.post(\"/do_something/\")\nasync def do_something(process_id: int):\n # some code\n return {\"process_id\": process_id}\n```\n\n```py\nfrom fastapi.testclient import TestClient\nfrom main import app\n\nclient = TestClient(app)\n\ndef test_do_something():\n response = client.post(\n \"/do_something/\",\n json={\n \"process_id\": 16\n }\n )\n return response.json()\n\nprint(test_do_something())\n```\n\n```json\n{'detail': [{'loc': ['query', 'process_id'], 'msg': 'field required', 'type': 'value_error.missing'}]}\n```\n\n```text\nmain.py\n```\n\n```text\nPOST\n```\n\n```text\ntest_main.py\n```\n\n```text\nPOST\n```\n\n```py\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\n\napp = FastAPI()\n\n\nclass Item(BaseModel):\n process_id: int\n\n\n@app.post(\"/do_something\")\nasync def do_something(item: Item):\n return item\n```\n\n```py\ndef test_do_something():\n response = client.post(\"/do_something\", json={\"process_id\": 16})\n return response.json()\n```\n\n```py\n@app.post(\"/do_something\")\nasync def do_something(process_id: int):\n return {\"process_id\": process_id}\n```\n\n```py\ndef test_do_something():\n response = client.post(\"/do_something\", params={\"process_id\": 16})\n return response.json()\n```\n\n```text\n@app.post(\"/do_something\")\ndef do_something(process_id: int = Body(..., embed=True)):\n return process_id\n```\n\n```text\nprocess_id\n```\n\n```text\nbody\n```\n\n```text\n\"/do_something?process_id=16\"\n```\n\n```text\nparams\n```\n\n```text\nBody(..., embed=True)\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.testclient import TestClient\n\napp = FastAPI()\n\n@app.post(\"/do_something/\")\nasync def do_something(process_id: int): # <--- same as in OP\n # some code\n return {\"process_id\": process_id}\n\n\nclient = TestClient(app)\nresponse = client.post(\n \"/do_something/\",\n params={\"process_id\": 16} # <--- different here\n)\nprint(response.json())\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.testclient import TestClient\n\napp = FastAPI()\n\n@app.post(\"/do_something/\")\nasync def do_something(item: dict[str, int]): # <--- expect a dict\n process_id = item.get(\"process_id\") # <--- get process_id\n # some code\n return {\"process_id\": process_id}\n\n\nclient = TestClient(app)\nresponse = client.post(\n \"/do_something/\",\n json={\"process_id\": 16} # <--- same as in OP\n)\nprint(response.json())\n```\n\n```text\nparams=\n```\n\n```text\ndict[str, int]\n```\n\n```text\nTypedDict\n```\n\n========================================\n\nComments:\n- Is it possible to do this without creating a Pydantic model? Normally, if I have multiple parameters, I use, for instance: `async def do_something_else(items: List[Dict], process_id: int = Body(...))` in the definition and `client.post(\"/do_something_else/\", json={\"process_id\": ..., \"items\": [{...}, {...}]})` for the call.\n- But `Body(...)` doesn't work if I have only one numeric parameter, as in the example in my question.","metadata":{"transformedAt":"2026-08-18T18:32:29.110Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":22,"totalLines":240,"estimatedTokens":1224}}208{"id":"stack-68850403","source":"stackoverflow","questionId":68850403,"title":"Best way to flatten and remap ORM to Pydantic Model","tags":["python","sqlalchemy","nested","fastapi","pydantic"],"text":"Title: Best way to flatten and remap ORM to Pydantic Model\nTags: python, sqlalchemy, nested, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI am using Pydantic with FastApi to output ORM data into JSON. I would like to flatten and remap the ORM model to eliminate an unnecessary level in the JSON.\n\nHere's a simplified example to illustrate the problem.\n\n```\noriginal output: {\"id\": 1, \"billing\": \n [\n {\"id\": 1, \"order_id\": 1, \"first_name\": \"foo\"},\n {\"id\": 2, \"order_id\": 1, \"first_name\": \"bar\"}\n ]\n }\n\ndesired output: {\"id\": 1, \"name\": [\"foo\", \"bar\"]}\n```\n\nHow to map values from nested dict to Pydantic Model? provides a solution that works for dictionaries by using the **init** function in the Pydantic model class. This example shows how that works with dictionaries:\n\n```\nfrom pydantic import BaseModel\n\n# The following approach works with a dictionary as the input\n\norder_dict = {\"id\": 1, \"billing\": {\"first_name\": \"foo\"}}\n\n# desired output: {\"id\": 1, \"name\": \"foo\"}\n\nclass Order_Model_For_Dict(BaseModel):\n id: int\n name: str = None\n\n class Config:\n orm_mode = True\n\n def __init__(self, **kwargs):\n print(\n \"kwargs for dictionary:\", kwargs\n ) # kwargs for dictionary: {'id': 1, 'billing': {'first_name': 'foo'}}\n kwargs[\"name\"] = kwargs[\"billing\"][\"first_name\"]\n super().__init__(**kwargs)\n\nprint(Order_Model_For_Dict.parse_obj(order_dict)) # id=1 name='foo'\n```\n\n(This script is complete, it should run \"as is\")\n\nHowever, when working with ORM objects, this approach does not work. It appears that the **init** function is not called. Here's an example which will not provide the desired output.\n\n```\nfrom pydantic import BaseModel, root_validator\nfrom typing import List\nfrom sqlalchemy.orm import relationship\nfrom sqlalchemy import Column, Integer, String, ForeignKey\nfrom sqlalchemy.dialects.postgresql import ARRAY\nfrom sqlalchemy.ext.declarative import declarative_base\nBase = declarative_base()\n\nfrom pydantic.utils import GetterDict\n\nclass BillingOrm(Base):\n __tablename__ = \"billing\"\n id = Column(Integer, primary_key=True, nullable=False)\n order_id = Column(ForeignKey(\"orders.id\", ondelete=\"CASCADE\"), nullable=False)\n first_name = Column(String(20))\n\nclass OrderOrm(Base):\n __tablename__ = \"orders\"\n id = Column(Integer, primary_key=True, nullable=False)\n billing = relationship(\"BillingOrm\")\n\nclass Billing(BaseModel):\n id: int\n order_id: int\n first_name: str\n\n class Config:\n orm_mode = True\n\nclass Order(BaseModel):\n id: int\n name: List[str] = None\n # billing: List[Billing] # uncomment to verify the relationship is working\n\n class Config:\n orm_mode = True\n\n def __init__(self, **kwargs):\n # This __init__ function does not run when using from_orm to parse ORM object\n print(\"kwargs for orm:\", kwargs)\n kwargs[\"name\"] = kwargs[\"billing\"][\"first_name\"]\n super().__init__(**kwargs)\n\nbilling_orm_1 = BillingOrm(id=1, order_id=1, first_name=\"foo\")\nbilling_orm_2 = BillingOrm(id=2, order_id=1, first_name=\"bar\")\norder_orm = OrderOrm(id=1)\norder_orm.billing.append(billing_orm_1)\norder_orm.billing.append(billing_orm_2)\n\norder_model = Order.from_orm(order_orm)\n# Output returns 'None' for name instead of ['foo','bar']\nprint(order_model) # id=1 name=None\n```\n\n(This script is complete, it should run \"as is\")\n\nThe output returns name=None instead of the desired list of names.\n\nIn the above example, I am using Order.from_orm to create the Pydantic model. This approach seems to be the same that is used by FastApi when specifying a response model. The desired solution should support use in the FastApi response model as shown in this example:\n\n```\n@router.get(\"/orders\", response_model=List[schemas.Order])\nasync def list_orders(db: Session = Depends(get_db)):\n return get_orders(db)\n```\n\nUpdate:\nRegarding MatsLindh comment to try validators, I replaced the **init** function with a root validator, however, I'm unable to mutate the return values to include a new attribute. I suspect this issue is because it is a ORM object and not a true dictionary. The following code will extract the names and print them in the desired list. However, I can't see how to include this updated result in the model response:\n\n```\n@root_validator(pre=True)\n def flatten(cls, values):\n if isinstance(values, GetterDict):\n names = [\n billing_entry.first_name for billing_entry in values.get(\"billing\")\n ]\n print(names)\n # values[\"name\"] = names # error: 'GetterDict' object does not support item assignment\n return values\n```\n\nI also found a couple other discussions on this problem that led me to try this approach:\nhttps://github.com/samuelcolvin/pydantic/issues/717\nhttps://gitmemory.com/issue/samuelcolvin/pydantic/821/744047672\n\n========================================\n\nTop Answer:\nI really missed the handy Django REST Framework serializers while working with the FastAPI + Pydantic stack... So I wrangled with GetterDict to allow defining field getter function in the Pydantic model like this:\n\n```\nclass User(FromORM):\n\n fullname: str\n\n class Config(FromORM.Config):\n getter_dict = FieldGetter.bind(lambda: User)\n\n @staticmethod\n def get_fullname(obj: User) -> str:\n return f'{obj.firstname} {obj.lastname}'\n```\n\nwhere the magic part `FieldGetter` is implemented as\n\n```\nfrom typing import Any, Callable, Optional, Type\nfrom types import new_class\nfrom pydantic import BaseModel\nfrom pydantic.utils import GetterDict\n\nclass FieldGetter(GetterDict):\n\n model_class_forward_ref: Optional[Callable] = None\n model_class: Optional[Type[BaseModel]] = None\n\n def __new__(cls, *args, **kwargs):\n inst = super().__new__(cls)\n if cls.model_class_forward_ref:\n inst.model_class = cls.model_class_forward_ref()\n\n return inst\n\n @classmethod\n def bind(cls, model_class_forward_ref: Callable):\n sub_class = new_class(f'{cls.__name__}FieldGetter', (cls,))\n sub_class.model_class_forward_ref = model_class_forward_ref\n return sub_class\n\n def get(self, key: str, default):\n if hasattr(self._obj, key):\n return super().get(key, default)\n\n getter_fun_name = f'get_{key}'\n if not (getter := getattr(self.model_class, getter_fun_name, None)):\n raise AttributeError(f'no field getter function found for {key}')\n\n return getter(self._obj)\n\nclass FromORM(BaseModel):\n\n class Config:\n orm_mode = True\n getter_dict = FieldGetter\n```\n\n========================================\n\nCode:\n```text\noriginal output: {\"id\": 1, \"billing\": \n [\n {\"id\": 1, \"order_id\": 1, \"first_name\": \"foo\"},\n {\"id\": 2, \"order_id\": 1, \"first_name\": \"bar\"}\n ]\n }\n\ndesired output: {\"id\": 1, \"name\": [\"foo\", \"bar\"]}\n```\n\n```text\nfrom pydantic import BaseModel\n\n# The following approach works with a dictionary as the input\n\norder_dict = {\"id\": 1, \"billing\": {\"first_name\": \"foo\"}}\n\n# desired output: {\"id\": 1, \"name\": \"foo\"}\n\n\nclass Order_Model_For_Dict(BaseModel):\n id: int\n name: str = None\n\n class Config:\n orm_mode = True\n\n def __init__(self, **kwargs):\n print(\n \"kwargs for dictionary:\", kwargs\n ) # kwargs for dictionary: {'id': 1, 'billing': {'first_name': 'foo'}}\n kwargs[\"name\"] = kwargs[\"billing\"][\"first_name\"]\n super().__init__(**kwargs)\n\n\nprint(Order_Model_For_Dict.parse_obj(order_dict)) # id=1 name='foo'\n```\n\n```text\nfrom pydantic import BaseModel, root_validator\nfrom typing import List\nfrom sqlalchemy.orm import relationship\nfrom sqlalchemy import Column, Integer, String, ForeignKey\nfrom sqlalchemy.dialects.postgresql import ARRAY\nfrom sqlalchemy.ext.declarative import declarative_base\nBase = declarative_base()\n\nfrom pydantic.utils import GetterDict\n\nclass BillingOrm(Base):\n __tablename__ = \"billing\"\n id = Column(Integer, primary_key=True, nullable=False)\n order_id = Column(ForeignKey(\"orders.id\", ondelete=\"CASCADE\"), nullable=False)\n first_name = Column(String(20))\n\n\nclass OrderOrm(Base):\n __tablename__ = \"orders\"\n id = Column(Integer, primary_key=True, nullable=False)\n billing = relationship(\"BillingOrm\")\n\n\nclass Billing(BaseModel):\n id: int\n order_id: int\n first_name: str\n\n class Config:\n orm_mode = True\n\n\nclass Order(BaseModel):\n id: int\n name: List[str] = None\n # billing: List[Billing] # uncomment to verify the relationship is working\n\n class Config:\n orm_mode = True\n\n def __init__(self, **kwargs):\n # This __init__ function does not run when using from_orm to parse ORM object\n print(\"kwargs for orm:\", kwargs)\n kwargs[\"name\"] = kwargs[\"billing\"][\"first_name\"]\n super().__init__(**kwargs)\n\n\nbilling_orm_1 = BillingOrm(id=1, order_id=1, first_name=\"foo\")\nbilling_orm_2 = BillingOrm(id=2, order_id=1, first_name=\"bar\")\norder_orm = OrderOrm(id=1)\norder_orm.billing.append(billing_orm_1)\norder_orm.billing.append(billing_orm_2)\n\norder_model = Order.from_orm(order_orm)\n# Output returns 'None' for name instead of ['foo','bar']\nprint(order_model) # id=1 name=None\n```\n\n```text\n@router.get(\"/orders\", response_model=List[schemas.Order])\nasync def list_orders(db: Session = Depends(get_db)):\n return get_orders(db)\n```\n\n```text\n@root_validator(pre=True)\n def flatten(cls, values):\n if isinstance(values, GetterDict):\n names = [\n billing_entry.first_name for billing_entry in values.get(\"billing\")\n ]\n print(names)\n # values[\"name\"] = names # error: 'GetterDict' object does not support item assignment\n return values\n```\n\n```text\nclass Order(BaseModel):\n id: int\n name: List[str] = None\n billing: List[Billing]\n\n class Config:\n orm_mode = True\n\n @classmethod\n def from_orm(cls, obj: Any) -> 'Order':\n # `obj` is the orm model instance\n if hasattr(obj, 'billing'):\n obj.name = obj.billing.first_name\n return super().from_orm(obj)\n```\n\n```text\nfrom_orm\n```\n\n```text\nclass User(FromORM):\n\n fullname: str\n\n class Config(FromORM.Config):\n getter_dict = FieldGetter.bind(lambda: User)\n\n @staticmethod\n def get_fullname(obj: User) -> str:\n return f'{obj.firstname} {obj.lastname}'\n```\n\n```text\nfrom typing import Any, Callable, Optional, Type\nfrom types import new_class\nfrom pydantic import BaseModel\nfrom pydantic.utils import GetterDict\n\n\nclass FieldGetter(GetterDict):\n\n model_class_forward_ref: Optional[Callable] = None\n model_class: Optional[Type[BaseModel]] = None\n\n def __new__(cls, *args, **kwargs):\n inst = super().__new__(cls)\n if cls.model_class_forward_ref:\n inst.model_class = cls.model_class_forward_ref()\n\n return inst\n\n @classmethod\n def bind(cls, model_class_forward_ref: Callable):\n sub_class = new_class(f'{cls.__name__}FieldGetter', (cls,))\n sub_class.model_class_forward_ref = model_class_forward_ref\n return sub_class\n\n def get(self, key: str, default):\n if hasattr(self._obj, key):\n return super().get(key, default)\n\n getter_fun_name = f'get_{key}'\n if not (getter := getattr(self.model_class, getter_fun_name, None)):\n raise AttributeError(f'no field getter function found for {key}')\n\n return getter(self._obj)\n\n\nclass FromORM(BaseModel):\n\n class Config:\n orm_mode = True\n getter_dict = FieldGetter\n```\n\n```text\nFieldGetter\n```\n\n========================================\n\nComments:\n- How about using a validator? pydantic-docs.helpmanual.io/usage/validators\n- @MatsLindh - thanks -- I found some suggestions on using a root_validator but still unsuccessful. I was able to access the ORM object which was a step forward over using **init** function. See my updated comments with details and references.\n- Thanks! This approach worked with one adjustment. The ORM model must include the attribute which is to be updated. If it doesn't include this attribute, then you can dynamically add the attribute in the from_orm method. For this example, add this statement: setattr(obj, \"name\", None)\n- Yep, that's the best we can do right now I guess. Though I prefer to first call `super` and then set an attribute on pydantic model instance rather than on db model instance. :)","metadata":{"transformedAt":"2026-08-18T18:32:29.110Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":10,"totalLines":406,"estimatedTokens":3031}}209{"id":"stack-61952845","source":"stackoverflow","questionId":61952845,"title":"FastAPI Single Parameter Body cause Pydantic Validation Error","tags":["python","http-post","httprequest","fastapi","pydantic"],"text":"Title: FastAPI Single Parameter Body cause Pydantic Validation Error\nTags: python, http-post, httprequest, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI have a POST FastAPI method. I do not want to construct a class nor query string. So, I decide to apply `Body()` method.\n\n```\n@app.post(\"/test-single-int\")\nasync def test_single_int(\n t: int = Body(...)\n):\n pass\n```\n\nThis is the request\n\n```\nPOST http://localhost:8000/test-single-int/\n\n{\n \"t\": 10\n}\n```\n\nAnd this is the response\n\n```\nHTTP/1.1 422 Unprocessable Entity\ndate: Fri, 22 May 2020 10:00:16 GMT\nserver: uvicorn\ncontent-length: 83\ncontent-type: application/json\nconnection: close\n\n{\n \"detail\": [\n {\n \"loc\": [\n \"body\",\n \"s\"\n ],\n \"msg\": \"str type expected\",\n \"type\": \"type_error.str\"\n }\n ]\n}\n```\n\nHowever, after trying with many samples, I found that they will not error if I have more than one `Body()`. For example,\n\n```\n@app.post(\"/test-multi-mix\")\nasync def test_multi_param(\n s: str = Body(...),\n t: int = Body(...),\n):\n pass\n```\n\nRequest\n\n```\nPOST http://localhost:8000/test-multi-mix/\n\n{\n \"s\": \"test\",\n \"t\": 10\n}\n```\n\nResponse\n\n```\nHTTP/1.1 200 OK\ndate: Fri, 22 May 2020 10:16:12 GMT\nserver: uvicorn\ncontent-length: 4\ncontent-type: application/json\nconnection: close\n\nnull\n```\n\nDoes anyone have any idea about my implementation? Are there wrong? Is it not best practice? Or it is a bug?\n\n========================================\n\nTop Answer:\nTo get any data from body with FastApi:\n\n```\n@app.post(\"/someurl\")\nasync def someMethod(body: dict):\n return body\n```\n\n========================================\n\nCode:\n```py\n@app.post(\"/test-single-int\")\nasync def test_single_int(\n t: int = Body(...)\n):\n pass\n```\n\n```text\nPOST http://localhost:8000/test-single-int/\n\n{\n \"t\": 10\n}\n```\n\n```text\nHTTP/1.1 422 Unprocessable Entity\ndate: Fri, 22 May 2020 10:00:16 GMT\nserver: uvicorn\ncontent-length: 83\ncontent-type: application/json\nconnection: close\n\n{\n \"detail\": [\n {\n \"loc\": [\n \"body\",\n \"s\"\n ],\n \"msg\": \"str type expected\",\n \"type\": \"type_error.str\"\n }\n ]\n}\n```\n\n```py\n@app.post(\"/test-multi-mix\")\nasync def test_multi_param(\n s: str = Body(...),\n t: int = Body(...),\n):\n pass\n```\n\n```text\nPOST http://localhost:8000/test-multi-mix/\n\n{\n \"s\": \"test\",\n \"t\": 10\n}\n```\n\n```text\nHTTP/1.1 200 OK\ndate: Fri, 22 May 2020 10:16:12 GMT\nserver: uvicorn\ncontent-length: 4\ncontent-type: application/json\nconnection: close\n\nnull\n```\n\n```text\nBody()\n```\n\n```text\nBody()\n```\n\n```text\nclass Item(BaseModel):\n name: str\n\nclass User(BaseModel):\n username: str\n full_name: str = None\n\n\n@app.put(\"/items/{item_id}\")\nasync def update_item(\n *,\n item_id: int,\n item: Item,\n user: User,\n importance: int = Body(..., gt=0),\n q: str = None\n):\n pass\n```\n\n```text\n{\n \"item\": {\n \"name\": \"Foo\",\n \"tax\": 3.2\n },\n \"user\": {\n \"username\": \"dave\",\n \"full_name\": \"Dave Grohl\"\n },\n \"importance\": 5\n}\n```\n\n```text\n@app.put(\"/items/{item_id}\")\nasync def update_item(\n *,\n item_id:int,\n importance: int = Body(..., gt=0, embed=True),\n q: str = None\n):\n pass\n```\n\n```text\nembed=True\n```\n\n```text\n@app.post(\"/someurl\")\nasync def someMethod(body: dict):\n return body\n```\n\n========================================\n\nComments:\n- I don't really understand why Body behaves like that by default. Do you have a good example of why they made that the default behaviour?","metadata":{"transformedAt":"2026-08-18T18:32:29.110Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":13,"totalLines":235,"estimatedTokens":859}}210{"id":"stack-68394091","source":"stackoverflow","questionId":68394091,"title":"fastapi + sqlalchemy + pydantic → how to process many-to-many relations","tags":["python","sqlalchemy","fastapi","pydantic"],"text":"Title: fastapi + sqlalchemy + pydantic → how to process many-to-many relations\nTags: python, sqlalchemy, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI have `editor`s and `article`s. Many editors may be related to many articles and many articles may have many editors at same time.\n\nMy DB tables are\n\n- **Article**\n\nid\nsubject\ntext\n\n1\nNew Year Holidays\nIn this year... etc etc etc\n\n- **Editor**\n\nid\nname\nemail\n\n1\nJohn Smith\nsome@email\n\n- **EditorArticleRelation**\n\neditor_id\narticle_id\n\n1\n1\n\nMy models are\n\n```\nfrom sqlalchemy import Boolean, Column, Integer, String, ForeignKey\nfrom sqlalchemy.orm import relationship\n\nfrom database import Base\n\nclass Editor(Base):\n __tablename__ = \"editor\"\n\n id = Column(Integer, primary_key=True, index=True)\n name = Column(String(32), unique=False, index=False, nullable=True)\n email = Column(String(115), unique=True, index=True)\n articles = relationship(\"Article\",\n secondary=EditorArticleRelation,\n back_populates=\"articles\",\n cascade=\"all, delete\")\n\nclass Article(Base):\n __tablename__ = \"article\"\n\n id = Column(Integer, primary_key=True, index=True)\n subject = Column(String(32), unique=True, index=False)\n text = Column(String(256), unique=True, index=True, nullable=True)\n editors = relationship(\"Editor\",\n secondary=EditorArticleRelation,\n back_populates=\"editors\",\n cascade=\"all, delete\")\n\nEditorArticleRelation = Table('editorarticlerelation', Base.metadata,\n Column('editor_id', Integer, ForeignKey('editor.id')),\n Column('article_id', Integer, ForeignKey('article.id'))\n)\n```\n\nMy schemas are\n\n```\nfrom typing import Optional, List\nfrom pydantic import BaseModel\n\nclass EditorBase(BaseModel):\n name: Optional[str]\n email: str\n\nclass EditorCreate(EditorBase):\n pass\n\nclass Editor(EditorBase):\n id: int\n\n class Config:\n orm_mode = True\n\nclass ArticleBase(BaseModel):\n subject: str\n text: str\n\nclass ArticleCreate(ArticleBase):\n # WHAT I NEED TO SET HERE???\n editor_ids: List[int] = []\n\nclass Article(ArticleBase):\n id: int\n editors: List[Editor] = []\n\n class Config:\n orm_mode = True\n```\n\nMy crud\n\n```\ndef create_article(db: Session, article_data: schema.ArticleCreate):\n db_article = model.Article(subject=article_data.subject, text=article_data.text, ??? HOW TO SET EDITORS HERE ???)\n db.add(db_article)\n db.commit()\n db.refresh(db_article)\n return db_article\n```\n\nMy route\n\n```\n@app.post(\"/articles/\", response_model=schema.Article)\ndef create_article(article_data: schema.ArticleCreate, db: Session = Depends(get_db)):\n db_article = crud.get_article_by_name(db, name=article_data.name)\n if db_article:\n raise HTTPException(status_code=400, detail=\"article already registered\")\n if len(getattr(article_data, 'editor_ids', [])) > 0:\n ??? WHAT I NEED TO SET HERE???\n return crud.create_article(db=db, article_data=article_data)\n```\n\n### What I want →\n\nI want to post data for article creation API and automatically resolve and add editor relations, or raise error if some of editors doesn't exist:\n\n```\n{\n \"subject\": \"Fresh news\"\n \"text\": \"Today is ...\"\n \"editor_ids\": [1, 2, ...]\n}\n```\n\n### Questions are:\n\n- How to correctly set crud operations (`HOW TO SET EDITORS HERE` place)?\n\n- How to correctly set create/read schemas and relation fields (especially `WHAT I NEED TO SET HERE` place)?\n\n- How to correctly set route code (especially `WHAT I NEED TO SET HERE` place)?\n\n- If here is no possible to resolve relations automatically, what place will be better to resolve relations (check if editor exists, etc)? route or crud?\n\n- Maybe my way is bad at all? If you know any examples how to handle many-to-many relations with `pydantic` and `sqlalchemy`, any information will be welcome\n\n========================================\n\nTop Answer:\nA solution I found.\n\n```\ndef create_user_groups(db: Session, user_groups: schemas.UserGroupsBase):\n db_user = db.query(models.User).filter(models.User.id == user_groups.id_user).first()\n db_group = db.query(models.Group).filter(models.Group.id == user_groups.id_group).first()\n\n if not db_user and db_group:\n raise HTTPException(status_code=409, detail=\"User or Group not found in system.\")\n\n db_user.groups.append(db_group)\n\n db.add(db_user)\n db.commit()\n db.refresh(db_user)\n return db_user\n```\n\n========================================\n\nCode:\n```py\nfrom sqlalchemy import Boolean, Column, Integer, String, ForeignKey\nfrom sqlalchemy.orm import relationship\n\nfrom database import Base\n\nclass Editor(Base):\n __tablename__ = \"editor\"\n\n id = Column(Integer, primary_key=True, index=True)\n name = Column(String(32), unique=False, index=False, nullable=True)\n email = Column(String(115), unique=True, index=True)\n articles = relationship(\"Article\",\n secondary=EditorArticleRelation,\n back_populates=\"articles\",\n cascade=\"all, delete\")\n\nclass Article(Base):\n __tablename__ = \"article\"\n\n id = Column(Integer, primary_key=True, index=True)\n subject = Column(String(32), unique=True, index=False)\n text = Column(String(256), unique=True, index=True, nullable=True)\n editors = relationship(\"Editor\",\n secondary=EditorArticleRelation,\n back_populates=\"editors\",\n cascade=\"all, delete\")\n\nEditorArticleRelation = Table('editorarticlerelation', Base.metadata,\n Column('editor_id', Integer, ForeignKey('editor.id')),\n Column('article_id', Integer, ForeignKey('article.id'))\n)\n```\n\n```py\nfrom typing import Optional, List\nfrom pydantic import BaseModel\n\nclass EditorBase(BaseModel):\n name: Optional[str]\n email: str\n\nclass EditorCreate(EditorBase):\n pass\n\nclass Editor(EditorBase):\n id: int\n\n class Config:\n orm_mode = True\n\nclass ArticleBase(BaseModel):\n subject: str\n text: str\n\nclass ArticleCreate(ArticleBase):\n # WHAT I NEED TO SET HERE???\n editor_ids: List[int] = []\n\nclass Article(ArticleBase):\n id: int\n editors: List[Editor] = []\n\n class Config:\n orm_mode = True\n```\n\n```py\ndef create_article(db: Session, article_data: schema.ArticleCreate):\n db_article = model.Article(subject=article_data.subject, text=article_data.text, ??? HOW TO SET EDITORS HERE ???)\n db.add(db_article)\n db.commit()\n db.refresh(db_article)\n return db_article\n```\n\n```py\n@app.post(\"/articles/\", response_model=schema.Article)\ndef create_article(article_data: schema.ArticleCreate, db: Session = Depends(get_db)):\n db_article = crud.get_article_by_name(db, name=article_data.name)\n if db_article:\n raise HTTPException(status_code=400, detail=\"article already registered\")\n if len(getattr(article_data, 'editor_ids', [])) > 0:\n ??? WHAT I NEED TO SET HERE???\n return crud.create_article(db=db, article_data=article_data)\n```\n\n```json\n{\n \"subject\": \"Fresh news\"\n \"text\": \"Today is ...\"\n \"editor_ids\": [1, 2, ...]\n}\n```\n\n```text\neditor\n```\n\n```text\narticle\n```\n\n```text\nHOW TO SET EDITORS HERE\n```\n\n```text\nWHAT I NEED TO SET HERE\n```\n\n```text\nWHAT I NEED TO SET HERE\n```\n\n```text\npydantic\n```\n\n```text\nsqlalchemy\n```\n\n```py\n...\n@app.post(\"/articles/\", response_model=schema.Article)\ndef create_article(article_data: schema.ArticleCreate, db: Session = Depends(get_db)):\n db_article = crud.get_article_by_name(db, name=article_data.name)\n if db_article:\n raise HTTPException(status_code=400, detail=\"article already registered\")\n return crud.create_article(db=db, article_data=article_data)\n...\n```\n\n```py\n...\nclass ArticleCreate(ArticleBase):\n editor_ids: List[int] = []\n...\n```\n\n```py\ndef create_article(db: Session, article_data: schema.ArticleCreate):\n db_article = model.Article(subject=article_data.subject, text=article_data.text)\n if (editors := db.query(model.Editor).filter(model.Editor.id.in_(article_data.editor_ids))).count() == len(endpoint_data.topic_ids):\n db_article.topics.extend(editors)\n else:\n # even if at least one editor is not found, an error is raised\n # if existence is not matter you can skip this check and add relations only for existing data\n raise HTTPException(status_code=404, detail=\"editor not found\")\n db.add(db_article)\n db.commit()\n db.refresh(db_article)\n return db_article\n```\n\n```text\ndef create_user_groups(db: Session, user_groups: schemas.UserGroupsBase):\n db_user = db.query(models.User).filter(models.User.id == user_groups.id_user).first()\n db_group = db.query(models.Group).filter(models.Group.id == user_groups.id_group).first()\n\n if not db_user and db_group:\n raise HTTPException(status_code=409, detail=\"User or Group not found in system.\")\n\n db_user.groups.append(db_group)\n\n db.add(db_user)\n db.commit()\n db.refresh(db_user)\n return db_user\n```\n\n========================================\n\nComments:\n- This answer could benefit from an explanation. Here are some guidelines for How do I write a good answer?. Code only answers are **not considered good answers** and are likely to be downvoted and/or deleted because they are **less useful** to a community of learners. It's only obvious to you. Explain what it does, and how it's different / better than the existing answer from the author of the OP. From Review\n- @Brayan Your answer is mostly repeating `create_article` method in my own answer.","metadata":{"transformedAt":"2026-08-18T18:32:29.110Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":16,"totalLines":357,"estimatedTokens":2314}}211{"id":"stack-76159708","source":"stackoverflow","questionId":76159708,"title":"How to disable Authentication in FastAPI based on environment?","tags":["python","authorization","fastapi","swagger-ui","openapi"],"text":"Title: How to disable Authentication in FastAPI based on environment?\nTags: python, authorization, fastapi, swagger-ui, openapi\nSource: Stack Overflow\n\nQuestion:\nI have a FastAPI application for which I enable `Authentication` by injecting a dependency function.\n\ncontroller.py\n\n```\nrouter = APIRouter(\n prefix=\"/v2/test\",\n tags=[\"helloWorld\"],\n dependencies=[Depends(api_key)],\n responses={404: {\"description\": \"Not found\"}},\n)\n```\n\nAuthorzation.py\n\n```\nasync def api_key(api_key_header: str = Security(api_key_header_auth)):\n if api_key_header != API_KEY:\n raise HTTPException(\n status_code=401,\n detail=\"Invalid API Key\",\n )\n```\n\nThis works fine. However, I would like to **disable** the authentication based on environment. For instance, I would want to keep entering the authentication key in `localhost` environment.\n\n========================================\n\nCode:\n```py\nrouter = APIRouter(\n prefix=\"/v2/test\",\n tags=[\"helloWorld\"],\n dependencies=[Depends(api_key)],\n responses={404: {\"description\": \"Not found\"}},\n)\n```\n\n```py\nasync def api_key(api_key_header: str = Security(api_key_header_auth)):\n if api_key_header != API_KEY:\n raise HTTPException(\n status_code=401,\n detail=\"Invalid API Key\",\n )\n```\n\n```text\nAuthentication\n```\n\n```text\nlocalhost\n```\n\n```py\nfrom fastapi import FastAPI, Request, Depends, HTTPException\nfrom starlette.status import HTTP_403_FORBIDDEN\nfrom fastapi.security.api_key import APIKeyHeader\nfrom fastapi import Security\nfrom typing import Optional\n\nAPI_KEY = 'some-api-key'\nAPI_KEY_NAME = 'X-API-KEY'\nsafe_clients = ['127.0.0.1']\n\n\nclass MyAPIKeyHeader(APIKeyHeader):\n async def __call__(self, request: Request) -> Optional[str]:\n # `safe_clients` won't need to provide an API key\n if request.client.host in safe_clients:\n api_key = API_KEY\n else:\n api_key = request.headers.get(self.model.name)\n if not api_key:\n if self.auto_error:\n raise HTTPException(\n status_code=HTTP_403_FORBIDDEN, detail='Not authenticated'\n )\n else:\n return None\n\n return api_key\n\n\napi_key_header_auth = MyAPIKeyHeader(name=API_KEY_NAME)\n\n\nasync def check_api_key(request: Request, api_key: str = Security(api_key_header_auth)):\n if api_key != API_KEY:\n raise HTTPException(status_code=401, detail='Invalid API Key')\n\n \napp = FastAPI(dependencies=[Depends(check_api_key)])\n\n\n@app.get('/')\ndef main(request: Request):\n return request.client.host\n```\n\n```py\nfrom fastapi import FastAPI, Request, Security, Depends, HTTPException\nfrom fastapi.security.api_key import APIKeyHeader\n\n\n# List of valid API keys\nAPI_KEYS = [\n 'z77xQYZWROmI4fY4',\n 'FXhO4i3bLA1WIsvR'\n]\nAPI_KEY_NAME = 'X-API-KEY'\nsafe_clients = ['127.0.0.1']\napi_key_header = APIKeyHeader(name=API_KEY_NAME, auto_error=False)\n\n\nasync def check_api_key(request: Request, api_key: str = Security(api_key_header)):\n # `safe_clients` won't need to provide an API key\n if api_key not in API_KEYS and request.client.host not in safe_clients:\n raise HTTPException(status_code=401, detail='Invalid or missing API Key')\n\n \napp = FastAPI(dependencies=[Depends(check_api_key)])\n\n\n@app.get('/')\ndef main(request: Request):\n return request.client.host\n```\n\n```py\nimport requests\n\nAPI_KEY = \"z77xQYZWROmI4fY4\"\nheaders = {\"X-API-KEY\": API_KEY}\nr = requests.get(url=\"http://127.0.0.1:8000/\", headers=headers)\nprint(r.status_code, r.json())\n```\n\n```py\nfrom fastapi import Response\n\n# ... rest of the code is the same as above\n\napp = FastAPI(dependencies=[Depends(check_api_key)])\n\n\n@app.middleware(\"http\")\nasync def remove_auth_btn(request: Request, call_next):\n response = await call_next(request)\n if request.url.path == '/openapi.json' and request.client.host in safe_clients:\n response_body = [section async for section in response.body_iterator]\n resp_str = response_body[0].decode() # convert \"response_body\" bytes into string\n resp_dict = json.loads(resp_str) # convert \"resp_str\" into dict\n del resp_dict['components']['securitySchemes'] # remove securitySchemes\n resp_str = json.dumps(resp_dict) # convert \"resp_dict\" back to str\n return Response(content=resp_str, status_code=response.status_code, media_type=response.media_type)\n \n return response\n```\n\n```text\nAPIKeyHeader\n```\n\n```text\n__call__()\n```\n\n```text\nclient\n```\n\n```text\nlocalhost\n```\n\n```text\n127.0.0.1\n```\n\n```text\nrequest.client.host\n```\n\n```text\napi_key\n```\n\n```text\nAPI_KEY\n```\n\n```text\ncheck_api_key()\n```\n\n```text\napi_key\n```\n\n```text\n__call__()\n```\n\n```text\ncheck_api_key()\n```\n\n```text\nsafe_clients\n```\n\n```text\nAPIKeyHeader\n```\n\n```text\nauto_error\n```\n\n```text\nFalse\n```\n\n```text\nAPIKeyHeader\n```\n\n```text\napi_key\n```\n\n```text\ncheck_api_key()\n```\n\n```text\nAuthorize\n```\n\n```text\nsafe_clients\n```\n\n```text\nAuthorize\n```\n\n```text\n/docs\n```\n\n```text\nAuthorize\n```\n\n```text\nsafe_clients\n```\n\n```text\nsecuritySchemes\n```\n\n```text\n/openapi.json\n```\n\n```text\napp = FastAPI(dependencies=...)\n```\n\n========================================\n\nComments:\n- I think that you can do it playing with the `.env` file then read it and on your Authorization.py put something like: `if os.environ.get(\"ENVIRONMENT\") == \"development\":`.\n- as I have already injected the dependency how will I by pass it?\n- This way I will be applying key through code for safe clients. I want to entirely remove the depends on authorization if the request comes from local host. So that we don't see an authorize button at all. Is this possible? to set decency in router based on safe clients?","metadata":{"transformedAt":"2026-08-18T18:32:29.110Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":36,"totalLines":284,"estimatedTokens":1427}}212{"id":"stack-77245595","source":"stackoverflow","questionId":77245595,"title":"FastAPI TestClient overriding lifespan function","tags":["python","python-3.x","dependency-injection","fastapi"],"text":"Title: FastAPI TestClient overriding lifespan function\nTags: python, python-3.x, dependency-injection, fastapi\nSource: Stack Overflow\n\nQuestion:\nIn a more complicated setup using the python dependency injector framework I use the lifespan function for the FastAPI app object to correctly wire everything.\n\nWhen testing I'd like to replace some of the objects with different versions (fakes), and the natural way to accomplish that seems to me like I should override or mock the lifespan function of the app object. However I can't seem to figure out if/how I can do that.\n\nMRE follows\n\n```\nimport pytest\nfrom contextlib import asynccontextmanager\nfrom fastapi.testclient import TestClient\nfrom fastapi import FastAPI, Response, status\n\ngreeting = None\n\n@asynccontextmanager\nasync def _lifespan(app: FastAPI):\n # Initialize dependency injection\n global greeting\n greeting = \"Hello\"\n yield\n\n@asynccontextmanager\nasync def _lifespan_override(app: FastAPI):\n # Initialize dependency injection\n global greeting\n greeting = \"Hi\"\n yield\n\napp = FastAPI(title=\"Test\", lifespan=_lifespan)\n\n@app.get(\"/\")\nasync def root():\n return Response(status_code=status.HTTP_200_OK, content=greeting)\n\n@pytest.fixture\ndef fake_client():\n with TestClient(app) as client:\n yield client\n\ndef test_override(fake_client):\n response = fake_client.get(\"/\")\n assert response.text == \"Hi\"\n```\n\nSo basically in the `fake_client` fixture I'd like to change it to use the `_lifespan_override` instead of the original `_lifespan`, making the dummy test-case above pass\n\nI'd have expected something like `with TestClient(app, lifespan=_lifespan_override) as client:` to work, but that's not supported. Is there some way I can mock it to get the behavior I want?\n\n(The mre above works if you replace \"Hi\" with \"Hello\" in the assert statement)\n\npyproject.toml below with needed dependencies\n\n```\n[tool.poetry]\nname = \"mre\"\nversion = \"0.1.0\"\ndescription = \"mre\"\nauthors = []\n\n[tool.poetry.dependencies]\npython = \"^3.10\"\nfastapi = \"^0.103.2\"\n\n[tool.poetry.group.dev.dependencies]\npytest = \"^7.1.2\"\nhttpx = \"^0.25.0\"\n\n[build-system]\nrequires = [\"poetry-core\"]\nbuild-backend = \"poetry.core.masonry.api\"\n```\n\nEDIT:\nTried extending my code with the suggestion from Hamed Akhavan below as follows\n\n```\n@pytest.fixture\ndef fake_client():\n app.dependency_overrides[_lifespan] = _lifespan_override\n with TestClient(app) as client:\n yield client\n```\n\nbut it doesn't work, even though it looks like it should be the right approach. Syntax problem?\n\n========================================\n\nTop Answer:\nYou can do it like this:\n\n```\nfrom starlette.routing import _DefaultLifespan\n\n@pytest.fixture\ndef client():\n # import app here\n # mock lifespan\n app.router.lifespan_context = _DefaultLifespan(app.router)\n\n with TestClient(app) as client:\n yield client\n```\n\n========================================\n\nCode:\n```py\nimport pytest\nfrom contextlib import asynccontextmanager\nfrom fastapi.testclient import TestClient\nfrom fastapi import FastAPI, Response, status\n\n\ngreeting = None\n\n@asynccontextmanager\nasync def _lifespan(app: FastAPI):\n # Initialize dependency injection\n global greeting\n greeting = \"Hello\"\n yield\n\n\n@asynccontextmanager\nasync def _lifespan_override(app: FastAPI):\n # Initialize dependency injection\n global greeting\n greeting = \"Hi\"\n yield\n\n\napp = FastAPI(title=\"Test\", lifespan=_lifespan)\n\n\n@app.get(\"/\")\nasync def root():\n return Response(status_code=status.HTTP_200_OK, content=greeting)\n\n\n@pytest.fixture\ndef fake_client():\n with TestClient(app) as client:\n yield client\n\n\ndef test_override(fake_client):\n response = fake_client.get(\"/\")\n assert response.text == \"Hi\"\n```\n\n```text\n[tool.poetry]\nname = \"mre\"\nversion = \"0.1.0\"\ndescription = \"mre\"\nauthors = []\n\n[tool.poetry.dependencies]\npython = \"^3.10\"\nfastapi = \"^0.103.2\"\n\n[tool.poetry.group.dev.dependencies]\npytest = \"^7.1.2\"\nhttpx = \"^0.25.0\"\n\n\n[build-system]\nrequires = [\"poetry-core\"]\nbuild-backend = \"poetry.core.masonry.api\"\n```\n\n```py\n@pytest.fixture\ndef fake_client():\n app.dependency_overrides[_lifespan] = _lifespan_override\n with TestClient(app) as client:\n yield client\n```\n\n```text\nfake_client\n```\n\n```text\n_lifespan_override\n```\n\n```text\n_lifespan\n```\n\n```text\nwith TestClient(app, lifespan=_lifespan_override) as client:\n```\n\n```py\nimport pytest\nfrom contextlib import asynccontextmanager\nfrom fastapi.testclient import TestClient\nfrom fastapi import FastAPI, Response, status, Depends\nfrom dependency_injector import containers, providers\nfrom dependency_injector.wiring import Provide, inject\n\n\nclass HelloGreeter():\n def greet(self):\n return \"Hello\"\n\n\nclass Container(containers.DeclarativeContainer):\n greeter = providers.Singleton(HelloGreeter)\n\n\n@asynccontextmanager\nasync def _lifespan(app: FastAPI):\n # Initialize dependency injection\n container = Container()\n container.wire(modules=[__name__])\n yield\n\n\napp = FastAPI(title=\"Test\", lifespan=_lifespan)\n\n\n@app.get(\"/\")\n@inject\nasync def root(greeter=Depends(Provide[Container.greeter])):\n return Response(status_code=status.HTTP_200_OK, content=greeter.greet())\n\n\n@pytest.fixture\ndef fake_client():\n class HiGreeter():\n def greet(self):\n return \"Hi\"\n with Container.greeter.override(HiGreeter()):\n with TestClient(app) as client:\n yield client\n\n\ndef test_override(fake_client):\n response = fake_client.get(\"/\")\n assert response.text == \"Hi\"\n```\n\n```text\nimport app # import your FastAPI app\napp.dependency_overrides[lifespan] = _lifespan\n```\n\n```text\nlifespan\n```\n\n```text\nfrom starlette.routing import _DefaultLifespan\n\n@pytest.fixture\ndef client():\n # import app here\n # mock lifespan\n app.router.lifespan_context = _DefaultLifespan(app.router)\n\n with TestClient(app) as client:\n yield client\n```\n\n```text\n@pytest.fixture\ndef client():\n # import app here\n # mock lifespan\n app.router.lifespan_context = YOUR_LIFESPAN_FOR_TEST\n\n with TestClient(app) as client:\n yield client\n```\n\n```text\nlifespan\n```\n\n```text\napp.router.lifespan_context\n```\n\n```text\nfrom fastapi import FastAPI\n\n\ndef create_app(life_span_method: Callable):\n \"\"\" The main application factory it create the fastapi application\"\"\"\n app = FastAPI(lifespan=life_span_method)\n\n # You can include your routers here.\n return app\n```\n\n```text\n@pytest.fixture(name=\"test_app\")\ndef test_lifespan_dependencies(mock_object, ):\n\n from aim.components.api.app_factory import create_app\n @asynccontextmanager\n async def mock_lifespan(app):\n yield {\n \"mock_object\": mock_object\n }\n app = create_app(life_span_method=mock_lifespan)\n yield app\n\n@pytest.fixture\ndef client(test_app):\n \"\"\"Test client using mock app.\n Use a context manager as per: \n https://www.starlette.dev/lifespan/#running-lifespan-in-tests\n \"\"\"\n with TestClient(app=test_app) as client:\n yield client\n```\n\n```text\nfactory.py\n```\n\n```text\napp = create_app(life_span_method=init_dependencies)\n```\n\n========================================\n\nComments:\n- Regarding initializing and reusing variables/client connections in FastAPI, please take a look at this and this\n- Great question. I have exactly the same problem as you. The way to write tests which depend on some \"dependency\" appears to be with the `Dependency` object and FastAPI dependency injection. (Or so other stack overflow users tell me.) However, how do you then create and destroy such an object during the lifecycle of your program? That is what the lifetime concept is for. It solves that problem. What is totally unclear is how do you combine these two concepts? The documentation doesn't say anything about it.\n- I tried your suggestion, so updates above. Maybe there is some small syntax problem? Because it didn't work, even if it seems to be the right approach\n- Where is the documentation which says this?\n- Also what is `app`?\n- Thanks, it saved my day. I was over dependent of finding a solution in chatgpt/github co-pilot. But after doing a simple google search. I could fix my issue in minutes before wasting few hours with LLMs :-)","metadata":{"transformedAt":"2026-08-18T18:32:29.111Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":18,"totalLines":343,"estimatedTokens":2042}}213{"id":"stack-59196645","source":"stackoverflow","questionId":59196645,"title":"Python3.7 asyncio start webserver (FastAPI) and aio_pika consumer","tags":["python-3.x","python-asyncio","fastapi","hypercorn"],"text":"Title: Python3.7 asyncio start webserver (FastAPI) and aio_pika consumer\nTags: python-3.x, python-asyncio, fastapi, hypercorn\nSource: Stack Overflow\n\nQuestion:\nIn my project I try to start a REST API (built with FastAPI and run with Hypercorn), additional I want on startup also to start a RabbitMQ Consumer (with aio_pika):\n\nAio Pika offers a robust connection which automatically reconnects on failure. If I run the code below with `hypercorn app:app` the consumer and the rest interface starts correctly, but the reconnect from aio_pika does not work anymore. How can I archive a production stable RabbitMQ Consumer and RestAPI in two different processes (or threads?). My python version is 3.7, please note I am actually a Java and Go developer in case my approach is not the Python way :-)\n\n```\n@app.on_event(\"startup\")\ndef startup():\n loop = asyncio.new_event_loop()\n asyncio.ensure_future(main(loop))\n\n@app.get(\"/\")\ndef read_root():\n return {\"Hello\": \"World\"}\n\nasync def main(loop):\nconnection = await aio_pika.connect_robust(\n \"amqp://guest:guest@127.0.0.1/\", loop=loop\n)\n\nasync with connection:\n queue_name = \"test_queue\"\n\n # Creating channel\n channel = await connection.channel() # type: aio_pika.Channel\n\n # Declaring queue\n queue = await channel.declare_queue(\n queue_name,\n auto_delete=True\n ) # type: aio_pika.Queue\n\n async with queue.iterator() as queue_iter:\n # Cancel consuming after __aexit__\n async for message in queue_iter:\n async with message.process():\n print(message.body)\n\n if queue.name in message.body.decode():\n break\n```\n\n========================================\n\nCode:\n```text\n@app.on_event(\"startup\")\ndef startup():\n loop = asyncio.new_event_loop()\n asyncio.ensure_future(main(loop))\n\n\n@app.get(\"/\")\ndef read_root():\n return {\"Hello\": \"World\"}\n\n\nasync def main(loop):\nconnection = await aio_pika.connect_robust(\n \"amqp://guest:guest@127.0.0.1/\", loop=loop\n)\n\nasync with connection:\n queue_name = \"test_queue\"\n\n # Creating channel\n channel = await connection.channel() # type: aio_pika.Channel\n\n # Declaring queue\n queue = await channel.declare_queue(\n queue_name,\n auto_delete=True\n ) # type: aio_pika.Queue\n\n async with queue.iterator() as queue_iter:\n # Cancel consuming after __aexit__\n async for message in queue_iter:\n async with message.process():\n print(message.body)\n\n if queue.name in message.body.decode():\n break\n```\n\n```text\nhypercorn app:app\n```\n\n```text\n@app.on_event(\"startup\")\ndef startup():\n loop = asyncio.get_event_loop()\n asyncio.ensure_future(main(loop))\n```\n\n```text\njob\n```\n\n```text\nasyncio.ensure_future\n```\n\n========================================\n\nComments:\n- I'm not sure why you create a new event loop in the startup function, which I think may be related. Could you say why it is required?\n- It is not required, I thought it was the way to do it. Similar to go\n- Ah, does it work without that? I'd imagine differing event loops could cause an issue.\n- you mean with get_current_event_loop() instead of a new one? Yes I tried it but it has the same issue.\n- Ah, I was hoping it would be that. Is there anything logged that could give a clue here? (Otherwise I can't see the issue).\n- Not at all, I tried to change the with the current_event_loop, to pass as argument for the consumer and this seems to work now`@app.on_event(\"startup\") def startup(): print(\"jdklasjdlas\") loop = asyncio.get_event_loop() asyncio.ensure_future(main(loop))` Thanksfor your help\n- btw thanks for your work on Hypercorn! Awesome Job!","metadata":{"transformedAt":"2026-08-18T18:32:29.111Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":117,"estimatedTokens":900}}214{"id":"stack-73155924","source":"stackoverflow","questionId":73155924,"title":"Inheritance/subclassing issue in Pydantic","tags":["python","fastapi","pydantic"],"text":"Title: Inheritance/subclassing issue in Pydantic\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI came across a code snippet for declaring Pydantic Models. The inheritance used there has me confused.\n\n```\nclass RecipeBase(BaseModel):\n label: str\n source: str\n url: HttpUrl\n\nclass RecipeCreate(RecipeBase):\n label: str\n source: str\n url: HttpUrl\n submitter_id: int\n\nclass RecipeUpdate(RecipeBase):\n label: str\n```\n\nI am not sure what's the benefit of inheriting from RecipeBase in the RecipeCreate and RecipeUpdate class. The part that has me confused is that after inheritance also, why does one has to re-declare label, source, and URL, which are already part of the RecipeBase class in the RecipeCreate class?\n\n========================================\n\nCode:\n```text\nclass RecipeBase(BaseModel):\n label: str\n source: str\n url: HttpUrl\n\n\nclass RecipeCreate(RecipeBase):\n label: str\n source: str\n url: HttpUrl\n submitter_id: int\n\n\nclass RecipeUpdate(RecipeBase):\n label: str\n```\n\n```text\nXyzBase\n```\n\n```text\nname: str\n```\n\n```text\nXyzCreate\n```\n\n```text\nname: str|None\n```\n\n========================================\n\nComments:\n- Less of an \"oversight\" and more of a total screw up. Change your tutorial provider.","metadata":{"transformedAt":"2026-08-18T18:32:29.111Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":66,"estimatedTokens":310}}215{"id":"stack-71542183","source":"stackoverflow","questionId":71542183,"title":"Websocket getting closed immediately after connecting to FastAPI Endpoint","tags":["python","python-3.x","websocket","fastapi","aiohttp"],"text":"Title: Websocket getting closed immediately after connecting to FastAPI Endpoint\nTags: python, python-3.x, websocket, fastapi, aiohttp\nSource: Stack Overflow\n\nQuestion:\nI'm trying to connect a websocket aiohttp client to a fastapi websocket endpoint, but I can't send or recieve any data because it seems that the websocket gets closed immediately after connecting to the endpoint.\n\n**server**\n\n```\nimport uvicorn\nfrom fastapi import FastAPI, WebSocket\n\napp = FastAPI()\n\n@app.websocket('/ws')\nasync def websocket_endpoint(websocket: WebSocket):\n await websocket.accept()\n ...\n\nif __name__ == '__main__':\n uvicorn.run('test:app', debug=True, reload=True)\n```\n\n**client**\n\n```\nimport aiohttp\nimport asyncio\n\nasync def main():\n s = aiohttp.ClientSession()\n ws = await s.ws_connect('ws://localhost:8000/ws')\n while True:\n ...\n\nasyncio.run(main())\n```\n\nWhen I try to send data from the server to the client when a connection is made\n\n**server**\n\n```\n@app.websocket('/ws')\nasync def websocket_endpoint(websocket: WebSocket):\n await websocket.accept()\n await websocket.send_text('yo')\n```\n\n**client**\n\n```\nwhile True:\n print(await ws.receive())\n```\n\nI always get printed in my client's console\n\n```\nWSMessage(type=, data=None, extra=None)\n```\n\nWhile in the server's debug console it says\n\n```\nINFO: ('127.0.0.1', 59792) - \"WebSocket /ws\" [accepted]\nINFO: connection open\nINFO: connection closed\n```\n\nWhen I try to send data from the client to the server\n\n**server**\n\n```\n@app.websocket('/ws')\nasync def websocket_endpoint(websocket: WebSocket):\n await websocket.accept()\n while True:\n await websocket.receive_text()\n```\n\n**client**\n\n```\nws = await s.ws_connect('ws://localhost:8000/ws')\nawait ws.send_str('client!')\n```\n\nNothing happens, I get no message printed out in the server's console, just the debug message saying the client got accepted, connection opened and closed again.\n\nI have no idea what I'm doing wrong, I followed this tutorial in the fastAPI docs for a websocket and the example there with the js websocket works completely fine.\n\n========================================\n\nCode:\n```py\nimport uvicorn\nfrom fastapi import FastAPI, WebSocket\n\napp = FastAPI()\n\n@app.websocket('/ws')\nasync def websocket_endpoint(websocket: WebSocket):\n await websocket.accept()\n ...\n\n\nif __name__ == '__main__':\n uvicorn.run('test:app', debug=True, reload=True)\n```\n\n```py\nimport aiohttp\nimport asyncio\n\nasync def main():\n s = aiohttp.ClientSession()\n ws = await s.ws_connect('ws://localhost:8000/ws')\n while True:\n ...\n\nasyncio.run(main())\n```\n\n```py\n@app.websocket('/ws')\nasync def websocket_endpoint(websocket: WebSocket):\n await websocket.accept()\n await websocket.send_text('yo')\n```\n\n```py\nwhile True:\n print(await ws.receive())\n```\n\n```text\nWSMessage(type=<WSMsgType.CLOSED: 257>, data=None, extra=None)\n```\n\n```text\nINFO: ('127.0.0.1', 59792) - \"WebSocket /ws\" [accepted]\nINFO: connection open\nINFO: connection closed\n```\n\n```py\n@app.websocket('/ws')\nasync def websocket_endpoint(websocket: WebSocket):\n await websocket.accept()\n while True:\n await websocket.receive_text()\n```\n\n```py\nws = await s.ws_connect('ws://localhost:8000/ws')\nawait ws.send_str('client!')\n```\n\n```py\nfrom fastapi import FastAPI, WebSocket, WebSocketDisconnect\nfrom websockets.exceptions import ConnectionClosed\nimport uvicorn\n\napp = FastAPI()\n\n@app.websocket(\"/ws\")\nasync def websocket_endpoint(websocket: WebSocket):\n # await for connections\n await websocket.accept()\n \n try:\n # send \"Connection established\" message to client\n await websocket.send_text(\"Connection established!\")\n \n # await for messages and send messages\n while True:\n msg = await websocket.receive_text()\n if msg.lower() == \"close\":\n await websocket.close()\n break\n else:\n print(f'CLIENT says - {msg}')\n await websocket.send_text(f\"Your message was: {msg}\")\n \n except (WebSocketDisconnect, ConnectionClosed):\n print(\"Client disconnected\")\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"127.0.0.1\", port=8000)\n```\n\n```py\nimport aiohttp\nimport asyncio\n\nasync def main():\n async with aiohttp.ClientSession() as session:\n async with session.ws_connect('ws://127.0.0.1:8000/ws') as ws:\n # await for messages and send messages\n async for msg in ws:\n if msg.type == aiohttp.WSMsgType.TEXT:\n print(f'SERVER says - {msg.data}')\n text = input('Enter a message: ')\n await ws.send_str(text)\n elif msg.type == aiohttp.WSMsgType.ERROR:\n break\n\nasyncio.run(main())\n```\n\n```text\nawait\n```\n\n```text\nawait websocket.receive_text()\n```\n\n```text\nWebSocketDisconnect\n```\n\n```text\ntry-except\n```\n\n```text\nWebSocketDisconnect\n```\n\n```text\nwebsockets.exceptions.ConnectionClosed\n```\n\n```text\naiohttp\n```\n\n```text\nFastAPI\n```\n\n```text\nwebsockets\n```\n\n```text\nwebsockets\n```\n\n```text\naiohttp\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.111Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":21,"totalLines":256,"estimatedTokens":1271}}216{"id":"stack-65114261","source":"stackoverflow","questionId":65114261,"title":"Is there a way to deploy a fastapi app on cpanel?","tags":["python","cpanel","passenger","fastapi"],"text":"Title: Is there a way to deploy a fastapi app on cpanel?\nTags: python, cpanel, passenger, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm having trouble deploying a FastAPI app on cpanel with Passenger\n\n========================================\n\nCode:\n```py\nfrom a2wsgi import ASGIMiddleware\nfrom main import app # Import your FastAPI app.\n\napplication = ASGIMiddleware(app)\n```\n\n```text\na2wsgi\n```\n\n```text\npassenger_wsgi.py\n```\n\n========================================\n\nComments:\n- Passenger at the moment only supports WSGI. FastAPI uses ASGI, so it's not possible to deploy it on Passenger at the moment. There is an open issue to support ASGI apps on passenger: github.com/phusion/passenger/issues/2272 There also is an issue on asgiref to convert ASGI to WSGI: github.com/django/asgiref/issues/109\n- How to start this app with uvicorn?\n- i applied it for a django app but it didn't work.\n- @DoctorHe Django already uses the WSGI spec. You don't need to convert it in any way. See phusionpassenger.com/library/deploy/wsgi_spec.html for reference.\n- @pypae i wanted to use the \"django channels\" library and it uses asgi.\n- I have still error ` App 2851150 output: socket_hijacked = self.process_request(env, input_stream, client) App 2851150 output: File \"/opt/cpanel/ea-ruby27/root/usr//passenger/helper-scrip‌​ts/wsgi-loader.py\", line 348, in process_request App 2851150 output: result = self.app(env, start_response) App 2851150 output: TypeError: __call__() missing 1 required positional argument: 'send' `","metadata":{"transformedAt":"2026-08-18T18:32:29.111Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":3,"totalLines":34,"estimatedTokens":381}}217{"id":"stack-69542217","source":"stackoverflow","questionId":69542217,"title":"How to disable server exceptions on fast-api when testing with httpx AsyncClient?","tags":["python","fastapi","httpx"],"text":"Title: How to disable server exceptions on fast-api when testing with httpx AsyncClient?\nTags: python, fastapi, httpx\nSource: Stack Overflow\n\nQuestion:\nWe have a FastApi app and using httpx AsyncClient for testing purposes. We are experiencing a problem where the unit tests run locally fine but fail on the CI server (Github Actions).\n\nAfter further research we have come across this proposed solution by setting `raise_server_exceptions=False` to `False`.\n\n```\nclient = TestClient(app, raise_server_exceptions=False)\n```\n\nHowever this is for the sync client. We are using the async client.\n\n```\n@pytest.fixture\nasync def client(test_app):\n async with AsyncClient(app=test_app, base_url=\"http://testserver\") as client:\n yield client\n```\n\nThe AsyncClient does not support the `raise_app_exceptions=False` option.\n\nDoes anyone have experience with this?\nThanks\n\n========================================\n\nTop Answer:\nFor `httpx` v0.14.0+ you need to use `httpx.ASGITransport`.\nExcerpt from the official documentation:\n\nFor some more complex cases you might need to customise the ASGI transport. This allows you to:\n\n- Inspect 500 error responses rather than raise exceptions by setting raise_app_exceptions=False.\n\n- Mount the ASGI application at a subpath by setting root_path.\n\n- Use a given client address for requests by setting client.\n\nFor example:\n\n```\n# Instantiate a client that makes ASGI requests with a client IP of \"1.2.3.4\",\n# on port 123.\ntransport = httpx.ASGITransport(app=app, raise_app_exceptions=False,\n client=(\"1.2.3.4\", 123))\nasync with httpx.AsyncClient(transport=transport, base_url=\"http://testserver\") as client:\n ...\n```\n\n========================================\n\nCode:\n```text\nclient = TestClient(app, raise_server_exceptions=False)\n```\n\n```text\n@pytest.fixture\nasync def client(test_app):\n async with AsyncClient(app=test_app, base_url=\"http://testserver\") as client:\n yield client\n```\n\n```text\nraise_server_exceptions=False\n```\n\n```text\nFalse\n```\n\n```text\nraise_app_exceptions=False\n```\n\n```text\nfastapi==0.65.0\n```\n\n```text\nraise_app_exceptions=False\n```\n\n```text\n# Instantiate a client that makes ASGI requests with a client IP of \"1.2.3.4\",\n# on port 123.\ntransport = httpx.ASGITransport(app=app, raise_app_exceptions=False,\n client=(\"1.2.3.4\", 123))\nasync with httpx.AsyncClient(transport=transport, base_url=\"http://testserver\") as client:\n ...\n```\n\n```text\nhttpx\n```\n\n```text\nhttpx.ASGITransport\n```\n\n========================================\n\nComments:\n- This answer worked for me, I just have an warning error on app=app -> `Type \"BaseAPI\" cannot be assigned to type \"_ASGIApp\"`\n- Ahh I see. This is a bug in `0.70.0` version.","metadata":{"transformedAt":"2026-08-18T18:32:29.111Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":10,"totalLines":108,"estimatedTokens":669}}218{"id":"stack-76781053","source":"stackoverflow","questionId":76781053,"title":"FastAPI generates incorrect OpenAPI 3.0.1 specification","tags":["python","fastapi","openapi"],"text":"Title: FastAPI generates incorrect OpenAPI 3.0.1 specification\nTags: python, fastapi, openapi\nSource: Stack Overflow\n\nQuestion:\nI am currently designing a REST API with FastAPI and using the generated openapi.json specification to generate a client. The client generator I am currently trying to use is limited to OpenAPI 3.0.x.\n\nThe generator is complaining about \"null\" being generated as a possible type for a parameter, which makes sense as that was only introduced in OpenAPI 3.1.0\n\nThe offending part of the specification:\n\n```\n\"name\": \"someParameter\",\n\"in\": \"query\",\n\"required\": false,\n\"schema\": {\n \"anyOf\": [\n {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n },\n \"minItems\": 3,\n \"maxItems\": 50\n },\n {\n \"type\": \"null\"\n }\n ],\n```\n\nThis is being generated from the following endpoint:\n\n```\n@router.get(\"/{itemId}\")\nasync def readItem(someParameter: Annotated[Optional[list[str]],\n Query(title=\"...\",\n description=\"...\",\n min_length=3, max_length=50)] = None)\n```\n\nI am customizing FastAPI to use the OpenAPI 3.0.1 spec like this:\n\n```\ndef customOpenAPI():\n openapiSchema = get_openapi(\n title = app.title,\n openapi_version = \"3.0.1\",\n version = app.version,\n summary = app.summary,\n description = app.description,\n routes = app.routes\n )\n\n app.openapi_schema = openapiSchema\n return app.openapi_schema\n\napp.openapi = customOpenAPI\n```\n\nA possible solution would be to restructure the endpoint like this:\n\n```\n@router.get(\"/{itemId}\")\nasync def readItem(someParameter: Annotated(list[str],\n Query(title=\"...\",\n description=\"...\",\n min_length=3, max_length=50,\n nullable=True)] = None)\n```\n\nBut then I would be losing the Optional typehint which I would like to keep for code readability purposes.\n\nThe same problem also applies to Fields in my models:\n\n```\nclass SomeModel(BaseModel)\n someField: Optional[str] = None\n```\n\nWhich I would have to reformat to\n\n```\nclass SomeModel(BaseModel)\n someField: str = Field(nullable=True, default=None)\n```\n\nIs there any way to get FastAPI to generate the correct OpenAPI 3.0.1 specification while keeping the Optional typehint in my code?\n\n========================================\n\nCode:\n```json\n\"name\": \"someParameter\",\n\"in\": \"query\",\n\"required\": false,\n\"schema\": {\n \"anyOf\": [\n {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n },\n \"minItems\": 3,\n \"maxItems\": 50\n },\n {\n \"type\": \"null\"\n }\n ],\n```\n\n```py\n@router.get(\"/{itemId}\")\nasync def readItem(someParameter: Annotated[Optional[list[str]],\n Query(title=\"...\",\n description=\"...\",\n min_length=3, max_length=50)] = None)\n```\n\n```py\ndef customOpenAPI():\n openapiSchema = get_openapi(\n title = app.title,\n openapi_version = \"3.0.1\",\n version = app.version,\n summary = app.summary,\n description = app.description,\n routes = app.routes\n )\n\n app.openapi_schema = openapiSchema\n return app.openapi_schema\n\napp.openapi = customOpenAPI\n```\n\n```py\n@router.get(\"/{itemId}\")\nasync def readItem(someParameter: Annotated(list[str],\n Query(title=\"...\",\n description=\"...\",\n min_length=3, max_length=50,\n nullable=True)] = None)\n```\n\n```py\nclass SomeModel(BaseModel)\n someField: Optional[str] = None\n```\n\n```py\nclass SomeModel(BaseModel)\n someField: str = Field(nullable=True, default=None)\n```\n\n```text\nExample\n\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\napp.openapi_version = \"3.0.2\"\n```\n\n```text\n3.0.1\n```\n\n```text\nget_openapi(...)\n```\n\n========================================\n\nComments:\n- Might be worth opening an issue.","metadata":{"transformedAt":"2026-08-18T18:32:29.111Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":178,"estimatedTokens":957}}219{"id":"stack-64522736","source":"stackoverflow","questionId":64522736,"title":"How to connect Vue.js as frontend and FastAPI as backend?","tags":["vue.js","fastapi"],"text":"Title: How to connect Vue.js as frontend and FastAPI as backend?\nTags: vue.js, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm building a project On Jobs Portal and I need Vue as frontend and FastAPI as backend for add, delete, update. I want to know if I can connect these both or not.\n\n========================================\n\nTop Answer:\nYou can do it, in quite a clean way IMO.\nThe best I can come up with is using Node.js/npm to bundle the Vue app to a `dist/` folder (by default)\n\n```\nvue-cli-service build\n```\n\nI then use the project folder structure like this\n\n```\n├── dist/ To archieve the same project setup, you can just simply init a Vue project using `vue create` and create your Python project in a same folder (using a IDE like Pycharm for example, make sure you don't override one with the other).\n\nThen you can use `FastAPI.staticfiles.StaticFiles` to serve them\n\n```\n# app.py\n\napp.mount('/', StaticFiles(directory='dist', html=True))\n```\n\nRemember to put the above `app.mount()` line after all other routes though, since it will override every route that comes after.\n\nYou can even use `vue-cli-service build --watch` so that every change in Vue code will be reflected in the HTML file right after, and all you need to do is to press F5 on your browser to see those changes.\n\nYou can change the `dist` folder output to something else too, using `vue-cli-service build --dest=` and change `directory` parameter in `app.mount()` line above. (according to Vue-CLI docs)\n\nHere is one of my projects using that setup: https://github.com/KhanhhNe/sshmanager-v2\n\n========================================\n\nCode:\n```py\n├── main.py\n└── templates\n └── home.html\n```\n\n```py\nfrom fastapi import FastAPI, Request\nfrom fastapi.templating import Jinja2Templates\nfrom pydantic import BaseModel\n\ntemplates = Jinja2Templates(directory=\"templates\") \n\napp = FastAPI()\n\n\nclass TextArea(BaseModel):\n content: str\n\n\n@app.post(\"/add\")\nasync def post_textarea(data: TextArea):\n print(data.dict())\n return {**data.dict()}\n\n\n@app.get(\"/\")\nasync def serve_home(request: Request):\n return templates.TemplateResponse(\"home.html\", {\"request\": request})\n```\n\n```js\n<html>\n<title></title>\n<script src=\"https://cdn.jsdelivr.net/npm/vue/dist/vue.js\"></script>\n<script src=\"https://unpkg.com/axios/dist/axios.min.js\"></script>\n\n<body>\n <div id=\"app\">\n <textarea name=\"\" id=\"content\" cols=\"30\" rows=\"10\" v-model=\"content\"></textarea>\n <button @click=\"addText\" id=\"add-textarea\">click me</button>\n </div>\n\n <script>\n new Vue({\n el: \"#app\",\n data: {\n title: '',\n content: ''\n },\n methods: {\n addText() {\n return axios.post(\"/add\", {\n content: this.content\n }, {\n headers: {\n 'Content-type': 'application/json',\n }\n }).then((response) => {\n console.log(\"content: \" + this.content);\n });\n }\n }\n });\n </script>\n</body>\n\n</html>\n```\n\n```py\n{'content': 'Hello textarea!'}\nINFO: 127.0.0.1:51682 - \"POST /add HTTP/1.1\" 200 OK\n```\n\n```text\nmain.py\n```\n\n```text\n/\n```\n\n```text\nhome.html\n```\n\n```text\n/add\n```\n\n```text\nhome.html\n```\n\n```text\n/add\n```\n\n```text\nvue-cli-service build\n```\n\n```text\n├── dist/ <- Vue-CLI output\n └── index.html\n├── src/ <- Vue source files\n└── app.py\n```\n\n```py\n# app.py\n\napp.mount('/', StaticFiles(directory='dist', html=True))\n```\n\n```text\ndist/\n```\n\n```text\nvue create\n```\n\n```text\nFastAPI.staticfiles.StaticFiles\n```\n\n```text\napp.mount()\n```\n\n```text\nvue-cli-service build --watch\n```\n\n```text\ndist\n```\n\n```text\nvue-cli-service build --dest=<folder name>\n```\n\n```text\ndirectory\n```\n\n```text\napp.mount()\n```\n\n```text\nconst { defineConfig } = require('@vue/cli-service')\nconst path = require('path');\n\nmodule.exports = defineConfig({\n transpileDependencies: true, //Transpile your dependencies\n publicPath: \"/static\", //Path of static directory\n outputDir: path.resolve(__dirname, '../static'), // Output path for the static files\n runtimeCompiler: true,\n devServer: {\n // Write files to disk in dev mode, so FastAPI can serve the assets\n port: 8080,\n devMiddleware: {\n writeToDisk: true,\n }\n },\n})\n```\n\n```text\nnpm run build\n```\n\n```text\nfrom fastapi import FastAPI\nfrom fastapi.staticfiles import StaticFiles #<-- Add this\n\napp = FastAPI()\n\n\n#static files & load\napp.mount(\"/\", StaticFiles(directory=\"static\", html = True), name=\"static\") #<-- Add this\n```\n\n```text\nfrom fastapi import FastAPI, Request\nfrom fastapi.templating import Jinja2Templates \nfrom fastapi.staticfiles import StaticFiles \n\napp = FastAPI()\n\n\n#static files & load\napp.mount(\"/static\", StaticFiles(directory=\"static\", html = True), name=\"static\") \ntemplates = Jinja2Templates(directory=\"static\")\n\n@app.get(\"/\")\nasync def serve_home(request: Request):\n return templates.TemplateResponse(\"index.html\", {\"request\": request})\n```\n\n```text\nvue.config.js\n```\n\n```text\nvue.config.js\n```\n\n```text\nmain.py\n```\n\n```text\nindex.html\n```\n\n```text\napp.mount(\"/\", StaticFiles(directory=\"static\", html = True), name=\"static\")\n```\n\n```text\nmain.py\n```\n\n```text\nindex.html\n```\n\n```text\nmain.js\n```\n\n========================================\n\nComments:\n- what if i'm using file.vue instead of file.html?\n- Jinja is an HTML rendering framework, thats exactly what I meant by if you want to use components you will need to run frontend and backend independently and you need to merge them with something like Nginx Apache etc.","metadata":{"transformedAt":"2026-08-18T18:32:29.111Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":34,"totalLines":281,"estimatedTokens":1423}}220{"id":"stack-68542054","source":"stackoverflow","questionId":68542054,"title":"FastAPI, add long tasks to buffer and process them one by one, while maintaining server responsiveness","tags":["python","asynchronous","fastapi"],"text":"Title: FastAPI, add long tasks to buffer and process them one by one, while maintaining server responsiveness\nTags: python, asynchronous, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to set up a FastAPI server that will take as input some biological data, and run some processing on them. Since the processing takes up all the server's resources, queries should be processed sequentially. However, the server should stay responsive and add further requests in a buffer. I've been trying to use the BackgroundTasks module for this, but after sending the second query, the response gets delayed while the task is running. Any help appreciated, and thanks in advance.\n\n```\nimport os\nimport sys\nimport time\nfrom dataclasses import dataclass\nfrom fastapi import FastAPI, Request, BackgroundTasks\n\nEXPERIMENTS_BASE_DIR = \"/experiments/\"\nQUERY_BUFFER = {}\n\napp = FastAPI()\n\n@dataclass\nclass Query():\n query_name: str\n query_sequence: str\n experiment_id: str = None\n status: str = \"pending\"\n\n def __post_init__(self):\n self.experiment_id = str(time.time())\n self.experiment_dir = os.path.join(EXPERIMENTS_BASE_DIR, self.experiment_id)\n os.makedirs(self.experiment_dir, exist_ok=False)\n\n def run(self):\n self.status = \"running\"\n # perform some long task using the query sequence and get a return code #\n self.status = \"finished\"\n return 0 # or another code depending on the final output\n\n@app.post(\"/\")\nasync def root(request: Request, background_tasks: BackgroundTasks):\n query_data = await request.body()\n query_data = query_data.decode(\"utf-8\")\n query_data = dict(str(x).split(\"=\") for x in query_data.split(\"&\"))\n query = Query(**query_data)\n QUERY_BUFFER[query.experiment_id] = query\n background_tasks.add_task(process, query)\n return {\"Query created\": query, \"Query ID\": query.experiment_id, \"Backlog Length\": len(QUERY_BUFFER)}\n\nasync def process(query):\n \"\"\" Process query and generate data\"\"\"\n ret_code = await query.run()\n del QUERY_BUFFER[query.experiment_id]\n print(f'Query {query.experiment_id} processing finished with return code {ret_code}.')\n\n@app.get(\"/backlog/\")\ndef return_backlog():\n return {f\"Currently {len(QUERY_BUFFER)} jobs in the backlog.\"}\n```\n\n========================================\n\nTop Answer:\nI think your issue is in the task you want to run, not in the `BackgroundTask` itself.\n\nFastAPI (and underlying Starlette, which is responsible for running the background tasks) is created on top of the asyncio and handles all requests asynchronously. That means, if one request is being processed, if there is any IO operation while processing the current request, and that IO operation supports the asynchronous approach, FastAPI will switch to the next request in queue while this IO operation is pending.\n\nSame goes for any background tasks added to the queue. If background task is pending, any requests or other background tasks will be handled only when FastAPI is waiting for any IO operation.\n\nAs you may see, this is not ideal when either your view or task doesn't have any IO operations or they cannot be run asynchronously. There is a workaround for that situation:\n\ndeclare your views or tasks as normal, non asynchronous functions\n\nStarlette will then run those views in a separate thread, outside of the main async loop, so other requests can be handled at the same time\nmanually run the part of your logic that may block the\nprocessing of other requests using `asgiref.sync_to_async`\n\nThis will also cause this logic to be executed in a separate thread, releasing the main async loop to take care of other requests until the function returns.\n\nIf you are not doing any asynchronous IO operations in your long-running task, the first approach will be most suitable for you. Otherwise, you should take any part of your code that is either long-running or performs any non-asynchronous IO operations and wrap it with `sync_to_async`.\n\n========================================\n\nCode:\n```text\nimport os\nimport sys\nimport time\nfrom dataclasses import dataclass\nfrom fastapi import FastAPI, Request, BackgroundTasks\n\nEXPERIMENTS_BASE_DIR = \"/experiments/\"\nQUERY_BUFFER = {}\n\napp = FastAPI()\n\n@dataclass\nclass Query():\n query_name: str\n query_sequence: str\n experiment_id: str = None\n status: str = \"pending\"\n\n def __post_init__(self):\n self.experiment_id = str(time.time())\n self.experiment_dir = os.path.join(EXPERIMENTS_BASE_DIR, self.experiment_id)\n os.makedirs(self.experiment_dir, exist_ok=False)\n\n def run(self):\n self.status = \"running\"\n # perform some long task using the query sequence and get a return code #\n self.status = \"finished\"\n return 0 # or another code depending on the final output\n\n@app.post(\"/\")\nasync def root(request: Request, background_tasks: BackgroundTasks):\n query_data = await request.body()\n query_data = query_data.decode(\"utf-8\")\n query_data = dict(str(x).split(\"=\") for x in query_data.split(\"&\"))\n query = Query(**query_data)\n QUERY_BUFFER[query.experiment_id] = query\n background_tasks.add_task(process, query)\n return {\"Query created\": query, \"Query ID\": query.experiment_id, \"Backlog Length\": len(QUERY_BUFFER)}\n\nasync def process(query):\n \"\"\" Process query and generate data\"\"\"\n ret_code = await query.run()\n del QUERY_BUFFER[query.experiment_id]\n print(f'Query {query.experiment_id} processing finished with return code {ret_code}.')\n\n@app.get(\"/backlog/\")\ndef return_backlog():\n return {f\"Currently {len(QUERY_BUFFER)} jobs in the backlog.\"}\n```\n\n```text\nimport asyncio\nimport os\nimport sys\nimport time\nfrom dataclasses import dataclass\nfrom fastapi import FastAPI, Request, BackgroundTasks\nimport logging\n\n\nlogging.basicConfig(level=logging.INFO, format=\"%(levelname)-9s %(asctime)s - %(name)s - %(message)s\")\nLOGGER = logging.getLogger(__name__)\n\nEXPERIMENTS_BASE_DIR = \"/experiments/\"\nQUERY_BUFFER = {}\n\napp = FastAPI()\nloop = asyncio.get_event_loop()\n\n@dataclass\nclass Query():\n query_name: str\n query_sequence: str\n experiment_id: str = None\n status: str = \"pending\"\n\n def __post_init__(self):\n self.experiment_id = str(time.time())\n self.experiment_dir = os.path.join(EXPERIMENTS_BASE_DIR, self.experiment_id)\n # os.makedirs(self.experiment_dir, exist_ok=False) # Commented out for testing\n\n async def run(self):\n self.status = \"running\"\n await asyncio.sleep(5) # simulate long running query\n # perform some long task using the query sequence and get a return code #\n self.status = \"finished\"\n return 0 # or another code depending on the final output\n\n@app.post(\"/\")\nasync def root(request: Request, background_tasks: BackgroundTasks):\n query_data = await request.body()\n query_data = query_data.decode(\"utf-8\")\n query_data = dict(str(x).split(\"=\") for x in query_data.split(\"&\"))\n query = Query(**query_data)\n QUERY_BUFFER[query.experiment_id] = query\n background_tasks.add_task(process, query)\n LOGGER.info(f'root - added task')\n return {\"Query created\": query, \"Query ID\": query.experiment_id, \"Backlog Length\": len(QUERY_BUFFER)}\n\n\ndef process(query):\n \"\"\" Schedule processing of query, and then run some long running non-IO job without blocking the app\"\"\"\n asyncio.run_coroutine_threadsafe(aprocess(query), loop)\n LOGGER.info(f\"process - {query.experiment_id} - Submitted query job. Now run non-IO work for 10 seconds...\")\n time.sleep(10) # simulate long running non-IO work, does not block app as this is in another thread - provided it is not cpu bound.\n LOGGER.info(f'process - {query.experiment_id} - wake up!')\n\n\nasync def aprocess(query):\n \"\"\" Process query and generate data \"\"\"\n ret_code = await query.run()\n del QUERY_BUFFER[query.experiment_id]\n LOGGER.info(f'aprocess - Query {query.experiment_id} processing finished with return code {ret_code}.')\n\n\n@app.get(\"/backlog/\")\ndef return_backlog():\n return {f\"return_backlog - Currently {len(QUERY_BUFFER)} jobs in the backlog.\"}\n\n\nif __name__ == \"__main__\":\n import uvicorn\n uvicorn.run(\"scratch_26:app\", host=\"127.0.0.1\", port=8000)\n```\n\n```text\n@app.post(\"/\")\nasync def root(request: Request, background_tasks: BackgroundTasks):\n ...\n background_tasks.add_task(process_wrapper, query)\n ...\n\nasync def process_wrapper(query):\n loop = asyncio.get_event_loop()\n loop.create_task(process(query))\n\nasync def process(query):\n \"\"\" Process query and generate data\"\"\"\n ret_code = await query.run()\n del QUERY_BUFFER[query.experiment_id]\n print(f'Query {query.experiment_id} processing finished with return code {ret_code}.')\n```\n\n```text\nimport asyncio\nimport os\nimport sys\nimport time\nfrom dataclasses import dataclass\nfrom fastapi import FastAPI, Request, BackgroundTasks\nfrom httpx import AsyncClient\n\nEXPERIMENTS_BASE_DIR = \"/experiments/\"\nQUERY_BUFFER = {}\n\napp = FastAPI()\nstart_ts = time.time()\n\n\n@dataclass\nclass Query():\n query_name: str\n query_sequence: str\n experiment_id: str = None\n status: str = \"pending\"\n\n def __post_init__(self):\n self.experiment_id = str(time.time())\n self.experiment_dir = os.path.join(EXPERIMENTS_BASE_DIR, self.experiment_id)\n # os.makedirs(self.experiment_dir, exist_ok=False) # Commented out for testing\n\n async def run(self):\n self.status = \"running\"\n await asyncio.sleep(2) # simulate long running query\n # perform some long task using the query sequence and get a return code #\n self.status = \"finished\"\n return 0 # or another code depending on the final output\n\n@app.post(\"/\")\nasync def root(request: Request, background_tasks: BackgroundTasks):\n query_data = await request.body()\n query_data = query_data.decode(\"utf-8\")\n query_data = dict(str(x).split(\"=\") for x in query_data.split(\"&\"))\n query = Query(**query_data)\n QUERY_BUFFER[query.experiment_id] = query\n background_tasks.add_task(process_wrapper, query)\n print(f'{fmt_duration()} - root - added task')\n return {\"Query created\": query, \"Query ID\": query.experiment_id, \"Backlog Length\": len(QUERY_BUFFER)}\n\n\nasync def process_wrapper(query):\n loop = asyncio.get_event_loop()\n loop.create_task(process(query))\n\nasync def process(query):\n \"\"\" Process query and generate data\"\"\"\n ret_code = await query.run()\n del QUERY_BUFFER[query.experiment_id]\n print(f'{fmt_duration()} - process - Query {query.experiment_id} processing finished with return code {ret_code}.')\n\n@app.get(\"/backlog/\")\ndef return_backlog():\n return {f\"{fmt_duration()} - return_backlog - Currently {len(QUERY_BUFFER)} jobs in the backlog.\"}\n\n\nasync def test_me():\n async with AsyncClient(app=app, base_url=\"http://example\") as ac:\n res = await ac.post(\"/\", content=\"query_name=foo&query_sequence=42\")\n print(f\"{fmt_duration()} - [{res.status_code}] - {res.content.decode('utf8')}\")\n res = await ac.post(\"/\", content=\"query_name=bar&query_sequence=43\")\n print(f\"{fmt_duration()} - [{res.status_code}] - {res.content.decode('utf8')}\")\n content = \"\"\n while not content.endswith('0 jobs in the backlog.\"]'):\n await asyncio.sleep(1)\n backlog_results = await ac.get(\"/backlog\")\n content = backlog_results.content.decode(\"utf8\")\n print(f\"{fmt_duration()} - test_me - content: {content}\")\n\n\ndef fmt_duration():\n return f\"Progress time: {time.time() - start_ts:.3f}s\"\n\nloop = asyncio.get_event_loop()\nprint(f'starting loop...')\nloop.run_until_complete(test_me())\nduration = time.time() - start_ts\nprint(f'Finished. Duration: {duration:.3f} seconds.')\n```\n\n```text\nstarting loop...\nProgress time: 0.005s - root - added task\nProgress time: 0.006s - [200] - {\"Query created\":{\"query_name\":\"foo\",\"query_sequence\":\"42\",\"experiment_id\":\"1627489235.9300923\",\"status\":\"pending\",\"experiment_dir\":\"/experiments/1627489235.9300923\"},\"Query ID\":\"1627489235.9300923\",\"Backlog Length\":1}\nProgress time: 0.007s - root - added task\nProgress time: 0.009s - [200] - {\"Query created\":{\"query_name\":\"bar\",\"query_sequence\":\"43\",\"experiment_id\":\"1627489235.932097\",\"status\":\"pending\",\"experiment_dir\":\"/experiments/1627489235.932097\"},\"Query ID\":\"1627489235.932097\",\"Backlog Length\":2}\nProgress time: 1.016s - test_me - content: [\"Progress time: 1.015s - return_backlog - Currently 2 jobs in the backlog.\"]\nProgress time: 2.008s - process - Query 1627489235.9300923 processing finished with return code 0.\nProgress time: 2.008s - process - Query 1627489235.932097 processing finished with return code 0.\nProgress time: 2.041s - test_me - content: [\"Progress time: 2.041s - return_backlog - Currently 0 jobs in the backlog.\"]\nFinished. Duration: 2.041 seconds.\n```\n\n```text\ndef process_wrapper(query):\n loop = asyncio.get_event_loop()\n asyncio.run_coroutine_threadsafe(process(query), loop)\n```\n\n```text\nhttpx.AsyncClient\n```\n\n```text\nhttpx.AsyncClient\n```\n\n```text\nprocess\n```\n\n```text\naprocess\n```\n\n```text\naprocess\n```\n\n```text\nrun\n```\n\n```text\ntime.sleep(10)\n```\n\n```text\nprocess\n```\n\n```text\nBackgroundTasks\n```\n\n```text\nawait\n```\n\n```text\nrun()\n```\n\n```text\nasync\n```\n\n```text\nprocess()\n```\n\n```text\nhttpx.AsyncClient\n```\n\n```text\nfmt_duration\n```\n\n```text\nrun()\n```\n\n```text\nprocess_wrapper\n```\n\n```text\nrun_coroutine_threadsafe\n```\n\n```text\ncreate_task\n```\n\n```text\nBackgroundTask\n```\n\n```text\nasgiref.sync_to_async\n```\n\n```text\nsync_to_async\n```\n\n========================================\n\nComments:\n- Have you look at using something like Celery? docs.celeryproject.org/en/stable/getting-started/…\n- Thanks for this fix. Although adding this process wrapper just for making pytests work is a bit cumbersome, this made my day! I was already in the process of filing an issue with fastapi... but this workaround could work for me. Thanks!\n- Are you certain the queries are processed sequentially with the \"new\" solution (= not the original one)? I run your code, and it appeared that queries were processed in parallel. The problem I am working on requires strictly sequential processing (takes GPU resources), hence your answer is of great practical interest to me.","metadata":{"transformedAt":"2026-08-18T18:32:29.111Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":28,"totalLines":425,"estimatedTokens":3535}}221{"id":"stack-71276790","source":"stackoverflow","questionId":71276790,"title":"List files from a static folder in FastAPI","tags":["filesystems","fastapi"],"text":"Title: List files from a static folder in FastAPI\nTags: filesystems, fastapi\nSource: Stack Overflow\n\nQuestion:\nI know how to serve static files in FastAPI using StaticFiles, how can I enable\ndirectory listing like in Apache web server?\n\n```\nfrom fastapi import FastAPI\nfrom fastapi.staticfiles import StaticFiles\n\napp = FastAPI(...)\n\napp.mount(\"/samples\", StaticFiles(directory='samples'), name=\"samples\")\n\n# GET http://localhost:8000/samples/path/to/file.jpg -> OK\n# GET http://localhost:8000/samples -> not found error\n```\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI\nfrom fastapi.staticfiles import StaticFiles\n\napp = FastAPI(...)\n\napp.mount(\"/samples\", StaticFiles(directory='samples'), name=\"samples\")\n\n# GET http://localhost:8000/samples/path/to/file.jpg -> OK\n# GET http://localhost:8000/samples -> not found error\n```\n\n```py\nimport os\nfrom fastapi import FastAPI, Request\nfrom fastapi.responses import HTMLResponse\nfrom fastapi.staticfiles import StaticFiles\nfrom fastapi.templating import Jinja2Templates\n\napp = FastAPI()\n\napp.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")\n\n\ntemplates = Jinja2Templates(directory=\"templates\")\n\n\n@app.get(\"/static\", response_class=HTMLResponse)\ndef list_files(request: Request):\n\n files = os.listdir(\"./static\")\n files_paths = sorted([f\"{request.url._url}/{f}\" for f in files])\n print(files_paths)\n return templates.TemplateResponse(\n \"list_files.html\", {\"request\": request, \"files\": files_paths}\n )\n```\n\n```html\n<html>\n <head>\n <title>Files</title>\n </head>\n <body>\n <h1>Files:</h1>\n <ul>\n {% for file in files %}\n <li><a href=\"{{file}}\">{{file}}</a></li>\n {% endfor %}\n </ul>\n </body>\n</html>\n```\n\n```text\n/static\n```\n\n```text\nlist_files.html\n```\n\n```text\ntemplates/\n```\n\n========================================\n\nComments:\n- Did you figure this out?\n- No, but maybe putting a reverse proxy such as nginx to serve static content can help\n- It can be as simple as this github.com/wemadefree/webook-fastapi/blob/main/nginx/…\n- Thank you for the answer, beware list_files.html should be in templates/ folder.","metadata":{"transformedAt":"2026-08-18T18:32:29.111Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":6,"totalLines":96,"estimatedTokens":542}}222{"id":"stack-71256713","source":"stackoverflow","questionId":71256713,"title":"How does CryptContext hashing know what secret to use?","tags":["fastapi","passlib"],"text":"Title: How does CryptContext hashing know what secret to use?\nTags: fastapi, passlib\nSource: Stack Overflow\n\nQuestion:\nI have the following code snippet:\n\n```\nfrom passlib.context import CryptContext\n\npwd_context = CryptContext(schemes=[\"bcrypt\"], deprecated=\"auto\")\npwd_context.hash(password)\n```\n\nWhich is described here.\n\nWhat i don't understand is, how can this be secure if it returns the same hashed password all the time without considering another secret_key for example to hash the password value?\n\n========================================\n\nCode:\n```text\nfrom passlib.context import CryptContext\n\npwd_context = CryptContext(schemes=[\"bcrypt\"], deprecated=\"auto\")\npwd_context.hash(password)\n```\n\n```text\n>>> from passlib.context import CryptContext\n>>>\n>>> pwd_context = CryptContext(schemes=[\"bcrypt\"], deprecated=\"auto\")\n>>> pwd_context.hash(\"test\")\n'$2b$12$0qdOrAMoK7dgySjmNbyRpOggbk.IM2vffMh8rFoITorRKabyFiElC'\n>>> pwd_context.hash(\"test\")\n'$2b$12$gqaNzwTmjAQbGW/08zs4guq1xWD/g7JkWtKqE2BWo6nU1TyP37Feq'\n```\n\n```text\n>>> pwd_context.hash(\"test\", salt=\"a\"*21 + \"e\")\n'$2b$12$aaaaaaaaaaaaaaaaaaaaaehsFuAEeaAnjmdgkAxYfzHEipCaNQ0ES'\n ^--------------------^\n```\n\n```text\n>>> pwd_context.hash(\"test\", salt=\"a\"*21 + \"e\")\n'$2b$12$aaaaaaaaaaaaaaaaaaaaaehsFuAEeaAnjmdgkAxYfzHEipCaNQ0ES'\n>>> pwd_context.hash(\"test\", salt=\"a\"*21 + \"e\")\n'$2b$12$aaaaaaaaaaaaaaaaaaaaaehsFuAEeaAnjmdgkAxYfzHEipCaNQ0ES'\n```\n\n```text\n>>> pwd_context.hash(\"test\")\n'$2b$12$gqaNzwTmjAQbGW/08zs4guq1xWD/g7JkWtKqE2BWo6nU1TyP37Feq'\n ^--------------------^\n```\n\n```text\n>>> pwd_context.hash(\"test\")\n'$2b$12$gqaNzwTmjAQbGW/08zs4guq1xWD/g7JkWtKqE2BWo6nU1TyP37Feq'\n ^-----------------------------^\n```\n\n```text\npwd_context.hash\n```\n\n```text\nhash\n```\n\n```text\npasslib\n```\n\n```text\nsalt\n```\n\n```text\nsalt + password\n```\n\n```text\nsalt\n```\n\n```text\n$\n```\n\n```text\n2b\n```\n\n```text\n12\n```\n\n```text\n[.Oeu]\n```\n\n```text\n[./A-Za-z0-9]\n```\n\n```text\ntest\n```\n\n```text\ntest\n```\n\n```text\ntest\n```\n\n```text\nbcrypt\n```\n\n```text\n12\n```\n\n```text\nrounds\n```\n\n```text\nrounds\n```\n\n```text\npasslib.hash\n```\n\n========================================\n\nComments:\n- Hi there, great explanation. Thank you!!! One last question that still bothers me... Assuming that passlib generates a salt for me, then how is it possible that i can run the same thing again from another pc without specifying a salt (so a new one will generated) but it will still be able to know if the plain text is the same value as the hashed one?\n- I touched on that in the last paragraph; since you know all the necessary parts when verifying a password (the password, the salt and the hash), you can supply all the necessary parts. When verifying you use the existing salt and do not generate a new one; you use the one stored in the string returned from `hash` (for bcrypt, the first 22 characters). You extract the salt from the string, then give that as the `salt` parameter (don't do it manually except for when playing around with this to learn - otherwise use `passlib.verify` that will extract the salt and do the comparison The Right Way)\n- @MatsLindh thanks for taking the time to write this detailed explanation, however I find parts of the answer a bit confusing. You said, \"The salt is the first 22 characters of the actual bcrypt value.\" and then later you said \"The first 22 characters of this string is the hash.\", did u mean to say `salt` instead of `hash` in the second sentence? In the password hash examples you gave, for eg '$2b$12$aaaaaaaaaaaaaaaaaaaaaOm/4kNFO.mb908CDiMw1TgDxyZeDSwu‌​m', none of the hashes have a salt length of 22, in above example 'aaaaaaaaaaaaaaaaaaaaa' has a length of 21. Are these typos(same for all egs)?\n- @lordvcs The length difference is related to the part mention about the passlib warning for padding bits; this occurs if the last character in the salt isn't one of `[.Oeu]`. I'll add a bit more details about that. And yes, the second sentence about 22 characters should reference the salt, not the hash. The answer has now been update to address all your concerns :-)","metadata":{"transformedAt":"2026-08-18T18:32:29.111Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":25,"totalLines":146,"estimatedTokens":1023}}223{"id":"stack-73585779","source":"stackoverflow","questionId":73585779,"title":"How to return a PDF file from in-memory buffer using FastAPI?","tags":["python","pdf","amazon-s3","boto3","fastapi"],"text":"Title: How to return a PDF file from in-memory buffer using FastAPI?\nTags: python, pdf, amazon-s3, boto3, fastapi\nSource: Stack Overflow\n\nQuestion:\nI want to get a PDF file from s3 and then return it to the frontend from FastAPI backend.\n\nThis is my code:\n\n```\n@router.post(\"/pdf_document\")\ndef get_pdf(document : PDFRequest) :\n s3 = boto3.client('s3')\n file=document.name\n f=io.BytesIO()\n s3.download_fileobj('adm2yearsdatapdf', file,f)\n return StreamingResponse(f, media_type=\"application/pdf\")\n```\n\nThis API returns `200` status code, but it does not return the PDF file as a response.\n\n========================================\n\nTop Answer:\nMy buffer and the code to send pdf as a downloadable link in http://127.0.0.1:8000/docs\nadd this in headers dictionary\n\"content-type\": \"application/octet-stream\"\n\n```\nasync def convert_img_to_webp(img):\n image_io = BytesIO()\n image = Image.open(img)\n image.convert(\"RGB\")\n image.save(image_io,\"PDF\")\n image_io.seek(0)\n # BackgroundTasks.add_task(image_io.close)\n return image_io\n\n@router.post(\"/image/\")\nasync def upload_file(file:UploadFile):\n if file:\n data = await convert_img_to_webp(file.file)\n headers = {'Content-Disposition': 'inline; filename=\"sample.pdf\"',\"content-type\": \"application/octet-stream\"}\n return StreamingResponse(data,media_type='application/pdf',headers=headers)\n else:\n print(\"file not found\")\n return\n```\n\n========================================\n\nCode:\n```py\n@router.post(\"/pdf_document\")\ndef get_pdf(document : PDFRequest) :\n s3 = boto3.client('s3')\n file=document.name\n f=io.BytesIO()\n s3.download_fileobj('adm2yearsdatapdf', file,f)\n return StreamingResponse(f, media_type=\"application/pdf\")\n```\n\n```text\n200\n```\n\n```py\nfrom fastapi import Response, BackgroundTasks\n\n@app.get(\"/pdf\")\ndef get_pdf(background_tasks: BackgroundTasks):\n buffer = io.BytesIO() # BytesIO stream containing the pdf data\n # ...\n background_tasks.add_task(buffer.close)\n headers = {'Content-Disposition': 'inline; filename=\"out.pdf\"'}\n return Response(buffer.getvalue(), headers=headers, media_type='application/pdf')\n```\n\n```py\nheaders = {'Content-Disposition': 'attachment; filename=\"out.pdf\"'}\n```\n\n```text\nStreamingResponse\n```\n\n```text\nResponse\n```\n\n```text\nBytesIO.getvalue()\n```\n\n```text\nmedia_type\n```\n\n```text\nContent-Disposition\n```\n\n```text\nbuffer\n```\n\n```text\nclose()\n```\n\n```text\nBackgroundTasks\n```\n\n```text\nbuffer\n```\n\n```text\npdf_bytes = buffer.getvalue()\n```\n\n```text\nbuffer.close()\n```\n\n```text\nreturn Response(pdf_bytes, headers=...\n```\n\n```text\nasync def convert_img_to_webp(img):\n image_io = BytesIO()\n image = Image.open(img)\n image.convert(\"RGB\")\n image.save(image_io,\"PDF\")\n image_io.seek(0)\n # BackgroundTasks.add_task(image_io.close)\n return image_io\n\n\n@router.post(\"/image/\")\nasync def upload_file(file:UploadFile):\n if file:\n data = await convert_img_to_webp(file.file)\n headers = {'Content-Disposition': 'inline; filename=\"sample.pdf\"',\"content-type\": \"application/octet-stream\"}\n return StreamingResponse(data,media_type='application/pdf',headers=headers)\n else:\n print(\"file not found\")\n return\n```\n\n========================================\n\nComments:\n- Tested with a local file I get AttributeError: '_io.BytesIO' object has no attribute 'encode' error\n- That should be `buffer.getvalue()` to get the bytes containing the entire contents of the buffer.\n- @climate-coder Please have a look at this answer and this answer. Related answers that might prove helpful can be found here, as well as here and here","metadata":{"transformedAt":"2026-08-18T18:32:29.111Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":17,"totalLines":158,"estimatedTokens":895}}224{"id":"stack-68505216","source":"stackoverflow","questionId":68505216,"title":"ModuleNotFoundError: No module named 'app.routes'","tags":["python","fastapi"],"text":"Title: ModuleNotFoundError: No module named 'app.routes'\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nSo I'm learning fastapi right now and I was trying to separate my project into multiple files but when I do I get this error.\n\n`ModuleNotFoundError: No module named 'app.routes'`\n\nI have read This multiple times and I'm pretty sure I did everything right can anyone tell me what I did wrong?\n\n```\napp\n│ main.py\n│ __init__.py\n│\n└───routes\n auth.py\n __init__.py\n```\n\nmain.py\n\n```\nfrom fastapi import FastAPI\nfrom app.routes import auth\n\napp = FastAPI()\n\napp.include_router(auth.router)\n```\n\nauth.py\n\n```\nfrom fastapi import APIRouter\n\nrouter = APIRouter()\n\n@router.get(\"/test\")\nasync def test():\n return {\"test\": \"test\"}\n```\n\nI ran `uvicorn main:app --reload`\n\n========================================\n\nTop Answer:\nJust run below command\n\nexport PYTHONPATH=$PWD\n\n========================================\n\nCode:\n```text\napp\n│ main.py\n│ __init__.py\n│\n└───routes\n auth.py\n __init__.py\n```\n\n```text\nfrom fastapi import FastAPI\nfrom app.routes import auth\n\napp = FastAPI()\n\napp.include_router(auth.router)\n```\n\n```text\nfrom fastapi import APIRouter\n\nrouter = APIRouter()\n\n@router.get(\"/test\")\nasync def test():\n return {\"test\": \"test\"}\n```\n\n```text\nModuleNotFoundError: No module named 'app.routes'\n```\n\n```text\nuvicorn main:app --reload\n```\n\n```text\nuvicorn app.main:app --reload\n```\n\n```text\napp\n```\n\n```text\nmyproject/\n└── app/\n ├── main.py\n ├── __init__.py\n └── utils/\n ├── tools.py\n └── __init__.py\n```\n\n```py\n#run.py\nfrom app.main import app\n```\n\n```text\nmyproject/\n├── app/\n│ ├── main.py\n│ └── utils/\n│ ├── tools.py\n│ └── __init__.py\n└── run.py\n```\n\n```text\ncd myproject/\nuvicorn app.main:app --reload\n```\n\n```text\nimport .utils.tools\n```\n\n```text\nimport utils.tools\n```\n\n```text\nimport app.utils.tools\n```\n\n```text\nimport myproject.app.utils.tools\n```\n\n```text\napp\n```\n\n```text\nuvicorn run:app --reload\n```\n\n```text\ncd\n```\n\n========================================\n\nComments:\n- Change routes to routers as said in docs.\n- The directory is called routes though?\n- I already tried that earlier and It didn't work it gives me `ERROR: Error loading ASGI app. Could not import module \"app.main\".`\n- Double check your `__init__.py` is spelled correctly. I replicated your code successfully on ubuntu 18.01\n- I checked them twice. They both have nothing in them and I copy and pasted from the docs and it still doesn't work.\n- Does me using windows 11 have anything to do with this?\n- No, windows does not make any difference. For whatever reason python is not seeing it as a module. Maybe try from a terminal to see if it works? From the directory above `app` run `python3 -c 'import app.main'`\n- I tried from VScode terminal, cmd, PowerShell, and windows terminal and they were all the same. Running `python3 -c 'import app.main'` gives me `ModuleNotFoundError: No module named 'app.router'`\n- I'm not overly familiar with windows but this sounds like a path issue -- maybe try the following and see if it's resolved net-informations.com/python/intro/path.htm\n- Instead of `from app.routes import auth` in main.py what if you do `from routes import auth` have you tried this?\n- @MichaelKremenetsky Did you saved the program? cause i had same error and when i saved it was gone\n- Post the information about the bugfix here, just adding a link is usually a bad idea.","metadata":{"transformedAt":"2026-08-18T18:32:29.111Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":18,"totalLines":174,"estimatedTokens":859}}225{"id":"stack-61383179","source":"stackoverflow","questionId":61383179,"title":"FastAPI passing json in get request via TestClient","tags":["python","fastapi"],"text":"Title: FastAPI passing json in get request via TestClient\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm try to test the api I wrote with Fastapi. I have the following method in my router :\n\n```\n@app.get('/webrecord/check_if_object_exist')\nasync def check_if_object_exist(payload: WebRecord) -> bool:\n key = get_key_of_obj(payload.data) if payload.key is None else payload.key\n return await check_if_key_exist(key)\n```\n\nand the following test in my test file :\n\n```\nclient = TestClient(app)\nclass ServiceTest(unittest.TestCase):\n.....\n def test_check_if_object_is_exist(self):\n webrecord_json = {'a':1}\n response = client.get(\"/webrecord/check_if_object_exist\", json=webrecord_json)\n assert response.status_code == 200\n assert response.json(), \"webrecord should already be in db, expected : True, got : {}\".format(response.json())\n```\n\nWhen I run the code in debug I realized that the break points inside the get method aren't reached. When I changed the type of the request to post everything worked fine.\n\nWhat am I doing wrong?\n\n========================================\n\nCode:\n```text\n@app.get('/webrecord/check_if_object_exist')\nasync def check_if_object_exist(payload: WebRecord) -> bool:\n key = get_key_of_obj(payload.data) if payload.key is None else payload.key\n return await check_if_key_exist(key)\n```\n\n```text\nclient = TestClient(app)\nclass ServiceTest(unittest.TestCase):\n.....\n def test_check_if_object_is_exist(self):\n webrecord_json = {'a':1}\n response = client.get(\"/webrecord/check_if_object_exist\", json=webrecord_json)\n assert response.status_code == 200\n assert response.json(), \"webrecord should already be in db, expected : True, got : {}\".format(response.json())\n```\n\n```text\n@app.get('/webrecord/check_if_object_exist/{key}')\nasync def check_if_object_exist(key: str, data: str) -> bool:\n key = get_key_of_obj(payload.data) if payload.key is None else payload.key\n return await check_if_key_exist(key)\n\n\nclient = TestClient(app)\nclass ServiceTest(unittest.TestCase):\n.....\n def test_check_if_object_is_exist(self):\n response = client.get(\"/webrecord/check_if_object_exist/key\", params={\"data\": \"my_data\")\n assert response.status_code == 200\n assert response.json(), \"webrecord should already be in db, expected : True, got : {}\".format(response.json())\n```\n\n```text\nNone\n```\n\n========================================\n\nComments:\n- Probably you are POSTing some data to an URL that expects GET requests. Fastapi uses starlette, which uses requests. I don't see any json parameter in get requests. Have you checked that the requeste url is correct? requests.readthedocs.io/en/master/user/quickstart/…\n- As u can see the request type is get and I'm using the get function of the client. The request url is indeed correct. How can I pass json in body to get request ?\n- That's my point. In order to pass data in a get request, you should encode it in the url and thus I asked about the url. I would change your type of request into POST, both in the test and the server code (so the server accepts POST requests for that url)\n- As I mentioned in the post that exactly what I have done aftewards and everything worked. I checked also the put method and its also based on request.put. There is an option to send there json , just need to pass on headers but it still doesnt work , check this post - stackoverflow.com/questions/38752091/…\n- That's my point. In order to pass data, you have to use POST, or as alternative, PUT. But GET cannot be used to pass data, unless you explicitly encode the data in the url, though it is not advisable if you have a lot of data or if you want it in a particular format (e.g. JSON). Either you change the representation of your data or you will never be able to pass data via the body with GET\n- I see, can u post your answer as a comment so that I can approve it ?\n- I'll, but would you be open to slightly changing the url? I can write down a possible alternative that keeps GET request\n- it depends how complicated the url is :) but sure","metadata":{"transformedAt":"2026-08-18T18:32:29.111Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":83,"estimatedTokens":1022}}226{"id":"stack-65361686","source":"stackoverflow","questionId":65361686,"title":"Websockets bridge for audio stream in FastAPI","tags":["python","websocket","python-asyncio","fastapi","starlette"],"text":"Title: Websockets bridge for audio stream in FastAPI\nTags: python, websocket, python-asyncio, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\n### Objective\n\nMy objective is to consume an audio stream. Logically, this is my objective:\n\n- Audio stream comes through WebSocket A (`FastAPI` endpoint)\n\n- Audio stream is bridged to a different WebSocket, B, which will return a JSON (Rev-ai's WebSocket)\n\n- Json results are sent back through WebSocket A, in real-time. Thus, **while the audio stream is still coming in.**\n\n### Possible solution\n\nTo solve this problem, I've had quite a few ideas, but ultimately I've been trying to bridge `WebSocket A` to `WebSocket B`. My attempt so far involves a `ConnectionManager` class, which contains a `Queue.queue`. The chunks of the audio stream are added to this queue so that we do not consume directly from `WebSocket A`.\n\nThe `ConnectionManager` also contains a generator method to yield all values from the queue.\n\nMy FastAPI implementation consumes from `websocket A` like this:\n\n```\n@app.websocket(\"/ws\")\nasync def predict_feature(websocket: WebSocket):\n await manager.connect(websocket)\n try:\n while True:\n chunk = await websocket.receive_bytes()\n manager.add_to_buffer(chunk)\n except KeyboardInterrupt:\n manager.disconnect()\n```\n\nConcurrent to this ingestion, I'd like to have a task that would bridge our audio stream to `WebSocket B`, and send the obtained values to `WebSocket A`. The audio stream could be consumed through the aforementioned `generator` method.\n\nThe generator method is necessary due to how WebSocket B consumes messages, as shown in Rev-ai's examples:\n\n```\nstreamclient = RevAiStreamingClient(access_token, config)\nresponse_generator = streamclient.start(MEDIA_GENERATOR)\nfor response in response_generator:\n # return through websocket A this value\n print(response)\n```\n\nThis is one of the biggest challenges, as we need to be consuming data into a generator and getting the results in real-time.\n\n### Latest attempts\n\nI've been trying my luck with `asyncio`; from what i'm understanding, a possibility would be to create a coroutine that would run in the background. I've been unsuccessful with this, but it sounded promising.\n\nI've thought about triggering this through the `FastAPI` startup event, but I'm having trouble achieving concurrency. I tried to use `event_loops`, but it gave me a `nested event loop` related error.\n\n### Caveat\n\nFastAPI can be optional if your insight deems so, and in a way so is WebSocket A. At the end of the day, the ultimate objective is to receive an audio stream through our own API endpoint, run it through Rev.ai's WebSocket, do some extra processing, and send the results back.\n\n========================================\n\nCode:\n```text\n@app.websocket(\"/ws\")\nasync def predict_feature(websocket: WebSocket):\n await manager.connect(websocket)\n try:\n while True:\n chunk = await websocket.receive_bytes()\n manager.add_to_buffer(chunk)\n except KeyboardInterrupt:\n manager.disconnect()\n```\n\n```text\nstreamclient = RevAiStreamingClient(access_token, config)\nresponse_generator = streamclient.start(MEDIA_GENERATOR)\nfor response in response_generator:\n # return through websocket A this value\n print(response)\n```\n\n```text\nFastAPI\n```\n\n```text\nWebSocket A\n```\n\n```text\nWebSocket B\n```\n\n```text\nConnectionManager\n```\n\n```text\nQueue.queue\n```\n\n```text\nWebSocket A\n```\n\n```text\nConnectionManager\n```\n\n```text\nwebsocket A\n```\n\n```text\nWebSocket B\n```\n\n```text\nWebSocket A\n```\n\n```text\ngenerator\n```\n\n```text\nasyncio\n```\n\n```text\nFastAPI\n```\n\n```text\nevent_loops\n```\n\n```text\nnested event loop\n```\n\n```py\nimport asyncio\n\nfrom fastapi import FastAPI\nfrom fastapi import WebSocket\nimport websockets\napp = FastAPI()\n\nws_b_uri = \"ws://localhost:8001/ws_b\"\n\n\nasync def forward(ws_a: WebSocket, ws_b: websockets.WebSocketClientProtocol):\n while True:\n data = await ws_a.receive_bytes()\n print(\"websocket A received:\", data)\n await ws_b.send(data)\n\n\nasync def reverse(ws_a: WebSocket, ws_b: websockets.WebSocketClientProtocol):\n while True:\n data = await ws_b.recv()\n await ws_a.send_text(data)\n print(\"websocket A sent:\", data)\n\n\n@app.websocket(\"/ws_a\")\nasync def websocket_a(ws_a: WebSocket):\n await ws_a.accept()\n async with websockets.connect(ws_b_uri) as ws_b_client:\n fwd_task = asyncio.create_task(forward(ws_a, ws_b_client))\n rev_task = asyncio.create_task(reverse(ws_a, ws_b_client))\n await asyncio.gather(fwd_task, rev_task)\n\n\n@app.websocket(\"/ws_b\")\nasync def websocket_b(ws_b_server: WebSocket):\n await ws_b_server.accept()\n while True:\n data = await ws_b_server.receive_bytes()\n print(\"websocket B server recieved: \", data)\n await ws_b_server.send_text('{\"response\": \"value from B server\"}')\n```\n\n```py\nimport asyncio\nimport time\nfrom typing import Generator\nfrom fastapi import FastAPI\nfrom fastapi import WebSocket\nimport janus\nimport queue\n\napp = FastAPI()\n\n\n# Stub generator function (using websocket B in internal)\ndef stream_client_start(input_gen: Generator) -> Generator:\n for chunk in input_gen:\n time.sleep(1)\n yield f\"Get {chunk}\"\n\n\n# queue to generator auxiliary adapter\ndef queue_to_generator(sync_queue: queue.Queue) -> Generator:\n while True:\n yield sync_queue.get()\n\n\nasync def forward(ws_a: WebSocket, queue_b):\n while True:\n data = await ws_a.receive_bytes()\n print(\"websocket A received:\", data)\n await queue_b.put(data)\n\n\nasync def reverse(ws_a: WebSocket, queue_b):\n while True:\n data = await queue_b.get()\n await ws_a.send_text(data)\n print(\"websocket A sent:\", data)\n\n\ndef process_b_client(fwd_queue, rev_queue):\n response_generator = stream_client_start(queue_to_generator(fwd_queue))\n for r in response_generator:\n rev_queue.put(r)\n\n\n@app.websocket(\"/ws_a\")\nasync def websocket_a(ws_a: WebSocket):\n loop = asyncio.get_event_loop()\n fwd_queue = janus.Queue()\n rev_queue = janus.Queue()\n await ws_a.accept()\n\n process_client_task = loop.run_in_executor(None, process_b_client, fwd_queue.sync_q, rev_queue.sync_q)\n fwd_task = asyncio.create_task(forward(ws_a, fwd_queue.async_q))\n rev_task = asyncio.create_task(reverse(ws_a, rev_queue.async_q))\n await asyncio.gather(process_client_task, fwd_task, rev_task)\n```\n\n```text\nA\n```\n\n```text\nB\n```\n\n```text\nB\n```\n\n```text\nws_b_uri\n```\n\n```text\nA\n```\n\n```text\nforward\n```\n\n```text\nreverse\n```\n\n```text\nasyncio.gather()\n```\n\n```text\nB\n```\n\n```text\nrev-ai\n```\n\n```text\nstream_client_start\n```\n\n```text\nstreamclient.start\n```\n\n```text\nMEDIA_GENERATOR\n```\n\n```text\nresponse_generator\n```\n\n```text\nrun_in_executor\n```\n\n```text\njanus\n```\n\n```text\nA -> B\n```\n\n```text\nB -> A\n```\n\n========================================\n\nComments:\n- Hello @alex_noname! Your answer is very insightful, but there's a layer I'm afraid I should've clarified further, which would be the interface Rev-ai provides to reach WebSocket B, enforcing a generator. Nonetheless, thank you for how you've structured your answer. I've added an extra bit to the question to clarify that point. I'd like to ask for your input with the generator in mind, and if no development comes I'll accept this answer - since it indeed shows how to bridge two WebSockets.\n- I've updated the answer for the generators, but if there are problems with the `rev-ai` library, then I probably won't be able to help.\n- @alex_noname thx a lot for the websocket bridge implementation, exactly what I needed!","metadata":{"transformedAt":"2026-08-18T18:32:29.111Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":37,"totalLines":321,"estimatedTokens":1897}}227{"id":"stack-70793174","source":"stackoverflow","questionId":70793174,"title":"FastAPI - @Schema(hidden=True) not working when trying to hide the schema section on swagger docs","tags":["python","swagger","openapi","fastapi"],"text":"Title: FastAPI - @Schema(hidden=True) not working when trying to hide the schema section on swagger docs\nTags: python, swagger, openapi, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm trying to hide the entire schemas section of the FastAPI generated swagger docs. I've checked the docs and tried this but the schema section still shows.\n\n```\n@Schema(hidden=True)\n class theSchema(BaseModel):\n category: str\n```\n\nHow do I omit one particular schema or the entire schemas section from the returned swagger docs.\n\ndocExpansion does not appear to work either. What am I missing?\n\n```\napp = FastAPI(\n openapi_tags=tags_metadata,\n title=\"Documentation\",\n description=\"API endpoints\",\n version=\"0.1\",\n docExpansion=\"None\"\n)\n```\n\n========================================\n\nTop Answer:\nset `include_in_schema=False` in the args to the `FastAPI` instance decorator instead\n\n```\napp = FastAPI(...)\n\n@app.get(\"/\", include_in_schema=False)\nasync def root():\n ...\n```\n\n========================================\n\nCode:\n```text\n@Schema(hidden=True)\n class theSchema(BaseModel):\n category: str\n```\n\n```text\napp = FastAPI(\n openapi_tags=tags_metadata,\n title=\"Documentation\",\n description=\"API endpoints\",\n version=\"0.1\",\n docExpansion=\"None\"\n)\n```\n\n```text\napp = FastAPI(swagger_ui_parameters={\"defaultModelsExpandDepth\": -1})\n```\n\n```text\napp = FastAPI(...)\n\n@app.get(\"/\", include_in_schema=False)\nasync def root():\n ...\n```\n\n```text\ninclude_in_schema=False\n```\n\n```text\nFastAPI\n```\n\n```py\nclass ModelA(BaseModel):\n Field1: int | None = None\n Field2: str | None = None\n\n\nclass Config:\n schema_extra = {\"hidden\": True}\n```\n\n```py\ndef custom_openapi():\n if app.openapi_schema:\n return app.openapi_schema\n openapi_schema = get_openapi(\n title=\"My app\",\n version=\"1.0\",\n description=\"My app's description\",\n routes=app.routes,\n )\n if \"components\" in openapi_schema:\n # I used jsonref to dereference related schemas\n # You will need to install jsonref\n dereferenced_schema = jsonref.loads(json.dumps(openapi_schema), lazy_load=False)\n openapi_schema[\"components\"] = jsonable_encoder(dereferenced_schema[\"components\"])\n for schema_name in openapi_schema[\"components\"][\"schemas\"].copy().keys():\n schema = openapi_schema[\"components\"][\"schemas\"][schema_name]\n if \"enum\" in schema:\n print(f\"Removing {schema_name} as it is an enum\")\n del openapi_schema[\"components\"][\"schemas\"][schema_name]\n continue\n\n hide = schema.get(\"hidden\", False)\n if hide:\n print(f\"Removing {schema_name} as it is hidden\")\n del openapi_schema[\"components\"][\"schemas\"][schema_name]\n continue\n\n app.openapi_schema = openapi_schema\n return app.openapi_schema\n```\n\n```py\napp.openapi = custom_openapi\n```\n\n```py\n@app.get(\"/items/\", include_in_schema=False)\nasync def read_items()\n```\n\n```text\ninclude_in_schema\n```\n\n```text\nFalse\n```\n\n========================================\n\nComments:\n- That removes the entire endpoint from the docs. I only want to remove the schema section\n- that is not a very good approach, and you have to deploy the new html/js files as static and .... it's a lot of work to do.","metadata":{"transformedAt":"2026-08-18T18:32:29.112Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":12,"totalLines":143,"estimatedTokens":827}}228{"id":"stack-77690364","source":"stackoverflow","questionId":77690364,"title":"How to return plain text in FastAPI","tags":["python","fastapi"],"text":"Title: How to return plain text in FastAPI\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nIn this example, the entrypoint http://127.0.0.1:8000/ returns formatted text:\n\n`\"Hello \\\"World\\\"!\"`\n\nThe quotes are masked by a slash, and quotes are added both at the beginning and at the end. How to return unformatted text, identical to my string `Hello \"World\"!`.\n\n```\nimport uvicorn\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/\",)\ndef read_root():\n return 'Hello \"World\"!'\n\nuvicorn.run(app)\n```\n\n========================================\n\nTop Answer:\nYou can also explicitly return a `PlainTextResponse` object:\n\n```\nimport uvicorn\nfrom fastapi import FastAPI\nfrom fastapi.responses import PlainTextResponse\n\napp = FastAPI()\n\n@app.get(\"/\")\ndef read_root():\n return PlainTextResponse('Hello \"World\"!')\n\nuvicorn.run(app)\n```\n\nSince media type is immaterial here, you can also return a `Response` object (`PlainTextResponse` is a child class of `Response` where `media_type=\"text/plain\"`):\n\n```\nimport uvicorn\nfrom fastapi import FastAPI, Response\n\napp = FastAPI()\n\n@app.get(\"/\")\ndef read_root():\n return Response('Hello \"World\"!')\n\nuvicorn.run(app)\n```\n\n========================================\n\nCode:\n```py\nimport uvicorn\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n\n@app.get(\"/\",)\ndef read_root():\n return 'Hello \"World\"!'\n\n\nuvicorn.run(app)\n```\n\n```text\n\"Hello \\\"World\\\"!\"\n```\n\n```text\nHello \"World\"!\n```\n\n```text\nimport uvicorn\nfrom fastapi import FastAPI\nfrom fastapi.responses import PlainTextResponse\n\napp = FastAPI()\n\n\n@app.get(\n \"/\",\n response_class=PlainTextResponse,\n)\ndef read_root():\n return 'Hello \"World\"!'\n\n\nuvicorn.run(app)\n```\n\n```text\nPlainTextResponse\n```\n\n```py\nimport uvicorn\nfrom fastapi import FastAPI\nfrom fastapi.responses import PlainTextResponse\n\napp = FastAPI()\n\n@app.get(\"/\")\ndef read_root():\n return PlainTextResponse('Hello \"World\"!')\n\nuvicorn.run(app)\n```\n\n```py\nimport uvicorn\nfrom fastapi import FastAPI, Response\n\napp = FastAPI()\n\n@app.get(\"/\")\ndef read_root():\n return Response('Hello \"World\"!')\n\nuvicorn.run(app)\n```\n\n```text\nPlainTextResponse\n```\n\n```text\nResponse\n```\n\n```text\nPlainTextResponse\n```\n\n```text\nResponse\n```\n\n```text\nmedia_type=\"text/plain\"\n```\n\n========================================\n\nComments:\n- This answer might help you better understand what takes place behind the scenes, when returning a response from a FastAPI app.","metadata":{"transformedAt":"2026-08-18T18:32:29.112Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":12,"totalLines":158,"estimatedTokens":604}}229{"id":"stack-70854314","source":"stackoverflow","questionId":70854314,"title":"Use FastAPI to interact with async loop","tags":["python","python-asyncio","fastapi"],"text":"Title: Use FastAPI to interact with async loop\nTags: python, python-asyncio, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am running coroutines of 'workers' whose job it is to wait 5s, get values from an asyncio.Queue() and print them out continually.\n\n```\nq = asyncio.Queue()\n\ndef worker():\n while True:\n await asyncio.sleep(5)\n i = await q.get()\n print(i)\n q.task_done()\n\nasync def main(q):\n workers = [asyncio.create_task(worker()) for n in range(10)]\n await asyncio.gather(*workers)\n\nif __name__ == \"__main__\":\n asyncio.run(main())\n```\n\nI would like to be able to interact with the queue through http requests using FastAPI. For example POST requests that would 'put' items in the queue for the workers to print.\n\nI'm unsure how I can run the coroutines of the workers concurrently with FastAPI to achieve this effect. Uvicorn has its own event loop I believe and my attempts to use asyncio methods have been unsuccessful.\n\nThe router would look something like this I think.\n\n```\n@app.post(\"/\")\nasync def put_queue(data:str):\n return q.put(data)\n```\n\nAnd I'm hoping there's something that would have an effect like this:\n\n```\nawait asyncio.gather(main(),{FastApi() app run})\n```\n\n========================================\n\nCode:\n```text\nq = asyncio.Queue()\n\ndef worker():\n while True:\n await asyncio.sleep(5)\n i = await q.get()\n print(i)\n q.task_done()\n\nasync def main(q):\n workers = [asyncio.create_task(worker()) for n in range(10)]\n await asyncio.gather(*workers)\n\n\nif __name__ == \"__main__\":\n asyncio.run(main())\n```\n\n```text\n@app.post(\"/\")\nasync def put_queue(data:str):\n return q.put(data)\n```\n\n```text\nawait asyncio.gather(main(),{FastApi() app run})\n```\n\n```py\nimport asyncio\n@app.on_event(\"startup\")\nasync def startup_event():\n asyncio.create_task(main())\n```\n\n========================================\n\nComments:\n- Do you know if there are any drawbacks to this? I am wondering which thread manages this process. Say if there was some blocking code inside main(), do you know if would that slow down my entire server?\n- @rID133 it would absolutely slow down your entire server, as it is using the same event-loop that the server is using to respond to requests. The fast-api documentation explains how to run background tasks within the event loop but points out running it as its own process with something like Celery is a better idea","metadata":{"transformedAt":"2026-08-18T18:32:29.112Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":87,"estimatedTokens":599}}230{"id":"stack-69083878","source":"stackoverflow","questionId":69083878,"title":"FastApi: How to define a global variable once","tags":["python","fastapi","asgi"],"text":"Title: FastApi: How to define a global variable once\nTags: python, fastapi, asgi\nSource: Stack Overflow\n\nQuestion:\nI want to define a dict variable once, generated from a text file, and use it to answer to API requests.\n\nThis variable should be always available till the end of server run.\n\nIn an example below:\n\n```\nfrom fastapi import FastAPI\nimport uvicorn\n\napp = FastAPI()\n\ndef init_data(path):\n print(\"init call\")\n data = {}\n data[1] = \"123\"\n data[2] = \"abc\"\n return data\n\ndata = init_data('path')\n\n@app.get('/')\ndef example_method():\n # data is defined\n return {'Data': data[1]}\n\nif __name__ == '__main__':\n uvicorn.run(f'example_trouble:app', host='localhost', port=8000)\n```\n\nI will get:\n\n```\ninit call\ninit call\nINFO: Started server process [9356]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\nINFO: Uvicorn running on http://localhost:8000 (Press CTRL+C to quit)\n```\n\nand request to localhost:8000 wouldn't raise any errors\n\nHow should I define a variable once, that would be accessed as a global variable to any request? Is there a common way to define it once and use it?\n\nrequirements if necessary:\n\n```\nfastapi==0.68.1\npydantic==1.8.2\nstarlette==0.14.2\ntyping-extensions==3.10.0.2\n```\n\n========================================\n\nTop Answer:\nThe current recommended approach to this in FastAPI is lifespans. Here's an example (untested):\n\n```\nfrom contextlib import asynccontextmanager\nfrom fastapi import FastAPI\n\ndata = {}\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI):\n # Init\n print(\"Startup\")\n data[\"path\"] = '/an/example/path'\n data[1] = \"123\"\n data[2] = \"abc\"\n\n yield\n\n # Shutdown\n print(\"Shutdown\")\n data.clear()\n\napp = FastAPI(lifespan=lifespan)\n\n@app.get('/')\ndef example_method():\n # data is defined\n return {'data': data[1]}\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nimport uvicorn\n\napp = FastAPI()\n\ndef init_data(path):\n print(\"init call\")\n data = {}\n data[1] = \"123\"\n data[2] = \"abc\"\n return data\n\ndata = init_data('path')\n\n@app.get('/')\ndef example_method():\n # data is defined\n return {'Data': data[1]}\n\nif __name__ == '__main__':\n uvicorn.run(f'example_trouble:app', host='localhost', port=8000)\n```\n\n```text\ninit call\ninit call\nINFO: Started server process [9356]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\nINFO: Uvicorn running on http://localhost:8000 (Press CTRL+C to quit)\n```\n\n```text\nfastapi==0.68.1\npydantic==1.8.2\nstarlette==0.14.2\ntyping-extensions==3.10.0.2\n```\n\n```py\nfrom fastapi import FastAPI\nimport uvicorn\n\napp = FastAPI()\ndata = {}\n\n@app.on_event('startup')\ndef init_data():\n print(\"init call\")\n path='/an/example/path'\n data[1] = \"123\"\n data[2] = \"abc\"\n return data\n\n@app.get('/')\ndef example_method():\n # data is defined\n return {'Data': data[1]}\n\nif __name__ == '__main__':\n uvicorn.run(f'example_trouble:app', host='localhost', port=8000)\n```\n\n```text\nINFO: Started server process [37992]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\nINFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\ninit call\n```\n\n```text\ndata\n```\n\n```py\nfrom contextlib import asynccontextmanager\nfrom fastapi import FastAPI\n\ndata = {}\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI):\n # Init\n print(\"Startup\")\n data[\"path\"] = '/an/example/path'\n data[1] = \"123\"\n data[2] = \"abc\"\n\n yield\n\n # Shutdown\n print(\"Shutdown\")\n data.clear()\n\napp = FastAPI(lifespan=lifespan)\n\n@app.get('/')\ndef example_method():\n # data is defined\n return {'data': data[1]}\n```\n\n========================================\n\nComments:\n- What is the problem of your approach?\n- Creating a dict from a big file twice could be a real problem\n- try preloading: stackoverflow.com/questions/65636962/…\n- @Alex do you have any idea why your method is executed twice?\n- I suppose this is due to the asynchronous nature of the server\n- It almost works. I changed \"data = {}\" to \"global data\" and defined global variable in init_data(). In this example, data variable is redefined to an Empty dict again after init_data method call\n- can you define global variables inside the startup loop instead of creating a data object? What would be the pros / cons of that approach?","metadata":{"transformedAt":"2026-08-18T18:32:29.112Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":7,"totalLines":209,"estimatedTokens":1087}}231{"id":"stack-65667152","source":"stackoverflow","questionId":65667152,"title":"How to modify pydantic field when another one is changed?","tags":["python","validation","decorator","fastapi","pydantic"],"text":"Title: How to modify pydantic field when another one is changed?\nTags: python, validation, decorator, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI have a pydantic class such as:\n\n```\nfrom pydantic import BaseModel\nclass Programmer(BaseModel):\n python_skill: float\n stackoverflow_skill: float\n total_score: float = None\n```\n\nNow I am calculating the total_score according to the other fields:\n\n```\n@validator(\"total_score\", always=True)\ndef calculat_total_score(cls, v, *, values):\n return values.get(\"python_skill\") + values.get(\"stackoverflow_skill\")\n```\n\nThis works fine, but now when I change one of the skills:\n\n```\nprogrammer = Programmer(python_skill=1.0, stackoverflow_skill=9.0)\nprint(programmer.total_score) # return 10.0\nprogrammer.python_skill=2.0 \nprint(programmer.total_score) # still return 10.0\n```\n\nI would like the total_score to automatically update.\n\nAny solutions?\nTNX!!\n\n========================================\n\nCode:\n```text\nfrom pydantic import BaseModel\nclass Programmer(BaseModel):\n python_skill: float\n stackoverflow_skill: float\n total_score: float = None\n```\n\n```text\n@validator(\"total_score\", always=True)\ndef calculat_total_score(cls, v, *, values):\n return values.get(\"python_skill\") + values.get(\"stackoverflow_skill\")\n```\n\n```text\nprogrammer = Programmer(python_skill=1.0, stackoverflow_skill=9.0)\nprint(programmer.total_score) # return 10.0\nprogrammer.python_skill=2.0 \nprint(programmer.total_score) # still return 10.0\n```\n\n```text\nfrom pydantic import BaseModel, validator, root_validator\n\n\nclass Programmer(BaseModel):\n python_skill: float\n stackoverflow_skill: float\n total_score: float = None\n\n class Config:\n validate_assignment = True\n\n @root_validator\n def calculate_total_score(cls, values):\n values[\"total_score\"] = values.get(\"python_skill\") + values.get(\"stackoverflow_skill\")\n return values\n\n\nprogrammer = Programmer(python_skill=1.0, stackoverflow_skill=9.0)\nprint(programmer.total_score) # 10.0\nprogrammer.python_skill = 2.0\nprint(programmer.total_score) # 11.0\n```\n\n========================================\n\nComments:\n- `@root_validator` has been deprecated in favor of `@model_validator`","metadata":{"transformedAt":"2026-08-18T18:32:29.112Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":89,"estimatedTokens":551}}232{"id":"stack-70617258","source":"stackoverflow","questionId":70617258,"title":"Session object in FastAPI similar to Flask","tags":["python","fastapi"],"text":"Title: Session object in FastAPI similar to Flask\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to use session to pass variables across view functions in fastapi. However, I do not find any doc which specifically says of about session object. Everywhere I see, cookies are used. Is there any way to convert the below flask code in fastapi? I want to keep session implementation as simple as possible.\n\n```\nfrom flask import Flask, session, render_template, request, redirect, url_for\n\napp=Flask(__name__)\napp.secret_key='asdsdfsdfs13sdf_df%&' \n\n@app.route('/a')\ndef a():\n session['my_var'] = '1234' \n return redirect(url_for('b')) \n\n@app.route('/b')\ndef b():\n my_var = session.get('my_var', None)\n return my_var \n\nif __name__=='__main__':\n app.run(host='0.0.0.0', port=5000, debug = True)\n```\n\n========================================\n\nCode:\n```text\nfrom flask import Flask, session, render_template, request, redirect, url_for\n\n\napp=Flask(__name__)\napp.secret_key='asdsdfsdfs13sdf_df%&' \n\n@app.route('/a')\ndef a():\n session['my_var'] = '1234' \n return redirect(url_for('b')) \n\n\n@app.route('/b')\ndef b():\n my_var = session.get('my_var', None)\n return my_var \n\n\nif __name__=='__main__':\n app.run(host='0.0.0.0', port=5000, debug = True)\n```\n\n```py\n@app.route(\"/a\")\nasync def a(request: Request) -> RedirectResponse:\n\n request.session[\"my_var\"] = \"1234\"\n\n return RedirectResponse(\"/b\")\n\n@app.route(\"/b\")\nasync def b(request: Request) -> PlainTextResponse:\n\n my_var = request.session.get(\"my_var\", None)\n\n return PlainTextResponse(my_var)\n```\n\n```text\nSessionMiddleware\n```\n\n```text\nSessionMiddleware\n```\n\n```text\nRequest.session\n```\n\n========================================\n\nComments:\n- I am surprised, no where you have mentioned the set cookie but still I see in browser cookies are set. Can you explain this, why? Using session automatically creates cookies as well?\n- When using `SessionMiddleware`, a cookie with a specified name is set. The default name is 'session'. This helps the application identify the session. Other cookies in your browser may not be part of the local application. For example, in Google Chrome there is a cookie with the name of '1P_JAR'. When using `SessionMiddleware`, one cookie is used. Other cookies may be set by other responses.","metadata":{"transformedAt":"2026-08-18T18:32:29.112Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":86,"estimatedTokens":586}}233{"id":"stack-70272414","source":"stackoverflow","questionId":70272414,"title":"Lots of \"Uncaught signal: 6\" errors in Cloud Run","tags":["python-3.x","docker","google-cloud-platform","fastapi","google-cloud-run"],"text":"Title: Lots of \"Uncaught signal: 6\" errors in Cloud Run\nTags: python-3.x, docker, google-cloud-platform, fastapi, google-cloud-run\nSource: Stack Overflow\n\nQuestion:\nI have a Python (3.x) webservice deployed in GCP. Everytime Cloud Run is shutting down instances, most noticeably after a big load spike, I get many logs like these `Uncaught signal: 6, pid=6, tid=6, fault_addr=0.` together with `[CRITICAL] WORKER TIMEOUT (pid:6)` They are always signal 6.\n\nThe service is using FastAPI and Gunicorn running in a Docker with this start command\n\n```\nCMD gunicorn -w 2 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8080 app.__main__:app\n```\n\nThe service is deployed using Terraform with 1 gig of ram, 2 cpu's and the timeout is set to 2 minutes\n\n```\nresource \"google_cloud_run_service\" {\n name = \n location = \n\n template {\n spec {\n service_account_name = \n timeout_seconds = 120\n containers {\n image = var.image\n env {\n name = \"GCP_PROJECT\"\n value = var.project\n }\n env {\n name = \"BRANCH_NAME\"\n value = var.branch\n }\n resources {\n limits = {\n cpu = \"2000m\"\n memory = \"1Gi\"\n }\n }\n }\n }\n }\n autogenerate_revision_name = true\n}\n```\n\nI have already tried tweaking the resources and timeout in Cloud Run, using the --timeout and --preload flag for gunicorn as that is what people always seem to recommend when googling the problem but all without success. I also dont exactly know why the workers are timing out.\n\n========================================\n\nTop Answer:\nExtending on the top answer which is correct, You are using **GUnicorn** which is a process manager that manages **Uvicorn** processes which runs the actual app.\n\nWhen Cloudrun wants to shutdown the instance (due to lack of requests probably) it will send a **signal 6** to process 1. However, GUnicorn occupies this process as the manager and will not pass it to the Uvicorn workers for handling - thus you receive the **Unhandled signal 6**.\n\nThe simplest solution, is to run Uvicorn directly instead of through GUnicorn (possibly with a smaller instance) and allow the scaling part to be handled via Cloudrun.\n\n```\nCMD [\"uvicorn\", \"app.__main__:app\", \"--host\", \"0.0.0.0\", \"--port\", \"8080\"]\n```\n\n========================================\n\nCode:\n```text\nCMD gunicorn -w 2 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8080 app.__main__:app\n```\n\n```text\nresource \"google_cloud_run_service\" <ressource-name> {\n name = <name>\n location = <location>\n\n template {\n spec {\n service_account_name = <sa-email>\n timeout_seconds = 120\n containers {\n image = var.image\n env {\n name = \"GCP_PROJECT\"\n value = var.project\n }\n env {\n name = \"BRANCH_NAME\"\n value = var.branch\n }\n resources {\n limits = {\n cpu = \"2000m\"\n memory = \"1Gi\"\n }\n }\n }\n }\n }\n autogenerate_revision_name = true\n}\n```\n\n```text\nUncaught signal: 6, pid=6, tid=6, fault_addr=0.\n```\n\n```text\n[CRITICAL] WORKER TIMEOUT (pid:6)\n```\n\n```text\nCMD [\"uvicorn\", \"app.__main__:app\", \"--host\", \"0.0.0.0\", \"--port\", \"8080\"]\n```\n\n```text\nSIGTERM\n```\n\n```text\nSIGKILL\n```\n\n```text\n[CRITICAL] WORKER TIMEOUT (pid:6)\n```\n\n```text\n--timeout != 0\n```\n\n```text\nUncaught signal: 6, pid=...\n```\n\n```text\nUnhandled signal\n```\n\n```text\n-t | --timeout\n```\n\n```text\nworker_abort\n```\n\n```text\nabort()\n```\n\n========================================\n\nComments:\n- Is there some kind of best practice on how I would run a python webservice? In the google docs they also use guniorn although with slightly different arguments. see: cloud.google.com/run/docs/quickstarts/build-and-deploy/pytho‌​n for now I copied their arguments (had to add the -k for fastapi to work) to see if that'll work\n- @JeremySchiemann I refer to Ahmet's Google Cloud Run FAQ. github.com/ahmetb/cloud-run-faq Cloud Run is basically a simple HTTP Request/Response system. Most server setups beyond that are not necessary.\n- Thanks, that helped me alot. Using only one worker and setting the timeout to 0 fixed it for me already. But the FAQ will be bookmarked!\n- This is an interesting/useful answer.\n- I struggled with this error notifications for some time myself until diving into it, when I tested adding signal handlers to the fastapi / uvicorn app it simply did nothing - until i figured out that it was the GUnicorn hogging the process 1 and not forwarding this. Essentially we use GUnicorn for scaling purposes - handling multiple requests simultaneously by the GUnicorn raising Uvicorn processes. Since we are in a CloudRun environment and can set the in-flight requests to as many as we like we can let Uvicorn handle his request, and get the scaling from Cloudrun.\n- Thanks for the info! Although i already fixed my problem with the other answer, I'm sure this is useful information to float around the internet.\n- I am getting error like `/opt/startup/startup.sh: 26: CMD: not found`\n- @Sathiamoorthy Are you working through docker and verified that you install `uvicorn` before running the CMD line ?\n- Is there any disadvantage using gunicorn over uvicorn? Specially performance-wise since gunicorn is written in python\n- Hi Or, maybe I'm wrong, but your answer seems to be incorrect an mixing things up even more. Could you please provide the source where you got this from \"> [...] it will send a signal 6 to process 1 [...]\"?","metadata":{"transformedAt":"2026-08-18T18:32:29.112Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":14,"totalLines":162,"estimatedTokens":1345}}234{"id":"stack-72831952","source":"stackoverflow","questionId":72831952,"title":"How do I integrate custom exception handling with the FastAPI exception handling?","tags":["python","python-3.x","exception","fastapi"],"text":"Title: How do I integrate custom exception handling with the FastAPI exception handling?\nTags: python, python-3.x, exception, fastapi\nSource: Stack Overflow\n\nQuestion:\nPython version 3.9, FastAPI version 0.78.0\n\nI have a custom function that I use for application exception handling. When requests run into internal logic problems, i.e I want to send an HTTP response of 400 for some reason, I call a utility function.\n\n```\n@staticmethod\ndef raise_error(error: str, code: int) -> None:\n logger.error(error)\n raise HTTPException(status_code=code, detail=error)\n```\n\nNot a fan of this approach. So I look at\n\n```\nfrom fastapi import FastAPI, HTTPException, status\nfrom fastapi.respones import JSONResponse\n\nclass ExceptionCustom(HTTPException):\n pass\n\ndef exception_404_handler(request: Request, exc: HTTPException):\n return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, content={\"message\": \"404\"})\n\napp.add_exception_handler(ExceptionCustom, exception_404_handler)\n```\n\nThe problem I run into with the above approach is the inability to pass in the message as an argument.\n\nAny thoughts on the whole topic?\n\n========================================\n\nTop Answer:\n### Option 1\n\nYou could add custom exception handlers, and use attributes in your `Exception` class (i.e., `MyException(Exception)` in the example below), in order to pass a custom message or variables. The exception handler (in the example below, that is, `my_exception_handler()` with the `@app.exception_handler(MyException)` decorator) will handle the exception as you wish and return your custom message. For more options, please have a look at this related answer as well.\n\n### Working Example\n\nIn order to trigger the exception in the example below, call the `/items/{item_id}` endpoint using an `item_id` that is not present in the `items` dictionary.\n\n```\nfrom fastapi import FastAPI, Request, status\nfrom fastapi.responses import JSONResponse\n\napp = FastAPI()\nitems = {\"foo\": \"The Foo Wrestlers\"}\n\nclass MyException(Exception):\n def __init__(self, item_id: str):\n self.item_id = item_id\n\n@app.exception_handler(MyException)\nasync def my_exception_handler(request: Request, exc: MyException):\n return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, \n content={\"message\": f\"Item for '{exc.item_id}' cannot be found.\" })\n\n@app.get(\"/items/{item_id}\")\nasync def read_item(item_id: str):\n if item_id not in items:\n raise MyException(item_id=item_id)\n return {\"item\": items[item_id]}\n```\n\nIn case you wouldn't like using the `@app.exception_handler()` decorator, you could remove the decorator from the `my_exception_handler()` function and instead use the `add_exception_handler()` method to add the handler to the `app` instance. Example:\n\n```\napp.add_exception_handler(MyException, my_exception_handler)\n```\n\nAnother way to add the exception handler to the `app` instance would be to use the `exception_handlers` parameter of the FastAPI class, as demonstrated in this answer. Related answers can also be found here and here.\n\n### Option 2\n\nYou could always use `HTTPException` to return HTTP responses with custom errors to the client (as well as add custom headers to the HTTP error).\n\n### Working Example\n\n```\nfrom fastapi import FastAPI, HTTPException\n\napp = FastAPI()\nitems = {\"foo\": \"The Foo Wrestlers\"}\n\n@app.get(\"/items/{item_id}\")\nasync def read_item(item_id: str):\n if item_id not in items:\n raise HTTPException(status_code=404, detail=\"Item not found\")\n return {\"item\": items[item_id]}\n```\n\n========================================\n\nCode:\n```text\n@staticmethod\ndef raise_error(error: str, code: int) -> None:\n logger.error(error)\n raise HTTPException(status_code=code, detail=error)\n```\n\n```text\nfrom fastapi import FastAPI, HTTPException, status\nfrom fastapi.respones import JSONResponse\n\nclass ExceptionCustom(HTTPException):\n pass\n\n\ndef exception_404_handler(request: Request, exc: HTTPException):\n return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, content={\"message\": \"404\"})\n\n\napp.add_exception_handler(ExceptionCustom, exception_404_handler)\n```\n\n```py\nclass ExceptionCustom(HTTPException):\n pass\n```\n\n```py\ndef exception_404_handler(request: Request, exc: HTTPException):\n return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, content={\"message\": exc.detail})\n```\n\n```py\nraise ExceptionCustom(status_code=404, detail='error message')\n```\n\n```py\nclass MyHTTPException(HTTPException):\n pass\n```\n\n```py\ndef my_http_exception_handler(request: Request, exc: HTTPException):\n return JSONResponse(status_code=exc.status_code, content={\"message\": exc.detail})\n```\n\n```py\napp.add_exception_handler(MyHTTPException, my_http_exception_handler)\n```\n\n```text\nExceptionCustom\n```\n\n```text\nmessage\n```\n\n```py\nfrom fastapi import FastAPI, Request, status\nfrom fastapi.responses import JSONResponse\n\napp = FastAPI()\nitems = {\"foo\": \"The Foo Wrestlers\"}\n\n\nclass MyException(Exception):\n def __init__(self, item_id: str):\n self.item_id = item_id\n\n\n@app.exception_handler(MyException)\nasync def my_exception_handler(request: Request, exc: MyException):\n return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, \n content={\"message\": f\"Item for '{exc.item_id}' cannot be found.\" })\n\n\n@app.get(\"/items/{item_id}\")\nasync def read_item(item_id: str):\n if item_id not in items:\n raise MyException(item_id=item_id)\n return {\"item\": items[item_id]}\n```\n\n```py\napp.add_exception_handler(MyException, my_exception_handler)\n```\n\n```py\nfrom fastapi import FastAPI, HTTPException\n\napp = FastAPI()\nitems = {\"foo\": \"The Foo Wrestlers\"}\n\n\n@app.get(\"/items/{item_id}\")\nasync def read_item(item_id: str):\n if item_id not in items:\n raise HTTPException(status_code=404, detail=\"Item not found\")\n return {\"item\": items[item_id]}\n```\n\n```text\nException\n```\n\n```text\nMyException(Exception)\n```\n\n```text\nmy_exception_handler()\n```\n\n```text\n@app.exception_handler(MyException)\n```\n\n```text\n/items/{item_id}\n```\n\n```text\nitem_id\n```\n\n```text\nitems\n```\n\n```text\n@app.exception_handler()\n```\n\n```text\nmy_exception_handler()\n```\n\n```text\nadd_exception_handler()\n```\n\n```text\napp\n```\n\n```text\napp\n```\n\n```text\nexception_handlers\n```\n\n```text\nHTTPException\n```\n\n```py\nclass Error(Exception):\n def __init__(self, status_code: int, message: str):\n self.status_code = status_code\n self.message = message\n```\n\n```py\nclass InternalError(Error):\n def __init__(self, message: str):\n logging.error(f\"internal error: {message}\")\n super().__init__(500, message)\n\nclass UserNotFound(Error):\n def __init__(self, user_id: str):\n super().__init__(404, f\"User {user_id} not found\")\n```\n\n```py\n@app.exception_handler(Error)\nasync def custom_exception_handler(request: Request, exc: Error):\n return JSONResponse(\n status_code=exc.status_code,\n content={\"message\": exc.message},\n )\n```\n\n```py\n@app.get(\"/health\")\nasync def health():\n raise InternalError(\"Service is unhealthy\")\n```\n\n```json\n{\n \"message\": \"Service is unhealthy\"\n}\n```\n\n```py\n@app.get(\"/user/{user_id}\")\nasync def get_user(user_id: str):\n raise UserNotFound(user_id)\n```\n\n```text\nGET /user/bob\n```\n\n```json\n{\n \"message\": \"User bob not found\"\n}\n```\n\n```text\nError\n```\n\n```text\nError\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.112Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":37,"totalLines":319,"estimatedTokens":1811}}235{"id":"stack-73908734","source":"stackoverflow","questionId":73908734,"title":"How to run Uvicorn FastAPI server as a module from another Python file?","tags":["python","python-3.x","fastapi","uvicorn"],"text":"Title: How to run Uvicorn FastAPI server as a module from another Python file?\nTags: python, python-3.x, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI want to run FastAPI server using Uvicorn from A different Python file.\n\n**uvicornmodule/main.py**\n\n```\nimport uvicorn\nimport webbrowser\nfrom fastapi import FastAPI\nfrom fastapi.responses import FileResponse\nfrom fastapi.staticfiles import StaticFiles\n\napp = FastAPI()\n\nimport os\nscript_dir = os.path.dirname(__file__)\nst_abs_file_path = os.path.join(script_dir, \"static/\")\napp.mount(\"/static\", StaticFiles(directory=st_abs_file_path), name=\"static\")\n\n@app.get(\"/\")\nasync def index():\n return FileResponse('static/index.html', media_type='text/html')\n\ndef start_server():\n # print('Starting Server...') \n\n uvicorn.run(\n \"app\",\n host=\"0.0.0.0\",\n port=8765,\n log_level=\"debug\",\n reload=True,\n )\n # webbrowser.open(\"http://127.0.0.1:8765\")\n\nif __name__ == \"__main__\":\n start_server()\n```\n\nSo, I want to run the FastAPI server from the below `test.py` file:\n\n```\nfrom uvicornmodule import main\nmain.start_server()\n```\n\nThen, I run `python test.py`.\n\nBut I am getting the below error:\n\n```\nRuntimeError:\n An attempt has been made to start a new process before the\n current process has finished its bootstrapping phase.\n\n This probably means that you are not using fork to start your\n child processes and you have forgotten to use the proper idiom\n in the main module:\n\n if __name__ == '__main__':\n freeze_support()\n ...\n\n The \"freeze_support()\" line can be omitted if the program\n is not going to be frozen to produce an executable.\n```\n\nWhat I am doing wrong? I need to run this module as package.\n\n========================================\n\nTop Answer:\n### TLDR;\n\nUse **`uvicorn.run('parent_dir.child_dir.grand_son_dir.main:Application', reload=True)`**\n\nNotice directories separated by a `dot`\n\nin a nutshell this should be : `'..:'`\n\n### LR;\n\nExample: Consider this project tree\n\nhttps://i.sstatic.net/jeazN.png\n\n- `parent_dir/child_dir/grand_son_dir/main.py` is as \n\n```\nfrom fastapi import FastAPI\nApplication = FastAPI()\n```\n\n- `main.py` is as \n\n```\nimport uvicorn\nif __name__ == '__main__':\n uvicorn.run(\n \"parent_dir.child_dir.grand_son_dir.main:Application\", reload=True)\n```\n\nNow, from `parent_dir` you can try one of these:\n\n- `uvicorn 'parent_dir.child_dir.grand_son_dir.main:Application'`\n\nOR\n\n- `python main.py`\n\nBoth will work like charm\nhttps://i.sstatic.net/RGmW3.png\n\n========================================\n\nCode:\n```text\nimport uvicorn\nimport webbrowser\nfrom fastapi import FastAPI\nfrom fastapi.responses import FileResponse\nfrom fastapi.staticfiles import StaticFiles\n\napp = FastAPI()\n\nimport os\nscript_dir = os.path.dirname(__file__)\nst_abs_file_path = os.path.join(script_dir, \"static/\")\napp.mount(\"/static\", StaticFiles(directory=st_abs_file_path), name=\"static\")\n\n@app.get(\"/\")\nasync def index():\n return FileResponse('static/index.html', media_type='text/html')\n\ndef start_server():\n # print('Starting Server...') \n\n uvicorn.run(\n \"app\",\n host=\"0.0.0.0\",\n port=8765,\n log_level=\"debug\",\n reload=True,\n )\n # webbrowser.open(\"http://127.0.0.1:8765\")\n\nif __name__ == \"__main__\":\n start_server()\n```\n\n```text\nfrom uvicornmodule import main\nmain.start_server()\n```\n\n```text\nRuntimeError:\n An attempt has been made to start a new process before the\n current process has finished its bootstrapping phase.\n\n This probably means that you are not using fork to start your\n child processes and you have forgotten to use the proper idiom\n in the main module:\n\n if __name__ == '__main__':\n freeze_support()\n ...\n\n The \"freeze_support()\" line can be omitted if the program\n is not going to be frozen to produce an executable.\n```\n\n```text\ntest.py\n```\n\n```text\npython test.py\n```\n\n```py\nfrom uvicornmodule import main\n\nif __name__ == \"__main__\":\n main.start_server()\n```\n\n```py\n# main.py\nimport uvicorn\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\nif __name__ == \"__main__\":\n uvicorn.run(\"main:app\", host=\"0.0.0.0\", port=8000, reload=True)\n```\n\n```py\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n```\n\n```text\n> uvicorn main:app --reload\n```\n\n```text\n> uvicorn main:app --host 0.0.0.0 --port 8000\n```\n\n```text\nuvicorn.run()\n```\n\n```text\nif __name__ == '__main__':\n```\n\n```text\nuvicorn\n```\n\n```text\nreload\n```\n\n```text\nworkers\n```\n\n```text\n\"<module>:<attribute>\"\n```\n\n```text\nreload\n```\n\n```text\nworkers\n```\n\n```text\nuvicorn main:app\n```\n\n```text\nmain\n```\n\n```text\nmain.py\n```\n\n```text\napp\n```\n\n```text\nmain.py\n```\n\n```text\napp = FastAPI()\n```\n\n```text\n--reload\n```\n\n```text\nhost\n```\n\n```text\nport\n```\n\n```text\n127.0.0.1\n```\n\n```text\n8000\n```\n\n```text\n--host\n```\n\n```text\n--port\n```\n\n```py\nfrom fastapi import FastAPI\nApplication = FastAPI()\n```\n\n```py\nimport uvicorn\nif __name__ == '__main__':\n uvicorn.run(\n \"parent_dir.child_dir.grand_son_dir.main:Application\", reload=True)\n```\n\n```text\nuvicorn.run('parent_dir.child_dir.grand_son_dir.main:Application', reload=True)\n```\n\n```text\ndot\n```\n\n```text\n'<module>.<sub_mod>.<sub_mod>:<app_name>'\n```\n\n```text\nparent_dir/child_dir/grand_son_dir/main.py\n```\n\n```text\nmain.py\n```\n\n```text\nparent_dir\n```\n\n```text\nuvicorn 'parent_dir.child_dir.grand_son_dir.main:Application'\n```\n\n```text\npython main.py\n```\n\n========================================\n\nComments:\n- if I want to run start_server method without including it on main how can I do that? Or anything we can modify main.py so that we can start directly fastapi server\n- You don't really have to include `start_server()` inside `main.py`. You could instead move that method inside `test.py`, if you wish. The first argument in `uvicorn.run()`, i.e., `\":\"` is what specifies where the app you would like to run is located, as described in the answer above. You can always run your application through command line as well.","metadata":{"transformedAt":"2026-08-18T18:32:29.112Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":41,"totalLines":348,"estimatedTokens":1495}}236{"id":"stack-74360992","source":"stackoverflow","questionId":74360992,"title":"How to cache data in FastAPI?","tags":["python","caching","fastapi","cache-control"],"text":"Title: How to cache data in FastAPI?\nTags: python, caching, fastapi, cache-control\nSource: Stack Overflow\n\nQuestion:\nHow can I cache requests in FastAPI?\n\nFor example, there are two functions and a PostgreSQL database:\n\n```\n@app.get(\"/\")\ndef home(request: Request):\n return templates.TemplateResponse(\"index.html\", {\"request\": request})\n\n@app.post(\"/api/getData\")\nasync def getData(request: Request, databody = Body()):\n data = databody[\"data\"]\n \n with connection.cursor() as cursor:\n cursor.execute(\n f\"INSERT INTO database (ip, useragent, datetime) VALUES ('request.headers['host']', 'request.headers['user-agent']', '{datetime.now()}'\")\n )\n return {\"req\": request}\n```\n\nThen the request is processed by JavaScript and displayed on the HTML page\n.\n\n========================================\n\nCode:\n```py\n@app.get(\"/\")\ndef home(request: Request):\n return templates.TemplateResponse(\"index.html\", {\"request\": request})\n\n\n@app.post(\"/api/getData\")\nasync def getData(request: Request, databody = Body()):\n data = databody[\"data\"]\n \n with connection.cursor() as cursor:\n cursor.execute(\n f\"INSERT INTO database (ip, useragent, datetime) VALUES ('request.headers['host']', 'request.headers['user-agent']', '{datetime.now()}'\")\n )\n return {\"req\": request}\n```\n\n```py\nfrom fastapi import FastAPI\nfrom starlette.requests import Request\nfrom starlette.responses import Response\n \nfrom fastapi_cache import FastAPICache\nfrom fastapi_cache.backends.redis import RedisBackend\nfrom fastapi_cache.decorator import cache\n \nfrom redis import asyncio as aioredis\n \napp = FastAPI()\n \n \n@cache()\nasync def get_cache():\n return 1\n \n \n@app.get(\"/\")\n@cache(expire=60)\nasync def index():\n return dict(hello=\"world\")\n \n \n@app.on_event(\"startup\")\nasync def startup():\n redis = aioredis.from_url(\"redis://localhost\", encoding=\"utf8\", decode_responses=True)\n FastAPICache.init(RedisBackend(redis), prefix=\"fastapi-cache\")\n```\n\n========================================\n\nComments:\n- Generally http caching should live outside of the web application for scalability - i.e. do caching in nginx or varnish or something else. Let your application send `Cache-Control`-headers that the reverse proxy/cache server respects. That way those requests will never even hit your API in any way, meaning that FastAPI will never see them unless when necessary (usually when a POST request happens).\n- Future readers looking for how to log an HTTP request/response in FastAPI instead, please have a look at this answer\n- How do I initialise MemcachedBackend, to use memcache\n- This package has a MemcachedBackend too. You can check it out here at the source repo: github.com/long2ice/fastapi-cache.","metadata":{"transformedAt":"2026-08-18T18:32:29.112Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":2,"totalLines":86,"estimatedTokens":681}}237{"id":"stack-67094564","source":"stackoverflow","questionId":67094564,"title":"FastAPI: Deleting cookies after logout not working","tags":["python-3.x","cookies","oauth-2.0","fastapi"],"text":"Title: FastAPI: Deleting cookies after logout not working\nTags: python-3.x, cookies, oauth-2.0, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have tried to implement OAuth2 Cookie based Authentication using **FastAPI**.\nOn calling `/auth/token` endpoint, it perfectly sets a HttpOnly cookie as shown below:\n\n```\n@router.post(\"/auth/token\", response_model=Token)\nasync def get_token(response: Response, form_data: OAuth2PasswordRequestForm = Depends()):\n user = await authenticate_user(form_data.username, form_data.password)\n if not user:\n raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=\"Incorrect username or password\")\n access_token_expires = timedelta(minutes=Config.ACCESS_TOKEN_EXPIRE_MINUTES)\n access_token = create_access_token(\n data={\"sub\": user.email_id}, expires_delta=access_token_expires\n )\n response.set_cookie(key=\"access_token\", value=access_token, httponly=True)\n return {\"access_token\": access_token, \"token_type\": \"bearer\"}\n```\n\nSimilarly, It should delete that cookie immediately after calling `/logout` endpoint as below:\n\n```\n@router.get(\"/logout\")\nasync def logout(request: Request, response: Response, current_user: User = Depends(get_current_active_user)):\n # Also tried following two comment lines\n # response.set_cookie(key=\"access_token\", value=\"\", max_age=1)\n # response.delete_cookie(\"access_token\", domain=\"localhost\")\n response.delete_cookie(\"access_token\")\n return templates.TemplateResponse(\"login.html\", {\"request\": request, \"title\": \"Login\", \"current_user\": AnonymousUser()})\n```\n\n**Problem:** After calling `/logout` endpoint it should delete the cookie which it does but when I again click on `/login` it is able to retrieve the same cookie with same auth token i.e. browser send the same cookie along with the auth token in the request.\n\nHere is the debug state of response after deleting cookies. It has deleted cookie from response object which is good:\n\nhttps://i.sstatic.net/mPrkM.png\n\nHere is the debug state of request when I attempt to login **AFTER LOGOUT**. It is still able to retrieve that cookie from browser:\n\nhttps://i.sstatic.net/lmVJp.png\n\nAny help regarding how to delete the cookies properly so that it could not be found again after logging out ?\n\n========================================\n\nTop Answer:\nThis three line code will also work.\n\n```\n@router.post(\"/logout\")\nasync def logout(response: Response,):\n response.delete_cookie(\"bearer\")\n return {\"status\":\"success\"}\n```\n\n========================================\n\nCode:\n```text\n@router.post(\"/auth/token\", response_model=Token)\nasync def get_token(response: Response, form_data: OAuth2PasswordRequestForm = Depends()):\n user = await authenticate_user(form_data.username, form_data.password)\n if not user:\n raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=\"Incorrect username or password\")\n access_token_expires = timedelta(minutes=Config.ACCESS_TOKEN_EXPIRE_MINUTES)\n access_token = create_access_token(\n data={\"sub\": user.email_id}, expires_delta=access_token_expires\n )\n response.set_cookie(key=\"access_token\", value=access_token, httponly=True)\n return {\"access_token\": access_token, \"token_type\": \"bearer\"}\n```\n\n```text\n@router.get(\"/logout\")\nasync def logout(request: Request, response: Response, current_user: User = Depends(get_current_active_user)):\n # Also tried following two comment lines\n # response.set_cookie(key=\"access_token\", value=\"\", max_age=1)\n # response.delete_cookie(\"access_token\", domain=\"localhost\")\n response.delete_cookie(\"access_token\")\n return templates.TemplateResponse(\"login.html\", {\"request\": request, \"title\": \"Login\", \"current_user\": AnonymousUser()})\n```\n\n```text\n/auth/token\n```\n\n```text\n/logout\n```\n\n```text\n/logout\n```\n\n```text\n/login\n```\n\n```text\n@router.get(\"/logout\")\nasync def logout(request: Request, response: Response, current_user: User = Depends(get_current_active_user)):\n # Also tried following two comment lines\n # response.set_cookie(key=\"access_token\", value=\"\", max_age=1)\n # response.delete_cookie(\"access_token\", domain=\"localhost\")\n response = templates.TemplateResponse(\"login.html\", {\"request\": request, \"title\": \"Login\", \"current_user\": AnonymousUser()})\n response.delete_cookie(\"access_token\")\n return response\n```\n\n```text\n/logout\n```\n\n```text\nresponse.delete_cookies(key=\"access_token\")\n```\n\n```text\nlogout()\n```\n\n```text\n@router.post(\"/logout\")\nasync def logout(response: Response,):\n response.delete_cookie(\"bearer\")\n return {\"status\":\"success\"}\n```\n\n========================================\n\nComments:\n- Hi @AKA, As a best practice suggested in this answer (stackoverflow.com/a/20320610/9058468) you can set the cookie with an expire value\n- @Santiago Yes, but on logout it has to be deleted immediately right. After logout, ideally it must ask credentials to login again but here it just doesnt ask that because it is able to retrieve it from request object.\n- I think the problem lies when it redirects after logging out. This will also happen for any custom header when you redirect. Try to return an empty string instead and see if it works. Also, take a look at this answer\n- @Santiago Finally resolved it by doing a little change in the response. Thanks for pointing me into that direction.\n- glad to help. You should accept your answer","metadata":{"transformedAt":"2026-08-18T18:32:29.114Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":11,"totalLines":139,"estimatedTokens":1334}}238{"id":"stack-68650162","source":"stackoverflow","questionId":68650162,"title":"FastApi - receive list of objects in body request","tags":["python","json","fastapi","pydantic"],"text":"Title: FastApi - receive list of objects in body request\nTags: python, json, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI need to create an endpoint that can receive the following JSON and recognize the objects contained in it:\n\n```\n{\n \"data\": [\n {\n \"start\": \"A\", \"end\": \"B\", \"distance\": 6\n },\n {\n \"start\": \"A\", \"end\": \"E\", \"distance\": 4\n }\n ]\n}\n```\n\nI created a model to handle a single object:\n\n```\nclass GraphBase(BaseModel):\n start: str\n end: str\n distance: int\n```\n\nAnd with it, I could save it in a database. But now I need to receive a list of objects and save them all.\nI tried to do something like this:\n\n```\nclass GraphList(BaseModel):\n data: Dict[str, List[GraphBase]]\n\n@app.post(\"/dummypath\")\nasync def get_body(data: schemas.GraphList):\n return data\n```\n\nBut I keep getting this error on FastApi: `Error getting request body: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)` and this message on the response:\n\n```\n{\n \"detail\": \"There was an error parsing the body\"\n}\n```\n\nI'm new to python and even newer to FastApi, how can I transform that JSON to a list of `GraphBase`to save them in my db?\n\n========================================\n\nTop Answer:\nGenerally, FastAPI allows for simply receiving a list of objects, there's no need to wrap that list in an extra object.\n\n```\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\n\napp = FastAPI()\n\nclass ObjectListItem(BaseModel):\n ...\n\n@app.post(\"/api_route\")\ndef receive_list_of_objects(objects_list: list[ObjectListItem]):\n ...\n```\n\nMore information in the FastAPI documentation.\n\n========================================\n\nCode:\n```text\n{\n \"data\": [\n {\n \"start\": \"A\", \"end\": \"B\", \"distance\": 6\n },\n {\n \"start\": \"A\", \"end\": \"E\", \"distance\": 4\n }\n ]\n}\n```\n\n```text\nclass GraphBase(BaseModel):\n start: str\n end: str\n distance: int\n```\n\n```text\nclass GraphList(BaseModel):\n data: Dict[str, List[GraphBase]]\n\n@app.post(\"/dummypath\")\nasync def get_body(data: schemas.GraphList):\n return data\n```\n\n```text\n{\n \"detail\": \"There was an error parsing the body\"\n}\n```\n\n```text\nError getting request body: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)\n```\n\n```text\nGraphBase\n```\n\n```py\nfrom typing import List\nfrom pydantic import BaseModel\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\nclass GraphBase(BaseModel):\n start: str\n end: str\n distance: int\n\nclass GraphList(BaseModel):\n data: List[GraphBase]\n\n@app.post(\"/dummypath\")\nasync def get_body(data: GraphList):\n return data\n```\n\n```sh\ncurl -X 'POST' \\\n 'http://localhost:8000/dummypath' \\\n -H 'accept: application/json' \\\n -H 'Content-Type: application/json' \\\n -d '{\n \"data\": [\n {\n \"start\": \"string\",\n \"end\": \"string\",\n \"distance\": 0\n }\n ]\n}'\n```\n\n```json\n{\n \"data\": [\n {\n \"start\": \"A\", \"end\": \"B\", \"distance\": 6\n },\n {\n \"start\": \"A\", \"end\": \"E\", \"distance\": 4\n }\n ]\n}\n```\n\n```py\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\n\napp = FastAPI()\n\nclass ObjectListItem(BaseModel):\n ...\n\n@app.post(\"/api_route\")\ndef receive_list_of_objects(objects_list: list[ObjectListItem]):\n ...\n```\n\n========================================\n\nComments:\n- What about `data: List[GraphBase]` in the definition of `GraphList`? `data` field is a list of graphbase objects.\n- @KotaMori I tried your suggestion and it returns the same error.\n- Did you try the API on the docs page?\n- @KotaMori I tried everything I could find on the API docs page but with no success.\n- Thank you so much!! I spent a lot of time looking for a problem in the code that was in the data!! It worked with your formatted data. What did you use to locate those extra whitespaces? And do you know if FastApi has a way to handle this kind of problem?\n- I used jsoneditoronline.org. The original data was invalid there. FastAPI won't help you because the data was not a valid JSON object. The best it could do is to tell you that the parsing data failed, which actually was in the error message.\n- Yeah, I realized that something could be wrong with the data, but couldn't figure out what it was. All editors I used were unable to show those extra spaces and the error message was unclear of what was the issue. Again, thank you for the explanation and the link to the json validator you used!!!\n- whilst that will work with json content type , it wont work with formdata content type\n- thanks! how do we specify minimum and maximum (or fixed) length of the list expected, for validation?\n- Assuming I need to post something really simple, like a list of integers, would the `objects_list` passed via the post request simply be a JSON list : [1,2,3] ?\n- There's an example of handling lists of primitive values (e.g. int, str) here: fastapi.tiangolo.com/tutorial/query-params-str-validations/… To pass it in the request body, you need to declare a Pydantic model for it: fastapi.tiangolo.com/tutorial/body","metadata":{"transformedAt":"2026-08-18T18:32:29.115Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":10,"totalLines":195,"estimatedTokens":1244}}239{"id":"stack-70690454","source":"stackoverflow","questionId":70690454,"title":"How to redirect the user back to the home page using FastAPI, after submitting an HTML form?","tags":["python","http","http-redirect","jinja2","fastapi"],"text":"Title: How to redirect the user back to the home page using FastAPI, after submitting an HTML form?\nTags: python, http, http-redirect, jinja2, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have a page with a table of students. I added a button that allows you to add a new row to the table. To do this, I redirect the user to a page with input forms.\n\nThe problem is that after submitting the completed forms, the user goes to a new empty page. How to transfer data in completed forms and redirect the user back to the table?\n\nI just started learning web programming, so I decided to first make an implementation without using AJAX technologies.\n\nCode:\n\n```\nfrom fastapi import FastAPI, Form\nfrom fastapi.responses import Response\n\nimport json\nfrom jinja2 import Template\n\napp = FastAPI()\n\n# The page with the table\n@app.get('/') \ndef index():\n students = get_students() # Get a list of students\n with open('templates/students.html', 'r', encoding='utf-8') as file:\n html = file.read()\n template = Template(html) # Creating a template with a table\n\n # Loading a template\n return Response(template.render(students=students), media_type='text/html')\n\n# Page with forms for adding a new entry\n@app.get('/add_student')\ndef add_student_page():\n with open('templates/add_student.html', 'r', encoding='utf-8') as file:\n html = file.read()\n\n # Loading a page\n return Response(html, media_type='text/html')\n\n# Processing forms and adding a new entry\n@app.post('/add')\ndef add(name: str = Form(...), surname: str = Form(...), _class: str = Form(...)):\n add_student(name, surname, _class) # Adding student data\n # ???\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI, Form\nfrom fastapi.responses import Response\n\nimport json\nfrom jinja2 import Template\n\napp = FastAPI()\n\n\n# The page with the table\n@app.get('/') \ndef index():\n students = get_students() # Get a list of students\n with open('templates/students.html', 'r', encoding='utf-8') as file:\n html = file.read()\n template = Template(html) # Creating a template with a table\n\n # Loading a template\n return Response(template.render(students=students), media_type='text/html')\n\n\n# Page with forms for adding a new entry\n@app.get('/add_student')\ndef add_student_page():\n with open('templates/add_student.html', 'r', encoding='utf-8') as file:\n html = file.read()\n\n # Loading a page\n return Response(html, media_type='text/html')\n\n\n# Processing forms and adding a new entry\n@app.post('/add')\ndef add(name: str = Form(...), surname: str = Form(...), _class: str = Form(...)):\n add_student(name, surname, _class) # Adding student data\n # ???\n```\n\n```py\nfrom fastapi import FastAPI, Request, Form, status\nfrom fastapi.templating import Jinja2Templates\nfrom fastapi.responses import RedirectResponse\n\napp = FastAPI()\ntemplates = Jinja2Templates(directory=\"templates\")\n\n\n# replace with your own get_students() method\ndef get_students():\n return [\"a\", \"b\", \"c\"]\n\n\n@app.post('/add')\nasync def add(request: Request, name: str = Form(...), surname: str = Form(...), _class: str = Form(...)):\n # add_student(name, surname, _class) # Adding student data\n redirect_url = request.url_for('index') \n return RedirectResponse(redirect_url, status_code=status.HTTP_303_SEE_OTHER) \n\n\n@app.get('/add_student')\nasync def add_student_page(request: Request):\n return templates.TemplateResponse(\"add_student.html\", {\"request\": request})\n\n\n@app.get('/')\nasync def index(request: Request):\n students = get_students() # Get a list of students\n return templates.TemplateResponse(\"index.html\", {\"request\": request, \"students\": students})\n```\n\n```html\n<!DOCTYPE html>\n<html>\n <body>\n <h1>Students: {{ students }}</h1>\n </body>\n</html>\n```\n\n```html\n<!DOCTYPE html>\n<html>\n <body>\n <form action=\"http://127.0.0.1:8000/add\" method=\"POST\">\n name : <input type=\"text\" name=\"name\"><br>\n surname : <input type=\"text\" name=\"surname\"><br>\n class : <input type=\"text\" name=\"_class\"><br>\n <input type=\"submit\" value=\"submit\">\n </form>\n </body>\n</html>\n```\n\n```text\nTemplateResponse\n```\n\n```text\nPOST\n```\n\n```text\nGET\n```\n\n```text\n405 (Method Not Allowed)\n```\n\n```text\nstatus_code=status.HTTP_303_SEE_OTHER\n```\n\n```text\n<form>\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.115Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":10,"totalLines":169,"estimatedTokens":1075}}240{"id":"stack-76297879","source":"stackoverflow","questionId":76297879,"title":"Benchmarks of FastAPI vs async Flask?","tags":["python","flask","fastapi"],"text":"Title: Benchmarks of FastAPI vs async Flask?\nTags: python, flask, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm a developer without an interest in benchmarking and I'm trying to decide whether I should use Flask or FastAPI to build some Python/Vue projects. I'm seeing stuff online about how FastAPI was faster than Flask because Flask was single-threaded or something like that, whereas FastAPI was async, but apparently more-recently Flask added async routes, and so now I'm wondering if FastAPI is still(?) faster than Flask.\n\nHas anyone done benchmarking tests comparing FastAPI to Flask async routes? I can't find any when I search Google.\n\n========================================\n\nComments:\n- I totally rewrote your answer, I hope you don't mind. If you want to keep your original answer I'll repost my answer separately, but I wanted you to get credit for finding that Grinberg link.\n- @NathanWailes Thanks. Your modification is nice. I would still add the link to Flask documentation about its async approaches, which Grinberg did not elaborate in his blog, but is a very important point of consideration for making decision between Flask and FastAPI/Quart.","metadata":{"transformedAt":"2026-08-18T18:32:29.115Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":0,"totalLines":14,"estimatedTokens":292}}241{"id":"stack-75726959","source":"stackoverflow","questionId":75726959,"title":"How to reroute requests to a different URL/endpoint in FastAPI?","tags":["python","fastapi","middleware","starlette","reroute"],"text":"Title: How to reroute requests to a different URL/endpoint in FastAPI?\nTags: python, fastapi, middleware, starlette, reroute\nSource: Stack Overflow\n\nQuestion:\nI am trying to write a middleware in my FastAPI application, so that requests coming to endpoints matching a particular format will be rerouted to a different URL, but I am unable to find a way to do that since `request.url` is read-only.\n\nI am also looking for a way to update request headers before rerouting.\n\nAre these things even possible in FastAPI?\n\nRedirection is the best I could do so far:\n\n```\nfrom fastapi import Request\nfrom fastapi.responses import RedirectResponse\n\n@app.middleware(\"http\")\nasync def redirect_middleware(request: Request, call_next):\n if matches_certain_format(request.url.path):\n new_url = create_target_url(request.url.path)\n return RedirectResponse(url=new_url)\n```\n\n========================================\n\nCode:\n```py\nfrom fastapi import Request\nfrom fastapi.responses import RedirectResponse\n\n@app.middleware(\"http\")\nasync def redirect_middleware(request: Request, call_next):\n if matches_certain_format(request.url.path):\n new_url = create_target_url(request.url.path)\n return RedirectResponse(url=new_url)\n```\n\n```text\nrequest.url\n```\n\n```py\nfrom fastapi import FastAPI, Request\n\napp = FastAPI()\nroutes_to_reroute = ['/']\n\n@app.middleware('http')\nasync def some_middleware(request: Request, call_next):\n if request.url.path in routes_to_reroute:\n request.scope['path'] = '/welcome'\n headers = dict(request.scope['headers'])\n headers[b'custom-header'] = b'my custom header'\n request.scope['headers'] = [(k, v) for k, v in headers.items()]\n \n return await call_next(request)\n\n@app.get('/')\nasync def main():\n return 'OK'\n\n@app.get('/welcome')\nasync def welcome(request: Request):\n return {'msg': 'Welcome!', 'headers': request.headers}\n```\n\n```text\nrequest\n```\n\n```text\nrequest.scope['path']\n```\n\n```text\n'/users/{user_id}'\n```\n\n```text\nrequest\n```\n\n```text\nroutes_to_reroute\n```\n\n```text\nrequest.scope['headers']\n```\n\n========================================\n\nComments:\n- Could you just request the other URL from `localhost` as if someone in the browser did it, and return whatever it returns?\n- @Libra, that'd work and I think I will go with that approach for now. I was expecting FastAPI to provide a better way though.\n- Does this answer your question? How to create a FastAPI endpoint that can accept either Form or JSON body?\n- This looks good and I think it would work, but not for my requirement (which is not mentioned in the original question). Could it be because I am trying to re-route the request to a different server? I tried changing the server with this statement `request.scope['server'] = (host, int(port))`, but it is not leaving the server. Do you know what might be wrong here?\n- For *redirecting/forwarding* requests to a different server, you could either keep using `RedirectResponse` (but it wouldn't allow you passing headers to the other server - see this answer, as well as this answer and this answer for more details; unless the request is issued using JS in the frontend, which would allow you to work around this problem - see here)...\n- .... or *forward* the requests to the other server, similar to the approach demonstrated in this answer.\n- Thanks a lot for these links, it gave me exactly the information I needed. And I agree with your suggestion about the question, I am going to leave it as is.","metadata":{"transformedAt":"2026-08-18T18:32:29.115Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":101,"estimatedTokens":875}}242{"id":"stack-57036856","source":"stackoverflow","questionId":57036856,"title":"Uvicorn server shutting down unexpectedly","tags":["ios","python-3.x","starlette","fastapi","uvicorn"],"text":"Title: Uvicorn server shutting down unexpectedly\nTags: ios, python-3.x, starlette, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI'm working with FastAPI framework, served by Uvicorn server.\nMy application should run some time consuming numerical computation at a given endpoint (/run). For this I am using 'background_task' from fastAPI (which is basically 'background_task' from Starlette).\n\nWhen running the application, after some times of nominal behaviour, the server is shut down for some reason.\n\nThe logs from the application look like this:\n\n```\nINFO: Started server process [922]\nINFO: Waiting for application startup.\nDEBUG: None - ASGI [1] Started\nDEBUG: None - ASGI [1] Sent {'type': 'lifespan.startup'}\nDEBUG: None - ASGI [1] Received {'type': 'lifespan.startup.complete'}\nINFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)\nDEBUG: ('10.0.2.111', 57396) - Connected\nDEBUG: ('10.0.2.111', 57397) - Connected\nDEBUG: ('10.0.2.111', 57396) - ASGI [2] Started\nDEBUG: ('10.0.2.111', 57396) - ASGI [2] Received {'type': 'http.response.start', 'status': 200, 'headers': ''}\nINFO: ('10.0.2.111', 57396) - \"GET /run HTTP/1.1\" 200\nDEBUG: ('10.0.2.111', 57396) - ASGI [2] Received {'type': 'http.response.body', 'body': ''}\nDEBUG: ('10.0.2.111', 57396) - ASGI [3] Started\nDEBUG: ('10.0.2.111', 57396) - ASGI [3] Received {'type': 'http.response.start', 'status': 404, 'headers': ''}\nINFO: ('10.0.2.111', 57396) - \"GET /favicon.ico HTTP/1.1\" 404\nDEBUG: ('10.0.2.111', 57396) - ASGI [3] Received {'type': 'http.response.body', 'body': ''}\nDEBUG: ('10.0.2.111', 57396) - ASGI [3] Completed\n\n...\n\nDEBUG: ('10.0.2.111', 57396) - Disconnected\n... The background task is completed.\nDEBUG: ('10.0.2.111', 57396) - ASGI [2] Completed\nDEBUG: ('10.0.2.111', 57397) - Disconnected\nDEBUG: ('10.0.2.111', 57405) - Connected\n\n...\nThe application goes on, with requests and completed background tasks.\nAt some point, during the execution of a background task:\n\nINFO: Shutting down\nDEBUG: ('10.0.2.111', 57568) - Disconnected\nDEBUG: ('10.0.2.111', 57567) - Disconnected\nINFO: Waiting for background tasks to complete. (CTRL+C to force quit)\nDEBUG: ('10.0.2.111', 57567) - ASGI [6] Completed\nINFO: Waiting for application shutdown.\nDEBUG: None - ASGI [1] Sent {'type': 'lifespan.shutdown'}\nDEBUG: None - ASGI [1] Received {'type': 'lifespan.shutdown.complete'}\nDEBUG: None - ASGI [1] Completed\nINFO: Finished server process [922]\n```\n\nI really don't get why this happens. I have no idea what to try in order to fix it. \n\nMy code looks like this.\n\n```\n#!/usr/bin/env python3.7\nimport time\nfrom fastapi import FastAPI, BackgroundTasks\nimport uvicorn\nfrom starlette.responses import JSONResponse\nimport my_imports_from_project\n\nanalysis_api = FastAPI()\n\n@analysis_api.get(\"/\")\ndef root():\n return {\"message\": \"root\"}\n\n@analysis_api.get(\"/test\")\ndef test():\n return {\"message\": \"test\"}\n\n@analysis_api.get(\"/run\")\ndef run(name: str, background_task: BackgroundTasks):\n try:\n some_checks(name)\n except RaisedExceptions:\n body = {\"running\": False,\n \"name\": name,\n \"cause\": \"Not found in database\"}\n return JSONResponse(status_code=400, content=body)\n body = {\"running\": True,\n \"name\": name}\n background_task.add_task(run_analysis, name)\n return JSONResponse(status_code=200, content=body)\n\nif __name__ == \"__main__\":\n uvicorn.run(\"api:analysis_api\", host=\"0.0.0.0\", log_level=\"debug\")\n```\n\n========================================\n\nCode:\n```text\nINFO: Started server process [922]\nINFO: Waiting for application startup.\nDEBUG: None - ASGI [1] Started\nDEBUG: None - ASGI [1] Sent {'type': 'lifespan.startup'}\nDEBUG: None - ASGI [1] Received {'type': 'lifespan.startup.complete'}\nINFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)\nDEBUG: ('10.0.2.111', 57396) - Connected\nDEBUG: ('10.0.2.111', 57397) - Connected\nDEBUG: ('10.0.2.111', 57396) - ASGI [2] Started\nDEBUG: ('10.0.2.111', 57396) - ASGI [2] Received {'type': 'http.response.start', 'status': 200, 'headers': '<...>'}\nINFO: ('10.0.2.111', 57396) - \"GET /run HTTP/1.1\" 200\nDEBUG: ('10.0.2.111', 57396) - ASGI [2] Received {'type': 'http.response.body', 'body': '<32 bytes>'}\nDEBUG: ('10.0.2.111', 57396) - ASGI [3] Started\nDEBUG: ('10.0.2.111', 57396) - ASGI [3] Received {'type': 'http.response.start', 'status': 404, 'headers': '<...>'}\nINFO: ('10.0.2.111', 57396) - \"GET /favicon.ico HTTP/1.1\" 404\nDEBUG: ('10.0.2.111', 57396) - ASGI [3] Received {'type': 'http.response.body', 'body': '<22 bytes>'}\nDEBUG: ('10.0.2.111', 57396) - ASGI [3] Completed\n\n...\n\nDEBUG: ('10.0.2.111', 57396) - Disconnected\n... The background task is completed.\nDEBUG: ('10.0.2.111', 57396) - ASGI [2] Completed\nDEBUG: ('10.0.2.111', 57397) - Disconnected\nDEBUG: ('10.0.2.111', 57405) - Connected\n\n...\nThe application goes on, with requests and completed background tasks.\nAt some point, during the execution of a background task:\n\nINFO: Shutting down\nDEBUG: ('10.0.2.111', 57568) - Disconnected\nDEBUG: ('10.0.2.111', 57567) - Disconnected\nINFO: Waiting for background tasks to complete. (CTRL+C to force quit)\nDEBUG: ('10.0.2.111', 57567) - ASGI [6] Completed\nINFO: Waiting for application shutdown.\nDEBUG: None - ASGI [1] Sent {'type': 'lifespan.shutdown'}\nDEBUG: None - ASGI [1] Received {'type': 'lifespan.shutdown.complete'}\nDEBUG: None - ASGI [1] Completed\nINFO: Finished server process [922]\n```\n\n```py\n#!/usr/bin/env python3.7\nimport time\nfrom fastapi import FastAPI, BackgroundTasks\nimport uvicorn\nfrom starlette.responses import JSONResponse\nimport my_imports_from_project\n\nanalysis_api = FastAPI()\n\n@analysis_api.get(\"/\")\ndef root():\n return {\"message\": \"root\"}\n\n\n@analysis_api.get(\"/test\")\ndef test():\n return {\"message\": \"test\"}\n\n@analysis_api.get(\"/run\")\ndef run(name: str, background_task: BackgroundTasks):\n try:\n some_checks(name)\n except RaisedExceptions:\n body = {\"running\": False,\n \"name\": name,\n \"cause\": \"Not found in database\"}\n return JSONResponse(status_code=400, content=body)\n body = {\"running\": True,\n \"name\": name}\n background_task.add_task(run_analysis, name)\n return JSONResponse(status_code=200, content=body)\n\n\nif __name__ == \"__main__\":\n uvicorn.run(\"api:analysis_api\", host=\"0.0.0.0\", log_level=\"debug\")\n```\n\n```text\nbackground_task\n```\n\n```text\nmultiprocessing.Process()\n```\n\n```text\nmultiprocessing.Process\n```\n\n```text\nsubprocess.Popen\n```\n\n========================================\n\nComments:\n- Have you tried running uvicorn through gunicorn? gunicorn might keep the process up\n- I'm wondering if the completion of the background tasks triggers a shutdown request somehow\n- About gunicorn: * It happens the same exact thing but at least gunicord re-starts the server. About the task triggering the shutdown: * I do not know, it just makes computation and saves the results in a database. Moreover, some tasks are successful and just one shuts the server (all tasks are equal)\n- Using an external queue will both let you control the number of consumers/subscribers/threads in your app instance processing work in parallel and let you deploy multiple instances of your application that can both add to queue and work on queue. In addition it will enable automatic restarting/resuming queued work items if an instance handling them crashes.","metadata":{"transformedAt":"2026-08-18T18:32:29.115Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":6,"totalLines":202,"estimatedTokens":1829}}243{"id":"stack-65531387","source":"stackoverflow","questionId":65531387,"title":"Tortoise ORM for Python no returns relations of entities (Pyndantic, FastAPI)","tags":["python","postgresql","fastapi","pydantic","tortoise-orm"],"text":"Title: Tortoise ORM for Python no returns relations of entities (Pyndantic, FastAPI)\nTags: python, postgresql, fastapi, pydantic, tortoise-orm\nSource: Stack Overflow\n\nQuestion:\nI was making a sample Fast Api server with Tortoise ORM as an asynchronous orm library, but I just cannot seem to return the relations I have defined. These are my relations:\n\n```\n# Category\nfrom tortoise.fields.data import DatetimeField\nfrom tortoise.models import Model\nfrom tortoise.fields import UUIDField, CharField\nfrom tortoise.fields.relational import ManyToManyField\nfrom tortoise.contrib.pydantic import pydantic_model_creator\n\nclass Category(Model):\n id = UUIDField(pk=True)\n name = CharField(max_length=255)\n description = CharField(max_length=255)\n keywords = ManyToManyField(\n \"models.Keyword\", related_name=\"categories\", through=\"category_keywords\"\n )\n created_on = DatetimeField(auto_now_add=True)\n updated_on = DatetimeField(auto_now=True)\n\nCategory_dto = pydantic_model_creator(Category, name=\"Category\", allow_cycles = True)\n```\n\n```\n# Keyword\nfrom models.expense import Expense\nfrom models.category import Category\nfrom tortoise.fields.data import DatetimeField\nfrom tortoise.fields.relational import ManyToManyRelation\nfrom tortoise.models import Model\nfrom tortoise.fields import UUIDField, CharField\nfrom tortoise.contrib.pydantic import pydantic_model_creator\n\nclass Keyword(Model):\n id = UUIDField(pk=True)\n name = CharField(max_length=255)\n description = CharField(max_length=255)\n categories: ManyToManyRelation[Category]\n expenses: ManyToManyRelation[Expense]\n created_on = DatetimeField(auto_now_add=True)\n updated_on = DatetimeField(auto_now=True)\n\n class Meta:\n table=\"keyword\"\n\nKeyword_dto = pydantic_model_creator(Keyword)\n```\n\nThe tables have been created correctly. When adding keywords to categories the db state is all good. The problem is when i want to query the categories and include the keywords. I have this code for that:\n\n```\nclass CategoryRepository():\n\n @staticmethod\n async def get_one(id: str) -> Category:\n category_orm = await Category.get_or_none(id=id).prefetch_related('keywords')\n if (category_orm is None):\n raise NotFoundHTTP('Category')\n return category_orm\n```\n\nDebugging the category_orm here I have the following:\n\ncategory_orm debug at run-time\n\nWhich kind of tells me that they are loaded.\nThen when i cant a Pydantic model I have this code\n\n```\nclass CategoryUseCases():\n\n @staticmethod\n async def get_one(id: str) -> Category_dto:\n category_orm = await CategoryRepository.get_one(id)\n category = await Category_dto.from_tortoise_orm(category_orm)\n return category\n```\n\nand debugging this, there is no `keywords` field\n\ncategory (pydantic) debug at run-time\n\nLooking at the source code of tortoise orm for the function `from_tortoise_orm`\n\n```\n@classmethod\n async def from_tortoise_orm(cls, obj: \"Model\") -> \"PydanticModel\":\n \"\"\"\n Returns a serializable pydantic model instance built from the provided model instance.\n\n .. note::\n\n This will prefetch all the relations automatically. It is probably what you want.\n```\n\nBut my relation is just not returned. Anyone have a similar experience ?\n\n========================================\n\nCode:\n```text\n# Category\nfrom tortoise.fields.data import DatetimeField\nfrom tortoise.models import Model\nfrom tortoise.fields import UUIDField, CharField\nfrom tortoise.fields.relational import ManyToManyField\nfrom tortoise.contrib.pydantic import pydantic_model_creator\n\n\nclass Category(Model):\n id = UUIDField(pk=True)\n name = CharField(max_length=255)\n description = CharField(max_length=255)\n keywords = ManyToManyField(\n \"models.Keyword\", related_name=\"categories\", through=\"category_keywords\"\n )\n created_on = DatetimeField(auto_now_add=True)\n updated_on = DatetimeField(auto_now=True)\n\n\n\nCategory_dto = pydantic_model_creator(Category, name=\"Category\", allow_cycles = True)\n```\n\n```text\n# Keyword\nfrom models.expense import Expense\nfrom models.category import Category\nfrom tortoise.fields.data import DatetimeField\nfrom tortoise.fields.relational import ManyToManyRelation\nfrom tortoise.models import Model\nfrom tortoise.fields import UUIDField, CharField\nfrom tortoise.contrib.pydantic import pydantic_model_creator\n\n\nclass Keyword(Model):\n id = UUIDField(pk=True)\n name = CharField(max_length=255)\n description = CharField(max_length=255)\n categories: ManyToManyRelation[Category]\n expenses: ManyToManyRelation[Expense]\n created_on = DatetimeField(auto_now_add=True)\n updated_on = DatetimeField(auto_now=True)\n\n class Meta:\n table=\"keyword\"\n\n\nKeyword_dto = pydantic_model_creator(Keyword)\n```\n\n```text\nclass CategoryRepository():\n\n @staticmethod\n async def get_one(id: str) -> Category:\n category_orm = await Category.get_or_none(id=id).prefetch_related('keywords')\n if (category_orm is None):\n raise NotFoundHTTP('Category')\n return category_orm\n```\n\n```text\nclass CategoryUseCases():\n\n @staticmethod\n async def get_one(id: str) -> Category_dto:\n category_orm = await CategoryRepository.get_one(id)\n category = await Category_dto.from_tortoise_orm(category_orm)\n return category\n```\n\n```text\n@classmethod\n async def from_tortoise_orm(cls, obj: \"Model\") -> \"PydanticModel\":\n \"\"\"\n Returns a serializable pydantic model instance built from the provided model instance.\n\n .. note::\n\n This will prefetch all the relations automatically. It is probably what you want.\n```\n\n```text\nkeywords\n```\n\n```text\nfrom_tortoise_orm\n```\n\n```text\nawait Tortoise.init(db_url=\"sqlite://:memory:\", modules={\"models\": [\"__main__\"]})\nawait Tortoise.generate_schemas()\n\nEvent_Pydantic = pydantic_model_creator(Event)\n```\n\n```text\nfrom tortoise import Tortoise\n\nTortoise.init_models([\"__main__\"], \"models\")\nTournament_Pydantic = pydantic_model_creator(Tournament)\n```\n\n```text\npydantic_model_creator\n```\n\n```text\nTortoise.init\n```\n\n```text\nTortoise.init_models()\n```\n\n```text\nTortoise.init_models()\n```\n\n========================================\n\nComments:\n- I see, I sort of followed the approach from the docs for Fast API. tortoise-orm.readthedocs.io/en/latest/examples/… Here, the code that creates the pydantic models are called first (because of the import), then later the `register_tortoise` function (which from looking at the sources initializes the model). But again, reordering the code, having `register_tortoise` first, then the creation of pydantic models did not work for me either.\n- I see the issue now, looking at `register_tortoise` `@app.on_event(\"startup\")` is when the models are initialized. Ill give it a try\n- Invoking `register_tortoise` only registers startup and shutdown handlers, without actual db initialization at this moment. Try to use early init approach.\n- I cannot get it function, no matter my efforts. I tried the early init approach tortoise api approach, and as well init of tortoise before fast api, but that approach was not feasible because of fast api limitations in regards to fast api initilization..\n- It makes sense to post a link to the gist of the latest version of the code that doesn't work\n- github.com/bozvul993/fast-api-tortoise-orm-experimentation Added instructions on how to run the app, the entry point, being main.py. The issue can be seen when trying to get a category by id: `/category/{id}`. The code that interacts with orm is in this file: github.com/bozvul993/fast-api-tortoise-orm-experimentation/b‌​lob/… There is open api docs on `http://127.0.0.1:8000/docs` when running the app in dev mode, with the command given in readme. The `keywords` relation is not loaded.. @alex_noname\n- If you do get a chance to look or make a PR, I would be very grateful.\n- I'v made the smaill PR, the main idea is to split pydantic and db models into different modules, so that importing the first does not lead to the creation of the second ahead of time\n- Thank you very much, I will take a look later tonight. Very grateful.\n- Thanks again for your help. All the best.\n- what does `[\"__main__\"]` represent? is that name of the main file like `main.py` or where does `__main__` come from? trying to know what to change this to for my code\n- `__main__` This is the name of the first module to run. More details here. In this example, the models are defined in one module, but here you can also pass the name of any other loaded module or the path as a string to the `py` file with the models.","metadata":{"transformedAt":"2026-08-18T18:32:29.115Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":13,"totalLines":241,"estimatedTokens":2128}}244{"id":"stack-77362216","source":"stackoverflow","questionId":77362216,"title":"Add startup/shutdown handlers to FastAPI app with lifespan API","tags":["python","fastapi","lifecycle","starlette"],"text":"Title: Add startup/shutdown handlers to FastAPI app with lifespan API\nTags: python, fastapi, lifecycle, starlette\nSource: Stack Overflow\n\nQuestion:\nConsider a FastAPI using the `lifespan` parameter like this:\n\n```\ndef lifespan(app):\n print('lifespan start')\n yield\n print('lifespan end')\n\napp = FastAPI(lifespan=lifespan)\n```\n\nNow I want to register a sub app with its own lifecycle functions:\n\n```\napp.mount(mount_path, sub_app)\n```\n\n**How can I register startup/shutdown handlers for the sub app?**\n\nAll solutions I could find either require control over the `lifespan` generator (which I don't have) or involve deprecated methods like `add_event_handler` (which doesn't work when `lifespan` is set).\n\n**Update** Minimal reproducible example:\n\n```\nfrom fastapi import FastAPI\n\n# --- main app ---\n\ndef lifespan(_):\n print(\"startup\")\n yield\n print(\"shutdown\")\n\napp = FastAPI(lifespan=lifespan)\n\n@app.get(\"/\")\nasync def root():\n return {\"message\": \"Hello World\"}\n\n# --- sub app ---\n\nsub_app = FastAPI()\n\n@sub_app.get(\"/\")\nasync def sub_root():\n return {\"message\": \"Hello Sub World\"}\n\napp.mount(\"/sub\", sub_app)\napp.on_event(\"startup\")(lambda: print(\"sub startup\")) # doesn't work\napp.on_event(\"shutdown\")(lambda: print(\"sub shutdown\")) # doesn't work\n```\n\nRun with: `uvicorn my_app:app --port 8000`\n\n========================================\n\nTop Answer:\nTry the add_event_handler function.\n\nThis works for me.\n\n```\napp.add_event_handler('startup', lambda: print(\"API startup\"))\napp.add_event_handler('shutdown', lambda: print(\"API shutdown\"))\n```\n\n========================================\n\nCode:\n```py\ndef lifespan(app):\n print('lifespan start')\n yield\n print('lifespan end')\n\n\napp = FastAPI(lifespan=lifespan)\n```\n\n```py\napp.mount(mount_path, sub_app)\n```\n\n```py\nfrom fastapi import FastAPI\n\n# --- main app ---\n\ndef lifespan(_):\n print(\"startup\")\n yield\n print(\"shutdown\")\n\napp = FastAPI(lifespan=lifespan)\n\n@app.get(\"/\")\nasync def root():\n return {\"message\": \"Hello World\"}\n\n# --- sub app ---\n\nsub_app = FastAPI()\n\n@sub_app.get(\"/\")\nasync def sub_root():\n return {\"message\": \"Hello Sub World\"}\n\napp.mount(\"/sub\", sub_app)\napp.on_event(\"startup\")(lambda: print(\"sub startup\")) # doesn't work\napp.on_event(\"shutdown\")(lambda: print(\"sub shutdown\")) # doesn't work\n```\n\n```text\nlifespan\n```\n\n```text\nlifespan\n```\n\n```text\nadd_event_handler\n```\n\n```text\nlifespan\n```\n\n```text\nuvicorn my_app:app --port 8000\n```\n\n```py\nfrom contextlib import asynccontextmanager\n\n...\n\nmain_app_lifespan = app.router.lifespan_context\n\n@asynccontextmanager\nasync def lifespan_wrapper(app):\n print(\"sub startup\")\n async with main_app_lifespan(app) as maybe_state:\n yield maybe_state\n print(\"sub shutdown\")\n\napp.router.lifespan_context = lifespan_wrapper\n```\n\n```text\nINFO: Waiting for application startup.\nsub startup\nstartup\nINFO: Application startup complete.\n...\nINFO: Shutting down\nINFO: Waiting for application shutdown.\nshutdown\nsub shutdown\nINFO: Application shutdown complete.\n```\n\n```text\napp.router.lifespan_context\n```\n\n```text\napp.add_event_handler('startup', lambda: print(\"API startup\"))\napp.add_event_handler('shutdown', lambda: print(\"API shutdown\"))\n```\n\n========================================\n\nComments:\n- @Chris Fair enough. I updated my post.\n- Exactly, also AFTER app is started - you can't actually add additional shutdown events, so this FastAPI decision is *strange* at least.\n- When using `add_event_handler` for the example in my original post, it isn't called. As I said, this doesn't work when `lifespan` is set.","metadata":{"transformedAt":"2026-08-18T18:32:29.115Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":12,"totalLines":182,"estimatedTokens":896}}245{"id":"stack-75975807","source":"stackoverflow","questionId":75975807,"title":"How to stop a loop on shutdown in FastAPI?","tags":["python","python-asyncio","fastapi","asgi"],"text":"Title: How to stop a loop on shutdown in FastAPI?\nTags: python, python-asyncio, fastapi, asgi\nSource: Stack Overflow\n\nQuestion:\nI have a route `/` which started an endless loop (technically until the websocket is disconnected but in this simplified example it is truly endless).\nHow do I stop this loop on shutdown:\n\n```\nfrom fastapi import FastAPI\n\nimport asyncio\n\napp = FastAPI()\nrunning = True\n\n@app.on_event(\"shutdown\")\ndef shutdown_event():\n global running\n running = False\n\n@app.get(\"/\")\nasync def index():\n while running:\n await asyncio.sleep(0.1)\n```\n\nAccording to the docs `@app.on_event(\"shutdown\")` should be called during the shutdown, but is suspect it is called similar to the lifetime event which is called after everything is finished which is a deadlock in this situation.\n\nTo test:\n\n- i run it as `uvicorn module.filename:app --host 0.0.0.0`\n\n- curl http://ip:port/\n\n- then stop the server (pressing `CTRL+C`)\n\nand you see that it hangs forever since running is never set to false because `shutdown_event` is not called.\n(Yes you can force shutdown by pressing `CTRL+C`)\n\n========================================\n\nTop Answer:\nAs @jsbueno and others pointed out, installing a second signal handler is problematic. Below is a complete template program that works within the uvicorn/FastAPI ecosystem and can be shut down by either invoking a URL (/shutdown or /restart) or sending a signal (e.g., SIGINT). You'll need to save as \"main.py\" to get it to work.\n\nIt returns different exit codes depending how the program was shutdown (0 or 1 for /shutdown or /restart, respectively). I used the return codes in a wrapper program that restarts the server, if that's what was requested.\n\n```\nfrom fastapi import FastAPI\nimport uvicorn\nimport time\nimport asyncio\nimport signal\nimport sys\nimport os\n\nclass RuntimeVals:\n shutdown = False\n restart = False\n shutdown_complete = False\n\nruntime_cfg = RuntimeVals()\napp = FastAPI()\n\nasync def worker(n):\n while not runtime_cfg.shutdown:\n await asyncio.sleep(0.1)\n if n == 1:\n raise RuntimeError(\"This is a demo error in worker 1\")\n else:\n print(f\"Worker {n} shutdown cleanly\")\n\nasync def mainloop():\n loop = asyncio.get_running_loop()\n done = []\n pending = [loop.create_task(worker(1)), loop.create_task(worker(2))]\n\n # Handle results in the order the task are completed\n # if exeption you can handle that as well.\n while len(pending) > 0:\n done, pending = await asyncio.wait(pending)\n for task in done:\n e = task.exception()\n if e is not None:\n # This will print the exception as stack trace\n task.print_stack()\n else:\n result = task.result()\n # This is needed to kill the Uvicorn server and communicate the\n # exit code\n if runtime_cfg.restart:\n print(\"RESTART\")\n else:\n print(\"SHUTDOWN\")\n runtime_cfg.shutdown_complete = True\n os.kill(os.getpid(), signal.SIGINT)\n\n@app.get(\"/shutdown\")\nasync def clean_shutdown():\n runtime_cfg.shutdown = True\n\n@app.get(\"/restart\")\nasync def clean_restart():\n runtime_cfg.restart = True\n runtime_cfg.shutdown = True\n\n@app.on_event(\"startup\")\nasync def startup_event():\n loop = asyncio.get_running_loop()\n loop.create_task(mainloop())\n\n@app.on_event(\"shutdown\")\nasync def shutdown_event():\n # This is a hook point where the event\n # loop has completely shut down\n runtime_cfg.shutdown = True\n while runtime_cfg.shutdown_complete is False:\n print(\"waiting\")\n await asyncio.sleep(1)\n\nif __name__ == \"__main__\":\n uv_cfg = uvicorn.Config(\n \"main:app\",\n host=\"0.0.0.0\",\n port=8000,\n log_level=\"debug\",\n timeout_graceful_shutdown=2,\n )\n server = uvicorn.Server(config=uv_cfg)\n server.run()\n import main\n if main.runtime_cfg.restart:\n sys.exit(1)\n else:\n sys.exit(0)\n```\n\nMost of the action happens in `mainloop`, which is invoked from the `startup_event`. Mainloop creates subtasks and monitors them, collecting and printing exceptions as needed. Each subtask is expected to return when `runtime_cfg.shutdown` is True.\n\nThere's 2 ways to close the program: via a signal or via a URL (/shutdown or /restart). If a SIGTERM/SIGINT is used, `shutdown_event` sets `runtime_cfg.shutdown = True` then waits. Each worker exits; once all the workers have stopped, mainloop sets `runtime_cfg.shutdown_complete = True`, which allows `shutdown_event` to return and uvicorn exits. The second signal sent from mainloop is ignored since the uvicorn server is already shutting down.\n\nIf a URL is invoked, it sets `runtime_cfg.shutdown = True`. Each worker exits, and `mainloop` sends a SIGINT to the program, which causes ucivorn to start the shutdown process.\n\nOne really tricky thing is at the end of the the program, when `server.run()` returns. Any module variables in main (e.g., `runtime_cfg.restart`) that were set while the server was running get shadowed. I'm pretty sure this is because uvicorn imports main again when it starts (it uses `\"main:app\"` in the `uvicorn.Config`). This shadowing makes communicating information from the server environment back to the main function very confusing.\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\n\nimport asyncio\n\napp = FastAPI()\nrunning = True\n\n@app.on_event(\"shutdown\")\ndef shutdown_event():\n global running\n running = False\n\n@app.get(\"/\")\nasync def index():\n while running:\n await asyncio.sleep(0.1)\n```\n\n```text\n/\n```\n\n```text\n@app.on_event(\"shutdown\")\n```\n\n```text\nuvicorn module.filename:app --host 0.0.0.0\n```\n\n```text\nCTRL+C\n```\n\n```text\nshutdown_event\n```\n\n```text\nCTRL+C\n```\n\n```text\nimport signal\nimport asyncio\nfrom fastapi import FastAPI\n\napp = FastAPI()\nrunning = True\n\ndef stop_server(*args):\n global running\n running = False\n\n@app.on_event(\"startup\")\ndef startup_event():\n signal.signal(signal.SIGINT, stop_server)\n\n@app.get(\"/\")\nasync def index():\n while running:\n await asyncio.sleep(0.1)\n```\n\n```text\nSIGINT\n```\n\n```text\nCNTR+C\n```\n\n```text\nrunning\n```\n\n```text\nFalse\n```\n\n```text\nindex()\n```\n\n```text\nfrom fastapi import FastAPI, Request\nimport asyncio\n\nfrom uvicorn.server import HANDLED_SIGNALS\nfrom functools import partial\n\napp = FastAPI()\nrunning = True\n\n#@app.on_event(\"shutdown\")\n#def shutdown_event():\n #global running\n #running = False\n\n@app.get(\"/\")\nasync def index(request: Request):\n while running:\n await asyncio.sleep(0.1)\n\n@app.on_event(\"startup\")\ndef chain_signals():\n loop = asyncio.get_running_loop()\n loop = asyncio.get_running_loop()\n signal_handlers = getattr(loop, \"_signal_handlers\", {}) # disclaimer 1: this is a private attribute: might change without notice.\n # Also: unix only, won't work on windows\n for sig in HANDLED_SIGNALS:\n loop.add_signal_handler(sig, partial(handle_exit, signal_handlers.get(sig, None)) , sig, None)\n\ndef handle_exit(original_handler, sig, frame):\n global running\n running = False\n if original_handler:\n return original_handler._run() # disclaimer 2: this should be opaque and performed only by the running loop. \n # not so bad: this is not changing, and is safe to do.\n```\n\n```text\nuvicorn\n```\n\n```text\nserver.should_exit\n```\n\n```text\nloop._signal_handlers\n```\n\n```text\nfrom fastapi import FastAPI\nimport uvicorn\nimport time\nimport asyncio\nimport signal\nimport sys\nimport os\n\n\nclass RuntimeVals:\n shutdown = False\n restart = False\n shutdown_complete = False\n\n\nruntime_cfg = RuntimeVals()\napp = FastAPI()\n\n\nasync def worker(n):\n while not runtime_cfg.shutdown:\n await asyncio.sleep(0.1)\n if n == 1:\n raise RuntimeError(\"This is a demo error in worker 1\")\n else:\n print(f\"Worker {n} shutdown cleanly\")\n\nasync def mainloop():\n loop = asyncio.get_running_loop()\n done = []\n pending = [loop.create_task(worker(1)), loop.create_task(worker(2))]\n\n # Handle results in the order the task are completed\n # if exeption you can handle that as well.\n while len(pending) > 0:\n done, pending = await asyncio.wait(pending)\n for task in done:\n e = task.exception()\n if e is not None:\n # This will print the exception as stack trace\n task.print_stack()\n else:\n result = task.result()\n # This is needed to kill the Uvicorn server and communicate the\n # exit code\n if runtime_cfg.restart:\n print(\"RESTART\")\n else:\n print(\"SHUTDOWN\")\n runtime_cfg.shutdown_complete = True\n os.kill(os.getpid(), signal.SIGINT)\n\n\n@app.get(\"/shutdown\")\nasync def clean_shutdown():\n runtime_cfg.shutdown = True\n\n\n@app.get(\"/restart\")\nasync def clean_restart():\n runtime_cfg.restart = True\n runtime_cfg.shutdown = True\n\n@app.on_event(\"startup\")\nasync def startup_event():\n loop = asyncio.get_running_loop()\n loop.create_task(mainloop())\n\n\n@app.on_event(\"shutdown\")\nasync def shutdown_event():\n # This is a hook point where the event\n # loop has completely shut down\n runtime_cfg.shutdown = True\n while runtime_cfg.shutdown_complete is False:\n print(\"waiting\")\n await asyncio.sleep(1)\n\n\nif __name__ == \"__main__\":\n uv_cfg = uvicorn.Config(\n \"main:app\",\n host=\"0.0.0.0\",\n port=8000,\n log_level=\"debug\",\n timeout_graceful_shutdown=2,\n )\n server = uvicorn.Server(config=uv_cfg)\n server.run()\n import main\n if main.runtime_cfg.restart:\n sys.exit(1)\n else:\n sys.exit(0)\n```\n\n```text\nmainloop\n```\n\n```text\nstartup_event\n```\n\n```text\nruntime_cfg.shutdown\n```\n\n```text\nshutdown_event\n```\n\n```text\nruntime_cfg.shutdown = True\n```\n\n```text\nruntime_cfg.shutdown_complete = True\n```\n\n```text\nshutdown_event\n```\n\n```text\nruntime_cfg.shutdown = True\n```\n\n```text\nmainloop\n```\n\n```text\nserver.run()\n```\n\n```text\nruntime_cfg.restart\n```\n\n```text\n\"main:app\"\n```\n\n```text\nuvicorn.Config\n```\n\n========================================\n\nComments:\n- good point i added more infos to the questions, yes i stop it via `CTRL+C`\n- There is a way to force exit programatically (after pressing `CTRL+C` once), but the client would receive an `Internal Server Error` response. Is that what you would like to do? Or, are you looking for a graceful shutdown, allowing all running tasks/futures to safely complete before shutting down?\n- I'm not overly concerned about forcing the shutdown programatically, i would prefere a way to cleanly and orderly shutdown but if it crashes the entire thing after the first `CNTR+C` thats better than not stopping\n- The answer you accepted in the github issue is very similar to the one I was talking about earlier. However, as mentioned by @Kludex, using that approach, the server doesn't shut down cleanly and that is why I haven't posted it here yet, as that approach actually **forces** the app to exit (similar to pressing `CTRL+C` twice). I have been trying to find a way to shutdown the server gracefully instead.\n- Plus the answer provided on github does not even exit the app, but lets it hanging there, as the poster of that comment missed executing `sys.exit()` inside the signal handler. If you do so, you would see that the app is forced to exit, and the client receives `Internal Server Error` response\n- @chris i mean yes if you do a sys.exit() then its a 'problem' but the solution on github is cooperative and just ensures that the endless loop stops on shutdown which is exactly what i want and i dont see how this kills other request also if you test the example you see the client gets null and not an error\n- A `null` response was returned simply because `running` was set to `False` and `sys.exit()` was not called, otherwise the client would receive `Internal Server Error` response. You asked how to stop the loop on **shutdown**. So, using that approach, did your app actually shut down when pressing `CTRL+C`? I guess not, as the app in the console is still running. Hence, you need to call `sys.exit()`, and if you do so, as described earlier, the app will be forced to exit, without giving time to already running tasks in the event loop to complete first.\n- Ah I see this solution works for me i can stop the loop cooperatively, but it would be a problem if the sleep would be way longer as this would not be aborted but the solution described in the github issue solves my specific problem\n- Can you please clarify whether or not the app actually terminates after pressing `CTRL+C` using that approach (as well as what Python version and OS are you using)? I don't mean just stopping the loop, but actually exiting the app.\n- yes works for me on fedora since it stoppes the loop and then fast api terminates as normal since all requests are done, where does this example not work for you?\n- I am afraid this is not a multiplatform solution and should be made clear in the answer's description (not in a code comment). As described in the example given in Python's documentation, registering handlers for signals using the `loop.add_signal_handler()` works **only** on Unix.\n- I created an issue since it would be neat to have a solution which does not require internals :) github.com/tiangolo/fastapi/discussions/9373, I tested your solution and for me this terminates the loop but it seems to me it never actually shutdowns the server itself it hangs until i kill the process manually\n- For windows, one canjust ignore the asyncio add_signal_handler and add a handler directly with `signal.signal`. That is what FastAPI does internally as well.\n- On Windows, using `signal.signal()` function to define a custom handler would require to run `sys.exit()` inside it, in order to terminate the app; otherwise, the app will keep running (after pressing `CTRL+C`). This is what actually happens when running (on Windows) the example recently posted by the asker. OP mentioned that, on Fedora, the app exits; regardless, that example does not provide a graceful shutdown, but rather a hard shutdown (i.e., forces the app to exit), meaning that any pending tasks (e.g., requests and background tasks) are not given time to complete before exiting.\n- This is why one would need to add an `async` handler instead, where the `loop` can be stopped and time can be given to pending tasks to complete - that is the problem I've been trying to solve the last couple of days. And btw, `signal.signal()` is not used internally by FastAPI, but Uvicorn instead (see here).\n- The original FastAPI installed handlers will take care of not exiting, and then exiting on the second try. They just have to be chained after the user installed handler, as I did in my example for a loop-tied handler. This, however, is no book chapter or production code, and the OP does not seen to be using windows: if one thinks a working windows example is due here, feel free to add it. (I would not have how to assert it works, anyway)\n- Why is `loop` created twice?\n- just a typo snafu when creating the code- only one is needed.","metadata":{"transformedAt":"2026-08-18T18:32:29.115Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":31,"totalLines":452,"estimatedTokens":3725}}246{"id":"stack-68930298","source":"stackoverflow","questionId":68930298,"title":"How to use Arrow type in FastAPI response schema?","tags":["openapi","fastapi","pydantic","arrow-python"],"text":"Title: How to use Arrow type in FastAPI response schema?\nTags: openapi, fastapi, pydantic, arrow-python\nSource: Stack Overflow\n\nQuestion:\nI want to use `Arrow` type in `FastAPI` response because I am using it already in `SQLAlchemy` model (thanks to `sqlalchemy_utils`).\n\nI prepared a small self-contained example with a minimal FastAPI app. I expect that this app return `product1` data from database.\n\nUnfortunately the code below gives exception:\n\n```\nException has occurred: FastAPIError\nInvalid args for response field! Hint: check that is a valid pydantic field type\n```\n\n```\nimport sqlalchemy\nimport uvicorn\nfrom arrow import Arrow\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\nfrom sqlalchemy import Column, Integer, Text, func\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import sessionmaker\nfrom sqlalchemy_utils import ArrowType\n\napp = FastAPI()\n\nengine = sqlalchemy.create_engine('sqlite:///db.db')\nBase = declarative_base()\n\nclass Product(Base):\n __tablename__ = \"product\"\n id = Column(Integer, primary_key=True, autoincrement=True)\n name = Column(Text, nullable=True)\n created_at = Column(ArrowType(timezone=True), nullable=False, server_default=func.now())\n\nBase.metadata.create_all(engine)\n\nSession = sessionmaker(bind=engine)\nsession = Session()\n\nproduct1 = Product(name=\"ice cream\")\nproduct2 = Product(name=\"donut\")\nproduct3 = Product(name=\"apple pie\")\n\nsession.add_all([product1, product2, product3])\nsession.commit()\n\nclass ProductResponse(BaseModel):\n id: int\n name: str\n created_at: Arrow\n\n class Config:\n orm_mode = True\n arbitrary_types_allowed = True\n\n@app.get('/', response_model=ProductResponse)\nasync def return_product():\n\n product = session.query(Product).filter(Product.id == 1).first()\n\n return product\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"localhost\", port=8000)\n```\n\nrequirements.txt:\n\n```\nsqlalchemy==1.4.23\nsqlalchemy_utils==0.37.8\narrow==1.1.1\nfastapi==0.68.1\nuvicorn==0.15.0\n```\n\nThis error is already discussed in those FastAPI issues:\n\n- https://github.com/tiangolo/fastapi/issues/1186\n\n- https://github.com/tiangolo/fastapi/issues/2382\n\nOne possible workaround is to add this code (source):\n\n```\nfrom pydantic import BaseConfig\nBaseConfig.arbitrary_types_allowed = True\n```\n\nIt is enough to put it just above `@app.get('/'...`, but it can be put even before `app = FastAPI()`\n\nThe problem with this solution is that output of GET endpoint will be:\n\n```\n// 20210826001330\n// http://localhost:8000/\n\n{\n \"id\": 1,\n \"name\": \"ice cream\",\n \"created_at\": {\n \"_datetime\": \"2021-08-25T21:38:01+00:00\"\n }\n}\n```\n\ninstead of desired:\n\n```\n// 20210826001330\n// http://localhost:8000/\n\n{\n \"id\": 1,\n \"name\": \"ice cream\",\n \"created_at\": \"2021-08-25T21:38:01+00:00\"\n}\n```\n\n========================================\n\nTop Answer:\nAdd a custom function with the `@validator` decorator that returns the desired `_datetime` of the object:\n\n```\nclass ProductResponse(BaseModel):\n id: int\n name: str\n created_at: Arrow\n\n class Config:\n orm_mode = True\n arbitrary_types_allowed = True\n\n @validator(\"created_at\")\n def format_datetime(cls, value):\n return value._datetime\n```\n\nTested on local, seems to be working:\n\n```\n$ curl -s localhost:8000 | jq\n{\n \"id\": 1,\n \"name\": \"ice cream\",\n \"created_at\": \"2021-12-02T08:25:10+00:00\"\n}\n```\n\n========================================\n\nCode:\n```text\nException has occurred: FastAPIError\nInvalid args for response field! Hint: check that <class 'arrow.arrow.Arrow'> is a valid pydantic field type\n```\n\n```py\nimport sqlalchemy\nimport uvicorn\nfrom arrow import Arrow\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\nfrom sqlalchemy import Column, Integer, Text, func\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import sessionmaker\nfrom sqlalchemy_utils import ArrowType\n\napp = FastAPI()\n\nengine = sqlalchemy.create_engine('sqlite:///db.db')\nBase = declarative_base()\n\nclass Product(Base):\n __tablename__ = \"product\"\n id = Column(Integer, primary_key=True, autoincrement=True)\n name = Column(Text, nullable=True)\n created_at = Column(ArrowType(timezone=True), nullable=False, server_default=func.now())\n\nBase.metadata.create_all(engine)\n\n\nSession = sessionmaker(bind=engine)\nsession = Session()\n\nproduct1 = Product(name=\"ice cream\")\nproduct2 = Product(name=\"donut\")\nproduct3 = Product(name=\"apple pie\")\n\nsession.add_all([product1, product2, product3])\nsession.commit()\n\n\nclass ProductResponse(BaseModel):\n id: int\n name: str\n created_at: Arrow\n\n class Config:\n orm_mode = True\n arbitrary_types_allowed = True\n\n\n@app.get('/', response_model=ProductResponse)\nasync def return_product():\n\n product = session.query(Product).filter(Product.id == 1).first()\n\n return product\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"localhost\", port=8000)\n```\n\n```text\nsqlalchemy==1.4.23\nsqlalchemy_utils==0.37.8\narrow==1.1.1\nfastapi==0.68.1\nuvicorn==0.15.0\n```\n\n```py\nfrom pydantic import BaseConfig\nBaseConfig.arbitrary_types_allowed = True\n```\n\n```json\n// 20210826001330\n// http://localhost:8000/\n\n{\n \"id\": 1,\n \"name\": \"ice cream\",\n \"created_at\": {\n \"_datetime\": \"2021-08-25T21:38:01+00:00\"\n }\n}\n```\n\n```json\n// 20210826001330\n// http://localhost:8000/\n\n{\n \"id\": 1,\n \"name\": \"ice cream\",\n \"created_at\": \"2021-08-25T21:38:01+00:00\"\n}\n```\n\n```text\nArrow\n```\n\n```text\nFastAPI\n```\n\n```text\nSQLAlchemy\n```\n\n```text\nsqlalchemy_utils\n```\n\n```text\nproduct1\n```\n\n```text\n@app.get('/'...\n```\n\n```text\napp = FastAPI()\n```\n\n```py\nfrom arrow import Arrow\nfrom pydantic.json import ENCODERS_BY_TYPE\nENCODERS_BY_TYPE |= {Arrow: str}\n```\n\n```json\n// 20220514022717\n// http://localhost:8000/\n\n{\n \"id\": 1,\n \"name\": \"ice cream\",\n \"created_at\": \"2022-05-14T00:20:11+00:00\"\n}\n```\n\n```py\nimport sqlalchemy\nimport uvicorn\nfrom arrow import Arrow\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\nfrom sqlalchemy import Column, Integer, Text, func\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import sessionmaker\nfrom sqlalchemy_utils import ArrowType\n\nfrom pydantic.json import ENCODERS_BY_TYPE\nENCODERS_BY_TYPE |= {Arrow: str}\n\nfrom pydantic import BaseConfig\nBaseConfig.arbitrary_types_allowed = True\n\napp = FastAPI()\n\nengine = sqlalchemy.create_engine('sqlite:///db.db')\nBase = declarative_base()\n\nclass Product(Base):\n __tablename__ = \"product\"\n id = Column(Integer, primary_key=True, autoincrement=True)\n name = Column(Text, nullable=True)\n created_at = Column(ArrowType(timezone=True), nullable=False, server_default=func.now())\n\nBase.metadata.create_all(engine)\n\n\nSession = sessionmaker(bind=engine)\nsession = Session()\n\nproduct1 = Product(name=\"ice cream\")\nproduct2 = Product(name=\"donut\")\nproduct3 = Product(name=\"apple pie\")\n\nsession.add_all([product1, product2, product3])\nsession.commit()\n\n\nclass ProductResponse(BaseModel):\n id: int\n name: str\n created_at: Arrow\n\n class Config:\n orm_mode = True\n arbitrary_types_allowed = True\n\n\n@app.get('/', response_model=ProductResponse)\nasync def return_product():\n\n product = session.query(Product).filter(Product.id == 1).first()\n\n return product\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"localhost\", port=8000)\n```\n\n```text\nENCODERS_BY_TYPE\n```\n\n```text\nBaseConfig.arbitrary_types_allowed = True\n```\n\n```py\nclass ProductResponse(BaseModel):\n id: int\n name: str\n created_at: Arrow\n\n class Config:\n orm_mode = True\n arbitrary_types_allowed = True\n\n @validator(\"created_at\")\n def format_datetime(cls, value):\n return value._datetime\n```\n\n```sh\n$ curl -s localhost:8000 | jq\n{\n \"id\": 1,\n \"name\": \"ice cream\",\n \"created_at\": \"2021-12-02T08:25:10+00:00\"\n}\n```\n\n```text\n@validator\n```\n\n```text\n_datetime\n```\n\n```py\nfrom psycopg2.extras import DateTimeTZRange as DateTimeTZRangeBase\nfrom sqlalchemy.dialects.postgresql import TSTZRANGE\nfrom sqlmodel import (\n Column,\n Field,\n Identity,\n SQLModel,\n)\n\nfrom pydantic.json import ENCODERS_BY_TYPE\n\nENCODERS_BY_TYPE |= {DateTimeTZRangeBase: str}\n\n\nclass DateTimeTZRange(DateTimeTZRangeBase):\n @classmethod\n def __get_validators__(cls):\n yield cls.validate\n\n @classmethod\n def validate(cls, v):\n if isinstance(v, str):\n lower = v.split(\", \")[0][1:].strip().strip()\n upper = v.split(\", \")[1][:-1].strip().strip()\n bounds = v[:1] + v[-1:]\n return DateTimeTZRange(lower, upper, bounds)\n elif isinstance(v, DateTimeTZRangeBase):\n return v\n raise TypeError(\"Type must be string or DateTimeTZRange\")\n\n @classmethod\n def __modify_schema__(cls, field_schema):\n field_schema.update(type=\"string\", example=\"[2022,01,01, 2022,02,02)\")\n\n\nclass EventBase(SQLModel):\n __tablename__ = \"event\"\n timestamp_range: DateTimeTZRange = Field(\n sa_column=Column(\n TSTZRANGE(),\n nullable=False,\n ),\n )\n\n\nclass Event(EventBase, table=True):\n id: int | None = Field(\n default=None,\n sa_column_args=(Identity(always=True),),\n primary_key=True,\n nullable=False,\n )\n```\n\n```text\nclass Config\n```\n\n```text\nValueError: Value not declarable with JSON Schema, field: name='created_at' type=ArrowType required=True\n```\n\n```text\nimport datetime\n\nclass ArrowType(datetime):\n @classmethod\n def __get_validators__(cls):\n yield cls.validate\n\n @classmethod\n def validate(cls, v):\n return v._datetime\n\nclass Domain(DomainBase):\n id: int\n created_at: ArrowType\n updated_at: ArrowType\n```\n\n```py\n# pydantic < 2.0\nimport arrow\nfrom pydantic import BaseModel\n\n\nclass ArrowPydanticV1(arrow.Arrow):\n @classmethod\n def __get_validators__(cls):\n yield cls.pydantic_validate\n\n @classmethod\n def __modify_schema__(cls, field_schema):\n field_schema.update(\n examples=[\"2024-02-06 13:38:18\", \"2024-02-06 13:38:30+00:00\"],\n )\n\n @classmethod\n def pydantic_validate(cls, v):\n try:\n arr = arrow.get(v)\n return arr\n except Exception as e:\n raise ValueError(f\"Arrow could not parse {v!r}: {e!r}\")\n\n def __repr__(self):\n return f\"PydanticV1Arrow({super().__repr__()})\"\n```\n\n```py\n# pydantic >= 2.0\nfrom typing import Any\n\nimport arrow\n\nfrom pydantic import (\n BaseModel,\n GetCoreSchemaHandler,\n GetJsonSchemaHandler,\n)\nfrom pydantic.json_schema import JsonSchemaValue\nfrom pydantic_core import core_schema\nfrom typing_extensions import Annotated\n\n\nclass ArrowPydanticV2(arrow.Arrow):\n @classmethod\n def __get_pydantic_core_schema__(\n cls,\n _source_type: Any,\n _handler: GetCoreSchemaHandler,\n ) -> core_schema.CoreSchema:\n \n def validate_by_arrow(value) -> arrow.Arrow:\n try:\n arr = arrow.get(value)\n return arr\n except Exception as e:\n raise ValueError(f\"Arrow can not parse\")\n\n def arrow_serialization(value: Any, _, info) -> str | arrow.Arrow:\n if info.mode == \"json\":\n return value.format(\"YYYY-MM-DDTHH:mm:ss.SSSSSSZZ\")\n return value \n\n return core_schema.no_info_after_validator_function(\n function=validate_by_arrow,\n schema=core_schema.str_schema(),\n serialization=core_schema.wrap_serializer_function_ser_schema(arrow_serialization, info_arg=True),\n )\n\nclass Model(BaseModel):\n datetime: ArrowPydanticV2\n\n# test\nm = Model(datetime=\"2024-02-06 11:38:18+00:00\")\nprint(m)\nprint(m.datetime)\nprint(m.model_dump(mode=\"python\"))\nprint(m.model_dump_json())\nprint(m.model_dump(mode=\"json\"))\n\n>>>\ndatetime=<Arrow [2024-02-06T11:38:18+00:00]>\n2024-02-06T11:38:18+00:00\n{'datetime': {'datetime': <Arrow [2024-02-06T11:38:18+00:00]>}}\n{\"datetime\":\"2024-02-06 11:38:18.000000+00:00\"}\n{'datetime': '2024-02-06T11:38:18Z'}\n```\n\n```text\nfrom typing import Any, Annotated\n\nimport arrow\nfrom pydantic import (\n GetCoreSchemaHandler,\n GetJsonSchemaHandler\n)\nfrom pydantic.json_schema import JsonSchemaValue\nfrom pydantic_core import core_schema\n\nfrom pydantic import BaseModel\n\nclass ArrowSchema:\n @classmethod\n def __get_pydantic_core_schema__(\n cls,\n _source_type: Any,\n _handler: GetCoreSchemaHandler,\n ) -> core_schema.CoreSchema:\n def validate_by_arrow(value) -> arrow.Arrow:\n try:\n arr = arrow.get(value)\n return arr\n except Exception as e:\n raise ValueError(f\"Arrow can not parse\")\n\n def arrow_serialization(value: arrow.Arrow, _, info) -> str | arrow.Arrow:\n if info.mode == \"json\":\n # impl your json serialization logic\n return value.isoformat()\n return value\n\n return core_schema.no_info_before_validator_function(\n function=validate_by_arrow,\n schema=core_schema.union_schema(\n [\n core_schema.str_schema(),\n core_schema.datetime_schema(),\n core_schema.is_instance_schema(arrow.Arrow),\n ]\n ),\n serialization=core_schema.wrap_serializer_function_ser_schema(\n arrow_serialization, info_arg=True\n ),\n )\n\n @classmethod\n def __get_pydantic_json_schema__(\n cls, core_schema: core_schema.CoreSchema, handler: GetJsonSchemaHandler\n ) -> JsonSchemaValue:\n return {\n \"title\": \"timestamp\",\n \"examples\": [\"2024-01-01 12:34:56.000+00:00\"],\n \"type\": \"string\",\n \"format\": \"date-time\",\n }\n\nArrowPydantic = Annotated[arrow.Arrow, ArrowSchema\n```\n\n```py\n# Optional, you can just use `float` instead\nTimeStamp = Annotated[\n float,\n WithJsonSchema(\n {\"type\": \"float\", \"example\": arrow.now().timestamp()}, mode=\"serialization\"\n ),\n]\n\nPydanticArrow = Annotated[\n arrow.Arrow,\n PlainSerializer(lambda x: x.timestamp(), return_type=TimeStamp, when_used=\"json\"),\n]\n\n\nclass SimpleSchema(BaseModel):\n id: UUID \n create_time: PydanticArrow\n```\n\n```text\nclass ArrowType(arrow.Arrow):\n @classmethod\n def __get_pydantic_core_schema__(\n cls, source_type: Any, handler: GetCoreSchemaHandler\n ) -> CoreSchema:\n def validate_by_arrow(value) -> arrow.Arrow:\n try:\n arr = arrow.get(value)\n return arr\n except Exception:\n raise ValueError('Arrow can not parse')\n\n _schema = core_schema.chain_schema(\n [\n core_schema.str_schema(),\n core_schema.no_info_plain_validator_function(validate_by_arrow),\n ]\n )\n\n return core_schema.json_or_python_schema(\n json_schema=_schema,\n python_schema=core_schema.union_schema(\n [\n core_schema.is_instance_schema(arrow.Arrow),\n _schema,\n ]\n ),\n serialization=core_schema.plain_serializer_function_ser_schema(\n lambda instance: instance.isoformat()\n ),\n )\n\n @classmethod\n def __get_pydantic_json_schema__(\n cls, _core_schema: core_schema.CoreSchema, handler: GetJsonSchemaHandler\n ) -> JsonSchemaValue:\n return handler(core_schema.str_schema())\n```\n\n========================================\n\nComments:\n- this Monkey Patch is strong +1\n- This is deprecated in pydantic v2, is there another way of monkey patching?\n- Nice, but I think your solution doesn't work with Arrow type.\n- This worked for me for Pydantic V2; however to get it working with FastAPI I needed to change \"schema=core_schema.str_schema()\" to \"schema=core_schema.is_instance_schema(arrow.Arrow)\".\n- @Oeste Thank you for your comment\n- Does this version still work? Could you define the specific version? I could not make it work in Pydantic 2.7","metadata":{"transformedAt":"2026-08-18T18:32:29.116Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":31,"totalLines":705,"estimatedTokens":3995}}247{"id":"stack-72915808","source":"stackoverflow","questionId":72915808,"title":"How to create a custom sort order for the API methods in FastAPI Swagger autodocs?","tags":["python","swagger","swagger-ui","fastapi","openapi"],"text":"Title: How to create a custom sort order for the API methods in FastAPI Swagger autodocs?\nTags: python, swagger, swagger-ui, fastapi, openapi\nSource: Stack Overflow\n\nQuestion:\nHow can I set a **custom** sort order for the API methods in FastAPI Swagger autodocs?\n\nThis question shows how to do it in Java. My previous question asked how to sort by \"Method\", which is a supported sorting method. I would really like to take this a step further, so that I can determine which **order** the methods appear. Right now `DELETE` appears at the top, but I want API methods to be in the order: `GET`, `POST`, `PUT`, `DELETE`.\n\nI know it is possible to implement a custom sort in JavaScript and give that function to `operationsSorter`, but you can't include it from the `swagger_ui_parameters` property that is available in the Python bindings. Is there some way to accomplish this in Python?\n\n```\nfrom fastapi import FastAPI\n\napp = FastAPI(swagger_ui_parameters={\"operationsSorter\": \"method\"})\n\n@app.get(\"/\")\ndef list_all_components():\n pass\n\n@app.get(\"/{component_id}\")\ndef get_component(component_id: int):\n pass\n\n@app.post(\"/\")\ndef create_component():\n pass\n\n@app.put(\"/{component_id}\")\ndef update_component(component_id: int):\n pass\n\n@app.delete(\"/{component_id}\")\ndef delete_component(component_id: int):\n pass\n```\n\nhttps://i.sstatic.net/Cyj1g.png\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI\n\napp = FastAPI(swagger_ui_parameters={\"operationsSorter\": \"method\"})\n\n@app.get(\"/\")\ndef list_all_components():\n pass\n\n@app.get(\"/{component_id}\")\ndef get_component(component_id: int):\n pass\n\n@app.post(\"/\")\ndef create_component():\n pass\n\n@app.put(\"/{component_id}\")\ndef update_component(component_id: int):\n pass\n\n@app.delete(\"/{component_id}\")\ndef delete_component(component_id: int):\n pass\n```\n\n```text\nDELETE\n```\n\n```text\nGET\n```\n\n```text\nPOST\n```\n\n```text\nPUT\n```\n\n```text\nDELETE\n```\n\n```text\noperationsSorter\n```\n\n```text\nswagger_ui_parameters\n```\n\n```py\nfrom fastapi import FastAPI\n\ntags_metadata = [\n {\"name\": \"Get\"},\n {\"name\": \"Post\"},\n {\"name\": \"Put\"},\n {\"name\": \"Delete\"}\n]\n\napp = FastAPI(openapi_tags=tags_metadata)\n\n@app.get(\"/\", tags=[\"Get\"])\ndef list_all_components():\n pass\n\n@app.get(\"/{component_id}\", tags=[\"Get\"])\ndef get_component(component_id: int):\n pass\n\n@app.post(\"/\", tags=[\"Post\"])\ndef create_component():\n pass\n\n@app.put(\"/{component_id}\", tags=[\"Put\"])\ndef update_component(component_id: int):\n pass\n\n@app.delete(\"/{component_id}\", tags=[\"Delete\"])\ndef delete_component(component_id: int):\n pass\n```\n\n```text\ntags\n```\n\n```text\ntags\n```\n\n```text\nlist\n```\n\n```text\nstr\n```\n\n```text\nstr\n```\n\n```text\nname\n```\n\n```text\nHTTP\n```\n\n```text\nGet\n```\n\n```text\nGET\n```\n\n```text\nGet\n```\n\n```text\nname\n```\n\n```text\nGET\n```\n\n```text\nPOST\n```\n\n```text\nPUT\n```\n\n```text\nDELETE\n```\n\n```text\nopenapi_tags\n```\n\n```text\nlist\n```\n\n```text\ndictionary\n```\n\n```text\nname\n```\n\n```text\nname\n```\n\n```text\ntags\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.116Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":30,"totalLines":212,"estimatedTokens":746}}248{"id":"stack-62532559","source":"stackoverflow","questionId":62532559,"title":"List of object attributes in pydantic model","tags":["python","sqlalchemy","fastapi","pydantic"],"text":"Title: List of object attributes in pydantic model\nTags: python, sqlalchemy, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI use Fast API to create a web service.\n\nThere are following sqlAlchemy models:\n\n```\nclass User(Base):\n __tablename__ = 'user'\n account_name = Column(String, primary_key=True, index=True, unique=True)\n email = Column(String, unique=True, index=True, nullable=False)\n roles = relationship(\"UserRole\", back_populates=\"users\", lazy=False, uselist=True)\n\nclass UserRole(Base):\n __tablename__ = 'user_role'\n __table_args__ = (UniqueConstraint('role_name', 'user_name', name='user_role_uc'),)\n role_name = Column(String, ForeignKey('role.name'), primary_key=True)\n user_name = Column(String, ForeignKey('user.account_name'), primary_key=True)\n users = relationship(\"User\", back_populates=\"roles\")\n```\n\nPydantic schemas are below:\n\n```\nclass UserRole(BaseModel):\n role_name: str\n\n class Config:\n orm_mode = True\n\nclass UserBase(BaseModel):\n account_name: str\n email: EmailStr\n roles: List[UserRole] = []\n\n class Config:\n orm_mode = True\n```\n\nWhat I have now is:\n\n```\n{\n \"account_name\": \"Test.Test\",\n \"email\": \"Test.Test@test.com\",\n \"roles\": [\n {\n \"role_name\": \"all:admin\"\n },\n {\n \"role_name\": \"all:read\"\n }\n ]\n}\n```\n\nWhat I want to achieve is to get user from api in following structure:\n\n```\n{\n \"account_name\": \"Test.Test\",\n \"email\": \"Test.Test@test.com\",\n \"roles\": [\n \"all:admin\",\n \"all:read\"\n ]\n}\n```\n\nIs that possible? How should I change schemas to get this?\n\n========================================\n\nTop Answer:\nAs UserRole is a class, it is represented as an object (using a dictionary). If you want to represent it as a list of strings you'll have to transform the data (and change your Pydantic model's field declaration). There's several approaches to this, but the pydantic model documentation is a good place to start. Mind that the ORM model serves as the data representation layer and the pydantic model is the validation (and perhaps serialization) layer, so there's a lot of places where you could 'hook in'.\n\n========================================\n\nCode:\n```text\nclass User(Base):\n __tablename__ = 'user'\n account_name = Column(String, primary_key=True, index=True, unique=True)\n email = Column(String, unique=True, index=True, nullable=False)\n roles = relationship(\"UserRole\", back_populates=\"users\", lazy=False, uselist=True)\n\n\nclass UserRole(Base):\n __tablename__ = 'user_role'\n __table_args__ = (UniqueConstraint('role_name', 'user_name', name='user_role_uc'),)\n role_name = Column(String, ForeignKey('role.name'), primary_key=True)\n user_name = Column(String, ForeignKey('user.account_name'), primary_key=True)\n users = relationship(\"User\", back_populates=\"roles\")\n```\n\n```text\nclass UserRole(BaseModel):\n role_name: str\n\n class Config:\n orm_mode = True\n\n\nclass UserBase(BaseModel):\n account_name: str\n email: EmailStr\n roles: List[UserRole] = []\n\n class Config:\n orm_mode = True\n```\n\n```text\n{\n \"account_name\": \"Test.Test\",\n \"email\": \"Test.Test@test.com\",\n \"roles\": [\n {\n \"role_name\": \"all:admin\"\n },\n {\n \"role_name\": \"all:read\"\n }\n ]\n}\n```\n\n```text\n{\n \"account_name\": \"Test.Test\",\n \"email\": \"Test.Test@test.com\",\n \"roles\": [\n \"all:admin\",\n \"all:read\"\n ]\n}\n```\n\n```py\nclass UserResponse(BaseModel):\n account_name: str\n email: EmailStr\n roles: List[str]\n```\n\n```py\ndef get_user_response(user_id) -> UserResponse:\n user = User.query.get(user_id)\n user_roles = UserRole.query.filter(user=user_id).all()\n role_names = [r.role_name for r in user_roles]\n response = UserResponse(\n account_name=user.account_name,\n email=user.email,\n roles=role_names\n }\n return response\n```\n\n```py\n@app.get(\"/users/{user_id}\", response_model=UserResponse)\nasync def read_item(user_id):\n return get_user_response(user_id)\n```\n\n```text\nuser_id\n```\n\n```text\nUserResponse\n```\n\n```text\nUserBase\n```\n\n```text\nUserBase\n```\n\n```text\naccount_name\n```\n\n```text\nemail\n```\n\n```text\nConfig\n```\n\n```text\nUserBase\n```\n\n```text\nget_user_response()\n```\n\n========================================\n\nComments:\n- Does this answer your question? How to use nested pydantic models for sqlalchemy in a flexible way","metadata":{"transformedAt":"2026-08-18T18:32:29.116Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":16,"totalLines":207,"estimatedTokens":1065}}249{"id":"stack-65709999","source":"stackoverflow","questionId":65709999,"title":"How to disable schema checking in FastAPI?","tags":["python","validation","schema","fastapi","pydantic"],"text":"Title: How to disable schema checking in FastAPI?\nTags: python, validation, schema, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI am migrating a service from Flask to FastAPI and using Pydantic models to generate the documentation. However, I'm a little unsure about the schema check. I'm afraid there will be some unexpected data (like a different field format) and it will return an error.\n\nIn the Pydantic documentation there are ways to create a model without checking the schema: https://pydantic-docs.helpmanual.io/usage/models/#creating-models-without-validation\n\nHowever, as this is apparently instantiated by FastAPI itself, I don't know how to disable this schema check when returning from FastAPI.\n\n========================================\n\nTop Answer:\nYou can set the request model as a `typing.Dict` or `typing.List`\n\n```\nfrom typing import Dict\n\napp.post('/')\nasync def your_function(body: Dict):\n return { 'request_body': body}\n```\n\n========================================\n\nCode:\n```text\nclass SomeModel(BaseModel):\n num: int\n\n\n@app.get(\"/get\", response_model=SomeModel)\ndef handler(param: int):\n if param == 1: # ok\n return {\"num\": \"1\"}\n elif param == 2: # validation error\n return {\"num\": \"not a number\"}\n elif param == 3: # ok (return without validation)\n return JSONResponse(content={\"num\": \"not a number\"})\n elif param == 4: # ok (return without validation and conversion)\n return Response(content=json.dumps({\"num\": \"not a number\"}), media_type=\"application/json\")\n```\n\n```py\napp.get('/')\nasync def your_function(input_param):\n return { 'param': input_param }\n\n# Don't use models or type hints when defining the function params.\n# `input_param` can be anything, no validation will be performed.\n```\n\n```py\nfrom typing import Any\nfrom pydantic import BaseModel\n\nclass YourClass(BaseModel):\n any_value: Any\n```\n\n```text\nAny\n```\n\n```text\nAny\n```\n\n```text\nNone\n```\n\n```text\ntyping.Any\n```\n\n```py\nfrom typing import Dict\n\napp.post('/')\nasync def your_function(body: Dict):\n return { 'request_body': body}\n```\n\n```text\ntyping.Dict\n```\n\n```text\ntyping.List\n```\n\n========================================\n\nComments:\n- You could also use the `Any` type. See answer below.\n- If you do Any, it won't show the fields for OpenAPI documentation. fastapi.tiangolo.com/#interactive-api-docs\n- pydantic models are also used to generate the documentation.\n- If you do dict, it won't show the fields for OpenAPI documentation. fastapi.tiangolo.com/#interactive-api-docs","metadata":{"transformedAt":"2026-08-18T18:32:29.116Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":10,"totalLines":100,"estimatedTokens":633}}250{"id":"stack-70002709","source":"stackoverflow","questionId":70002709,"title":"How to apply transaction logic in FastAPI RealWorld example app?","tags":["python","fastapi","asyncpg"],"text":"Title: How to apply transaction logic in FastAPI RealWorld example app?\nTags: python, fastapi, asyncpg\nSource: Stack Overflow\n\nQuestion:\nI am using nsidnev/fastapi-realworld-example-app.\n\nI need to apply transaction logic to this project.\n\nIn one API, I am calling a lot of methods from repositories and doing updating, inserting and deleting operations in many tables. If there is an exception in any of these operations, how can I roll back changes?\n(Or if everything is correct then commit.)\n\n========================================\n\nCode:\n```py\nasync with conn.transaction():\n await repo_one.update_one(...)\n await repo_two.insert_two(...)\n await repo_three.delete_three(...)\n\n # This automatically rolls back the transaction:\n raise Exception\n```\n\n```py\ntx = conn.transaction()\nawait tx.start()\n\ntry:\n await repo_one.update_one(...)\n await repo_two.insert_two(...)\n await repo_three.delete_three(...)\nexcept:\n await tx.rollback()\n raise\nelse:\n await tx.commit()\n```\n\n```py\nfrom asyncpg.connection import Connection\nfrom fastapi import Depends\n\nfrom app.api.dependencies.database import _get_connection_from_pool\n\n\n@router.post(\n ...\n)\nasync def create_new_article(\n ...\n conn: Connection = Depends(_get_connection_from_pool), # Add this\n) -> ArticleInResponse:\n```\n\n```text\nasync with\n```\n\n```text\nstart\n```\n\n```text\nrollback\n```\n\n```text\ncommit\n```\n\n```text\nconn\n```\n\n```text\nconn: Connection = Depends(_get_connection_from_pool)\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.116Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":79,"estimatedTokens":371}}251{"id":"stack-75942865","source":"stackoverflow","questionId":75942865,"title":"Async solution for factory boy style fixtures in FastAPI?","tags":["python","fastapi","fixtures","factory-boy"],"text":"Title: Async solution for factory boy style fixtures in FastAPI?\nTags: python, fastapi, fixtures, factory-boy\nSource: Stack Overflow\n\nQuestion:\nI really like the factory boy style of generated factories that can handle things like sequences, complex relationships etc.\n\nFor a FastAPI app with fully async database access using factory boy seems likely problematic. There is dated discussion here and an old PR to add async support that seems stuck.\n\nIs there a good solution for these kinds of fixtures that has full async support?\n\n========================================\n\nCode:\n```py\n@pytest.fixture(scope=\"function\")\ndef user_factory(db: Session):\n \"\"\"A factory for creating users\"\"\"\n last_user = 0\n\n def create_user(\n email=None, name=None, role=None, org: Organization | None = None\n ) -> User:\n \"\"\"Return a new user, optionally with role for an existing organization\"\"\"\n nonlocal last_user\n last_user += 1\n email = email or f\"user{last_user}@example.com\"\n name = name or f\"User {last_user}\"\n user = User(email=email, name=name, auth_id=auth_id)\n db.add(user)\n\n if role:\n role = OrganizationRole(user_id=user_id, organization_id=org.id, role=role)\n db.add(role)\n\n db.commit()\n db.refresh(user)\n return user\n\n return create_user\n\n# use in test \ndef test_something(user_factory) -> None:\n user = user_factory()\n # ...\n```\n\n========================================\n\nComments:\n- Do you have any updates on this issue?\n- @MiradilZeynalli - I added an answer that summarizes where I ended up with this, hope it is helpful for you!","metadata":{"transformedAt":"2026-08-18T18:32:29.116Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":1,"totalLines":52,"estimatedTokens":414}}252{"id":"stack-67911334","source":"stackoverflow","questionId":67911334,"title":"Is there a way to exclude Pydantic models from FastAPI's auto-generated documentation?","tags":["python","fastapi","pydantic"],"text":"Title: Is there a way to exclude Pydantic models from FastAPI's auto-generated documentation?\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nIs there a way for a FastAPI application to not display a model in its schema documentation? I have some models which are slight variations of others, and with this duplication occurring for each model, the schema documentation is quite cluttered.\n\n```\nfrom pydantic import BaseModel\nclass A(BaseModel):\n name: str\n\nclass HasID(BaseModel):\n id_: int\n\nclass AWithID(A, HasID):\n pass\n```\n\nIs there some way not to display class `AWithID` in the documentation?\n\n========================================\n\nCode:\n```py\nfrom pydantic import BaseModel\nclass A(BaseModel):\n name: str\n\nclass HasID(BaseModel):\n id_: int\n\nclass AWithID(A, HasID):\n pass\n```\n\n```text\nAWithID\n```\n\n```json\n{\n \"openapi\": \"3.0.2\",\n \"info\": {...},\n \"paths\": {...},\n \"components\": {\n \"schemas\": {\n \"A\": {\n \"title\": \"A\",\n \"required\": [...],\n \"type\": \"object\",\n \"properties\": {...}\n },\n \"AWithID\": {\n \"title\": \"AWithID\",\n \"required\": [...],\n \"type\": \"object\",\n \"properties\": {...}\n },\n \"HasID\": {\n \"title\": \"HasID\",\n \"required\": [...],\n \"type\": \"object\",\n \"properties\": {...}\n },\n ...\n }\n }\n}\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.openapi.utils import get_openapi\n\napp = FastAPI()\n\n# Define routes before customizing the OpenAPI schema\n# ...\n\ndef custom_openapi():\n if app.openapi_schema:\n return app.openapi_schema\n\n openapi_schema = get_openapi(title=\"My App\", version=\"1.0.0\", routes=app.routes)\n openapi_schema[\"components\"][\"schemas\"].pop(\"AWithID\", None)\n \n app.openapi_schema = openapi_schema\n return app.openapi_schema\n\n\napp.openapi = custom_openapi\n```\n\n```text\nFastAPI\n```\n\n```text\n.openapi()\n```\n\n```text\n/openapi.json\n```\n\n```text\n.openapi()\n```\n\n```text\n.openapi()\n```\n\n```text\n.openapi_schema\n```\n\n```text\nfastapi.openapi.utils.get_openapi\n```\n\n```text\nget_openapi()\n```\n\n```text\ncomponents\n```\n\n```text\nschemas\n```\n\n```text\npop\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.116Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":15,"totalLines":137,"estimatedTokens":576}}253{"id":"stack-70051619","source":"stackoverflow","questionId":70051619,"title":"Pass on value from dependencies in include_router to routes FastAPI","tags":["python","fastapi"],"text":"Title: Pass on value from dependencies in include_router to routes FastAPI\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI was wondering if it was possible to pass the results from the `dependencies` kwarg in `include_router` to the router that is passed to it. What I want to do is decode a JWT from the `x-token` header of a request and pass the decoded payload to the `books` routes.\n\nI know that I could just write `authenticate_and_decode_JWT` as a dependency of each of the routes in routers/book.py, but this would be quite repetitive for a large app.\n\nmain.py\n\n```\nfrom typing import Optional\nfrom jose import jwt\n\nfrom fastapi import FastAPI, Depends, Header, HTTPException, status\nfrom jose.exceptions import JWTError\n\nfrom routers import books\n\napp = FastAPI()\n\ndef authenticate_and_decode_JWT(x_token: str = Header(None)):\n try:\n payload = jwt.decode(x_token.split(' ')[1], 'secret key', algorithms=['HS256'])\n return payload # pass decoded user information from here to books.router routes somehow\n except JWTError:\n raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)\n\napp.include_router(\n books.router,\n prefix=\"/books\",\n dependencies=[Depends(authenticate_and_decode_JWT)], \n)\n\n@app.get(\"/\")\ndef read_root():\n return {\"Hello\": \"World\"}\n```\n\nrouters/books.py\n\n```\nfrom fastapi import APIRouter\n\nrouter = APIRouter()\n\n@router.get('/')\ndef get_book():\n # do stuff with decoded authenticated user data from JWT payload here\n pass\n\n@router.post('/')\ndef create_book():\n # do stuff with decoded authenticated user data from JWT payload here\n pass\n```\n\n========================================\n\nTop Answer:\nFor the larger application you mentioned, You can do following things,\n\n- Write a Authentication Backend. So, you can access request.user from every route\n\n```\nclass BearerTokenAuthBackend(AuthenticationBackend):\n \"\"\"\n This is a custom auth backend class which will allow you to authenticate your request and return auth and user as\n a tuple\n \"\"\"\n async def authenticate(self, request):\n # This function is inherited from the base class and called by some other class\n if \"Authorization\" not in request.headers:\n return\n auth = request.headers[\"Authorization\"]\n try:\n scheme, token = auth.split()\n if scheme.lower() != 'bearer':\n return\n decoded = jwt.decode(\n token,\n settings.JWT_SECRET,\n algorithms=[settings.JWT_ALGORITHM],\n options={\"verify_aud\": False},\n )\n except (ValueError, UnicodeDecodeError, JWTError) as exc:\n raise AuthenticationError('Invalid JWT Token.')\n username: str = decoded.get(\"sub\")\n # QUERY FROM DATABASE/CACHE add to user\n user = None\n if user is None:\n raise AuthenticationError('Invalid JWT Token.')\n return auth, user\n```\n\n- Add the Middleware to application startup\n\n```\napp.add_middleware(AuthenticationMiddleware, backend=BearerTokenAuthBackend())\n```\n\n- You you can access `request.user`\n\n```\n@router.get('/')\ndef get_book(request: Request):\n print(request.user)\n # do stuff with decoded authenticated user data from JWT payload here\n pass\n```\n\n**I've written this hack for myself. You can suit like yours.**\n\n========================================\n\nCode:\n```py\nfrom typing import Optional\nfrom jose import jwt\n\nfrom fastapi import FastAPI, Depends, Header, HTTPException, status\nfrom jose.exceptions import JWTError\n\nfrom routers import books\n\n\napp = FastAPI()\n\ndef authenticate_and_decode_JWT(x_token: str = Header(None)):\n try:\n payload = jwt.decode(x_token.split(' ')[1], 'secret key', algorithms=['HS256'])\n return payload # pass decoded user information from here to books.router routes somehow\n except JWTError:\n raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)\n\napp.include_router(\n books.router,\n prefix=\"/books\",\n dependencies=[Depends(authenticate_and_decode_JWT)], \n)\n\n@app.get(\"/\")\ndef read_root():\n return {\"Hello\": \"World\"}\n```\n\n```py\nfrom fastapi import APIRouter\n\nrouter = APIRouter()\n\n@router.get('/')\ndef get_book():\n # do stuff with decoded authenticated user data from JWT payload here\n pass\n\n@router.post('/')\ndef create_book():\n # do stuff with decoded authenticated user data from JWT payload here\n pass\n```\n\n```text\ndependencies\n```\n\n```text\ninclude_router\n```\n\n```text\nx-token\n```\n\n```text\nbooks\n```\n\n```text\nauthenticate_and_decode_JWT\n```\n\n```text\nfrom fastapi import Request # <== new import\n\ndef authenticate_and_decode_JWT(x_token: str = Header(None), request: Request): # <== request is a new param\n try:\n payload = jwt.decode(x_token.split(' ')[1], 'secret key', algorithms=['HS256'])\n request.token_payload = payload # type: ignore # <== store the token payload in request\n return payload\n except JWTError:\n raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)\n```\n\n```text\nfrom fastapi import Request # <== new import\n\n@router.get('/', request: Request) # <== request is a new param\ndef get_book():\n # do stuff with decoded authenticated user data from JWT payload here\n print(request.token_payload) # <== access your token payload\n```\n\n```text\ninclude_router\n```\n\n```text\nauthenticate_and_decode_JWT\n```\n\n```text\nrequest\n```\n\n```text\nrequest\n```\n\n```text\nrequest\n```\n\n```py\nclass BearerTokenAuthBackend(AuthenticationBackend):\n \"\"\"\n This is a custom auth backend class which will allow you to authenticate your request and return auth and user as\n a tuple\n \"\"\"\n async def authenticate(self, request):\n # This function is inherited from the base class and called by some other class\n if \"Authorization\" not in request.headers:\n return\n auth = request.headers[\"Authorization\"]\n try:\n scheme, token = auth.split()\n if scheme.lower() != 'bearer':\n return\n decoded = jwt.decode(\n token,\n settings.JWT_SECRET,\n algorithms=[settings.JWT_ALGORITHM],\n options={\"verify_aud\": False},\n )\n except (ValueError, UnicodeDecodeError, JWTError) as exc:\n raise AuthenticationError('Invalid JWT Token.')\n username: str = decoded.get(\"sub\")\n # QUERY FROM DATABASE/CACHE add to user\n user = None\n if user is None:\n raise AuthenticationError('Invalid JWT Token.')\n return auth, user\n```\n\n```py\napp.add_middleware(AuthenticationMiddleware, backend=BearerTokenAuthBackend())\n```\n\n```py\n@router.get('/')\ndef get_book(request: Request):\n print(request.user)\n # do stuff with decoded authenticated user data from JWT payload here\n pass\n```\n\n```text\nrequest.user\n```\n\n========================================\n\nComments:\n- Related answers could be found here, as well as here and here\n- great information, as a new to FastAPI - could you please let me know, is there any document for creating custom middleware\n- You can this: stackoverflow.com/questions/71525132/…","metadata":{"transformedAt":"2026-08-18T18:32:29.116Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":18,"totalLines":277,"estimatedTokens":1731}}254{"id":"stack-68603658","source":"stackoverflow","questionId":68603658,"title":"How to terminate a Uvicorn + FastAPI application cleanly with workers >= 2 when testing with pytest","tags":["python","pytest","fastapi","uvicorn"],"text":"Title: How to terminate a Uvicorn + FastAPI application cleanly with workers >= 2 when testing with pytest\nTags: python, pytest, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI have an application written with Uvicorn + FastAPI.\nI am testing the response time using PyTest.\n\nReferring to How to start a Uvicorn + FastAPI in background when testing with PyTest, I wrote the test.\nHowever, I found the application process alive after completing the test when workers >= 2.\n\nI want to terminate the application process cleanly at the end of the test.\n\nDo you have any idea?\n\nThe details are as follows.\n\n### Environment\n\n- Windows 10\n\n- Bash 4.4.23 (https://cmder.net/)\n\n- python 3.7.5\n\n### Libraries\n\n- fastapi == 0.68.0\n\n- uvicorn == 0.14.0\n\n- requests == 2.26.0\n\n- pytest == 6.2.4\n\n### Sample Codes\n\nApplication: main.py\n\n```\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/\")\ndef hello_world():\n return \"hello world\"\n```\n\nTest: test_main.py\n\n```\nfrom multiprocessing import Process\nimport pytest\nimport requests\nimport time\nimport uvicorn\n\nHOST = \"127.0.0.1\"\nPORT = 8765\nWORKERS = 1\n\ndef run_server(host: str, port: int, workers: int, wait: int = 15) -> Process:\n proc = Process(\n target=uvicorn.run,\n args=(\"main:app\",),\n kwargs={\n \"host\": host,\n \"port\": port,\n \"workers\": workers,\n },\n )\n proc.start()\n time.sleep(wait)\n assert proc.is_alive()\n return proc\n\ndef shutdown_server(proc: Process):\n proc.terminate()\n for _ in range(5):\n if proc.is_alive():\n time.sleep(5)\n else:\n return\n else:\n raise Exception(\"Process still alive\")\n\ndef check_response(host: str, port: int):\n assert requests.get(f\"http://{host}:{port}\").text == '\"hello world\"'\n\ndef check_response_time(host: str, port: int, tol: float = 1e-2):\n s = time.time()\n requests.get(f\"http://{host}:{port}\")\n e = time.time()\n assert e-s \n\n### Execution Result\n\n```\n$ curl http://localhost:8765\ncurl: (7) Failed to connect to localhost port 8765: Connection refused\n$ pytest test_main.py\n=============== test session starts =============== platform win32 -- Python 3.7.5, pytest-6.2.4, py-1.10.0, pluggy-0.13.1\nrootdir: .\\\ncollected 1 item\n\ntest_main.py . [100%]\n\n=============== 1 passed in 20.23s ===============\n$ curl http://localhost:8765\ncurl: (7) Failed to connect to localhost port 8765: Connection refused\n$ sed -i -e \"s/WORKERS = 1/WORKERS = 3/g\" test_main.py\n$ curl http://localhost:8765\ncurl: (7) Failed to connect to localhost port 8765: Connection refused\n$ pytest test_main.py\n=============== test session starts =============== platform win32 -- Python 3.7.5, pytest-6.2.4, py-1.10.0, pluggy-0.13.1\nrootdir: .\\\ncollected 1 item\n\ntest_main.py . [100%]\n\n=============== 1 passed in 20.21s ===============\n$ curl http://localhost:8765\n\"hello world\"\n\n$ # Why is localhost:8765 still alive?\n```\n\n========================================\n\nTop Answer:\n** up of @hmasdev answer**\n\n```\nimport os\nimport fastapi\nimport uvicorn\nimport psutil\n\n @app.get(\"/quit\")\n def iquit():\n parent_pid = os.getpid()\n parent = psutil.Process(parent_pid)\n for child in parent.children(recursive=True): # or parent.children() for recursive=False\n child.kill()\n parent.kill()\n \n \n \n \n if __name__ == '__main__':\n uvicorn.run(app, port=36113, host='127.0.0.1')\n```\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/\")\ndef hello_world():\n return \"hello world\"\n```\n\n```py\nfrom multiprocessing import Process\nimport pytest\nimport requests\nimport time\nimport uvicorn\n\nHOST = \"127.0.0.1\"\nPORT = 8765\nWORKERS = 1\n\n\ndef run_server(host: str, port: int, workers: int, wait: int = 15) -> Process:\n proc = Process(\n target=uvicorn.run,\n args=(\"main:app\",),\n kwargs={\n \"host\": host,\n \"port\": port,\n \"workers\": workers,\n },\n )\n proc.start()\n time.sleep(wait)\n assert proc.is_alive()\n return proc\n\n\ndef shutdown_server(proc: Process):\n proc.terminate()\n for _ in range(5):\n if proc.is_alive():\n time.sleep(5)\n else:\n return\n else:\n raise Exception(\"Process still alive\")\n\n\ndef check_response(host: str, port: int):\n assert requests.get(f\"http://{host}:{port}\").text == '\"hello world\"'\n\n\ndef check_response_time(host: str, port: int, tol: float = 1e-2):\n s = time.time()\n requests.get(f\"http://{host}:{port}\")\n e = time.time()\n assert e-s < tol\n\n\n@pytest.fixture(scope=\"session\")\ndef server():\n proc = run_server(HOST, PORT, WORKERS)\n try:\n yield\n finally:\n shutdown_server(proc)\n\n\ndef test_main(server):\n check_response(HOST, PORT)\n check_response_time(HOST, PORT)\n check_response(HOST, PORT)\n check_response_time(HOST, PORT)\n```\n\n```sh\n$ curl http://localhost:8765\ncurl: (7) Failed to connect to localhost port 8765: Connection refused\n$ pytest test_main.py\n=============== test session starts =============== platform win32 -- Python 3.7.5, pytest-6.2.4, py-1.10.0, pluggy-0.13.1\nrootdir: .\\\ncollected 1 item\n\ntest_main.py . [100%]\n\n=============== 1 passed in 20.23s ===============\n$ curl http://localhost:8765\ncurl: (7) Failed to connect to localhost port 8765: Connection refused\n$ sed -i -e \"s/WORKERS = 1/WORKERS = 3/g\" test_main.py\n$ curl http://localhost:8765\ncurl: (7) Failed to connect to localhost port 8765: Connection refused\n$ pytest test_main.py\n=============== test session starts =============== platform win32 -- Python 3.7.5, pytest-6.2.4, py-1.10.0, pluggy-0.13.1\nrootdir: .\\\ncollected 1 item\n\ntest_main.py . [100%]\n\n=============== 1 passed in 20.21s ===============\n$ curl http://localhost:8765\n\"hello world\"\n\n$ # Why is localhost:8765 still alive?\n```\n\n```py\nfrom multiprocessing import Process\nimport psutil\nimport pytest\nimport requests\nimport time\nimport uvicorn\n\nHOST = \"127.0.0.1\"\nPORT = 8765\nWORKERS = 3\n\n\ndef run_server(host: str, port: int, workers: int, wait: int = 15) -> Process:\n proc = Process(\n target=uvicorn.run,\n args=(\"main:app\",),\n kwargs={\n \"host\": host,\n \"port\": port,\n \"workers\": workers,\n },\n )\n proc.start()\n time.sleep(wait)\n assert proc.is_alive()\n return proc\n\n\ndef shutdown_server(proc: Process):\n\n ##### SOLUTION #####\n pid = proc.pid\n parent = psutil.Process(pid)\n for child in parent.children(recursive=True):\n child.kill()\n ##### SOLUTION END ####\n\n proc.terminate()\n for _ in range(5):\n if proc.is_alive():\n time.sleep(5)\n else:\n return\n else:\n raise Exception(\"Process still alive\")\n\n\ndef check_response(host: str, port: int):\n assert requests.get(f\"http://{host}:{port}\").text == '\"hello world\"'\n\n\ndef check_response_time(host: str, port: int, tol: float = 1e-2):\n s = time.time()\n requests.get(f\"http://{host}:{port}\")\n e = time.time()\n assert e-s < tol\n\n\n@pytest.fixture(scope=\"session\")\ndef server():\n proc = run_server(HOST, PORT, WORKERS)\n try:\n yield\n finally:\n shutdown_server(proc)\n\n\ndef test_main(server):\n check_response(HOST, PORT)\n check_response_time(HOST, PORT)\n check_response(HOST, PORT)\n check_response_time(HOST, PORT)\n```\n\n```sh\n$ curl http://localhost:8765\ncurl: (7) Failed to connect to localhost port 8765: Connection refused\n$ pytest test_main.py\n================== test session starts ================== platform win32 -- Python 3.7.5, pytest-6.2.4, py-1.10.0, pluggy-0.13.1\nrootdir: .\\\ncollected 1 item\n\ntest_main.py . [100%]\n\n================== 1 passed in 20.24s ==================\n$ curl http://localhost:8765\ncurl: (7) Failed to connect to localhost port 8765: Connection refused\n```\n\n```text\npip install psutil\n```\n\n```text\nimport os\nimport fastapi\nimport uvicorn\nimport psutil\n\n @app.get(\"/quit\")\n def iquit():\n parent_pid = os.getpid()\n parent = psutil.Process(parent_pid)\n for child in parent.children(recursive=True): # or parent.children() for recursive=False\n child.kill()\n parent.kill()\n \n \n \n \n if __name__ == '__main__':\n uvicorn.run(app, port=36113, host='127.0.0.1')\n```\n\n========================================\n\nComments:\n- This is a related version of stackoverflow.com/q/61577643/4165272 issue.\n- I use **sys.exit(4)**. Here are the details: stackoverflow.com/a/74117959/1689733\n- I use **sys.exit(4)** Here are more details\n- TypeError: cannot pickle '_io.TextIOWrapper' object\n- @WolfgangFahl thanks comment. May I ask you two questions? 1. in which environment did you try the solution? 2. where was the error raised? In my environment, which is written above, my solution still works.\n- 1. MacOS. 2. justpy CI tests\n- Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.","metadata":{"transformedAt":"2026-08-18T18:32:29.116Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":7,"totalLines":388,"estimatedTokens":2404}}255{"id":"stack-63830284","source":"stackoverflow","questionId":63830284,"title":"FastAPI and Pydantic RecursionError Causing Exception in ASGI application","tags":["python","fastapi","pydantic","uvicorn"],"text":"Title: FastAPI and Pydantic RecursionError Causing Exception in ASGI application\nTags: python, fastapi, pydantic, uvicorn\nSource: Stack Overflow\n\nQuestion:\n### Description\n\nI've seen similar issues about self-referencing Pydantic models causing `RecursionError: maximum recursion depth exceeded in comparison` but as far as I can tell there are no self-referencing models included in the code. I'm just just using Pydantic's `BaseModel` class.\n\nThe code runs successfully until the function in `audit.py` below tries to return the output from the model.\n\nI've included the full traceback as I'm not sure where to begin with this error. I've run the code with PyCharm and without an IDE and it always produces the traceback below but doesn't crash the app but returns a http status code of 500 to the front end.\n\nAny advice would be much appreciated.\n\nAs suggested I have also tried `sys.setrecursionlimit(1500)` to increase the recursion limit.\n\n### Environment\n\n- OS: Windows 10\n\n- FastAPI Version: 0.61.1\n\n- Pydantic Version: 1.6.1\n\n- Uvicorn Version: 0.11.8\n\n- Python Version: 3.7.1\n\n- Pycharm Version: 2020.2\n\n### App\n\n`main.py`\n\n```\nimport uvicorn\nfrom fastapi import FastAPI\nfrom starlette.middleware.cors import CORSMiddleware\n\nfrom app.api.routes.router import api_router\nfrom app.core.logging import init_logging\nfrom app.core.config import settings\n\ninit_logging()\n\ndef get_app() -> FastAPI:\n application = FastAPI(title=settings.APP_NAME, version=settings.APP_VERSION, debug=settings.DEBUG)\n\n if settings.BACKEND_CORS_ORIGINS:\n # middleware support for cors\n application.add_middleware(\n CORSMiddleware,\n allow_origins=[str(origin) for origin in settings.BACKEND_CORS_ORIGINS],\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n )\n application.include_router(api_router, prefix=settings.API_V1_STR)\n return application\n\napp = get_app()\n\nif __name__ == \"__main__\":\n uvicorn.run(\"main:app\", host=\"127.0.0.1\", port=80)\n```\n\n`router.py`\n\n```\nfrom fastapi import APIRouter\n\nfrom app.api.routes import audit\n\napi_router = APIRouter()\napi_router.include_router(audit.router, tags=[\"audit\"], prefix=\"/audit\")\n```\n\n`audit.py`\n\n```\nimport validators\nfrom fastapi import APIRouter, HTTPException\nfrom loguru import logger\n\nfrom app.api.dependencies.audit import analyzer\nfrom app.schemas.audit import AuditPayload, AuditResult\n\nrouter = APIRouter()\n\n@router.post(\"/\", response_model=AuditResult, name=\"audit\", status_code=200)\nasync def post_audit(payload: AuditPayload) -> AuditResult:\n logger.info(\"Audit request received\")\n # validate URL\n try:\n logger.info(\"Validating URL\")\n validators.url(payload.url)\n except HTTPException:\n HTTPException(status_code=404, detail=\"Invalid URL.\")\n logger.exception(\"HTTPException - Invalid URL\")\n\n # generate output from route audit.py\n logger.info(\"Running audit analysis. This could take up to 10 minutes. Maybe grab a coffee...\")\n analyzed_output = analyzer.analyze(url=payload.url,\n brand=payload.brand,\n twitter_screen_name=payload.twitter_screen_name,\n facebook_page_name=payload.facebook_page_name,\n instagram_screen_name=payload.instagram_screen_name,\n youtube_user_name=payload.youtube_user_name,\n ignore_robots=payload.ignore_robots,\n ignore_sitemap=payload.ignore_sitemap,\n google_analytics_view_id=payload.google_analytics_view_id)\n output = AuditResult(**analyzed_output)\n return output\n```\n\n`audit_models.py`\n\n```\nfrom pydantic import BaseModel\n\nclass AuditPayload(BaseModel):\n url: str\n brand: str\n twitter_screen_name: str\n facebook_page_name: str\n instagram_screen_name: str\n youtube_user_name: str\n ignore_robots: bool\n ignore_sitemap: bool\n google_analytics_view_id: str\n\nclass AuditResult(BaseModel):\n base_url: str\n run_time: float\n website_404: dict\n website_302: dict\n website_h1_tags: dict\n website_duplicate_h1: dict\n website_h2_tags: dict\n website_page_duplications: dict\n website_page_similarities: dict\n website_page_desc_duplications: dict\n website_page_title_duplications: dict\n pages: list\n pages_out_links_404: dict = None\n pages_canonicals: dict\n seo_phrases: dict\n social: dict\n google_analytics_report: dict\n google_psi_desktop: dict\n google_psi_mobile: dict\n google_algo_updates: dict\n google_sb: list\n robots_txt: list\n```\n\nThis line throws the error in the logs:\n2020-09-10 10:02:31.483 | ERROR | uvicorn.protocols.http.h11_impl:run_asgi:391 - Exception in ASGI application\n\nI believe this bit is the most relevant to understanding why this error is occuring:\n\n```\nFile \"pydantic\\main.py\", line 623, in pydantic.main.BaseModel._get_value\n [Previous line repeated 722 more times]\n```\n\nFull traceback:\n\n```\nTraceback (most recent call last):\n File \"C:\\Users\\\\AppData\\Local\\JetBrains\\Toolbox\\apps\\PyCharm-P\\ch-0\\202.6948.78\\plugins\\python\\helpers\\pydev\\pydevconsole.py\", line 483, in \n pydevconsole.start_client(host, port)\n │ │ │ └ 50488\n │ │ └ '127.0.0.1'\n │ └ \n └ \\\\AppData\\\\Local\\\\JetBrains\\\\Toolbox\\\\apps\\\\PyCharm-P\\\\ch-0\\\\202.6948.78\\\\pl...\n File \"C:\\Users\\\\AppData\\Local\\JetBrains\\Toolbox\\apps\\PyCharm-P\\ch-0\\202.6948.78\\plugins\\python\\helpers\\pydev\\pydevconsole.py\", line 411, in start_client\n process_exec_queue(interpreter)\n │ └ \n └ \n File \"C:\\Users\\\\AppData\\Local\\JetBrains\\Toolbox\\apps\\PyCharm-P\\ch-0\\202.6948.78\\plugins\\python\\helpers\\pydev\\pydevconsole.py\", line 258, in process_exec_queue\n more = interpreter.add_exec(code_fragment)\n │ │ └ \n │ └ \n └ \n File \"C:\\Users\\\\AppData\\Local\\JetBrains\\Toolbox\\apps\\PyCharm-P\\ch-0\\202.6948.78\\plugins\\python\\helpers\\pydev\\_pydev_bundle\\pydev_code_executor.py\", line 106, in add_exec\n more = self.do_add_exec(code_fragment)\n │ │ └ \n │ └ \n └ \n File \"C:\\Users\\\\AppData\\Local\\JetBrains\\Toolbox\\apps\\PyCharm-P\\ch-0\\202.6948.78\\plugins\\python\\helpers\\pydev\\_pydev_bundle\\pydev_ipython_console.py\", line 36, in do_add_exec\n res = bool(self.interpreter.add_exec(code_fragment.text))\n │ │ │ │ └ \"runfile('E:/Users//Documents/GitHub/HawkSense/backend/app/app/main.py', wdir='E:/Users//Docume...\n │ │ │ └ \n │ │ └ \n │ └ \n └ \n File \"C:\\Users\\\\AppData\\Local\\JetBrains\\Toolbox\\apps\\PyCharm-P\\ch-0\\202.6948.78\\plugins\\python\\helpers\\pydev\\_pydev_bundle\\pydev_ipython_console_011.py\", line 483, in add_exec\n self.ipython.run_cell(line, store_history=True)\n │ │ │ └ \"runfile('E:/Users//Documents/GitHub/HawkSense/backend/app/app/main.py', wdir='E:/Users//Docume...\n │ │ └ \n │ └ \n └ \n File \"C:\\Program Files\\Python37\\lib\\site-packages\\IPython\\core\\interactiveshell.py\", line 2843, in run_cell\n raw_cell, store_history, silent, shell_futures)\n │ │ │ └ True\n │ │ └ False\n │ └ True\n └ \"runfile('E:/Users//Documents/GitHub/HawkSense/backend/app/app/main.py', wdir='E:/Users//Docume...\n File \"C:\\Program Files\\Python37\\lib\\site-packages\\IPython\\core\\interactiveshell.py\", line 2869, in _run_cell\n return runner(coro)\n │ └ \n └ \n File \"C:\\Program Files\\Python37\\lib\\site-packages\\IPython\\core\\async_helpers.py\", line 67, in _pseudo_sync_runner\n coro.send(None)\n │ └ \n └ \n File \"C:\\Program Files\\Python37\\lib\\site-packages\\IPython\\core\\interactiveshell.py\", line 3044, in run_cell_async\n interactivity=interactivity, compiler=compiler, result=result)\n │ │ └ \n └ 'last_expr'\n File \"C:\\Program Files\\Python37\\lib\\site-packages\\IPython\\core\\interactiveshell.py\", line 3215, in run_ast_nodes\n if (yield from self.run_code(code, result)):\n │ │ │ └ at 0x000001BCEDCDADB0, file \"\", line 1>\n │ └ \n └ \n File \"C:\\Program Files\\Python37\\lib\\site-packages\\IPython\\core\\interactiveshell.py\", line 3291, in run_code\n exec(code_obj, self.user_global_ns, self.user_ns)\n │ │ │ │ └ {'__name__': 'pydev_umd', '__doc__': 'Automatically created module for IPython interactive environment', '__package__': None,...\n │ │ │ └ \n │ │ └ \n │ └ \n └ at 0x000001BCEDCDADB0, file \"\", line 1>\n File \"\", line 1, in \n runfile('E:/Users//Documents/GitHub/HawkSense/backend/app/app/main.py', wdir='E:/Users//Documents/GitHub/HawkSense/backend/app/app')\n File \"C:\\Users\\\\AppData\\Local\\JetBrains\\Toolbox\\apps\\PyCharm-P\\ch-0\\202.6948.78\\plugins\\python\\helpers\\pydev\\_pydev_bundle\\pydev_umd.py\", line 197, in runfile\n pydev_imports.execfile(filename, global_vars, local_vars) # execute the script\n │ │ │ │ └ {'__name__': '__main__', '__doc__': \"\\nMain entry point into API for endpoints related to HawkSense's main functionality.\\nto...\n │ │ │ └ {'__name__': '__main__', '__doc__': \"\\nMain entry point into API for endpoints related to HawkSense's main functionality.\\nto...\n │ │ └ 'E:/Users//Documents/GitHub/HawkSense/backend/app/app/main.py'\n │ └ \n └ \\\\AppData\\\\Local\\\\JetBrains\\\\Toolbox\\\\apps\\\\PyCharm-P\\\\ch-0\\\\...\n File \"C:\\Users\\\\AppData\\Local\\JetBrains\\Toolbox\\apps\\PyCharm-P\\ch-0\\202.6948.78\\plugins\\python\\helpers\\pydev\\_pydev_imps\\_pydev_execfile.py\", line 18, in execfile\n exec(compile(contents+\"\\n\", file, 'exec'), glob, loc)\n │ │ │ └ {'__name__': '__main__', '__doc__': \"\\nMain entry point into API for endpoints related to HawkSense's main functionality.\\nto...\n │ │ └ {'__name__': '__main__', '__doc__': \"\\nMain entry point into API for endpoints related to HawkSense's main functionality.\\nto...\n │ └ 'E:/Users//Documents/GitHub/HawkSense/backend/app/app/main.py'\n └ '#!/usr/bin/env python\\n\\n\"\"\"\\nMain entry point into API for endpoints related to HawkSense\\'s main functionality.\\ntodo: htt...\n File \"E:/Users//Documents/GitHub/HawkSense/backend/app/app\\main.py\", line 47, in \n uvicorn.run(\"main:app\", host=\"127.0.0.1\", port=80) # for debug only\n │ └ \n └ \n File \"C:\\Program Files\\Python37\\lib\\site-packages\\uvicorn\\main.py\", line 362, in run\n server.run()\n │ └ \n └ \n File \"C:\\Program Files\\Python37\\lib\\site-packages\\uvicorn\\main.py\", line 390, in run\n loop.run_until_complete(self.serve(sockets=sockets))\n │ │ │ │ └ None\n │ │ │ └ \n │ │ └ \n │ └ \n └ \n File \"C:\\Program Files\\Python37\\lib\\asyncio\\base_events.py\", line 560, in run_until_complete\n self.run_forever()\n │ └ \n └ \n File \"C:\\Program Files\\Python37\\lib\\asyncio\\base_events.py\", line 528, in run_forever\n self._run_once()\n │ └ \n └ \n File \"C:\\Program Files\\Python37\\lib\\asyncio\\base_events.py\", line 1764, in _run_once\n handle._run()\n │ └ \n └ ()>\n File \"C:\\Program Files\\Python37\\lib\\asyncio\\events.py\", line 88, in _run\n self._context.run(self._callback, *self._args)\n │ │ │ │ │ └ \n │ │ │ │ └ ()>\n │ │ │ └ \n │ │ └ ()>\n │ └ \n └ ()>\n> File \"C:\\Program Files\\Python37\\lib\\site-packages\\uvicorn\\protocols\\http\\h11_impl.py\", line 388, in run_asgi\n result = await app(self.scope, self.receive, self.send)\n │ │ │ │ │ │ └ \n │ │ │ │ │ └ \n │ │ │ │ └ \n │ │ │ └ \n │ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.1'}, 'http_version': '1.1', 'server': ('127.0.0.1', 80), 'clie...\n │ └ \n └ \n File \"C:\\Program Files\\Python37\\lib\\site-packages\\uvicorn\\middleware\\proxy_headers.py\", line 45, in __call__\n return await self.app(scope, receive, send)\n │ │ │ │ └ >\n │ │ │ └ \n └ \n File \"C:\\Program Files\\Python37\\lib\\site-packages\\fastapi\\applications.py\", line 149, in __call__\n await super().__call__(scope, receive, send)\n │ │ └ >\n │ └ >\n │ │ │ └ \n └ \n File \"C:\\Program Files\\Python37\\lib\\site-packages\\starlette\\middleware\\errors.py\", line 181, in __call__\n raise exc from None\n File \"C:\\Program Files\\Python37\\lib\\site-packages\\starlette\\middleware\\errors.py\", line 159, in __call__\n await self.app(scope, receive, _send)\n │ │ │ │ └ ._send at 0x000001BCFC72AE18>\n │ │ │ └ \n └ \n File \"C:\\Program Files\\Python37\\lib\\site-packages\\starlette\\middleware\\cors.py\", line 84, in __call__\n await self.simple_response(scope, receive, send, request_headers=headers)\n │ │ │ │ │ └ Headers({'host': '127.0.0.1', 'connection': 'keep-alive', 'content-length': '295', 'accept': 'application/json', 'user-agent'...\n │ │ │ │ └ ._send at 0x000001BCFC72AE18>\n │ │ │ └ \n └ \n File \"C:\\Program Files\\Python37\\lib\\site-packages\\starlette\\middleware\\cors.py\", line 140, in simple_response\n await self.app(scope, receive, send)\n │ │ │ │ └ functools.partial(\n └ \n File \"C:\\Program Files\\Python37\\lib\\site-packages\\starlette\\exceptions.py\", line 82, in __call__\n raise exc from None\n File \"C:\\Program Files\\Python37\\lib\\site-packages\\starlette\\exceptions.py\", line 71, in __call__\n await self.app(scope, receive, sender)\n │ │ │ │ └ .sender at 0x000001BCFC7C18C8>\n │ │ │ └ \n └ \n File \"C:\\Program Files\\Python37\\lib\\site-packages\\starlette\\routing.py\", line 550, in __call__\n await route.handle(scope, receive, send)\n │ │ │ │ └ .sender at 0x000001BCFC7C18C8>\n │ │ │ └ \n └ \n File \"C:\\Program Files\\Python37\\lib\\site-packages\\starlette\\routing.py\", line 227, in handle\n await self.app(scope, receive, send)\n │ │ │ │ └ .sender at 0x000001BCFC7C18C8>\n │ │ │ └ .app at 0x000001BCFC7C1A60>\n └ \n File \"C:\\Program Files\\Python37\\lib\\site-packages\\starlette\\routing.py\", line 41, in app\n response = await func(request)\n │ └ \n └ .app at 0x000001BCFC7C19D8>\n File \"C:\\Program Files\\Python37\\lib\\site-packages\\fastapi\\routing.py\", line 213, in app\n is_coroutine=is_coroutine,\n └ True\n File \"C:\\Program Files\\Python37\\lib\\site-packages\\fastapi\\routing.py\", line 113, in serialize_response\n exclude_none=exclude_none,\n └ False\n File \"C:\\Program Files\\Python37\\lib\\site-packages\\fastapi\\routing.py\", line 65, in _prepare_response_content\n exclude_none=exclude_none,\n └ False\n File \"pydantic\\main.py\", line 386, in pydantic.main.BaseModel.dict\n File \"pydantic\\main.py\", line 706, in _iter\n File \"pydantic\\main.py\", line 623, in pydantic.main.BaseModel._get_value\n File \"pydantic\\main.py\", line 623, in pydantic.main.BaseModel._get_value\n File \"pydantic\\main.py\", line 623, in pydantic.main.BaseModel._get_value\n [Previous line repeated 722 more times]\n File \"pydantic\\main.py\", line 605, in pydantic.main.BaseModel._get_value\n File \"C:\\Program Files\\Python37\\lib\\abc.py\", line 139, in __instancecheck__\n return _abc_instancecheck(cls, instance)\n │ │ └ 8\n │ └ \n └ \nRecursionError: maximum recursion depth exceeded in comparison```\n```\n\n========================================\n\nTop Answer:\nIn my own case, I was referencing a cache key from Redis that hadn't been created yet.\n\n========================================\n\nCode:\n```py\nimport uvicorn\nfrom fastapi import FastAPI\nfrom starlette.middleware.cors import CORSMiddleware\n\n\nfrom app.api.routes.router import api_router\nfrom app.core.logging import init_logging\nfrom app.core.config import settings\n\ninit_logging()\n\n\ndef get_app() -> FastAPI:\n application = FastAPI(title=settings.APP_NAME, version=settings.APP_VERSION, debug=settings.DEBUG)\n\n if settings.BACKEND_CORS_ORIGINS:\n # middleware support for cors\n application.add_middleware(\n CORSMiddleware,\n allow_origins=[str(origin) for origin in settings.BACKEND_CORS_ORIGINS],\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n )\n application.include_router(api_router, prefix=settings.API_V1_STR)\n return application\n\n\napp = get_app()\n\nif __name__ == \"__main__\":\n uvicorn.run(\"main:app\", host=\"127.0.0.1\", port=80)\n```\n\n```py\nfrom fastapi import APIRouter\n\nfrom app.api.routes import audit\n\napi_router = APIRouter()\napi_router.include_router(audit.router, tags=[\"audit\"], prefix=\"/audit\")\n```\n\n```py\nimport validators\nfrom fastapi import APIRouter, HTTPException\nfrom loguru import logger\n\nfrom app.api.dependencies.audit import analyzer\nfrom app.schemas.audit import AuditPayload, AuditResult\n\nrouter = APIRouter()\n\n\n@router.post(\"/\", response_model=AuditResult, name=\"audit\", status_code=200)\nasync def post_audit(payload: AuditPayload) -> AuditResult:\n logger.info(\"Audit request received\")\n # validate URL\n try:\n logger.info(\"Validating URL\")\n validators.url(payload.url)\n except HTTPException:\n HTTPException(status_code=404, detail=\"Invalid URL.\")\n logger.exception(\"HTTPException - Invalid URL\")\n\n # generate output from route audit.py\n logger.info(\"Running audit analysis. This could take up to 10 minutes. Maybe grab a coffee...\")\n analyzed_output = analyzer.analyze(url=payload.url,\n brand=payload.brand,\n twitter_screen_name=payload.twitter_screen_name,\n facebook_page_name=payload.facebook_page_name,\n instagram_screen_name=payload.instagram_screen_name,\n youtube_user_name=payload.youtube_user_name,\n ignore_robots=payload.ignore_robots,\n ignore_sitemap=payload.ignore_sitemap,\n google_analytics_view_id=payload.google_analytics_view_id)\n output = AuditResult(**analyzed_output)\n return output\n```\n\n```py\nfrom pydantic import BaseModel\n\n\nclass AuditPayload(BaseModel):\n url: str\n brand: str\n twitter_screen_name: str\n facebook_page_name: str\n instagram_screen_name: str\n youtube_user_name: str\n ignore_robots: bool\n ignore_sitemap: bool\n google_analytics_view_id: str\n\n\nclass AuditResult(BaseModel):\n base_url: str\n run_time: float\n website_404: dict\n website_302: dict\n website_h1_tags: dict\n website_duplicate_h1: dict\n website_h2_tags: dict\n website_page_duplications: dict\n website_page_similarities: dict\n website_page_desc_duplications: dict\n website_page_title_duplications: dict\n pages: list\n pages_out_links_404: dict = None\n pages_canonicals: dict\n seo_phrases: dict\n social: dict\n google_analytics_report: dict\n google_psi_desktop: dict\n google_psi_mobile: dict\n google_algo_updates: dict\n google_sb: list\n robots_txt: list\n```\n\n```text\nFile \"pydantic\\main.py\", line 623, in pydantic.main.BaseModel._get_value\n [Previous line repeated 722 more times]\n```\n\n```py\nTraceback (most recent call last):\n File \"C:\\Users\\<user>\\AppData\\Local\\JetBrains\\Toolbox\\apps\\PyCharm-P\\ch-0\\202.6948.78\\plugins\\python\\helpers\\pydev\\pydevconsole.py\", line 483, in <module>\n pydevconsole.start_client(host, port)\n │ │ │ └ 50488\n │ │ └ '127.0.0.1'\n │ └ <function start_client at 0x000001BCEDC19D08>\n └ <module 'pydevconsole' from 'C:\\\\Users\\\\<user>\\\\AppData\\\\Local\\\\JetBrains\\\\Toolbox\\\\apps\\\\PyCharm-P\\\\ch-0\\\\202.6948.78\\\\pl...\n File \"C:\\Users\\<user>\\AppData\\Local\\JetBrains\\Toolbox\\apps\\PyCharm-P\\ch-0\\202.6948.78\\plugins\\python\\helpers\\pydev\\pydevconsole.py\", line 411, in start_client\n process_exec_queue(interpreter)\n │ └ <_pydev_bundle.pydev_ipython_console.InterpreterInterface object at 0x000001BCEDC1BF98>\n └ <function process_exec_queue at 0x000001BCEDC19A60>\n File \"C:\\Users\\<user>\\AppData\\Local\\JetBrains\\Toolbox\\apps\\PyCharm-P\\ch-0\\202.6948.78\\plugins\\python\\helpers\\pydev\\pydevconsole.py\", line 258, in process_exec_queue\n more = interpreter.add_exec(code_fragment)\n │ │ └ <_pydev_bundle.pydev_console_types.CodeFragment object at 0x000001BCEDCFE748>\n │ └ <function BaseCodeExecutor.add_exec at 0x000001BCECF38488>\n └ <_pydev_bundle.pydev_ipython_console.InterpreterInterface object at 0x000001BCEDC1BF98>\n File \"C:\\Users\\<user>\\AppData\\Local\\JetBrains\\Toolbox\\apps\\PyCharm-P\\ch-0\\202.6948.78\\plugins\\python\\helpers\\pydev\\_pydev_bundle\\pydev_code_executor.py\", line 106, in add_exec\n more = self.do_add_exec(code_fragment)\n │ │ └ <_pydev_bundle.pydev_console_types.CodeFragment object at 0x000001BCEDCFE748>\n │ └ <function InterpreterInterface.do_add_exec at 0x000001BCEDC15D90>\n └ <_pydev_bundle.pydev_ipython_console.InterpreterInterface object at 0x000001BCEDC1BF98>\n File \"C:\\Users\\<user>\\AppData\\Local\\JetBrains\\Toolbox\\apps\\PyCharm-P\\ch-0\\202.6948.78\\plugins\\python\\helpers\\pydev\\_pydev_bundle\\pydev_ipython_console.py\", line 36, in do_add_exec\n res = bool(self.interpreter.add_exec(code_fragment.text))\n │ │ │ │ └ \"runfile('E:/Users/<user>/Documents/GitHub/HawkSense/backend/app/app/main.py', wdir='E:/Users/<user>/Docume...\n │ │ │ └ <_pydev_bundle.pydev_console_types.CodeFragment object at 0x000001BCEDCFE748>\n │ │ └ <function _PyDevFrontEnd.add_exec at 0x000001BCEDC15A60>\n │ └ <_pydev_bundle.pydev_ipython_console_011._PyDevFrontEnd object at 0x000001BCEDC350B8>\n └ <_pydev_bundle.pydev_ipython_console.InterpreterInterface object at 0x000001BCEDC1BF98>\n File \"C:\\Users\\<user>\\AppData\\Local\\JetBrains\\Toolbox\\apps\\PyCharm-P\\ch-0\\202.6948.78\\plugins\\python\\helpers\\pydev\\_pydev_bundle\\pydev_ipython_console_011.py\", line 483, in add_exec\n self.ipython.run_cell(line, store_history=True)\n │ │ │ └ \"runfile('E:/Users/<user>/Documents/GitHub/HawkSense/backend/app/app/main.py', wdir='E:/Users/<user>/Docume...\n │ │ └ <function InteractiveShell.run_cell at 0x000001BCED5E7268>\n │ └ <_pydev_bundle.pydev_ipython_console_011.PyDevTerminalInteractiveShell object at 0x000001BCEDC350F0>\n └ <_pydev_bundle.pydev_ipython_console_011._PyDevFrontEnd object at 0x000001BCEDC350B8>\n File \"C:\\Program Files\\Python37\\lib\\site-packages\\IPython\\core\\interactiveshell.py\", line 2843, in run_cell\n raw_cell, store_history, silent, shell_futures)\n │ │ │ └ True\n │ │ └ False\n │ └ True\n └ \"runfile('E:/Users/<user>/Documents/GitHub/HawkSense/backend/app/app/main.py', wdir='E:/Users/<user>/Docume...\n File \"C:\\Program Files\\Python37\\lib\\site-packages\\IPython\\core\\interactiveshell.py\", line 2869, in _run_cell\n return runner(coro)\n │ └ <generator object InteractiveShell.run_cell_async at 0x000001BCEDC49C78>\n └ <function _pseudo_sync_runner at 0x000001BCED5D0C80>\n File \"C:\\Program Files\\Python37\\lib\\site-packages\\IPython\\core\\async_helpers.py\", line 67, in _pseudo_sync_runner\n coro.send(None)\n │ └ <method 'send' of 'generator' objects>\n └ <generator object InteractiveShell.run_cell_async at 0x000001BCEDC49C78>\n File \"C:\\Program Files\\Python37\\lib\\site-packages\\IPython\\core\\interactiveshell.py\", line 3044, in run_cell_async\n interactivity=interactivity, compiler=compiler, result=result)\n │ │ └ <ExecutionResult object at 1bcedcd3470, execution_count=2 error_before_exec=None error_in_exec=None info=<ExecutionInfo objec...\n │ └ <IPython.core.compilerop.CachingCompiler object at 0x000001BCEDC356D8>\n └ 'last_expr'\n File \"C:\\Program Files\\Python37\\lib\\site-packages\\IPython\\core\\interactiveshell.py\", line 3215, in run_ast_nodes\n if (yield from self.run_code(code, result)):\n │ │ │ └ <ExecutionResult object at 1bcedcd3470, execution_count=2 error_before_exec=None error_in_exec=None info=<ExecutionInfo objec...\n │ │ └ <code object <module> at 0x000001BCEDCDADB0, file \"<ipython-input-2-086756a0f1dd>\", line 1>\n │ └ <function InteractiveShell.run_code at 0x000001BCED5E76A8>\n └ <_pydev_bundle.pydev_ipython_console_011.PyDevTerminalInteractiveShell object at 0x000001BCEDC350F0>\n File \"C:\\Program Files\\Python37\\lib\\site-packages\\IPython\\core\\interactiveshell.py\", line 3291, in run_code\n exec(code_obj, self.user_global_ns, self.user_ns)\n │ │ │ │ └ {'__name__': 'pydev_umd', '__doc__': 'Automatically created module for IPython interactive environment', '__package__': None,...\n │ │ │ └ <_pydev_bundle.pydev_ipython_console_011.PyDevTerminalInteractiveShell object at 0x000001BCEDC350F0>\n │ │ └ <property object at 0x000001BCED5D8958>\n │ └ <_pydev_bundle.pydev_ipython_console_011.PyDevTerminalInteractiveShell object at 0x000001BCEDC350F0>\n └ <code object <module> at 0x000001BCEDCDADB0, file \"<ipython-input-2-086756a0f1dd>\", line 1>\n File \"<ipython-input-2-086756a0f1dd>\", line 1, in <module>\n runfile('E:/Users/<user>/Documents/GitHub/HawkSense/backend/app/app/main.py', wdir='E:/Users/<user>/Documents/GitHub/HawkSense/backend/app/app')\n File \"C:\\Users\\<user>\\AppData\\Local\\JetBrains\\Toolbox\\apps\\PyCharm-P\\ch-0\\202.6948.78\\plugins\\python\\helpers\\pydev\\_pydev_bundle\\pydev_umd.py\", line 197, in runfile\n pydev_imports.execfile(filename, global_vars, local_vars) # execute the script\n │ │ │ │ └ {'__name__': '__main__', '__doc__': \"\\nMain entry point into API for endpoints related to HawkSense's main functionality.\\nto...\n │ │ │ └ {'__name__': '__main__', '__doc__': \"\\nMain entry point into API for endpoints related to HawkSense's main functionality.\\nto...\n │ │ └ 'E:/Users/<user>/Documents/GitHub/HawkSense/backend/app/app/main.py'\n │ └ <function execfile at 0x000001BCECC521E0>\n └ <module '_pydev_bundle.pydev_imports' from 'C:\\\\Users\\\\<user>\\\\AppData\\\\Local\\\\JetBrains\\\\Toolbox\\\\apps\\\\PyCharm-P\\\\ch-0\\\\...\n File \"C:\\Users\\<user>\\AppData\\Local\\JetBrains\\Toolbox\\apps\\PyCharm-P\\ch-0\\202.6948.78\\plugins\\python\\helpers\\pydev\\_pydev_imps\\_pydev_execfile.py\", line 18, in execfile\n exec(compile(contents+\"\\n\", file, 'exec'), glob, loc)\n │ │ │ └ {'__name__': '__main__', '__doc__': \"\\nMain entry point into API for endpoints related to HawkSense's main functionality.\\nto...\n │ │ └ {'__name__': '__main__', '__doc__': \"\\nMain entry point into API for endpoints related to HawkSense's main functionality.\\nto...\n │ └ 'E:/Users/<user>/Documents/GitHub/HawkSense/backend/app/app/main.py'\n └ '#!/usr/bin/env python\\n\\n\"\"\"\\nMain entry point into API for endpoints related to HawkSense\\'s main functionality.\\ntodo: htt...\n File \"E:/Users/<user>/Documents/GitHub/HawkSense/backend/app/app\\main.py\", line 47, in <module>\n uvicorn.run(\"main:app\", host=\"127.0.0.1\", port=80) # for debug only\n │ └ <function run at 0x000001BCEDE041E0>\n └ <module 'uvicorn' from 'C:\\\\Program Files\\\\Python37\\\\lib\\\\site-packages\\\\uvicorn\\\\__init__.py'>\n File \"C:\\Program Files\\Python37\\lib\\site-packages\\uvicorn\\main.py\", line 362, in run\n server.run()\n │ └ <function Server.run at 0x000001BCEDE4B510>\n └ <uvicorn.main.Server object at 0x000001BCFC722198>\n File \"C:\\Program Files\\Python37\\lib\\site-packages\\uvicorn\\main.py\", line 390, in run\n loop.run_until_complete(self.serve(sockets=sockets))\n │ │ │ │ └ None\n │ │ │ └ <function Server.serve at 0x000001BCEDE4B598>\n │ │ └ <uvicorn.main.Server object at 0x000001BCFC722198>\n │ └ <function BaseEventLoop.run_until_complete at 0x000001BCED49FE18>\n └ <_WindowsSelectorEventLoop running=True closed=False debug=False>\n File \"C:\\Program Files\\Python37\\lib\\asyncio\\base_events.py\", line 560, in run_until_complete\n self.run_forever()\n │ └ <function BaseEventLoop.run_forever at 0x000001BCED49FD90>\n └ <_WindowsSelectorEventLoop running=True closed=False debug=False>\n File \"C:\\Program Files\\Python37\\lib\\asyncio\\base_events.py\", line 528, in run_forever\n self._run_once()\n │ └ <function BaseEventLoop._run_once at 0x000001BCED4A27B8>\n └ <_WindowsSelectorEventLoop running=True closed=False debug=False>\n File \"C:\\Program Files\\Python37\\lib\\asyncio\\base_events.py\", line 1764, in _run_once\n handle._run()\n │ └ <function Handle._run at 0x000001BCED43AB70>\n └ <Handle <TaskStepMethWrapper object at 0x000001BCFC7D4B00>()>\n File \"C:\\Program Files\\Python37\\lib\\asyncio\\events.py\", line 88, in _run\n self._context.run(self._callback, *self._args)\n │ │ │ │ │ └ <member '_args' of 'Handle' objects>\n │ │ │ │ └ <Handle <TaskStepMethWrapper object at 0x000001BCFC7D4B00>()>\n │ │ │ └ <member '_callback' of 'Handle' objects>\n │ │ └ <Handle <TaskStepMethWrapper object at 0x000001BCFC7D4B00>()>\n │ └ <member '_context' of 'Handle' objects>\n └ <Handle <TaskStepMethWrapper object at 0x000001BCFC7D4B00>()>\n> File \"C:\\Program Files\\Python37\\lib\\site-packages\\uvicorn\\protocols\\http\\h11_impl.py\", line 388, in run_asgi\n result = await app(self.scope, self.receive, self.send)\n │ │ │ │ │ │ └ <function RequestResponseCycle.send at 0x000001BCFC757840>\n │ │ │ │ │ └ <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x000001BCFC7D4A90>\n │ │ │ │ └ <function RequestResponseCycle.receive at 0x000001BCFC7578C8>\n │ │ │ └ <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x000001BCFC7D4A90>\n │ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.1'}, 'http_version': '1.1', 'server': ('127.0.0.1', 80), 'clie...\n │ └ <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x000001BCFC7D4A90>\n └ <uvicorn.middleware.proxy_headers.ProxyHeadersMiddleware object at 0x000001BCFC722BA8>\n File \"C:\\Program Files\\Python37\\lib\\site-packages\\uvicorn\\middleware\\proxy_headers.py\", line 45, in __call__\n return await self.app(scope, receive, send)\n │ │ │ │ └ <bound method RequestResponseCycle.send of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x000001BCFC7D4A90>>\n │ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x000001BCFC7D4...\n │ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.1'}, 'http_version': '1.1', 'server': ('127.0.0.1', 80), 'clie...\n │ └ <fastapi.applications.FastAPI object at 0x000001BCFC722710>\n └ <uvicorn.middleware.proxy_headers.ProxyHeadersMiddleware object at 0x000001BCFC722BA8>\n File \"C:\\Program Files\\Python37\\lib\\site-packages\\fastapi\\applications.py\", line 149, in __call__\n await super().__call__(scope, receive, send)\n │ │ └ <bound method RequestResponseCycle.send of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x000001BCFC7D4A90>>\n │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x000001BCFC7D4...\n └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.1'}, 'http_version': '1.1', 'server': ('127.0.0.1', 80), 'clie...\n File \"C:\\Program Files\\Python37\\lib\\site-packages\\starlette\\applications.py\", line 102, in __call__\n await self.middleware_stack(scope, receive, send)\n │ │ │ │ └ <bound method RequestResponseCycle.send of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x000001BCFC7D4A90>>\n │ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x000001BCFC7D4...\n │ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.1'}, 'http_version': '1.1', 'server': ('127.0.0.1', 80), 'clie...\n │ └ <starlette.middleware.errors.ServerErrorMiddleware object at 0x000001BCFC7B8FD0>\n └ <fastapi.applications.FastAPI object at 0x000001BCFC722710>\n File \"C:\\Program Files\\Python37\\lib\\site-packages\\starlette\\middleware\\errors.py\", line 181, in __call__\n raise exc from None\n File \"C:\\Program Files\\Python37\\lib\\site-packages\\starlette\\middleware\\errors.py\", line 159, in __call__\n await self.app(scope, receive, _send)\n │ │ │ │ └ <function ServerErrorMiddleware.__call__.<locals>._send at 0x000001BCFC72AE18>\n │ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x000001BCFC7D4...\n │ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.1'}, 'http_version': '1.1', 'server': ('127.0.0.1', 80), 'clie...\n │ └ <starlette.middleware.cors.CORSMiddleware object at 0x000001BCFC7B8F60>\n └ <starlette.middleware.errors.ServerErrorMiddleware object at 0x000001BCFC7B8FD0>\n File \"C:\\Program Files\\Python37\\lib\\site-packages\\starlette\\middleware\\cors.py\", line 84, in __call__\n await self.simple_response(scope, receive, send, request_headers=headers)\n │ │ │ │ │ └ Headers({'host': '127.0.0.1', 'connection': 'keep-alive', 'content-length': '295', 'accept': 'application/json', 'user-agent'...\n │ │ │ │ └ <function ServerErrorMiddleware.__call__.<locals>._send at 0x000001BCFC72AE18>\n │ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x000001BCFC7D4...\n │ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.1'}, 'http_version': '1.1', 'server': ('127.0.0.1', 80), 'clie...\n │ └ <function CORSMiddleware.simple_response at 0x000001BCEE53DC80>\n └ <starlette.middleware.cors.CORSMiddleware object at 0x000001BCFC7B8F60>\n File \"C:\\Program Files\\Python37\\lib\\site-packages\\starlette\\middleware\\cors.py\", line 140, in simple_response\n await self.app(scope, receive, send)\n │ │ │ │ └ functools.partial(<bound method CORSMiddleware.send of <starlette.middleware.cors.CORSMiddleware object at 0x000001BCFC7B8F60...\n │ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x000001BCFC7D4...\n │ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.1'}, 'http_version': '1.1', 'server': ('127.0.0.1', 80), 'clie...\n │ └ <starlette.exceptions.ExceptionMiddleware object at 0x000001BCFC7B8E48>\n └ <starlette.middleware.cors.CORSMiddleware object at 0x000001BCFC7B8F60>\n File \"C:\\Program Files\\Python37\\lib\\site-packages\\starlette\\exceptions.py\", line 82, in __call__\n raise exc from None\n File \"C:\\Program Files\\Python37\\lib\\site-packages\\starlette\\exceptions.py\", line 71, in __call__\n await self.app(scope, receive, sender)\n │ │ │ │ └ <function ExceptionMiddleware.__call__.<locals>.sender at 0x000001BCFC7C18C8>\n │ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x000001BCFC7D4...\n │ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.1'}, 'http_version': '1.1', 'server': ('127.0.0.1', 80), 'clie...\n │ └ <fastapi.routing.APIRouter object at 0x000001BCFC7220F0>\n └ <starlette.exceptions.ExceptionMiddleware object at 0x000001BCFC7B8E48>\n File \"C:\\Program Files\\Python37\\lib\\site-packages\\starlette\\routing.py\", line 550, in __call__\n await route.handle(scope, receive, send)\n │ │ │ │ └ <function ExceptionMiddleware.__call__.<locals>.sender at 0x000001BCFC7C18C8>\n │ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x000001BCFC7D4...\n │ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.1'}, 'http_version': '1.1', 'server': ('127.0.0.1', 80), 'clie...\n │ └ <function Route.handle at 0x000001BCEE4FF6A8>\n └ <fastapi.routing.APIRoute object at 0x000001BCFC7B8E80>\n File \"C:\\Program Files\\Python37\\lib\\site-packages\\starlette\\routing.py\", line 227, in handle\n await self.app(scope, receive, send)\n │ │ │ │ └ <function ExceptionMiddleware.__call__.<locals>.sender at 0x000001BCFC7C18C8>\n │ │ │ └ <bound method RequestResponseCycle.receive of <uvicorn.protocols.http.h11_impl.RequestResponseCycle object at 0x000001BCFC7D4...\n │ │ └ {'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.1'}, 'http_version': '1.1', 'server': ('127.0.0.1', 80), 'clie...\n │ └ <function request_response.<locals>.app at 0x000001BCFC7C1A60>\n └ <fastapi.routing.APIRoute object at 0x000001BCFC7B8E80>\n File \"C:\\Program Files\\Python37\\lib\\site-packages\\starlette\\routing.py\", line 41, in app\n response = await func(request)\n │ └ <starlette.requests.Request object at 0x000001BCFC7D4588>\n └ <function get_request_handler.<locals>.app at 0x000001BCFC7C19D8>\n File \"C:\\Program Files\\Python37\\lib\\site-packages\\fastapi\\routing.py\", line 213, in app\n is_coroutine=is_coroutine,\n └ True\n File \"C:\\Program Files\\Python37\\lib\\site-packages\\fastapi\\routing.py\", line 113, in serialize_response\n exclude_none=exclude_none,\n └ False\n File \"C:\\Program Files\\Python37\\lib\\site-packages\\fastapi\\routing.py\", line 65, in _prepare_response_content\n exclude_none=exclude_none,\n └ False\n File \"pydantic\\main.py\", line 386, in pydantic.main.BaseModel.dict\n File \"pydantic\\main.py\", line 706, in _iter\n File \"pydantic\\main.py\", line 623, in pydantic.main.BaseModel._get_value\n File \"pydantic\\main.py\", line 623, in pydantic.main.BaseModel._get_value\n File \"pydantic\\main.py\", line 623, in pydantic.main.BaseModel._get_value\n [Previous line repeated 722 more times]\n File \"pydantic\\main.py\", line 605, in pydantic.main.BaseModel._get_value\n File \"C:\\Program Files\\Python37\\lib\\abc.py\", line 139, in __instancecheck__\n return _abc_instancecheck(cls, instance)\n │ │ └ 8\n │ └ <class 'pydantic.main.BaseModel'>\n └ <built-in function _abc_instancecheck>\nRecursionError: maximum recursion depth exceeded in comparison```\n```\n\n```text\nRecursionError: maximum recursion depth exceeded in comparison\n```\n\n```text\nBaseModel\n```\n\n```text\naudit.py\n```\n\n```text\nsys.setrecursionlimit(1500)\n```\n\n```text\nmain.py\n```\n\n```text\nrouter.py\n```\n\n```text\naudit.py\n```\n\n```text\naudit_models.py\n```\n\n```text\noutput\n```\n\n```text\naudit.py\n```\n\n========================================\n\nComments:\n- Can you try adding a orm_mode=True to your Pydantic model.\n- Hey, I tried as you suggested and the same traceback occurs\n- Does this answer your question? What is the maximum recursion depth in Python, and how to increase it?\n- @AhmadAnis thank you for suggesting, but it doesn't. I tried `sys.setrecursionlimit(1500)` in 'main.py' and 'audit.py' and it hasn't removed the `RecursionError`\n- This may sound silly but can you try using Typing, since pydantic models, typing 's standard types\n- @YagizcanDegirmenci, sorry but I don't understand what you mean. Where would I use the Typing lib?\n- Instead of dict use typing.Dict whole FastAPI and Pydantic stands on Type hints, typing library so nearly everywhere you should use typing. for example `website_h1_tags: Dict[Any,Any]`\n- I see, thanks for the clarification. I implemented the change but the error remains: `2020-09-10 19:26:31.298 | ERROR | uvicorn.protocols.http.h11_impl:run_asgi:391 - Exception in ASGI application` then the same traceback\n- This comment lack of basic information on how to resolve the issue. Please elaborate on the solution made\n- and how can you find out which one assuming you many many files in your project?\n- Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.\n- This does not really answer the question. If you have a different question, you can ask it by clicking Ask Question. To get notified when this question gets new answers, you can this question. Once you have enough reputation, you can also add a bounty to draw more attention to this question. - From Review","metadata":{"transformedAt":"2026-08-18T18:32:29.117Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":16,"totalLines":776,"estimatedTokens":10078}}256{"id":"stack-65878595","source":"stackoverflow","questionId":65878595,"title":"Invalid HTTP method in Traceback: Uvicorn","tags":["python","digital-ocean","fastapi","linode","uvicorn"],"text":"Title: Invalid HTTP method in Traceback: Uvicorn\nTags: python, digital-ocean, fastapi, linode, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI am using uvicorn 0.11.8 and fastapi 0.61.1. My application is hosted in VPS. When I run the app in local server, such error is not reproducible. It shows correct message 404 Not found for methods not available but I couldn't figure out what is causing this issue in VPS (error in Traceback).\nhttps://i.sstatic.net/qm3gD.png\n\n========================================\n\nCode:\n```text\nWARNING: Invalid HTTP request received.\n```\n\n```text\nhttps\n```\n\n```text\nhttps\n```\n\n```text\nhttp\n```\n\n========================================\n\nComments:\n- Happened with me in `httpS://localhost:8000` instead of `http`\n- I came here during similar search, and my issue was that I created a `Celery` client which was trying to connect to the `RabbitMQ` constantly, and all the requests were forwarded to `FastAPI` via `rpc` or `amqp` protocols`, which leads to error above","metadata":{"transformedAt":"2026-08-18T18:32:29.117Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":32,"estimatedTokens":250}}257{"id":"stack-70118412","source":"stackoverflow","questionId":70118412,"title":"Keeping endpoint function declarations in separate modules with FastAPI","tags":["python","python-3.x","fastapi"],"text":"Title: Keeping endpoint function declarations in separate modules with FastAPI\nTags: python, python-3.x, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have an API that uses FastAPI. In a single file (main.py), I have the call to the function that creates the API\n\n```\nfrom fastapi import FastAPI\n# ...\napp = FastAPI()\n```\n\nAs well as all the endpoints:\n\n```\n@app.post(\"/sum\")\nasync def sum_two_numbers(number1: int, number2: int):\n return {'result': number1 + number2}\n```\n\nBut as the application gets larger, the file is becoming messy and hard to maintain. The obvious solution would be to keep function definitions in separate modules and just import them and use them in main.py, like this:\n\n```\nfrom mymodules.operations import sum_two_numbers\n# ...\n@app.post(\"/sum\")\nsum_two_numbers(number1: int, number2: int)\n```\n\nOnly that doesn't work. I don't know if I'm doing it wrong or it can't be done, but I get this error from VSCode:\n\nExpected function or class declaration after decorator | Pylance\n\n(My program has so many errors that I haven't seen the actual interpreter complaint, but if that's important, I can try debug it and post it here)\n\nSo is this impossible to do and I have to stick to the one-file API, or it is possible to do, but I'm doing it wrong? If the second, what is the right way?\n\n========================================\n\nTop Answer:\nThe common solution is to split your application into subrouters. Instead of using `app` directly when registering your views, you create an instance `APIRouter` (`from fastapi import APIRouter`) inside each of your modules, then you register these subrouters into your main application.\n\nInside a dedicated api module, such as `api/pages.py`:\n\n```\nfrom fastapi import APIRouter\n\nrouter = APIRouter()\n\n@router.get('')\nasync def get_pages():\n return ...\n```\n\n```\nfrom .api import (\n pages,\n posts,\n users,\n)\n\napp.include_router(pages.router, prefix='/pages')\napp.include_router(posts.router, prefix='/posts')\napp.include_router(users.router, prefix='/users')\n```\n\nAnother powerful construct you can use is to have two dedicated base routers, one that requires authentication and one that doesn't:\n\n```\nunauthenticated_router = APIRouter()\nauthenticated_router = APIRouter(dependencies=[Depends(get_authenticated_user)])\n```\n\n.. and you can then register the different routes under each router, depending on whether you want to guard the route with an authenticated user or not. You'd have two subrouters inside each module, one for endpoints that require authentication and one for those that doesn't, and name them appropriately (and if you have no public endpoints, just use `authenticated_router` as the single name).\n\n```\nunauthenticated_router.include_router(authentication.router, prefix='/authenticate')\nunauthenticated_router.include_router(users.unauthenticated_router, prefix='/users', tags=['users'])\nauthenticated_router.include_router(users.router, prefix='/users')\n```\n\nAny sub router registered under `authenticated_router` will have the `get_authenticated_user` dependency evaluated first, which in this case would throw a 401 error if the user wasn't logged in. You can then authorized further based on roles etc. in the dependencies for the view function - but this makes it very explicit whether you want your endpoint to end up in a chain that requires authentication or not.\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\n# ...\napp = FastAPI()\n```\n\n```text\n@app.post(\"/sum\")\nasync def sum_two_numbers(number1: int, number2: int):\n return {'result': number1 + number2}\n```\n\n```text\nfrom mymodules.operations import sum_two_numbers\n# ...\n@app.post(\"/sum\")\nsum_two_numbers(number1: int, number2: int)\n```\n\n```text\n.\n├── app\n│ ├── __init__.py\n│ ├── main.py\n│ ├── dependencies.py\n│ └── routers\n│ │ ├── __init__.py\n│ │ ├── items.py\n│ │ └── users.py\n│ └── internal\n│ ├── __init__.py\n│ └── admin.py\n```\n\n```text\n.\n├── app\n│ ├── __init__.py\n│ ├── main.py\n│ ├── dependencies.py\n│ └── routers\n│ │ ├── __init__.py\n│ │ ├── items.py\n│ │ └── users.py\n│ └── models\n│ │ ├── __init__.py\n│ │ ├── items.py\n│ │ └── users.py\n│ └── schemas\n│ │ ├── __init__.py\n│ │ ├── items.py\n│ │ └── users.py\n│ └── internal\n│ │ ├── __init__.py\n│ │ └── admin.py\n```\n\n```py\nfrom fastapi import APIRouter\n\nrouter = APIRouter()\n\n@router.get('')\nasync def get_pages():\n return ...\n```\n\n```py\nfrom .api import (\n pages,\n posts,\n users,\n)\n\n\napp.include_router(pages.router, prefix='/pages')\napp.include_router(posts.router, prefix='/posts')\napp.include_router(users.router, prefix='/users')\n```\n\n```py\nunauthenticated_router = APIRouter()\nauthenticated_router = APIRouter(dependencies=[Depends(get_authenticated_user)])\n```\n\n```py\nunauthenticated_router.include_router(authentication.router, prefix='/authenticate')\nunauthenticated_router.include_router(users.unauthenticated_router, prefix='/users', tags=['users'])\nauthenticated_router.include_router(users.router, prefix='/users')\n```\n\n```text\napp\n```\n\n```text\nAPIRouter\n```\n\n```text\nfrom fastapi import APIRouter\n```\n\n```text\napi/pages.py\n```\n\n```text\nauthenticated_router\n```\n\n```text\nauthenticated_router\n```\n\n```text\nget_authenticated_user\n```\n\n========================================\n\nComments:\n- Thanks, I'm certainly going to use every bit of advice from this answer. But I'm choosing Bastien's because he included the link to the official documentation with the full implementation details","metadata":{"transformedAt":"2026-08-18T18:32:29.117Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":16,"totalLines":210,"estimatedTokens":1383}}258{"id":"stack-66612990","source":"stackoverflow","questionId":66612990,"title":"FastAPI (Python) Why I get \"Unsupported upgrade request.\" with POST request?","tags":["python","fastapi"],"text":"Title: FastAPI (Python) Why I get \"Unsupported upgrade request.\" with POST request?\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have similar apps on Flask and FastAPI.\nWhen I do this curl requests with Flask, that is all right:\n\nWithout TLS:\n\n```\ncurl -X POST -H \"Content-Type: application/json\" -d '{\"method\": \"account.auth\"}' http://X.X.X.X:5050/\n\n{\"error\":0,\"result\":{\"token\":\"XXX\"}}\n```\n\nWith TLS:\n\n```\ncurl -X POST -H \"Content-Type: application/json\" -d '{\"method\": \"account.auth\"}' https://example.com:8443/api/\n\n{\"error\":0,\"result\":{\"token\":\"XXX\"}}\n```\n\n!!! But with FastAPI I get another result:\n\nWithout TLS:\n\n```\ncurl -X POST -H \"Content-Type: application/json\" -d '{\"method\": \"account.auth\"}' http://X.X.X.X:5050/\n\n{\"error\":0,\"result\":{\"token\":\"XXX\"}}\n```\n\nWith TLS:\n\n```\ncurl -X POST -H \"Content-Type: application/json\" -d '{\"method\": \"account.auth\"}' https://example.com:8443/api/\n\nUnsupported upgrade request.\n```\n\nHow to fix problem with \"Unsupported upgrade request.\"? And what is it? Flask are working with it normally.\n\n========================================\n\nTop Answer:\nI had this problem using java to access the api. The solution was to set HTTP Request to 1.1\n\n```\nvar httpRequest = HttpRequest.newBuilder()\n .uri(URI.create(\"http://127.0.0.1:8000/jobs\"))\n .version(HttpClient.Version.HTTP_1_1)\n .GET()\n .build();\n```\n\n========================================\n\nCode:\n```text\ncurl -X POST -H \"Content-Type: application/json\" -d '{\"method\": \"account.auth\"}' http://X.X.X.X:5050/\n\n{\"error\":0,\"result\":{\"token\":\"XXX\"}}\n```\n\n```text\ncurl -X POST -H \"Content-Type: application/json\" -d '{\"method\": \"account.auth\"}' https://example.com:8443/api/\n\n{\"error\":0,\"result\":{\"token\":\"XXX\"}}\n```\n\n```text\ncurl -X POST -H \"Content-Type: application/json\" -d '{\"method\": \"account.auth\"}' http://X.X.X.X:5050/\n\n{\"error\":0,\"result\":{\"token\":\"XXX\"}}\n```\n\n```text\ncurl -X POST -H \"Content-Type: application/json\" -d '{\"method\": \"account.auth\"}' https://example.com:8443/api/\n\nUnsupported upgrade request.\n```\n\n```sh\npython3 -m pip uninstall uvicorn\npython3 -m pip install uvicorn[standard]\n```\n\n```text\nuvicorn\n```\n\n```text\nuvicorn\n```\n\n```text\nvar httpRequest = HttpRequest.newBuilder()\n .uri(URI.create(\"http://127.0.0.1:8000/jobs\"))\n .version(HttpClient.Version.HTTP_1_1)\n .GET()\n .build();\n```\n\n```text\nWARNING: Unsupported upgrade request.\n```\n\n```text\nuvicorn\n```\n\n```java\nvar httpServiceProxyFactory = HttpServiceProxyFactory\n .builder(\n WebClientAdapter.forClient(\n WebClient.builder()\n .baseUrl(\"xxx\")\n .clientConnector(new JdkClientHttpConnector(\n HttpClient.newBuilder()\n .version(HttpClient.Version.HTTP_1_1)\n .build()\n ))\n .defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)\n .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)\n .build()\n )\n )\n .blockTimeout(Duration.ofDays(1))\n .build();\n```\n\n```text\nrequestFactory = OkHttp3ClientHttpRequestFactory()\n```\n\n========================================\n\nComments:\n- Okay, It is work. But I get new error with uvicorn[standard]: error walking file system: OSError [Errno 40] Too many levels of symbolic links: '/sys/class/vtconsole/vtcon0/subsystem/vtcon0/subsystem/vtco‌​n0/subsystem/vtcon0/‌​subsystem/vtcon0/sub‌​system/vtcon0/subsys‌​tem/vtcon0/subsystem‌​/vtcon0/subsystem/vt‌​con0/subsystem/vtcon‌​0/subsystem/vtcon0/s‌​ubsystem/vtcon0/subs‌​ystem/vtcon0/subsyst‌​em/vtcon0/subsystem/‌​vtcon0/subsystem/vtc‌​on0/subsystem/vtcon0‌​/subsystem/vtcon0/su‌​bsystem/vtcon0/subsy‌​stem/vtcon0/subsyste‌​m/vtcon0' How to fix it?\n- thanks! That fixed it for me, too. I had to access a third party Python REST service and could not connect, always this strange \"Unsupported upgrade request.\" error. Switching to Http 1.1 made it work immediately. I found this statement about HttpClient: \"HttpClient will use HTTP/2 by default. It will also automatically downgrade to HTTP/1.1 if the server doesn't support HTTP/2.\" but this does not seem to work with Python servers.\n- Had the same issue with a Java client calling my Python service, and reinstalling `uvicorn` didn't resolve it. This worked, thanks!\n- Thank you! I've lost half a day with this issue making a request with Scala sttp...","metadata":{"transformedAt":"2026-08-18T18:32:29.117Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":12,"totalLines":144,"estimatedTokens":1186}}259{"id":"stack-74009210","source":"stackoverflow","questionId":74009210,"title":"How to create a FastAPI endpoint that can accept either File/Form or JSON body?","tags":["python","json","multipartform-data","fastapi","starlette"],"text":"Title: How to create a FastAPI endpoint that can accept either File/Form or JSON body?\nTags: python, json, multipartform-data, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nI would like to create an endpoint in FastAPI that might receive either `multipart/form-data` or JSON body. Is there a way I can make such an endpoint accept either, or detect which type of data is receiving?\n\n========================================\n\nCode:\n```text\nmultipart/form-data\n```\n\n```py\nfrom fastapi import FastAPI, Depends, Request, HTTPException\nfrom starlette.datastructures import FormData\nfrom json import JSONDecodeError\n\napp = FastAPI()\n\nasync def get_body(request: Request):\n content_type = request.headers.get('Content-Type')\n if content_type is None:\n raise HTTPException(status_code=400, detail='No Content-Type provided!')\n elif content_type == 'application/json':\n try:\n return await request.json()\n except JSONDecodeError:\n raise HTTPException(status_code=400, detail='Invalid JSON data')\n elif (content_type == 'application/x-www-form-urlencoded' or\n content_type.startswith('multipart/form-data')):\n try:\n return await request.form()\n except Exception:\n raise HTTPException(status_code=400, detail='Invalid Form data')\n else:\n raise HTTPException(status_code=400, detail='Content-Type not supported!')\n\n@app.post('/')\ndef main(body = Depends(get_body)):\n if isinstance(body, dict): # if JSON data received\n return body\n elif isinstance(body, FormData): # if Form/File data received\n msg = body.get('msg')\n items = body.getlist('items')\n files = body.getlist('files') # returns a list of UploadFile objects\n if files:\n print(files[0].file.read(10))\n return msg\n```\n\n```py\nfrom fastapi import FastAPI, UploadFile, File, Form, Request, HTTPException\nfrom typing import Optional, List\nfrom json import JSONDecodeError\n\napp = FastAPI()\n\n@app.post('/')\nasync def submit(request: Request, items: Optional[List[str]] = Form(None),\n files: Optional[List[UploadFile]] = File(None)):\n # if File(s) and/or form-data were received\n if items or files:\n filenames = None\n if files:\n filenames = [f.filename for f in files]\n return {'File(s)/form-data': {'items': items, 'filenames': filenames}}\n else: # check if JSON data were received\n try:\n data = await request.json()\n return {'JSON': data}\n except JSONDecodeError:\n raise HTTPException(status_code=400, detail='Invalid JSON data')\n```\n\n```py\nfrom fastapi import FastAPI, Request, Form, File, UploadFile\nfrom fastapi.responses import JSONResponse\nfrom typing import List, Optional\nfrom pydantic import BaseModel\n\napp = FastAPI()\n\nclass Item(BaseModel):\n items: List[str]\n msg: str\n\n@app.middleware(\"http\")\nasync def some_middleware(request: Request, call_next):\n if request.url.path == '/':\n content_type = request.headers.get('Content-Type')\n if content_type is None:\n return JSONResponse(\n content={'detail': 'No Content-Type provided!'}, status_code=400)\n elif content_type == 'application/json':\n request.scope['path'] = '/submitJSON'\n elif (content_type == 'application/x-www-form-urlencoded' or\n content_type.startswith('multipart/form-data')):\n request.scope['path'] = '/submitForm'\n else:\n return JSONResponse(\n content={'detail': 'Content-Type not supported!'}, status_code=400)\n\n return await call_next(request)\n\n@app.post('/')\ndef main():\n return\n\n@app.post('/submitJSON')\ndef submit_json(item: Item):\n return item\n\n@app.post('/submitForm')\ndef submit_form(msg: str = Form(...), items: List[str] = Form(...),\n files: Optional[List[UploadFile]] = File(None)):\n return msg\n```\n\n```py\nimport requests\n\nurl = 'http://127.0.0.1:8000/'\nfiles = [('files', open('a.txt', 'rb')), ('files', open('b.txt', 'rb'))]\npayload ={'items': ['foo', 'bar'], 'msg': 'Hello!'}\n \n# Send Form data and files\nr = requests.post(url, data=payload, files=files) \nprint(r.text)\n\n# Send Form data only\nr = requests.post(url, data=payload) \nprint(r.text)\n\n# Send JSON data\nr = requests.post(url, json=payload) \nprint(r.text)\n```\n\n```text\nContent-Type\n```\n\n```text\nContent-Type\n```\n\n```text\napplication/json\n```\n\n```text\napplication/x-www-form-urlencoded\n```\n\n```text\nmultipart/form-data\n```\n\n```text\ntry-except\n```\n\n```text\nBaseModel\n```\n\n```text\nparse_obj\n```\n\n```text\nRequest\n```\n\n```text\nrequest.form()\n```\n\n```text\nFormData\n```\n\n```text\nImmutableMultiDict\n```\n\n```text\nlist\n```\n\n```text\nform\n```\n\n```text\nfiles\n```\n\n```text\ngetlist()\n```\n\n```text\nlist\n```\n\n```text\nlist\n```\n\n```text\nUploadFile\n```\n\n```text\nrequest.form()\n```\n\n```text\nstream\n```\n\n```text\nstreaming-form-data\n```\n\n```text\nOptional\n```\n\n```text\nContent-Type\n```\n\n```text\napplication/x-www-form-urlencoded\n```\n\n```text\nmultipart/form-data\n```\n\n```text\nNone\n```\n\n```text\n/\n```\n\n```text\nContent-Type\n```\n\n```text\n/submitJSON\n```\n\n```text\n/submitForm\n```\n\n```text\npath\n```\n\n```text\nrequest.scope\n```\n\n```text\nOptional\n```\n\n```text\nmodel_validate_json()\n```\n\n```text\nForm\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.117Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":41,"totalLines":283,"estimatedTokens":1334}}260{"id":"stack-73962743","source":"stackoverflow","questionId":73962743,"title":"FastAPI is not returning cookies to React frontend","tags":["javascript","python","cookies","axios","fastapi"],"text":"Title: FastAPI is not returning cookies to React frontend\nTags: javascript, python, cookies, axios, fastapi\nSource: Stack Overflow\n\nQuestion:\nWhy doesn't FastAPI return the cookie to my frontend, which is a React app?\n\nHere is my code:\n\n```\n@router.post(\"/login\")\ndef user_login(response: Response,username :str = Form(),password :str = Form(),db: Session = Depends(get_db)):\n user = db.query(models.User).filter(models.User.mobile_number==username).first()\n if not user:\n raise HTTPException(400, detail='wrong phone number or password')\n if not verify_password(password, user.password):\n raise HTTPException(400, detail='wrong phone number or password')\n \n \n access_token = create_access_token(data={\"sub\": user.mobile_number})\n response.set_cookie(key=\"fakesession\", value=\"fake-cookie-session-value\") #here I am set cookie \n return {\"status\":\"success\"}\n```\n\nWhen I login from Swagger UI autodocs, I can see the cookie in the response headers using DevTools on Chrome browser. However, when I login from my React app, no cookie is returned. I am using `axios` to send the request like this:\n\n```\nawait axios.post(login_url, formdata)\n```\n\n========================================\n\nCode:\n```text\n@router.post(\"/login\")\ndef user_login(response: Response,username :str = Form(),password :str = Form(),db: Session = Depends(get_db)):\n user = db.query(models.User).filter(models.User.mobile_number==username).first()\n if not user:\n raise HTTPException(400, detail='wrong phone number or password')\n if not verify_password(password, user.password):\n raise HTTPException(400, detail='wrong phone number or password')\n \n \n access_token = create_access_token(data={\"sub\": user.mobile_number})\n response.set_cookie(key=\"fakesession\", value=\"fake-cookie-session-value\") #here I am set cookie \n return {\"status\":\"success\"}\n```\n\n```text\nawait axios.post(login_url, formdata)\n```\n\n```text\naxios\n```\n\n```py\nfrom fastapi import FastAPI, Response\n\napp = FastAPI()\n\n@app.get('/')\ndef main(response: Response):\n response.set_cookie(key='token', value='some-token-value', httponly=True) \n return {'status': 'success'}\n```\n\n```js\nawait axios.post(url, data, {withCredentials: true}))\n```\n\n```js\nfetch('https://example.com', {\n credentials: 'include'\n});\n```\n\n```js\naxios.post('http://localhost:8000',...\n```\n\n```js\naxios.post('http://127.0.0.1:8000',...\n```\n\n```py\norigins = ['http://localhost:3000', 'http://127.0.0.1:3000',\n 'https://localhost:3000', 'https://127.0.0.1:3000']\n```\n\n```py\napp.add_middleware(\n CORSMiddleware,\n allow_origins=origins,\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n```\n\n```text\n'status': 'success'\n```\n\n```text\n200\n```\n\n```text\nmax_age\n```\n\n```text\nexpires\n```\n\n```text\nwithCredentials\n```\n\n```text\ntrue\n```\n\n```text\nfalse\n```\n\n```text\nwithCredentials: true\n```\n\n```text\nwithCredentials\n```\n\n```text\nfalse\n```\n\n```text\nwithCredentials: true\n```\n\n```text\nfetch()\n```\n\n```text\ncredentials: 'include'\n```\n\n```text\ncredentials\n```\n\n```text\nsame-origin\n```\n\n```text\ncredentials: 'include'\n```\n\n```text\nhttp://localhost:8000\n```\n\n```text\nhttp://localhost:3000\n```\n\n```text\nsame-site\n```\n\n```text\ncross-site\n```\n\n```text\nsame-origin\n```\n\n```text\ncross-origin\n```\n\n```text\nsame-site\n```\n\n```text\nhttp\n```\n\n```text\nhttps\n```\n\n```text\nlocalhost\n```\n\n```text\n127.0.0.1\n```\n\n```text\nexample.com\n```\n\n```text\nsame-origin\n```\n\n```text\nhttp://localhost:3000\n```\n\n```text\nlocalhost\n```\n\n```text\n127.0.0.1\n```\n\n```text\nlocalhost\n```\n\n```text\n127.0.0.1\n```\n\n```text\nlocalhost\n```\n\n```text\n127.0.0.1\n```\n\n```text\naxios\n```\n\n```text\nhttp://127.0.0.1:3000\n```\n\n```text\n127.0.0.1\n```\n\n```text\naxios.post('http://127.0.0.1:8000',...\n```\n\n```text\nAccess-Control-Allow-Origin\n```\n\n```text\n*\n```\n\n```text\ncredentials\n```\n\n```text\n*\n```\n\n```text\nallow_credentials=True\n```\n\n```text\nCORSMiddleware\n```\n\n```text\nAccess-Control-Allow-Credentials\n```\n\n```text\ntrue\n```\n\n========================================\n\nComments:\n- What is the actual response? Is it 200 OK, or is there an error that occurs? What does the response headers look like?\n- Also make sure to set your Cookie's `SameSite` to `none` (`lax` did not work for me), see this answer for more stackoverflow.com/a/72024519/9878135\n- @Myzel394 Please **DON'T** set the `SameSite` flag to `None`, as the cookie would **not be protected** from external access (use with `cross-domain cookies` **only**).\n- @Myzel394 If you are creating cookies for the same domain (e.g., `http://localhost` or `http://127.0.0.1`), setting that flag to `Lax` or `Strict` should be fine. Note that `localhost` and `127.0.0.1` are considered to be different domains (the same applies to `https://localhost` and `http://localhost` - note the **s** in the first domain, which uses the `HTTPS` protocol); hence, if you are accessing your frontend at `http://localhost`, make sure that your axios request uses `http://localhost`, not `http://127.0.0.1`, and vice versa.\n- for development it's fine to set your cookies to `None`, for production however, you are totally right to not set it to `None`.\n- @Myzel394 I am afraid that's not how it works. I would suggest you have a look at the answer above (including the references), as well as the comments above to better understand how things work, and that in the above case (where **same-domain** cookies need to be created), you **don't** have to and **shouldn't** set the `SameSite` flag to `None`. Making that mistake during development, it would be easier for you to make it in production as well. Read more about cross-site and same-site cookies here.","metadata":{"transformedAt":"2026-08-18T18:32:29.117Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":58,"totalLines":301,"estimatedTokens":1419}}261{"id":"stack-71949467","source":"stackoverflow","questionId":71949467,"title":"Pydantic validation error for BaseSettings model with local ENV file","tags":["python","fastapi","pydantic"],"text":"Title: Pydantic validation error for BaseSettings model with local ENV file\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI'm developing a simple FastAPI app and I'm using Pydantic for storing app settings.\n\nSome settings are populated from the environment variables set by Ansible deployment tools but some other settings are needed to be set explicitly from a separate env file.\n\nSo I have this in `config.py`\n\n```\nclass Settings(BaseSettings):\n\n # Project wide settings\n PROJECT_MODE: str = getenv(\"PROJECT_MODE\", \"sandbox\")\n VERSION: str\n\n class Config:\n env_file = \"config.txt\"\n```\n\nAnd I have this `config.txt`\n\n```\nVERSION=\"0.0.1\"\n```\n\nSo `project_mode` env var is being set by deployment script and `version` is being set from the env file. The reason for that is that we'd like to keep deployment script similar across all projects, so any custom vars are populated from the project specific env files.\n\nBut the problem is that when I run the app, it fails with:\n\n```\npydantic.error_wrappers.ValidationError: 1 validation error for Settings\nVERSION\n field required (type=value_error.missing)\n```\n\nSo how can I populate Pydantic settings model from the local ENV file?\n\n========================================\n\nTop Answer:\nThe path of env_file is relative to the current working directory, which confused me as well. In order to always use a path relative to the config module I set it up like this:\n\n```\nenv_file = f\"{pathlib.Path(__file__).resolve().parent}/config.txt\"\n```\n\n========================================\n\nCode:\n```text\nclass Settings(BaseSettings):\n\n # Project wide settings\n PROJECT_MODE: str = getenv(\"PROJECT_MODE\", \"sandbox\")\n VERSION: str\n\n class Config:\n env_file = \"config.txt\"\n```\n\n```text\nVERSION=\"0.0.1\"\n```\n\n```text\npydantic.error_wrappers.ValidationError: 1 validation error for Settings\nVERSION\n field required (type=value_error.missing)\n```\n\n```text\nconfig.py\n```\n\n```text\nconfig.txt\n```\n\n```text\nproject_mode\n```\n\n```text\nversion\n```\n\n```text\nenv_file = f\"{pathlib.Path(__file__).resolve().parent}/config.txt\"\n```\n\n========================================\n\nComments:\n- Your example works for me. Perhaps `config.txt` is not in the application's working directory? Have you tried using an absolute path?\n- Make sure the current working directory (i.e. where you launch the application from) is the directory with `config.txt`.\n- @AnthonyCarapetis both `config.py`and `confix.txt` are in the same directory. So the main `app.py` file is in the root of the project and those two setting files are in the `/settings/` directory\n- Then the `config.txt` file is in the wrong location - the current working directory is the directory where *you are running your application from*, not the same directory as the config.py directory.\n- @MatsLindh Yes, you are absolutely right! No matter how much time I've spent with python, there are two things I just never get right - relative vs absolute imports and current working directory )) Would you mind posting it as answer so I can accept it?","metadata":{"transformedAt":"2026-08-18T18:32:29.117Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":8,"totalLines":101,"estimatedTokens":767}}262{"id":"stack-62798421","source":"stackoverflow","questionId":62798421,"title":"How to send file to FastAPI endpoint using Postman?","tags":["python","file-upload","postman","fastapi"],"text":"Title: How to send file to FastAPI endpoint using Postman?\nTags: python, file-upload, postman, fastapi\nSource: Stack Overflow\n\nQuestion:\nI faced the difficulty of testing api using postman. Through swagger file upload functionality works correctly, I get a saved file on my hard disk. I would like to understand how to do this with Postman. I use the standard way to work with files which I use when working with Django and Flask:\n\n```\nBody -> form-data: key=file, value=image.jpeg\n```\n\nBut with FastAPI, I get an error:\n\n```\n127.0.0.1:54294 - \"POST /uploadfile/ HTTP/1.1\" 422 Unprocessable Entity\n```\n\n**main.py**\n\n```\n@app.post(\"/uploadfile/\")\nasync def create_upload_file(file: UploadFile = File(...)):\n img = await file.read()\n if file.content_type not in ['image/jpeg', 'image/png']:\n raise HTTPException(status_code=406, detail=\"Please upload only .jpeg files\")\n async with aiofiles.open(f\"{file.filename}\", \"wb\") as f:\n await f.write(img)\n return {\"filename\": file.filename}\n```\n\nI also tried `body -> binary: image.jpeg`, but got the same result:\n\nhttps://i.sstatic.net/6pqzh.png\n\n========================================\n\nCode:\n```text\nBody -> form-data: key=file, value=image.jpeg\n```\n\n```text\n127.0.0.1:54294 - \"POST /uploadfile/ HTTP/1.1\" 422 Unprocessable Entity\n```\n\n```text\n@app.post(\"/uploadfile/\")\nasync def create_upload_file(file: UploadFile = File(...)):\n img = await file.read()\n if file.content_type not in ['image/jpeg', 'image/png']:\n raise HTTPException(status_code=406, detail=\"Please upload only .jpeg files\")\n async with aiofiles.open(f\"{file.filename}\", \"wb\") as f:\n await f.write(img)\n return {\"filename\": file.filename}\n```\n\n```text\nbody -> binary: image.jpeg\n```\n\n```text\nfrom fastapi import FastAPI, UploadFile, File\n\napp = FastAPI()\n\n@app.post(\"/file/\")\nasync def create_upload_file(file: UploadFile = File(...)):\n return {\"filename\": file.filename}\n```\n\n```text\nkey=file\n```\n\n```text\nvalue=image.png\n```\n\n```text\nfile=image.png\n```\n\n```text\nfile\n```\n\n========================================\n\nComments:\n- I'm not at my office desk, but I faced a similar problem once. The solution is to simply add the file to the `FormData` javascript class, and send it. This will directly attach the image to the body of the request. With your`key=file` you are passing multiple parameters (it's an extra one with respect to the `value=image.jpeg`). In any case you can inspect the content of your request via the console of your browser and get inspired\n- @lsabi Thank you for the feedback, but I'm not sure what I need to do exactly. Maybe you can show me?\n- Future readers that might be looking for a way to upload file(s) using the `binary` option through Postman (which should result in considerably better performance, not because of Postman, but because of how FastAPI deals with uploading file(s) when using the `UploadFile` type), instead of `form-data`, should have a look at this answer (see the **Update** section) and this answer on how to have the API endpoint properly implemented in your backend.\n- What about multiple files?\n- @MrPatience do you mean to have more than one parameter declared of type `UploadFile` ?\n- I meant to use `List` of `UploadFile`. I figured it out - you need to specify the key as `files`","metadata":{"transformedAt":"2026-08-18T18:32:29.117Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":95,"estimatedTokens":820}}263{"id":"stack-71464757","source":"stackoverflow","questionId":71464757,"title":"What does 'sa_relationship_kwargs={\"lazy\": \"selectin\"}' means on SQLModel with Fastapi?","tags":["python","foreign-keys","fastapi","sqlmodel"],"text":"Title: What does 'sa_relationship_kwargs={\"lazy\": \"selectin\"}' means on SQLModel with Fastapi?\nTags: python, foreign-keys, fastapi, sqlmodel\nSource: Stack Overflow\n\nQuestion:\nI'm trying to use SQLModel with Fastapi, and on the way I found this example for implementing entities relationships, and I would like to know what does `sa_relationship_kwargs={\"lazy\": \"selectin\"}` means and what does it do?\n\n```\nclass UserBase(SQLModel):\n first_name: str\n last_name: str\n email: EmailStr = Field(nullable=True, index=True, sa_column_kwargs={\"unique\": True}) \n is_active: bool = Field(default=True)\n is_superuser: bool = Field(default=False)\n birthdate: Optional[datetime]\n phone: Optional[str]\n state: Optional[str]\n country: Optional[str]\n address: Optional[str]\n created_at: Optional[datetime]\n updated_at: Optional[datetime]\n\nclass User(UserBase, table=True):\n id: Optional[int] = Field(default=None, nullable=False, primary_key=True)\n hashed_password: str = Field(\n nullable=False, index=True\n )\n role_id: Optional[int] = Field(default=None, foreign_key=\"role.id\")\n role: Optional[\"Role\"] = Relationship(back_populates=\"users\", sa_relationship_kwargs={\"lazy\": \"selectin\"})\n groups: List[\"Group\"] = Relationship(back_populates=\"users\", link_model=LinkGroupUser)\n```\n\n========================================\n\nCode:\n```text\nclass UserBase(SQLModel):\n first_name: str\n last_name: str\n email: EmailStr = Field(nullable=True, index=True, sa_column_kwargs={\"unique\": True}) \n is_active: bool = Field(default=True)\n is_superuser: bool = Field(default=False)\n birthdate: Optional[datetime]\n phone: Optional[str]\n state: Optional[str]\n country: Optional[str]\n address: Optional[str]\n created_at: Optional[datetime]\n updated_at: Optional[datetime]\n\nclass User(UserBase, table=True):\n id: Optional[int] = Field(default=None, nullable=False, primary_key=True)\n hashed_password: str = Field(\n nullable=False, index=True\n )\n role_id: Optional[int] = Field(default=None, foreign_key=\"role.id\")\n role: Optional[\"Role\"] = Relationship(back_populates=\"users\", sa_relationship_kwargs={\"lazy\": \"selectin\"})\n groups: List[\"Group\"] = Relationship(back_populates=\"users\", link_model=LinkGroupUser)\n```\n\n```text\nsa_relationship_kwargs={\"lazy\": \"selectin\"}\n```\n\n```text\nWHERE parent_id IN (...)\n```\n\n```text\nlazy='select'\n```\n\n```text\nlazyload()\n```\n\n```text\nlazy='joined'\n```\n\n```text\njoinedload()\n```\n\n```text\nlazy='subquery'\n```\n\n```text\nsubqueryload()\n```\n\n```text\nlazy='selectin'\n```\n\n```text\nselectinload()\n```\n\n```text\nlazy='raise'\n```\n\n```text\nlazy='raise_on_sql'\n```\n\n```text\nlazy='noload'\n```\n\n```text\nnoload()\n```\n\n```text\nNone\n```\n\n```text\n[]\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.117Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":17,"totalLines":123,"estimatedTokens":674}}264{"id":"stack-60397218","source":"stackoverflow","questionId":60397218,"title":"FastAPI docs not working with nginx Ingress controller","tags":["nginx","kubernetes","kubernetes-ingress","nginx-ingress","fastapi"],"text":"Title: FastAPI docs not working with nginx Ingress controller\nTags: nginx, kubernetes, kubernetes-ingress, nginx-ingress, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have written an application that runs a FastAPI server inside a Kubernetes pod. The external communication with the pod goes through an nginx ingress controller in a separate pod. I am running nginx:1.17.0.\n\nWhen it is all up and running I can use `curl` calls to interact with the app server through the ingress address, and access all the simple GET paths as well as *address/openapi.json* in my browser. I can also access the interactive documentation page if I use the internal ip of the app service in Kubernetes.\nHowever trying to reach the interactive documentation page (*address/docs#/default/*) gives me an error regarding */openapi.json*.\n\nhttps://i.sstatic.net/yKAT6.png\n\nSince the `curl` calls work as expected I do not think the problem is necessarily in the ingress definition but as using the internal ip of the app also works fine the issue should not be inside the app.\n\nI have included the ingress definition file below.\n\n```\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: my-app-nginx-deployment\n labels:\n app: nginx\nspec:\n replicas: 1\n selector:\n matchLabels:\n app: nginx\n template:\n metadata:\n labels:\n app: nginx\n spec:\n containers:\n - name: nginx\n image: nginx:1.17.0\n imagePullPolicy: IfNotPresent\n ports:\n - containerPort: 80\n\n---\napiVersion: networking.k8s.io/v1beta1\nkind: Ingress\nmetadata:\n name: my-app-ingress\n annotations:\n nginx.ingress.kubernetes.io/rewrite-target: /$2\nspec:\n rules:\n - host: my-host.info\n http:\n paths:\n - path: /server(/|$)(.*)\n backend:\n serviceName: my-app-service # This is the service that runs my fastAPI server pod\n servicePort: 80\n```\n\n**EDIT**\n\nThis is the service.yaml file\n\n```\napiVersion: v1\nkind: Service\nmetadata:\n name: my-app-service\nspec:\n type: ClusterIP\n selector:\n app: server\n ports:\n - protocol: \"TCP\"\n port: 80\n targetPort: 80\n```\n\nAs the service is a ClusterIP inside my local cluster I have might be able to curl straight to it, I have not tried though. When I curl I use commands like \n\n```\ncurl -X GET \"http://my-host.info/server/subpath/\" -H \"accept: application/json\"\ncurl -X POST \"http://my-host.info/server/subpath/update/\" -H \"accept: application/json\"\n```\n\nfrom outside the local cluster.\n\nThese are all the services that are running: \n\n```\nNAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE\ndefault kubernetes ClusterIP 10.96.0.1 443/TCP 11d\ndefault my-app-service ClusterIP 10.96.68.29 80/TCP 18h\nkube-system kube-dns ClusterIP 10.96.0.10 53/UDP,53/TCP,9153/TCP 28d\nkubernetes-dashboard dashboard-metrics-scraper ClusterIP 10.96.114.1 8000/TCP 28d\nkubernetes-dashboard kubernetes-dashboard ClusterIP 10.96.249.255 80/TCP 28d\n```\n\nand inside my `/etc/hosts` file I have connected 10.0.0.1 (cluster \"external\" IP) to *my-host.info*.\n\nAny ideas of why this is happening?\n\n========================================\n\nTop Answer:\nUsing Kubernetes rewrite feature for ingress I could solve my problem like this:\n\ningress.yaml:\n\n```\napiVersion: networking.k8s.io/v1\nkind: Ingress\nmetadata:\n name: my-app-ingress\n annotations:\n nginx.ingress.kubernetes.io/rewrite-target: /$2\nspec:\n rules:\n - host: my-app\n http:\n paths:\n - path: /server(/|$)(.*)\n pathType: Prefix\n backend:\n service:\n name: my-fastapi\n port:\n number: 80\n```\n\nthen I just needed to add root_path to my FastAPI app:\n\n```\napp = FastAPI(root_path=\"/server\")\n```\n\n========================================\n\nCode:\n```text\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: my-app-nginx-deployment\n labels:\n app: nginx\nspec:\n replicas: 1\n selector:\n matchLabels:\n app: nginx\n template:\n metadata:\n labels:\n app: nginx\n spec:\n containers:\n - name: nginx\n image: nginx:1.17.0\n imagePullPolicy: IfNotPresent\n ports:\n - containerPort: 80\n\n---\napiVersion: networking.k8s.io/v1beta1\nkind: Ingress\nmetadata:\n name: my-app-ingress\n annotations:\n nginx.ingress.kubernetes.io/rewrite-target: /$2\nspec:\n rules:\n - host: my-host.info\n http:\n paths:\n - path: /server(/|$)(.*)\n backend:\n serviceName: my-app-service # This is the service that runs my fastAPI server pod\n servicePort: 80\n```\n\n```text\napiVersion: v1\nkind: Service\nmetadata:\n name: my-app-service\nspec:\n type: ClusterIP\n selector:\n app: server\n ports:\n - protocol: \"TCP\"\n port: 80\n targetPort: 80\n```\n\n```text\ncurl -X GET \"http://my-host.info/server/subpath/\" -H \"accept: application/json\"\ncurl -X POST \"http://my-host.info/server/subpath/update/\" -H \"accept: application/json\"\n```\n\n```text\nNAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE\ndefault kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 11d\ndefault my-app-service ClusterIP 10.96.68.29 <none> 80/TCP 18h\nkube-system kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 28d\nkubernetes-dashboard dashboard-metrics-scraper ClusterIP 10.96.114.1 <none> 8000/TCP 28d\nkubernetes-dashboard kubernetes-dashboard ClusterIP 10.96.249.255 <none> 80/TCP 28d\n```\n\n```text\ncurl\n```\n\n```text\ncurl\n```\n\n```text\n/etc/hosts\n```\n\n```text\n- path: /server(/|$)(.*)\n backend:\n serviceName: my-app-service # This is the service that runs my fastAPI server pod\n servicePort: 80\n```\n\n```py\nfrom fastapi import FastAPI, Request\n\napp = FastAPI(openapi_prefix=\"/server\")\n\n@app.get(\"/\")\ndef read_root(request: Request):\n return {\"message\": \"Hello World\", \"root_path\": request.scope.get(\"root_path\")}\n```\n\n```py\nimport os\nfrom fastapi import FastAPI, Request\n\napp = FastAPI(openapi_prefix=os.getenv('ROOT_PATH', ''))\n\n@app.get(\"/\")\ndef read_root(request: Request):\n return {\"message\": \"Hello World\", \"root_path\": request.scope.get(\"root_path\")}\n```\n\n```text\nservice.yaml\n```\n\n```text\nroot_path\n```\n\n```text\nuvicorn main:app --root-path /server\n```\n\n```text\nmain.py\n```\n\n```text\nroot_path\n```\n\n```text\n$ROOT_PATH=/server\n```\n\n```text\nuvicorn main:app --root-path $ROOT_PATH\n```\n\n```text\nmain.py\n```\n\n```text\napiVersion: networking.k8s.io/v1\nkind: Ingress\nmetadata:\n name: my-app-ingress\n annotations:\n nginx.ingress.kubernetes.io/rewrite-target: /$2\nspec:\n rules:\n - host: my-app\n http:\n paths:\n - path: /server(/|$)(.*)\n pathType: Prefix\n backend:\n service:\n name: my-fastapi\n port:\n number: 80\n```\n\n```text\napp = FastAPI(root_path=\"/server\")\n```\n\n```text\napp = FastAPI(\n title=\"My Service API\",\n version=\"1.0.0\",\n description=\"my-service application\",\n docs_url=\"/swagger\",\n openapi_url=\"/api/v1/openapi.json\",\n redoc_url=\"/swagger/redoc\",\n root_path=\"/services/my-service\",\n)\napi_router = APIRouter(prefix=\"/api/v1\")\n```\n\n```text\napiVersion: networking.k8s.io/v1\nkind: Ingress\nmetadata:\n name: my-service-ingress\n annotations:\n nginx.ingress.kubernetes.io/rewrite-target: /$2\n nginx.ingress.kubernetes.io/use-regex: \"true\"\n\nspec:\n ingressClassName: nginx\n tls:\n - hosts:\n - \"base_url\"\n rules:\n - host: base_url\n http:\n paths:\n - path: /services/my-service(/|$)(.*)\n pathType: ImplementationSpecific\n backend:\n service:\n name: my-service-service\n port:\n number: 8001\n```\n\n========================================\n\nComments:\n- Could you please your `service` yaml and exact command you are using to curl it? You ale trying to connect from outside the cluster? Also could you provide `kubectl get svc --all-namespaces`? It's On-Prem or local cluster?\n- First issue I found here is that your deployment and service have different selectors/labels. In deployment its `app: nginx` but in svc is `app: server`. Should be the same. I will try to reproduce your issue. You can check this answer `Issue 2` - stackoverflow.com/a/59372425/11148139\n- Its On-Prem or local cluster?\n- @PjoterS I have the deployment in a separate file. The app for the server is `server` and the nginx app is a different one, at least that's the way all the examples I've seen work. If this was the problem it wouldn't have worked at all. And as I've stated it's on a local cluster. The app is functioning fully it is just the connection to the FastAPI default docs page that doesn't work.\n- @PjoterS Turns out I misunderstood the tutorials and the nginx pod I deploy is not being used at all. Instead a different pod that is deployed by my minikube is running the nginx-ingress-controller which is then used by the ingress I've defined.\n- to map service with deployment you should use labe/selector (kubernetes.io/docs/concepts/services-networking/…). As you are using Minikube and Ingress you can check this thread (stackoverflow.com/a/60061508/1114813)). What will happen if you will use the same labels/selectors in delployment and svc?","metadata":{"transformedAt":"2026-08-18T18:32:29.118Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":22,"totalLines":355,"estimatedTokens":2310}}265{"id":"stack-74070505","source":"stackoverflow","questionId":74070505,"title":"How to run FastAPI application inside Jupyter","tags":["python","jupyter-notebook","fastapi","uvicorn"],"text":"Title: How to run FastAPI application inside Jupyter\nTags: python, jupyter-notebook, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI have this example:\n\n```\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/\")\nasync def root():\n return {\"message\": \"Hello World\"}\n```\n\nI saved the script as `main.ipynb`\n\nThe tutorial says to run this line of code in the command line: `uvicorn main:app --reload`\n\nI am getting this error:\n\n```\n(venv) PS C:\\Users\\xxx\\xxxx> uvicorn main:app --reload\nINFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\nINFO: Started reloader process [21304] using WatchFiles\nERROR: Error loadinimport module \"main\".INFO: Stopping reloader process [21304]\n```\n\nThe reason is because I am using `.ipynb` as opposed to `.py`.\n\nHow can i fix this error while using .ipynb?\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/\")\nasync def root():\n return {\"message\": \"Hello World\"}\n```\n\n```text\n(venv) PS C:\\Users\\xxx\\xxxx> uvicorn main:app --reload\nINFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\nINFO: Started reloader process [21304] using WatchFiles\nERROR: Error loadinimport module \"main\".INFO: Stopping reloader process [21304]\n```\n\n```text\nmain.ipynb\n```\n\n```text\nuvicorn main:app --reload\n```\n\n```text\n.ipynb\n```\n\n```text\n.py\n```\n\n```py\nimport uvicorn\n\nif __name__ == \"__main__\":\n uvicorn.run(app)\n```\n\n```text\nRuntimeError: asyncio.run() cannot be called from a running event loop\n```\n\n```py\nimport asyncio\nimport uvicorn\n\nif __name__ == \"__main__\":\n config = uvicorn.Config(app)\n server = uvicorn.Server(config)\n await server.serve()\n```\n\n```py\nimport asyncio\nimport uvicorn\n\nif __name__ == \"__main__\":\n config = uvicorn.Config(app)\n server = uvicorn.Server(config)\n loop = asyncio.get_running_loop()\n loop.create_task(server.serve())\n```\n\n```py\nimport nest_asyncio\nimport uvicorn\n\nif __name__ == \"__main__\":\n nest_asyncio.apply()\n uvicorn.run(app)\n```\n\n```text\nasyncio.run()\n```\n\n```text\nasyncio.run()\n```\n\n```text\nasyncio\n```\n\n```text\nasyncio\n```\n\n```text\nuvicorn\n```\n\n```text\nasync\n```\n\n```text\nuvicorn.Server.serve()\n```\n\n```text\nasyncio.get_running_loop()\n```\n\n```text\nloop.create_task()\n```\n\n```text\nnest_asyncio\n```\n\n```text\nasyncio.run()\n```\n\n```text\nloop.run_until_complete()\n```\n\n========================================\n\nComments:\n- Does this answer your question? How to run FastAPI / Uvicorn in Google Colab?\n- Thanks a lot. The code is taking a while to run. is it normal? What does the code do?\n- It should normally start the server right away. Try restarting the Jupyter kernel and see if it fixes it. I have also updated the answer above with more details and solutions on the issue.\n- Thanks it still taking a while ...very strange I have a 16 RAM of memory. Maybe I should just stick to .py\n- The URL is running fine now ...I get HTTP response 200 OK.","metadata":{"transformedAt":"2026-08-18T18:32:29.118Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":23,"totalLines":167,"estimatedTokens":738}}266{"id":"stack-70775544","source":"stackoverflow","questionId":70775544,"title":"Authenticate FastAPI with clientid/clientsecret","tags":["keycloak","fastapi"],"text":"Title: Authenticate FastAPI with clientid/clientsecret\nTags: keycloak, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm trying to set up FastAPI (0.71.0) authentication with clientid-clientsecret.\n\nI configured `OAuth2AuthorizationCodeBearer` and apparently from the swagger (`/docs`) endpoint it looks fine, it asks for client-id and client-secret for authentication.\n\n```\nauth = OAuth2PasswordBearer(\n authorizationUrl=AUTH_URL,\n tokenUrl=TOKEN_URL,\n)\n\nagent = FastAPI(\n description=_DESCRIPTION,\n version=VERSION,\n dependencies=[Depends(auth)],\n middleware=middlewares,\n root_path=os.getenv('BASEPATH', '/'),\n swagger_ui_init_oauth={\n 'usePkceWithAuthorizationCodeGrant': True,\n 'scopes': 'openid profile email'\n }\n)\n```\n\nHowever calling the API directly I can access with any Bearer such as:\n\n```\nimport requests\n\nurl = 'http://localhost:8080/test'\nheaders = {'Authorization': 'Bearer BADTOKEN', 'Content-Type': 'application/json', 'Accept': 'application/json'}\nresponse = requests.get(url=url, params={}, headers=headers)\n```\n\nand `response.ok = True`, so I might be missing something in FastAPI settings but cannot see where.\n\nIs this the correct authentication flow?\n\nPS: What I want to achieve is service to service communication, so the API is not getting accessed by a regular user\n\n========================================\n\nTop Answer:\n```\nfrom fastapi import FastAPI, Depends, HTTPException\nfrom fastapi.security import OAuth2AuthorizationCodeBearer\nimport uvicorn\nfrom jose import JOSEError,jwt\nimport requests\n\nISSUER_URL=\"http://localhost:8083/realms/realmname\"\napp = FastAPI()\n\noauth_2_scheme = OAuth2AuthorizationCodeBearer(\n tokenUrl=\"http://localhost:8083/realms/realmname/protocol/openid-connect/token\",\n authorizationUrl=\"http://localhost:8083/realms/realmname/protocol/openid-connect/auth\")\n\npublic_key = requests.get(ISSUER_URL).json().get('public_key')\nkey = '-----BEGIN PUBLIC KEY-----\\n' + public_key + '\\n-----END PUBLIC KEY-----'\n\ndef valid_access_token(token: str | None = Depends(oauth_2_scheme)):\n try:\n jwt.decode(\n token,\n key=key,\n options={\n \"verify_signature\": True,\n \"verify_aud\": False,\n \"verify_iss\": ISSUER_URL\n }\n )\n except JOSEError as e: # catches any exception\n raise HTTPException(\n status_code=401,\n detail=str(e))\n\n@app.get(\"/public\")\ndef get_public():\n return {\"message\": \"This endpoint is public\"}\n\n@app.get(\"/private\", dependencies=[Depends(valid_access_token)])\ndef get_private():\n return {\"message\": \"This endpoint is private\"}\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", port=8034)\n```\n\n========================================\n\nCode:\n```py\nauth = OAuth2PasswordBearer(\n authorizationUrl=AUTH_URL,\n tokenUrl=TOKEN_URL,\n)\n\nagent = FastAPI(\n description=_DESCRIPTION,\n version=VERSION,\n dependencies=[Depends(auth)],\n middleware=middlewares,\n root_path=os.getenv('BASEPATH', '/'),\n swagger_ui_init_oauth={\n 'usePkceWithAuthorizationCodeGrant': True,\n 'scopes': 'openid profile email'\n }\n)\n```\n\n```py\nimport requests\n\nurl = 'http://localhost:8080/test'\nheaders = {'Authorization': 'Bearer BADTOKEN', 'Content-Type': 'application/json', 'Accept': 'application/json'}\nresponse = requests.get(url=url, params={}, headers=headers)\n```\n\n```text\nOAuth2AuthorizationCodeBearer\n```\n\n```text\n/docs\n```\n\n```text\nresponse.ok = True\n```\n\n```py\npublic_key = requests.get(ISSUER_URL).json().get('public_key')\nkey = '-----BEGIN PUBLIC KEY-----\\n' + public_key + '\\n-----END PUBLIC KEY-----'\n\noauth = OAuth2AuthorizationCodeBearer(\n authorizationUrl=AUTH_URL,\n tokenUrl=TOKEN_URL,\n)\nasync def auth(token: str | None = Depends(oauth)):\n try:\n jwt.decode(\n token,\n key=key,\n options={\n \"verify_signature\": True,\n \"verify_aud\": False,\n \"verify_iss\": ISSUER_URL\n }\n )\n except JOSEError as e: # catches any exception\n raise HTTPException(\n status_code=401,\n detail=str(e))\n```\n\n```text\nOAuth2AuthorizationCodeBearer\n```\n\n```text\nfrom fastapi import FastAPI, Depends, HTTPException\nfrom fastapi.security import OAuth2AuthorizationCodeBearer\nimport uvicorn\nfrom jose import JOSEError,jwt\nimport requests\n\nISSUER_URL=\"http://localhost:8083/realms/realmname\"\napp = FastAPI()\n\n\noauth_2_scheme = OAuth2AuthorizationCodeBearer(\n tokenUrl=\"http://localhost:8083/realms/realmname/protocol/openid-connect/token\",\n authorizationUrl=\"http://localhost:8083/realms/realmname/protocol/openid-connect/auth\")\n\npublic_key = requests.get(ISSUER_URL).json().get('public_key')\nkey = '-----BEGIN PUBLIC KEY-----\\n' + public_key + '\\n-----END PUBLIC KEY-----'\n\ndef valid_access_token(token: str | None = Depends(oauth_2_scheme)):\n try:\n jwt.decode(\n token,\n key=key,\n options={\n \"verify_signature\": True,\n \"verify_aud\": False,\n \"verify_iss\": ISSUER_URL\n }\n )\n except JOSEError as e: # catches any exception\n raise HTTPException(\n status_code=401,\n detail=str(e))\n\n@app.get(\"/public\")\ndef get_public():\n return {\"message\": \"This endpoint is public\"}\n\n\n@app.get(\"/private\", dependencies=[Depends(valid_access_token)])\ndef get_private():\n return {\"message\": \"This endpoint is private\"}\n\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", port=8034)\n```\n\n========================================\n\nComments:\n- As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.","metadata":{"transformedAt":"2026-08-18T18:32:29.118Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":8,"totalLines":215,"estimatedTokens":1431}}267{"id":"stack-61688444","source":"stackoverflow","questionId":61688444,"title":"What happens to existing awaits when WebSocket.close is called","tags":["python","websocket","python-asyncio","fastapi","starlette"],"text":"Title: What happens to existing awaits when WebSocket.close is called\nTags: python, websocket, python-asyncio, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nIf I open a Starlette/FastAPI WebSocket, what happens to any coroutines currently waiting to receive data from the client if I close the WebSocket from outside the coroutine? Does the call to `receive` raise an exception or does the coroutine sit in memory forever because it is never going to receive anything?\n\n```\nfrom fastapi import FastAPI\nfrom fastapi.websockets import WebSocket\n\napp = FastAPI()\n\nopen_sockets = {}\n\n@app.websocket('/connection/')\nasync def connection(websocket: WebSocket):\n await websocket.accept()\n\n id = await websocket.receive_json()['id']\n open_sockets[id] = websocket\n\n while True:\n data = await websocket.receive_json()\n\n@app.post('/kill/{id}/')\nasync def kill(id=str):\n # What does this do to the above `await websocket.receive_json()`?\n await open_sockets[id].close()\n del open_sockets[id]\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nfrom fastapi.websockets import WebSocket\n\napp = FastAPI()\n\nopen_sockets = {}\n\n@app.websocket('/connection/')\nasync def connection(websocket: WebSocket):\n await websocket.accept()\n\n id = await websocket.receive_json()['id']\n open_sockets[id] = websocket\n\n while True:\n data = await websocket.receive_json()\n\n@app.post('/kill/{id}/')\nasync def kill(id=str):\n # What does this do to the above `await websocket.receive_json()`?\n await open_sockets[id].close()\n del open_sockets[id]\n```\n\n```text\nreceive\n```\n\n```text\nFile \".\\websocket_close_test.py\", line 27, in connection\n data = await websocket.receive_json()\n File \"C:\\Apps\\Python38\\lib\\site-packages\\starlette\\websockets.py\", line 98, in receive_json\n self._raise_on_disconnect(message)\n File \"C:\\Apps\\Python38\\lib\\site-packages\\starlette\\websockets.py\", line 80, in _raise_on_disconnect\n raise WebSocketDisconnect(message[\"code\"])\n```\n\n```py\nimport time\n\nimport requests\nimport websocket\n\nws = websocket.WebSocket()\nws.connect(\"ws://localhost:8000/connection/\")\nprint('Sending id 0')\nws.send('{ \"id\": \"0\" }')\ntime.sleep(2)\nprint('Closing id 0')\nrequests.post('http://localhost:8000/kill/0/')\nprint('id 0 is closed')\ntime.sleep(2)\nprint('Trying to send data on closed connection')\nws.send('{ \"id\": \"10\" }')\n```\n\n```text\nstarlette.websockets.WebSocketDisconnect\n```\n\n```text\nws.send\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.118Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":6,"totalLines":99,"estimatedTokens":613}}268{"id":"stack-66332049","source":"stackoverflow","questionId":66332049,"title":"How do I authenticate with HTTP Digest?","tags":["python","authentication","fastapi","digest-authentication"],"text":"Title: How do I authenticate with HTTP Digest?\nTags: python, authentication, fastapi, digest-authentication\nSource: Stack Overflow\n\nQuestion:\nI'm currently authenticating with basic, following this tutorial:\n\n```\nimport secrets\n\nfrom fastapi import FastAPI, Depends, HTTPException, status\nfrom fastapi.security import HTTPBasic, HTTPBasicCredentials,\n\nhttp_basic = HTTPBasic()\n\ndef authorize_basic(credentials: HTTPBasicCredentials = Depends(http_basic)):\n correct_username = secrets.compare_digest(credentials.username, \"test\")\n correct_password = secrets.compare_digest(credentials.password, \"test\")\n if not (correct_username and correct_password):\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Incorrect username or password\",\n headers={\"WWW-Authenticate\": \"Basic\"},\n )\n\n@app.get(\"/auth/\", dependencies=[Depends(authorize_basic)])\ndef auth():\n return {\"success\": \"true\"}\n```\n\nHow do I use HTTPDigest instead?\n\n========================================\n\nTop Answer:\nFollowing my comment in rednafi's answer: to make the browser prompt the input of credentials in HTTP Digest Auth, two conditions have to be met.\n\nThe response status code is `401 Unauthorized`\n\nThe response header contains proper `WWW-Authenticate`\n\nUnfortunately `headers={\"WWW-Authenticate\": \"Digest\"}` is not considered \"proper\" enough (at least by my Edge chromium), probably because it doesn't tell the browser which algorithm for digest to use. My testing shows at least `nonce` and `realm` are required.\n\nOne can refer to the wiki for HTTP Digest Auth for details of how the digest algorithm works. I didn't find any material about using Base64 encoding in the digest as in the example test-suites posted by rednafi. MDN says the algorithm should be `MD5` or one of `SHA` family.\n\nOf course you are fine with it if you manually specify the `Autherization` headers in every request. But if you want to use the browser's prompt to input credentials, here is an working example:\n\n```\nfrom pydantic import BaseModel, ValidationError\nfrom ..config import AppSettings, get_config\nfrom fastapi.security import (\n HTTPDigest,\n HTTPAuthorizationCredentials,\n)\nfrom fastapi import Depends, HTTPException, Request, Security\nfrom fastapi.responses import JSONResponse\nimport secrets\nimport base64\nfrom hashlib import md5\nfrom typing import Annotated\n\nsecurity = HTTPDigest(auto_error=False)\n\nclass HTTPDigestCredentials(BaseModel):\n username: str\n realm: str\n nonce: str\n uri: str\n response: str\n\n @classmethod\n def from_digest_line(cls, digest_line: str):\n \"\"\"Parse the digest line and return a dict of fields\"\"\"\n cred_dict = {}\n\n try:\n cred_fields = [s.strip() for s in digest_line.split(\",\")]\n for field, value in [s.split(\"=\", maxsplit=1) for s in cred_fields]:\n # remove quotes\n cred_dict[field] = value.strip('\"')\n \n cred_obj = cls.model_validate(cred_dict)\n\n except (ValueError, ValidationError):\n return None\n \n return cred_obj\n\nasync def auth_admin(\n request: Request,\n credentials: Annotated[HTTPAuthorizationCredentials, Security(security)],\n config: AppSettings = Depends(get_config),\n):\n \"\"\" \"\"\"\n # http digest headers\n digest_params = {\n \"realm\": \"admin-panel\",\n # \"qop\": \"auth\",\n # \"algorithm\": \"SHA-256\",\n \"nonce\": secrets.token_hex(8),\n # \"opaque\": secrets.token_hex(8),\n }\n digest_line = \",\".join(\n f'{key}=\"{value}\"' for key, value in digest_params.items()\n )\n\n login_fail_exception = HTTPException(\n 401,\n detail=\"Invalid authentication credentials\",\n headers={\"WWW-Authenticate\": f'Digest {digest_line}'},\n )\n\n # if no Authorization header is present, credentials will be None\n if credentials is None:\n raise login_fail_exception\n \n # we use pydantic to validate the requested credential strings\n current_cred = HTTPDigestCredentials.from_digest_line(credentials.credentials)\n if current_cred is None:\n raise login_fail_exception\n\n # caluculate response\n # https://en.wikipedia.org/wiki/Digest_access_authentication#Overview\n admin_config = config.ADMIN_PANEL\n \n # We don't store plain passwords but HA1 instead\n # HA1 = md5(f\"{admin_config.username}:{admin_config.realm}:{admin_config.password}\".encode()).hexdigest()\n HA1 = admin_config.token\n HA2 = md5(f\"{request.method}:{current_cred.uri}\".encode()).hexdigest()\n expected_response = md5(f\"{HA1}:{current_cred.nonce}:{HA2}\".encode()).hexdigest()\n\n correct_token = secrets.compare_digest(current_cred.response, expected_response)\n\n if not correct_token:\n raise login_fail_exception\n\n return JSONResponse({\"user\": admin_config.username})\n```\n\nIn this example, I used the default `algorithm` and `qop`, which is based on `MD5`. The first part `MD5(username:realm:password)` contains all credentials (you probably want to store this hash instead of plain username/password), and the second part `{method}:{uri}` depends on request. `nonce` is dynamically generated to prevent replay attacks.\n\nThe credentials extracted by `HTTPAuthorizationCredentials` is actually a strings with format `xx=\"xxx\", yy=yyy`. I ended up processing it on my own, but I really think this should be part of the `fastapi` project, perhaps with a separate `HTTPDigestCredentials` class or similar.\n\n========================================\n\nCode:\n```text\nimport secrets\n\nfrom fastapi import FastAPI, Depends, HTTPException, status\nfrom fastapi.security import HTTPBasic, HTTPBasicCredentials,\n\nhttp_basic = HTTPBasic()\n\ndef authorize_basic(credentials: HTTPBasicCredentials = Depends(http_basic)):\n correct_username = secrets.compare_digest(credentials.username, \"test\")\n correct_password = secrets.compare_digest(credentials.password, \"test\")\n if not (correct_username and correct_password):\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Incorrect username or password\",\n headers={\"WWW-Authenticate\": \"Basic\"},\n )\n\n@app.get(\"/auth/\", dependencies=[Depends(authorize_basic)])\ndef auth():\n return {\"success\": \"true\"}\n```\n\n```py\nimport base64\nimport secrets\n\nfrom fastapi import Depends, FastAPI, HTTPException, Security, status\nfrom fastapi.security import HTTPAuthorizationCredentials, HTTPDigest\n\nhttp_digest = HTTPDigest()\n\napp = FastAPI()\n\n\ndef authorize_digest(credentials: HTTPAuthorizationCredentials = Security(http_digest)):\n # Credentials returns the token as string.\n incoming_token = credentials.credentials\n\n # Let's say you want to generate the digest token from username and pass.\n expected_username = \"test\"\n expected_password = \"test\"\n\n # Digest tokens are encoded via base64 encoding algo.\n expected_token = base64.standard_b64encode(\n bytes(f\"{expected_username}:{expected_password}\", encoding=\"UTF-8\"),\n )\n\n correct_token = secrets.compare_digest(\n bytes(incoming_token, encoding=\"UTF-8\"),\n expected_token,\n )\n if not correct_token:\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Incorrect digest token\",\n headers={\"WWW-Authenticate\": \"Digest\"},\n )\n\n\n@app.get(\"/auth/\", dependencies=[Depends(authorize_digest)])\ndef auth():\n return {\"success\": \"true\"}\n```\n\n```text\npython -c 'import base64; h = base64.urlsafe_b64encode(b\"test:test\"); print(h)'\n```\n\n```text\nb'dGVzdDp0ZXN0'\n```\n\n```text\ncurl -X 'GET' 'http://localhost:5000/auth/' \\\n -H 'accept: application/json' \\\n -H \"Authorization: Digest dGVzdDp0ZXN0\" \\\n -H 'Content-Type: application/json' \\\n```\n\n```text\n{\"success\":\"true\"}\n```\n\n```text\ntest\n```\n\n```py\nfrom pydantic import BaseModel, ValidationError\nfrom ..config import AppSettings, get_config\nfrom fastapi.security import (\n HTTPDigest,\n HTTPAuthorizationCredentials,\n)\nfrom fastapi import Depends, HTTPException, Request, Security\nfrom fastapi.responses import JSONResponse\nimport secrets\nimport base64\nfrom hashlib import md5\nfrom typing import Annotated\n\nsecurity = HTTPDigest(auto_error=False)\n\nclass HTTPDigestCredentials(BaseModel):\n username: str\n realm: str\n nonce: str\n uri: str\n response: str\n\n @classmethod\n def from_digest_line(cls, digest_line: str):\n \"\"\"Parse the digest line and return a dict of fields\"\"\"\n cred_dict = {}\n\n try:\n cred_fields = [s.strip() for s in digest_line.split(\",\")]\n for field, value in [s.split(\"=\", maxsplit=1) for s in cred_fields]:\n # remove quotes\n cred_dict[field] = value.strip('\"')\n \n cred_obj = cls.model_validate(cred_dict)\n\n except (ValueError, ValidationError):\n return None\n \n return cred_obj\n\n\nasync def auth_admin(\n request: Request,\n credentials: Annotated[HTTPAuthorizationCredentials, Security(security)],\n config: AppSettings = Depends(get_config),\n):\n \"\"\" \"\"\"\n # http digest headers\n digest_params = {\n \"realm\": \"admin-panel\",\n # \"qop\": \"auth\",\n # \"algorithm\": \"SHA-256\",\n \"nonce\": secrets.token_hex(8),\n # \"opaque\": secrets.token_hex(8),\n }\n digest_line = \",\".join(\n f'{key}=\"{value}\"' for key, value in digest_params.items()\n )\n\n login_fail_exception = HTTPException(\n 401,\n detail=\"Invalid authentication credentials\",\n headers={\"WWW-Authenticate\": f'Digest {digest_line}'},\n )\n\n # if no Authorization header is present, credentials will be None\n if credentials is None:\n raise login_fail_exception\n \n # we use pydantic to validate the requested credential strings\n current_cred = HTTPDigestCredentials.from_digest_line(credentials.credentials)\n if current_cred is None:\n raise login_fail_exception\n\n # caluculate response\n # https://en.wikipedia.org/wiki/Digest_access_authentication#Overview\n admin_config = config.ADMIN_PANEL\n \n # We don't store plain passwords but HA1 instead\n # HA1 = md5(f\"{admin_config.username}:{admin_config.realm}:{admin_config.password}\".encode()).hexdigest()\n HA1 = admin_config.token\n HA2 = md5(f\"{request.method}:{current_cred.uri}\".encode()).hexdigest()\n expected_response = md5(f\"{HA1}:{current_cred.nonce}:{HA2}\".encode()).hexdigest()\n\n correct_token = secrets.compare_digest(current_cred.response, expected_response)\n\n if not correct_token:\n raise login_fail_exception\n\n return JSONResponse({\"user\": admin_config.username})\n```\n\n```text\n401 Unauthorized\n```\n\n```text\nWWW-Authenticate\n```\n\n```text\nheaders={\"WWW-Authenticate\": \"Digest\"}\n```\n\n```text\nnonce\n```\n\n```text\nrealm\n```\n\n```text\nMD5\n```\n\n```text\nSHA\n```\n\n```text\nAutherization\n```\n\n```text\nalgorithm\n```\n\n```text\nqop\n```\n\n```text\nMD5\n```\n\n```text\nMD5(username:realm:password)\n```\n\n```text\n{method}:{uri}\n```\n\n```text\nnonce\n```\n\n```text\nHTTPAuthorizationCredentials\n```\n\n```text\nxx=\"xxx\", yy=yyy\n```\n\n```text\nfastapi\n```\n\n```text\nHTTPDigestCredentials\n```\n\n========================================\n\nComments:\n- The header `headers={\"WWW-Authenticate\": \"Digest\"}` does not trigger the prompt to enter credentials on my chromium browser. I guess additional field is required to specify the algorithems and additional parameters. wikipedia.","metadata":{"transformedAt":"2026-08-18T18:32:29.118Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":26,"totalLines":403,"estimatedTokens":2779}}269{"id":"stack-79673866","source":"stackoverflow","questionId":79673866,"title":"How to generate a tar.gz stream to be returned as a StreamingResponse in FastAPI/Starlette?","tags":["python","python-3.x","python-asyncio","fastapi","starlette"],"text":"Title: How to generate a tar.gz stream to be returned as a StreamingResponse in FastAPI/Starlette?\nTags: python, python-3.x, python-asyncio, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nI'm making an FastAPI/Starlette server which requests to another server (well, S3) large files. These chunks feed a `tarfile.TarFile` object to produce a `.tar.gz` stream. This stream should be sent on the fly to a `StreamingResponse`.\n\n```\nS3 server --files chunks--> My server --tar.gz chunks--> User\n```\n\nThere is a big issue with the tarfile.TarFile implementation as:\n\n### it writes chunks in file-like objects (with a `write` method),\n\nThis is not easy to be interfaced with the `stralette.StreamingResponse` which expects a chunk generator.\n\nMy idea was to rewrite the `StreamingResponse.stream_response` method (cf here). Something like this:\n\n```\n\"\"\"A script to test the tar.gz streaming.\"\"\"\n\nimport os\nimport tarfile\nfrom pathlib import Path\nfrom typing import Mapping\n\nfrom fastapi import FastAPI\nfrom fastapi.responses import StreamingResponse\nfrom fastapi.testclient import TestClient\nfrom starlette.background import BackgroundTask\nfrom starlette.types import Send\n\nTAR_FILE_PATH = Path(\"archive.tar.gz\")\n\nCHUNK_SIZE = 1024\n\napp = FastAPI()\n\nclass FileStreamingResponse(StreamingResponse):\n\n def __init__(\n self,\n files_to_tar: list[Path],\n status_code: int = 200,\n headers: Mapping[str, str] | None = None,\n media_type: str | None = None,\n background: BackgroundTask | None = None,\n ) -> None:\n self.files_to_tar = files_to_tar\n self.status_code = status_code\n self.media_type = self.media_type if media_type is None else media_type\n self.background = background\n self.init_headers(headers)\n\n async def stream_response(self, send: Send) -> None:\n await send(\n {\n \"type\": \"http.response.start\",\n \"status\": self.status_code,\n \"headers\": self.raw_headers,\n }\n )\n\n class DumpWriter:\n async def write(buffer):\n print(f\"Really sending {len(buffer)} bytes\")\n await send(\n {\"type\": \"http.response.body\", \"body\": buffer, \"more_body\": True}\n )\n\n async with tarfile.open(\n mode=\"w|gz\", fileobj=DumpWriter(), bufsize=CHUNK_SIZE\n ) as file:\n for input_file in self.files_to_tar:\n await file.add(input_file.open(\"rb\"))\n\n await send({\"type\": \"http.response.body\", \"body\": b\"\", \"more_body\": False})\n\nFILES_TO_TAR = Path(\"src\").iterdir()\n\n@app.get(\"/\")\ndef send_tar() -> StreamingResponse:\n \"\"\"Send a tar file.\"\"\"\n\n return FileStreamingResponse(\n files_to_tar=FILES_TO_TAR,\n media_type=\"application/tar+gzip\",\n headers={\"Content-Disposition\": f'attachment; filename=\"{TAR_FILE_PATH.name}\"'},\n )\n\n#\n# TESTS\n#\n\nTEST_TAR_FILE_PATH = Path(\"archive.tar.gz\")\nclient = TestClient(app)\n\ndef test_main():\n if TEST_TAR_FILE_PATH.exists():\n os.remove(TEST_TAR_FILE_PATH)\n\n response = client.get(\"/\")\n response.raise_for_status()\n\n with TEST_TAR_FILE_PATH.open(\"wb\") as file:\n for chunk in response.iter_bytes(CHUNK_SIZE):\n file.write(chunk)\n\n with tarfile.open(TEST_TAR_FILE_PATH, \"r:gz\") as tar_file:\n files = [tarinfo.name for tarinfo in tar_file.getmembers()]\n\n src_files = [file.name for file in FILES_TO_TAR]\n assert set(files) == set(src_files)\n```\n\nbut the issue is that...\n\n### it writes them *synchronuosly*\n\nOk, then to write it correctly, I need to run the `DumpWriter.write` method synchronously? I tried to do\n\n```\nclass DumpWriter:\n def write(buffer):\n print(f\"Really sending {len(buffer)} bytes\")\n asyncio.run_coroutine_threadsafe(\n send(\n {\n \"type\": \"http.response.body\",\n \"body\": buffer,\n \"more_body\": True,\n }\n ),\n asyncio.get_running_loop(),\n )\n```\n\nbut the data chunks were not transmitted.\n\nI also thought to rewrite the TarFile class to be async, but this is a nightmare!\n\nHow can I achieve that?\n\n**EDIT**\n\nHere is a MWE (run `pytest main.py`)\n\n```\n\"\"\"A script to test the tar.gz streaming.\"\"\"\n\nimport asyncio\nimport os\nimport tarfile\nfrom pathlib import Path\nfrom typing import Mapping\n\nfrom fastapi import FastAPI\nfrom fastapi.responses import StreamingResponse\nfrom fastapi.testclient import TestClient\nfrom starlette.background import BackgroundTask\nfrom starlette.types import Send\n\nTAR_FILE_PATH = Path(\"archive.tar.gz\")\n\nCHUNK_SIZE = 1024\n\napp = FastAPI()\n\nFILES_TO_TAR = [(\"tarfile.py\", Path(tarfile.__file__)), (\"os.py\", Path(os.__file__))]\n\nclass FileStreamingResponse(StreamingResponse):\n\n def __init__(\n self,\n files_to_tar: list[tuple[str, Path]],\n status_code: int = 200,\n headers: Mapping[str, str] | None = None,\n media_type: str | None = None,\n background: BackgroundTask | None = None,\n ) -> None:\n self.files_to_tar = files_to_tar\n self.status_code = status_code\n self.media_type = self.media_type if media_type is None else media_type\n self.background = background\n self.init_headers(headers)\n\n async def stream_response(self, send: Send) -> None:\n await send(\n {\n \"type\": \"http.response.start\",\n \"status\": self.status_code,\n \"headers\": self.raw_headers,\n }\n )\n\n class DumpWriter:\n def write(self, buffer):\n print(f\"Really sending {len(buffer)} bytes\")\n asyncio.run_coroutine_threadsafe(\n send(\n {\n \"type\": \"http.response.body\",\n \"body\": buffer,\n \"more_body\": True,\n }\n ),\n asyncio.get_running_loop(),\n )\n\n async with tarfile.open(\n mode=\"w|gz\", fileobj=DumpWriter(), bufsize=CHUNK_SIZE\n ) as file:\n for name, input_path in self.files_to_tar:\n await file.addfile(tarfile.TarInfo(name), input_path.open(\"rb\"))\n\n await send({\"type\": \"http.response.body\", \"body\": b\"\", \"more_body\": False})\n\n@app.get(\"/\")\ndef send_tar() -> StreamingResponse:\n \"\"\"Send a tar file.\"\"\"\n\n return FileStreamingResponse(\n files_to_tar=FILES_TO_TAR,\n media_type=\"application/tar+gzip\",\n headers={\"Content-Disposition\": f'attachment; filename=\"{TAR_FILE_PATH.name}\"'},\n )\n\n#\n# TESTS\n#\n\nTEST_TAR_FILE_PATH = Path(\"archive.tar.gz\")\nclient = TestClient(app)\n\ndef test_main():\n if TEST_TAR_FILE_PATH.exists():\n os.remove(TEST_TAR_FILE_PATH)\n\n response = client.get(\"/\")\n response.raise_for_status()\n\n with TEST_TAR_FILE_PATH.open(\"wb\") as file:\n for chunk in response.iter_bytes(CHUNK_SIZE):\n file.write(chunk)\n\n with tarfile.open(TEST_TAR_FILE_PATH, \"r:gz\") as tar_file:\n files = [tarinfo.name for tarinfo in tar_file.getmembers()]\n\n src_files_names = [file[0] for file in FILES_TO_TAR]\n assert set(files) == set(src_files_names)\n```\n\nAs explained earlier, I get this kind of error:\n\n```\n> async with tarfile.open(\n mode=\"w|gz\", fileobj=DumpWriter(), bufsize=CHUNK_SIZE\n ) as file:\nE TypeError: 'TarFile' object does not support the asynchronous context manager protocol\n```\n\nMy issue here is that I would need\n\n- or to make tarfile write asynchronously in its fileobjet (but in stream mode, it writes via a sub `_Stream` object which is not asynchronous either),\n\n- or to run the `DumpWriter.write` synchronously but running the inner `send` function asynchronously (my previous tests gave strange results, as if it was not transmitting data. Yet, I'm not really good with loops, threads etc)\n\n- or to make the `tarfile.addfile` method yield written chunks as a generator to be provided to the original `StreamResponse` class.\n\nI can't figure out which solution to use and how to make that.\n\nHelp!\n\n========================================\n\nCode:\n```text\nS3 server --files chunks--> My server --tar.gz chunks--> User\n```\n\n```py\n\"\"\"A script to test the tar.gz streaming.\"\"\"\n\nimport os\nimport tarfile\nfrom pathlib import Path\nfrom typing import Mapping\n\nfrom fastapi import FastAPI\nfrom fastapi.responses import StreamingResponse\nfrom fastapi.testclient import TestClient\nfrom starlette.background import BackgroundTask\nfrom starlette.types import Send\n\nTAR_FILE_PATH = Path(\"archive.tar.gz\")\n\nCHUNK_SIZE = 1024\n\napp = FastAPI()\n\n\nclass FileStreamingResponse(StreamingResponse):\n\n def __init__(\n self,\n files_to_tar: list[Path],\n status_code: int = 200,\n headers: Mapping[str, str] | None = None,\n media_type: str | None = None,\n background: BackgroundTask | None = None,\n ) -> None:\n self.files_to_tar = files_to_tar\n self.status_code = status_code\n self.media_type = self.media_type if media_type is None else media_type\n self.background = background\n self.init_headers(headers)\n\n async def stream_response(self, send: Send) -> None:\n await send(\n {\n \"type\": \"http.response.start\",\n \"status\": self.status_code,\n \"headers\": self.raw_headers,\n }\n )\n\n class DumpWriter:\n async def write(buffer):\n print(f\"Really sending {len(buffer)} bytes\")\n await send(\n {\"type\": \"http.response.body\", \"body\": buffer, \"more_body\": True}\n )\n\n async with tarfile.open(\n mode=\"w|gz\", fileobj=DumpWriter(), bufsize=CHUNK_SIZE\n ) as file:\n for input_file in self.files_to_tar:\n await file.add(input_file.open(\"rb\"))\n\n await send({\"type\": \"http.response.body\", \"body\": b\"\", \"more_body\": False})\n\n\nFILES_TO_TAR = Path(\"src\").iterdir()\n\n\n@app.get(\"/\")\ndef send_tar() -> StreamingResponse:\n \"\"\"Send a tar file.\"\"\"\n\n return FileStreamingResponse(\n files_to_tar=FILES_TO_TAR,\n media_type=\"application/tar+gzip\",\n headers={\"Content-Disposition\": f'attachment; filename=\"{TAR_FILE_PATH.name}\"'},\n )\n\n\n#\n# TESTS\n#\n\nTEST_TAR_FILE_PATH = Path(\"archive.tar.gz\")\nclient = TestClient(app)\n\n\ndef test_main():\n if TEST_TAR_FILE_PATH.exists():\n os.remove(TEST_TAR_FILE_PATH)\n\n response = client.get(\"/\")\n response.raise_for_status()\n\n with TEST_TAR_FILE_PATH.open(\"wb\") as file:\n for chunk in response.iter_bytes(CHUNK_SIZE):\n file.write(chunk)\n\n with tarfile.open(TEST_TAR_FILE_PATH, \"r:gz\") as tar_file:\n files = [tarinfo.name for tarinfo in tar_file.getmembers()]\n\n src_files = [file.name for file in FILES_TO_TAR]\n assert set(files) == set(src_files)\n```\n\n```py\nclass DumpWriter:\n def write(buffer):\n print(f\"Really sending {len(buffer)} bytes\")\n asyncio.run_coroutine_threadsafe(\n send(\n {\n \"type\": \"http.response.body\",\n \"body\": buffer,\n \"more_body\": True,\n }\n ),\n asyncio.get_running_loop(),\n )\n```\n\n```py\n\"\"\"A script to test the tar.gz streaming.\"\"\"\n\nimport asyncio\nimport os\nimport tarfile\nfrom pathlib import Path\nfrom typing import Mapping\n\nfrom fastapi import FastAPI\nfrom fastapi.responses import StreamingResponse\nfrom fastapi.testclient import TestClient\nfrom starlette.background import BackgroundTask\nfrom starlette.types import Send\n\nTAR_FILE_PATH = Path(\"archive.tar.gz\")\n\nCHUNK_SIZE = 1024\n\napp = FastAPI()\n\nFILES_TO_TAR = [(\"tarfile.py\", Path(tarfile.__file__)), (\"os.py\", Path(os.__file__))]\n\n\nclass FileStreamingResponse(StreamingResponse):\n\n def __init__(\n self,\n files_to_tar: list[tuple[str, Path]],\n status_code: int = 200,\n headers: Mapping[str, str] | None = None,\n media_type: str | None = None,\n background: BackgroundTask | None = None,\n ) -> None:\n self.files_to_tar = files_to_tar\n self.status_code = status_code\n self.media_type = self.media_type if media_type is None else media_type\n self.background = background\n self.init_headers(headers)\n\n async def stream_response(self, send: Send) -> None:\n await send(\n {\n \"type\": \"http.response.start\",\n \"status\": self.status_code,\n \"headers\": self.raw_headers,\n }\n )\n\n class DumpWriter:\n def write(self, buffer):\n print(f\"Really sending {len(buffer)} bytes\")\n asyncio.run_coroutine_threadsafe(\n send(\n {\n \"type\": \"http.response.body\",\n \"body\": buffer,\n \"more_body\": True,\n }\n ),\n asyncio.get_running_loop(),\n )\n\n async with tarfile.open(\n mode=\"w|gz\", fileobj=DumpWriter(), bufsize=CHUNK_SIZE\n ) as file:\n for name, input_path in self.files_to_tar:\n await file.addfile(tarfile.TarInfo(name), input_path.open(\"rb\"))\n\n await send({\"type\": \"http.response.body\", \"body\": b\"\", \"more_body\": False})\n\n\n@app.get(\"/\")\ndef send_tar() -> StreamingResponse:\n \"\"\"Send a tar file.\"\"\"\n\n return FileStreamingResponse(\n files_to_tar=FILES_TO_TAR,\n media_type=\"application/tar+gzip\",\n headers={\"Content-Disposition\": f'attachment; filename=\"{TAR_FILE_PATH.name}\"'},\n )\n\n\n#\n# TESTS\n#\n\nTEST_TAR_FILE_PATH = Path(\"archive.tar.gz\")\nclient = TestClient(app)\n\n\ndef test_main():\n if TEST_TAR_FILE_PATH.exists():\n os.remove(TEST_TAR_FILE_PATH)\n\n response = client.get(\"/\")\n response.raise_for_status()\n\n with TEST_TAR_FILE_PATH.open(\"wb\") as file:\n for chunk in response.iter_bytes(CHUNK_SIZE):\n file.write(chunk)\n\n with tarfile.open(TEST_TAR_FILE_PATH, \"r:gz\") as tar_file:\n files = [tarinfo.name for tarinfo in tar_file.getmembers()]\n\n src_files_names = [file[0] for file in FILES_TO_TAR]\n assert set(files) == set(src_files_names)\n```\n\n```text\n> async with tarfile.open(\n mode=\"w|gz\", fileobj=DumpWriter(), bufsize=CHUNK_SIZE\n ) as file:\nE TypeError: 'TarFile' object does not support the asynchronous context manager protocol\n```\n\n```text\ntarfile.TarFile\n```\n\n```text\n.tar.gz\n```\n\n```text\nStreamingResponse\n```\n\n```text\nwrite\n```\n\n```text\nstralette.StreamingResponse\n```\n\n```text\nStreamingResponse.stream_response\n```\n\n```text\nDumpWriter.write\n```\n\n```text\npytest main.py\n```\n\n```text\n_Stream\n```\n\n```text\nDumpWriter.write\n```\n\n```text\nsend\n```\n\n```text\ntarfile.addfile\n```\n\n```text\nStreamResponse\n```\n\n```py\n# /// script\n# requires-python = \">=3.12\"\n# dependencies = [\n# \"fastapi\",\n# \"httpx\",\n# \"pytest\",\n# \"uvicorn\",\n# ]\n# ///\n\"\"\"A script to read files by chunks, archive them, compress them and send them as a streaming response on the fly.\n\nTo run it, use the uv package manager and run `uv run main.py`.\n\"\"\"\n\nimport os\nimport struct\nimport tarfile\nimport time\nimport zlib\nfrom pathlib import Path\nfrom typing import Callable, Generator, Mapping\n\nimport pytest\nimport uvicorn\nfrom fastapi import FastAPI\nfrom fastapi.responses import StreamingResponse\nfrom fastapi.testclient import TestClient\nfrom starlette.background import BackgroundTask\nfrom starlette.types import Send\n\n### PARAMETERS ###\n\n# The list of file paths to be read and tar-gz and streamed\nFILES_TO_TAR = [(\"tarfile.py\", Path(tarfile.__file__)), (\"os.py\", Path(os.__file__))]\n\n# The size of a chunk to be sent as a response\nCHUNK_SIZE = 1024\n\n# Mode: pytest or uvicorn\nEXECUTION_MODE = \"pytest\"\n\n##\n## ADAPTER\n##\n\n\ndef file_reader(file_path: Path, bufsize: int) -> Generator[bytes, None, None]:\n \"\"\"Read a file and return a generator with bytes.\n\n Parameters\n ----------\n file_path : Path\n The file path to be read\n bufsize : int\n The size of a buffer\n\n Yields\n ------\n bytes\n File chunks\n \"\"\"\n with open(file_path, \"rb\") as file:\n while chunk := file.read(bufsize):\n yield chunk\n\n\nclass TarGzWriterStream:\n \"\"\"An object to read files and generate tar-gz chunks.\n\n This is written using pieces of `tarfile.TarFile` and `tarfile._Stream`.\n \"\"\"\n\n def __init__(\n self,\n files_to_tar: list[tuple[str, Path]],\n write_method: Callable[[bytes], None],\n bufsize: int = CHUNK_SIZE,\n compresslevel: int = 9,\n filename: str = \"archive.tar.gz\",\n ) -> None:\n \"\"\"Initialize the object\n\n Parameters\n ----------\n files_to_tar : list[tuple[str, Path]]\n The list of files to be sent as tuples (filename, filepath)\n write_method : Callable[[bytes], None]\n The function to call to send chunks to the network (the streamingresponse method)\n bufsize : int, optional\n The chunk size, by default CHUNK_SIZE\n compresslevel : int, optional\n The compression level, by default 9\n filename : str, optional\n The final file name, by default \"archive.tar.gz\"\n \"\"\"\n self.files_to_tar = files_to_tar\n self.write_method = write_method\n self.bufsize = bufsize\n self.filename = filename\n\n self.buf = b\"\"\n self.pos = 0\n\n self.compresslevel = compresslevel\n self.exception = zlib.error\n\n self.crc = zlib.crc32(b\"\")\n\n async def write(self, chunk: bytes) -> None:\n \"\"\"Write a chunk\"\"\"\n self.crc = zlib.crc32(chunk, self.crc)\n self.pos += len(chunk)\n\n chunk = self.cmp.compress(chunk)\n await self.__write(chunk)\n\n async def __write(self, chunk: bytes) -> None:\n \"\"\"Write strings to the stream if a whole new block\n is ready to be written.\n \"\"\"\n self.buf += chunk\n while len(self.buf) > self.bufsize:\n await self.write_method(self.buf[: self.bufsize])\n self.buf = self.buf[self.bufsize :]\n\n async def init_write_gz(self) -> None:\n # Initialize the stream data (header)\n self.cmp = zlib.compressobj(\n self.compresslevel,\n zlib.DEFLATED,\n -zlib.MAX_WBITS,\n zlib.DEF_MEM_LEVEL,\n 0,\n )\n timestamp = struct.pack(\"<L\", int(time.time()))\n print(\"writing header\")\n await self.__write(b\"\\037\\213\\010\\010\" + timestamp + b\"\\002\\377\")\n\n # Add filename info\n #\n if self.filename.endswith(\".gz\"):\n self.filename = self.filename[:-3]\n # Honor \"directory components removed\" from RFC1952\n self.filename = os.path.basename(self.filename)\n # RFC1952 says we must use ISO-8859-1 for the FNAME field.\n await self.__write(self.filename.encode(\"iso-8859-1\", \"replace\") + tarfile.NUL)\n\n async def stream_tar(self) -> None:\n \"\"\"Generate the tar file.\"\"\"\n offset = 0\n bufsize = CHUNK_SIZE\n\n for name, input_path in self.files_to_tar:\n\n # Create tarinfo\n tarinfo = tarfile.TarInfo(name)\n tarinfo.size = input_path.stat().st_size\n tarinfo.type = tarfile.REGTYPE\n\n # Write tarinfo buffer\n buf = tarinfo.tobuf()\n await self.write(buf)\n offset += len(buf) # Update offset\n\n # Add file data\n for chunk in file_reader(input_path, bufsize):\n await self.write(chunk)\n offset += tarinfo.size # Update offset\n\n blocks, remainder = divmod(tarinfo.size, tarfile.BLOCKSIZE)\n if remainder > 0:\n await self.write(tarfile.NUL * (tarfile.BLOCKSIZE - remainder))\n blocks += 1\n offset += blocks * tarfile.BLOCKSIZE # Update offset\n\n # Close file\n await self.write(tarfile.NUL * (tarfile.BLOCKSIZE * 2))\n offset += tarfile.BLOCKSIZE * 2 # Update offset\n\n # fill up the end with zero-blocks\n # (like option -b20 for tar does)\n blocks, remainder = divmod(offset, tarfile.RECORDSIZE)\n if remainder > 0:\n await self.write(tarfile.NUL * (tarfile.RECORDSIZE - remainder))\n\n async def close(self) -> None:\n \"\"\"Close the stream file once everything has been sent.\"\"\"\n self.buf += self.cmp.flush()\n\n await self.write_method(self.buf)\n\n await self.write_method(struct.pack(\"<L\", self.crc))\n await self.write_method(struct.pack(\"<L\", self.pos & 0xFFFFFFFF))\n\n\nclass FileStreamingResponse(StreamingResponse):\n \"\"\"An extension of StreamingResponse to archive and compress files on the fly.\"\"\"\n\n def __init__(\n self,\n files_to_tar: list[tuple[str, Path]],\n filename: str = \"archive.tar.gz\",\n status_code: int = 200,\n headers: Mapping[str, str] | None = None,\n media_type: str | None = None,\n background: BackgroundTask | None = None,\n ) -> None:\n \"\"\"Initialize the FileStreamingResponse object.\"\"\"\n self.files_to_tar = files_to_tar\n self.filename = filename\n self.status_code = status_code\n self.media_type = self.media_type if media_type is None else media_type\n self.background = background\n self.init_headers(headers)\n\n async def stream_response(self, send: Send) -> None:\n \"\"\"The function to perform streaming.\"\"\"\n # Send response start\n await send(\n {\n \"type\": \"http.response.start\",\n \"status\": self.status_code,\n \"headers\": self.raw_headers,\n }\n )\n\n async def write(buffer):\n \"\"\"The function to be called to send a chunk to the network.\"\"\"\n await send(\n {\n \"type\": \"http.response.body\",\n \"body\": buffer,\n \"more_body\": True,\n }\n )\n\n # Generate chunks and send them\n archiver = TarGzWriterStream(\n self.files_to_tar, write, bufsize=CHUNK_SIZE, filename=self.filename\n )\n await archiver.init_write_gz()\n await archiver.stream_tar()\n await archiver.close()\n\n # Send last response body (no more)\n await send({\"type\": \"http.response.body\", \"body\": b\"\", \"more_body\": False})\n\n\n###\n### THE FASTAPI APPLICATION\n###\n\n# The FastAPI application\napp = FastAPI()\n\n\n@app.get(\"/\")\ndef send_tar() -> StreamingResponse:\n \"\"\"Send a tar file.\"\"\"\n return FileStreamingResponse(\n files_to_tar=FILES_TO_TAR,\n media_type=\"application/tar+gzip\",\n headers={\"Content-Disposition\": 'attachment; filename=\"archive.tar.gz\"'},\n )\n\n\n##\n## TESTS\n##\n\n# The path where the testarchive is saved\nTEST_TAR_FILE_PATH = Path(\"archive.tar.gz\")\n\n# The test client\nclient = TestClient(app)\n\n\ndef test_main():\n \"\"\"Test the tar-gz streaming response.\"\"\"\n if TEST_TAR_FILE_PATH.exists():\n os.remove(TEST_TAR_FILE_PATH)\n\n # Request the app\n response = client.get(\"/\")\n response.raise_for_status()\n\n # Write the archive\n with TEST_TAR_FILE_PATH.open(\"wb\") as file:\n for chunk in response.iter_bytes(CHUNK_SIZE):\n file.write(chunk)\n\n # Check also the file is a valid .tar.gz\n with tarfile.open(TEST_TAR_FILE_PATH, \"r:gz\") as tar_file:\n files = [tarinfo.name for tarinfo in tar_file.getmembers()]\n\n # Check all files are in the archive\n src_files_names = [file[0] for file in FILES_TO_TAR]\n assert set(files) == set(src_files_names)\n\n\nif __name__ == \"__main__\":\n match EXECUTION_MODE:\n case \"pytest\":\n # To run tests\n pytest.main([__file__, \"-v\"])\n case \"uvicorn\":\n # To test it locally\n uvicorn.run(\"main_ter:app\", port=8080, reload=True)\n case _:\n print(\"Nothing to execute\")\n```\n\n```text\nStreamingResponse\n```\n\n```text\ntarfile.TarFile\n```\n\n```text\ntarfile._Stream\n```\n\n========================================\n\nComments:\n- Please have a look at this answer, as well as this answer and this answer\n- You might find this answer helpful as well\n- Hi, thanks a lot for your help, but these links did not answer my issue. I added more details in the question. In fact, the links all use Steaming with generators. My case is that the chunks are written to a byte buffer instead :( The discussions I found to be the closest to my issues was this one but this is the other way. A gist was added, but I did not achieve to make it work the tar-to-stream way.\n- A `BytesIO` is a file-like object and you could return it directly in a `StreamingResponse` - see this as well","metadata":{"transformedAt":"2026-08-18T18:32:29.118Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":22,"totalLines":899,"estimatedTokens":6001}}270{"id":"stack-62744379","source":"stackoverflow","questionId":62744379,"title":"Microservices FastAPI test in docker, return 404","tags":["python","docker","microservices","pytest","fastapi"],"text":"Title: Microservices FastAPI test in docker, return 404\nTags: python, docker, microservices, pytest, fastapi\nSource: Stack Overflow\n\nQuestion:\nI created a simple library project in microservices to study and implement FastAPI.\nDocker starts 5 main services:\n\n- books\n\n- db-book\n\n- author\n\n- db-author\n\n- nginx\n\nEverything works as expected, making requests with postman I have no problem.\n\n### Structure\n\nhttps://i.sstatic.net/5DPAT.png\n\n### Problem description\n\nI added a test directory where I test endpoints.\n\n### Example of (incomplete) author test\n\n```\nfrom starlette.testclient import TestClient\nfrom app.main import app\nfrom app.api.author import authors\nimport logging\nlog = logging.getLogger('__name__')\nimport requests\n\nclient = TestClient(app)\n\ndef test_get_authors():\n response = client.get(\"/\")\n assert response.status_code == 200\n\ndef test_get_author():\n response = client.get(\"/1\")\n assert response.status_code == 200\n```\n\n`$> docker-compose exec author_service pytest .`\nreturns this\n\n```\n============================================================================================================= test session starts =============================================================================================================\nplatform linux -- Python 3.8.3, pytest-5.3.2, py-1.9.0, pluggy-0.13.1\nrootdir: /app\ncollected 2 items \n\ntests/test_author.py FF [100%]\n\n================================================================================================================== FAILURES ===================================================================================================================\n______________________________________________________________________________________________________________ test_get_authors _______________________________________________________________________________________________________________\n\n def test_get_authors():\n response = client.get(\"/\")\n> assert response.status_code == 200\nE assert 404 == 200\nE + where 404 = .status_code\n\ntests/test_author.py:12: AssertionError\n_______________________________________________________________________________________________________________ test_get_author _______________________________________________________________________________________________________________\n\n def test_get_author():\n response = client.get(\"/1\")\n> assert response.status_code == 200\nE assert 404 == 200\nE + where 404 = .status_code\n\ntests/test_author.py:16: AssertionError\n============================================================================================================== 2 failed in 0.35s ==============================================================================================================\n```\n\nI tried to start the tests directly from the container shell but nothing the same.\nThis problem occurs only with tests that are done following the documentation (using starlette / fastapi) and with requests\n\nYou can find the complete project here\nLibrary Microsrevices example\n\n### Environment\n\n- OS:[Linux Fedora 32]\n\n- FastAPI Version [0.55.1]:\n\n- Python: [Python 3.8.3]\n\ndocker-compose file\n\n```\nversion: '3.7'\n\nservices:\n book_service:\n build: ./book-service\n command: uvicorn app.main:app --reload --host 0.0.0.0 --port 8000\n volumes:\n - ./book-service/:/app/\n ports:\n - 8001:8000\n environment:\n - DATABASE_URI=postgresql://book_db_username:book_db_password@book_db/book_db_dev\n - AUTHOR_SERVICE_HOST_URL=http://author_service:8000/api/v1/authors/\n depends_on:\n - book_db\n\n book_db:\n image: postgres:12.1-alpine\n volumes:\n - postgres_data_book:/var/lib/postgresql/data/\n environment:\n - POSTGRES_USER=book_db_username\n - POSTGRES_PASSWORD=book_db_password\n - POSTGRES_DB=book_db_dev\n \n author_service:\n build: ./author-service\n command: uvicorn app.main:app --reload --host 0.0.0.0 --port 8000\n volumes:\n - ./author-service/:/app/\n ports:\n - 8002:8000\n environment:\n - DATABASE_URI=postgresql://author_db_username:author_db_password@author_db/author_db_dev\n depends_on:\n - author_db\n\n author_db:\n image: postgres:12.1-alpine\n volumes:\n - postgres_data_author:/var/lib/postgres/data\n environment:\n - POSTGRES_USER=author_db_username\n - POSTGRES_PASSWORD=author_db_password\n - POSTGRES_DB=author_db_dev\n\n nginx:\n image: nginx:latest\n ports:\n - \"8080:8080\"\n volumes:\n - ./nginx_config.conf:/etc/nginx/conf.d/default.conf\n depends_on:\n - author_service\n - book_service\n\nvolumes:\n postgres_data_book:\n postgres_data_author:\n```\n\n========================================\n\nTop Answer:\nthe main problem here are your endpoints on test file\n\n**Test example fixed:**\n\n```\nfrom starlette.testclient import TestClient\nfrom app.main import app\nfrom app.api.author import authors\nimport logging\nlog = logging.getLogger('__name__')\nimport requests\n\nclient = TestClient(app)\n\ndef test_get_authors():\n response = client.get(\"/authors\") # this must be your API endpoint to test\n assert response.status_code == 200\n\ndef test_get_author():\n response = client.get(\"/authors/1\") # this must be your API endpoint to test \n assert response.status_code == 200\n```\n\n========================================\n\nCode:\n```py\nfrom starlette.testclient import TestClient\nfrom app.main import app\nfrom app.api.author import authors\nimport logging\nlog = logging.getLogger('__name__')\nimport requests\n\nclient = TestClient(app)\n\ndef test_get_authors():\n response = client.get(\"/\")\n assert response.status_code == 200\n\ndef test_get_author():\n response = client.get(\"/1\")\n assert response.status_code == 200\n```\n\n```py\n============================================================================================================= test session starts =============================================================================================================\nplatform linux -- Python 3.8.3, pytest-5.3.2, py-1.9.0, pluggy-0.13.1\nrootdir: /app\ncollected 2 items \n\ntests/test_author.py FF [100%]\n\n================================================================================================================== FAILURES ===================================================================================================================\n______________________________________________________________________________________________________________ test_get_authors _______________________________________________________________________________________________________________\n\n def test_get_authors():\n response = client.get(\"/\")\n> assert response.status_code == 200\nE assert 404 == 200\nE + where 404 = <Response [404]>.status_code\n\ntests/test_author.py:12: AssertionError\n_______________________________________________________________________________________________________________ test_get_author _______________________________________________________________________________________________________________\n\n def test_get_author():\n response = client.get(\"/1\")\n> assert response.status_code == 200\nE assert 404 == 200\nE + where 404 = <Response [404]>.status_code\n\ntests/test_author.py:16: AssertionError\n============================================================================================================== 2 failed in 0.35s ==============================================================================================================\n```\n\n```text\nversion: '3.7'\n\nservices:\n book_service:\n build: ./book-service\n command: uvicorn app.main:app --reload --host 0.0.0.0 --port 8000\n volumes:\n - ./book-service/:/app/\n ports:\n - 8001:8000\n environment:\n - DATABASE_URI=postgresql://book_db_username:book_db_password@book_db/book_db_dev\n - AUTHOR_SERVICE_HOST_URL=http://author_service:8000/api/v1/authors/\n depends_on:\n - book_db\n\n book_db:\n image: postgres:12.1-alpine\n volumes:\n - postgres_data_book:/var/lib/postgresql/data/\n environment:\n - POSTGRES_USER=book_db_username\n - POSTGRES_PASSWORD=book_db_password\n - POSTGRES_DB=book_db_dev\n \n author_service:\n build: ./author-service\n command: uvicorn app.main:app --reload --host 0.0.0.0 --port 8000\n volumes:\n - ./author-service/:/app/\n ports:\n - 8002:8000\n environment:\n - DATABASE_URI=postgresql://author_db_username:author_db_password@author_db/author_db_dev\n depends_on:\n - author_db\n\n author_db:\n image: postgres:12.1-alpine\n volumes:\n - postgres_data_author:/var/lib/postgres/data\n environment:\n - POSTGRES_USER=author_db_username\n - POSTGRES_PASSWORD=author_db_password\n - POSTGRES_DB=author_db_dev\n\n nginx:\n image: nginx:latest\n ports:\n - \"8080:8080\"\n volumes:\n - ./nginx_config.conf:/etc/nginx/conf.d/default.conf\n depends_on:\n - author_service\n - book_service\n\nvolumes:\n postgres_data_book:\n postgres_data_author:\n```\n\n```text\n$> docker-compose exec author_service pytest .\n```\n\n```py\nfrom starlette.testclient import TestClient\nfrom app.main import app\nfrom app.api.author import authors\nimport logging\nlog = logging.getLogger('__name__')\nimport requests\n\nclient = TestClient(app)\n\ndef test_get_authors():\n response = client.get(\"/authors\") # this must be your API endpoint to test\n assert response.status_code == 200\n\ndef test_get_author():\n response = client.get(\"/authors/1\") # this must be your API endpoint to test \n assert response.status_code == 200\n```\n\n========================================\n\nComments:\n- Please add here your docker-compose file? How is your network declared?\n- @abestrad added docker-compose\n- Hi @Sanjiv I don't understand how this guide can help me. It absolutely does not talk about how to set up docker to run the tests","metadata":{"transformedAt":"2026-08-18T18:32:29.118Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":5,"totalLines":329,"estimatedTokens":2523}}271{"id":"stack-63233378","source":"stackoverflow","questionId":63233378,"title":"How can I create Swagger docs for dynamic FastAPI endpoints?","tags":["python","swagger","fastapi"],"text":"Title: How can I create Swagger docs for dynamic FastAPI endpoints?\nTags: python, swagger, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have a list of endpoints like below.\n\n```\nendpoints [\"/endpoint1\", \"/endpoint2\", \"/endpoint3\"]\n```\n\nI would like to create dynamic endpoints in my app and create swagger API docs for all the endpoints, how can I do this.\n\n```\n@app.route():\n def process():\n```\n\n========================================\n\nCode:\n```py\nendpoints [\"/endpoint1\", \"/endpoint2\", \"/endpoint3\"]\n```\n\n```py\n@app.route(<endpoint>):\n def process():\n```\n\n```text\nfrom enum import Enum\nfrom fastapi import FastAPI\n\n\nclass ModelName(str, Enum):\n endpoint1 = \"endpoint1\"\n endpoint2 = \"endpoint2\"\n endpoint3 = \"endpoint3\"\n\n\napp = FastAPI()\n\n\n@app.get(\"/model/{model_name}\")\nasync def process(model_name: ModelName):\n return {\"model_name\": model_name, \"message\": \"Some message\"}\n```\n\n```text\nEnum\n```\n\n========================================\n\nComments:\n- In which framework?, Flask or FastAPI ?\n- anything is fine\n- Thanks for the answer, is it possible to provide list of endpoints, instead of hardcoding inside the Class ModelName\n- as per my question, I have endpoints in a list... so my use case needs like that\n- the term *endpoint* is confusing (me). Is that a ***path parameter***?\n- hmmm yes. I have 5 endpoints and each endpoint have 5 path parameter, in that case, I need 5 `Enum class` I guess. Thanks\n- can you provide an example in your answer\n- Shouldn't be it handled in a different ***API function***? [ Sorry, I removed the previous comment. ].\n- yes different function and different class because the path parameters also differs\n- Then, you may need different Enum classes wrt your usecase","metadata":{"transformedAt":"2026-08-18T18:32:29.118Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":66,"estimatedTokens":431}}272{"id":"stack-70949248","source":"stackoverflow","questionId":70949248,"title":"SqlModel datetime field is throwing error upon execution","tags":["python","datetime","fastapi","sqlmodel"],"text":"Title: SqlModel datetime field is throwing error upon execution\nTags: python, datetime, fastapi, sqlmodel\nSource: Stack Overflow\n\nQuestion:\nI am using SQLModel in python 3.8\n\nWhen I add my datetime field `created_at: datetime = Field(default_factory=utcnow(), nullable=False)`\n\nI get this\n**Error**\n\n```\nFile \"./app/main.py\", line 16, in \n class Post(SQLModel, table=True):\n File \"/Users/markwardell/PycharmProjects/pythonProject/venv/lib/python3.8/site-packages/sqlmodel/main.py\", line 277, in __new__\n new_cls = super().__new__(cls, name, bases, dict_used, **config_kwargs)\n File \"pydantic/main.py\", line 204, in pydantic.main.ModelMetaclass.__new__\n File \"pydantic/fields.py\", line 488, in pydantic.fields.ModelField.infer\n File \"pydantic/fields.py\", line 419, in pydantic.fields.ModelField.__init__\n File \"pydantic/fields.py\", line 539, in pydantic.fields.ModelField.prepare\n File \"pydantic/fields.py\", line 801, in pydantic.fields.ModelField.populate_validators\n File \"pydantic/validators.py\", line 718, in find_validators\nRuntimeError: error checking inheritance of (type: module)\n```\n\nIf I do not the add the `created_at` the table is created in PostgresSql as expected.\n**Code**\n\n```\nimport datetime\nfrom typing import Optional\nimport utcnow as utcnow\nfrom fastapi import FastAPI\nfrom sqlalchemy import TIMESTAMP, text\nfrom sqlmodel import Field, Session, SQLModel, create_engine, select\nfrom app.database import SQLALCHEMY_DATABASE_URL\n\nclass Hero(SQLModel, table=True):\n id: Optional[int] = Field(default=None, primary_key=True)\n name: str = Field(index=True)\n secret_name: str\n age: Optional[int] = Field(default=None, index=True)\n\nclass Post(SQLModel, table=True):\n id: Optional[int] = Field(default=None, primary_key=True, nullable=False)\n title: str = Field(nullable=False)\n content: str = Field(nullable=False)\n published: bool = Field(default=True, nullable=False)\n created_at: datetime = Field(default_factory=utcnow(), nullable=False)\n\nengine = create_engine(SQLALCHEMY_DATABASE_URL)\n\ndef create_db_and_tables():\n SQLModel.metadata.create_all(engine)\n\napp = FastAPI()\n\n@app.on_event(\"startup\")\ndef on_startup():\n create_db_and_tables()\n```\n\n========================================\n\nTop Answer:\nAlso, note that your code should be\n\n```\ncreated_at: datetime.datetime = Field(default_factory=datetime.utcnow, nullable=False)\n```\n\nwithout calling utcnow on instantiation, doing so will give every entry datetime as consulted at instantiation. Thus, `default_factory` should be the function, not the value.\n\n========================================\n\nCode:\n```text\nFile \"./app/main.py\", line 16, in <module>\n class Post(SQLModel, table=True):\n File \"/Users/markwardell/PycharmProjects/pythonProject/venv/lib/python3.8/site-packages/sqlmodel/main.py\", line 277, in __new__\n new_cls = super().__new__(cls, name, bases, dict_used, **config_kwargs)\n File \"pydantic/main.py\", line 204, in pydantic.main.ModelMetaclass.__new__\n File \"pydantic/fields.py\", line 488, in pydantic.fields.ModelField.infer\n File \"pydantic/fields.py\", line 419, in pydantic.fields.ModelField.__init__\n File \"pydantic/fields.py\", line 539, in pydantic.fields.ModelField.prepare\n File \"pydantic/fields.py\", line 801, in pydantic.fields.ModelField.populate_validators\n File \"pydantic/validators.py\", line 718, in find_validators\nRuntimeError: error checking inheritance of <module 'datetime' from '/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/datetime.py'> (type: module)\n```\n\n```text\nimport datetime\nfrom typing import Optional\nimport utcnow as utcnow\nfrom fastapi import FastAPI\nfrom sqlalchemy import TIMESTAMP, text\nfrom sqlmodel import Field, Session, SQLModel, create_engine, select\nfrom app.database import SQLALCHEMY_DATABASE_URL\n\nclass Hero(SQLModel, table=True):\n id: Optional[int] = Field(default=None, primary_key=True)\n name: str = Field(index=True)\n secret_name: str\n age: Optional[int] = Field(default=None, index=True)\n\n\nclass Post(SQLModel, table=True):\n id: Optional[int] = Field(default=None, primary_key=True, nullable=False)\n title: str = Field(nullable=False)\n content: str = Field(nullable=False)\n published: bool = Field(default=True, nullable=False)\n created_at: datetime = Field(default_factory=utcnow(), nullable=False)\n\nengine = create_engine(SQLALCHEMY_DATABASE_URL)\n\n\ndef create_db_and_tables():\n SQLModel.metadata.create_all(engine)\n\n\napp = FastAPI()\n\n\n@app.on_event(\"startup\")\ndef on_startup():\n create_db_and_tables()\n```\n\n```text\ncreated_at: datetime = Field(default_factory=utcnow(), nullable=False)\n```\n\n```text\ncreated_at\n```\n\n```py\nfrom datetime import datetime\n```\n\n```text\ndatetime\n```\n\n```text\ndatetime\n```\n\n```text\ncreated_at: datetime.datetime = Field(default_factory=datetime.utcnow, nullable=False)\n```\n\n```text\ndefault_factory\n```\n\n========================================\n\nComments:\n- Your import should be `from datetime import datetime`.\n- @KlausD. that fixes it. If you like add as answer and i will with the answered checkmark. Thank you so much!\n- `default_factory=datetime.datetime.utcnow` I think\n- `datetime.datetime.utcnow` has been deprecated in favour of `datetime.datetime.now`","metadata":{"transformedAt":"2026-08-18T18:32:29.118Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":9,"totalLines":164,"estimatedTokens":1307}}273{"id":"stack-65078775","source":"stackoverflow","questionId":65078775,"title":"Accept gzipped body in FastAPI / Uvicorn","tags":["python","fastapi","uvicorn"],"text":"Title: Accept gzipped body in FastAPI / Uvicorn\nTags: python, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI'm using FastAPI with Uvicorn to implement a u-service which accepts a json payload in the request's body. Since the request body can be quite large, I wish the service to accept gzipped. How do I accomplish that?\n\nSo far the following:\n\n- added the GZipMiddleware, but it encodes responses, rather that decoding requests\n\n- added a 'Content-Encoding: gzip' to my request\n\nFail with response:\n\nStatus: 400 Bad Request \n\n{ \"detail\": \"There was an error parsing the body\" }\n\n========================================\n\nTop Answer:\nAnother way to achieve the same would be like this:\n\n```\nfrom fastapi import FastAPI\nfrom starlette.types import Message\nfrom starlette.requests import Request\nfrom starlette.middleware.base import BaseHTTPMiddleware\nimport gzip \n \n\nclass GZipedMiddleware(BaseHTTPMiddleware):\n async def set_body(self, request: Request):\n receive_ = await request._receive()\n if \"gzip\" in request.headers.getlist(\"Content-Encoding\"):\n print(receive_) \n data = gzip.decompress(receive_.get('body'))\n receive_['body'] = data\n\n async def receive() -> Message:\n return receive_\n\n request._receive = receive \n\n async def dispatch(self, request, call_next):\n await self.set_body(request) \n response = await call_next(request) \n return response\n\n \n\napp = FastAPI()\n\napp.add_middleware(GZipedMiddleware)\n\n@app.post(\"/post\")\nasync def post(req: Request):\n body = await req.body()\n # I'm decoding here in case you just gziped an string\n return body.decode(\"utf-8\")\n```\n\n========================================\n\nCode:\n```py\nimport gzip\nfrom typing import Callable, List\n\nfrom fastapi import Body, FastAPI, Request, Response\nfrom fastapi.routing import APIRoute\n\n\nclass GzipRequest(Request):\n async def body(self) -> bytes:\n if not hasattr(self, \"_body\"):\n body = await super().body()\n if \"gzip\" in self.headers.getlist(\"Content-Encoding\"):\n body = gzip.decompress(body)\n self._body = body\n return self._body\n\n\nclass GzipRoute(APIRoute):\n def get_route_handler(self) -> Callable:\n original_route_handler = super().get_route_handler()\n\n async def custom_route_handler(request: Request) -> Response:\n request = GzipRequest(request.scope, request.receive)\n return await original_route_handler(request)\n\n return custom_route_handler\n\n\napp = FastAPI()\napp.router.route_class = GzipRoute\n\n\n@app.post(\"/sum\")\nasync def sum_numbers(numbers: List[int] = Body(...)):\n return {\"sum\": sum(numbers)}\n```\n\n```text\nFastAPI\n```\n\n```py\nfrom fastapi import FastAPI\nfrom starlette.types import Message\nfrom starlette.requests import Request\nfrom starlette.middleware.base import BaseHTTPMiddleware\nimport gzip \n \n\nclass GZipedMiddleware(BaseHTTPMiddleware):\n async def set_body(self, request: Request):\n receive_ = await request._receive()\n if \"gzip\" in request.headers.getlist(\"Content-Encoding\"):\n print(receive_) \n data = gzip.decompress(receive_.get('body'))\n receive_['body'] = data\n\n async def receive() -> Message:\n return receive_\n\n request._receive = receive \n\n async def dispatch(self, request, call_next):\n await self.set_body(request) \n response = await call_next(request) \n return response\n\n \n\napp = FastAPI()\n\napp.add_middleware(GZipedMiddleware)\n\n\n@app.post(\"/post\")\nasync def post(req: Request):\n body = await req.body()\n # I'm decoding here in case you just gziped an string\n return body.decode(\"utf-8\")\n```\n\n```text\nimport typing\nimport zlib\n\nfrom starlette import status\nfrom starlette.datastructures import Headers\nfrom starlette.exceptions import HTTPException\nfrom starlette.types import ASGIApp\nfrom starlette.types import Message\nfrom starlette.types import Receive\nfrom starlette.types import Scope\nfrom starlette.types import Send\n\n\nclass GZipRequestMiddleware:\n def __init__(self, app: ASGIApp):\n self.app = app\n\n async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:\n if scope[\"type\"] == \"http\":\n headers = Headers(scope=scope)\n\n if headers.get(\"Content-Encoding\") == \"gzip\":\n # Decompress only if 'gzip' compression is applied\n reader = GZipRequestReader(self.app)\n await reader(scope, receive, send)\n return\n\n await self.app(scope, receive, send)\n\n\nclass GZipRequestReader:\n def __init__(self, app: ASGIApp) -> None:\n self.app = app\n self.receive: Receive = unattached_receive\n self.scope: Scope = {}\n # Uncompressed Body size\n self.actual_body_size = 0\n # Decompress a compressed stream (Source: https://stackoverflow.com/a/22311297)\n self.decompressor = zlib.decompressobj(16 + zlib.MAX_WBITS)\n\n async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:\n self.scope = scope\n self.receive = receive\n await self.app(scope, self._receive_gzipped_request, send)\n\n async def _receive_gzipped_request(self) -> Message:\n message = await self.receive()\n body = message.get(\"body\", b\"\")\n if body:\n try:\n message[\"body\"] = self.decompressor.decompress(body)\n except zlib.error as e:\n raise HTTPException(\n status.HTTP_422_UNPROCESSABLE_ENTITY, \"Compressed request body is malformed!\"\n ) from e\n else:\n self.actual_body_size += len(message[\"body\"])\n\n if not message.get(\"more_body\", False):\n if not self.decompressor.eof:\n raise HTTPException(\n status.HTTP_422_UNPROCESSABLE_ENTITY, \"Compressed request body is truncated or incomplete!\"\n )\n\n headers_copy = Headers(scope=self.scope).mutablecopy()\n del headers_copy[\"Content-Encoding\"]\n headers_copy[\"Content-Length\"] = str(self.actual_body_size)\n self.scope[\"headers\"] = headers_copy.raw\n\n return message\n\n\nasync def unattached_receive() -> typing.NoReturn:\n raise RuntimeError(\"awaitable not set\") # noqa: EM101, TRY003 # pragma: no cover\n```\n\n```text\nBaseHTTPMiddleware\n```\n\n========================================\n\nComments:\n- hmm. I wonder why implement this as a router and not as a middleware. Is it just for the sake of the example, or are there other considerations?\n- It also seems to me that it was for the sake of an example. There is an open issue for this\n- Be careful if, like me, you start using this code simply because it is simpler: POSTing content with a fake Content-Length header (bigger than the content actually is) will get your worker to hang until it eventually times out and gets killed by the main process, even if your server is behind nginx and even if the body of the request isn’t gzipped!\n- Yes, be very aware of the above comment by Mathieu. This is a nightmare to debug and find.\n- Also, you should consider that the `receive_.get('more_body')` value holds a `bool` that tells whether the full body content has already been read. There is a chance that you need to iterate over these chunks, otherwise only a part of the body will be passed to the `decompress` method which will fail.","metadata":{"transformedAt":"2026-08-18T18:32:29.118Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":5,"totalLines":237,"estimatedTokens":1872}}274{"id":"stack-62400506","source":"stackoverflow","questionId":62400506,"title":"Errror parsing data in python FastAPI","tags":["python","python-3.x","fastapi"],"text":"Title: Errror parsing data in python FastAPI\nTags: python, python-3.x, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm learning to use FastAPI, and I'm getting this error over and over again while implementing a simple API and I've not being able to figure out why\n\n```\n\"detail\": \"There was an error parsing the body\"\n```\n\nThis happends me on this two endpoints:\n\nFull code: Code Repository\n\nsnippet:\n\n```\napp_v1 = FastAPI(root_path='/v1')\n\n# JWT Token request\n@app_v1.post('/token')\nasync def login_access_token(form_data: OAuth2PasswordRequestForm = Depends()):\n jwt_user_dict = {\"username\": form_data.username, \"password\": form_data.password}\n jwt_user = JWTUser(**jwt_user_dict)\n user = authenticate_user(jwt_user)\n if user is None:\n return HTTP_401_UNAUTHORIZED\n jwt_token = create_jwt_token(user)\n return {\"token\": jwt_token}\n```\n\nrequest:\n\nhttps://i.sstatic.net/n3DOn.png\n\nhttps://i.sstatic.net/kPhRt.png\n\n```\n@app_v1.post(\"/user/photo\")\nasync def update_photo(response: Response, profile_photo: bytes = File(...)):\n response.headers['x-file-size'] = str(len(profile_photo))\n response.set_cookie(key='cookie-api', value=\"test\")\n return {\"profile photo size\": len(profile_photo)}\n```\n\nrequest:\nhttps://i.sstatic.net/3TC8V.png\n\n========================================\n\nTop Answer:\nThe problem with the first request is that you should be sending `username` and `password` in a `form-data`. Instead of `x-www-form-urlencoded`, use `form-data` and you should be fine.\n\nhttps://i.sstatic.net/DsGHB.png\n\nI can't see the problem with the second one. Can you try using Swagger interface and see if the same happens there?\n\n========================================\n\nCode:\n```text\n\"detail\": \"There was an error parsing the body\"\n```\n\n```text\napp_v1 = FastAPI(root_path='/v1')\n\n# JWT Token request\n@app_v1.post('/token')\nasync def login_access_token(form_data: OAuth2PasswordRequestForm = Depends()):\n jwt_user_dict = {\"username\": form_data.username, \"password\": form_data.password}\n jwt_user = JWTUser(**jwt_user_dict)\n user = authenticate_user(jwt_user)\n if user is None:\n return HTTP_401_UNAUTHORIZED\n jwt_token = create_jwt_token(user)\n return {\"token\": jwt_token}\n```\n\n```text\n@app_v1.post(\"/user/photo\")\nasync def update_photo(response: Response, profile_photo: bytes = File(...)):\n response.headers['x-file-size'] = str(len(profile_photo))\n response.set_cookie(key='cookie-api', value=\"test\")\n return {\"profile photo size\": len(profile_photo)}\n```\n\n```text\nusername\n```\n\n```text\npassword\n```\n\n```text\nform-data\n```\n\n```text\nx-www-form-urlencoded\n```\n\n```text\nform-data\n```\n\n========================================\n\nComments:\n- Have you tried this answer stackoverflow.com/a/60670614/977593 already?\n- I've tried form data too, but still gets the same error, even from the swagger. I edit question to show the swagger print\n- After installing `python-multipart` just like what you did, my form data worked, thank you!","metadata":{"transformedAt":"2026-08-18T18:32:29.118Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":8,"totalLines":114,"estimatedTokens":739}}275{"id":"stack-66084376","source":"stackoverflow","questionId":66084376,"title":"Any way to limit the input arguments of a FastAPI handler into several specified options?","tags":["python-asyncio","fastapi"],"text":"Title: Any way to limit the input arguments of a FastAPI handler into several specified options?\nTags: python-asyncio, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm wondering if there's someway could let me easily deal with input arguments and limit them into several values in FASTAPI.\n\nFor example if I got a hello-world handler here:\n\n```\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(/)\nasync def root(name:str):\n return {\"user_name_is\": name}\n```\n\nAnd what I'd like to achieve is , to let user can only input one of the following names as parameter [`Bob` ,`Jack`] , other names are all illegal.\n\nIt's not complicated to write some further check code to achieve the expected result:\n\n```\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(/)\nasync def root(name:str):\n if name in ['Bob' , 'Jack']:\n return {\"user_name_is\": name}\n else:\n raise HTTPException(status_code=403)\n```\n\nHowever it's still not easy enough to write codes especially when there're lots of input arguments need to deal with. I'm wondering if there's a way I can use type-hints and pydantic to achieve the same result?\n\nDidn't find much information in doc, need help , thanks.\n\n=======\n\nbtw , if there's also chance I need to get a list of input prameters , is there any way to check them all , like the following code,?\n\n```\nfrom fastapi import FastAPI\nfrom typing import List\n\napp = FastAPI()\n\n@app.get(/)\nasync def root(names:List[str]):\n for name in names:\n if name not in ['Bob','Jack']:\n raise ...\n # else ,check passed\n return {\"user_name_is\": name}\n```\n\n========================================\n\nTop Answer:\nI know this question has already an answer accepted but I feel that the cleanest way is to use the `Literal` typing like this:\n\n```\nfrom fastapi import FastAPI\nfrom typing import Literal\n\napp = FastAPI()\n\n@app.get(\"/{name}\")\nasync def root(name: Literal[\"Bob\", \"Jack\"]):\n return {\"user_name_is\": name}\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(/)\nasync def root(name:str):\n return {\"user_name_is\": name}\n```\n\n```text\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(/)\nasync def root(name:str):\n if name in ['Bob' , 'Jack']:\n return {\"user_name_is\": name}\n else:\n raise HTTPException(status_code=403)\n```\n\n```text\nfrom fastapi import FastAPI\nfrom typing import List\n\napp = FastAPI()\n\n@app.get(/)\nasync def root(names:List[str]):\n for name in names:\n if name not in ['Bob','Jack']:\n raise ...\n # else ,check passed\n return {\"user_name_is\": name}\n```\n\n```text\nBob\n```\n\n```text\nJack\n```\n\n```py\nfrom enum import Enum\n\nimport uvicorn\nfrom fastapi import FastAPI\n\n\nclass Names(str, Enum):\n Bob = \"Bob\"\n Jack = \"Jack\"\n\n\napp = FastAPI()\n\n\n@app.get(\"/\")\nasync def root(name: Names):\n return {\"user_name_is\": name}\n```\n\n```text\nEnum\n```\n\n```py\nfrom pydantic import BaseModel, validator\nfrom typing import List\nfrom fastapi import FastAPI, Depends\n\n\napp = FastAPI()\n\n\nclass Names(BaseModel):\n names: List[str]\n\n @validator(\"names\", pre=True, always=True)\n def check_allowed_names(cls, v):\n allowed_names = [\"Billie\", \"Joe\"]\n for name in v:\n if name not in allowed_names:\n raise ValueError(f\"Name {name} is not allowed\")\n\n return v\n\n\n@app.post(\"/\")\nasync def root(names: Names):\n return {\"user_name_is\": names.names}\n```\n\n```text\n@validator\n```\n\n```text\nfrom fastapi import FastAPI\nfrom typing import Literal\n\napp = FastAPI()\n\n@app.get(\"/{name}\")\nasync def root(name: Literal[\"Bob\", \"Jack\"]):\n return {\"user_name_is\": name}\n```\n\n```text\nLiteral\n```\n\n========================================\n\nComments:\n- Thanks bro, maybe that's the best practice","metadata":{"transformedAt":"2026-08-18T18:32:29.119Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":11,"totalLines":198,"estimatedTokens":936}}276{"id":"stack-73026698","source":"stackoverflow","questionId":73026698,"title":"Java's Spring Boot vs Python's FastAPI: Threads","tags":["python","java","multithreading","fastapi","project-loom"],"text":"Title: Java's Spring Boot vs Python's FastAPI: Threads\nTags: python, java, multithreading, fastapi, project-loom\nSource: Stack Overflow\n\nQuestion:\nI'm a Java Spring boot developer and I develop 3-tier crud applications. I talked to a guy who seemed knowledgeable on the subject, but I didn't get his contact details. He was advocating for Python's FastAPI, because horizontally it scales better than Spring boot. One of the reasons he mentioned is that FastAPI is single-threaded. When the thread encounters a database lookup (or other work the can be done asyncly), it picks up other work to later return to the current work when the database results have come in. In Java, when you have many requests pending, the thread pool may get exhausted.\n\nI don't understand this reasoning a 100%. Let me play the devil's advocate. When the Python program encounters an async call, it must somehow store the program pointer somewhere, to remember where it needs to continue later. I know that that place where the program pointer is stored is not at all a thread, but I have to give it some name, so let's call it a \"logical thread\". In Python , you can have many logical threads that are waiting. In Java, you can have a thread pool with many real threads that are waiting. To me, the only difference seems to be that Java's threads are managed at the operating system level, whereas Python's \"logical threads\" are managed by Python or FastAPI. Why are real threads that are waiting in a thread pool so much more expensive than logical threads that are waiting? If most of my threads are waiting, why can't I just increase the thread pool size to avoid exhaustion?\n\n========================================\n\nTop Answer:\nFastAPI is a fast framework, and you can quickly (and easily) create API backends in it. To be honest, if you are a Java developer, I would recommend Quarkus or something for building a REST API, not FastAPI. FastAPI is a fantastic tool, absolutely great if you are already in the Python ecosystem.\n\nWhen it goes about multithreading; Java is 'real' multithreading where as Python is very much not. Java threads will run concurrently; two tasks can and will be executed at the same time. In Python, within one Python process, this is (nearly) impossible. The reason for this is GIL (google it, there is ton's of stuff out there on how it works). The result is; even if you use 'real' threads in Python, code is still not executed concurrently but rather serially, where the interpreter (big difference to Java) is jumping from one call stack to another constantly.\n\nAs to what you refer to as 'logical threads', I think you mean the asynchronous capability of Python. This is basically the same as using threads (not really, but on an abstract level they are very similar); tasks are not run concurrently. There is just one thread that constantly switches between tasks. Tasks will yield back control to the event loop (the object that coordinates tasks and decides what is executed in which order), and another task is further executed until that task yields control, etc. It is basically the same kind of execution pattern as with threads within Python.\n\nComparing a Python framework to a Java framework is just weird in my opinion. They are both useful and cool, but not really competitors.\n\n========================================\n\nComments:\n- Just a heads up, this kind of question is veering *heavily* into religious/opinion territory.\n- Future readers might find this answer helpful as well.\n- Thanks for your reply, but in imho it doesn't answer my question why FastApi scales better horizontally than Spring Boot for crud applications.\n- It doesn’t, Fastapi doesn’t scale better horizontally per se than Spring Boot. The reasoning of your buddy does not make any sense at all, especially on the “because it’s single threaded” part, that is what my answer tries (but fails) to explain.\n- the FAST in FastAPI stands for faster development time, that's all. It's a wrapper over starlette web framework\n- Project loom is now available in JDK21.\n- Beware that Python can run in parallel simply by running multiple processes (containers), so it's false that it's not possible with Python. This way Python processes that utilize x processors can handle more requests than a Java process that utilizes x processors. That's what's meant by horizontal scaling. Interesting benchmark though, +1.\n- True, but certain technics known from jvm (not java specific) world cannot be applied then. For instance - for jvm many threads can some cache. This is huge advantage if you can cache some things. The need for external cache can be applied much later (when you hit the scale) In python if you want to some state between multiple python processes you need external state (database or cache) from the very beginning. Many python advocates advertise python is easy - but it's harder when you go beyond \"hello world\" stateless microservice.","metadata":{"transformedAt":"2026-08-18T18:32:29.119Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":0,"totalLines":31,"estimatedTokens":1237}}277{"id":"stack-71996380","source":"stackoverflow","questionId":71996380,"title":"How to assign a function to a route functionally, without a route decorator in FastAPI?","tags":["python","fastapi"],"text":"Title: How to assign a function to a route functionally, without a route decorator in FastAPI?\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nIn Flask, it is possible to assign an arbitrary function to a route functionally like:\n\n```\nfrom flask import Flask\napp = Flask()\n\ndef say_hello():\n return \"Hello\"\n\napp.add_url_rule('/hello', 'say_hello', say_hello)\n```\n\nwhich is equal to (with decorators):\n\n```\n@app.route(\"/hello\")\ndef say_hello():\n return \"Hello\"\n```\n\nIs there such a simple and functional way (`add_url_rule`) in FastAPI?\n\n========================================\n\nTop Answer:\nDecorators are just syntactic sugar. They are simply functions that take another function as the first positional argument.\n\nFor example this:\n\n```\nfrom fastapi import FastAPI\napp = FastAPI()\n\n@app.get(\"/hello\")\ndef say_hello():\n return \"Hello\"\n```\n\nIs equal to this:\n\n```\nfrom fastapi import FastAPI\napp = FastAPI()\n\ndef say_hello():\n return \"Hello\"\n\nsay_hello = app.get(\"/hello\")(say_hello)\n```\n\nYou don't need the assignment (setting the variable `say_hello`) as FastAPI always returns the function itself. That was to illustrate what decorators do.\n\nI agree that the above is ugly and you might want to use the `app.add_api_route` as MatsLindh's answer suggests. However, I did not find that in the FastAPI documentation so not sure how official it is. Overall, it seems FastAPI's documentation lacks in this regard.\n\n========================================\n\nCode:\n```py\nfrom flask import Flask\napp = Flask()\n\ndef say_hello():\n return \"Hello\"\n\napp.add_url_rule('/hello', 'say_hello', say_hello)\n```\n\n```py\n@app.route(\"/hello\")\ndef say_hello():\n return \"Hello\"\n```\n\n```text\nadd_url_rule\n```\n\n```py\nfrom fastapi import FastAPI, APIRouter\n\n\ndef foo_it():\n return {'Fooed': True}\n\n\napp = FastAPI()\nrouter = APIRouter()\nrouter.add_api_route('/foo', endpoint=foo_it)\napp.include_router(router)\napp.add_api_route('/foo-app', endpoint=foo_it)\n```\n\n```text\nλ curl http://localhost:8000/foo\n{\"Fooed\":true}\nλ curl http://localhost:8000/foo-app\n{\"Fooed\":true}\n```\n\n```text\nadd_api_route\n```\n\n```text\nfrom fastapi import FastAPI\napp = FastAPI()\n\n@app.get(\"/hello\")\ndef say_hello():\n return \"Hello\"\n```\n\n```text\nfrom fastapi import FastAPI\napp = FastAPI()\n\ndef say_hello():\n return \"Hello\"\n\n\nsay_hello = app.get(\"/hello\")(say_hello)\n```\n\n```text\nsay_hello\n```\n\n```text\napp.add_api_route\n```\n\n========================================\n\nComments:\n- You can always call the decorator directly, of course `app.route(\"/hello\")(say_hello)`\n- To define the method `methods=[\"POST\"]` should be passed as another keyword argument. Unfortunately there is no clear documentation about that.\n- You can safely assume that it supports all of the parameters that the regular view decorator does, since `app.get` / `app.post` just wraps the same `APIRouter` and the `api_route` method.\n- Thank you. This was very helpful. I just want to add that `router.add_websocket_route` is the corresponding method for `@router.websocket` (in case you are looking for both, as I was).","metadata":{"transformedAt":"2026-08-18T18:32:29.119Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":10,"totalLines":143,"estimatedTokens":766}}278{"id":"stack-65716615","source":"stackoverflow","questionId":65716615,"title":"FastAPI file upload","tags":["python-requests","fastapi","uvicorn","http-status-code-422"],"text":"Title: FastAPI file upload\nTags: python-requests, fastapi, uvicorn, http-status-code-422\nSource: Stack Overflow\n\nQuestion:\nI am trying to upload JSON data + file (binary) to FastAPI 'POST' endpoint using requests.\n\nThis is the server code:\n\n```\n@app.post(\"/files/\")\nasync def create_file(\n file: bytes = File(...), fileb: UploadFile = File(...), timestamp: str = Form(...)\n):\n return {\n \"file_size\": len(file),\n \"timestamp\": timestamp,\n \"fileb_content_type\": fileb.content_type,\n }\n```\n\nThis is the client code:\n\n```\nsession = requests.Session()\nadapter = requests.adapters.HTTPAdapter(max_retries=0)\nsession.mount('http://', adapter)\n\njpg_image = open(IMG_PATH, 'rb').read()\n\ntimestamp_str = datetime.datetime.now().isoformat()\nfiles = {\n 'timestamp': (None, timestamp_str),\n 'file': ('image.jpg', jpg_image),\n}\nrequest = requests.Request('POST',\n FILE_UPLOAD_ENDPOINT,\n files=files)\nprepared_request = request.prepare()\nresponse = session.send(prepared_request)\n```\n\nThe server fails with\n\n\"POST /files/ HTTP/1.1\" 422 Unprocessable Entity\n\n========================================\n\nCode:\n```text\n@app.post(\"/files/\")\nasync def create_file(\n file: bytes = File(...), fileb: UploadFile = File(...), timestamp: str = Form(...)\n):\n return {\n \"file_size\": len(file),\n \"timestamp\": timestamp,\n \"fileb_content_type\": fileb.content_type,\n }\n```\n\n```text\nsession = requests.Session()\nadapter = requests.adapters.HTTPAdapter(max_retries=0)\nsession.mount('http://', adapter)\n\njpg_image = open(IMG_PATH, 'rb').read()\n\ntimestamp_str = datetime.datetime.now().isoformat()\nfiles = {\n 'timestamp': (None, timestamp_str),\n 'file': ('image.jpg', jpg_image),\n}\nrequest = requests.Request('POST',\n FILE_UPLOAD_ENDPOINT,\n files=files)\nprepared_request = request.prepare()\nresponse = session.send(prepared_request)\n```\n\n```text\nfileb: Optional[UploadFile] = File(None)\n```\n\n```text\nfileb\n```\n\n========================================\n\nComments:\n- Please add the 422 response's body in your question for clarity.\n- For what it's worth , the response with status `422` comes from `fastapi.exception_handlers.request_validation_exception_hand‌​ler(req, exc)` , if you are on development stage , you can set breakpoint then get more detail about the error from `exc` (the exception object) , the exception should describe that there is a missing field `fileb` , which means in your client code you should also specify the same field name `fileb` in the request body\n- If you are trying to upload both JSON data and file(s), as mentioned in the question, please have a look at this answer as well\n- Thanks @JohnMoutafis for the response. I fixed the endpoint to match the request and it worked. The correct code is: `@app.post(\"/files/\", status_code=201) async def create_file( file: bytes = File(...), timestamp: str = Form(...), ):`","metadata":{"transformedAt":"2026-08-18T18:32:29.119Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":95,"estimatedTokens":729}}279{"id":"stack-59920126","source":"stackoverflow","questionId":59920126,"title":"REST API in Python with FastAPI and pydantic: read-only property in model","tags":["python","python-3.x","rest","fastapi","pydantic"],"text":"Title: REST API in Python with FastAPI and pydantic: read-only property in model\nTags: python, python-3.x, rest, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nAssume a REST API which defines a POST method on a resource /foos to create a new Foo. When creating a Foo the name of the Foo is an input parameter (present in the request body). When the server creates a Foo it assigns it an ID. This ID is returned together with the name in the REST response.\nI am looking for something similar to readOnly in OpenAPI.\n\nThe input JSON should look like this:\n\n```\n{\n \"name\": \"bar\"\n}\n```\n\nThe output JSON should look like that:\n\n```\n{\n \"id\": 123,\n \"name\": \"bar\"\n}\n```\n\nIs there a way to reuse the same pydantic model? Or is it necessary to use two diffent models?\n\n```\nclass FooIn(BaseModel):\n name: str\n\nclass Foo(BaseModel):\n id: int\n name: str\n```\n\nI cannot find any mentions of \"read only\", \"read-only\", or \"readonly\" in the pydantic documentation or in the Field class code.\n\nGoogling I found a post which mentions\n\n```\nid: int = Schema(..., readonly=True)\n```\n\nBut that seems to have no effect in my use case.\n\n========================================\n\nCode:\n```text\n{\n \"name\": \"bar\"\n}\n```\n\n```text\n{\n \"id\": 123,\n \"name\": \"bar\"\n}\n```\n\n```text\nclass FooIn(BaseModel):\n name: str\n\nclass Foo(BaseModel):\n id: int\n name: str\n```\n\n```text\nid: int = Schema(..., readonly=True)\n```\n\n```text\nfrom pydantic import BaseModel\n\n\n# Properties to receive via API create/update\nclass Foo(BaseModel):\n name: str\n\n\n# Properties to return via API\nclass FooDB(Foo):\n id: int\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.119Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":88,"estimatedTokens":397}}280{"id":"stack-68997345","source":"stackoverflow","questionId":68997345,"title":"How to dict or data check keys in pydantic","tags":["python","fastapi","pydantic"],"text":"Title: How to dict or data check keys in pydantic\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\n```\nclass mail(BaseModel):\n mailid: int\n email: str\n \nclass User(BaseModel):\n id: int\n name: str\n mails: List[mail]\n\ndata1 = {\n 'id': 123,\n 'name': 'Jane Doe',\n 'mails':[\n {'mailid':1,'email':'aeajhs@gmail.com'}, \n {'mailid':2,'email':'aeajhsds@gmail.com'}\n ]\n}\nuserobj = User(**data1) # Accepted\ndata2 = {\n 'id': 123,\n 'name': 'Jane Doe',\n 'mails':[\n {'mailid':1,'email':'aeajhs@gmail.com'}, \n {'email':'aeajhsds@gmail.com'}\n ]\n }\n \nuserobj = User(**data2) # Discarded or not accepted\n```\n\nI want to check the keys in the dictionary that we passing to pydantic model so If the key is not present in the given dictionary I want to discard that data.\nFor example in data2 in mails `{'email':'aeajhsds@gmail.com'}` data2 must be discarded\n\n========================================\n\nTop Answer:\nYou could iterate over the `mails` list in a pre validation and do a simple `try`-clause to check if each `mail` item is correct:\n\n```\nfrom pydantic import BaseModel, validator\nfrom pydantic.error_wrappers import ValidationError\nfrom typing import List\n\nclass mail(BaseModel):\n mailid: int\n email: str\n\nclass User(BaseModel):\n id: int\n name: str\n mails: List[mail]\n\n @validator(\"mails\", pre=True)\n def must_be_valid_mail(cls, v):\n ret = []\n for item in list(v):\n try:\n mail(**item)\n ret.append(item)\n except ValidationError as er:\n print(er)\n return ret\n\ndata = {\n 'id': 123,\n 'name': 'Jane Doe',\n 'mails':[\n {'mailid':1,'email':'aeajhs@gmail.com'}, \n {'email':'aeajhsds@gmail.com'}\n ]\n}\n\nuserobj = User(**data)\nprint(userobj)\n```\n\n========================================\n\nCode:\n```text\nclass mail(BaseModel):\n mailid: int\n email: str\n \nclass User(BaseModel):\n id: int\n name: str\n mails: List[mail]\n\ndata1 = {\n 'id': 123,\n 'name': 'Jane Doe',\n 'mails':[\n {'mailid':1,'email':'aeajhs@gmail.com'}, \n {'mailid':2,'email':'aeajhsds@gmail.com'}\n ]\n}\nuserobj = User(**data1) # Accepted\ndata2 = {\n 'id': 123,\n 'name': 'Jane Doe',\n 'mails':[\n {'mailid':1,'email':'aeajhs@gmail.com'}, \n {'email':'aeajhsds@gmail.com'}\n ]\n }\n \nuserobj = User(**data2) # Discarded or not accepted\n```\n\n```text\n{'email':'aeajhsds@gmail.com'}\n```\n\n```py\nfrom pydantic import BaseModel, validator\nfrom typing import List, Optional\n\n\nclass Mail(BaseModel):\n mailid: int\n email: str\n \nclass User(BaseModel):\n id: int\n name: str\n mails: Optional[List[Mail]]\n\n @validator('mails', pre=True)\n def mail_check(cls, v):\n mail_att = [i for i in Mail.__fields__.keys()]\n mail_att_count = 0\n for i, x in enumerate(v):\n for k in dict(x).keys():\n if k in mail_att:\n mail_att_count += 1\n if mail_att_count != len(mail_att):\n v.pop(i)\n mail_att_count = 0\n return v\n```\n\n```py\ndata = {\n 'id': 123,\n 'name': 'Jane Doe',\n 'mails':[\n {'mailid':1,'email':'aaa@gmail.com'},\n {'mailid':2,'email':'bbb@gmail.com'},\n {'email':'ccc@gmail.com'}\n ]\n}\n\nx = User(**data) # Discarded or not accepted\nprint(x.id)\nprint(x.name)\nprint(x.mails)\n\n# Output\n# >>123\n# >>Jane Doe\n# >>[Mail(mailid=1, email='aaa@gmail.com'), Mail(mailid=2, email='bbb@gmail.com')]\n```\n\n```text\npydantic.validator\n```\n\n```text\nOptional\n```\n\n```text\npre=True\n```\n\n```none\nTraceback (most recent call last):\n...\npydantic.error_wrappers.ValidationError: 1 validation error for User\nmails -> 1 -> mailid\n field required (type=value_error.missing)\n```\n\n```py\nfrom pydantic import ValidationError\n\n# your code here\n\ntry:\n userobj = User(**data2)\nexcept ValidationError as exc:\n # Optional printout or logging:\n print(f\"Encountered the following error when parsing `{data2}`:\\n{exc}.\\nSkipping...\")\n```\n\n```none\nEncountered the following error when parsing `{'id': 123, 'name': 'Jane Doe', 'mails': [{'mailid': 1, 'email': 'aeajhs@gmail.com'}, {'email': 'aeajhsds@gmail.com'}]}`:\n1 validation error for User\nmails -> 1 -> mailid\n field required (type=value_error.missing).\nSkipping...\n```\n\n```py\nfrom typing import Optional\n\nclass mail(BaseModel):\n mailid: Optional[int]\n email: str\n\n# ... everything stays the same\n\n# This works now:\nuserobj = User(**data2)\n\nprint(userobj)\n# id=123 name='Jane Doe' mails=[mail(mailid=1, email='aeajhs@gmail.com'), mail(mailid=None, email='aeajhsds@gmail.com')]\n```\n\n```text\nValidationError\n```\n\n```text\nmailid\n```\n\n```text\nmails\n```\n\n```text\ndata2\n```\n\n```text\ndata2\n```\n\n```text\ntry\n```\n\n```text\nexcept\n```\n\n```text\nmailid\n```\n\n```text\nOptional\n```\n\n```text\nfrom pydantic import BaseModel, validator\nfrom pydantic.error_wrappers import ValidationError\nfrom typing import List\n\nclass mail(BaseModel):\n mailid: int\n email: str\n\nclass User(BaseModel):\n id: int\n name: str\n mails: List[mail]\n\n @validator(\"mails\", pre=True)\n def must_be_valid_mail(cls, v):\n ret = []\n for item in list(v):\n try:\n mail(**item)\n ret.append(item)\n except ValidationError as er:\n print(er)\n return ret\n\ndata = {\n 'id': 123,\n 'name': 'Jane Doe',\n 'mails':[\n {'mailid':1,'email':'aeajhs@gmail.com'}, \n {'email':'aeajhsds@gmail.com'}\n ]\n}\n\nuserobj = User(**data)\nprint(userobj)\n```\n\n```text\nmails\n```\n\n```text\ntry\n```\n\n```text\nmail\n```\n\n========================================\n\nComments:\n- use a validator?\n- Yes can you give me example code\n- Do you only want to discard that single item in the list, or do you want to refuse to generate the `User` object at all?\n- I want to discard total data\n- Can I use validator for user class with some keys only like id and name\n- Can I use validator for user class with some keys only like id and name\n- You could always use `Optional` on any of the fields. See updated solution.\n- Can I use validator for user class with some keys only like id and name\n- Can I use validator for user class with some keys only like id and name\n- Yeah, you can write your own validators for any key you like: pydantic-docs.helpmanual.io/usage/validators","metadata":{"transformedAt":"2026-08-18T18:32:29.119Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":24,"totalLines":325,"estimatedTokens":1556}}281{"id":"stack-73375390","source":"stackoverflow","questionId":73375390,"title":"How to override \"env_file\" during tests?","tags":["python","pytest","fastapi","pydantic"],"text":"Title: How to override \"env_file\" during tests?\nTags: python, pytest, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI'm reading env variables from `.prod.env` file in my *config.py*:\n\n```\nfrom pydantic import BaseSettings\n\nclass Settings(BaseSettings):\n A: int\n\n class Config:\n env_file = \".prod.env\"\n env_file_encoding = \"utf-8\"\n\nsettings = Settings()\n```\n\nin my *main.py* I'm creating the `app` like so:\n\n```\nfrom fastapi import FastAPI\nfrom app.config import settings\n\napp = FastAPI()\nprint(settings.A)\n```\n\nI am able to override settings variables like this in my `conftest.py`:\n\n```\nimport pytest\nfrom fastapi.testclient import TestClient\n\nfrom app.main import app\nfrom app.config import settings\n\nsettings.A = 42\n\n@pytest.fixture(scope=\"module\")\ndef test_clinet():\n with TestClient(app) as client:\n yield client\n```\n\nThis works fine, whenever I use `settings.A` I get 42.\n\nBut is it possible to override the whole `env_file` from `.prod.env` to another env file `.test.env`?\n\nAlso I probably want to call `settings.A = 42` in *conftest.py* before I import `app`, right?\n\n========================================\n\nTop Answer:\nThe Pydantic Settings class reads both the environment variables specified in a .env file as well as the environment variables found in the current sessions environment. If a value is present in both it will opt to read from the environment instead. You can leverage this fact to overwrite values found in the env file during testing.\n\nIf you include `pytest_configure` in `/conftest.py` you can run code before any imports are made. This allows you to overwrite environment variables before Settings is initialised. The changes in the environment variables only affect the python process.\n\n```\nfrom pathlib import Path\nfrom dotenv import load_dotenv\n\ndef pytest_configure(config):\n # This is run before any imports allowing us to inject\n # dependencies via environment variables into Settings\n # This just affects the variables in this process's environment\n\n # Find the .env file for the test environment\n test_env = str(Path(__file__).parent / \"test.env\")\n # Load the environment variables and overwrite any existing ones\n load_dotenv(test_env, override=True)\n```\n\n========================================\n\nCode:\n```py\nfrom pydantic import BaseSettings\n\n\nclass Settings(BaseSettings):\n A: int\n\n class Config:\n env_file = \".prod.env\"\n env_file_encoding = \"utf-8\"\n\nsettings = Settings()\n```\n\n```py\nfrom fastapi import FastAPI\nfrom app.config import settings\n\napp = FastAPI()\nprint(settings.A)\n```\n\n```py\nimport pytest\nfrom fastapi.testclient import TestClient\n\nfrom app.main import app\nfrom app.config import settings\n\nsettings.A = 42\n\n@pytest.fixture(scope=\"module\")\ndef test_clinet():\n with TestClient(app) as client:\n yield client\n```\n\n```text\n.prod.env\n```\n\n```text\napp\n```\n\n```text\nconftest.py\n```\n\n```text\nsettings.A\n```\n\n```text\nenv_file\n```\n\n```text\n.prod.env\n```\n\n```text\n.test.env\n```\n\n```text\nsettings.A = 42\n```\n\n```text\napp\n```\n\n```text\nimport pytest\nfrom fastapi.testclient import TestClient\n\nimport app.config as conf\nfrom app.config import Settings\n\n# replace the settings object that you created in the module\nconf.settings = Settings(_env_file='.test.env')\n\nfrom app.main import app\n\n# just to show you that you changed the module-level\n# settings\nfrom app.config import settings\n\n@pytest.fixture(scope=\"module\")\ndef test_client():\n with TestClient(app) as client:\n yield client\n\ndef test_settings():\n print(conf.settings)\n print(settings)\n```\n\n```text\npytest -rP conftest.py\n\n# stuff\n----- Captured stdout call -----\nA=10000000\nA=10000000\n```\n\n```text\nSettings\n```\n\n```text\n_env_file\n```\n\n```text\n_env_file\n```\n\n```text\nConfig\n```\n\n```text\n.test.env\n```\n\n```text\nA=10000000\n```\n\n```text\nsettings\n```\n\n```text\n__main__\n```\n\n```py\nfrom pydantic import BaseSettings\nfrom dotenv import load_dotenv\n\nload_dotenv(\".prod.env\")\n\n\nclass Settings(BaseSettings):\n A: int\n\n\nsettings = Settings()\n```\n\n```py\nimport pytest\nfrom fastapi.testclient import TestClient\nfrom dotenv import load_dotenv\n\nload_dotenv(\"test.env\")\n\nfrom app.config import settings\nfrom app.main import app\n\n\n@pytest.fixture(scope=\"module\")\ndef test_clinet():\n with TestClient(app) as client:\n yield client\n```\n\n```text\nenv_file\n```\n\n```text\nload_dotenv()\n```\n\n```text\nload_dotenv(\"test.env\")\n```\n\n```text\nfrom app.config import settings\n```\n\n```text\nenv_file\n```\n\n```text\nimport pytest\n\nfrom typing import Generator\nfrom fastapi.testclient import TestClient\n\nimport app.core.config as config\nfrom app.core.config import Settings\n\n# Replace individual attribute in the settings object\nconfig.settings = Settings(\n POSTGRES_DB=\"test_db\")\n\n# Or replace the env file in the settings object\nconfig.settings = Settings(_env_file='.test.env')\n\n# All other modules that import settings are imported here\n# This ensures that those modules will use the updated settings object\n# Don't forget to use \"noqa\", otherwise a formatter might put it back on top\nfrom app.main import app # noqa\nfrom app.db.session import SessionLocal # noqa\n\n\n@pytest.fixture(scope=\"session\")\ndef db() -> Generator:\n try:\n db = SessionLocal()\n yield db\n finally:\n db.close()\n\n\n@pytest.fixture(scope=\"module\")\ndef client() -> Generator:\n with TestClient(app) as c:\n yield c\n```\n\n```text\n.env\n```\n\n```text\nconftest.py\n```\n\n```text\nSettings.model_config.update(env_file=\".test.env\")\n```\n\n```py\nfrom pathlib import Path\nfrom dotenv import load_dotenv\n\ndef pytest_configure(config):\n # This is run before any imports allowing us to inject\n # dependencies via environment variables into Settings\n # This just affects the variables in this process's environment\n\n # Find the .env file for the test environment\n test_env = str(Path(__file__).parent / \"test.env\")\n # Load the environment variables and overwrite any existing ones\n load_dotenv(test_env, override=True)\n```\n\n```text\npytest_configure\n```\n\n```text\n/conftest.py\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.119Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":36,"totalLines":341,"estimatedTokens":1506}}282{"id":"stack-67910582","source":"stackoverflow","questionId":67910582,"title":"How can I properly setup basic traefik reverse proxy?","tags":["docker","docker-compose","reverse-proxy","traefik","fastapi"],"text":"Title: How can I properly setup basic traefik reverse proxy?\nTags: docker, docker-compose, reverse-proxy, traefik, fastapi\nSource: Stack Overflow\n\nQuestion:\nAssume my current public IP is `101.15.14.71`, I have a domain called `example.com` which I configured using cloudflare and I created multiple DNS entry pointing to my public ip.\n\nEg:\n\n```\n1) new1.example.com - 101.15.14.71\n2) new2.example.com - 101.15.14.71\n3) new3.example.com - 101.15.14.71\n```\n\nNow, Here's my example project structure,\n\n```\n├── myapp\n│ ├── app\n│ │ └── main.py\n│ ├── docker-compose.yml\n│ └── Dockerfile\n├── myapp1\n│ ├── app\n│ │ └── main.py\n│ ├── docker-compose.yml\n│ └── Dockerfile\n└── traefik\n ├── acme.json\n ├── docker-compose.yml\n ├── traefik_dynamic.toml\n └── traefik.toml\n```\n\nHere I have two fastAPIs (i.e., myapp, myapp1)\n\nHere's the example code I have in **main.py** in both myapp and myapp1, Its exactly same but return staement is different that's all\n\n```\nfrom fastapi import FastAPI\napp = FastAPI()\n@app.get(\"/\")\ndef read_main():\n return {\"message\": \"Hello world for my project myapp\"}\n```\n\nHere's my **Dockerfile** for myapp and myapp1, here too both are exactly same but the only difference is I deploy myapp on `7777` and myapp1 on `7778` in different containers\n\n```\nFROM ubuntu:latest\n\nARG DEBIAN_FRONTEND=noninteractive\nRUN apt update && apt upgrade -y\nRUN apt install -y -q build-essential python3-pip python3-dev\n\n# python dependencies\nRUN pip3 install -U pip setuptools wheel\nRUN pip3 install gunicorn fastapi uvloop httptools \"uvicorn[standard]\"\n\n# copy required files\nRUN bash -c 'mkdir -p /app'\nCOPY ./app /app\n\nENTRYPOINT /usr/local/bin/gunicorn \\\n -b 0.0.0.0:7777 \\ # this line I use for myapp dockerfile\n -b 0.0.0.0:7778 \\ # this line I change for myapp1 dockerfile\n -w 1 \\\n -k uvicorn.workers.UvicornWorker app.main:app \\\n --chdir /app\n```\n\nHere's my **docker-compose.yml** file for myapp and myapp1, here also I have exactly same but only difference is I change the port,\n\n```\nservices:\n myapp: # I use this line for myapp docker-compose file\n myapp1: # I use this line for myapp1 docker-compose file\n build: .\n restart: always\n labels:\n - \"traefik.enable=true\"\n - \"traefik.docker.network=traefik_public\"\n\n - \"traefik.backend=myapp\" # I use this line for myapp docker-compose file\n - \"traefik.backend=myapp1\" # I use this line for myapp1 docker-compose file\n\n - \"traefik.frontend.rule=Host:new2.example.com\" # I use this for myapp compose file\n - \"traefik.frontend.rule=Host:new3.example.com\" # I use this for myapp1 compose file\n\n - \"traefik.port=7777\" # I use this line for myapp docker-compose file\n - \"traefik.port=7778\" # I use this line for myapp1 docker-compose file\n networks:\n - traefik_public\n\nnetworks:\n traefik_public:\n external: true\n```\n\nNow coming to traefik folder,\n\n**acme.json** # I created it using `nano acme.json` command with nothing in it,\nbut did `chmod 600 acme.json` for proper permissions.\n\ntraefik_dynamic.toml\n\n```\n[http]\n [http.routers]\n [http.routers.route0]\n entryPoints = [\"web\"]\n middlewares = [\"my-basic-auth\"]\n service = \"api@internal\"\n rule = \"Host(`new1.example.com`)\"\n [http.routers.route0.tls]\n certResolver = \"myresolver\"\n\n[http.middlewares.test-auth.basicAuth]\n users = [\n [\"admin:your_encrypted_password\"]\n ]\n```\n\n- traefik.toml\n\n```\n[entryPoints]\n [entryPoints.web]\n address = \":80\"\n [entryPoints.web.http]\n [entryPoints.web.http.redirections]\n [entryPoints.web.http.redirections.entryPoint]\n to = \"websecure\"\n scheme = \"https\"\n\n [entryPoints.websecure]\n address = \":443\"\n\n[api]\n dashboard = true\n\n[certificatesResolvers.myresolver.acme]\n email = \"reallygoodtraefik@gmail.com\"\n storage= \"acme.json\"\n [certificatesResolvers.myresolver.acme.httpChallenge]\n entryPoint = \"web\"\n\n[providers]\n [providers.docker]\n watch = true\n network = \"web\"\n [providers.file]\n filename = \"traefik_dynamic.toml\"\n```\n\n- docker-compose.yml\n\n```\nservices:\n traefik:\n image: traefik:latest\n ports:\n - 80:80\n - 443:443\n - 8080:8080\n volumes:\n - /var/run/docker.sock:/var/run/docker.sock\n - ./traefik.toml:/traefik.toml\n - ./acme.json:/acme.json\n - ./traefik_dynamic.toml:/traefik_dynamic.toml\n networks:\n - web\n\nnetworks:\n web:\n```\n\nThese are the details about my files, what I am trying to achieve here is,\n\nI want to setup traefik and traefik dashboard with basic authentication, and I deploy two of my fastapi services,\n\n- myapp **7777**, I need to access this app via `new2.example.com`\n\n- myapp1 **7778**, I need to access this app via `new3.example.com`\n\n- traefik dashboard, I need to access this via `new1.example.com`\n\nAll of these should be https and also has certification autorenew enabled.\n\nI got all these from online articles for latest version of traefik. But the problem is this is not working. I used docker-compose to build and deploy the traefik and I open the api dashboard. It is asking for password and user (`basic auth I setup`) I entered my user details I setup in `traefik_dynamic.toml` but its not working.\n\nWhere did I do wrong? Please help me correcting mistakes in my configuration. I am really interested to learn more about this.\n\nError Update:\n\n```\ntraefik_1 | time=\"2021-06-16T01:51:16Z\" level=error msg=\"Unable to obtain ACME certificate for domains \\\"new1.example.com\\\": unable to generate a certificate for the domains [new1.example.com]: error: one or more domains had a problem:\\n[new1.example.com] acme: error: 403 :: urn:ietf:params:acme:error:unauthorized :: Invalid response from http://new1.example.com/.well-known/acme-challenge/mu85LkYEjlvnbDI-wM2xMaRFO1QsPDNjepTDb47dWF0 [2606:4700:3032::6815:55c4]: 404\\n\" rule=\"Host(`new1.example.com`)\" routerName=api@docker providerName=myresolver.acme\n\ntraefik_1 | time=\"2021-06-16T01:51:19Z\" level=error msg=\"Unable to obtain ACME certificate for domains \\\"new2.example.com\\\": unable to generate a certificate for the domains [new2.example.com]: error: one or more domains had a problem:\\n[new2.example.com] acme: error: 403 :: urn:ietf:params:acme:error:unauthorized :: Invalid response from http://new2.example.com/.well-known/acme-challenge/ykiCAEpJeQ1qgVdeFtSRo3q-ATTwgKdRdGHUs2kgIsY [2606:4700:3031::ac43:d1e9]: 404\\n\" providerName=myresolver.acme routerName=myapp1@docker rule=\"Host(`new2.example.com`)\"\n\ntraefik_1 | time=\"2021-06-16T01:51:20Z\" level=error msg=\"Unable to obtain ACME certificate for domains \\\"new3.example.com\\\": unable to generate a certificate for the domains [new3.example.com]: error: one or more domains had a problem:\\n[new3.example.com] acme: error: 403 :: urn:ietf:params:acme:error:unauthorized :: Invalid response from http://new3.example.com/.well-known/acme-challenge/BUZWuWdNd2XAXwXCwkeqe5-PHb8cGV8V6UtzeLaKryE [2606:4700:3031::ac43:d1e9]: 404\\n\" providerName=myresolver.acme routerName=myapp@docker rule=\"Host(`new3.example.com`)\"\n```\n\n========================================\n\nCode:\n```text\n1) new1.example.com - 101.15.14.71\n2) new2.example.com - 101.15.14.71\n3) new3.example.com - 101.15.14.71\n```\n\n```text\n├── myapp\n│ ├── app\n│ │ └── main.py\n│ ├── docker-compose.yml\n│ └── Dockerfile\n├── myapp1\n│ ├── app\n│ │ └── main.py\n│ ├── docker-compose.yml\n│ └── Dockerfile\n└── traefik\n ├── acme.json\n ├── docker-compose.yml\n ├── traefik_dynamic.toml\n └── traefik.toml\n```\n\n```text\nfrom fastapi import FastAPI\napp = FastAPI()\n@app.get(\"/\")\ndef read_main():\n return {\"message\": \"Hello world for my project myapp\"}\n```\n\n```text\nFROM ubuntu:latest\n\nARG DEBIAN_FRONTEND=noninteractive\nRUN apt update && apt upgrade -y\nRUN apt install -y -q build-essential python3-pip python3-dev\n\n# python dependencies\nRUN pip3 install -U pip setuptools wheel\nRUN pip3 install gunicorn fastapi uvloop httptools \"uvicorn[standard]\"\n\n# copy required files\nRUN bash -c 'mkdir -p /app'\nCOPY ./app /app\n\n\nENTRYPOINT /usr/local/bin/gunicorn \\\n -b 0.0.0.0:7777 \\ # this line I use for myapp dockerfile\n -b 0.0.0.0:7778 \\ # this line I change for myapp1 dockerfile\n -w 1 \\\n -k uvicorn.workers.UvicornWorker app.main:app \\\n --chdir /app\n```\n\n```text\nservices:\n myapp: # I use this line for myapp docker-compose file\n myapp1: # I use this line for myapp1 docker-compose file\n build: .\n restart: always\n labels:\n - \"traefik.enable=true\"\n - \"traefik.docker.network=traefik_public\"\n\n - \"traefik.backend=myapp\" # I use this line for myapp docker-compose file\n - \"traefik.backend=myapp1\" # I use this line for myapp1 docker-compose file\n\n\n - \"traefik.frontend.rule=Host:new2.example.com\" # I use this for myapp compose file\n - \"traefik.frontend.rule=Host:new3.example.com\" # I use this for myapp1 compose file\n\n - \"traefik.port=7777\" # I use this line for myapp docker-compose file\n - \"traefik.port=7778\" # I use this line for myapp1 docker-compose file\n networks:\n - traefik_public\n\nnetworks:\n traefik_public:\n external: true\n```\n\n```text\n[http]\n [http.routers]\n [http.routers.route0]\n entryPoints = [\"web\"]\n middlewares = [\"my-basic-auth\"]\n service = \"api@internal\"\n rule = \"Host(`new1.example.com`)\"\n [http.routers.route0.tls]\n certResolver = \"myresolver\"\n\n[http.middlewares.test-auth.basicAuth]\n users = [\n [\"admin:your_encrypted_password\"]\n ]\n```\n\n```text\n[entryPoints]\n [entryPoints.web]\n address = \":80\"\n [entryPoints.web.http]\n [entryPoints.web.http.redirections]\n [entryPoints.web.http.redirections.entryPoint]\n to = \"websecure\"\n scheme = \"https\"\n\n [entryPoints.websecure]\n address = \":443\"\n\n[api]\n dashboard = true\n\n[certificatesResolvers.myresolver.acme]\n email = \"reallygoodtraefik@gmail.com\"\n storage= \"acme.json\"\n [certificatesResolvers.myresolver.acme.httpChallenge]\n entryPoint = \"web\"\n\n[providers]\n [providers.docker]\n watch = true\n network = \"web\"\n [providers.file]\n filename = \"traefik_dynamic.toml\"\n```\n\n```text\nservices:\n traefik:\n image: traefik:latest\n ports:\n - 80:80\n - 443:443\n - 8080:8080\n volumes:\n - /var/run/docker.sock:/var/run/docker.sock\n - ./traefik.toml:/traefik.toml\n - ./acme.json:/acme.json\n - ./traefik_dynamic.toml:/traefik_dynamic.toml\n networks:\n - web\n\nnetworks:\n web:\n```\n\n```text\ntraefik_1 | time=\"2021-06-16T01:51:16Z\" level=error msg=\"Unable to obtain ACME certificate for domains \\\"new1.example.com\\\": unable to generate a certificate for the domains [new1.example.com]: error: one or more domains had a problem:\\n[new1.example.com] acme: error: 403 :: urn:ietf:params:acme:error:unauthorized :: Invalid response from http://new1.example.com/.well-known/acme-challenge/mu85LkYEjlvnbDI-wM2xMaRFO1QsPDNjepTDb47dWF0 [2606:4700:3032::6815:55c4]: 404\\n\" rule=\"Host(`new1.example.com`)\" routerName=api@docker providerName=myresolver.acme\n\ntraefik_1 | time=\"2021-06-16T01:51:19Z\" level=error msg=\"Unable to obtain ACME certificate for domains \\\"new2.example.com\\\": unable to generate a certificate for the domains [new2.example.com]: error: one or more domains had a problem:\\n[new2.example.com] acme: error: 403 :: urn:ietf:params:acme:error:unauthorized :: Invalid response from http://new2.example.com/.well-known/acme-challenge/ykiCAEpJeQ1qgVdeFtSRo3q-ATTwgKdRdGHUs2kgIsY [2606:4700:3031::ac43:d1e9]: 404\\n\" providerName=myresolver.acme routerName=myapp1@docker rule=\"Host(`new2.example.com`)\"\n\ntraefik_1 | time=\"2021-06-16T01:51:20Z\" level=error msg=\"Unable to obtain ACME certificate for domains \\\"new3.example.com\\\": unable to generate a certificate for the domains [new3.example.com]: error: one or more domains had a problem:\\n[new3.example.com] acme: error: 403 :: urn:ietf:params:acme:error:unauthorized :: Invalid response from http://new3.example.com/.well-known/acme-challenge/BUZWuWdNd2XAXwXCwkeqe5-PHb8cGV8V6UtzeLaKryE [2606:4700:3031::ac43:d1e9]: 404\\n\" providerName=myresolver.acme routerName=myapp@docker rule=\"Host(`new3.example.com`)\"\n```\n\n```text\n101.15.14.71\n```\n\n```text\nexample.com\n```\n\n```text\n7777\n```\n\n```text\n7778\n```\n\n```text\nnano acme.json\n```\n\n```text\nchmod 600 acme.json\n```\n\n```text\nnew2.example.com\n```\n\n```text\nnew3.example.com\n```\n\n```text\nnew1.example.com\n```\n\n```text\nbasic auth I setup\n```\n\n```text\ntraefik_dynamic.toml\n```\n\n```text\n├── docker-compose.yml\n├── myapp\n│ ├── .dockerignore\n│ ├── Dockerfile\n│ └── app\n│ └── main.py\n├── myapp1\n│ ├── .dockerignore\n│ ├── Dockerfile\n│ └── app\n│ └── main.py\n└── traefik\n ├── acme.json\n └── traefik.yml\n```\n\n```text\nFROM python:3.7-slim\n\nARG DEBIAN_FRONTEND=noninteractive\n\nENV PYTHONUNBUFFERED=1\n\nRUN pip3 install -U pip setuptools wheel && \\\n pip3 install gunicorn fastapi uvloop httptools \"uvicorn[standard]\"\n\nCOPY . /app\n\nENV PORT=7777 # and 7778 for myapp1\n\nENTRYPOINT /usr/local/bin/gunicorn -b 0.0.0.0:$PORT -w 1 -k uvicorn.workers.UvicornWorker app.main:app --chdir /app\n```\n\n```text\nDockerfile\n```\n\n```yml\nproviders:\n docker:\n exposedByDefault: false\n\nglobal:\n checkNewVersion: false\n sendAnonymousUsage: false\n\napi: {}\naccessLog: {}\n\nentryPoints:\n web:\n address: \":80\"\n http:\n redirections:\n entryPoint:\n to: \"websecure\"\n scheme: \"https\"\n websecure:\n address: \":443\"\n\nping:\n entryPoint: \"websecure\"\n\ncertificatesResolvers:\n myresolver:\n acme:\n caServer: \"https://acme-staging-v02.api.letsencrypt.org/directory\"\n email: \"example@example.com\"\n storage: \"/etc/traefik/acme.json\"\n httpChallenge:\n entryPoint: \"web\"\n```\n\n```yml\nversion: \"3.9\"\n\nservices:\n myapp:\n build:\n context: ./myapp\n dockerfile: ./Dockerfile\n image: myapp\n depends_on:\n - traefik\n expose:\n - 7777\n labels:\n - \"traefik.enable=true\"\n - \"traefik.http.routers.myapp.tls=true\"\n - \"traefik.http.routers.myapp.tls.certResolver=myresolver\"\n - \"traefik.http.routers.myapp.entrypoints=websecure\"\n - \"traefik.http.routers.myapp.rule=Host(`new2.example.com`)\"\n - \"traefik.http.services.myapp.loadbalancer.server.port=7777\"\n myapp1:\n build:\n context: ./myapp1\n dockerfile: ./Dockerfile\n image: myapp1\n depends_on:\n - traefik\n expose:\n - 7778\n labels:\n - \"traefik.enable=true\"\n - \"traefik.http.routers.myapp1.tls=true\"\n - \"traefik.http.routers.myapp1.tls.certResolver=myresolver\"\n - \"traefik.http.routers.myapp1.entrypoints=websecure\"\n - \"traefik.http.routers.myapp1.rule=Host(`new3.example.com`)\"\n - \"traefik.http.services.myapp1.loadbalancer.server.port=7778\"\n traefik:\n image: traefik:v2.4\n volumes:\n - /var/run/docker.sock:/var/run/docker.sock\n - ./traefik/traefik.yml:/etc/traefik/traefik.yml\n - ./traefik/acme.json:/etc/traefik/acme.json\n ports:\n - 80:80\n - 443:443\n labels:\n - \"traefik.enable=true\"\n - \"traefik.http.routers.api.tls=true\"\n - \"traefik.http.routers.api.tls.certResolver=myresolver\"\n - \"traefik.http.routers.api.entrypoints=websecure\"\n - \"traefik.http.routers.api.rule=Host(`new1.example.com`)\"\n - \"traefik.http.routers.api.service=api@internal\"\n - \"traefik.http.routers.api.middlewares=myAuth\"\n - \"traefik.http.middlewares.myAuth.basicAuth.users=admin:$$apr1$$4zjvsq3w$$fLCqJddLvrIZA.CCoGE2E.\" # generate with htpasswd. replace $ with $$\n```\n\n```text\nhtpasswd -n admin | sed 's/\\$/\\$\\$/g'\n```\n\n```text\npython:3.7-slim\n```\n\n```text\nmyapp\n```\n\n```text\nmyapp1\n```\n\n```text\ndocker-compose.yml\n```\n\n```text\nmyapp\n```\n\n```text\nmyapp1\n```\n\n```text\ndocker-compose.yml\n```\n\n```text\nDockerfile\n```\n\n```text\n./myapp/Dockerfile\n```\n\n```text\n./myapp1/Dockerfile\n```\n\n```text\n.dockerignore\n```\n\n```text\n./myapp/.dockerignore\n```\n\n```text\n./myapp1/.dockerignore\n```\n\n```text\nDockerfile\n```\n\n```text\n./traefik/traefik.yml\n```\n\n```text\ncaServer\n```\n\n```text\n./docker-compose.yml\n```\n\n```text\n$$\n```\n\n```text\ndocker-compose up\n```\n\n```text\ndocker-compose.yml\n```\n\n```text\nmyapp\n```\n\n```text\nmyapp1\n```\n\n========================================\n\nComments:\n- Thank you so much for helping out. I am receiving some error. I have updated the question with the error can you help with the error\n- I was getting that error only on my local when I tried this on aws ec2 instance its working fine. There is one issue in aws ec2 instance, when I try to go to `new1.example.com` and it asks for username and password. I entered it but it keeps asking me again. Its not authorizing my username and password. Can you tell me how to create username and password using htpasswd. And why is it that we need to replace `#` with two `##`?\n- Regarding your initial error, acme will only generate the certificate if it can reach the specific domain from the internet, so it would be normal not being able to do so, if the domain and service is not externally accessible. I will update the answer to include the password generation command","metadata":{"transformedAt":"2026-08-18T18:32:29.119Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":48,"totalLines":637,"estimatedTokens":4207}}283{"id":"stack-70138815","source":"stackoverflow","questionId":70138815,"title":"FastAPI responding slowly when calling through other Python app, but fast in cURL","tags":["python","windows","python-requests","fastapi","asgi"],"text":"Title: FastAPI responding slowly when calling through other Python app, but fast in cURL\nTags: python, windows, python-requests, fastapi, asgi\nSource: Stack Overflow\n\nQuestion:\nI have an issue that I can't wrap my head around. I have an API service built using FastAPI, and when I try to call any endpoint from another Python script on my local machine, the response takes 2+ seconds. When I send the same request through cURL or the built-in Swagger docs, the response is nearly instant.\n\nThe entire server script is this:\n\n```\nfrom fastapi import FastAPI\nimport uvicorn\n\napp = FastAPI()\n\n@app.get(\"/\")\nasync def root():\n return {\"message\": \"Hello World\"}\n\nif __name__ == '__main__':\n uvicorn.run(app, host='0.0.0.0', port=8000)\n```\n\nI then call it from a test script using HTTPX. I also tried with the requests package, and it is the same result.\n\n```\nimport httpx\nr = httpx.get('http://localhost:8000/')\nprint(r.elapsed)\n```\n\nThis prints something like: `0:00:02.069705`\n\nI then do the same thing using cURL:\n\n```\ncurl -w \"@curl-format.txt\" -o /dev/null -X 'GET' 'http://localhost:8000/'\n```\n\nThis prints:\n\n```\n% Total % Received % Xferd Average Speed Time Time Time Current\n Dload Upload Total Spent Left Speed\n100 32 100 32 0 0 941 0 --:--:-- --:--:-- --:--:-- 969\n time_namelookup: 0.006436s\n time_connect: 0.006747s\n time_appconnect: 0.000000s\n time_pretransfer: 0.006788s\n time_redirect: 0.000000s\n time_starttransfer: 0.034037s\n ----------\n time_total: 0.034093s\n```\n\nThe issue isn't what the endpoint does, but rather that it doesn't even start executing for 2 seconds. I have a debugger running on the endpoint, and the first line only gets executed after those 2 seconds.\n\nI tried to inspect the request to see whether there are any headers or similar in the request that could slow it down, but nothing. When I try again with the headers generated by HTTPX, it still executes fast:\n\n```\ncurl -w \"@curl-format.txt\" -o /dev/null -X 'GET' \\\n 'http://localhost:8000/events' \\\n -H 'accept: */*' \\\n -H 'host: localhost:8000' \\\n -H 'accept-encoding: gzip, deflate' \\\n -H 'connection: keep-alive' \\\n -H 'user-agent: python-httpx/0.20.0'\n```\n\nHere is a screenshot of the request in PyCharm, it unfortunately can't be dumped to JSON directly.\nhttps://i.sstatic.net/T6Gy1.png\n\nI'm starting to think that it has something to do with Uvicorn and how it runs the app, but I can't figure out why.\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nimport uvicorn\n\napp = FastAPI()\n\n@app.get(\"/\")\nasync def root():\n return {\"message\": \"Hello World\"}\n\nif __name__ == '__main__':\n uvicorn.run(app, host='0.0.0.0', port=8000)\n```\n\n```text\nimport httpx\nr = httpx.get('http://localhost:8000/')\nprint(r.elapsed)\n```\n\n```text\ncurl -w \"@curl-format.txt\" -o /dev/null -X 'GET' 'http://localhost:8000/'\n```\n\n```text\n% Total % Received % Xferd Average Speed Time Time Time Current\n Dload Upload Total Spent Left Speed\n100 32 100 32 0 0 941 0 --:--:-- --:--:-- --:--:-- 969\n time_namelookup: 0.006436s\n time_connect: 0.006747s\n time_appconnect: 0.000000s\n time_pretransfer: 0.006788s\n time_redirect: 0.000000s\n time_starttransfer: 0.034037s\n ----------\n time_total: 0.034093s\n```\n\n```text\ncurl -w \"@curl-format.txt\" -o /dev/null -X 'GET' \\\n 'http://localhost:8000/events' \\\n -H 'accept: */*' \\\n -H 'host: localhost:8000' \\\n -H 'accept-encoding: gzip, deflate' \\\n -H 'connection: keep-alive' \\\n -H 'user-agent: python-httpx/0.20.0'\n```\n\n```text\n0:00:02.069705\n```\n\n========================================\n\nComments:\n- I have no solution to offer, but have to tried using 127.0.0.1 instead of localhost? I once had a similar issues where it would take half a second or more for my windows machine to resolve the host name before it would make the actual request.\n- Well the python itself might be bottleneck. Could you try to debug the request on the client site? Could be problem with HTTP/1 vs HTTP/2\n- @thisisalsomypassword Oh god you are right. Switching to 127.0.0.1 literally solves it. I can not thank you enough, I already spent multiple hours on this. This really should not happen though.\n- I was kind of afraid to suggest it but it reminded me too much of my issue. I was making the request from javascript in the browser, though. It didn‘t bother to look into it any further then, so sorry I don‘t have a solution. But maybe it narrows down your search.\n- Oh you definitely solved my issue. That was exactly the problem.\n- Well, glad it helped.\n- Why not put that 127.0.0.1 as answer though you may also want to tag question as `windows`? @thisisalsomypassword. Easier to find solution as answer than comment, later.\n- Yes, you‘re right. Will do.\n- You're right. I added the Windows tag to the post.","metadata":{"transformedAt":"2026-08-18T18:32:29.119Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":6,"totalLines":141,"estimatedTokens":1220}}284{"id":"stack-72801333","source":"stackoverflow","questionId":72801333,"title":"How to pass URL as a path parameter to a FastAPI route?","tags":["python","url","fastapi","starlette","path-parameter"],"text":"Title: How to pass URL as a path parameter to a FastAPI route?\nTags: python, url, fastapi, starlette, path-parameter\nSource: Stack Overflow\n\nQuestion:\nI have created a simple API using FastAPI, and I am trying to pass a URL to a FastAPI route as an arbitrary `path` parameter.\n\n```\nfrom fastapi import FastAPI\napp = FastAPI()\n@app.post(\"/{path}\")\ndef pred_image(path:str):\n print(\"path\",path)\n return {'path':path}\n```\n\nWhen I test it, it doesn't work and throws an error. I am testing it this way:\n\n```\nhttp://127.0.0.1:8000/https://raw.githubusercontent.com/ultralytics/yolov5/master/data/images/zidane.jpg\n```\n\n========================================\n\nTop Answer:\n```\nfrom fastapi import FastAPI, Request\n\napp = FastAPI()\n@app.get(\"/proxy/{p:path}\")\ndef read_item(p: str, req: Request):\n query = req.url.query\n if query:\n p += '?' + query\n return p\n```\n\ntest url `http://127.0.0.1/proxy/http://www.google.com/p/q?a=100&b=200`\n\nimg req:Request\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI\napp = FastAPI()\n@app.post(\"/{path}\")\ndef pred_image(path:str):\n print(\"path\",path)\n return {'path':path}\n```\n\n```text\nhttp://127.0.0.1:8000/https://raw.githubusercontent.com/ultralytics/yolov5/master/data/images/zidane.jpg\n```\n\n```text\npath\n```\n\n```py\nfrom fastapi import FastAPI, Request\n\napp = FastAPI()\n\n\n@app.get('/{_:path}')\nasync def pred_image(request: Request):\n url = request.url.path[1:] if not request.url.query else request.url.path[1:] + \"?\" + request.url.query\n return {'url': url}\n```\n\n```py\n@app.get('/{full_path:path}')\nasync def pred_image(full_path: str, request: Request):\n url = full_path if not request.url.query else full_path + \"?\" + request.url.query\n return {'url': url}\n```\n\n```py\n@app.get('/{_:path}')\nasync def pred_image(request: Request):\n url = request.url._url.split('/', 3)[-1]\n return {'url': url}\n```\n\n```text\nhttp://127.0.0.1:8000/https://www.google.com/search?q=my+query\n```\n\n```text\nhttp://127.0.0.1:8000/https%3A%2F%2Fwww.google.com%2Fsearch%3Fq%3Dmy%2Bquery\n```\n\n```py\nimport requests\nfrom urllib.parse import quote \n\nbase_url = 'http://127.0.0.1:8000/'\npath_param = 'https://www.google.com/search?q=my+query'\nurl = base_url + quote(path_param, safe='')\nr = requests.get(url)\nprint(r.json())\n```\n\n```json\n{'url': 'https://www.google.com/search?q=my+query'}\n```\n\n```py\nfrom urllib.parse import unquote \n\n@app.get('/{path}')\nasync def pred_image(path: str):\n return {'url': unquote(unquote(path))}\n```\n\n```text\nhttp://127.0.0.1:8000/https%253A%252F%252Fwww.google.com%252Fsearch%253Fq%253Dmy%252Bquery\n```\n\n```py\nimport requests\nfrom urllib.parse import quote \n\nbase_url = 'http://127.0.0.1:8000/'\npath_param = 'https://www.google.com/search?q=my+query'\nurl = base_url + quote(quote(path_param, safe=''), safe='')\nr = requests.get(url)\nprint(r.json())\n```\n\n```py\n@app.get('/')\nasync def pred_image(url: str):\n return {'url': url}\n```\n\n```text\nhttp://127.0.0.1:8000/?url=https://www.google.com/search?q=my+query\n```\n\n```py\nimport requests\n\nbase_url = 'http://127.0.0.1:8000/'\nparams = {'url': 'https://www.google.com/search?q=my+query'}\nr = requests.get(base_url, params=params)\nprint(r.json())\n```\n\n```text\npath\n```\n\n```text\npath\n```\n\n```text\n/\n```\n\n```text\nsplit()\n```\n\n```text\n/\n```\n\n```text\n%\n```\n\n```text\nrequests\n```\n\n```text\nurllib.parse.quote()\n```\n\n```text\nquote()\n```\n\n```text\n/\n```\n\n```text\n/\n```\n\n```text\nsafe\n```\n\n```text\n''\n```\n\n```text\n/\n```\n\n```text\nrequests\n```\n\n```text\n<form>\n```\n\n```text\n<form>\n```\n\n```text\n<input>\n```\n\n```text\n<form>\n```\n\n```text\n<form>\n```\n\n```text\nencodeURIComponent()\n```\n\n```text\nencodeURI()\n```\n\n```text\nrequests\n```\n\n```text\n\"detail\": \"Not Found\"\n```\n\n```text\nrequest.url\n```\n\n```text\n%2F\n```\n\n```text\n/\n```\n\n```text\nrequests\n```\n\n```text\nrequests\n```\n\n```text\nrequests\n```\n\n```text\nquote()\n```\n\n```text\nrequests\n```\n\n```text\nPOST\n```\n\n```text\n@app.get()\n```\n\n```text\nGET\n```\n\n```text\nPOST\n```\n\n```text\n@app.post()\n```\n\n```text\n405 \"Method Not Allowed\"\n```\n\n```text\nasync def\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\ndef\n```\n\n```py\nfrom fastapi import FastAPI, Request\n\napp = FastAPI()\n@app.get(\"/proxy/{p:path}\")\ndef read_item(p: str, req: Request):\n query = req.url.query\n if query:\n p += '?' + query\n return p\n```\n\n```text\nhttp://127.0.0.1/proxy/http://www.google.com/p/q?a=100&b=200\n```\n\n========================================\n\nComments:\n- The path needs to be url encoded.\n- do i need to encode before passing or after passing\n- before... `http://127.0.0.1:8000/https%3A%2F%2Fraw.githubusercontent.co‌​m%2Fultralytics%2Fyo‌​lov5%2Fmaster%2Fdata‌​%2Fimages%2Fzidane.j‌​pg` would be the right url.\n- let say i am providing an API which require a user to pass a path. so the end user has to first encode it?\n- the client, whether that is and end user, a browser, javascript, does not matter.\n- Please consider adding some explanation to the source code explaining how it solves the problem. For reference, look at the accepted answer.","metadata":{"transformedAt":"2026-08-18T18:32:29.119Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":60,"totalLines":345,"estimatedTokens":1267}}285{"id":"stack-66054356","source":"stackoverflow","questionId":66054356,"title":"Multiple async unit tests fail, but running them one by one will pass","tags":["python","pytest","fastapi","python-3.9","pytest-asyncio"],"text":"Title: Multiple async unit tests fail, but running them one by one will pass\nTags: python, pytest, fastapi, python-3.9, pytest-asyncio\nSource: Stack Overflow\n\nQuestion:\nI have two unit tests, if I run them one by one, they pass. If I run them at class level, one pass and the other one fails at `response = await ac.post(` with the error message: `RuntimeError: Event loop is closed`\n\n```\n@pytest.mark.asyncio\nasync def test_successful_register_saves_expiry_to_seven_days(self):\n async with AsyncClient(app=app, base_url=\"http://127.0.0.1\") as ac:\n response = await ac.post(\n \"/register/\",\n headers={},\n json={\n \"device_id\": \"u1\",\n \"device_type\": DeviceType.IPHONE.value,\n },\n )\n query = device.select(whereclause=device.c.id == \"u1\")\n d = await db.fetch_one(query)\n assert d.expires_at == datetime.utcnow().replace(\n second=0, microsecond=0\n ) + timedelta(days=7)\n\n@pytest.mark.asyncio\nasync def test_successful_register_saves_device_type(self):\n async with AsyncClient(app=app, base_url=\"http://127.0.0.1\") as ac:\n response = await ac.post(\n \"/register/\",\n headers={},\n json={\n \"device_id\": \"u1\",\n \"device_type\": DeviceType.ANDROID.value,\n },\n )\n query = device.select(whereclause=device.c.id == \"u1\")\n d = await db.fetch_one(query)\n assert d.type == DeviceType.ANDROID.value\n```\n\nI have been trying for hours, what am I missing please?\n\n========================================\n\nCode:\n```text\n@pytest.mark.asyncio\nasync def test_successful_register_saves_expiry_to_seven_days(self):\n async with AsyncClient(app=app, base_url=\"http://127.0.0.1\") as ac:\n response = await ac.post(\n \"/register/\",\n headers={},\n json={\n \"device_id\": \"u1\",\n \"device_type\": DeviceType.IPHONE.value,\n },\n )\n query = device.select(whereclause=device.c.id == \"u1\")\n d = await db.fetch_one(query)\n assert d.expires_at == datetime.utcnow().replace(\n second=0, microsecond=0\n ) + timedelta(days=7)\n\n@pytest.mark.asyncio\nasync def test_successful_register_saves_device_type(self):\n async with AsyncClient(app=app, base_url=\"http://127.0.0.1\") as ac:\n response = await ac.post(\n \"/register/\",\n headers={},\n json={\n \"device_id\": \"u1\",\n \"device_type\": DeviceType.ANDROID.value,\n },\n )\n query = device.select(whereclause=device.c.id == \"u1\")\n d = await db.fetch_one(query)\n assert d.type == DeviceType.ANDROID.value\n```\n\n```text\nresponse = await ac.post(\n```\n\n```text\nRuntimeError: Event loop is closed\n```\n\n```text\n@pytest.fixture(scope=\"session\")\ndef event_loop(request):\n loop = asyncio.get_event_loop()\n yield loop\n loop.close()\n```\n\n```text\n@pytest.yield_fixture(scope=\"session\")\ndef event_loop(request):\n \"\"\"Create an instance of the default event loop for each test case.\"\"\"\n loop = asyncio.get_event_loop_policy().new_event_loop()\n yield loop\n loop.close()\n```\n\n```text\n0.19.0\n```\n\n```text\npytest-asyncio\n```\n\n```text\nstrict\n```\n\n```text\n@pytest.fixture\n```\n\n```text\nconftest.py\n```\n\n```text\n@pytest_asyncio.fixture\n```\n\n```text\n@pytest.yield_fixture\n```\n\n```text\n0.19.0\n```\n\n```text\nconftest.py\n```\n\n```text\ntests\n```\n\n========================================\n\nComments:\n- Please update your question to include a minimal, reproducible example (ideally, something we can copy to a local file and run `pytest` to reproduce the error). I put together a simple test with two async tests and it seems to run without a problem, leading me to wonder if there are other parts of your code that could be causing a problem.\n- I have uploaded an example github.com/houmie/async-unittests. The test you have provided doesn't use the stack I had tagged, hence you couldn't reproduce it.\n- Thanks for the clear answer. I was searching for an hour, only to miss the necessary file name `conftest.py`\n- You're welcome. Yeah, it's not straight forward.\n- You are a day saver :)\n- Is there supposed to be some kind of implied change to the test case where the loop passed back from the fixture is used?\n- To this day, it works. Thanks! Tested on `pytest==7.1.2 pytest-asyncio==0.18.3 uvicorn==0.17.6`- I'm testing a `fastapi` app with `fastapi==0.66.0`\n- the fixture comment is misleading, it isn't creating an instance of the event loop for each test case, it's creating the event loop just once (for the session) and using it across all tests\n- On Pytest 7.1.2 with pytest-asyncio 0.18.3: `PytestDeprecationWarning: @pytest.yield_fixture is deprecated.`\n- hey, thank you for your comment and for the solution. Can you advice the similiar solution for Django async tests?\n- You're welcome. I haven't worked with Django for a long time. Sorry.","metadata":{"transformedAt":"2026-08-18T18:32:29.119Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":15,"totalLines":159,"estimatedTokens":1192}}286{"id":"stack-64919868","source":"stackoverflow","questionId":64919868,"title":"FastAPI - module 'app.routers.test' has no attribute 'routes'","tags":["python","fastapi"],"text":"Title: FastAPI - module 'app.routers.test' has no attribute 'routes'\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to setup an app using FastAPI but keep getting this error which I can't make sense of. My `main.py` file is as follows:\n\n```\nfrom fastapi import FastAPI\nfrom app.routers import test\n\napp = FastAPI()\napp.include_router(test, prefix=\"/api/v1/test\")\n```\n\nAnd in my `routers/test.py` file I have:\n\n```\nfrom fastapi import APIRouter, File, UploadFile\nimport app.schemas.myschema as my_schema\n\nrouter = APIRouter()\nResponse = my_schema.Response\n\n@router.get(\"/\", response_model=Response)\ndef process(file: UploadFile = File(...)):\n # Do work\n```\n\nBut I keep getting the following error:\n\nFile\n\"/Users/Desktop/test-service/venv/lib/python3.8/site-packages/fastapi/routing.py\",\nline 566, in include_router\nfor route in router.routes: AttributeError: module 'app.routers.test' has no attribute 'routes'\npython-BaseException\n\nI cant make sense of this as I can see something similar being done in the sample app here.\n\n========================================\n\nTop Answer:\nNo, you can not directly access it from the `app`, because when you add an instance of APIRouter with `include_router`, FastAPI adds every router to the `app.routes`.\n\n```\nfor route in router.routes:\n if isinstance(route, APIRoute):\n self.add_api_route(\n ...\n )\n```\n\nIt does not add the route to the application instead it adds the routes, but since your router is an instance of APIRouter, you can reach the routes from that.\n\n```\nclass APIRouter(routing.Router):\n def __init__(\n self,\n routes: Optional[List[routing.BaseRoute]] = None,\n ...\n )\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nfrom app.routers import test\n\napp = FastAPI()\napp.include_router(test, prefix=\"/api/v1/test\")\n```\n\n```text\nfrom fastapi import APIRouter, File, UploadFile\nimport app.schemas.myschema as my_schema\n\nrouter = APIRouter()\nResponse = my_schema.Response\n\n\n@router.get(\"/\", response_model=Response)\ndef process(file: UploadFile = File(...)):\n # Do work\n```\n\n```text\nmain.py\n```\n\n```text\nrouters/test.py\n```\n\n```text\napp.include_router(test.router, prefix=\"/api/v1/test\")\n```\n\n```text\napp.include_router(test, prefix=\"/api/v1/test\")\n```\n\n```text\nfor route in router.routes:\n if isinstance(route, APIRoute):\n self.add_api_route(\n ...\n )\n```\n\n```py\nclass APIRouter(routing.Router):\n def __init__(\n self,\n routes: Optional[List[routing.BaseRoute]] = None,\n ...\n )\n```\n\n```text\napp\n```\n\n```text\ninclude_router\n```\n\n```text\napp.routes\n```\n\n```text\nfrom parentfolder.file import attribute\n```\n\n```text\nfrom routers.test import routes\n```\n\n```text\nroutes = APIRouter()\n```\n\n========================================\n\nComments:\n- Does `app.routers.test` have a `routes` attribute? What is `app.routers.test`? Is it a router? I don't have this stuff on my machine, so I can't take a look, but my guess is that `app.include_router` expects a different first argument than whatever `test` is. (this is the downside to dynamically typed languages)\n- it doesnt have a routes attribute but the example also doesnt have one. yes it is a router. the contents of test.py is given in question itself\n- I still don't see where you define what the `test` is that's being passed to `app.include_router`. If it's `test.py`, then it's a module, not a normal Python object. So if that's true, do you maybe want `app.include_router(test.router, prefix=\"/api/v1/test\")`? UPDATE: Ah, I missed this before. The error message is telling you that `app.routers.test` is a Python Module. I doubt that's what you want to pass into anything. Now I'm thinking more than ever that you want to pass in `test.router` rather than `test`.\n- totally true. my bad","metadata":{"transformedAt":"2026-08-18T18:32:29.119Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":14,"totalLines":151,"estimatedTokens":959}}287{"id":"stack-62386287","source":"stackoverflow","questionId":62386287,"title":"FastAPI equivalent of Flask's request.form, for agnostic forms","tags":["python","fastapi"],"text":"Title: FastAPI equivalent of Flask's request.form, for agnostic forms\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI try to migrate from Flask to FastAPI, and I was wondering if there is something similar to Flask's:\n\n```\npayload = request.form.to_dict(flat=False)\npayload = {key:payload[key][0] for key in payload}\n```\n\nfor FastAPI.\n\nUntil now I've found only some hacks, were you still had to implement one-by-one all the form's arguments to a function:\n\n```\nfrom pydantic import BaseModel\nclass FormData(BaseModel):\n alfa: str=Form(...)\n vita: str=Form(...)\nasync def Home(request: Request, form_data:FormData)\n```\n\nThis example is of course better in readability than the standard form handling:\n\n```\nasync def Home(username: str = Form(...), something_else: str = Form(...)):\n```\n\nBut still it's quite restricting, due to the necessary declaration of all form fields.\n\nIs there any other more agnostic & elegant approach?\n\n========================================\n\nCode:\n```text\npayload = request.form.to_dict(flat=False)\npayload = {key:payload[key][0] for key in payload}\n```\n\n```text\nfrom pydantic import BaseModel\nclass FormData(BaseModel):\n alfa: str=Form(...)\n vita: str=Form(...)\nasync def Home(request: Request, form_data:FormData)\n```\n\n```text\nasync def Home(username: str = Form(...), something_else: str = Form(...)):\n```\n\n```text\nfrom fastapi import FastAPI, Request\n\napp = FastAPI()\n\n@app.post(\"/example\")\nasync def example(request: Request):\n form_data = await request.form()\n return form_data\n```\n\n```text\nC:\\>curl -X POST \"http://localhost:8000/example\" -d \"hello=there&another=value\"\n{\"hello\":\"there\",\"another\":\"value\"}\n```\n\n========================================\n\nComments:\n- **Option 1** of this answer demonstrates how to use `request.form()` in FastAPI to retrieve both Form data and Files.\n- Why is this not the first solution to the form problem, even the form examples don't even work from the FastApi site. This really helped me a lot .\n- @clockwatcher If my HTML page has more tags and different names, Can I use this name to choose a specific name for this?","metadata":{"transformedAt":"2026-08-18T18:32:29.119Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":76,"estimatedTokens":529}}288{"id":"stack-67636088","source":"stackoverflow","questionId":67636088,"title":"How to access request object in router function using FastAPI?","tags":["python","fastapi"],"text":"Title: How to access request object in router function using FastAPI?\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am new to FastAPI framework, I want to print out the response. For example, in Django:\n\n```\n@api_view(['POST'])\ndef install_grandservice(req):\n print(req.body)\n```\n\nAnd in FastAPI:\n\n```\n@app.post('/install/grandservice')\nasync def login():\n //print out req\n```\n\nI tried to to like this\n\n```\n@app.post('/install/grandservice')\nasync def login(req):\n print(req.body)\n```\n\nBut I received this error: **127.0.0.1:52192 - \"POST /install/login HTTP/1.1\" 422 Unprocessable Entity**\n\nPlease help me :(\n\n========================================\n\nTop Answer:\nHere is an example that will print the content of the `Request` for **fastAPI**.\nIt will print the body of the request as a json (if it is json parsable) otherwise print the raw byte array.\n\n```\nasync def print_request(request):\n print(f'request header : {dict(request.headers.items())}' )\n print(f'request query params : {dict(request.query_params.items())}') \n try : \n print(f'request json : {await request.json()}')\n except Exception as err:\n # could not parse json\n print(f'request body : {await request.body()}')\n\n@app.post(\"/printREQUEST\")\nasync def create_file(request: Request):\n try:\n await print_request(request)\n return {\"status\": \"OK\"}\n except Exception as err:\n logging.error(f'could not print REQUEST: {err}')\n return {\"status\": \"ERR\"}\n```\n\n========================================\n\nCode:\n```text\n@api_view(['POST'])\ndef install_grandservice(req):\n print(req.body)\n```\n\n```text\n@app.post('/install/grandservice')\nasync def login():\n //print out req\n```\n\n```text\n@app.post('/install/grandservice')\nasync def login(req):\n print(req.body)\n```\n\n```text\nfrom fastapi import FastAPI, Request\n\napp = FastAPI()\n\n\n@app.post('/install/grandservice')\nasync def login(request: Request):\n print(request)\n return {\"foo\": \"bar\"}\n```\n\n```text\nRequest\n```\n\n```text\nasync def print_request(request):\n print(f'request header : {dict(request.headers.items())}' )\n print(f'request query params : {dict(request.query_params.items())}') \n try : \n print(f'request json : {await request.json()}')\n except Exception as err:\n # could not parse json\n print(f'request body : {await request.body()}')\n\n\n@app.post(\"/printREQUEST\")\nasync def create_file(request: Request):\n try:\n await print_request(request)\n return {\"status\": \"OK\"}\n except Exception as err:\n logging.error(f'could not print REQUEST: {err}')\n return {\"status\": \"ERR\"}\n```\n\n```text\nRequest\n```\n\n========================================\n\nComments:\n- defining the function with async will make the application run in a single thread","metadata":{"transformedAt":"2026-08-18T18:32:29.120Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":7,"totalLines":125,"estimatedTokens":690}}289{"id":"stack-65270624","source":"stackoverflow","questionId":65270624,"title":"How to connect to a sqlite3 db file and fetch contents in fastapi?","tags":["python","python-3.x","fastapi"],"text":"Title: How to connect to a sqlite3 db file and fetch contents in fastapi?\nTags: python, python-3.x, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have a sqlite.db file which has 5 columns and 10million rows. I have created a api using fastapi, now in one of the api methods I want to connect to that sqlite.db file and fetch content based on certain conditions (based on the columns present). I mostly will be using SELECT and WHERE.\n\nHow can I do it by also taking advantage of async requests. I have came across Tortoise ORM but I am not sure how to properly use it to fetch results.\n\n```\nfrom fastapi import FastAPI, UploadFile, File, Form\nfrom fastapi.middleware.cors import CORSMiddleware\n\nDATABASE_URL = \"sqlite:///test.db\"\n\n@app.post(\"/test\")\nasync def fetch_data(id: int):\n query = \"SELECT * FROM tablename WHERE ID={}\".format(str(id))\n\n # how can I fetch such query faster from 10 million records while taking advantage of async func\n return results\n```\n\n========================================\n\nTop Answer:\nAn approach to accessing data from a column in a query result set:\n\nYou can read a db result set into a Pandas dataframe. From there, you can use dataframe[“column name”] to access the column data which returns a listlike iterable of that column’s data.\nYou can use the dataframe’s built-in to_dict() method for dictionary data.\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI, UploadFile, File, Form\nfrom fastapi.middleware.cors import CORSMiddleware\n\nDATABASE_URL = \"sqlite:///test.db\"\n\n\n@app.post(\"/test\")\nasync def fetch_data(id: int):\n query = \"SELECT * FROM tablename WHERE ID={}\".format(str(id))\n\n # how can I fetch such query faster from 10 million records while taking advantage of async func\n return results\n```\n\n```py\npip install databases\n```\n\n```py\npip install databases[sqlite]\n```\n\n```py\nfrom fastapi import FastAPI, UploadFile, File, Form\nfrom fastapi.middleware.cors import CORSMiddleware\nfrom databases import Database\n\ndatabase = Database(\"sqlite:///test.db\")\n\n\n@app.on_event(\"startup\")\nasync def database_connect():\n await database.connect()\n\n\n@app.on_event(\"shutdown\")\nasync def database_disconnect():\n await database.disconnect()\n\n\n@app.post(\"/test\")\nasync def fetch_data(id: int):\n query = \"SELECT * FROM tablename WHERE ID={}\".format(str(id))\n results = await database.fetch_all(query=query)\n\n return results\n```\n\n```text\nasync\n```\n\n========================================\n\nComments:\n- Thank you so much for helping me. Will this be fast enough when querying 10 million data? (or) Do I have to do something else?\n- No, you don't have to do anything else. As long as it runs as a coroutine, it will return the data without waiting for the other one to return.\n- But having a coroutine will not make your query execution faster but more scalable. Imagine you are sending 3 requests at the same time and each one of them returns 10 million items. They will return them without waiting for each other. So if one request returns in 1 second. 3 requests will return in 1 second too. But it will not make the 1-second query faster.\n- Is there a way I can access the results as dictionary, Because I want to access the respective column as `results.column1` or `results.column2` . This will be much easier, but now I have to count the columns and use `results[0] (for column 0 )`etc.,\n- Are you getting a list of dictionaries and you wanna get just a dictionary instead?\n- no I meant, is there a way to access the results using column names?\n- No, AFAIK even ORM's can't do that\n- Just one small doubts, if I have a sql server located in this ip `26.1.180.78` and port `3306` and its a mysql can you please help me how to create a connection to it and then how can I execute a insert command and commit it?\n- Instead of localhost use `26.1.180.78` when you are connecting to it.\n- Do you mean like Database(26.1.180.78)? How can I pass username, password and port info\n- I am sorry to disturb you, because actually my server is password protected. I have to execute and commit the results?\n- Yes something like this `user:pass@26.1.180.78:3306/db`, should work.\n- I am not being able to connect using `mysql://test:pass@26.1.180.78:3306/db`","metadata":{"transformedAt":"2026-08-18T18:32:29.120Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":5,"totalLines":103,"estimatedTokens":1063}}290{"id":"stack-65971081","source":"stackoverflow","questionId":65971081,"title":"Streaming video from camera in FastAPI results in frozen image after first frame","tags":["python","opencv","flask","fastapi"],"text":"Title: Streaming video from camera in FastAPI results in frozen image after first frame\nTags: python, opencv, flask, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to stream video from a camera using FastAPI, similar to an example I found for Flask. In Flask, the example works correctly, and the video is streamed without any issues. However, when I try to replicate the same functionality in FastAPI, I encounter a problem where the video stream freezes after the first frame.\n\nI have followed the example provided in this Flask code https://www.pyimagesearch.com/2019/09/02/opencv-stream-video-to-web-browser-html-page/ but when I adapt it to FastAPI, the video only displays the first frame and then remains frozen. I suspect there might be a difference in how FastAPI handles streaming responses compared to Flask.\n\nExample in Flask (Works normally):\n\n```\ndef generate():\n # grab global references to the output frame and lock variables\n global outputFrame, lock\n # loop over frames from the output stream\n while True:\n # wait until the lock is acquired\n with lock:\n # check if the output frame is available, otherwise skip\n # the iteration of the loop\n if outputFrame is None:\n continue\n # encode the frame in JPEG format\n (flag, encodedImage) = cv2.imencode(\".jpg\", outputFrame)\n # ensure the frame was successfully encoded\n if not flag:\n continue\n # yield the output frame in the byte format\n yield (b'--frame\\r\\n' b'Content-Type: image/jpeg\\r\\n\\r\\n' +\n bytearray(encodedImage) + b'\\r\\n')\n\n@app.route(\"/\")\ndef video_feed():\n # return the response generated along with the specific media\n # type (mime type)\n return Response(generate(),\n mimetype=\"multipart/x-mixed-replace; boundary=frame\")\n```\n\nHere is my FastAPI code:\n\n```\ndef generate():\n # grab global references to the output frame and lock variables\n global outputFrame, lock\n # loop over frames from the output stream\n while True:\n # wait until the lock is acquired\n with lock:\n # check if the output frame is available, otherwise skip\n # the iteration of the loop\n if outputFrame is None:\n continue\n # encode the frame in JPEG format\n (flag, encodedImage) = cv2.imencode(\".jpg\", outputFrame)\n # ensure the frame was successfully encoded\n if not flag:\n continue\n # yield the output frame in the byte format\n yield b''+bytearray(encodedImage)\n\n@app.get(\"/\")\ndef video_feed():\n # return the response generated along with the specific media\n # type (mime type)\n # return StreamingResponse(generate())\n return StreamingResponse(generate(), media_type=\"image/jpeg\")\n```\n\nI have also reviewed the question Video Streaming App using FastAPI and OpenCV, but I couldn't find a solution that addresses my specific issue.\n\nCould someone please help me understand what modifications I need to make in my FastAPI code to ensure that the video stream is continuously updated and not frozen after the first frame? I would appreciate any guidance or suggestions. Thank you!\n\n========================================\n\nTop Answer:\n### Range request (valid for video/PDF/etc...)\n\n```\nimport os\nfrom typing import BinaryIO\n\nfrom fastapi import HTTPException, Request, status\nfrom fastapi.responses import StreamingResponse\n\ndef send_bytes_range_requests(\n file_obj: BinaryIO, start: int, end: int, chunk_size: int = 10_000\n):\n \"\"\"Send a file in chunks using Range Requests specification RFC7233\n\n `start` and `end` parameters are inclusive due to specification\n \"\"\"\n with file_obj as f:\n f.seek(start)\n while (pos := f.tell()) tuple[int, int]:\n def _invalid_range():\n return HTTPException(\n status.HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE,\n detail=f\"Invalid request range (Range:{range_header!r})\",\n )\n\n try:\n h = range_header.replace(\"bytes=\", \"\").split(\"-\")\n start = int(h[0]) if h[0] != \"\" else 0\n end = int(h[1]) if h[1] != \"\" else file_size - 1\n except ValueError:\n raise _invalid_range()\n\n if start > end or start file_size - 1:\n raise _invalid_range()\n return start, end\n\ndef range_requests_response(\n request: Request, file_path: str, content_type: str\n):\n \"\"\"Returns StreamingResponse using Range Requests of a given file\"\"\"\n\n file_size = os.stat(file_path).st_size\n range_header = request.headers.get(\"range\")\n\n headers = {\n \"content-type\": content_type,\n \"accept-ranges\": \"bytes\",\n \"content-encoding\": \"identity\",\n \"content-length\": str(file_size),\n \"access-control-expose-headers\": (\n \"content-type, accept-ranges, content-length, \"\n \"content-range, content-encoding\"\n ),\n }\n start = 0\n end = file_size - 1\n status_code = status.HTTP_200_OK\n\n if range_header is not None:\n start, end = _get_range_header(range_header, file_size)\n size = end - start + 1\n headers[\"content-length\"] = str(size)\n headers[\"content-range\"] = f\"bytes {start}-{end}/{file_size}\"\n status_code = status.HTTP_206_PARTIAL_CONTENT\n\n return StreamingResponse(\n send_bytes_range_requests(open(file_path, mode=\"rb\"), start, end),\n headers=headers,\n status_code=status_code,\n )\n```\n\n### Usage\n\n```\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/video\")\ndef get_video(request: Request):\n return range_requests_response(\n request, file_path=\"path_to_my_video.mp4\", content_type=\"video/mp4\"\n )\n```\n\n========================================\n\nCode:\n```text\ndef generate():\n # grab global references to the output frame and lock variables\n global outputFrame, lock\n # loop over frames from the output stream\n while True:\n # wait until the lock is acquired\n with lock:\n # check if the output frame is available, otherwise skip\n # the iteration of the loop\n if outputFrame is None:\n continue\n # encode the frame in JPEG format\n (flag, encodedImage) = cv2.imencode(\".jpg\", outputFrame)\n # ensure the frame was successfully encoded\n if not flag:\n continue\n # yield the output frame in the byte format\n yield (b'--frame\\r\\n' b'Content-Type: image/jpeg\\r\\n\\r\\n' +\n bytearray(encodedImage) + b'\\r\\n')\n\n@app.route(\"/\")\ndef video_feed():\n # return the response generated along with the specific media\n # type (mime type)\n return Response(generate(),\n mimetype=\"multipart/x-mixed-replace; boundary=frame\")\n```\n\n```text\ndef generate():\n # grab global references to the output frame and lock variables\n global outputFrame, lock\n # loop over frames from the output stream\n while True:\n # wait until the lock is acquired\n with lock:\n # check if the output frame is available, otherwise skip\n # the iteration of the loop\n if outputFrame is None:\n continue\n # encode the frame in JPEG format\n (flag, encodedImage) = cv2.imencode(\".jpg\", outputFrame)\n # ensure the frame was successfully encoded\n if not flag:\n continue\n # yield the output frame in the byte format\n yield b''+bytearray(encodedImage)\n\n\n@app.get(\"/\")\ndef video_feed():\n # return the response generated along with the specific media\n # type (mime type)\n # return StreamingResponse(generate())\n return StreamingResponse(generate(), media_type=\"image/jpeg\")\n```\n\n```text\n@app.get(\"/\")\ndef video_feed():\n # return the response generated along with the specific media\n # type (mime type)\n # return StreamingResponse(generate())\n return StreamingResponse(generate(), media_type=\"multipart/x-mixed-replace;boundary=frame\")\n```\n\n```text\nyield (b'--frame\\r\\n' b'Content-Type: image/jpeg\\r\\n\\r\\n' +\n bytearray(encodedImage) + b'\\r\\n')\n```\n\n```py\nimport os\nfrom typing import BinaryIO\n\nfrom fastapi import HTTPException, Request, status\nfrom fastapi.responses import StreamingResponse\n\n\ndef send_bytes_range_requests(\n file_obj: BinaryIO, start: int, end: int, chunk_size: int = 10_000\n):\n \"\"\"Send a file in chunks using Range Requests specification RFC7233\n\n `start` and `end` parameters are inclusive due to specification\n \"\"\"\n with file_obj as f:\n f.seek(start)\n while (pos := f.tell()) <= end:\n read_size = min(chunk_size, end + 1 - pos)\n yield f.read(read_size)\n\n\ndef _get_range_header(range_header: str, file_size: int) -> tuple[int, int]:\n def _invalid_range():\n return HTTPException(\n status.HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE,\n detail=f\"Invalid request range (Range:{range_header!r})\",\n )\n\n try:\n h = range_header.replace(\"bytes=\", \"\").split(\"-\")\n start = int(h[0]) if h[0] != \"\" else 0\n end = int(h[1]) if h[1] != \"\" else file_size - 1\n except ValueError:\n raise _invalid_range()\n\n if start > end or start < 0 or end > file_size - 1:\n raise _invalid_range()\n return start, end\n\n\ndef range_requests_response(\n request: Request, file_path: str, content_type: str\n):\n \"\"\"Returns StreamingResponse using Range Requests of a given file\"\"\"\n\n file_size = os.stat(file_path).st_size\n range_header = request.headers.get(\"range\")\n\n headers = {\n \"content-type\": content_type,\n \"accept-ranges\": \"bytes\",\n \"content-encoding\": \"identity\",\n \"content-length\": str(file_size),\n \"access-control-expose-headers\": (\n \"content-type, accept-ranges, content-length, \"\n \"content-range, content-encoding\"\n ),\n }\n start = 0\n end = file_size - 1\n status_code = status.HTTP_200_OK\n\n if range_header is not None:\n start, end = _get_range_header(range_header, file_size)\n size = end - start + 1\n headers[\"content-length\"] = str(size)\n headers[\"content-range\"] = f\"bytes {start}-{end}/{file_size}\"\n status_code = status.HTTP_206_PARTIAL_CONTENT\n\n return StreamingResponse(\n send_bytes_range_requests(open(file_path, mode=\"rb\"), start, end),\n headers=headers,\n status_code=status_code,\n )\n```\n\n```py\nfrom fastapi import FastAPI\n\n\napp = FastAPI()\n\n\n@app.get(\"/video\")\ndef get_video(request: Request):\n return range_requests_response(\n request, file_path=\"path_to_my_video.mp4\", content_type=\"video/mp4\"\n )\n```\n\n```text\ndef get_video_range_response(request: Request, file_path: str, content_type: str = \"video/mp4\")\n file_size = os.stat(file_path).st_size\n h = request.headers.get(\"range\").replace(\"bytes=\", \"\").split(\"-\")\n start = int(h[0]) if h[0] != \"\" else 0\n\n maxSize = 200000\n end = start + maxSize # this is the expected end\n if end >= file_size #if end > file_size then obviously end = file_size - 1\n end = file_size - 1\n size = end - start\n headers = {\"content-type\": content_type,\n \"accept-ranges\": \"bytes\",\n \"content-encoding\": \"identity\",\n \"content-length\": str(size),\n \"content-range\": f\" bytes {start}-{end}/{file_size}\",\n }\n\n file_obj = open(file_path, mode=\"rb\")\n file_obj.seek(start)\n data = file_obj.read(size)\n file_obj.close()\n status_code = status.HTTP_206_PARTIAL_CONTENT\n\n return Response(content=data,\n status_code=status_code,\n headers=headers,\n media_type=content_type\n )\n```\n\n```text\n@app.get('/Video')\ndef video_endpoint(req: Request):\n video_path = r\"C:\\WOI\\pict\\videos\\Modi.mp4\"\n return get_video_range_response(req, file_path = video_path, content_type = \"video/mp4\")\n```\n\n```text\n<video controls class=\"w-100\">\n <source src=\"/Video\" type=\"video/mp4\"> \n</video>\n```\n\n========================================\n\nComments:\n- this helped. thanks a lot. BTW, this blocks all other API calls. I cant get responses from any other APIs until the stream is complete. Any idea how I can fix that?\n- @Abarajithan I don't know what's going on. However, I put an example I made in fast api github.com/mpimentel04/rtsp_fastapi Hope this helps.\n- You may want to have a look at this answer as well, whcih provides an additional approach based on the `WebSocket` protocol.\n- @Abarajithan used `def` instead of `async def` to avoid blocking the server !\n- HTML Your browser does not support the video tag.","metadata":{"transformedAt":"2026-08-18T18:32:29.120Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":9,"totalLines":381,"estimatedTokens":3042}}291{"id":"stack-71467630","source":"stackoverflow","questionId":71467630,"title":"FastAPI issues with MongoDB - TypeError: 'ObjectId' object is not iterable","tags":["python","mongodb","pymongo","fastapi"],"text":"Title: FastAPI issues with MongoDB - TypeError: 'ObjectId' object is not iterable\nTags: python, mongodb, pymongo, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am having some issues inserting into MongoDB via FastAPI.\n\nThe below code works as expected. Notice how the `response` variable has not been used in `response_to_mongo()`.\n\nThe `model` is an sklearn ElasticNet model.\n\n```\napp = FastAPI()\n\ndef response_to_mongo(r: dict):\n client = pymongo.MongoClient(\"mongodb://mongo:27017\")\n db = client[\"models\"]\n model_collection = db[\"example-model\"]\n model_collection.insert_one(r)\n\n@app.post(\"/predict\")\nasync def predict_model(features: List[float]):\n\n prediction = model.predict(\n pd.DataFrame(\n [features],\n columns=model.feature_names_in_,\n )\n )\n\n response = {\"predictions\": prediction.tolist()}\n response_to_mongo(\n {\"predictions\": prediction.tolist()},\n )\n return response\n```\n\nHowever when I write `predict_model()` like this and pass the `response` variable to `response_to_mongo()`:\n\n```\n@app.post(\"/predict\")\nasync def predict_model(features: List[float]):\n\n prediction = model.predict(\n pd.DataFrame(\n [features],\n columns=model.feature_names_in_,\n )\n )\n\n response = {\"predictions\": prediction.tolist()}\n response_to_mongo(\n response,\n )\n return response\n```\n\nI get an error stating that:\n\n```\nTypeError: 'ObjectId' object is not iterable\n```\n\nFrom my reading, it seems that this is due to BSON/JSON issues between FastAPI and Mongo. However, why does it work in the first case when I do not use a variable? Is this due to the asynchronous nature of FastAPI?\n\n========================================\n\nTop Answer:\nSolution 4, from Chris's excellent answer, can also be accomplished with function output type hints. Thus:\n\n```\nfrom pydantic import BaseModel\n\nclass ResponseBody(BaseModel):\n name: str\n age: int\n\n@app.get('/')\ndef example() -> ResponseBody:\n # you'd need to await this if you were using Motor (the Async MongoDB Driver)\n return db.my_collection.find_one(...)\n```\n\n========================================\n\nCode:\n```py\napp = FastAPI()\n\n\ndef response_to_mongo(r: dict):\n client = pymongo.MongoClient(\"mongodb://mongo:27017\")\n db = client[\"models\"]\n model_collection = db[\"example-model\"]\n model_collection.insert_one(r)\n\n\n@app.post(\"/predict\")\nasync def predict_model(features: List[float]):\n\n prediction = model.predict(\n pd.DataFrame(\n [features],\n columns=model.feature_names_in_,\n )\n )\n\n response = {\"predictions\": prediction.tolist()}\n response_to_mongo(\n {\"predictions\": prediction.tolist()},\n )\n return response\n```\n\n```py\n@app.post(\"/predict\")\nasync def predict_model(features: List[float]):\n\n prediction = model.predict(\n pd.DataFrame(\n [features],\n columns=model.feature_names_in_,\n )\n )\n\n response = {\"predictions\": prediction.tolist()}\n response_to_mongo(\n response,\n )\n return response\n```\n\n```text\nTypeError: 'ObjectId' object is not iterable\n```\n\n```text\nresponse\n```\n\n```text\nresponse_to_mongo()\n```\n\n```text\nmodel\n```\n\n```text\npredict_model()\n```\n\n```text\nresponse\n```\n\n```text\nresponse_to_mongo()\n```\n\n```py\n# place these at the top of your .py file\nimport pydantic\nfrom bson import ObjectId\npydantic.json.ENCODERS_BY_TYPE[ObjectId]=str\n\nreturn response # as usual\n```\n\n```py\nfrom bson import json_util\nimport json\n\nresponse = json.loads(json_util.dumps(response))\nreturn response\n```\n\n```py\nimport json\nfrom bson import ObjectId\n\nclass JSONEncoder(json.JSONEncoder):\n def default(self, o):\n if isinstance(o, ObjectId):\n return str(o)\n return json.JSONEncoder.default(self, o)\n\n\nresponse = JSONEncoder().encode(response)\nreturn response\n```\n\n```py\nfrom pydantic import BaseModel\n\nclass ResponseBody(BaseModel):\n name: str\n age: int\n\n\n@app.get('/', response_model=ResponseBody)\ndef main():\n # response sample\n response = {'_id': ObjectId('53ad61aa06998f07cee687c3'), 'name': 'John', 'age': '25'}\n return response\n```\n\n```py\nresponse.pop('_id', None)\nreturn response\n```\n\n```text\n\"_id\"\n```\n\n```text\n\"_id\"\n```\n\n```text\n\"_id\"\n```\n\n```text\ninsert_one()\n```\n\n```text\ninsert_one()\n```\n\n```text\nObjectId\n```\n\n```text\nObjectId\n```\n\n```text\njsonable_encoder\n```\n\n```text\nstr\n```\n\n```text\nJSONResponse\n```\n\n```text\njson\n```\n\n```text\nObjectId\n```\n\n```text\nstr\n```\n\n```text\nresponse\n```\n\n```text\nBSON\n```\n\n```text\nJSON\n```\n\n```text\ndict\n```\n\n```text\nJSONEncoder\n```\n\n```text\nObjectId\n```\n\n```text\nstr\n```\n\n```text\n_id\n```\n\n```text\nresponse_model\n```\n\n```text\n\"_id\"\n```\n\n```text\nresponse\n```\n\n```text\ndict\n```\n\n```py\nfrom pydantic import BaseModel\n\n\nclass ResponseBody(BaseModel):\n name: str\n age: int\n\n\n@app.get('/')\ndef example() -> ResponseBody:\n # you'd need to await this if you were using Motor (the Async MongoDB Driver)\n return db.my_collection.find_one(...)\n```\n\n```text\nValueError: [TypeError(\"'ObjectId' object is not iterable\"), TypeError('vars() argument must have __dict__ attribute')]\n```\n\n```text\nfrom typing import Any, Callable\nfrom typing_extensions import Annotated\nfrom bson import ObjectId as _ObjectId\nfrom pydantic_core import core_schema\nfrom pydantic.functional_serializers import PlainSerializer\n\nclass _ObjectIdPydanticAnnotation:\n # Based on https://docs.pydantic.dev/latest/usage/types/custom/#handling-third-party-types.\n\n @classmethod\n def __get_pydantic_core_schema__(\n # Generate a Pydantic core schema for the custom `_ObjectId` type.\n # This method is used to define how the `_ObjectId` type should be validated\n # and serialized when used with Pydantic models.\n # Args:\n # cls: The class on which this method is defined.\n # _source_type (Any): The source type for schema generation.\n # _handler (Callable[[Any], core_schema.CoreSchema]): A handler function\n # for generating core schemas.\n # Returns:\n # core_schema.CoreSchema: A Pydantic core schema that validates and\n # serializes the `_ObjectId` type.\n # The schema performs the following:\n # 1. Checks if the input is an instance of `_ObjectId`.\n # 2. If not, validates the input by attempting to create an `_ObjectId`\n # instance from a string.\n # 3. Serializes the `_ObjectId` instance to a string representation.\n \n cls,\n _source_type: Any,\n _handler: Callable[[Any], core_schema.CoreSchema],\n ) -> core_schema.CoreSchema:\n def validate_from_str(input_value: str) -> _ObjectId:\n return _ObjectId(input_value)\n\n return core_schema.union_schema(\n [\n # check if it's an instance first before doing any further work\n core_schema.is_instance_schema(_ObjectId),\n core_schema.no_info_plain_validator_function(validate_from_str),\n ],\n serialization=core_schema.to_string_ser_schema(),\n )\n\ndef decode_object_id(id: _ObjectId):\n \"\"\"\n Converts an ObjectId instance to its string representation.\n\n Args:\n id (_ObjectId): The ObjectId instance to be converted.\n\n Returns:\n str: The string representation of the given ObjectId.\n \"\"\"\n return str(id)\n\nObjectId = Annotated[\n _ObjectId, _ObjectIdPydanticAnnotation,\n PlainSerializer(decode_object_id, return_type=str)\n]\n```\n\n========================================\n\nComments:\n- While it seems like a stretch, does `ObjectId` gets populated inside the response object when sent to `insert_one`? If that is the case, your first example ends up with it being inserted in a throw away dict, while in the second example it gets inserted into a dict you're still referencing.\n- @MatsLindh I wouldn't think thats the case because the `response` object is not being changed in-place\n- Sounds like that's exactly what's happening based on the answer below :-)\n- Happy to be proven wrong! Thanks a lot for your answer :D","metadata":{"transformedAt":"2026-08-18T18:32:29.120Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":42,"totalLines":401,"estimatedTokens":2001}}292{"id":"stack-73128975","source":"stackoverflow","questionId":73128975,"title":"Pydantic created at and updated at fields","tags":["python","database","postgresql","fastapi","pydantic"],"text":"Title: Pydantic created at and updated at fields\nTags: python, database, postgresql, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI'm new to using Pydantic and I'm using it to set up the models for FastAPI to integrate with my postgres database. I want to make a model that has an updated_at and created_at field which store the last datetime the model was updated and the datetime the model was created. I figured created_at could be something like this:\n\n```\ncreated_at: datetime = datetime.now()\n```\n\nHow would I do an updated_at so it updates the datetime automatically every time the model is updated?\n\n========================================\n\nTop Answer:\nThe accepted answer has some depracated syntaxes.\n\nI found the following solution compatible with PyDantic V2.\n\n```\n# Standard library imports\nfrom datetime import datetime\n\n# Third party imports\nfrom pydantic import Field, model_validator, ConfigDict\n\nNOW_FACTORY = datetime.now\n\nclass CreatedUpdatedAt:\n \"\"\"Created and updated at mixin that automatically updates updated_at field.\"\"\"\n\n created_at: datetime = Field(default_factory=NOW_FACTORY)\n updated_at: datetime = Field(default_factory=NOW_FACTORY)\n\n model_config = ConfigDict(\n validate_assignment=True,\n )\n\n @model_validator(mode=\"after\")\n @classmethod\n def update_updated_at(cls, obj: \"CreatedUpdatedAt\") -> \"CreatedUpdatedAt\":\n \"\"\"Update updated_at field.\"\"\"\n # must disable validation to avoid infinite loop\n obj.model_config[\"validate_assignment\"] = False\n\n # update updated_at field\n obj.updated_at = NOW_FACTORY()\n\n # enable validation again\n obj.model_config[\"validate_assignment\"] = True\n return obj\n```\n\nThen you should be able to use this mixin to inherit your models that will automatically update the updated_at field on a value assignment.\n\n```\nclass Foo(CreatedUpdatedAt, BaseModel):\n \"\"\"Example model.\"\"\"\n\n bar: str\n\nfoo = Foo(bar=\"foobar\")\n\nprint(foo.updated_at)\n\ntime.sleep(5)\n\nprint(foo.updated_at) # should have the latest timestamp\n```\n\n========================================\n\nCode:\n```text\ncreated_at: datetime = datetime.now()\n```\n\n```text\nfrom datetime import datetime\nfrom time import sleep\n\nfrom pydantic import BaseModel,root_validator\n\n\nclass Foo(BaseModel):\n data: str = \"Some data\"\n created_at: datetime = datetime.now()\n updated_at: datetime = datetime.now()\n\n class Config:\n validate_assignment = True\n\n @root_validator\n def number_validator(cls, values):\n values[\"updated_at\"] = datetime.now()\n return values\n\n\nif __name__ == '__main__':\n bar = Foo()\n print(bar.dict())\n sleep(5)\n bar.data = \"New data\"\n print(bar.dict())\n```\n\n```text\n{\n 'data': 'Some data',\n 'created_at': datetime.datetime(2022, 7, 31, 10, 41, 13, 176243),\n 'updated_at': datetime.datetime(2022, 7, 31, 10, 41, 13, 179253)\n}\n\n{\n 'data': 'New data',\n 'created_at': datetime.datetime(2022, 7, 31, 10, 41, 13, 176243),\n 'updated_at': datetime.datetime(2022, 7, 31, 10, 41, 18, 184983)\n}\n```\n\n```text\n@root_validator\n def number_validator(cls, values):\n if values[\"updated_at\"]:\n values[\"updated_at\"] = datetime.now()\n else:\n values[\"updated_at\"] = values[\"created_at\"]\n return values\n```\n\n```text\n{\n 'data': 'Some data',\n 'created_at': datetime.datetime(2022, 7, 31, 10, 54, 33, 715379), \n 'updated_at': datetime.datetime(2022, 7, 31, 10, 54, 33, 715379)\n}\n\n{\n 'data': 'New data',\n 'created_at': datetime.datetime(2022, 7, 31, 10, 54, 33, 715379),\n 'updated_at': datetime.datetime(2022, 7, 31, 10, 54, 38, 728778)\n}\n```\n\n```text\nupdated_at\n```\n\n```text\nupdated_at: Optional[datetime] = None\n```\n\n```py\n# Standard library imports\nfrom datetime import datetime\n\n# Third party imports\nfrom pydantic import Field, model_validator, ConfigDict\n\nNOW_FACTORY = datetime.now\n\n\nclass CreatedUpdatedAt:\n \"\"\"Created and updated at mixin that automatically updates updated_at field.\"\"\"\n\n created_at: datetime = Field(default_factory=NOW_FACTORY)\n updated_at: datetime = Field(default_factory=NOW_FACTORY)\n\n model_config = ConfigDict(\n validate_assignment=True,\n )\n\n @model_validator(mode=\"after\")\n @classmethod\n def update_updated_at(cls, obj: \"CreatedUpdatedAt\") -> \"CreatedUpdatedAt\":\n \"\"\"Update updated_at field.\"\"\"\n # must disable validation to avoid infinite loop\n obj.model_config[\"validate_assignment\"] = False\n\n # update updated_at field\n obj.updated_at = NOW_FACTORY()\n\n # enable validation again\n obj.model_config[\"validate_assignment\"] = True\n return obj\n```\n\n```py\nclass Foo(CreatedUpdatedAt, BaseModel):\n \"\"\"Example model.\"\"\"\n\n bar: str\n\nfoo = Foo(bar=\"foobar\")\n\nprint(foo.updated_at)\n\ntime.sleep(5)\n\nprint(foo.updated_at) # should have the latest timestamp\n```\n\n```py\nfrom datetime import datetime\nfrom time import sleep\n\nfrom pydantic import BaseModel,root_validator\n\n\nclass Foo(BaseModel):\n data: str = \"Some data\"\n created_at: datetime = datetime.now()\n updated_at: datetime = datetime.now()\n\n class Config:\n validate_assignment = True\n\n @root_validator\n def number_validator(cls, values):\n values[\"updated_at\"] = datetime.now()\n return values\n\n\nif __name__ == '__main__':\n bar = Foo()\n print(bar.dict())\n sleep(5)\n bar.data = \"New data\"\n print(bar.dict()) \n bar = Foo()\n print(bar.dict())\n sleep(5)\n bar.data = \"New data\"\n print(bar.dict())\n```\n\n```text\n{'data': 'Some data', 'created_at': datetime.datetime(2024, 4, 18, 10, 55, 8, 728593), 'updated_at': datetime.datetime(2024, 4, 18, 10, 55, 8, 729567)}\n{'data': 'New data', 'created_at': datetime.datetime(2024, 4, 18, 10, 55, 8, 728593), 'updated_at': datetime.datetime(2024, 4, 18, 10, 55, 13, 734877)}\n{'data': 'Some data', 'created_at': datetime.datetime(2024, 4, 18, 10, 55, 8, 728593), 'updated_at': datetime.datetime(2024, 4, 18, 10, 55, 13, 734985)}\n{'data': 'New data', 'created_at': datetime.datetime(2024, 4, 18, 10, 55, 8, 728593), 'updated_at': datetime.datetime(2024, 4, 18, 10, 55, 18, 740454)}\n```\n\n```py\nclass Foo(BaseModel):\n data: str = \"Some data\"\n created_at: datetime = None\n updated_at: datetime = None\n\n class Config:\n validate_assignment = True\n \n @root_validator\n def number_validator(cls, values):\n dt = datetime.now()\n if values[\"created_at\"] is None:\n values[\"created_at\"] = dt\n values[\"updated_at\"] = dt\n return values\n```\n\n```text\ncreated_at\n```\n\n```text\ndatetime.now()\n```\n\n========================================\n\nComments:\n- In your model set updated_at to None using optional then go where you wrote you update logic(your update route) and set update_at to datetime.now when the user request a update and it success.\n- How are you integrating with your Postgres database? This is probably better handled on the database access layer than on the Pydantic layer.\n- @MatsLindh Could you elaborate a bit more on this or some documentation?\n- @bballboy8 For anyone to be able to say how you do that or some documentation, they'll need to know *what you use to talk to your postgres database*. Are you using SQLAlchemy? psychopg2 or asyncpg directly?\n- `Parameter 'skip_on_failure' unfilled Pydantic V1 style`@root_validator` validators are deprecated. You should migrate to Pydantic V2 style `@model_validator` validators, see the migration guide for more details `\n- Defining `created_at` with this default value will create all instances of `Foo` with the same value. You should rather use a `default_factory` to define the default value: stackoverflow.com/questions/71512035/…","metadata":{"transformedAt":"2026-08-18T18:32:29.120Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":14,"totalLines":279,"estimatedTokens":1908}}293{"id":"stack-70965148","source":"stackoverflow","questionId":70965148,"title":"FASTAPI: what is`(..)` in the Body(...) while reading from a post request?","tags":["python","json","python-3.x","fastapi"],"text":"Title: FASTAPI: what is`(..)` in the Body(...) while reading from a post request?\nTags: python, json, python-3.x, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to read body from my POST request using FastAPI.\nHowever i am not able to understand what `(...)` argument for the Body function\n\nHere is my code :\n\n```\n@app.post('/createPosts')\ndef create_post(payload: dict = Body(...)):\n print(payload)\n return {'message': 'succesfully created post'}\n```\n\n========================================\n\nTop Answer:\n`...` (Ellipsis) was the way of declaring a required parameter in FastAPI.\n\nHowever, from 0.78.0, you can just omit the default value to do that.\n\nSee release note and documentation for details.\n\n========================================\n\nCode:\n```text\n@app.post('/createPosts')\ndef create_post(payload: dict = Body(...)):\n print(payload)\n return {'message': 'succesfully created post'}\n```\n\n```text\n(...)\n```\n\n```text\n...\n```\n\n========================================\n\nComments:\n- It's the python built-in constant `Ellipsis`. I'm surprised that I can't find a duplicate for this question, maybe someone else can.\n- Even i couldn't find a duplicate :(, okay its a built-in constant but what is the use of it? it throws error if i omit it\n- I think this might be the aforementioned duplicate, and this answer discusses FastAPI specifically\n- even though it explain `what` is Ellipsis but it doesnt say `why`? Also it doesnt even mention the context in using with FASTAPI, post request\n- This should be marked the correct answer. The other one from Srdan is technically correct, because Ellipsis is a builtin python literal docs.python.org/dev/library/constants.html#Ellipsis, but its interpretation is entirely up to any function that accepts its as a parameter (a parameter with its own unique type). Srdan's answer references an SO answer that describes some uses. But marukaz's answer here describes and links the *FastAPI use*.","metadata":{"transformedAt":"2026-08-18T18:32:29.120Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":3,"totalLines":52,"estimatedTokens":488}}294{"id":"stack-74010813","source":"stackoverflow","questionId":74010813,"title":"FastAPI - How can I modify request from inside dependency?","tags":["python","fastapi","starlette"],"text":"Title: FastAPI - How can I modify request from inside dependency?\nTags: python, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nHow can I modify request from inside a dependency? Basically I would like to add some information (`test_value`) to the request and later be able to get it from the view function (in my case `root()` function).\n\nBelow is a simple example:\n\n```\nfrom fastapi import FastAPI, Depends, Request\n\napp = FastAPI()\n\ndef test(request: Request):\n request['test_value'] = 'test value'\n\n@app.get(\"/\", dependencies=[Depends(test)])\nasync def root(request: Request):\n print(request.test_value)\n return {\"test\": \"test root path.\"}\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI, Depends, Request\n\napp = FastAPI()\n\ndef test(request: Request):\n request['test_value'] = 'test value'\n\n@app.get(\"/\", dependencies=[Depends(test)])\nasync def root(request: Request):\n print(request.test_value)\n return {\"test\": \"test root path.\"}\n```\n\n```text\ntest_value\n```\n\n```text\nroot()\n```\n\n```py\nfrom fastapi import FastAPI, Depends, Request\n\napp = FastAPI()\n\nasync def func(request: Request):\n request.state.test = 'test value'\n\n@app.get('/', dependencies=[Depends(func)])\nasync def root(request: Request):\n return request.state.test\n```\n\n```py\nfrom fastapi import FastAPI, Depends, Request\n\napp = FastAPI()\n\nasync def func(request: Request):\n return 'test value'\n\n@app.get('/')\nasync def root(test: str = Depends(func)):\n return test\n```\n\n```text\nrequest.state\n```\n\n```text\nRequest\n```\n\n```text\nState\n```\n\n```text\ntest\n```\n\n```text\ndependencies=[Depends(test)]\n```\n\n```text\ntest\n```\n\n```text\nDepends\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.120Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":12,"totalLines":101,"estimatedTokens":417}}295{"id":"stack-71823151","source":"stackoverflow","questionId":71823151,"title":"Deploy React's build folder via FastAPI","tags":["python","reactjs","fastapi"],"text":"Title: Deploy React's build folder via FastAPI\nTags: python, reactjs, fastapi\nSource: Stack Overflow\n\nQuestion:\nI want to serve my React frontend using FastAPI. The goal being 0 Javascript dependency for the user. The user can simply download the Python code, start server, and view the website on localhost.\n\nMy folder structure is:\n\n```\n- my-fullstack-app\n - frontend/\n - build/\n - public/\n - ...\n - package.json\n - backend/\n - main.py\n - static/\n```\n\nI ran `npm run build` to generate the `frontend/build/` folder which contains:\n\n```\nbuild/\n├── asset-manifest.json\n├── favicon.ico\n├── index.html\n├── logo192.png\n├── logo512.png\n├── manifest.json\n├── robots.txt\n└── static\n ├── css\n │ ├── main.073c9b0a.css\n │ └── main.073c9b0a.css.map\n ├── js\n │ ├── 787.cda612ba.chunk.js\n │ ├── 787.cda612ba.chunk.js.map\n │ ├── main.af955102.js\n │ ├── main.af955102.js.LICENSE.txt\n │ └── main.af955102.js.map\n └── media\n └── logo.6ce24c58023cc2f8fd88fe9d219db6c6.svg\n```\n\nI copied the contents of the `frontend/build/` folder inside `backend/static/`.\n\nNow, I want to serve this `backend/static/` folder via FastAPI as opposed to running another server.\n\nIn my FastAPI's `main.py` I have:\n\n```\nfrom fastapi import FastAPI\nfrom fastapi.staticfiles import StaticFiles\n\napp = FastAPI()\n\napp.mount(\"/\", StaticFiles(directory=\"static/\"), name=\"static\")\n```\n\nI then start the server using - `uvicorn main:app --reload`.\n\nBut it doesn't work.\n\nWhen I open `http://127.0.0.1:8000/` in the browser, the output is a JSON file which says `{\"detail\":\"Not Found\"}` and console has `Content Security Policy: The page's settings blocked the loading of a resource at http://127.0.0.1:8000/favicon.ico (\"default-src\").`.\n\nHow do I get this to work? I've seen examples for similar functionality with React and Express.\n\n========================================\n\nTop Answer:\nWhat you can do is have the `index.html` serve all routes except API specific ones, then load all static assets. My approach looks like this:\n\n```\nfrom fastapi import FastAPI, Request\nfrom fastapi.responses import FileResponse\nfrom fastapi.staticfiles import StaticFiles\nfrom fastapi.exception_handlers import http_exception_handler\nfrom starlette.exceptions import HTTPException as StarletteHTTPException\n\ndef SPA(app: FastAPI, build_dir: Union[Path, str]) -> FastAPI:\n# Serves a React application in the root directory\n\n @app.exception_handler(StarletteHTTPException)\n async def _spa_server(req: Request, exc: StarletteHTTPException):\n if exc.status_code == 404:\n return FileResponse(f'{build_dir}/index.html', media_type='text/html')\n else:\n return await http_exception_handler(req, exc)\n\n if isinstance(build_dir, str):\n build_dir = Path(build_dir)\n\n app.mount(\n '/static/',\n StaticFiles(directory=build_dir / 'static'),\n name='React app static files',\n )\n```\n\nThen in your entry point file\n\n```\napp: FastAPI = SPA(FastAPI(title='PROJECT_NAME', './build')\n```\n\n========================================\n\nCode:\n```text\n- my-fullstack-app\n - frontend/\n - build/\n - public/\n - ...\n - package.json\n - backend/\n - main.py\n - static/\n```\n\n```text\nbuild/\n├── asset-manifest.json\n├── favicon.ico\n├── index.html\n├── logo192.png\n├── logo512.png\n├── manifest.json\n├── robots.txt\n└── static\n ├── css\n │ ├── main.073c9b0a.css\n │ └── main.073c9b0a.css.map\n ├── js\n │ ├── 787.cda612ba.chunk.js\n │ ├── 787.cda612ba.chunk.js.map\n │ ├── main.af955102.js\n │ ├── main.af955102.js.LICENSE.txt\n │ └── main.af955102.js.map\n └── media\n └── logo.6ce24c58023cc2f8fd88fe9d219db6c6.svg\n```\n\n```text\nfrom fastapi import FastAPI\nfrom fastapi.staticfiles import StaticFiles\n\napp = FastAPI()\n\napp.mount(\"/\", StaticFiles(directory=\"static/\"), name=\"static\")\n```\n\n```text\nnpm run build\n```\n\n```text\nfrontend/build/\n```\n\n```text\nfrontend/build/\n```\n\n```text\nbackend/static/\n```\n\n```text\nbackend/static/\n```\n\n```text\nmain.py\n```\n\n```text\nuvicorn main:app --reload\n```\n\n```text\nhttp://127.0.0.1:8000/\n```\n\n```text\n{\"detail\":\"Not Found\"}\n```\n\n```text\nContent Security Policy: The page's settings blocked the loading of a resource at http://127.0.0.1:8000/favicon.ico (\"default-src\").\n```\n\n```text\napp.mount(\"/\", StaticFiles(directory=\"static/\"), name=\"static\")\n```\n\n```text\napp.mount(\"/\", StaticFiles(directory=\"static/\", html=True), name=\"static\")\n```\n\n```text\nhtml=True\n```\n\n```text\nhttp://127.0.0.1:8000/index.html\n```\n\n```text\nhtml=True\n```\n\n```text\nhttp://127.0.0.1:8000/\n```\n\n```text\nfrom fastapi import FastAPI, Request\nfrom fastapi.responses import FileResponse\nfrom fastapi.staticfiles import StaticFiles\nfrom fastapi.exception_handlers import http_exception_handler\nfrom starlette.exceptions import HTTPException as StarletteHTTPException\n\ndef SPA(app: FastAPI, build_dir: Union[Path, str]) -> FastAPI:\n# Serves a React application in the root directory\n\n @app.exception_handler(StarletteHTTPException)\n async def _spa_server(req: Request, exc: StarletteHTTPException):\n if exc.status_code == 404:\n return FileResponse(f'{build_dir}/index.html', media_type='text/html')\n else:\n return await http_exception_handler(req, exc)\n\n if isinstance(build_dir, str):\n build_dir = Path(build_dir)\n\n app.mount(\n '/static/',\n StaticFiles(directory=build_dir / 'static'),\n name='React app static files',\n )\n```\n\n```text\napp: FastAPI = SPA(FastAPI(title='PROJECT_NAME', './build')\n```\n\n```text\nindex.html\n```\n\n========================================\n\nComments:\n- You would need to redirect `\"/\"` to `\"/index.html\"`\n- See stackoverflow.com/questions/65916537/…\n- I didn't realise a redirect to `index.html` was required. It's working perfectly. Thank you! :)","metadata":{"transformedAt":"2026-08-18T18:32:29.120Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":22,"totalLines":259,"estimatedTokens":1436}}296{"id":"stack-72200552","source":"stackoverflow","questionId":72200552,"title":"fastapi - firebase authentication with JWT's?","tags":["python","firebase","firebase-authentication","fastapi"],"text":"Title: fastapi - firebase authentication with JWT's?\nTags: python, firebase, firebase-authentication, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm trying to use fastapi to return some basic ML models to users.\n\nCurrently, I secure user details with firebase auth. I want to use the JWT's users have when using the basic application to authenticate their request for the ML model.\n\nWith fastapi, there doesn't seem to be a straightforward answer to doing this.\n\nI've followed two main threads as ways to work out how to do this, but am a bit lost as to how I can simply take the JWT from the header of a request and check it against firebase admin or whathave you?\n\nFollowing this tutorial and using this package, I end up with something like this,\nhttps://github.com/tokusumi/fastapi-cloudauth . This doesn't really do anything - it doesn't authenticate the JWT for me, bit confused as to if this package is actually worthwhile?\n\n```\nfrom fastapi import FastAPI, HTTPException, Header,Depends\nfrom fastapi.middleware.cors import CORSMiddleware\nfrom fastapi.security import HTTPAuthorizationCredentials, HTTPBearer\nfrom fastapi_cloudauth.firebase import FirebaseCurrentUser, FirebaseClaims\n\napp = FastAPI()\nsecurity = HTTPBearer()\n\norigins = [\n xxxx\n]\n\napp.add_middleware(\n xxxx\n\n)\n\nget_current_user = FirebaseCurrentUser(\n project_id=os.environ[\"PROJECT_ID\"]\n)\n\n@app.get(\"/user/\")\ndef secure_user(current_user: FirebaseClaims = Depends(get_current_user)):\n # ID token is valid and getting user info from ID token\n return f\"Hello, {current_user.user_id}\"\n```\n\nAlternatively, looking at this,\n\nhttps://github.com/tiangolo/fastapi/issues/4768\n\nIt seems like something like this would work,\n\n```\nsecurity = HTTPBearer()\n\napi = FastAPI()\nsecurity = HTTPBearer()\n\nfirebase_client = FirebaseClient(\n firebase_admin_credentials_url=firebase_test_admin_credentials_url\n # ...\n)\n\nuser_roles = [test_role]\n\nasync def firebase_authentication(token: HTTPAuthorizationCredentials = Depends(security)) -> dict:\n user = firebase_client.verify_token(token.credentials)\n return user\n\nasync def firebase_authorization(user: dict = Depends(firebase_authentication)):\n roles = firebase_client.get_user_roles(user)\n\n for role in roles:\n if role in user_roles:\n return user\n\n raise HTTPException(detail=\"User does not have the required roles\", status_code=HTTPStatus.FORBIDDEN)\n\n@api.get(\"/\")\nasync def root(uid: str = Depends(firebase_authorization)):\n return {\"message\": \"Successfully authenticated & authorized!\"}\n```\n\nBut honestly I'm a bit confused about how I would set up the firebase environment variables, what packages I would need (firebaseadmin?)\n\nWould love some helpers, thanks!\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI, HTTPException, Header,Depends\nfrom fastapi.middleware.cors import CORSMiddleware\nfrom fastapi.security import HTTPAuthorizationCredentials, HTTPBearer\nfrom fastapi_cloudauth.firebase import FirebaseCurrentUser, FirebaseClaims\n\napp = FastAPI()\nsecurity = HTTPBearer()\n\n\norigins = [\n xxxx\n]\n\napp.add_middleware(\n xxxx\n\n)\n\nget_current_user = FirebaseCurrentUser(\n project_id=os.environ[\"PROJECT_ID\"]\n)\n\n\n@app.get(\"/user/\")\ndef secure_user(current_user: FirebaseClaims = Depends(get_current_user)):\n # ID token is valid and getting user info from ID token\n return f\"Hello, {current_user.user_id}\"\n```\n\n```text\nsecurity = HTTPBearer()\n\napi = FastAPI()\nsecurity = HTTPBearer()\n\nfirebase_client = FirebaseClient(\n firebase_admin_credentials_url=firebase_test_admin_credentials_url\n # ...\n)\n\nuser_roles = [test_role]\n\nasync def firebase_authentication(token: HTTPAuthorizationCredentials = Depends(security)) -> dict:\n user = firebase_client.verify_token(token.credentials)\n return user\n\nasync def firebase_authorization(user: dict = Depends(firebase_authentication)):\n roles = firebase_client.get_user_roles(user)\n\n for role in roles:\n if role in user_roles:\n return user\n\n raise HTTPException(detail=\"User does not have the required roles\", status_code=HTTPStatus.FORBIDDEN)\n\n@api.get(\"/\")\nasync def root(uid: str = Depends(firebase_authorization)):\n return {\"message\": \"Successfully authenticated & authorized!\"}\n```\n\n```text\nfrom fastapi.security import HTTPBearer, HTTPAuthorizationCredentials\nfrom fastapi import Depends, HTTPException, status, Response\nfrom firebase_admin import auth, credentials, initialize_app\n\ncredential = credentials.Certificate('./key.json')\ninitialize_app(credential)\n\ndef get_user_token(res: Response, credential: HTTPAuthorizationCredentials=Depends(HTTPBearer(auto_error=False))):\n if cred is None:\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Bearer authentication is needed\",\n headers={'WWW-Authenticate': 'Bearer realm=\"auth_required\"'},\n )\n try:\n decoded_token = auth.verify_id_token(credential.credentials)\n except Exception as err:\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=f\"Invalid authentication from Firebase. {err}\",\n headers={'WWW-Authenticate': 'Bearer error=\"invalid_token\"'},\n )\n res.headers['WWW-Authenticate'] = 'Bearer realm=\"auth_required\"'\n return decoded_token\n```\n\n```text\nfrom fastapi.security import HTTPBearer, HTTPAuthorizationCredentials\nfrom fastapi import Depends, HTTPException, status, Response, FastAPI, Depends\nfrom firebase_admin import auth, credentials, initialize_app\n\ncredential = credentials.Certificate('./key.json')\ninitialize_app(credential)\n\ndef get_user_token(res: Response, credential: HTTPAuthorizationCredentials=Depends(HTTPBearer(auto_error=False))):\n if cred is None:\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Bearer authentication is needed\",\n headers={'WWW-Authenticate': 'Bearer realm=\"auth_required\"'},\n )\n try:\n decoded_token = auth.verify_id_token(credential.credentials)\n except Exception as err:\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=f\"Invalid authentication from Firebase. {err}\",\n headers={'WWW-Authenticate': 'Bearer error=\"invalid_token\"'},\n )\n res.headers['WWW-Authenticate'] = 'Bearer realm=\"auth_required\"'\n return decoded_token\n\napp = FastAPI()\n\n@app.get(\"/api/\")\nasync def hello():\n return {\"msg\":\"Hello, this is API server\"} \n\n\n@app.get(\"/api/user_token\")\nasync def hello_user(user = Depends(get_user_token)):\n return {\"msg\":\"Hello, user\",\"uid\":user['uid']}\n```\n\n```text\npip3 install firebase_admin\n```\n\n========================================\n\nComments:\n- What outcome do you get from your first try? (using `fastapi_cloudauth.firebase`?)\n- Thanks @bauyrzhan, this is exactly what I needed. Is there a typo though in `get_user_token`? Should it be: `if credential is None:` in get_user_token\n- Hello, maybe, sorry it was long time ago when I have written that answer.\n- Great help here, thanks.","metadata":{"transformedAt":"2026-08-18T18:32:29.120Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":225,"estimatedTokens":1768}}297{"id":"stack-67732361","source":"stackoverflow","questionId":67732361,"title":"Python read/write vs shutil copy","tags":["python","file","io","fastapi","shutil"],"text":"Title: Python read/write vs shutil copy\nTags: python, file, io, fastapi, shutil\nSource: Stack Overflow\n\nQuestion:\nI need to save files uploaded to my server (Max file size is 10MB) and found this answer, which works perfectly. However, I'm wondering what is the point of using the `shutil` module, and what is the difference between this:\n\n```\nfile_location = f\"files/{uploaded_file.filename}\"\nwith open(file_location, \"wb+\") as file_object:\n file_object.write(uploaded_file.file.read())\n```\n\nand this:\n\n```\nimport shutil\n\nfile_location = f\"files/{uploaded_file.filename}\"\nwith open(file_location, \"wb+\") as file_object:\n shutil.copyfileobj(uploaded_file.file, file_object)\n```\n\nDuring my programming experience, I came across `shutil` module multiple times, but still can't figure out what its benefits are over `read()` and `write()` methods.\n\n========================================\n\nTop Answer:\nI would like to highlight a few points with regard to OP's question and the (currently accepted) answer by @Tim Roberts:\n\n*\"`shutil` copies in chunks so you can copy files larger than memory\"*. One could also copy a file in chunks using the `read()` method instead (and the \"walrus operator\")—please have a look at the short example below, as well as **this** and **this** answers for more details—just like one could load the whole file into memory using `shutil.copyfileobj()`, but passing a negative `length` value.\n\n```\nwith open(uploaded_file.filename, 'wb') as f:\n while contents := uploaded_file.file.read(1024 * 1024): # adjust the chunk size as desired\n f.write(contents)\n```\n\nUnder the hood, `copyfileob()` uses a very similar approach to the above, utilizing `read()` and `write()` methods of file objects; hence, it would make little difference, if one chose to use one over the other. The source code of `copyfileob()` can be seen below. The default buffer size, i.e., `COPY_BUFSIZE` below, is set to `1MB` (`1024 *1024` bytes), if it is running on Wnidows, or `64KB` (`64 * 1024` bytes) on other platforms (see here).\n\n```\ndef copyfileobj(fsrc, fdst, length=0):\n \"\"\"copy data from file-like object fsrc to file-like object fdst\"\"\"\n if not length:\n length = COPY_BUFSIZE\n # Localize variable access to minimize overhead.\n fsrc_read = fsrc.read\n fdst_write = fdst.write\n while True:\n buf = fsrc_read(length)\n if not buf:\n break\n fdst_write(buf)\n```\n\n*\"`shutil` has routines to copy files by name so you don't have to open them at all...\"* Since OP seems to be using the FastAPI framework (which is actually Starlette underneath), `UploadFile` exposes an actual Python `SpooledTemporaryFile` (a file-like object) that you can get using the `.file` attribute (the source code can be found here). When FastAPI/Starlette creates a new instance of `UploadFile`, it already creates the `SpooledTemporaryFile` behind the scenes, which remains `open`. Hence, since you are dealing with a temporary file that has no visible name in the file system—that would otherwise allow you to copy the contents without opening the file using `shutil`—and which is already `open`, it would make **no difference** using either `read()` or `copyfileobj()`.\n\n*\"it can preserve the permissions, ownership, and creation/modification/access timestamps.\"* Even though this is about saving a file uploaded through a web framework—and hence, most of these metadata wouldn't be transfered along with the file—as per the documentation, the above statement is not entirely true:\n\n**Warning:** Even the higher-level file copying functions (`shutil.copy()`, `shutil.copy2()`) **cannot** copy all file\nmetadata.\n\nOn POSIX platforms, this means that file owner and group are lost\nas well as ACLs. On Mac OS, the resource fork and other metadata are\n**not used**. This means that resources **will be lost** and file type and creator codes **will not be correct**. On Windows, file\nowners,\nACLs and alternate data streams are not copied.\n\nThat being said, there is nothing wrong with using `copyfileobj()`. On the contrary, if you are dealing with large files and you would like to avoid loading the entire file into memory—as you may not have enough RAM to accommodate all the data—and you would rather use `copyfileobj()` instead of a similar solution using `read()` method (as described in point 1 above), it is perfectly fine to use `shutil.copyfileobj(fsrc, fdst)`. Besides, `copyfileobj()` has been offered (since Python 3.8) as an alternative platform-dependent efficient copy operation. One could change the default buffer size through adjusting the `length` argument in `copyfileobj()`.\n\n### Important Note\n\nIf `copyfileobj()` was used inside a FastAPI `def` (sync) endpoint instead of `async def` one, it would be perfectly fine (even though you should always aim using *asynchronous* code, as described in this answer), as a normal `def` endpoint in FastAPI is run in an external threadpool that is then `await`ed, instead of being called directly (as it would otherwise block the server). On the other hand, `async def` endpoints run directly in the event loop of the main (single) thread, and thus, calling such a method as `copyfileobj()` that performs **blocking** I/O operations (as shown in the source code) would result in blocking the entire server, until such a task is completed (for more information on `def` vs `async def` in FastAPI, please have a look at **this answer**).\n\nHence, if you are about to call `copyfileobj()` from within an `async def` endpoint, you should make sure to run this operation—as well as every file operation, such as `open()` and `close()`—in a separate thread to ensure that the main thread (where coroutines are run) does not get blocked. One could do that using Starlette's `run_in_threadpool()`, which is also used internally by FastAPI, when you call the `async` methods of the `UploadFile` object, as shown here. For instance:\n\n```\nawait run_in_threadpool(shutil.copyfileobj, fsrc, fdst)\n```\n\nFor more details and code examples, please have a look at **this answer**.\n\n========================================\n\nCode:\n```py\nfile_location = f\"files/{uploaded_file.filename}\"\nwith open(file_location, \"wb+\") as file_object:\n file_object.write(uploaded_file.file.read())\n```\n\n```py\nimport shutil\n\nfile_location = f\"files/{uploaded_file.filename}\"\nwith open(file_location, \"wb+\") as file_object:\n shutil.copyfileobj(uploaded_file.file, file_object)\n```\n\n```text\nshutil\n```\n\n```text\nshutil\n```\n\n```text\nread()\n```\n\n```text\nwrite()\n```\n\n```text\nshutil\n```\n\n```text\nshutil\n```\n\n```py\nwith open(uploaded_file.filename, 'wb') as f:\n while contents := uploaded_file.file.read(1024 * 1024): # adjust the chunk size as desired\n f.write(contents)\n```\n\n```py\ndef copyfileobj(fsrc, fdst, length=0):\n \"\"\"copy data from file-like object fsrc to file-like object fdst\"\"\"\n if not length:\n length = COPY_BUFSIZE\n # Localize variable access to minimize overhead.\n fsrc_read = fsrc.read\n fdst_write = fdst.write\n while True:\n buf = fsrc_read(length)\n if not buf:\n break\n fdst_write(buf)\n```\n\n```py\nawait run_in_threadpool(shutil.copyfileobj, fsrc, fdst)\n```\n\n```text\nshutil\n```\n\n```text\nread()\n```\n\n```text\nshutil.copyfileobj()\n```\n\n```text\nlength\n```\n\n```text\ncopyfileob()\n```\n\n```text\nread()\n```\n\n```text\nwrite()\n```\n\n```text\ncopyfileob()\n```\n\n```text\nCOPY_BUFSIZE\n```\n\n```text\n1MB\n```\n\n```text\n1024 *1024\n```\n\n```text\n64KB\n```\n\n```text\n64 * 1024\n```\n\n```text\nshutil\n```\n\n```text\nUploadFile\n```\n\n```text\nSpooledTemporaryFile\n```\n\n```text\n.file\n```\n\n```text\nUploadFile\n```\n\n```text\nSpooledTemporaryFile\n```\n\n```text\nopen\n```\n\n```text\nshutil\n```\n\n```text\nopen\n```\n\n```text\nread()\n```\n\n```text\ncopyfileobj()\n```\n\n```text\nshutil.copy()\n```\n\n```text\nshutil.copy2()\n```\n\n```text\ncopyfileobj()\n```\n\n```text\ncopyfileobj()\n```\n\n```text\nread()\n```\n\n```text\nshutil.copyfileobj(fsrc, fdst)\n```\n\n```text\ncopyfileobj()\n```\n\n```text\nlength\n```\n\n```text\ncopyfileobj()\n```\n\n```text\ncopyfileobj()\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\ndef\n```\n\n```text\nawait\n```\n\n```text\nasync def\n```\n\n```text\ncopyfileobj()\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\ncopyfileobj()\n```\n\n```text\nasync def\n```\n\n```text\nopen()\n```\n\n```text\nclose()\n```\n\n```text\nrun_in_threadpool()\n```\n\n```text\nasync\n```\n\n```text\nUploadFile\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.120Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":60,"totalLines":343,"estimatedTokens":2075}}298{"id":"stack-73282411","source":"stackoverflow","questionId":73282411,"title":"How to add background tasks when request fails and HTTPException is raised in FastAPI?","tags":["python","logging","fastapi","background-task","starlette"],"text":"Title: How to add background tasks when request fails and HTTPException is raised in FastAPI?\nTags: python, logging, fastapi, background-task, starlette\nSource: Stack Overflow\n\nQuestion:\nI was trying to generate logs when an exception occurs in my FastAPI endpoint using a Background task as:\n\n```\nfrom fastapi import BackgroundTasks, FastAPI\n\napp = FastAPI()\n\ndef write_notification(message=\"\"):\n with open(\"log.txt\", mode=\"w\") as email_file:\n content = f\"{message}\"\n email_file.write(content)\n\n@app.post(\"/send-notification/{email}\")\nasync def send_notification(email: str, background_tasks: BackgroundTasks):\n if \"hello\" in email:\n background_tasks.add_task(write_notification, message=\"helloworld\")\n raise HTTPException(status_code=500, detail=\"example error\")\n\n background_tasks.add_task(write_notification, message=\"hello world.\")\n return {\"message\": \"Notification sent in the background\"}\n```\n\nHowever, the logs are not generated because according to the documentation here and here, a background task runs \"only\" after the `return` statement is executed.\n\nIs there any workaround to this?\n\n========================================\n\nCode:\n```py\nfrom fastapi import BackgroundTasks, FastAPI\n\napp = FastAPI()\n\ndef write_notification(message=\"\"):\n with open(\"log.txt\", mode=\"w\") as email_file:\n content = f\"{message}\"\n email_file.write(content)\n\n@app.post(\"/send-notification/{email}\")\nasync def send_notification(email: str, background_tasks: BackgroundTasks):\n if \"hello\" in email:\n background_tasks.add_task(write_notification, message=\"helloworld\")\n raise HTTPException(status_code=500, detail=\"example error\")\n\n background_tasks.add_task(write_notification, message=\"hello world.\")\n return {\"message\": \"Notification sent in the background\"}\n```\n\n```text\nreturn\n```\n\n```py\nfrom fastapi import BackgroundTasks, FastAPI, HTTPException, Request\nfrom fastapi.responses import PlainTextResponse\nfrom starlette.exceptions import HTTPException as StarletteHTTPException\nfrom starlette.background import BackgroundTask\n\napp = FastAPI()\n\ndef write_notification(message):\n with open('log.txt', 'a') as f:\n f.write(f'{message}'+'\\n')\n\n@app.exception_handler(StarletteHTTPException)\nasync def http_exception_handler(request, exc):\n task = BackgroundTask(write_notification, message=exc.detail)\n return PlainTextResponse(str(exc.detail), status_code=exc.status_code, background=task)\n \n@app.get(\"/{msg}\")\ndef send_notification(msg: str, background_tasks: BackgroundTasks):\n if \"hello\" in msg:\n raise HTTPException(status_code=500, detail=\"Something went wrong\")\n\n background_tasks.add_task(write_notification, message=\"Success\")\n return {\"message\": \"Request has been successfully submitted.\"}\n```\n\n```py\nfrom fastapi import BackgroundTasks\n\n@app.exception_handler(StarletteHTTPException)\nasync def http_exception_handler(request, exc):\n tasks = BackgroundTasks()\n tasks.add_task(write_notification, message=exc.detail)\n tasks.add_task(some_other_function, message=\"some other message\")\n return PlainTextResponse(str(exc.detail), status_code=exc.status_code, background=tasks)\n```\n\n```py\nfrom starlette.background import BackgroundTask\n\n@app.exception_handler(StarletteHTTPException)\nasync def http_exception_handler(request, exc):\n response = PlainTextResponse(str(exc.detail), status_code=exc.status_code)\n response.background = BackgroundTask(write_notification, message=exc.detail)\n # to add multiple background tasks use:\n # response.background = tasks # create `tasks` as shown in the code above\n return response\n```\n\n```text\nHTTPException\n```\n\n```text\nBackgroundTasks\n```\n\n```text\nexception_handler\n```\n\n```text\nasync def\n```\n\n```text\ndef\n```\n\n```text\nawait\n```\n\n========================================\n\nComments:\n- You can try using Starlette background tasks","metadata":{"transformedAt":"2026-08-18T18:32:29.120Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":11,"totalLines":135,"estimatedTokens":966}}299{"id":"stack-75150942","source":"stackoverflow","questionId":75150942,"title":"How to get a session from async_session() generator FastApi Sqlalchemy","tags":["python","python-3.x","sqlalchemy","python-asyncio","fastapi"],"text":"Title: How to get a session from async_session() generator FastApi Sqlalchemy\nTags: python, python-3.x, sqlalchemy, python-asyncio, fastapi\nSource: Stack Overflow\n\nQuestion:\nI see in many places an approach for getting SqlAlchemy session just like this one below:\n\n```\nasync def get_session() -> AsyncSession:\n async with async_session() as session:\n yield session\n```\n\nIt used together with Depends:\n\n```\n@app.post(\"/endpoint\")\nasync def vieww(session: AsyncSession = Depends(get_session)):\n session.execute(some_statement)\n```\n\n**So my question is how to get a session from `get_session` ooutside Depends?**\n\nI had a lot of attempts and got a headache..\nI tried with\n\n```\ns = await get_session()\ns.execute(stmt)\n```\n\nAnd I get `AttributeError: 'async_generator' object has no attribute 'execute'`\n\n========================================\n\nTop Answer:\nCheck this article. Basically you can pass the session via context:\n\nFirst crete the AsyncSession\n\n```\nasync def get_session() -> AsyncSession:\n async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)\n async with async_session() as session:\n yield session\n```\n\nCreate the context. This is the key part, in here you can use the Dependency.\n\n```\nasync def get_context(session: AsyncSession = Depends(get_session)):\n return {'session': session}\n```\n\nAdd it into the context_gettr param\n\n```\ngraphql_app = GraphQLRouter(schema, context_getter=get_context)\n```\n\nAnd now it is usable from everywhere like this:\n\n```\n@strawberry.type\nclass Query:\n @strawberry.field\n async def songs(self, info: Info) -> typing.List[SongType]:\n \"\"\" Get all songs \"\"\"\n session = info.context['session']\n songs_data_list = await get_songs(session)\n return songs_data_list\n\nasync def get_songs(session) -> typing.List[SongType]:\n \"\"\" Get all songs resolver \"\"\"\n result = await session.exec(select(Song))\n ... # now you have the query result, do whatever you want from here\n```\n\n========================================\n\nCode:\n```py\nasync def get_session() -> AsyncSession:\n async with async_session() as session:\n yield session\n```\n\n```text\n@app.post(\"/endpoint\")\nasync def vieww(session: AsyncSession = Depends(get_session)):\n session.execute(some_statement)\n```\n\n```text\ns = await get_session()\ns.execute(stmt)\n```\n\n```text\nget_session\n```\n\n```text\nAttributeError: 'async_generator' object has no attribute 'execute'\n```\n\n```py\nfrom asyncio import run\nfrom collections.abc import AsyncIterator\n\n\nasync def get_generator() -> AsyncIterator[int]:\n yield 1\n\n\nasync def main() -> None:\n generator = get_generator()\n print(await generator.__anext__())\n\n\nif __name__ == \"__main__\":\n run(main())\n```\n\n```py\n...\nasync def main() -> None:\n generator = get_generator()\n print(await anext(generator)\n...\n```\n\n```py\nasync with async_session() as session:\n ... # do things with the session\n session.execute()\n```\n\n```text\nget_session\n```\n\n```text\nawait\n```\n\n```text\n__anext__\n```\n\n```text\n1\n```\n\n```text\n3.10\n```\n\n```text\nanext\n```\n\n```text\ns = await anext(get_session())\n```\n\n```text\nget_session\n```\n\n```text\nDepends\n```\n\n```text\n__anext__\n```\n\n```text\nStopAsyncIteration\n```\n\n```text\nasync def get_session() -> AsyncSession:\n async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)\n async with async_session() as session:\n yield session\n```\n\n```text\nasync def get_context(session: AsyncSession = Depends(get_session)):\n return {'session': session}\n```\n\n```text\ngraphql_app = GraphQLRouter(schema, context_getter=get_context)\n```\n\n```text\n@strawberry.type\nclass Query:\n @strawberry.field\n async def songs(self, info: Info) -> typing.List[SongType]:\n \"\"\" Get all songs \"\"\"\n session = info.context['session']\n songs_data_list = await get_songs(session)\n return songs_data_list\n\nasync def get_songs(session) -> typing.List[SongType]:\n \"\"\" Get all songs resolver \"\"\"\n result = await session.exec(select(Song))\n ... # now you have the query result, do whatever you want from here\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.121Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":23,"totalLines":213,"estimatedTokens":1011}}300{"id":"stack-68701240","source":"stackoverflow","questionId":68701240,"title":"FastApi Post Request With Bytes Object Got 422 Error","tags":["python","python-requests","fastapi"],"text":"Title: FastApi Post Request With Bytes Object Got 422 Error\nTags: python, python-requests, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am writing a python post request with a bytes body:\n\n```\nwith open('srt_file.srt', 'rb') as f:\n data = f.read()\n\n res = requests.post(url='http://localhost:8000/api/parse/srt',\n data=data,\n headers={'Content-Type': 'application/octet-stream'})\n```\n\nAnd in the server part, I tried to parse the body:\n\n```\napp = FastAPI()\nBaseConfig.arbitrary_types_allowed = True\n\nclass Data(BaseModel):\n data: bytes\n\n@app.post(\"/api/parse/{format}\", response_model=CaptionJson)\nasync def parse_input(format: str, data: Data) -> CaptionJson:\n ...\n```\n\nHowever, I got the 422 error:\n`{\"detail\":[{\"loc\":[\"body\"],\"msg\":\"value is not a valid dict\",\"type\":\"type_error.dict\"}]}`\n\nSo where is wrong with my code, and how should I fix it?\nThank you all in advance for helping out!!\n\n========================================\n\nTop Answer:\nIf the endgoal of your request is to only send bytes then please look at the documentation of FastAPI to accept bytes-like objects: https://fastapi.tiangolo.com/tutorial/request-files.\n\nThere is no need for the bytes to be enclosed into a model.\n\n========================================\n\nCode:\n```text\nwith open('srt_file.srt', 'rb') as f:\n data = f.read()\n\n res = requests.post(url='http://localhost:8000/api/parse/srt',\n data=data,\n headers={'Content-Type': 'application/octet-stream'})\n```\n\n```text\napp = FastAPI()\nBaseConfig.arbitrary_types_allowed = True\n\n\nclass Data(BaseModel):\n data: bytes\n\n@app.post(\"/api/parse/{format}\", response_model=CaptionJson)\nasync def parse_input(format: str, data: Data) -> CaptionJson:\n ...\n```\n\n```text\n{\"detail\":[{\"loc\":[\"body\"],\"msg\":\"value is not a valid dict\",\"type\":\"type_error.dict\"}]}\n```\n\n```text\nfrom fastapi import FastAPI, Request\n\napp = FastAPI()\n\n@app.get(\"/foo\")\nasync def parse_input(request: Request):\n data: bytes = await request.body()\n # Do something with data\n```\n\n```text\nfrom fastapi import FastAPI, Request, Depends\n\napp = FastAPI()\n\nasync def parse_body(request: Request):\n data: bytes = await request.body()\n return data\n\n\n@app.get(\"/foo\")\nasync def parse_input(data: bytes = Depends(parse_body)):\n # Do something with data\n pass\n```\n\n```text\nRequest\n```\n\n```text\nDepends\n```\n\n```text\nparse_body\n```\n\n========================================\n\nComments:\n- That's specifically for uploading files as form data. This is not the same as sending an arbitrary stream of bytes in the body.","metadata":{"transformedAt":"2026-08-18T18:32:29.121Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":8,"totalLines":115,"estimatedTokens":643}}301{"id":"stack-63788083","source":"stackoverflow","questionId":63788083,"title":"How to check if a cookie is set in FastAPI?","tags":["python","fastapi"],"text":"Title: How to check if a cookie is set in FastAPI?\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI defined an optional cookie parameter and now want to check if the cookie was set. Unfortunately, the variable does not equal to `None` but to an empty `Cookie` object. How can I check the cookie object if it is set?\n\nHere's how I defined the cookie parameter:\n\n```\n@app.route(\"/graphcall\")\ndef graphcall(request: Request, ads_id: Optional[str] = Cookie(None)):\n if ads_id:\n # Do stuff if the ads_id is set\n```\n\n========================================\n\nTop Answer:\nFor me this works\n\n```\nasync def setcookie(request: Request, nm: str = Form(...)):\n print(\"setcookie \"+nm)\n response = templates.TemplateResponse(\"readcookie.html\",{\"request\": request})\n response.set_cookie(key=\"userID\", value=nm)\n\n@app.get(\"/getcookie/\", response_class=HTMLResponse)\nasync def getcookie(request: Request,userID: Optional[str] = Cookie(None)):\n if userID:\n print(\"getcookie \"+userID)\n else:\n print(\"getcookie None\")\n return templates.TemplateResponse(\"showcookie.html\", {\"request\": request, \"name\": userID})\n```\n\nIn getcookie I have the cookie set in setcookie.\n\nI this approach:\n\nhttps://fastapi.tiangolo.com/advanced/response-cookies/#return-a-response-directly\n\n========================================\n\nCode:\n```text\n@app.route(\"/graphcall\")\ndef graphcall(request: Request, ads_id: Optional[str] = Cookie(None)):\n if ads_id:\n # Do stuff if the ads_id is set\n```\n\n```text\nNone\n```\n\n```text\nCookie\n```\n\n```text\n@app.get(\"/items/\")\nasync def read_items(ads_id: Optional[str] = Cookie(None)):\n if ads_id:\n answer = \"set to %s\" % ads_id\n else:\n answer = \"not set\"\n return {\"ads_id\": answer}\n```\n\n```text\n$ curl -X GET \"http://127.0.0.1:8000/items/\" -H \"accept: application/json\" -H \"Cookie: ads_id=foobar\"\n{\"ads_id\":\"set to foobar\"}\n\n$ curl -X GET \"http://127.0.0.1:8000/items/\" -H \"accept: application/json\"\n{\"ads_id\":\"not set\"}\n```\n\n```text\nasync def setcookie(request: Request, nm: str = Form(...)):\n print(\"setcookie \"+nm)\n response = templates.TemplateResponse(\"readcookie.html\",{\"request\": request})\n response.set_cookie(key=\"userID\", value=nm)\n\n@app.get(\"/getcookie/\", response_class=HTMLResponse)\nasync def getcookie(request: Request,userID: Optional[str] = Cookie(None)):\n if userID:\n print(\"getcookie \"+userID)\n else:\n print(\"getcookie None\")\n return templates.TemplateResponse(\"showcookie.html\", {\"request\": request, \"name\": userID})\n```\n\n```text\n@router.post('/login')\nasync def sign_in(\n user_data: OAuth2PasswordRequestForm = Depends(),\n service: AuthService = Depends(),\n):\n session = await service.authenticate_user(\n user_data.username,\n user_data.password\n )\n response = RedirectResponse(url='/')\n response.set_cookie('Authorization', value=session['session_id'], httponly=True)\n return response\n\n\nasync def get_current_user(request: Request): \n try:\n cookie_authorization: str = request.cookies.get(\"Authorization\")\n # some logic with cookie_authorization\n except Exception as e:\n raise HTTPException(\n status_code=status.HTTP_403_FORBIDDEN, detail=\"Invalid authentication\"\n )\n```\n\n```text\nOptional[str] = Cookie(None)\n```\n\n```text\nads_id: Optional[str] = Cookie(None)\n```\n\n```text\nasync defer(cookie_token: Optional[std] = Cookie(default=None)):\n```\n\n========================================\n\nComments:\n- Hey @guerda i'm not very confident with cookies but this approach could work `request.cookies.get()`\n- I did test it without swagger, I'm rendering an HTML template. Still the variable always is not None.\n- Same situation, did you solve the problem?\n- They should highlight this in the docs. This has bite me twice... See the original issue github.com/tiangolo/fastapi/issues/880\n- That type specification `std` should be `str` instead?","metadata":{"transformedAt":"2026-08-18T18:32:29.121Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":10,"totalLines":138,"estimatedTokens":977}}302{"id":"stack-72052908","source":"stackoverflow","questionId":72052908,"title":"How to return and download Excel file using FastAPI?","tags":["python","excel","fastapi","media-type"],"text":"Title: How to return and download Excel file using FastAPI?\nTags: python, excel, fastapi, media-type\nSource: Stack Overflow\n\nQuestion:\nHow do I return an excel file (version: Office365) using FastAPI? The documentation seems pretty straightforward. But, I don't know what `media_type` to use. Here's my code:\n\n```\nimport os\nfrom fastapi import FastAPI\nfrom fastapi.responses import FileResponse\nfrom pydantic import BaseModel\nfrom typing import Optional\n\nexcel_file_path = r\"C:\\Users\\some_path\\the_excel_file.xlsx\"\n\napp = FastAPI()\n\nclass ExcelRequestInfo(BaseModel):\n client_id: str\n\n@app.post(\"/post_for_excel_file/\")\nasync def serve_excel(item: ExcelRequestInfo):\n # (Generate excel using item.)\n # For now, return a fixed excel.\n return FileResponse(\n path=excel_file_path,\n\n # Swagger UI says 'cannot render, look at console', but console shows nothing.\n media_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'\n\n # Swagger renders funny chars with this argument:\n # 'application/vnd.ms-excel'\n )\n```\n\nAssuming I get it right, how to download the file? Can I use Swagger UI generated by FastAPI to view the sheet? Or, curl? Ideally, I'd like to be able to download and view the file in Excel.\n\n**Solution**\n\nHere's my final (edited) solution to save you from clicking about. In the course of development, I had to switch from a `FileResponse` to `Response` that returns `io.BytesIO`.\n\n```\nimport io\nimport os.path\nfrom fastapi.responses import Response\n\n@router.get(\"/customer/{customer}/sheet\")\nasync def generate_excel(customer: str):\n excel_file_path: str = None\n buffer: io.BytesIO = None\n\n # Generate the sheet.\n excel_file_path, buffer = make_excel(customer=customer)\n\n # Return excel back to client.\n headers = {\n # By adding this, browsers can download this file.\n 'Content-Disposition': f'attachment; filename={os.path.basename(excel_file_path)}',\n # Needed by our client readers, for CORS (cross origin resource sharing).\n \"Access-Control-Allow-Origin\": \"*\",\n \"Access-Control-Allow-Headers\": \"*\",\n \"Access-Control_Allow-Methods\": \"POST, GET, OPTIONS\",\n }\n media_type = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'\n\n return Response(\n content=buffer.getvalue(),\n headers=headers,\n media_type=media_type\n )\n```\n\n========================================\n\nCode:\n```text\nimport os\nfrom fastapi import FastAPI\nfrom fastapi.responses import FileResponse\nfrom pydantic import BaseModel\nfrom typing import Optional\n\nexcel_file_path = r\"C:\\Users\\some_path\\the_excel_file.xlsx\"\n\napp = FastAPI()\n\nclass ExcelRequestInfo(BaseModel):\n client_id: str\n\n\n@app.post(\"/post_for_excel_file/\")\nasync def serve_excel(item: ExcelRequestInfo):\n # (Generate excel using item.)\n # For now, return a fixed excel.\n return FileResponse(\n path=excel_file_path,\n\n # Swagger UI says 'cannot render, look at console', but console shows nothing.\n media_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'\n\n # Swagger renders funny chars with this argument:\n # 'application/vnd.ms-excel'\n )\n```\n\n```text\nimport io\nimport os.path\nfrom fastapi.responses import Response\n\n\n@router.get(\"/customer/{customer}/sheet\")\nasync def generate_excel(customer: str):\n excel_file_path: str = None\n buffer: io.BytesIO = None\n\n # Generate the sheet.\n excel_file_path, buffer = make_excel(customer=customer)\n\n # Return excel back to client.\n headers = {\n # By adding this, browsers can download this file.\n 'Content-Disposition': f'attachment; filename={os.path.basename(excel_file_path)}',\n # Needed by our client readers, for CORS (cross origin resource sharing).\n \"Access-Control-Allow-Origin\": \"*\",\n \"Access-Control-Allow-Headers\": \"*\",\n \"Access-Control_Allow-Methods\": \"POST, GET, OPTIONS\",\n }\n media_type = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'\n\n return Response(\n content=buffer.getvalue(),\n headers=headers,\n media_type=media_type\n )\n```\n\n```text\nmedia_type\n```\n\n```text\nFileResponse\n```\n\n```text\nResponse\n```\n\n```text\nio.BytesIO\n```\n\n```py\nheaders = {'Content-Disposition': 'attachment; filename=\"Book.xlsx\"'}\nreturn FileResponse(excel_file_path, headers=headers)\n```\n\n```text\nContent-Disposition\n```\n\n```text\nattachment\n```\n\n```text\nDownload file\n```\n\n```text\ninline\n```\n\n```text\nattachment\n```\n\n```text\nContent-Disposition\n```\n\n```text\nmedia_type\n```\n\n```text\nFileResponse\n```\n\n```text\n.xlsx\n```\n\n```text\n.xls\n```\n\n========================================\n\nComments:\n- To enable CORS, I would suggest having a look at this, as well as this and this","metadata":{"transformedAt":"2026-08-18T18:32:29.121Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":17,"totalLines":203,"estimatedTokens":1165}}303{"id":"stack-74137116","source":"stackoverflow","questionId":74137116,"title":"How to hide a Pydantic discriminator field from FastAPI docs","tags":["python","fastapi","pydantic"],"text":"Title: How to hide a Pydantic discriminator field from FastAPI docs\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nWe have a discriminator field `type` which we want to hide from the Swagger UI docs:\n\n```\nclass Foo(BDCBaseModel):\n type: Literal[\"Foo\"] = Field(\"Foo\", exclude=True)\n Name: str\n\nclass Bar(BDCBaseModel):\n type: Literal[\"Bar\"] = Field(\"Bar\", exclude=True)\n Name: str\n\nclass Demo(BDCBaseModel):\n example: Union[Foo, Bar] = Field(discriminator=\"type\")\n```\n\nThe following router:\n\n```\n@router.post(\"/demo\")\nasync def demo(\n foo: Foo,\n):\n demo = Demo(example=foo)\n return demo\n```\n\nAnd this is shown in the Swagger docs:\nhttps://i.sstatic.net/hrukJ.png\n\nWe don't want the user to see the type field as it is useless for him/her anyways.\nWe tried making the field private: `_type` which hides it from the docs but then it cannot be used as discriminator anymore:\n\n```\nclass Demo(BDCBaseModel):\n File \"pydantic\\main.py\", line 205, in pydantic.main.ModelMetaclass.__new__\n File \"pydantic\\fields.py\", line 491, in pydantic.fields.ModelField.infer\n File \"pydantic\\fields.py\", line 421, in pydantic.fields.ModelField.__init__\n File \"pydantic\\fields.py\", line 537, in pydantic.fields.ModelField.prepare\n File \"pydantic\\fields.py\", line 639, in pydantic.fields.ModelField._type_analysis\n File \"pydantic\\fields.py\", line 753, in pydantic.fields.ModelField.prepare_discriminated_union_sub_fields\n File \"pydantic\\utils.py\", line 739, in pydantic.utils.get_discriminator_alias_and_values\npydantic.errors.ConfigError: Model 'Foo' needs a discriminator field for key '_type'\n```\n\n========================================\n\nTop Answer:\nThere's a simple and correct way to do it just using annotations\n\n```\nfrom pydantic import BaseModel\nfrom pydantic.json_schema import SkipJsonSchema\n\nclass Bar(BaseModel):\n fiels_a: SkipJsonSchema[str] = Field(exclude=True)\n field_b: str\n```\n\n**field_a** will be excluded from the docs\n\n========================================\n\nCode:\n```text\nclass Foo(BDCBaseModel):\n type: Literal[\"Foo\"] = Field(\"Foo\", exclude=True)\n Name: str\n\nclass Bar(BDCBaseModel):\n type: Literal[\"Bar\"] = Field(\"Bar\", exclude=True)\n Name: str\n\nclass Demo(BDCBaseModel):\n example: Union[Foo, Bar] = Field(discriminator=\"type\")\n```\n\n```text\n@router.post(\"/demo\")\nasync def demo(\n foo: Foo,\n):\n demo = Demo(example=foo)\n return demo\n```\n\n```text\nclass Demo(BDCBaseModel):\n File \"pydantic\\main.py\", line 205, in pydantic.main.ModelMetaclass.__new__\n File \"pydantic\\fields.py\", line 491, in pydantic.fields.ModelField.infer\n File \"pydantic\\fields.py\", line 421, in pydantic.fields.ModelField.__init__\n File \"pydantic\\fields.py\", line 537, in pydantic.fields.ModelField.prepare\n File \"pydantic\\fields.py\", line 639, in pydantic.fields.ModelField._type_analysis\n File \"pydantic\\fields.py\", line 753, in pydantic.fields.ModelField.prepare_discriminated_union_sub_fields\n File \"pydantic\\utils.py\", line 739, in pydantic.utils.get_discriminator_alias_and_values\npydantic.errors.ConfigError: Model 'Foo' needs a discriminator field for key '_type'\n```\n\n```text\ntype\n```\n\n```text\n_type\n```\n\n```py\nfrom typing import Literal, Union\n\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel, Field\n\nclass FooBase(BaseModel):\n name: str\n\nclass FooRequest(FooBase):\n pass # possibly configure other request specific things here\n\nclass Foo(FooBase):\n type: Literal[\"Foo\"] = Field(\"Foo\", exclude=True)\n\n class Config:\n orm_mode = True\n\nclass Bar(BaseModel):\n type: Literal[\"Bar\"] = Field(\"Bar\", exclude=True)\n name: str\n\nclass Demo(BaseModel):\n example: Union[Foo, Bar] = Field(discriminator=\"type\")\n\napi = FastAPI()\n\n@api.post(\"/demo\")\nasync def demo(foo: FooRequest):\n foo = Foo.from_orm(foo)\n return Demo(example=foo)\n```\n\n```text\ntype\n```\n\n```text\nFooBase\n```\n\n```text\nname\n```\n\n```text\nFoo\n```\n\n```text\ntype\n```\n\n```text\nDemo\n```\n\n```text\nFooRequest\n```\n\n```text\norm_mode = True\n```\n\n```text\nFooRequest\n```\n\n```text\nFoo\n```\n\n```text\nfoo = Foo.parse_obj(foo.dict())\n```\n\n```text\nFooRequest\n```\n\n```text\nFooBase\n```\n\n```py\nfrom typing import Any, Literal, Union\n\nfrom fastapi import APIRouter\nfrom pydantic import BaseModel, Field\n\nrouter_demo = APIRouter(prefix=\"/demo\", tags=[\"demo\"])\n\n\nclass BDCBaseModel(BaseModel):\n # ...\n\n class Config:\n\n @staticmethod\n def schema_extra(schema: dict[str, Any], model: type[\"BDCBaseModel\"]) -> None:\n # https://docs.pydantic.dev/1.10/usage/schema/#schema-customization\n properties = schema.get(\"properties\", {})\n if \"type\" in properties:\n del properties[\"type\"]\n\n\nclass Foo(BDCBaseModel):\n type: Literal[\"Foo\"]\n Name: str\n\n\nclass Bar(BDCBaseModel):\n type: Literal[\"Bar\"]\n Name: str\n\n\nclass Demo(BDCBaseModel):\n example: Union[Foo, Bar] = Field(discriminator=\"type\")\n\n\n@router_demo.post(\"/demo\", response_model=Demo)\nasync def demo(\n foo: Foo,\n):\n return Demo(example=foo)\n```\n\n```py\nfrom pydantic import BaseModel\nfrom pydantic.json_schema import SkipJsonSchema\n\n\nclass Bar(BaseModel):\n fiels_a: SkipJsonSchema[str] = Field(exclude=True)\n field_b: str\n```\n\n========================================\n\nComments:\n- possible answer here stackoverflow.com/questions/67911334/…\n- @Anentropic thanks, looks like an option. We will try but it feels kind of hacky. Maybe there is a more sophisticated way?\n- I think you misunderstood the setup. `Foo` is what is sent **to** the API and `Demo` is what is returned. The `type` field on `Foo` is optional with its default (and only possible) value being the string `\"Foo\"`. That is why it makes little sense to force the user to send it along with the `name` field.\n- Exactly what I needed! This should be the accepted answer (for pydantic 2)\n- But using exclude=True will exclude the filed from the serializer not from the docs","metadata":{"transformedAt":"2026-08-18T18:32:29.121Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":21,"totalLines":256,"estimatedTokens":1471}}304{"id":"stack-72560837","source":"stackoverflow","questionId":72560837,"title":"custom fastapi query parameter validation","tags":["python","fastapi"],"text":"Title: custom fastapi query parameter validation\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nIs there any way to have custom validation logic in a FastAPI query parameter?\n\n**example**\n\nI have a `FastAPI` app with a bunch of request handlers taking `Path` components as query parameters. For example:\n\n```\ndef _raise_if_non_relative_path(path: Path):\n if path.is_absolute():\n raise HTTPException(\n status_code=409,\n detail=f\"Absolute paths are not allowed, {path} is absolute.\"\n )\n\n@app.get(\"/new\",)\ndef new_file(where: Path):\n _raise_if_non_relative_path(where)\n # do save a file\n return Response(status_code=requests.codes.ok)\n\n@app.get(\"/new\",)\ndef delete_file(where: Path):\n _raise_if_non_relative_path(where)\n # do save a file\n return Response(status_code=requests.codes.ok)\n```\n\nI was wondering if there is way to ensure that the handler is not even called when the given file path is absolute.\nNow I have to repeat myself with `_raise_if_non_relative_path` everywhere.\n\n**what I tried**\n\n`fastapi.Query`: \n\nThis only allows very basic validation (string length and regex).\nI could define a *absolute path regex* in this example.\nBut a regex solution is really not generic, I want to validate with a custom function.\nSubclass `pathlib.Path` with validation logic in `__init__`: \n\nThis doesn't work, the type given in the type signature is ignored,\nand the object in my handler is a regular `pathlib.PosixPath`.\nUse `@app.middleware`: \n\nthis can work but seems overkill\nsince not all my request handlers deal with `Path` objects.\n`class RelativePath(pydantic.Basemodel)`: \n\nI.e. define a class with single `path` field, which I can validate however I want.\nUnfortunately, this does not work for query parameters.\nIf I do this, the request handler insists on having a json content body.\nOr at least that is what the swagger docs say.\n\n========================================\n\nTop Answer:\n**Note: There is atm still a chance you may be using an older version of Pydantic and there is some chance it will require a modified solution. This is for projects using Pydantic >= 2.0.**\n\nFastAPI uses Pydantic under the hood also for validating parameters not defined as a Pydantic model, and it passes along the extra arguments to `Path()`, `Query()` and `Body()` to the `FieldInfo` object in Pydantic.\n\nThis means you can pass an extra `annotation=` argument to `Query()` and `Path()`, which can then be used to define a custom validator with `AfterValidator()`.\n\n```\nfrom typing import Annotated\nfrom fastapi import APIRouter, Path, Query\n\nrouter = APIRouter(\"/prefix\")\n\n# Define validator according to Pydantic patterns\n# https://docs.pydantic.dev/latest/concepts/validators/\ndef lowercase_validator(value: str) -> str:\n assert value.lower() == value, f\"{value} is not lowercase\"\n return value\n\n# Define route using Path and Query parameters\n# https://fastapi.tiangolo.com/tutorial/path-params-numeric-validations/\n# https://fastapi.tiangolo.com/tutorial/query-params-str-validations/\n@router.get(\"/{path}\")\nasync def some_path(\n path: str = Path(annotation=Annotated[str, AfterValidator(lowercase_validator)]),\n arg: str = Query(annotation=Annotated[str, AfterValidator(lowercase_validator)]),\n):\n pass\n```\n\nThis solution leads to FastAPI directly handling this as a part of the normal validation and returning the same type of `422 Unprocessable Entity` error as all other validation failures.\n\nIn the case of the original question then you would make a validator something like\n\n```\nimport pathlib\ndef validate_relative_path(path: pathlib.Path):\n assert not path.is_absolute(), f\"{path} is not relative\"\n return Path\n```\n\nAnd use it in the route something like\n\n```\n@app.get(\"/new\",)\ndef new_file(where: pathlib.Path = Query(annotation=Annotated[str, AfterValidator(validate_relative_path)])):\n pass\n```\n\n========================================\n\nCode:\n```py\ndef _raise_if_non_relative_path(path: Path):\n if path.is_absolute():\n raise HTTPException(\n status_code=409,\n detail=f\"Absolute paths are not allowed, {path} is absolute.\"\n )\n\n@app.get(\"/new\",)\ndef new_file(where: Path):\n _raise_if_non_relative_path(where)\n # do save a file\n return Response(status_code=requests.codes.ok)\n\n@app.get(\"/new\",)\ndef delete_file(where: Path):\n _raise_if_non_relative_path(where)\n # do save a file\n return Response(status_code=requests.codes.ok)\n```\n\n```text\nFastAPI\n```\n\n```text\nPath\n```\n\n```text\n_raise_if_non_relative_path\n```\n\n```text\nfastapi.Query\n```\n\n```text\npathlib.Path\n```\n\n```text\n__init__\n```\n\n```text\npathlib.PosixPath\n```\n\n```text\n@app.middleware\n```\n\n```text\nPath\n```\n\n```text\nclass RelativePath(pydantic.Basemodel)\n```\n\n```text\npath\n```\n\n```py\nfrom fastapi import Depends, FastAPI, Response, Query\nfrom fastapi.exceptions import HTTPException\nfrom pathlib import Path\nimport requests\n\napp = FastAPI()\n\ndef relative_where_query(where: Path = Query(...)):\n if where.is_absolute():\n raise HTTPException(\n status_code=409,\n detail=f\"Absolute paths are not allowed, {where} is absolute.\"\n )\n \n return where\n \n@app.get(\"/new\")\ndef new_file(where: Path = Depends(relative_where_query)):\n return Response(status_code=requests.codes.ok)\n```\n\n```py\nfrom fastapi import Depends, FastAPI, Response, Query, Request\nfrom fastapi.exceptions import HTTPException\nfrom fastapi.responses import JSONResponse\nfrom pathlib import Path\nfrom pydantic import create_model, validator\nimport requests\n\napp = FastAPI()\n\n\nclass PathNotAbsoluteError(Exception):\n pass\n\n\n@app.exception_handler(PathNotAbsoluteError)\nasync def value_error_exception_handler(request: Request, exc: PathNotAbsoluteError):\n return JSONResponse(\n status_code=400,\n content={\"message\": str(exc)},\n )\n \n\ndef path_is_absolute(cls, value):\n if not value.is_absolute():\n raise PathNotAbsoluteError(\"Given path is not absolute\")\n \n return value\n\n\ndef path_validator(param_name):\n validators = {\n 'pathname_validator': validator(param_name)(path_is_absolute)\n }\n \n return create_model(\n \"AbsolutePathQuery\", \n **{param_name: (Path, Query(...))},\n __validators__=validators,\n )\n\n\n@app.get(\"/path\")\ndef new_file(path: Path = Depends(path_validator(\"where\"))):\n return Response(status_code=requests.codes.ok)\n```\n\n```py\ndef new_file(path: Path = Depends(path_validator(\"my_path\"))):\n ...\n\ndef old_file(path: Path = Depends(path_validator(\"where\"))):\n ...\n```\n\n```text\nDepends\n```\n\n```text\nrelative_where_query\n```\n\n```text\nwhere\n```\n\n```text\nwhere\n```\n\n```text\npath_validator\n```\n\n```text\ncreate_model\n```\n\n```text\npath\n```\n\n```py\nfrom typing import Annotated\nfrom fastapi import APIRouter, Path, Query\n\nrouter = APIRouter(\"/prefix\")\n\n\n# Define validator according to Pydantic patterns\n# https://docs.pydantic.dev/latest/concepts/validators/\ndef lowercase_validator(value: str) -> str:\n assert value.lower() == value, f\"{value} is not lowercase\"\n return value\n\n\n# Define route using Path and Query parameters\n# https://fastapi.tiangolo.com/tutorial/path-params-numeric-validations/\n# https://fastapi.tiangolo.com/tutorial/query-params-str-validations/\n@router.get(\"/{path}\")\nasync def some_path(\n path: str = Path(annotation=Annotated[str, AfterValidator(lowercase_validator)]),\n arg: str = Query(annotation=Annotated[str, AfterValidator(lowercase_validator)]),\n):\n pass\n```\n\n```py\nimport pathlib\ndef validate_relative_path(path: pathlib.Path):\n assert not path.is_absolute(), f\"{path} is not relative\"\n return Path\n```\n\n```py\n@app.get(\"/new\",)\ndef new_file(where: pathlib.Path = Query(annotation=Annotated[str, AfterValidator(validate_relative_path)])):\n pass\n```\n\n```text\nPath()\n```\n\n```text\nQuery()\n```\n\n```text\nBody()\n```\n\n```text\nFieldInfo\n```\n\n```text\nannotation=\n```\n\n```text\nQuery()\n```\n\n```text\nPath()\n```\n\n```text\nAfterValidator()\n```\n\n```text\n422 Unprocessable Entity\n```\n\n========================================\n\nComments:\n- Thanks, this works. I knew about dependencies but somehow I was locked in the mindset that they were meant for accessing external resources like databases and such.\n- After a while it clicks and you see how much you actually can describe as \"this function depends on ..\" and get very compact view functions. It's a powerful feature.\n- It's a real shame that this solution requires all parameters using `relative_where_query` to be called `where`. No other name is possible. There doesn't seem to be a way to apply `Depends` validators to routes which have differently-named query params.\n- Sure there is - you can use `create_model` from Pydantic to create a dynamic dependency. I'll add an example.\n- Instead of using the \"422 Unprocessable Entity\" responses, this now returns some specific error for this validation failure, which is undesirable.\n- @JanneEnberg OPs question used 409 as the response code explicitly, which is why this example is based on using that. Thank you for your answer showing how to return the common 422 error.","metadata":{"transformedAt":"2026-08-18T18:32:29.121Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":34,"totalLines":364,"estimatedTokens":2269}}305{"id":"stack-69934160","source":"stackoverflow","questionId":69934160,"title":"Python - How to manipulate FastAPI request headers to be mutable?","tags":["python-3.x","fastapi"],"text":"Title: Python - How to manipulate FastAPI request headers to be mutable?\nTags: python-3.x, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to change my request headers in my api code. Its immutable right now oob with fastapi starlette. how can i change it so my request headers are mutable? i would like to add, remove, and delete request headers. i tried to instantiate a new request and directly modify the request using\n\n```\nrequest.headers[\"authorization\"] = \"XXXXXX\"\n```\n\nbut I get the following error\n\n```\nTypeError: ‘Headers’ object does not support item assignment\n```\n\nThanks!\n\n========================================\n\nCode:\n```text\nrequest.headers[\"authorization\"] = \"XXXXXX\"\n```\n\n```text\nTypeError: ‘Headers’ object does not support item assignment\n```\n\n```text\nfrom starlette.datastructures import MutableHeaders\nfrom fastapi import Request \n\n@router.get(\"/test\")\ndef test(request: Request):\n new_header = MutableHeaders(request._headers)\n new_header[\"xxxxx\"]=\"XXXXX\"\n request._headers = new_header\n request.scope.update(headers=request.headers.raw)\n print(request.headers)\n return {}\n```\n\n```text\nMutableHeaders({'host': '127.0.0.1:8001', 'user-agent': 'insomnia/2021.5.3', 'content-type': 'application/json', 'authorization': '', 'accept': '*/*', 'content-length': '633', 'xxxxx': 'XXXXX'})\n```\n\n========================================\n\nComments:\n- It might be added that this will not update the scope attribute of the Request-object. For that to happen the update member function has to be called `request.scope.update(headers=request.headers.raw)`\n- The above response is useless without your suggestion for the `scope` update. Thank you!\n- This doesn't Work.\n- Really, author, please, consider adding the @F.Sonntag suggestion to the answer, otherwise it doesn't work...\n- This code is written in an odd way. I'd recommend using the mutablecopy() method on request.headers to make the copy: `request.headers.mutablecopy()`. I'd recommend updating the scope FIRST: `request.scope['headers'] = new_header.raw`, then deleting the `_headers` attribute, so it's recreated when request.headers is called: `delattr(request, '_headers')`.","metadata":{"transformedAt":"2026-08-18T18:32:29.121Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":56,"estimatedTokens":546}}306{"id":"stack-71396605","source":"stackoverflow","questionId":71396605,"title":"How can I specify several examples for the FastAPI docs when response_model is a list of models?","tags":["python","openapi","fastapi","pydantic"],"text":"Title: How can I specify several examples for the FastAPI docs when response_model is a list of models?\nTags: python, openapi, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI am writing a FastAPI app in python and I would like to use the openapi docs which are automatically generated. In particular, I would like to specify examples for the response value. I know how to do it when the `response_model` is a class that inherits from pydantic's `BaseModel`, but I am having trouble when it is a list of such classes. Here's a minimal example:\n\n```\nfrom fastapi import FastAPI\n\nfrom typing import List\nfrom pydantic import BaseModel, Field\n\nclass Person(BaseModel):\n name: str = Field(\n ...,\n title=\"Name\",\n description=\"The name of the person\",\n example=\"Alice\"\n )\n\n age: int = Field(\n ...,\n title=\"Age\",\n description=\"The age of the person\",\n example=83\n )\n\n class Config:\n schema_extra = {\n 'examples': [\n {\n \"name\": \"Alice\",\n \"age\": 83\n },\n {\n \"name\": \"Bob\",\n \"age\": 77\n }\n ]\n }\n\napp = FastAPI()\n\n@app.get('/person', response_model=Person)\ndef person():\n return {\n \"name\": \"Alice\",\n \"age\": 83\n }\n\n@app.get('/people', response_model=List[Person])\ndef people():\n return [\n {\n \"name\": \"Alice\",\n \"age\": 83\n },\n {\n \"name\": \"Bob\",\n \"age\": 77\n }\n ]\n```\n\nIn the automatically generated openapi docs, the example value for a successful response for `/person` is\n\n```\n{\n \"name\": \"Alice\",\n \"age\": 83\n}\n```\n\nwhich is what I want. However, for `/people` it is\n\n```\n[\n {\n \"name\": \"Alice\",\n \"age\": 83\n }\n]\n```\n\nbut I would prefer for it to be\n\n```\n[\n {\n \"name\": \"Alice\",\n \"age\": 83\n },\n {\n \"name\": \"Bob\",\n \"age\": 77\n }\n]\n```\n\nIs there any way to achieve that? Thank you in advance!\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\n\nfrom typing import List\nfrom pydantic import BaseModel, Field\n\n\nclass Person(BaseModel):\n name: str = Field(\n ...,\n title=\"Name\",\n description=\"The name of the person\",\n example=\"Alice\"\n )\n\n age: int = Field(\n ...,\n title=\"Age\",\n description=\"The age of the person\",\n example=83\n )\n\n class Config:\n schema_extra = {\n 'examples': [\n {\n \"name\": \"Alice\",\n \"age\": 83\n },\n {\n \"name\": \"Bob\",\n \"age\": 77\n }\n ]\n }\n\n\napp = FastAPI()\n\n\n@app.get('/person', response_model=Person)\ndef person():\n return {\n \"name\": \"Alice\",\n \"age\": 83\n }\n\n\n@app.get('/people', response_model=List[Person])\ndef people():\n return [\n {\n \"name\": \"Alice\",\n \"age\": 83\n },\n {\n \"name\": \"Bob\",\n \"age\": 77\n }\n ]\n```\n\n```text\n{\n \"name\": \"Alice\",\n \"age\": 83\n}\n```\n\n```text\n[\n {\n \"name\": \"Alice\",\n \"age\": 83\n }\n]\n```\n\n```text\n[\n {\n \"name\": \"Alice\",\n \"age\": 83\n },\n {\n \"name\": \"Bob\",\n \"age\": 77\n }\n]\n```\n\n```text\nresponse_model\n```\n\n```text\nBaseModel\n```\n\n```text\n/person\n```\n\n```text\n/people\n```\n\n```text\n@app.get('/people', response_model=List[Person], responses={\n 200: {\n \"description\": \"People successfully found\",\n \"content\": {\n \"application/json\": {\n \"example\": [\n {\n \"name\": \"Alice\",\n \"age\": 83\n },\n {\n \"name\": \"Bob\",\n \"age\": 77\n }\n ]\n }\n }\n },\n 404: {\"description\": \"People not found\"}\n})\ndef people():\n return [\n {\n \"name\": \"Alice\",\n \"age\": 83\n },\n {\n \"name\": \"Bob\",\n \"age\": 77\n }\n ]\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.121Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":245,"estimatedTokens":953}}307{"id":"stack-67307159","source":"stackoverflow","questionId":67307159,"title":"What is the actual use of OAuth2PasswordBearer?","tags":["python","oauth-2.0","fastapi"],"text":"Title: What is the actual use of OAuth2PasswordBearer?\nTags: python, oauth-2.0, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am new to `fastapi`. I was trying to implement an authentication feature in it. It uses `OAuth2PasswordBearer` for that. I do not actually understand what's the use of this if I can simply get the username and password as a post request and match it with my database. Please explain this.\n\n========================================\n\nTop Answer:\n`OAuth2PasswordBearer` is a class in FastAPI that is used for handling security and authentication in your application using the OAuth2 Password Flow.\n\nAs shown in the official documentation, here's a simple example of how it's used:\n\n```\nfrom fastapi import Depends, FastAPI, HTTPException, status\nfrom fastapi.security import OAuth2PasswordBearer\n\napp = FastAPI()\n\noauth2_scheme = OAuth2PasswordBearer(tokenUrl=\"token\")\n\n@app.get(\"/items/\")\nasync def read_items(token: str = Depends(oauth2_scheme)):\n return {\"token\": token}\n```\n\nIn this example, `OAuth2PasswordBearer` is used to declare a dependency that will be used in a route.\n\nWhen a client requests this route, FastAPI will check for a `Authorization: Bearer xxx` header, extract the token xxx, and pass it as the token parameter to the route.\n\nThe `tokenUrl=\"token\"` argument is the URL that the client (like a frontend) will use to send the username and password to get a token.\n\nThis information is used in the OpenAPI schema and user interface.\n\nNote that `OAuth2PasswordBearer` does not check the token or verify it against a database, it only checks that the token is included in the request. The verification of the token is usually done in the dependency.\n\n========================================\n\nCode:\n```text\nfastapi\n```\n\n```text\nOAuth2PasswordBearer\n```\n\n```text\noauth2_scheme = OAuth2PasswordBearer(tokenUrl='login')\n```\n\n```text\n{\"access_token\": access_token, \"token_type\":\"bearer\"}\n```\n\n```text\nget_current_user\n```\n\n```text\nsecrete_key(private)\n```\n\n```py\nfrom fastapi import Depends, FastAPI, HTTPException, status\nfrom fastapi.security import OAuth2PasswordBearer\n\napp = FastAPI()\n\noauth2_scheme = OAuth2PasswordBearer(tokenUrl=\"token\")\n\n@app.get(\"/items/\")\nasync def read_items(token: str = Depends(oauth2_scheme)):\n return {\"token\": token}\n```\n\n```text\nOAuth2PasswordBearer\n```\n\n```text\nOAuth2PasswordBearer\n```\n\n```text\nAuthorization: Bearer xxx\n```\n\n```text\ntokenUrl=\"token\"\n```\n\n```text\nOAuth2PasswordBearer\n```\n\n========================================\n\nComments:\n- It is generally not a good idea to just pass username and password around, so tokens that have limit powers are used. Read up on OAuth2 here\n- so is it that the user token generated at successful login is used throughout the application? So that it keeps track of which user is logged in?\n- Not really, I suggest you read that documentation I sent you to get a feel for how the entire system works.\n- Suggest read: Cookie-based vs Session vs Token-based vs Claims-based authentications\n- I just want to note about tokenUrl='login': this used only in the automatic docs. More info here.\n- If the header does not have an `Authorization: Bearer xxx` record, will FastAPI automatically raise `status.HTTP_401_UNAUTHORIZE`, or does it just populate the `token` variable as `None`?\n- @StefanMusarra Yes, FasAPI will raise the following: `raise HTTPException(` ` status_code=HTTP_401_UNAUTHORIZED,` ` detail=\"Not authenticated\",` ` headers={\"WWW-Authenticate\": \"Bearer\"},` `)` More code relevant to this case can be found in `/fastapi/security/oauth2.py` PS Not sure why formatting is not working, sorry.","metadata":{"transformedAt":"2026-08-18T18:32:29.121Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":12,"totalLines":107,"estimatedTokens":908}}308{"id":"stack-67947099","source":"stackoverflow","questionId":67947099,"title":"Send / receive in parallel using websockets in Python FastAPI","tags":["python","websocket","python-asyncio","fastapi"],"text":"Title: Send / receive in parallel using websockets in Python FastAPI\nTags: python, websocket, python-asyncio, fastapi\nSource: Stack Overflow\n\nQuestion:\nI will try to explain what I am doing with an example, say I am building a weather client. The browser sends a message over websocket, eg:\n\n```\n{\n \"city\": \"Chicago\",\n \"country\": \"US\"\n}\n```\n\nThe server queries the weather every 5 minutes and updates the browser back with the latest data.\n\nNow the browser could send another message, eg:\n\n```\n{\n \"city\": \"Bangalore\",\n \"country\": \"IN\"\n}\n```\n\nNow I the server should STOP updating the weather details of Chicago and start updating the details about Bangalore, i.e. simultaneously send / receive messages over websocket. How should I go about implementing this?\n\nCurrently I have this but this only updates the browser on receiving an event:\n\n```\n@app.websocket(\"/ws\")\nasync def read_webscoket(websocket: WebSocket):\n await websocket.accept()\n weather_client = WeatherClient(client)\n while True:\n data = await websocket.receive_json()\n weather = await weather_client.weather(data)\n await websocket.send_json(weather.dict())\n```\n\nIf I move `websocket.receive_json()` outside the loop, I won't be able to continuously listen to the message from browser. I guess I need to spin up two asyncio tasks but I am not quite able to nail down the implementation since I am new to asynchronous way of programming.\n\n========================================\n\nTop Answer:\n```\nasync def send_message(item:formated):\n \"\"\"\n concurrently to all clients with a per-client timeout,\n then remove any clients that failed.\n \"\"\"\n if not connected:\n return\n\n payload = convert_into_json(item)\n ws_list = list(connected) # snapshot\n\n async def _send(ws: WebSocket):\n try:\n # per-client timeout so a slow client doesn't block others separate coroutines\n await asyncio.wait_for(ws.send_json(payload), timeout=2.0)\n return True, ws\n except Exception:\n return False, ws\n\n # run sends concurrently\n results = await asyncio.gather(*(_send(ws) for ws in ws_list), return_exceptions=False)\n\n # cleanup failed clients\n for ok, ws in results:\n if not ok:\n connected.discard(ws)\n```\n\n========================================\n\nCode:\n```json\n{\n \"city\": \"Chicago\",\n \"country\": \"US\"\n}\n```\n\n```json\n{\n \"city\": \"Bangalore\",\n \"country\": \"IN\"\n}\n```\n\n```py\n@app.websocket(\"/ws\")\nasync def read_webscoket(websocket: WebSocket):\n await websocket.accept()\n weather_client = WeatherClient(client)\n while True:\n data = await websocket.receive_json()\n weather = await weather_client.weather(data)\n await websocket.send_json(weather.dict())\n```\n\n```text\nwebsocket.receive_json()\n```\n\n```text\n@app.websocket(\"/ws\")\nasync def read_webscoket(websocket: WebSocket):\n await websocket.accept()\n json_data = await websocket.receive_json()\n\n async def read_from_socket(websocket: WebSocket):\n nonlocal json_data\n async for data in websocket.iter_json():\n json_data = data\n\n asyncio.create_task(read_from_socket(websocket))\n while True:\n print(f\"getting weather data for {json_data}\")\n await asyncio.sleep(1) # simulate a slow call to the weather service\n```\n\n```text\n@app.websocket(\"/wsqueue\")\nasync def read_webscoket(websocket: WebSocket):\n await websocket.accept()\n queue = asyncio.queues.Queue()\n\n async def read_from_socket(websocket: WebSocket):\n async for data in websocket.iter_json():\n print(f\"putting {data} in the queue\")\n queue.put_nowait(data)\n\n async def get_data_and_send():\n data = await queue.get()\n while True:\n if queue.empty():\n print(f\"getting weather data for {data}\")\n await asyncio.sleep(1)\n else:\n data = queue.get_nowait()\n print(f\"Setting data to {data}\")\n\n await asyncio.gather(read_from_socket(websocket), get_data_and_send())\n```\n\n```text\nasync def read_and_send_to_client(data):\n print(f'reading {data} from client')\n await asyncio.sleep(10) # simulate a slow call\n print(f'finished reading {data}, sending to websocket client')\n\n\n@app.websocket(\"/wsqueue\")\nasync def read_webscoket(websocket: WebSocket):\n await websocket.accept()\n queue = asyncio.queues.Queue()\n\n async def read_from_socket(websocket: WebSocket):\n async for data in websocket.iter_json():\n print(f\"putting {data} in the queue\")\n queue.put_nowait(data)\n\n async def get_data_and_send():\n data = await queue.get()\n fetch_task = asyncio.create_task(read_and_send_to_client(data))\n while True:\n data = await queue.get()\n if not fetch_task.done():\n print(f'Got new data while task not complete, canceling.')\n fetch_task.cancel()\n fetch_task = asyncio.create_task(read_and_send_to_client(data))\n\n await asyncio.gather(read_from_socket(websocket), get_data_and_send())\n```\n\n```text\niter_json\n```\n\n```text\nreceive_json\n```\n\n```text\ngather\n```\n\n```text\nread_and_send_to_client\n```\n\n```text\nasync def send_message(item:formated):\n \"\"\"\n concurrently to all clients with a per-client timeout,\n then remove any clients that failed.\n \"\"\"\n if not connected:\n return\n\n payload = convert_into_json(item)\n ws_list = list(connected) # snapshot\n\n async def _send(ws: WebSocket):\n try:\n # per-client timeout so a slow client doesn't block others separate coroutines\n await asyncio.wait_for(ws.send_json(payload), timeout=2.0)\n return True, ws\n except Exception:\n return False, ws\n\n # run sends concurrently\n results = await asyncio.gather(*(_send(ws) for ws in ws_list), return_exceptions=False)\n\n # cleanup failed clients\n for ok, ws in results:\n if not ok:\n connected.discard(ws)\n```\n\n========================================\n\nComments:\n- Awesome! This is almost exactly what I was looking for and I was so close. However, there is one more thing, say we send data back and sleep for 10 seconds before sending updated data and in between, we receive a message. Right now what would happen is we would still need to wait for the sleep to get over. How can I call `notify` or `cancel` on that thread to wake up as soon as I receive a new message? I also didn't know just doing `create_task` would be enough and that we don't need to do `asyncio.gather` on top of it. I need to read more about `asyncio`. Thanks!\n- @mohitmayank you'll need to create a task of the long operation you want to cancel and then call cancel if it is not done. Updated the answer to show how to do this.\n- As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.\n- Please don't post code-only answers. The main audience, future readers, will be grateful to see explained *why* this answers the question instead of having to infer it from the code. Also, it's helpful to explain how it complements the other answer.","metadata":{"transformedAt":"2026-08-18T18:32:29.121Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":12,"totalLines":229,"estimatedTokens":1794}}309{"id":"stack-72978364","source":"stackoverflow","questionId":72978364,"title":"ModuleNotFoundError: No module named 'httpx'","tags":["python-3.x","fastapi","uvicorn","httpx"],"text":"Title: ModuleNotFoundError: No module named 'httpx'\nTags: python-3.x, fastapi, uvicorn, httpx\nSource: Stack Overflow\n\nQuestion:\nGetting above error have installing the correct package\n\nPython --version\n\n**Python 3.6.9**\n\nInstall command\n\n**pip3 install httpx**\n\n**pip3 list**\n\n```\nanyio (3.6.1)\nasync-generator (1.10)\nBrotli (1.0.9)\ncertifi (2022.6.15)\ncharset-normalizer (2.1.0)\ncontextvars (2.4)\ndataclasses (0.8)\ndnspython (2.2.1)\nemail-validator (1.2.1)\nh11 (0.12.0)\nhttpcore (0.14.7)\nhttpx (0.22.0)\nidna (3.3)\nimmutables (0.18)\nMarkupSafe (2.0.1)\npip (9.0.1)\npkg-resources (0.0.0)\npydantic (1.9.1)\npython-dateutil (2.8.2)\nrfc3986 (1.5.0)\nsetuptools (39.0.1)\nsix (1.16.0)\nsniffio (1.2.0)\ntyping-extensions (4.1.1)\nvalidator (0.7.1)\n```\n\nIn virtual environment interactive shell the package is also working\n\n```\n(env) PEOPLE\\saurabhkamble@lp7948:/var/www/vip_select_shaadi_api$ uvicorn main:app --reload\n INFO: Will watch for changes in these directories: ['/var/www/vip_select_shaadi_api']\n INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\n INFO: Started reloader process [15073] using statreload\n None\n Process SpawnProcess-1:\n Traceback (most recent call last):\n File \"/usr/lib/python3.6/multiprocessing/process.py\", line 258, in _bootstrap\n self.run()\n File \"/usr/lib/python3.6/multiprocessing/process.py\", line 93, in run\n self._target(*self._args, **self._kwargs)\n File \"/home/saurabhkamble/.local/lib/python3.6/site-packages/uvicorn/subprocess.py\", line 76, in subprocess_started\n target(sockets=sockets)\n File \"/home/saurabhkamble/.local/lib/python3.6/site-packages/uvicorn/server.py\", line 69, in run\n return asyncio.get_event_loop().run_until_complete(self.serve(sockets=sockets))\n File \"/usr/lib/python3.6/asyncio/base_events.py\", line 484, in run_until_complete\n return future.result()\n File \"/home/saurabhkamble/.local/lib/python3.6/site-packages/uvicorn/server.py\", line 76, in serve\n config.load()\n File \"/home/saurabhkamble/.local/lib/python3.6/site-packages/uvicorn/config.py\", line 456, in load\n self.loaded_app = import_from_string(self.app)\n File \"/home/saurabhkamble/.local/lib/python3.6/site-packages/uvicorn/importer.py\", line 24, in import_from_string\n raise exc from None\n File \"/home/saurabhkamble/.local/lib/python3.6/site-packages/uvicorn/importer.py\", line 21, in import_from_string\n module = importlib.import_module(module_str)\n File \"/usr/lib/python3.6/importlib/__init__.py\", line 126, in import_module\n return _bootstrap._gcd_import(name[level:], package, level)\n File \"\", line 994, in _gcd_import\n File \"\", line 971, in _find_and_load\n File \"\", line 955, in _find_and_load_unlocked\n File \"\", line 665, in _load_unlocked\n File \"\", line 678, in exec_module\n File \"\", line 219, in _call_with_frames_removed\n File \"./main.py\", line 3, in \n from routes.member import routes_member\n File \"./routes/member.py\", line 5, in \n from api import universities\n File \"./api/universities.py\", line 3, in \n import httpx\n ModuleNotFoundError: No module named 'httpx'\n INFO: Stopping reloader process [15073]\n```\n\nhttps://i.sstatic.net/sTxxT.png\n\nError when running Fastapi on local\n\n```\n(env) PEOPLE\\saurabhkamble@lp7948:/var/www/vip_select_shaadi_api$ python3\nPython 3.6.9 (default, Mar 15 2022, 13:55:28) \n[GCC 8.4.0] on linux\nType \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n>>> import httpx\n>>> r = httpx.get('https://www.example.org/')\n^[[Ar\n\n```\n\nhttps://i.sstatic.net/x5idL.png\n\n========================================\n\nTop Answer:\nHad the same error message, this solved it for me\n\n```\npip3 install httpx\n```\n\n========================================\n\nCode:\n```text\nanyio (3.6.1)\nasync-generator (1.10)\nBrotli (1.0.9)\ncertifi (2022.6.15)\ncharset-normalizer (2.1.0)\ncontextvars (2.4)\ndataclasses (0.8)\ndnspython (2.2.1)\nemail-validator (1.2.1)\nh11 (0.12.0)\nhttpcore (0.14.7)\nhttpx (0.22.0)\nidna (3.3)\nimmutables (0.18)\nMarkupSafe (2.0.1)\npip (9.0.1)\npkg-resources (0.0.0)\npydantic (1.9.1)\npython-dateutil (2.8.2)\nrfc3986 (1.5.0)\nsetuptools (39.0.1)\nsix (1.16.0)\nsniffio (1.2.0)\ntyping-extensions (4.1.1)\nvalidator (0.7.1)\n```\n\n```text\n(env) PEOPLE\\saurabhkamble@lp7948:/var/www/vip_select_shaadi_api$ uvicorn main:app --reload\n INFO: Will watch for changes in these directories: ['/var/www/vip_select_shaadi_api']\n INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\n INFO: Started reloader process [15073] using statreload\n None\n Process SpawnProcess-1:\n Traceback (most recent call last):\n File \"/usr/lib/python3.6/multiprocessing/process.py\", line 258, in _bootstrap\n self.run()\n File \"/usr/lib/python3.6/multiprocessing/process.py\", line 93, in run\n self._target(*self._args, **self._kwargs)\n File \"/home/saurabhkamble/.local/lib/python3.6/site-packages/uvicorn/subprocess.py\", line 76, in subprocess_started\n target(sockets=sockets)\n File \"/home/saurabhkamble/.local/lib/python3.6/site-packages/uvicorn/server.py\", line 69, in run\n return asyncio.get_event_loop().run_until_complete(self.serve(sockets=sockets))\n File \"/usr/lib/python3.6/asyncio/base_events.py\", line 484, in run_until_complete\n return future.result()\n File \"/home/saurabhkamble/.local/lib/python3.6/site-packages/uvicorn/server.py\", line 76, in serve\n config.load()\n File \"/home/saurabhkamble/.local/lib/python3.6/site-packages/uvicorn/config.py\", line 456, in load\n self.loaded_app = import_from_string(self.app)\n File \"/home/saurabhkamble/.local/lib/python3.6/site-packages/uvicorn/importer.py\", line 24, in import_from_string\n raise exc from None\n File \"/home/saurabhkamble/.local/lib/python3.6/site-packages/uvicorn/importer.py\", line 21, in import_from_string\n module = importlib.import_module(module_str)\n File \"/usr/lib/python3.6/importlib/__init__.py\", line 126, in import_module\n return _bootstrap._gcd_import(name[level:], package, level)\n File \"<frozen importlib._bootstrap>\", line 994, in _gcd_import\n File \"<frozen importlib._bootstrap>\", line 971, in _find_and_load\n File \"<frozen importlib._bootstrap>\", line 955, in _find_and_load_unlocked\n File \"<frozen importlib._bootstrap>\", line 665, in _load_unlocked\n File \"<frozen importlib._bootstrap_external>\", line 678, in exec_module\n File \"<frozen importlib._bootstrap>\", line 219, in _call_with_frames_removed\n File \"./main.py\", line 3, in <module>\n from routes.member import routes_member\n File \"./routes/member.py\", line 5, in <module>\n from api import universities\n File \"./api/universities.py\", line 3, in <module>\n import httpx\n ModuleNotFoundError: No module named 'httpx'\n INFO: Stopping reloader process [15073]\n```\n\n```text\n(env) PEOPLE\\saurabhkamble@lp7948:/var/www/vip_select_shaadi_api$ python3\nPython 3.6.9 (default, Mar 15 2022, 13:55:28) \n[GCC 8.4.0] on linux\nType \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n>>> import httpx\n>>> r = httpx.get('https://www.example.org/')\n^[[Ar\n<Response [200 OK]>\n```\n\n```text\nuvicorn\n```\n\n```text\n(env)\n```\n\n```text\n~/.local\n```\n\n```text\nuvicorn\n```\n\n```text\nenv\n```\n\n```text\npip uninstall --user -y uvicorn\n```\n\n```text\nenv\n```\n\n```text\npip install uvicorn\n```\n\n```text\npip list --user\n```\n\n```text\nPIP_REQUIRE_VIRTUALENV=false\n```\n\n```text\npip3 install httpx\n```\n\n========================================\n\nComments:\n- perfect answer had install uvicorn and then changed virtual env and again created new env which caused this issue\n- `pip install httpx` Seems like a lazy answer doesn't it? Well, the creator of fastapi said it github.com/tiangolo/fastapi/discussions/…","metadata":{"transformedAt":"2026-08-18T18:32:29.121Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":14,"totalLines":252,"estimatedTokens":1926}}310{"id":"stack-70265343","source":"stackoverflow","questionId":70265343,"title":"python fastAPI Server. How to extend connection timeout","tags":["python","fastapi"],"text":"Title: python fastAPI Server. How to extend connection timeout\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm using fastAPI python framework to build a simple POST/GET https server.\nOn the client side, i send heartbeat POST messages every 10 seconds and i'd like to keep my connection open during this period.\n\nHowever, for some reason I see that every new heartbeat, my connection get disconnected by the peer, so I need to re-establish it. If the idle period between 2 consecutive keepalives is 1 second, the Connection remains active, and can be reused.\n\nI'm using `HTTP/1.1` with `Connection: keep-alive`, but it is entirely up to the server how long it will keep the connection alive, and I'm looking for a way to extend this timeout to ~15 seconds. is there any suitable way to do it ? or even just make the server print proper log message when it decide to disconnect the client peer ...\n\nP.S. in order to start the server I'm using the following command, Perhaps it need to be modified ?\n\n```\nuvicorn main:app --port 44444 --host 0.0.0.0 --reload --ssl-keyfile ./key.pem \n--ssl-certfile ./certificate.pem --log-level debug\n```\n\n========================================\n\nTop Answer:\nIn addition to the accepted answer, if you want to add the timeout programmatically, you should use something like:\n\n```\nuvicorn.run(app, host=\"YOUR_HOST\", port=YOUR_PORT, timeout_keep_alive=YOUR_TIMEOUT_IN_SECONDS)\n```\n\n========================================\n\nCode:\n```text\nuvicorn main:app --port 44444 --host 0.0.0.0 --reload --ssl-keyfile ./key.pem \n--ssl-certfile ./certificate.pem --log-level debug\n```\n\n```text\nHTTP/1.1\n```\n\n```text\nConnection: keep-alive\n```\n\n```text\n--timeout-keep-alive <int> - Close Keep-Alive connections if no new data is received within this timeout. Default: 5.\n```\n\n```text\nuvicorn.run(app, host=\"YOUR_HOST\", port=YOUR_PORT, timeout_keep_alive=YOUR_TIMEOUT_IN_SECONDS)\n```\n\n========================================\n\nComments:\n- I'd like to keep the connection open in order to reuse it, instead of create a new one for each heartbeat. isn't it a good practice ? why ?\n- Opening and closing connections is a lot of what webservers do, so, if you are worrying about resources, don‘t. I would be much more worried about 10-minute-zombie-connections. I‘m not an expert on this but 5 seconds seems like a sensible default. You need a good reason to crank this up to 10 minutes.\n- ok, I meant 10-15 seconds sorry, is this an acceptable timeout ?\n- I cannot answer that, sorry. It depends on your application, expected load etc. But if it is important to you to have a long lived connection, maybe look into websockets. FastAPI supports them natively, I think.","metadata":{"transformedAt":"2026-08-18T18:32:29.121Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":5,"totalLines":59,"estimatedTokens":673}}311{"id":"stack-64323261","source":"stackoverflow","questionId":64323261,"title":"How does FastAPI's application mounting works?","tags":["python","plugins","middleware","fastapi","starlette"],"text":"Title: How does FastAPI's application mounting works?\nTags: python, plugins, middleware, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nFor certain reasons, we have chosen the FastAPI, in order to use it as back-end tier of our multi-module production. One of its attractive features is sub application, that helps us to separate different modules with intention of making it more modular. But we are ***concerned*** about some possible deficiencies which are missing in the official documentation. There are a considerable amount of common things -- e.g data, services, etc -- that we need to them between main module and submodule through plugins, middle-wares and dependency-injection. The questions are: **Is this feature good enough for separate modules?** and so: **Do sub applications inherit middle-ware, plugins and dependency injection from parent app?**\n\n*thanks for sharing your experiences.*\n\nthe sample code in the official docs\n\n```\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/app\")\ndef read_main():\n return {\"message\": \"Hello World from main app\"}\n\nsubapi = FastAPI()\n\n@subapi.get(\"/sub\")\ndef read_sub():\n return {\"message\": \"Hello World from sub API\"}\n\napp.mount(\"/subapi\", subapi)\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n\n@app.get(\"/app\")\ndef read_main():\n return {\"message\": \"Hello World from main app\"}\n\n\nsubapi = FastAPI()\n\n\n@subapi.get(\"/sub\")\ndef read_sub():\n return {\"message\": \"Hello World from sub API\"}\n\n\napp.mount(\"/subapi\", subapi)\n```\n\n```text\n[{\"path\":route.path} for route in subapi.routes] = [\n {'path': '/openapi.json'},\n {'path': '/docs'},\n {'path': '/docs/oauth2-redirect'},\n {'path': '/redoc'},\n {'path': '/sub'}\n ]\n```\n\n```text\n[{\"path\":route.path} for route in app.routes] = [{'path': '/openapi.json'},\n {'path': '/docs'},\n {'path': '/docs/oauth2-redirect'},\n {'path': '/redoc'},\n {'path': '/app'},\n {'path': '/subapi'}\n ]\n```\n\n```text\nuvicorn my_app_name:app\n```\n\n```text\nsubapi.mount(\"/app\", app)\n```\n\n```text\nuvicorn my_app_name:subapi\n```\n\n```text\ncurl http://127.0.0.1:8000/app/subapi/sub\n\nOut: {\"message\":\"Hello World from sub API\"}\n```\n\n```text\ncurl http://127.0.0.1:8000/app/subapi/app/subapi/app/subapi/app/subapi/app/subapi/app/app\n\nOut: {\"message\":\"Hello World from main app\"}\n```\n\n```text\n/app/\n```\n\n```text\n/app/subapi/\n```\n\n```text\n/app/subapi/app\n```\n\n```text\nfrom fastapi.middleware.cors import CORSMiddleware\n\nsubapi.add_middleware(CORSMiddleware)\n```\n\n```text\nsubapi.__dict__['user_middleware'] = [Middleware(CORSMiddleware)]\napp.__dict__['user_middleware'] = []\n```\n\n```text\n/app\n```\n\n```text\n/docs\n```\n\n```text\n/subapi/docs\n```\n\n```text\n/docs\n```\n\n```text\n/app/docs\n```\n\n```text\n/app/subapi/sub\n```\n\n```text\nuvicorn my_app_name:subapi\n```\n\n```text\n/app/subapi/app/subapi/app/subapi/app/subapi/app/subapi/app/app\n```\n\n```text\nroot_path\n```\n\n```text\nroot_path\n```\n\n```text\nroot_path\n```\n\n```text\napp.routes\n```\n\n```text\nroot_path\n```\n\n```text\nroot_path\n```\n\n```text\n/app\n```\n\n```text\nroot_path\n```\n\n```text\nroot_path\n```\n\n```text\n__dict__\n```\n\n========================================\n\nComments:\n- Future readers might find this answer and this answer helpful as well.\n- thanks a lot for your complete answer. I could lesson more than what I asked from your answer indeed. it seems I should pack my dependancies in order to inject them in each of sub apps separately.\n- You are welcome! I'm glad it helped. Yes it's pretty useful in some cases, I don't exactly know what is your use case but, it seems you want to use a lot of middleware and dependency injection, maybe you should consider creating your own APIRouter class\n- It seems good suggestion. it can integrate most of middle wares I will try ti out. thanks once more.","metadata":{"transformedAt":"2026-08-18T18:32:29.121Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":31,"totalLines":200,"estimatedTokens":956}}312{"id":"stack-63614660","source":"stackoverflow","questionId":63614660,"title":"Testing FastAPI FormData Upload","tags":["python","upload","fastapi"],"text":"Title: Testing FastAPI FormData Upload\nTags: python, upload, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm trying to test the upload of a file and its metadata using **Python** and **FastAPI**.\n\nHere is how I defined the route for the upload:\n\n```\n@app.post(\"/upload_files\")\nasync def creste_upload_files(uploaded_files: List[UploadFile], selectedModel: str = Form(...),\n patientId: str = Form(...), patientSex: str = Form(...),\n actualMedication: str = Form(...), imageDim: str = Form(...),\n imageFormat: str = Form(...), dateOfScan: str = Form(...)):\n for uploaded_dicom in uploaded_files:\n upload_folder = \"webapp/src/data/\"\n file_object = uploaded_dicom.file\n #create empty file to copy the file_object to\n upload_folder = open(os.path.join(upload_folder, uploaded_dicom.filename), 'wb+')\n shutil.copyfileobj(file_object, upload_folder)\n upload_folder.close()\n return \"hello\"\n```\n\n(I'm not using the metadata but I will later).\n\nI use unittest for the testing:\n\n```\nclass TestServer(unittest.TestCase):\n def setUp(self):\n self.client = TestClient(app)\n self.metadata = {\n \"patientId\": \"1\",\n \"patient_age\": \"M\",\n \"patientSex\": \"59\",\n \"patient_description\": \"test\",\n \"actualeMedication\": \"test\",\n \"dateOfScan\": datetime.strftime(datetime.now(), \"%d/%m/%Y\"),\n \"selectedModel\": \"unet\",\n \"imageDim\": \"h\",\n \"imageFormat\": \"h\"\n }\n\n def tearDown(self):\n pass\n\n def test_dcm_upload(self):\n dicom_file = pydicom.read_file(\"tests/data/1-001.dcm\")\n bytes_data = dicom_file.PixelData\n \n files = {\"uploaded_files\": (\"dicom_file\", bytes_data, \"multipart/form-data\")}\n response = self.client.post(\n \"/upload_files\",\n json=self.metadata,\n files=files\n )\n print(response.json())\n```\n\nBut it seems that the upload doesn't work, I get the following print of the *response*:\n\n```\n{'detail': [{'loc': ['body', 'selectedModel'], 'msg': 'field required', 'type': 'value_error.missing'}, {'loc': ['body', 'patientId'], 'msg': 'field required', 'type': 'value_error.missing'}, {'loc': ['body', 'patientSex'], 'msg': 'field required', 'type': 'value_error.missing'}, {'loc': ['body', 'actualMedication'], 'msg': 'field required', 'type': 'value_error.missing'}, {'loc': ['body', 'imageDim'], 'msg': 'field required', 'type': 'value_error.missing'}, {'loc': ['body', 'imageFormat'], 'msg': 'field required', 'type': 'value_error.missing'}, {'loc': ['body', 'dateOfScan'], 'msg': 'field required', 'type': 'value_error.missing'}]}\n```\n\nIt is possible that I should upload using a Formdata instead of the body request (`json=self.metadata`) but I don't know how it should be done.\n\n========================================\n\nCode:\n```text\n@app.post(\"/upload_files\")\nasync def creste_upload_files(uploaded_files: List[UploadFile], selectedModel: str = Form(...),\n patientId: str = Form(...), patientSex: str = Form(...),\n actualMedication: str = Form(...), imageDim: str = Form(...),\n imageFormat: str = Form(...), dateOfScan: str = Form(...)):\n for uploaded_dicom in uploaded_files:\n upload_folder = \"webapp/src/data/\"\n file_object = uploaded_dicom.file\n #create empty file to copy the file_object to\n upload_folder = open(os.path.join(upload_folder, uploaded_dicom.filename), 'wb+')\n shutil.copyfileobj(file_object, upload_folder)\n upload_folder.close()\n return \"hello\"\n```\n\n```text\nclass TestServer(unittest.TestCase):\n def setUp(self):\n self.client = TestClient(app)\n self.metadata = {\n \"patientId\": \"1\",\n \"patient_age\": \"M\",\n \"patientSex\": \"59\",\n \"patient_description\": \"test\",\n \"actualeMedication\": \"test\",\n \"dateOfScan\": datetime.strftime(datetime.now(), \"%d/%m/%Y\"),\n \"selectedModel\": \"unet\",\n \"imageDim\": \"h\",\n \"imageFormat\": \"h\"\n }\n\n def tearDown(self):\n pass\n\n def test_dcm_upload(self):\n dicom_file = pydicom.read_file(\"tests/data/1-001.dcm\")\n bytes_data = dicom_file.PixelData\n \n files = {\"uploaded_files\": (\"dicom_file\", bytes_data, \"multipart/form-data\")}\n response = self.client.post(\n \"/upload_files\",\n json=self.metadata,\n files=files\n )\n print(response.json())\n```\n\n```text\n{'detail': [{'loc': ['body', 'selectedModel'], 'msg': 'field required', 'type': 'value_error.missing'}, {'loc': ['body', 'patientId'], 'msg': 'field required', 'type': 'value_error.missing'}, {'loc': ['body', 'patientSex'], 'msg': 'field required', 'type': 'value_error.missing'}, {'loc': ['body', 'actualMedication'], 'msg': 'field required', 'type': 'value_error.missing'}, {'loc': ['body', 'imageDim'], 'msg': 'field required', 'type': 'value_error.missing'}, {'loc': ['body', 'imageFormat'], 'msg': 'field required', 'type': 'value_error.missing'}, {'loc': ['body', 'dateOfScan'], 'msg': 'field required', 'type': 'value_error.missing'}]}\n```\n\n```text\njson=self.metadata\n```\n\n```text\njson=self.metadata\n```\n\n```text\ndata=self.metadata\n```\n\n========================================\n\nComments:\n- I also want to test with formData, have you found any method? I am trying but no lib supporting that.","metadata":{"transformedAt":"2026-08-18T18:32:29.122Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":6,"totalLines":140,"estimatedTokens":1303}}313{"id":"stack-73983298","source":"stackoverflow","questionId":73983298,"title":"pydantic.error_wrappers.ValidationError : value is not a valid list (type=type_error.list)","tags":["python","fastapi","pydantic"],"text":"Title: pydantic.error_wrappers.ValidationError : value is not a valid list (type=type_error.list)\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nNew to FastAPI\n\nGetting a \"value is not a valid list (type=type_error.list)\" error\n\nWhenever I try to return {\"posts\": post}\n\n```\n@router.get('', response_model = List[schemas.PostResponseSchema])\ndef get_posts(db : Session = Depends(get_db)):\n print(limit)\n posts = db.query(models.Post).all()\n return {\"posts\" : posts}\n```\n\nAlthough it works if I return posts like this:\n\n```\nreturn posts\n```\n\nHere is my response model:\n\n```\nclass PostResponseSchema(PostBase):\n user_id: int\n id: str\n created_at : datetime\n user : UserResponseSchema\n\n class Config:\n orm_mode = True\n```\n\nAnd Model:\n\n```\nclass Post(Base):\n __tablename__ = \"posts\"\n id = Column(Integer, primary_key=True, nullable=False)\n title = Column(String, nullable=False)\n content = Column(String, nullable = False)\n published = Column(Boolean, server_default = 'TRUE' , nullable = False)\n created_at = Column(TIMESTAMP(timezone=True), nullable = False, server_default = \n text('now()'))\n user_id = Column(Integer, ForeignKey(\"users.id\", ondelete = \"CASCADE\"), nullable = \n False )\n\n user = relationship(\"User\")\n```\n\nwhat am I missing here?\n\n========================================\n\nCode:\n```text\n@router.get('', response_model = List[schemas.PostResponseSchema])\ndef get_posts(db : Session = Depends(get_db)):\n print(limit)\n posts = db.query(models.Post).all()\n return {\"posts\" : posts}\n```\n\n```text\nreturn posts\n```\n\n```text\nclass PostResponseSchema(PostBase):\n user_id: int\n id: str\n created_at : datetime\n user : UserResponseSchema\n\n class Config:\n orm_mode = True\n```\n\n```text\nclass Post(Base):\n __tablename__ = \"posts\"\n id = Column(Integer, primary_key=True, nullable=False)\n title = Column(String, nullable=False)\n content = Column(String, nullable = False)\n published = Column(Boolean, server_default = 'TRUE' , nullable = False)\n created_at = Column(TIMESTAMP(timezone=True), nullable = False, server_default = \n text('now()'))\n user_id = Column(Integer, ForeignKey(\"users.id\", ondelete = \"CASCADE\"), nullable = \n False )\n\n user = relationship(\"User\")\n```\n\n```text\n@router.get('', response_model = List[schemas.PostResponseSchema])\n```\n\n```text\n{\"posts\": [......]}\n```\n\n```text\nreturn {\"posts\" : posts}\n```\n\n```text\nreturn {\"posts\": posts}\n```\n\n```text\nrouter.get('', response_model = List[schemas.PostResponseSchema])\n```\n\n```text\nrouter.get('')\n```\n\n========================================\n\nComments:\n- Don't remove the `response_model=` as this will mean that the documentation no longer contains any information about the response; instead, create a new response model (schema) that has `posts: List[schemas.PostResponseSchema])` as its only property. That way the generated documentation will reflect what the endpoint returns and you still get validation that you're returning the expected format.\n- Please upvote Ismaili and accept his answer as he had the actual answer to make it work :-)","metadata":{"transformedAt":"2026-08-18T18:32:29.122Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":10,"totalLines":127,"estimatedTokens":760}}314{"id":"stack-69822360","source":"stackoverflow","questionId":69822360,"title":"Separate FastApi documentation into sections","tags":["python","openapi","fastapi"],"text":"Title: Separate FastApi documentation into sections\nTags: python, openapi, fastapi\nSource: Stack Overflow\n\nQuestion:\nCurrently the OpenAPI documentation looks like this: https://i.sstatic.net/RHOgA.png\nIs it possible to separate it into multiple sections?\n\nFor example, 2 sections, one being the \"books\" section that contains the methods from \"/api/bookcollection/books/\" endpoints and the other containing the endpoints with \"/api/bookcollection/authors/\".\n\nI have consulted the FastApi documentation, but I do not find anything close to the operation I want to do.\n\n========================================\n\nTop Answer:\nAnother solution for this would be just to create different routers for every resource that you want to have in different documentation sections.\n\nsource\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\n\ntags_metadata = [\n {\n \"name\": \"users\",\n \"description\": \"Operations with users. The **login** logic is also here.\",\n },\n {\n \"name\": \"items\",\n \"description\": \"Manage items. So _fancy_ they have their own docs.\",\n \"externalDocs\": {\n \"description\": \"Items external docs\",\n \"url\": \"https://fastapi.tiangolo.com/\",\n },\n },\n]\n\napp = FastAPI(openapi_tags=tags_metadata)\n\n\n@app.get(\"/users/\", tags=[\"users\"])\nasync def get_users():\n return [{\"name\": \"Harry\"}, {\"name\": \"Ron\"}]\n\n\n@app.get(\"/items/\", tags=[\"items\"])\nasync def get_items():\n return [{\"name\": \"wand\"}, {\"name\": \"flying broom\"}]\n```\n\n```text\nOpenAPI\n```\n\n```text\nFastAPI\n```\n\n========================================\n\nComments:\n- My apologies. I will leave the related answer here: stackoverflow.com/questions/72915808/…","metadata":{"transformedAt":"2026-08-18T18:32:29.122Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":3,"totalLines":65,"estimatedTokens":431}}315{"id":"stack-75350395","source":"stackoverflow","questionId":75350395,"title":"How should we manage datetime fields in SQLModel in python?","tags":["python","fastapi","pydantic","sqlmodel"],"text":"Title: How should we manage datetime fields in SQLModel in python?\nTags: python, fastapi, pydantic, sqlmodel\nSource: Stack Overflow\n\nQuestion:\nLet's say I want to create an API with a `Hero` SQLModel, below are minimum viable codes illustrating this:\n\n```\nfrom typing import Optional\nfrom sqlmodel import Field, Relationship, SQLModel\nfrom datetime import datetime\nfrom sqlalchemy import Column, TIMESTAMP, text\n\nclass HeroBase(SQLModel): # essential fields\n name: str = Field(index=True)\n secret_name: str\n age: Optional[int] = Field(default=None, index=True)\n created_datetime: datetime = Field(sa_column=Column(TIMESTAMP(timezone=True),\n nullable=False, server_default=text(\"now()\")))\n updated_datetime: datetime = Field(sa_column=Column(TIMESTAMP(timezone=True),\n nullable=False, server_onupdate=text(\"now()\")))\n\n team_id: Optional[int] = Field(default=None, foreign_key=\"team.id\")\n\nclass Hero(HeroBase, table=True): # essential fields + uniq identifier + relationships\n id: Optional[int] = Field(default=None, primary_key=True)\n\n team: Optional[\"Team\"] = Relationship(back_populates=\"heroes\")\n\nclass HeroRead(HeroBase): # uniq identifier\n id: int\n\nclass HeroCreate(HeroBase): # same and Base\n pass\n\nclass HeroUpdate(SQLModel): # all essential fields without datetimes\n name: Optional[str] = None\n secret_name: Optional[str] = None\n age: Optional[int] = None\n team_id: Optional[int] = None\n\nclass HeroReadWithTeam(HeroRead):\n team: Optional[\"TeamRead\"] = None\n```\n\nMy question is, how should the `SQLModel` for `HeroUpdate` be like?\n\n- Does it include the `create_datetime` and `update_datetime` fields?\n\n- How do I delegate the responsibility of creating these fields to the database instead of using the `app` to do so?\n\n========================================\n\nTop Answer:\nI would like to add to Daniil Fajnberg's excellent answer two changes I made when I had similar problem.\n\nIn `created_datetime` when providing value for `server_onupdate` argument in `Column` you should pass `FetchedValue()` which represents value generated by database server and indicates to SQLModel that this value needs to be fetched from the database after update operation. Of course provided that you have a proper trigger on database side.\n\nBoth in `created_datetime` and `updated_datetime` fields you should pass argument `default=None`. Without it when converting HeroRead to Hero you will get validation error. I believe this change was made with Pydantic v2 where `from_orm` was replaced with `model_validation`.\n\n```\nfrom sqlmodel import FetchedValue\n\nclass Hero(HeroBase, table=True):\n id: Optional[int] = Field(default=None, primary_key=True)\n created_datetime: Optional[datetime] = Field(\n default=None,\n sa_column=Column(\n TIMESTAMP(timezone=True),\n nullable=False,\n server_default=text(\"CURRENT_TIMESTAMP\"),\n ))\n updated_datetime: Optional[datetime] = Field(\n default=None,\n sa_column=Column(\n TIMESTAMP(timezone=True),\n nullable=False,\n server_default=text(\"CURRENT_TIMESTAMP\"),\n server_onupdate=FetchedValue(),\n ))\n```\n\n========================================\n\nCode:\n```text\nfrom typing import Optional\nfrom sqlmodel import Field, Relationship, SQLModel\nfrom datetime import datetime\nfrom sqlalchemy import Column, TIMESTAMP, text\n\nclass HeroBase(SQLModel): # essential fields\n name: str = Field(index=True)\n secret_name: str\n age: Optional[int] = Field(default=None, index=True)\n created_datetime: datetime = Field(sa_column=Column(TIMESTAMP(timezone=True),\n nullable=False, server_default=text(\"now()\")))\n updated_datetime: datetime = Field(sa_column=Column(TIMESTAMP(timezone=True),\n nullable=False, server_onupdate=text(\"now()\")))\n\n team_id: Optional[int] = Field(default=None, foreign_key=\"team.id\")\n\n\nclass Hero(HeroBase, table=True): # essential fields + uniq identifier + relationships\n id: Optional[int] = Field(default=None, primary_key=True)\n\n team: Optional[\"Team\"] = Relationship(back_populates=\"heroes\")\n\n\nclass HeroRead(HeroBase): # uniq identifier\n id: int\n\n\nclass HeroCreate(HeroBase): # same and Base\n pass\n\n\nclass HeroUpdate(SQLModel): # all essential fields without datetimes\n name: Optional[str] = None\n secret_name: Optional[str] = None\n age: Optional[int] = None\n team_id: Optional[int] = None\n\n\nclass HeroReadWithTeam(HeroRead):\n team: Optional[\"TeamRead\"] = None\n```\n\n```text\nHero\n```\n\n```text\nSQLModel\n```\n\n```text\nHeroUpdate\n```\n\n```text\ncreate_datetime\n```\n\n```text\nupdate_datetime\n```\n\n```text\napp\n```\n\n```py\nfrom datetime import datetime\nfrom typing import Optional\n\nfrom sqlmodel import Column, Field, SQLModel, TIMESTAMP, text\n\n\nclass HeroBase(SQLModel):\n name: str = Field(index=True)\n secret_name: str\n age: Optional[int] = Field(default=None, index=True)\n\n\nclass Hero(HeroBase, table=True):\n id: Optional[int] = Field(default=None, primary_key=True)\n created_datetime: Optional[datetime] = Field(sa_column=Column(\n TIMESTAMP(timezone=True),\n nullable=False,\n server_default=text(\"CURRENT_TIMESTAMP\"),\n ))\n updated_datetime: Optional[datetime] = Field(sa_column=Column(\n TIMESTAMP(timezone=True),\n nullable=False,\n server_default=text(\"CURRENT_TIMESTAMP\"),\n server_onupdate=text(\"CURRENT_TIMESTAMP\"),\n ))\n\n\nclass HeroRead(HeroBase):\n id: int\n\n\nclass HeroCreate(HeroBase):\n pass\n\n\nclass HeroUpdate(SQLModel):\n name: Optional[str] = None\n secret_name: Optional[str] = None\n age: Optional[int] = None\n```\n\n```py\nfrom sqlmodel import Session, create_engine, select\n\n# Initialize database & session:\nengine = create_engine(\"sqlite:///\", echo=True)\nSQLModel.metadata.create_all(engine)\nsession = Session(engine)\n\n# Create:\nhero_create = HeroCreate(name=\"foo\", secret_name=\"bar\")\nsession.add(Hero.from_orm(hero_create))\nsession.commit()\n\n# Query (SELECT):\nstatement = select(Hero).filter(Hero.name == \"foo\")\nhero = session.execute(statement).scalar()\n\n# Read (Response):\nhero_read = HeroRead.from_orm(hero)\nprint(hero_read.json(indent=4))\n\n# Update (comprehensive as in the docs, although we change only one field):\nhero_update = HeroUpdate(secret_name=\"baz\")\nhero_update_data = hero_update.dict(exclude_unset=True)\nfor key, value in hero_update_data.items():\n setattr(hero, key, value)\nsession.add(hero)\nsession.commit()\n\n# Read again:\nhero_read = HeroRead.from_orm(hero)\nprint(hero_read.json(indent=4))\n```\n\n```sql\nCREATE TABLE hero (\n created_datetime TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, \n updated_datetime TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL, \n name VARCHAR NOT NULL, \n secret_name VARCHAR NOT NULL, \n age INTEGER, \n id INTEGER NOT NULL, \n PRIMARY KEY (id)\n)\n```\n\n```json\n{\n \"name\": \"foo\",\n \"secret_name\": \"bar\",\n \"age\": null,\n \"id\": 1\n}\n```\n\n```json\n{\n \"name\": \"foo\",\n \"secret_name\": \"baz\",\n \"age\": null,\n \"id\": 1\n}\n```\n\n```text\nHeroUpdate\n```\n\n```text\ncreate_datetime\n```\n\n```text\nupdate_datetime\n```\n\n```text\nhero\n```\n\n```text\ncreate_datetime\n```\n\n```text\nupdate_datetime\n```\n\n```text\nHeroRead\n```\n\n```text\ncreate_datetime\n```\n\n```text\nupdate_datetime\n```\n\n```text\nserver_default\n```\n\n```text\nserver_onupdate\n```\n\n```text\nColumn\n```\n\n```text\nCURRENT_TIMESTAMP\n```\n\n```text\nCREATE\n```\n\n```text\nHeroRead\n```\n\n```text\nON UPDATE\n```\n\n```py\nfrom sqlmodel import FetchedValue\n\nclass Hero(HeroBase, table=True):\n id: Optional[int] = Field(default=None, primary_key=True)\n created_datetime: Optional[datetime] = Field(\n default=None,\n sa_column=Column(\n TIMESTAMP(timezone=True),\n nullable=False,\n server_default=text(\"CURRENT_TIMESTAMP\"),\n ))\n updated_datetime: Optional[datetime] = Field(\n default=None,\n sa_column=Column(\n TIMESTAMP(timezone=True),\n nullable=False,\n server_default=text(\"CURRENT_TIMESTAMP\"),\n server_onupdate=FetchedValue(),\n ))\n```\n\n```text\ncreated_datetime\n```\n\n```text\nserver_onupdate\n```\n\n```text\nColumn\n```\n\n```text\nFetchedValue()\n```\n\n```text\ncreated_datetime\n```\n\n```text\nupdated_datetime\n```\n\n```text\ndefault=None\n```\n\n```text\nfrom_orm\n```\n\n```text\nmodel_validation\n```\n\n========================================\n\nComments:\n- Your code example is far from minimal as it relates to your question. I would suggest you at least remove all the relationship and foreign key stuff because it is irrelevant here. That way there is less distraction from the actual issue for future readers of this post.\n- Sir, thank you for your great response! Can I ask why did you place the `Hero` class above `HeroUpdate` and `HeroRead`? And why is `created_datetime` annotated as `Optional[datetime]` instead of merely `datetime`?\n- The order between those classes you mentioned is arbitrary. The field should be marked as `Optional` for the same reason as the primary key `id` is. In terms of the DB table it of course is not. But from the point of view of the Pydantic model it is optional because you should be able to initialize an instance of `Hero` **without** providing a value for those fields since they will be provided by the DB. Here is the relevant docs section.","metadata":{"transformedAt":"2026-08-18T18:32:29.122Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":38,"totalLines":386,"estimatedTokens":2297}}316{"id":"stack-74168582","source":"stackoverflow","questionId":74168582,"title":"How to read the request body using orjson library in FastAPI?","tags":["python","json","fastapi","starlette","orjson"],"text":"Title: How to read the request body using orjson library in FastAPI?\nTags: python, json, fastapi, starlette, orjson\nSource: Stack Overflow\n\nQuestion:\nI am writing code to receive a JSON payload in FastAPI.\n\nHere is my code:\n\n```\nfrom fastapi import FastAPI, status, Request\nfrom fastapi.responses import ORJSONResponse\nimport uvicorn\nimport asyncio\nimport orjson\n\napp = FastAPI()\n\n@app.post(\"/\", status_code = status.HTTP_200_OK)\nasync def get_data(request: Request):\n param = await request.json()\n return param\n```\n\nHowever, what I want is `request.json()` to be used with `orjson` instead of the default `json` library of Python.\nAny idea how to address this problem? Please help me, thanks.\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI, status, Request\nfrom fastapi.responses import ORJSONResponse\nimport uvicorn\nimport asyncio\nimport orjson\n\napp = FastAPI()\n\n@app.post(\"/\", status_code = status.HTTP_200_OK)\nasync def get_data(request: Request):\n param = await request.json()\n return param\n```\n\n```text\nrequest.json()\n```\n\n```text\norjson\n```\n\n```text\njson\n```\n\n```py\nfrom fastapi import FastAPI, Request, HTTPException\nimport orjson\n\napp = FastAPI()\n\n\n@app.post('/submit')\nasync def submit(request: Request):\n try:\n # orjson.loads() could be run in a separate thread/process\n data = orjson.loads(await request.body())\n except orjson.JSONDecodeError:\n raise HTTPException(status_code=400, detail='Invalid JSON data')\n \n return \"success\"\n```\n\n```py\nfrom fastapi import FastAPI, Request, Response, HTTPException\nimport orjson\n\napp = FastAPI()\n\n\n@app.get('/item')\nasync def get_item(request: Request):\n try:\n # orjson.dumps() could be run in a separate thread/process\n return Response(orjson.dumps({\"item_id\": \"foo\"}), media_type='application/json')\n except TypeError:\n raise HTTPException(status_code=500, detail='Unable to serialize the object')\n```\n\n```py\n@app.post('/submit')\nasync def submit(request: Request):\n try:\n # orjson.loads() could be run in a separate thread/process\n data = orjson.loads(await request.body())\n # orjson.dumps() could be run in a separate thread/process\n return Response(orjson.dumps(data), media_type='application/json')\n except orjson.JSONDecodeError:\n raise HTTPException(status_code=400, detail='Invalid JSON data')\n except TypeError:\n raise HTTPException(status_code=500, detail='Unable to serialize the object')\n```\n\n```py\nfrom fastapi import FastAPI, Request\nfrom fastapi.responses import ORJSONResponse\n\napp = FastAPI()\n\n\n@app.get('/item', response_class=ORJSONResponse)\nasync def get_item():\n return ORJSONResponse({\"item_id\": \"foo\"})\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.responses import ORJSONResponse\n\napp = FastAPI(default_response_class=ORJSONResponse)\n\n\n@app.get(\"/item\")\nasync def get_item():\n return {\"item_id\": \"foo\"}\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.responses import ORJSONResponse, HTMLResponse\n\napp = FastAPI(default_response_class=ORJSONResponse)\n\n\n@app.get(\"/item\")\nasync def get_item():\n return {\"item_id\": \"foo\"}\n\n\n@app.get(\"/html\", response_class=HTMLResponse)\nasync def get_html():\n html_content = \"\"\"\n <html>\n <body>\n <h1>HTML!</h1>\n </body>\n </html>\n \"\"\"\n return HTMLResponse(content=html_content, status_code=200)\n```\n\n```text\nrequest\n```\n\n```text\norjson\n```\n\n```text\nawait request.json()\n```\n\n```text\n.body()\n```\n\n```text\nRequest\n```\n\n```text\njson.loads()\n```\n\n```text\njson\n```\n\n```text\ndict\n```\n\n```text\nlist\n```\n\n```text\njson.dumps()\n```\n\n```text\njson.loads()\n```\n\n```text\nawait run_in_threadpool()\n```\n\n```text\norjson.loads()\n```\n\n```text\norjson.dumps()\n```\n\n```text\nawait\n```\n\n```text\nasync def\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\ndef\n```\n\n```text\nasync\n```\n\n```text\norjson.loads()\n```\n\n```text\ndef\n```\n\n```text\nawait\n```\n\n```text\nasync def\n```\n\n```text\nasync def\n```\n\n```text\nasync\n```\n\n```text\ndef\n```\n\n```text\norjson.dumps()\n```\n\n```text\njson.dumps()\n```\n\n```text\nasync def\n```\n\n```text\nrequest.stream()\n```\n\n```text\nawait request.body()\n```\n\n```text\nresponse\n```\n\n```text\norjson\n```\n\n```text\ndict\n```\n\n```text\nlist\n```\n\n```text\njson.dumps()\n```\n\n```text\njsonable_encoder()\n```\n\n```text\nJSONResponse\n```\n\n```text\njson.dumps()\n```\n\n```text\norjson\n```\n\n```text\njsonable_encoder()\n```\n\n```text\norjson\n```\n\n```text\ndefault\n```\n\n```text\norjson.dumps(data, default=str)\n```\n\n```text\nResponse\n```\n\n```text\norjson.loads()\n```\n\n```text\norjson.dumps()\n```\n\n```text\nasync def\n```\n\n```text\ndef\n```\n\n```text\nresponse\n```\n\n```text\nORJSONResponse\n```\n\n```text\nORJSONResponse\n```\n\n```text\norjson\n```\n\n```text\nORJSONResponse\n```\n\n```text\nORJSONResponse\n```\n\n```text\nresponse_class\n```\n\n```text\nResponse\n```\n\n```text\nresponse_class\n```\n\n```text\nresponse_class=ORJSONResponse\n```\n\n```text\nreturn ORJSONResponse(...)\n```\n\n```text\nresponse_class\n```\n\n```text\n/docs\n```\n\n```text\nORJSONResponse\n```\n\n```text\norjson.dumps()\n```\n\n```text\nasync def\n```\n\n```text\nORJSONResponse\n```\n\n```text\ndef\n```\n\n```text\nasync\n```\n\n```text\nresponse_class=ORJSONResponse\n```\n\n```text\napplication/json\n```\n\n```text\nHTMLResponse\n```\n\n```text\nresponse_class=HTMLResponse\n```\n\n```text\napplication/json\n```\n\n```text\nORJSONResponse\n```\n\n```text\ndefault_response_class\n```\n\n```text\nORJSONResponse\n```\n\n```text\nresponse_class=ORJSONResponse\n```\n\n```text\nreturn ORJSONResponse(...)\n```\n\n```text\nresponse_class\n```\n\n```text\nResponse\n```\n\n```text\nawait request.json()\n```\n\n========================================\n\nComments:\n- Does this answer your question? FastAPI is very slow in returning a large amount of JSON data\n- it seems to be reading and then dumping a JSON file while mine is getting a payload in JSON format. In `request.json`, it was used `json.dumps()`, I wanna replace it with orgjson package.","metadata":{"transformedAt":"2026-08-18T18:32:29.122Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":92,"totalLines":486,"estimatedTokens":1471}}317{"id":"stack-71613305","source":"stackoverflow","questionId":71613305,"title":"How to process requests from multiiple users using ML model and FastAPI?","tags":["python","machine-learning","multiprocessing","fastapi"],"text":"Title: How to process requests from multiiple users using ML model and FastAPI?\nTags: python, machine-learning, multiprocessing, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm studying the process of distributing artificial intelligence modules through FastAPI.\n\nI created a FastAPI app that answers questions using a pre-learned Machine Learning model.\n\nIn this case, it is not a problem for one user to use it, but when multiple users use it at the same time, the response may be too slow.\n\nHence, when multiple users enter a question, is there any way to copy the model and load it in at once?\n\n```\nclass sentencebert_ai():\n def __init__(self) -> None:\n super().__init__()\n\n def ask_query(self,query, topN):\n startt = time.time()\n\n ask_result = []\n score = []\n result_value = [] \n embedder = torch.load(model_path)\n corpus_embeddings = embedder.encode(corpus, convert_to_tensor=True)\n query_embedding = embedder.encode(query, convert_to_tensor=True)\n cos_scores = util.pytorch_cos_sim(query_embedding, corpus_embeddings)[0] #torch.Size([121])121개의 말뭉치에 대한 코사인 유사도 값이다.\n cos_scores = cos_scores.cpu()\n\n top_results = np.argpartition(-cos_scores, range(topN))[0:topN]\n\n for idx in top_results[0:topN]: \n ask_result.append(corpusid[idx].item())\n #.item()으로 접근하는 이유는 tensor(5)에서 해당 숫자에 접근하기 위한 방식이다.\n score.append(round(cos_scores[idx].item(),3))\n\n #서버에 json array 형태로 내보내기 위한 작업\n for i,e in zip(ask_result,score):\n result_value.append({\"pred_id\":i,\"pred_weight\":e})\n endd = time.time()\n print('시간체크',endd-startt)\n return result_value\n # return ','.join(str(e) for e in ask_result),','.join(str(e) for e in score)\n\nclass Item_inference(BaseModel):\n text : str\n topN : Optional[int] = 1\n\n@app.post(\"/retrieval\", tags=[\"knowledge recommendation\"])\nasync def Knowledge_recommendation(item: Item_inference):\n \n # db.append(item.dict())\n item.dict()\n results = _ai.ask_query(item.text, item.topN)\n\n return results\n\nif __name__ == \"__main__\":\n parser = argparse.ArgumentParser()\n parser.add_argument(\"--port\", default='9003', type=int)\n # parser.add_argument(\"--mode\", default='cpu', type=str, help='cpu for CPU mode, gpu for GPU mode')\n args = parser.parse_args()\n\n _ai = sentencebert_ai()\n uvicorn.run(app, host=\"0.0.0.0\", port=args.port,workers=4)\n```\n\ncorrected version\n\n```\n@app.post(\"/aaa\") def your_endpoint(request: Request, item:Item_inference): start = time.time() model = request.app.state.model item.dict() #커널 실행시 필요 _ai = sentencebert_ai() results = _ai.ask_query(item.text, item.topN,model) end = time.time() print(end-start) return results ```\n```\n\n========================================\n\nCode:\n```py\nclass sentencebert_ai():\n def __init__(self) -> None:\n super().__init__()\n\n def ask_query(self,query, topN):\n startt = time.time()\n\n ask_result = []\n score = []\n result_value = [] \n embedder = torch.load(model_path)\n corpus_embeddings = embedder.encode(corpus, convert_to_tensor=True)\n query_embedding = embedder.encode(query, convert_to_tensor=True)\n cos_scores = util.pytorch_cos_sim(query_embedding, corpus_embeddings)[0] #torch.Size([121])121개의 말뭉치에 대한 코사인 유사도 값이다.\n cos_scores = cos_scores.cpu()\n\n top_results = np.argpartition(-cos_scores, range(topN))[0:topN]\n\n for idx in top_results[0:topN]: \n ask_result.append(corpusid[idx].item())\n #.item()으로 접근하는 이유는 tensor(5)에서 해당 숫자에 접근하기 위한 방식이다.\n score.append(round(cos_scores[idx].item(),3))\n\n #서버에 json array 형태로 내보내기 위한 작업\n for i,e in zip(ask_result,score):\n result_value.append({\"pred_id\":i,\"pred_weight\":e})\n endd = time.time()\n print('시간체크',endd-startt)\n return result_value\n # return ','.join(str(e) for e in ask_result),','.join(str(e) for e in score)\n\n\n\nclass Item_inference(BaseModel):\n text : str\n topN : Optional[int] = 1\n\n@app.post(\"/retrieval\", tags=[\"knowledge recommendation\"])\nasync def Knowledge_recommendation(item: Item_inference):\n \n # db.append(item.dict())\n item.dict()\n results = _ai.ask_query(item.text, item.topN)\n\n return results\n\n\nif __name__ == \"__main__\":\n parser = argparse.ArgumentParser()\n parser.add_argument(\"--port\", default='9003', type=int)\n # parser.add_argument(\"--mode\", default='cpu', type=str, help='cpu for CPU mode, gpu for GPU mode')\n args = parser.parse_args()\n\n _ai = sentencebert_ai()\n uvicorn.run(app, host=\"0.0.0.0\", port=args.port,workers=4)\n```\n\n```py\n@app.post(\"/aaa\") def your_endpoint(request: Request, item:Item_inference): start = time.time() model = request.app.state.model item.dict() #커널 실행시 필요 _ai = sentencebert_ai() results = _ai.ask_query(item.text, item.topN,model) end = time.time() print(end-start) return results ```\n```\n\n```py\nfrom fastapi import Request\n\n@app.on_event(\"startup\")\nasync def startup_event():\n app.state.model = torch.load('<model_path>')\n```\n\n```py\n@app.post('/')\ndef your_endpoint(request: Request):\n model = request.app.state.model\n # run your synchronous ask_query() function here\n```\n\n```py\nfrom fastapi import FastAPI, Request\nimport concurrent.futures\nimport asyncio\nimport uvicorn\n\n\nclass MyAIClass():\n def __init__(self) -> None:\n super().__init__()\n\n def ask_query(self, model, query, topN):\n # ...\n \n\nai = MyAIClass()\napp = FastAPI()\n\n\n@app.on_event(\"startup\")\nasync def startup_event():\n app.state.model = torch.load('<model_path>')\n\n\n@app.post('/')\nasync def your_endpoint(request: Request):\n model = request.app.state.model\n\n loop = asyncio.get_running_loop()\n with concurrent.futures.ProcessPoolExecutor() as pool:\n res = await loop.run_in_executor(pool, ai.ask_query, model, item.text, item.topN)\n\n\nif __name__ == '__main__':\n uvicorn.run(app)\n```\n\n```text\ngunicorn --workers 4 --preload --worker-class=uvicorn.workers.UvicornWorker app:app\n```\n\n```text\nstartup\n```\n\n```text\nstartup\n```\n\n```text\napp.state\n```\n\n```text\nstartup\n```\n\n```text\nstartup\n```\n\n```text\nshutdown\n```\n\n```text\nlifespan\n```\n\n```text\nstartup\n```\n\n```text\nasync def\n```\n\n```text\nawait\n```\n\n```text\ndef\n```\n\n```text\ndef\n```\n\n```text\nawait\n```\n\n```text\nasync def\n```\n\n```text\nasync\n```\n\n```text\nawait\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\nProcessPoolExecutor\n```\n\n```text\nasyncio\n```\n\n```text\nawait\n```\n\n```text\nif __name__ == '__main__'\n```\n\n```text\nProcessPool\n```\n\n```text\n/\n```\n\n```text\nProcessPoolExecutor\n```\n\n```text\napp.state\n```\n\n```text\nrequest.state\n```\n\n```text\nstartup\n```\n\n```text\nlifepsan\n```\n\n```text\n--preload\n```\n\n```text\n--preload\n```\n\n```text\nFalse\n```\n\n```text\n--preload\n```\n\n```text\n--reload\n```\n\n```text\nfork()\n```\n\n========================================\n\nComments:\n- This question is not very clear, can you reformulate it and complete a bit the code ?\n- If your recommendation engine takes a lot of time, there's not really much you can do magically to speed that up - limit the amount of work done that is not specific to each user (so that depends on how `ask_query` is implemented). Since this is probably CPU bound, you might want to instead start multiple instances (worker threads/processes) of your application when using gunicorn or similar, so that you can use more processor cores efficiently.\n- @MatsLindh OP is already using `uvicorn`, no need to use `gunicorn`.\n- Ah, I missed that. My bad. uvicorn should support the same through `workers`.\n- Thank you for the best answer that suits my situation.\n- Thank you Chris. Like the advice you gave, As a result of saving the model in the app and loading it, The average response time was reduced to 0.72 -> 0.5. And since I don't need to use concurrence, I decided to use def instead of async def. Could you please check if the method is correct?\n- I was able to save time by instantiating. In the performance load test, I didn't see any reduction in time by using def, so I was wondering if I understood something wrong.\n- @WONJUN it seems like your `ask_query` is doing some CPU intensive work which means when you have multiple calls to your endpoint performance will get a hit (even after loading the model in the startup phase). You probably should use FastAPI with multiprocessing, see an example here: stackoverflow.com/questions/63169865/…\n- In the case of a process pool, is the model going to be copied to each process? Typically, the model needs internal state when it's run, if a copy of the model is done for each process, it might take too long (eg. a small embedding model is already ~100MB).\n- I'm also wondering with `def` (and not `async def`) in the case of a thread unsafe model would not be a problem. If FastAPI really runs queries from different threads that call the same (thread unsafe) model created once for the app, the results would likely be erroneous at best?\n- @Frank Pytorch models are thread safe to read (but are not to write into). See the relevant documentation","metadata":{"transformedAt":"2026-08-18T18:32:29.122Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":43,"totalLines":357,"estimatedTokens":2237}}318{"id":"stack-70975344","source":"stackoverflow","questionId":70975344,"title":"How to post JSON data to FastAPI and retrieve the JSON data inside the endpoint?","tags":["python","json","rest","fastapi","streamlit"],"text":"Title: How to post JSON data to FastAPI and retrieve the JSON data inside the endpoint?\nTags: python, json, rest, fastapi, streamlit\nSource: Stack Overflow\n\nQuestion:\nI would like to pass a JSON object to a FastAPI backend. Here is what I am doing in the frontend app:\n\n```\ndata = {'labels': labels, 'sequences': sequences}\nresponse = requests.post(api_url, data = data)\n```\n\nHere is how the backend API looks like in FastAPI:\n\n```\n@app.post(\"/api/zero-shot/\")\nasync def Zero_Shot_Classification(request: Request):\n data = await request.json()\n```\n\nHowever, I am getting this error:\n\n```\njson.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)\n```\n\n========================================\n\nCode:\n```py\ndata = {'labels': labels, 'sequences': sequences}\nresponse = requests.post(api_url, data = data)\n```\n\n```py\n@app.post(\"/api/zero-shot/\")\nasync def Zero_Shot_Classification(request: Request):\n data = await request.json()\n```\n\n```json\njson.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)\n```\n\n```py\npayload = {'labels': labels, 'sequences': sequences}\nr = requests.post(url, json=payload)\n```\n\n```py\npayload = {'labels': labels, 'sequences': sequences}\nr = requests.post(url, data=json.dumps(payload), headers={'Content-Type': 'application/json'})\n```\n\n```text\njson\n```\n\n```text\nContent-Type\n```\n\n```text\napplication/json\n```\n\n```text\ndata\n```\n\n```text\nform\n```\n\n```text\nContent-Type\n```\n\n```text\napplication/x-www-form-urlencoded\n```\n\n```text\nmultipart/form-data\n```\n\n```text\nfiles\n```\n\n```text\nContent-Type\n```\n\n```text\napplication/json\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.122Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":16,"totalLines":97,"estimatedTokens":396}}319{"id":"stack-59307024","source":"stackoverflow","questionId":59307024,"title":"Nginx reverse proxy on unix socket for uvicorn not working","tags":["python","nginx","reverse-proxy","fastapi","uvicorn"],"text":"Title: Nginx reverse proxy on unix socket for uvicorn not working\nTags: python, nginx, reverse-proxy, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\n**Files**:\n\n```\n# main.py:\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/\")\ndef read_root():\n return {\"Hello\": \"World\"}\n```\n\n-\n\n```\n# nginx.conf:\nevents {\n worker_connections 128;\n}\nhttp{\n server {\n listen 0.0.0.0:8080;\n location / {\n include uwsgi_params;\n uwsgi_pass unix:/tmp/uvi.sock;\n }\n }\n}\n```\n\n-\n\n```\n# Dockerfile\nFROM python:3\n\nCOPY main.py .\n\nRUN apt-get -y update && apt-get install -y htop tmux vim nginx\n\nRUN pip install fastapi uvicorn\n\nCOPY nginx.conf /etc/nginx/\n```\n\n**Setup**:\n\n```\ndocker build -t nginx-uvicorn:latest .\ndocker run -it --entrypoint=/bin/bash --name nginx-uvicorn -p 80:8080 nginx-uvicorn:latest\n```\n\n**Starting uvicorn as usual**:\n\n```\n$ uvicorn --host 0.0.0.0 --port 8080 main:app\n```\n\nWorks - I can access http://127.0.0.1/ from my browser.\n\n**Starting uvicorn behind nginx**:\n\n```\n$ service nginx start\n[ ok ] Starting nginx: nginx.\n\n$ uvicorn main:app --uds /tmp/uvi.sock\nINFO: Started server process [40]\nINFO: Uvicorn running on unix socket /tmp/uvi.sock (Press CTRL+C to quit)\nINFO: Waiting for application startup.\nINFO: Application startup complete.\n```\n\nIf I now request http://127.0.0.1/ then:\n\n- Nginx: Responds with 502 Bad Gateway\n\n- uvicorn: Responds with `WARNING: Invalid HTTP request received.`\n\nHence a connection is established but something is wrong about the configuration.\n\nAny ideas?\n\n========================================\n\nCode:\n```text\n# main.py:\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/\")\ndef read_root():\n return {\"Hello\": \"World\"}\n```\n\n```text\n# nginx.conf:\nevents {\n worker_connections 128;\n}\nhttp{\n server {\n listen 0.0.0.0:8080;\n location / {\n include uwsgi_params;\n uwsgi_pass unix:/tmp/uvi.sock;\n }\n }\n}\n```\n\n```text\n# Dockerfile\nFROM python:3\n\nCOPY main.py .\n\nRUN apt-get -y update && apt-get install -y htop tmux vim nginx\n\nRUN pip install fastapi uvicorn\n\nCOPY nginx.conf /etc/nginx/\n```\n\n```text\ndocker build -t nginx-uvicorn:latest .\ndocker run -it --entrypoint=/bin/bash --name nginx-uvicorn -p 80:8080 nginx-uvicorn:latest\n```\n\n```text\n$ uvicorn --host 0.0.0.0 --port 8080 main:app\n```\n\n```text\n$ service nginx start\n[ ok ] Starting nginx: nginx.\n\n$ uvicorn main:app --uds /tmp/uvi.sock\nINFO: Started server process [40]\nINFO: Uvicorn running on unix socket /tmp/uvi.sock (Press CTRL+C to quit)\nINFO: Waiting for application startup.\nINFO: Application startup complete.\n```\n\n```text\nWARNING: Invalid HTTP request received.\n```\n\n```text\nuwsgi\n```\n\n```text\nasgi\n```\n\n```text\nuwsgi\n```\n\n```text\nproxy_pass\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.122Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":11,"totalLines":171,"estimatedTokens":685}}320{"id":"stack-69585048","source":"stackoverflow","questionId":69585048,"title":"FastAPI with nginx does not serve static files in HTTPS","tags":["nginx","https","jinja2","fastapi","uvicorn"],"text":"Title: FastAPI with nginx does not serve static files in HTTPS\nTags: nginx, https, jinja2, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI have a small, test FastAPI web application that is serving a simple HTML page that requires a css style sheet located in the static folder. It is installed on a Linode server (Ubuntu 20.04 LTS), nginx, gunicorn, uvicorn workers, and supervisorctl. I have added a certificate using certbot.\n\nThe application works fine in http but does not access the static files in https. When accessed in http all static-based features work but when accessed with https it lacks all styling from css stylesheet. I need to get this working so I can load a much more complex app that needs css and other static folder-stored features.\n\nThe file structure is:\n\n```\n/home//application\n- main.py\n- static\n |_ css\n |_ bootstrap\n- templates\n |_ index.html\n```\n\nmain.py:\n\n```\nimport fastapi\nimport uvicorn\nfrom fastapi import Request\nfrom fastapi.responses import HTMLResponse\nfrom fastapi.staticfiles import StaticFiles\nfrom fastapi.templating import Jinja2Templates\n\napi = fastapi.FastAPI()\n\napi.mount('/static', StaticFiles(directory='static'), name='static')\ntemplates = Jinja2Templates(directory=\"templates\")\n\n@api.get('/')\n@api.get('/index', response_class=HTMLResponse)\ndef index(request: Request):\n message = None\n return templates.TemplateResponse(\"index.html\", {\"request\": request,\n 'message': message})\n\nif __name__ == '__main__':\n uvicorn.run(api, port=8000, host='127.0.0.1')\n```\n\nnginx is at /etc/nginx/sites-enabled/.nginx\n\n```\nserver {\n listen 80;\n server_name www..com .com;\n server_tokens off;\n charset utf-8;\n\n location / {\n try_files $uri @yourapplication;\n }\n\n location /static {\n gzip on;\n gzip_buffers 8 256k;\n\n alias /home//application/static;\n expires 365d;\n }\n\n location @yourapplication {\n gzip on;\n gzip_buffers 8 256k;\n\n proxy_pass http://127.0.0.1:8000;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-Protocol $scheme;\n }\n }\n\nserver {\n listen 443 ssl;\n server_name www..com;\n ssl_certificate /etc/letsencrypt/live/.com/fullchain.pem; # mana>\n ssl_certificate_key /etc/letsencrypt/live/.com/privkey.pem; # ma>\n include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot\n ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot\n\n location / {\n try_files $uri @yourapplication;\n }\n\n location /static {\n gzip on;\n gzip_buffers 8 256k;\n\n alias /home//application/static;\n expires 365d;\n }\n\n location @yourapplication {\n gzip on;\n gzip_buffers 8 256k;\n\n proxy_pass http://127.0.0.1:8000;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-Protocol $scheme;\n }\n}\n```\n\nand am serving using supervisor script:\n\n```\n[program:api]\ndirectory=/home//application\ncommand=gunicorn -b 127.0.0.1:8000 -w 4 -k uvicorn.workers.UvicornWorker main:api\nenvironmentenvironment=PYTHONPATH=1\nautostart=true\nautorestart=true\nstopasgroup=true\nkillasgroup=true\nstderr_logfile=/var/log/app/app.err.log\nstdout_logfile=/var/log/app/app.out.log\n```\n\nThe css stylesheet is called in the html using url_for like this:\n\n```\n\n```\n\nI have tried a whole host of modifications to the location /static block in nginx including:\n\n- adding slash after static in either line or both\n\n- trying to add https://static or https://www..com/home//application/static\n\n- adding and removing the location static from the http and https lines\n\n- changing proxy_pass to https://127.0.0.1:8000;\n\n- added root /home//application to the server section\n\nI have loaded this server twice, once letting certbot modify the nginx file the second, and current configuration, where I did it manually. I am at a complete loss on what to do.\n\n========================================\n\nTop Answer:\nI'd think you want the server to handle it. If you just setup a separate block on port 80 to convert all requests to 443 (HTTPS) permanently, you'd be good:\n\n```\nserver {\n listen 80;\n server_name yourserver.com;\n return 301 https://yourserver.com$request_uri;\n}\n\nserver {\n listen 443 ssl http2;\n server_name yourserver.com;\n ...\n}```\n```\n\n========================================\n\nCode:\n```text\n/home/<user_name>/application\n- main.py\n- static\n |_ css\n |_ bootstrap\n- templates\n |_ index.html\n```\n\n```text\nimport fastapi\nimport uvicorn\nfrom fastapi import Request\nfrom fastapi.responses import HTMLResponse\nfrom fastapi.staticfiles import StaticFiles\nfrom fastapi.templating import Jinja2Templates\n\n\napi = fastapi.FastAPI()\n\napi.mount('/static', StaticFiles(directory='static'), name='static')\ntemplates = Jinja2Templates(directory=\"templates\")\n\n\n@api.get('/')\n@api.get('/index', response_class=HTMLResponse)\ndef index(request: Request):\n message = None\n return templates.TemplateResponse(\"index.html\", {\"request\": request,\n 'message': message})\n\n\nif __name__ == '__main__':\n uvicorn.run(api, port=8000, host='127.0.0.1')\n```\n\n```text\nserver {\n listen 80;\n server_name www.<my_url>.com <my_url>.com;\n server_tokens off;\n charset utf-8;\n\n location / {\n try_files $uri @yourapplication;\n }\n\n location /static {\n gzip on;\n gzip_buffers 8 256k;\n\n alias /home/<user_name>/application/static;\n expires 365d;\n }\n\n\n location @yourapplication {\n gzip on;\n gzip_buffers 8 256k;\n\n proxy_pass http://127.0.0.1:8000;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-Protocol $scheme;\n }\n }\n\nserver {\n listen 443 ssl;\n server_name www.<my_url>.com;\n ssl_certificate /etc/letsencrypt/live/<my_url>.com/fullchain.pem; # mana>\n ssl_certificate_key /etc/letsencrypt/live/<my_url>.com/privkey.pem; # ma>\n include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot\n ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot\n\n location / {\n try_files $uri @yourapplication;\n }\n\n location /static {\n gzip on;\n gzip_buffers 8 256k;\n\n alias /home/<user_name>/application/static;\n expires 365d;\n }\n\n location @yourapplication {\n gzip on;\n gzip_buffers 8 256k;\n\n proxy_pass http://127.0.0.1:8000;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-Protocol $scheme;\n }\n}\n```\n\n```text\n[program:api]\ndirectory=/home/<user_name>/application\ncommand=gunicorn -b 127.0.0.1:8000 -w 4 -k uvicorn.workers.UvicornWorker main:api\nenvironmentenvironment=PYTHONPATH=1\nautostart=true\nautorestart=true\nstopasgroup=true\nkillasgroup=true\nstderr_logfile=/var/log/app/app.err.log\nstdout_logfile=/var/log/app/app.out.log\n```\n\n```text\n<link href=\"{{ url_for('static', path='/css/ATB_style.css') }}\" rel=\"stylesheet\">\n```\n\n```text\n<meta http-equiv=\"Content-Security-Policy\" content=\"upgrade-insecure-requests\">\n```\n\n```text\n<link href=\"{{ url_for('static', path='/css/MH_style.css') }}\" rel=\"stylesheet\">\n```\n\n```text\n<link rel=\"stylesheet\" href=\"/static/css/MH_style.css\"/>\n```\n\n```text\nserver {\n listen 80;\n server_name yourserver.com;\n return 301 https://yourserver.com$request_uri;\n}\n\nserver {\n listen 443 ssl http2;\n server_name yourserver.com;\n ...\n}```\n```\n\n```text\nhttp {\n upstream myapp {\n server application_container:4001;\n }\n\n server {\n\n listen 80;\n server_name localhost;\n\n location / {\n ...\n }\n\n location /myapp/ {\n proxy_pass http://myapp;\n ...\n }\n\n location /static/ {\n proxy_pass http://myapp;\n alias ...\n }\n}\n```\n\n```text\nupstream\n```\n\n```text\nproxy_pass\n```\n\n```text\nadd_header Content-Security-Policy upgrade-insecure-requests;\n```\n\n========================================\n\nComments:\n- browser will block resoures loaded by HTTP request if you visit a HTTPS URL. make sure your img/css/js URL not hardcoded with `http://`\n- Everything looks okay. Tries to add a trailing slash in both server https as well as http. Then also change the root directory to your applications directory. Just tries to restart the server. With systemctl. Remember you need to restart both. Nginx and also gunicorn. And please file serving via your fastapi app because nginx is fast in terms on file sharing. After ping me if it still not fixed.\n- Add this to your html page. If you really have hardcode http urls problems. It will redirect all http requests to https.\n- @emptyhua, thanks, I am using url_for, edited the question to show the actual line.\n- @AkramKhan, thank you, adding the meta did the trick. WOW!\n- @Brad Allen so you have hard coded http route in your website. A better is not to rely on meta tag. Just find the http route in website. And change that to https.\n- @AdramKhan, this is really puzzling as I pulled almost everything out, searched through all files for http and all references are https. The only thing I can think of is some sort of call in a python dependency. I'm lost without the meta http-equivalent.\n- @AdamKhan, kept troubleshooting as you advised, found root cause and posted edited answer. Thank you for the help.\n- You, sir, saved my day - spent the better part of a working day hunting for a solution to this problem.\n- Changed the port 80 to a redirect, as in this answer, then commented out the meta http-equivalent line in the html. The redirect works great but lost the static directory access again and was not using the css style sheet. Added the http-equivalent line back and it worked with the redirect. Would love to figure out what I've got different than, apparently, everyone else and causes this problem.\n- Is there any chance this is related to using Bootstrap 4.1 from disk (in the static folder as well)?\n- Kenndy, I followed your advice and found the direct http call. Edited answer to show result.","metadata":{"transformedAt":"2026-08-18T18:32:29.122Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":13,"totalLines":365,"estimatedTokens":2506}}321{"id":"stack-70521784","source":"stackoverflow","questionId":70521784,"title":"FastAPI links created by url_for in Jinja2 template use HTTP instead of HTTPS","tags":["https","jinja2","fastapi","uvicorn"],"text":"Title: FastAPI links created by url_for in Jinja2 template use HTTP instead of HTTPS\nTags: https, jinja2, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI migrated an application in Flask served by waitress to FastAPI served by uvicorn, but I can't force the links (generated by url_for inside the index.html template) to use HTTPS instead of HTTP.\n\nWith waitress I used:\n\n```\nfrom waitress import serve\nimport flask_app\n\nPORT=5000\nHOST_IP_ADDRESS='0.0.0.0'\n\nserve(flask_app.app, host=HOST_IP_ADDRESS, port=PORT, url_scheme=\"https\")\n```\n\nwith uvicorn I tried to use proxy_headers, but that didn't work. I used a workaround in the index.html\n\n```\n\n```\n\nwhich correctly loaded the style.css from static files, but the links to another endpoint still use HTTP.\n\nIs there an easy way to force all links created by url_for to use HTTPS?\n\n========================================\n\nTop Answer:\nI had the same problems. On develop environment all links were with http.\nI solved it this way.\n\n```\nfrom starlette.templating import Jinja2Templates\nfrom sqladmin import Admin\nfrom jinja2 import ChoiceLoader, FileSystemLoader, PackageLoader\nimport jinja2\nif hasattr(jinja2, \"pass_context\"):\n pass_context = jinja2.pass_context\nelse:\n pass_context = jinja2.contextfunction\n\n@pass_context\ndef https_url_for(context: dict, name: str, **path_params) -> str:\n request = context[\"request\"]\n http_url = request.url_for(name, **path_params)\n return http_url.replace(\"http\", \"https\", 1)\n\nclass CustomAdmin(Admin):\n def init_templating_engine(self) -> Jinja2Templates:\n templates = Jinja2Templates(\"templates\")\n loaders = [\n FileSystemLoader(self.templates_dir),\n PackageLoader(\"sqladmin\", \"templates\"),\n ]\n\n templates.env.loader = ChoiceLoader(loaders)\n templates.env.globals[\"min\"] = min\n templates.env.globals[\"zip\"] = zip\n templates.env.globals[\"admin\"] = self\n templates.env.globals[\"is_list\"] = lambda x: isinstance(x, list)\n templates.env.globals[\"url_for\"] = https_url_for\n return templates\n```\n\nAfter all just import this class in main file and init the admin class\n\n========================================\n\nCode:\n```text\nfrom waitress import serve\nimport flask_app\n\nPORT=5000\nHOST_IP_ADDRESS='0.0.0.0'\n\nserve(flask_app.app, host=HOST_IP_ADDRESS, port=PORT, url_scheme=\"https\")\n```\n\n```text\n<meta http-equiv=\"Content-Security-Policy\" content=\"upgrade-insecure-requests\">\n```\n\n```py\ntemplate = Jinja2Templates(\"/path/to/templates\")\n\ndef https_url_for(request: Request, name: str, **path_params: Any) -> str:\n\n http_url = request.url_for(name, **path_params)\n\n # Replace 'http' with 'https'\n return http_url.replace(\"http\", \"https\", 1)\n\ntemplate.env.globals[\"https_url_for\"] = https_url_for\n```\n\n```text\nhttps_url_for(request, \"/https/path\", search=\"hi\")\n```\n\n```text\nurl_for\n```\n\n```text\nurl_for\n```\n\n```text\nhttps://<domain>/https/path?search=hi\n```\n\n```text\nfrom starlette.templating import Jinja2Templates\nfrom sqladmin import Admin\nfrom jinja2 import ChoiceLoader, FileSystemLoader, PackageLoader\nimport jinja2\nif hasattr(jinja2, \"pass_context\"):\n pass_context = jinja2.pass_context\nelse:\n pass_context = jinja2.contextfunction\n\n\n@pass_context\ndef https_url_for(context: dict, name: str, **path_params) -> str:\n request = context[\"request\"]\n http_url = request.url_for(name, **path_params)\n return http_url.replace(\"http\", \"https\", 1)\n\n\nclass CustomAdmin(Admin):\n def init_templating_engine(self) -> Jinja2Templates:\n templates = Jinja2Templates(\"templates\")\n loaders = [\n FileSystemLoader(self.templates_dir),\n PackageLoader(\"sqladmin\", \"templates\"),\n ]\n\n templates.env.loader = ChoiceLoader(loaders)\n templates.env.globals[\"min\"] = min\n templates.env.globals[\"zip\"] = zip\n templates.env.globals[\"admin\"] = self\n templates.env.globals[\"is_list\"] = lambda x: isinstance(x, list)\n templates.env.globals[\"url_for\"] = https_url_for\n return templates\n```\n\n```text\nfrom fastapi import Request \nfrom fastapi.templating import Jinja2Templates\nfrom jinja2 import pass_context\n\n\n@pass_context\ndef urlx_for(context: dict, name: str, **path_params: Any, ) -> str:\n request: Request = context['request']\n http_url = request.url_for(name, **path_params)\n if scheme := request.headers.get('x-forwarded-proto'):\n return http_url.replace(scheme=scheme)\n return http_url\n\n\ntemplates = Jinja2Templates(directory=\"core/templates\")\ntemplates.env.globals['url_for'] = urlx_for\n```\n\n```text\n@pass_context\n```\n\n========================================\n\nComments:\n- Please have a look at this answer.\n- Perfect, this workaround worked for me. Just to complete the final code: I had links in jinja in format `url_for('fastapi_function_name', kwarg1='something', kwarg2='somethingelse')`. I modified it to your https_url_for function and added the request as first argument: `https_url_for(request, 'fastapi_function_name', kwarg1='something', kwarg2='somethingelse')`. The stylesheet and images inside the html still stay the same: `{{ url_for('static', path='css/style.css') }}` if `app.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")` and the same for images\n- Wow, what a frustrating limitation. Is there any better official fix from jinja2 upstream?","metadata":{"transformedAt":"2026-08-18T18:32:29.122Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":10,"totalLines":180,"estimatedTokens":1323}}322{"id":"stack-67307265","source":"stackoverflow","questionId":67307265,"title":"Where to put depends/ dependendies for authentication in Fastapi?","tags":["python","python-3.x","authentication","fastapi"],"text":"Title: Where to put depends/ dependendies for authentication in Fastapi?\nTags: python, python-3.x, authentication, fastapi\nSource: Stack Overflow\n\nQuestion:\nI've seen two different methods of using *depends* in Fastapi authentication:\n\nMethod 1:\n\n```\n@app.get('/api/user/me')\nasync def user_me(user: dict = Depends(auth)):\n return user\n```\n\nand method 2:\n\n```\n@app.get('/api/user/me', dependencies=[Depends(auth)])\nasync def user_me(user: dict):\n return user\n```\n\nWhat is the difference between method 1 and method 2 and which is better for securing an API i.e. requiring authentication?\n\n========================================\n\nTop Answer:\nIn some cases you don't really need the return value of a dependency inside your path operation function. Or the dependency doesn't return a value. But you still need it to be executed/solved. For those cases, instead of declaring a path operation function parameter with Depends, you can add a list of dependencies to the path operation decorator.\n\nMore detail and tips can be found in here: https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-in-path-operation-decorators/\n\n========================================\n\nCode:\n```text\n@app.get('/api/user/me')\nasync def user_me(user: dict = Depends(auth)):\n return user\n```\n\n```text\n@app.get('/api/user/me', dependencies=[Depends(auth)])\nasync def user_me(user: dict):\n return user\n```\n\n```text\nasync def get_current_user(token: str = Depends(oauth2_scheme)):\n user = fake_decode_token(token)\n return user\n\n\n@app.get(\"/users/me\")\nasync def read_users_me(current_user: User = Depends(get_current_user)):\n return current_user\n```\n\n```text\nasync def get_token_header(x_token: str = Header(...)):\n if x_token != \"fake-super-secret-token\":\n raise HTTPException(status_code=400, detail=\"X-Token header invalid\")\n\nrouter = APIRouter(\n prefix=\"/items\",\n tags=[\"items\"],\n dependencies=[Depends(get_token_header)],\n responses={404: {\"description\": \"Not found\"}},\n)\n```\n\n```text\nAPIRouter\n```\n\n========================================\n\nComments:\n- please explain `Header(...)`\n- This is the header `x_token` declaration without a default value, as required.\n- I was assuming that adding `get_current_user` in the router level dependency will allow me to get the logged in user in my view functions. Instead, I have to specify the dependency in all of my path operations. I think FastAPI fails here while following DRY principle (as they have repeatedly claimed that FastAPI focuses on DRY).","metadata":{"transformedAt":"2026-08-18T18:32:29.122Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":5,"totalLines":81,"estimatedTokens":630}}323{"id":"stack-70104983","source":"stackoverflow","questionId":70104983,"title":"How to use ApScheduler correctly in FastAPI?","tags":["python-3.x","fastapi","apscheduler","uvicorn"],"text":"Title: How to use ApScheduler correctly in FastAPI?\nTags: python-3.x, fastapi, apscheduler, uvicorn\nSource: Stack Overflow\n\nQuestion:\n```\nfrom fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware\nimport uvicorn\nimport time\nfrom loguru import logger\nfrom apscheduler.schedulers.background import BackgroundScheduler\n\napp = FastAPI()\napp.add_middleware(\n CORSMiddleware,\n allow_origins=[\"*\"],\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n\ntest_list = [\"1\"]*10\n\ndef check_list_len():\n global test_list\n while True:\n time.sleep(5)\n logger.info(f\"check_list_len:{len(test_list)}\")\n\n@app.on_event('startup')\ndef init_data():\n scheduler = BackgroundScheduler()\n scheduler.add_job(check_list_len, 'cron', second='*/5')\n scheduler.start()\n\n@app.get(\"/pop\")\nasync def list_pop():\n global test_list\n test_list.pop(1)\n logger.info(f\"current_list_len:{len(test_list)}\")\n\nif __name__ == '__main__':\n uvicorn.run(app=\"main3:app\", host=\"0.0.0.0\", port=80, reload=False, debug=False)\n```\n\nAbove is my code, I want to take out a list of elements through get request, and set a periodic task constantly check the number of elements in the list, but when I run, always appear the following error:\n\n```\nExecution of job \"check_list_len (trigger: cron[second='*/5'], next run at: 2021-11-25 09:48:50 CST)\" skipped: maximum number of running instances reached (1)\n2021-11-25 09:48:50.016 | INFO | main3:check_list_len:23 - check_list_len:10\nExecution of job \"check_list_len (trigger: cron[second='*/5'], next run at: 2021-11-25 09:48:55 CST)\" skipped: maximum number of running instances reached (1)\n2021-11-25 09:48:55.018 | INFO | main3:check_list_len:23 - check_list_len:10\nINFO: 127.0.0.1:55961 - \"GET /pop HTTP/1.1\" 200 OK\n2021-11-25 09:48:57.098 | INFO | main3:list_pop:35 - current_list_len:9\nExecution of job \"check_list_len (trigger: cron[second='*/5'], next run at: 2021-11-25 09:49:00 CST)\" skipped: maximum number of running instances reached (1)\n2021-11-25 09:49:00.022 | INFO | main3:check_list_len:23 - check_list_len:9\n```\n\nIt looks like I started two scheduled tasks and only one succeeded, but I started only one task. How do I avoid this\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware\nimport uvicorn\nimport time\nfrom loguru import logger\nfrom apscheduler.schedulers.background import BackgroundScheduler\n\napp = FastAPI()\napp.add_middleware(\n CORSMiddleware,\n allow_origins=[\"*\"],\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n\ntest_list = [\"1\"]*10\n\ndef check_list_len():\n global test_list\n while True:\n time.sleep(5)\n logger.info(f\"check_list_len:{len(test_list)}\")\n\n@app.on_event('startup')\ndef init_data():\n scheduler = BackgroundScheduler()\n scheduler.add_job(check_list_len, 'cron', second='*/5')\n scheduler.start()\n\n@app.get(\"/pop\")\nasync def list_pop():\n global test_list\n test_list.pop(1)\n logger.info(f\"current_list_len:{len(test_list)}\")\n\n\nif __name__ == '__main__':\n uvicorn.run(app=\"main3:app\", host=\"0.0.0.0\", port=80, reload=False, debug=False)\n```\n\n```text\nExecution of job \"check_list_len (trigger: cron[second='*/5'], next run at: 2021-11-25 09:48:50 CST)\" skipped: maximum number of running instances reached (1)\n2021-11-25 09:48:50.016 | INFO | main3:check_list_len:23 - check_list_len:10\nExecution of job \"check_list_len (trigger: cron[second='*/5'], next run at: 2021-11-25 09:48:55 CST)\" skipped: maximum number of running instances reached (1)\n2021-11-25 09:48:55.018 | INFO | main3:check_list_len:23 - check_list_len:10\nINFO: 127.0.0.1:55961 - \"GET /pop HTTP/1.1\" 200 OK\n2021-11-25 09:48:57.098 | INFO | main3:list_pop:35 - current_list_len:9\nExecution of job \"check_list_len (trigger: cron[second='*/5'], next run at: 2021-11-25 09:49:00 CST)\" skipped: maximum number of running instances reached (1)\n2021-11-25 09:49:00.022 | INFO | main3:check_list_len:23 - check_list_len:9\n```\n\n```text\ndef check_list_len():\n global test_list # you really don't need this either, since you're not reassigning the variable\n logger.info(f\"check_list_len:{len(test_list)}\")\n```\n\n```text\ncheck_list_len\n```\n\n```text\napscheduler\n```\n\n```text\napscheduler\n```\n\n========================================\n\nComments:\n- Thank you very much for your answer. I thought it was a framework problem, but it was a low-level code problem. I'm sorry.@MatsLindh","metadata":{"transformedAt":"2026-08-18T18:32:29.122Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":6,"totalLines":139,"estimatedTokens":1123}}324{"id":"stack-66265511","source":"stackoverflow","questionId":66265511,"title":"How to return image and json in one response in fastapi?","tags":["python","fastapi"],"text":"Title: How to return image and json in one response in fastapi?\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI get an image, change it, then it is classified using a neural network, should return a new image and json with a response. How to do it with one endpoint?\nimage is returned with Streaming Response but how to add json to it?\n\n```\nimport io\nfrom starlette.responses import StreamingResponse\n\napp = FastAPI()\n\n@app.post(\"/predict\")\ndef predict(file: UploadFile = File(...)):\n img = file.read()\n new_image = prepare_image(img)\n result = predict(new_image)\n return StreamingResponse(io.BytesIO(new_image.tobytes()), media_type=\"image/png\")\n```\n\n========================================\n\nTop Answer:\nI was having the same issue, although, my file was stored locally but still I have to return JSON, and Image in a single response.\n\nThis worked for me, much neater and shorter:\n\n```\n@app.post(\"/ImgAndJSON\")\n# Postmsg is a Pydantic model having 1 str field\ndef ImgAndJSON(message:PostMsg):\n\n results={\"message\":\"This is just test message\"}\n\n return FileResponse('path/to/file.png',headers=results)\n```\n\n========================================\n\nCode:\n```text\nimport io\nfrom starlette.responses import StreamingResponse\n\napp = FastAPI()\n\n@app.post(\"/predict\")\ndef predict(file: UploadFile = File(...)):\n img = file.read()\n new_image = prepare_image(img)\n result = predict(new_image)\n return StreamingResponse(io.BytesIO(new_image.tobytes()), media_type=\"image/png\")\n```\n\n```text\n@app.post(\"/predict\")\ndef predict(file: UploadFile = File(...)):\n img = file.read()\n new_image = prepare_image(img)\n result = predict(new_image)\n return StreamingResponse(io.BytesIO(new_image.tobytes()), media_type=\"image/png\")\n```\n\n```text\n@app.post(\"/predict/\")\ndef predict(file: UploadFile = File(...)):\n file_bytes = file.file.read()\n image = Image.open(io.BytesIO(file_bytes))\n new_image = prepare_image(image)\n result = predict(image)\n bytes_image = io.BytesIO()\n new_image.save(bytes_image, format='PNG')\n return Response(content = bytes_image.getvalue(), headers = result, media_type=\"image/png\")\n```\n\n```text\n@app.post(\"/ImgAndJSON\")\n# Postmsg is a Pydantic model having 1 str field\ndef ImgAndJSON(message:PostMsg):\n\n results={\"message\":\"This is just test message\"}\n\n return FileResponse('path/to/file.png',headers=results)\n```\n\n```text\n@app.post(\"/detect\")\nasync def detect_and_return_image(image_file: UploadFile = File(...)):\n \"\"\"\n Handler of /detect POST endpoint\n Receives uploaded file with a name \"image_file\",\n passes it through YOLOv8 object detection\n network and returns an array of bounding boxes.\n :return: a JSON array of objects bounding\n boxes in format\n [[x1,y1,x2,y2,object_type,probability],..]\n \"\"\"\n buf = await image_file.read()\n boxes, class_prob = detect_objects_on_image(Image.open(BytesIO(buf)))\n print(f'class proba {class_prob}')\n annotated_image = annotate_image(Image.open(BytesIO(buf)), boxes)\n return {\n \"annotated_image\": image_to_base64(annotated_image),\n \"class_prob\": class_prob\n }\n\n\ndef detect_objects_on_image(image):\n \"\"\"\n Function receives an image,\n passes it through YOLOv8 neural network\n and returns an array of detected objects\n and their bounding boxes\n :param image: Input image\n :return: Array of bounding boxes in format\n [[x1,y1,x2,y2,object_type,probability],..]\n \"\"\"\n model = YOLO('best.pt')\n results = model.predict(image)\n result = results[0]\n output = []\n class_prob = []\n for box in result.boxes:\n x1, y1, x2, y2 = [round(x) for x in box.xyxy[0].tolist()]\n class_id = box.cls[0].item()\n prob = round(box.conf[0].item(), 2)\n output.append([x1, y1, x2, y2, result.names[class_id], prob])\n class_prob.append([result.names[class_id], prob])\n return output, class_prob\n\n\ndef annotate_image(image, boxes):\n \"\"\"\n Function annotates the image with bounding boxes.\n :param image: Input image\n :param boxes: Array of bounding boxes in format\n [[x1,y1,x2,y2,object_type,probability],..]\n :return: Annotated image\n \"\"\"\n # Draw bounding boxes on the image\n draw = ImageDraw.Draw(image)\n for box in boxes:\n x1, y1, x2, y2, object_type, probability = box\n draw.rectangle([(x1, y1), (x2, y2)], outline=\"red\", width=3)\n draw.text((x1, y1 - 10), f\"{object_type} ({probability})\", fill=\"red\")\n\n return image\n\n\ndef save_annotated_image(image):\n \"\"\"\n Function saves the annotated image and returns\n the image as a response.\n :param image: Annotated image\n :return: StreamingResponse with the image\n \"\"\"\n output_buffer = BytesIO()\n image.save(output_buffer, format=\"PNG\")\n output_buffer.seek(0)\n return StreamingResponse(output_buffer, media_type=\"image/png\")\n\ndef image_to_base64(image):\n buffered = BytesIO()\n image.save(buffered, format=\"PNG\")\n return base64.b64encode(buffered.getvalue()).decode('utf-8')\n```\n\n========================================\n\nComments:\n- Can you provide what your desired json response looks like?\n- json of this kind : { 'objects': { 'object1': { 'x' : 5 , 'y': 3 }, 'object2': { 'x' : 5 , 'y': 3 }}}\n- What is `objects`, what does represent `x` and `y` (you have 2 times the same coordinates) ?\n- this is just an example of what json looks like, objects and x, y have nothing to do with the question, the question is how to send the response image and this json together\n- Possible solution\n- This works well but returning an image in base64 format increases the size of that image i.e, approximately 33% which is huge and it also add the overhead of encoding and decoding the image. Real-time application with this approach can become less efficient if we do like this. Returning in binary form is a better approach.","metadata":{"transformedAt":"2026-08-18T18:32:29.122Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":5,"totalLines":178,"estimatedTokens":1468}}325{"id":"stack-65983012","source":"stackoverflow","questionId":65983012,"title":"AIOHTTP having request body/content/text when calling raise_for_status","tags":["python","aiohttp","fastapi"],"text":"Title: AIOHTTP having request body/content/text when calling raise_for_status\nTags: python, aiohttp, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm using `FastAPI` with `aiohttp`, I built a singleton for a persistent session and I'm using it for opening the session at startup and closing it at shutdown.\n\n**Demand**: The `response` body is precious in **case of a failure** I must log it with the other details.\n\nBecause how `raise_for_status` behave I had to write those ugly functions which handle each HTTP method, this is one of them:\n\n```\nasync def post(self, url: str, json: dict, headers: dict) -> ClientResponse:\n response = await self.session.post(url=url, json=json, headers=headers)\n response_body = await response.text()\n\n try:\n response.raise_for_status()\n except Exception:\n logger.exception('Request failed',\n extra={'url': url, 'json': json, 'headers': headers, 'body': response_body})\n raise\n\n return response\n```\n\nIf I could count on `raise_for_status` to return also the body (`response.text()`),\nI just could initiate the session `ClientSession(raise_for_status=True)` and write a clean code:\n\n```\nresponse = await self.session.post(url=url, json=json, headers=headers)\n```\n\nIs there a way to force somehow `raise_for_status` to return also the payload/body, maybe in the initialization of the `ClientSession`?\n\nThanks for the help.\n\n========================================\n\nCode:\n```text\nasync def post(self, url: str, json: dict, headers: dict) -> ClientResponse:\n response = await self.session.post(url=url, json=json, headers=headers)\n response_body = await response.text()\n\n try:\n response.raise_for_status()\n except Exception:\n logger.exception('Request failed',\n extra={'url': url, 'json': json, 'headers': headers, 'body': response_body})\n raise\n\n return response\n```\n\n```text\nresponse = await self.session.post(url=url, json=json, headers=headers)\n```\n\n```text\nFastAPI\n```\n\n```text\naiohttp\n```\n\n```text\nresponse\n```\n\n```text\nraise_for_status\n```\n\n```text\nraise_for_status\n```\n\n```text\nresponse.text()\n```\n\n```text\nClientSession(raise_for_status=True)\n```\n\n```text\nraise_for_status\n```\n\n```text\nClientSession\n```\n\n```text\ndef raise_on_4xx_5xx(response):\n response.raise_for_status()\n\nasync with httpx.AsyncClient(event_hooks={'response': [raise_on_4xx_5xx]}) as client:\n try:\n r = await client.get('http://httpbin.org/status/418')\n except httpx.HTTPStatusError as e:\n print(e.response.text)\n```\n\n```text\naiohttp\n```\n\n```text\nraise_for_status\n```\n\n========================================\n\nComments:\n- Thank you, eventually, `httpx` winning the race, the `raise_for_status`, the support for async tests ...","metadata":{"transformedAt":"2026-08-18T18:32:29.122Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":14,"totalLines":118,"estimatedTokens":680}}326{"id":"stack-68664973","source":"stackoverflow","questionId":68664973,"title":"Create SQLAlchemy session on event","tags":["python","sqlalchemy","fastapi"],"text":"Title: Create SQLAlchemy session on event\nTags: python, sqlalchemy, fastapi\nSource: Stack Overflow\n\nQuestion:\nIf I want to use database while processing a request, I make a Dependency Injection like this:\n\n```\n@app.post(\"/sample_test\")\nasync def sample_test(db: Session = Depends(get_db)):\n return db.query(models.User.height).all()\n```\n\nBut I cannot do it with events like this:\n\n```\n@app.on_event(\"startup\")\nasync def sample_test(db: Session = Depends(get_db)):\n return db.query(models.User.height).all()\n```\n\nbecause `starlette` events don't support Depends.\n\nThis is my `get_db()` function:\n\n```\ndef get_db():\n db = SessionLocal()\n try:\n yield db\n finally:\n db.close()\n```\n\njust like in FastAPI manual (https://fastapi.tiangolo.com/tutorial/sql-databases/).\n\nHow can I access `get_db()` inside my event function, so I can work with a Session?\n\nI've tried:\n\n```\n@app.on_event(\"startup\")\nasync def sample_test(db: Session = Depends(get_db)):\n db = next(get_db())\n return db.query(models.User.height).all()\n```\n\nbut it doesn't work.\n\nI use MSSQL, if it's important.\n\n========================================\n\nCode:\n```text\n@app.post(\"/sample_test\")\nasync def sample_test(db: Session = Depends(get_db)):\n return db.query(models.User.height).all()\n```\n\n```text\n@app.on_event(\"startup\")\nasync def sample_test(db: Session = Depends(get_db)):\n return db.query(models.User.height).all()\n```\n\n```text\ndef get_db():\n db = SessionLocal()\n try:\n yield db\n finally:\n db.close()\n```\n\n```text\n@app.on_event(\"startup\")\nasync def sample_test(db: Session = Depends(get_db)):\n db = next(get_db())\n return db.query(models.User.height).all()\n```\n\n```text\nstarlette\n```\n\n```text\nget_db()\n```\n\n```text\nget_db()\n```\n\n```py\n@app.on_event(\"startup\")\nasync def sample_test():\n with SessionLocal() as db:\n return db.query(models.User.height).all()\n```\n\n```text\nSessionLocal\n```\n\n========================================\n\nComments:\n- ahh, so easy, yet so hard to come up to... thanks man!","metadata":{"transformedAt":"2026-08-18T18:32:29.122Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":109,"estimatedTokens":502}}327{"id":"stack-68486025","source":"stackoverflow","questionId":68486025,"title":"FastAPI route: Adding dynamic path parameters validation","tags":["python-3.x","validation","server","fastapi"],"text":"Title: FastAPI route: Adding dynamic path parameters validation\nTags: python-3.x, validation, server, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm trying to add validation to my route in a fastapi server, followed the instructions here and managed to have added validation on my int path parameters like so:\n\n```\nroute1 = router.get(\"/start={start:int}/end={end:int}\")(route1_func)\n```\n\nand my `route1_func`:\n\n```\nasync def route1_func(request: Request,\n start: int = Path(..., title=\"my start\", ge=1),\n end: int = Path(..., title=\"my end\", ge=1)):\n if end and this works great... but i would like to validate the `end > start` if possible as part of the definition, instead of checking this after going into `route1_func`\n\nis this possible?\n\n========================================\n\nTop Answer:\nYou can use your validator function as dependency. The function parameters must be the same as in the path\n\n```\ndef check(start: int, end: int):\n print(start, end)\n if start > end:\n raise HTTPException(status_code=400, detail='error message')\n\n@router.get('/{start}/{end}', dependencies=[Depends(check)])\nasync def start_end(\n start: int,\n end: int\n):\n return start, end\n```\n\n========================================\n\nCode:\n```text\nroute1 = router.get(\"/start={start:int}/end={end:int}\")(route1_func)\n```\n\n```text\nasync def route1_func(request: Request,\n start: int = Path(..., title=\"my start\", ge=1),\n end: int = Path(..., title=\"my end\", ge=1)):\n if end <= start:\n raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST)\n else:\n return True\n```\n\n```text\nroute1_func\n```\n\n```text\nend > start\n```\n\n```text\nroute1_func\n```\n\n```text\nclass Route1Request(BaseModel):\n start: int = Query(..., title=\"my start\", ge=1)\n end: int = Query(..., title=\"my end\", ge=1)\n\n @root_validator\n def verify_start_end(cls, vals: dict) -> dict:\n assert vals.get(\"end\", 0) > vals.get(\"start\", 0)\n return vals\n\n@router.get(\"/\")\nasync def route1(route1_data: Route1Request = Depends()):\n return True\n```\n\n```text\n= Depends()\n```\n\n```text\nQuery\n```\n\n```text\nPath\n```\n\n```text\ndef check(start: int, end: int):\n print(start, end)\n if start > end:\n raise HTTPException(status_code=400, detail='error message')\n\n\n@router.get('/{start}/{end}', dependencies=[Depends(check)])\nasync def start_end(\n start: int,\n end: int\n):\n return start, end\n```\n\n========================================\n\nComments:\n- When I try this Pydantic throws a `ValidationError`, but it's *not* caught by FastAPI and automatically turned into a `RequestValidationError`, so instead of a nice 422 status code with diagnostics I get a plain **Internal Server Error**. The solution seems to be explicitly to `raise RequestValidationError([ErrorWrapper(ex, (\"path\"))])` in the validator. Does anyone know if this is the correct approach?\n- @IanGoldby yes, this is a longstanding problem when using Depends() for query params: github.com/tiangolo/fastapi/issues/1474 It works fine for request bodies. It looks like you're using the recommended workaround. (I haven't needed this myself.)\n- `root_validator` has been deprecated\n- Please explain your solution. Code only is not an answer.","metadata":{"transformedAt":"2026-08-18T18:32:29.123Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":10,"totalLines":118,"estimatedTokens":810}}328{"id":"stack-76012644","source":"stackoverflow","questionId":76012644,"title":"FastAPI / uvicorn (or hypercorn): where is my root-path?","tags":["python","fastapi","uvicorn","hypercorn"],"text":"Title: FastAPI / uvicorn (or hypercorn): where is my root-path?\nTags: python, fastapi, uvicorn, hypercorn\nSource: Stack Overflow\n\nQuestion:\nBased on a few FastAPI tutorials, including this, I made a simple FastAPI app:\n\n```\nfrom fastapi import FastAPI, Request\napp = FastAPI() # also tried FastAPI(root_path=\"/api/v1\")\n\n@app.get(\"/app\")\ndef read_main(request: Request):\n return {\"message\": \"Hello World\", \"root_path\": request.scope.get(\"root_path\")}\n```\n\nWhich I want to have at a path other than root (e.g. `/api/vi`). Again based on most tutorials and common sense, I tried to start it with e.g.:\n\n```\nuvicorn main:app --root-path /api/v1\n```\n\nThe service comes up ok (on `http://127.0.0.1:8000`), however, the `root-path` seems to be ignored, i.e., any `GET` request to `http://127.0.0.1:8000/` gives:\n\n```\nmessage \"Hello World\"\nroot_path \"/api/v1\"\n```\n\nand any `GET` request to `http://127.0.0.1:8000/api/v1` gives:\n\n```\ndetail \"Not Found\"\n```\n\nI would expect the requests to produce the reverse outcomes. What is going on here?!\n\nI also tried initializing FastAPI with `FastAPI(root_path=\"/api/v1\")`, as well as switching to `hypercorn` without avail.\n\nDetails of the versions of apps (I might have tried a few others as well, though these should be the latest tried):\n\n```\npython 3.9.7 hf930737_3_cpython conda-forge\nfastapi 0.85.1 pyhd8ed1ab_0 conda-forge\nuvicorn 0.20.0 py39h06a4308_0 \nhypercorn 0.14.3 py39hf3d152e_1 conda-forge\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI, Request\napp = FastAPI() # also tried FastAPI(root_path=\"/api/v1\")\n\n@app.get(\"/app\")\ndef read_main(request: Request):\n return {\"message\": \"Hello World\", \"root_path\": request.scope.get(\"root_path\")}\n```\n\n```text\nuvicorn main:app --root-path /api/v1\n```\n\n```text\nmessage \"Hello World\"\nroot_path \"/api/v1\"\n```\n\n```text\ndetail \"Not Found\"\n```\n\n```text\npython 3.9.7 hf930737_3_cpython conda-forge\nfastapi 0.85.1 pyhd8ed1ab_0 conda-forge\nuvicorn 0.20.0 py39h06a4308_0 \nhypercorn 0.14.3 py39hf3d152e_1 conda-forge\n```\n\n```text\n/api/vi\n```\n\n```text\nhttp://127.0.0.1:8000\n```\n\n```text\nroot-path\n```\n\n```text\nGET\n```\n\n```text\nhttp://127.0.0.1:8000/\n```\n\n```text\nGET\n```\n\n```text\nhttp://127.0.0.1:8000/api/v1\n```\n\n```text\nFastAPI(root_path=\"/api/v1\")\n```\n\n```text\nhypercorn\n```\n\n```text\nuvicorn main:app --root-path /api/v1\n```\n\n```text\napp = FastAPI(root_path=\"/api/v1\")\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.routing import APIRouter\n\n\nrouter = APIRouter()\n\n\n@router.get('/app')\ndef main():\n return 'Hello world!'\n\n\napp = FastAPI()\napp.include_router(router, prefix='/api/v1')\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.routing import APIRouter\n\n\nrouter_v1 = APIRouter()\nrouter_v2 = APIRouter()\n\n\n@router_v1.get('/app')\ndef main():\n return 'Hello world - v1'\n\n\n@router_v2.get('/app')\ndef main():\n return 'Hello world - v2'\n\n\napp = FastAPI()\n\napp.include_router(router_v1, prefix='/api/v1')\n\napp.include_router(router_v2, prefix='/api/v2')\napp.include_router(router_v2, prefix='/latest') # optional\n```\n\n```py\nfrom fastapi import FastAPI\n\napp = FastAPI()\nsubapi = FastAPI()\n\n\n@app.get('/app')\ndef read_main():\n return {'message': 'Hello World from main app'}\n \n \n@subapi.get('/app')\ndef read_sub():\n return {'message': 'Hello World from sub API'}\n\n\napp.mount('/api/v1', subapi)\n```\n\n```text\nroot_path\n```\n\n```text\n--root-path\n```\n\n```text\n/app\n```\n\n```text\n/api/v1\n```\n\n```text\n/app\n```\n\n```text\n/api/v1/app\n```\n\n```text\n/app\n```\n\n```text\n/app\n```\n\n```text\n/api/v1\n```\n\n```text\n/openapi.json\n```\n\n```text\n/api/v1/openapi.json\n```\n\n```text\n/openapi.json\n```\n\n```text\n/api/v1\n```\n\n```text\n/api/v1/openapi.json\n```\n\n```text\n/api/v1\n```\n\n```text\n--root-path\n```\n\n```text\n--root-path\n```\n\n```text\nroot_path\n```\n\n```text\nAPIRouter\n```\n\n```text\nprefix\n```\n\n```text\nprefix\n```\n\n```text\n/\n```\n\n```text\nprefix\n```\n\n```text\nAPIRouter\n```\n\n```text\nrouter = APIRouter(prefix='/api/v1')\n```\n\n```text\n.include_router()\n```\n\n```text\n.include_router()\n```\n\n```text\n/api/v1\n```\n\n```text\n/api/latest\n```\n\n```text\n/app\n```\n\n```text\nprefix\n```\n\n```text\nroot_path\n```\n\n```text\nroot_path\n```\n\n```text\n/app\n```\n\n```text\n/app\n```\n\n========================================\n\nComments:\n- `root_path` does *not change the application prefix path*. It only instructs the swagger ui/openapi schema to prefix every request with a root path because *a proxy in between the client and the service* strips away that part (i.e. the request is being mapped between the schemes *by a proxy* in between). Use `api = APIRouter(prefix=\"/api/v1\"), app.include_router(api)` for example if you want to have a prefix to your routes. You can also give the prefix when calling `include_router` to make the router independent of its mounting point (`include_router(api, prefix=\"/api/v1\")` iirc.)\n- doesn't help, you still cant get the /docs endpoint","metadata":{"transformedAt":"2026-08-18T18:32:29.123Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":54,"totalLines":333,"estimatedTokens":1251}}329{"id":"stack-70730551","source":"stackoverflow","questionId":70730551,"title":"Pycharm debugger setup with FastApi and docker compose","tags":["python","docker","docker-compose","pycharm","fastapi"],"text":"Title: Pycharm debugger setup with FastApi and docker compose\nTags: python, docker, docker-compose, pycharm, fastapi\nSource: Stack Overflow\n\nQuestion:\nI struggle to attach a debugger with Pycharm with a docker-compose fastAPI setup\n\ndocker-compose\n\n```\nversion: '3.8'\n\nservices:\n api:\n build: .\n volumes:\n - .:/app\n ports:\n - \"8080:80\"\n environment:\n - DATABASE_URL=postgresql://test_user:test_pwd@db:5432/test_db\n depends_on:\n - db\n \n db:\n image: postgres:13-alpine\n volumes:\n - postgres_data:/var/lib/postgres/data/\n ports:\n - \"5432:5432\"\n environment:\n - POSTGRES_USER=test_user\n - POSTGRES_PASSWORD=test_pwd\n - POSTGRES_DB=test_db\n\nvolumes:\n postgres_data:\n```\n\ndockerfile:\n\n```\nFROM tiangolo/uvicorn-gunicorn:python3.9\n\nCOPY requirements.txt /tmp/requirements.txt\nRUN pip install --no-cache-dir -r /tmp/requirements.txt\n\nCOPY ./app /app/app\n\nCMD [ \"/start-reload.sh\" ]\n```\n\nI have set up a remote interpreter for docker-compose in pycharm\nWhen i start the application it works but breakpoint doest not\n\nI try to setup python configurations:\nhttps://i.sstatic.net/fpm8z.png\n\napplication start but breakpoint doest not too\n\nIf you have any suggestions?\nthank you\n\n========================================\n\nCode:\n```text\nversion: '3.8'\n\nservices:\n api:\n build: .\n volumes:\n - .:/app\n ports:\n - \"8080:80\"\n environment:\n - DATABASE_URL=postgresql://test_user:test_pwd@db:5432/test_db\n depends_on:\n - db\n \n db:\n image: postgres:13-alpine\n volumes:\n - postgres_data:/var/lib/postgres/data/\n ports:\n - \"5432:5432\"\n environment:\n - POSTGRES_USER=test_user\n - POSTGRES_PASSWORD=test_pwd\n - POSTGRES_DB=test_db\n\nvolumes:\n postgres_data:\n```\n\n```text\nFROM tiangolo/uvicorn-gunicorn:python3.9\n\nCOPY requirements.txt /tmp/requirements.txt\nRUN pip install --no-cache-dir -r /tmp/requirements.txt\n\nCOPY ./app /app/app\n\nCMD [ \"/start-reload.sh\" ]\n```\n\n```text\nfrom fastapi import FastAPI\nimport uvicorn\n\napp = FastAPI()\n\n@app.get(\"/\")\ndef root():\n a = \"a\"\n b = \"b\" + a\n return {\"hello world\": b}\n\n\nif __name__ == '__main__':\n uvicorn.run(\"main:app\", host='0.0.0.0', port=8000, reload=True)\n```\n\n========================================\n\nComments:\n- probably related with this: youtrack.jetbrains.com/issue/PY-34070","metadata":{"transformedAt":"2026-08-18T18:32:29.123Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":3,"totalLines":128,"estimatedTokens":573}}330{"id":"stack-71162915","source":"stackoverflow","questionId":71162915,"title":"Conditional call of a FastAPI Model","tags":["python","mongodb","fastapi","pydantic"],"text":"Title: Conditional call of a FastAPI Model\nTags: python, mongodb, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI have a multilang FastAPI connected to MongoDB. My document in MongoDB is duplicated in the two languages available and structured this way (simplified example):\n\n```\n{\n \"_id\": xxxxxxx,\n \"en\": { \n \"title\": \"Drinking Water Composition\",\n \"description\": \"Drinking water composition expressed in... with pesticides.\",\n \"category\": \"Water\", \n \"tags\": [\"water\",\"pesticides\"] \n },\n \"fr\": { \n \"title\": \"Composition de l'eau de boisson\",\n \"description\": \"Composition de l'eau de boisson exprimée en... présence de pesticides....\",\n \"category\": \"Eau\", \n \"tags\": [\"eau\",\"pesticides\"] \n }, \n}\n```\n\nI therefore implemented two models `DatasetFR` and `DatasetEN`, each one makes references with specific external Models (`Enum`) for `category` and `tags` in each lang.\n\n```\nclass DatasetFR(BaseModel):\n title:str\n description: str\n category: CategoryFR\n tags: Optional[List[TagsFR]]\n\n# same for DatasetEN chnaging the lang tag to EN\n```\n\nIn the routes definition I forced the language parameter to declare the corresponding Model and get the corresponding validation.\n\n```\n@router.post(\"?lang=fr\", response_description=\"Add a dataset\")\nasync def create_dataset(request:Request, dataset: DatasetFR = Body(...), lang:str=\"fr\"):\n ...\n return JSONResponse(status_code=status.HTTP_201_CREATED, content=created_dataset)\n\n@router.post(\"?lang=en\", response_description=\"Add a dataset\")\nasync def create_dataset(request:Request, dataset: DatasetEN = Body(...), lang:str=\"en\"):\n ...\n return JSONResponse(status_code=status.HTTP_201_CREATED, content=created_dataset)\n```\n\nBut this seems to be in contradiction with the DRY principle. So, I wonder here if someone knows an elegant solution to: - given the `lang` parameter, **dynamically call the corresponding model**.\n\nOr, if we can create a Parent Model `Dataset` that takes the `lang` argument and retrieve the child model `Dataset`.\n\nThis would incredibly ease building my API routes and the call of my models and mathematically divide by two the writing.\n\n========================================\n\nTop Answer:\nThere are 2 parts to the answer (API call and data structure)\n\nfor the API call, you could separate them into 2 routes like `/api/v1/fr/...` and `/api/v1/en/...` (separating ressource representation!) and play with fastapi.APIRouter to declare the same route twice but changing for each route the validation schema by the one you want to use.\n\nyou could start by declaring a common BaseModel as an ABC as well as an ABCEnum.\n\n```\nfrom abc import ABC\nfrom pydantic import BaseModel\n\nclass MyModelABC(ABC, BaseModel):\n attribute1: MyEnumABC\n\nclass MyModelFr(MyModelABC):\n attribute1: MyEnumFR\n\nclass MyModelEn(MyModelABC):\n attribute1: MyEnumEn\n```\n\nThen you can select the accurate Model for the routes through a class factory:\n\n```\nmy_class_factory: dict[str, MyModelABC] = {\n \"fr\": MyModelFr,\n \"en\": MyModelEn, \n}\n```\n\nFinally you can create your routes through a route factory:\n\n```\ndef generate_language_specific_router(language: str, ...) -> APIRouter:\n router = APIRouter(prefix=language)\n MySelectedModel: MyModelABC = my_class_factory[language]\n\n @router.post(\"/\")\n def post_something(my_model_data: MySelectedModel):\n # My internal logic\n return router\n```\n\nAbout the second part (internal computation and data storage), internationalisation is often done through hashmaps.\n\nThe standard python library gettext could be investigated\n\nOtherwise, the original language can be explicitely used as the key/hash and then map translations to it (also including the original language if you want to have consistency in your calls).\n\nIt can look like:\n\n```\ndictionnary_of_babel = {\n \"word1\": {\n \"en\": \"word1\",\n \"fr\": \"mot1\",\n },\n \"word2\": {\n \"en\": \"word2\",\n },\n \"Drinking Water Composition\": {\n \"en\": \"Drinking Water Composition\",\n \"fr\": \"Composition de l'eau de boisson\",\n },\n}\n\nmy_arbitrary_object = {\n \"attribute1\": \"word1\",\n \"attribute2\": \"word2\",\n \"attribute3\": \"Drinking Water Composition\",\n}\n\nmy_translated_object = {}\nfor attribute, english_sentence in my_arbitrary_object.items():\n if \"fr\" in dictionnary_of_babel[english_sentence].keys():\n my_translated_object[attribute] = dictionnary_of_babel[english_sentence][\"fr\"]\n else:\n my_translated_object[attribute] = dictionnary_of_babel[english_sentence][\"en\"] # ou sans \"en\"\n\nexpected_translated_object = {\n \"attribute1\": \"mot1\",\n \"attribute2\": \"word2\",\n \"attribute3\": \"Composition de l'eau de boisson\",\n}\n\nassert expected_translated_object == my_translated_object\n```\n\n***This code should run as is***\n\nA proposal for mongoDB representation, if we don't want to have a separate table for translations, could be a `data structure` such as:\n\n```\n# normal:\nmy_attribute: \"sentence\"\n\n# internationalized\nmy_attribute_internationalized: {\n sentence: {\n original_lang: \"sentence\"\n lang1: \"sentence_lang1\",\n lang2: \"sentence_lang2\",\n }\n}\n```\n\nA simple tactic to generalize string translation is to define an anonymous function `_()` that embeds the translation like:\n\n```\nCURRENT_MODULE_LANG = \"fr\"\n\ndef _(original_string: str) -> str:\n \"\"\"Switch from original_string to translation\"\"\"\n return dictionnary_of_babel[original_string][CURRENT_MODULE_LANG]\n```\n\nThen call it everywhere a translation is needed:\n\n```\n>>> print(_(\"word 1\"))\n\"mot 1\"\n```\n\nYou can find a reference to this practice in the django documentation about internationalization-in-python-code.\n\nFor static translation (for example a website or a documentation), you can use .po files and editors like poedit (See the french translation of python docs for a practical usecase)!\n\n========================================\n\nCode:\n```json\n{\n \"_id\": xxxxxxx,\n \"en\": { \n \"title\": \"Drinking Water Composition\",\n \"description\": \"Drinking water composition expressed in... with pesticides.\",\n \"category\": \"Water\", \n \"tags\": [\"water\",\"pesticides\"] \n },\n \"fr\": { \n \"title\": \"Composition de l'eau de boisson\",\n \"description\": \"Composition de l'eau de boisson exprimée en... présence de pesticides....\",\n \"category\": \"Eau\", \n \"tags\": [\"eau\",\"pesticides\"] \n }, \n}\n```\n\n```py\nclass DatasetFR(BaseModel):\n title:str\n description: str\n category: CategoryFR\n tags: Optional[List[TagsFR]]\n\n# same for DatasetEN chnaging the lang tag to EN\n```\n\n```py\n@router.post(\"?lang=fr\", response_description=\"Add a dataset\")\nasync def create_dataset(request:Request, dataset: DatasetFR = Body(...), lang:str=\"fr\"):\n ...\n return JSONResponse(status_code=status.HTTP_201_CREATED, content=created_dataset)\n\n@router.post(\"?lang=en\", response_description=\"Add a dataset\")\nasync def create_dataset(request:Request, dataset: DatasetEN = Body(...), lang:str=\"en\"):\n ...\n return JSONResponse(status_code=status.HTTP_201_CREATED, content=created_dataset)\n```\n\n```text\nDatasetFR\n```\n\n```text\nDatasetEN\n```\n\n```text\nEnum\n```\n\n```text\ncategory\n```\n\n```text\ntags\n```\n\n```text\nlang\n```\n\n```text\nDataset\n```\n\n```text\nlang\n```\n\n```text\nDataset<LANG>\n```\n\n```text\nimport pydantic \nfrom fastapi import FastAPI, Response, status, Body, Query\nfrom fastapi.responses import JSONResponse\nfrom fastapi.encoders import jsonable_encoder\n\nmodels = {\"fr\": DatasetFR, \"en\": DatasetEN}\n\n@router.post(\"/\", response_description=\"Add a dataset\")\nasync def create_dataset(body: dict = Body(...), lang: str = Query(..., regex=\"^(fr|en)$\")):\n try:\n model = models[lang].parse_obj(body)\n except pydantic.ValidationError as e:\n return Response(content=e.json(), status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, media_type=\"application/json\")\n\n return JSONResponse(content=jsonable_encoder(dict(model)), status_code=status.HTTP_201_CREATED)\n```\n\n```text\nclass Dataset(BaseModel):\n title:str\n description: str\n \nclass DatasetFR(Dataset):\n category: CategoryFR\n tags: Optional[List[TagsFR]]\n \nclass DatasetEN(Dataset):\n category: CategoryEN\n tags: Optional[List[TagsEN]]\n```\n\n```text\nfrom fastapi.exceptions import HTTPException\nfrom fastapi import Depends\n\nmodels = {\"fr\": DatasetFR, \"en\": DatasetEN}\n\nasync def checker(body: dict = Body(...), lang: str = Query(..., regex=\"^(fr|en)$\")):\n try:\n model = models[lang].parse_obj(body)\n except pydantic.ValidationError as e:\n raise HTTPException(detail=jsonable_encoder(e.errors()), status_code=status.HTTP_422_UNPROCESSABLE_ENTITY)\n\n return model\n \n@router.post(\"/\", response_description=\"Add a dataset\")\nasync def create_dataset(model: Dataset = Depends(checker)): \n return JSONResponse(content=jsonable_encoder(dict(model)), status_code=status.HTTP_201_CREATED)\n```\n\n```text\nfrom pydantic import validator\n\ncategories_FR = set(item.value for item in CategoryFR) \ncategories_EN = set(item.value for item in CategoryEN) \ntags_FR = set(item.value for item in TagsFR) \ntags_EN = set(item.value for item in TagsEN) \ncats = {\"fr\": categories_FR, \"en\": categories_EN}\ntags = {\"fr\": tags_FR, \"en\": tags_EN}\n\ndef raise_error(values):\n raise ValueError(f'value is not a valid enumeration member; permitted: {values}')\n\nclass Dataset(BaseModel):\n lang: str = Body(..., regex=\"^(fr|en)$\")\n title: str\n description: str\n category: str\n tags: List[str]\n\n @validator(\"category\", \"tags\")\n def validate_atts(cls, v, values, field):\n lang = values.get('lang')\n if lang:\n if field.name == \"category\":\n if v not in cats[lang]: raise_error(cats[lang])\n elif field.name == \"tags\":\n if not set(v).issubset(tags[lang]): raise_error(tags[lang])\n return v\n\n \n@router.post(\"/\", response_description=\"Add a dataset\")\nasync def create_dataset(model: Dataset): \n return JSONResponse(content=jsonable_encoder(dict(model)), status_code=status.HTTP_201_CREATED)\n```\n\n```text\nlang\n```\n\n```text\nQuery\n```\n\n```text\n^(fr|en)$\n```\n\n```text\nfr\n```\n\n```text\nen\n```\n\n```text\nbody\n```\n\n```text\ndict\n```\n\n```text\nBody\n```\n\n```text\nJSON\n```\n\n```text\nmodels\n```\n\n```text\nlang\n```\n\n```text\nmodel\n```\n\n```text\ntry\n```\n\n```text\nJSON\n```\n\n```text\nmodels[lang].parse_obj(body)\n```\n\n```text\nmodels[lang](**body)\n```\n\n```text\nValidationError\n```\n\n```text\nmodel\n```\n\n```text\nHTTP_422_UNPROCESSABLE_ENTITY\n```\n\n```text\nFR\n```\n\n```text\nEN\n```\n\n```text\nlang\n```\n\n```text\n^(?i)(fr|en)$\n```\n\n```text\nlang\n```\n\n```text\nmodels[lang.lower()].parse_obj(body)\n```\n\n```text\ntitle\n```\n\n```text\ndescription\n```\n\n```text\nDataset\n```\n\n```text\nDatasetFR\n```\n\n```text\nDatasetEN\n```\n\n```text\nmodel\n```\n\n```text\nHTTPException\n```\n\n```text\njsonable_encoder\n```\n\n```text\nerrors()\n```\n\n```text\nJSONResponse\n```\n\n```text\nDataset\n```\n\n```text\ncategory\n```\n\n```text\ntags\n```\n\n```text\nlang\n```\n\n```text\nDataset\n```\n\n```text\nset\n```\n\n```text\nEnum\n```\n\n```text\nEnum\n```\n\n```text\nset\n```\n\n```text\nlang\n```\n\n```text\ntags\n```\n\n```text\nset.issubset\n```\n\n```text\nraise ValueError\n```\n\n```text\nValidationError\n```\n\n```text\nlang\n```\n\n```text\nregex\n```\n\n```text\nEnum\n```\n\n```text\nset\n```\n\n```text\ncategories_FR = {\"Eau\"} categories_EN = {\"Water\"} tags_FR = {\"eau\", \"pesticides\"} tags_EN = {\"water\", \"pesticides\"}\n```\n\n```text\nlang\n```\n\n```text\nvalidator\n```\n\n```text\n@validator\n```\n\n```text\n@field_validator\n```\n\n```text\nUnion\n```\n\n```text\nmy_discriminator\n```\n\n```text\nLiteral\n```\n\n```text\nUnion\n```\n\n```text\nField(discriminator='my_discriminator')\n```\n\n```text\nfrom abc import ABC\nfrom pydantic import BaseModel\n\nclass MyModelABC(ABC, BaseModel):\n attribute1: MyEnumABC\n\nclass MyModelFr(MyModelABC):\n attribute1: MyEnumFR\n\nclass MyModelEn(MyModelABC):\n attribute1: MyEnumEn\n```\n\n```text\nmy_class_factory: dict[str, MyModelABC] = {\n \"fr\": MyModelFr,\n \"en\": MyModelEn, \n}\n```\n\n```text\ndef generate_language_specific_router(language: str, ...) -> APIRouter:\n router = APIRouter(prefix=language)\n MySelectedModel: MyModelABC = my_class_factory[language]\n\n @router.post(\"/\")\n def post_something(my_model_data: MySelectedModel):\n # My internal logic\n return router\n```\n\n```text\ndictionnary_of_babel = {\n \"word1\": {\n \"en\": \"word1\",\n \"fr\": \"mot1\",\n },\n \"word2\": {\n \"en\": \"word2\",\n },\n \"Drinking Water Composition\": {\n \"en\": \"Drinking Water Composition\",\n \"fr\": \"Composition de l'eau de boisson\",\n },\n}\n\nmy_arbitrary_object = {\n \"attribute1\": \"word1\",\n \"attribute2\": \"word2\",\n \"attribute3\": \"Drinking Water Composition\",\n}\n\nmy_translated_object = {}\nfor attribute, english_sentence in my_arbitrary_object.items():\n if \"fr\" in dictionnary_of_babel[english_sentence].keys():\n my_translated_object[attribute] = dictionnary_of_babel[english_sentence][\"fr\"]\n else:\n my_translated_object[attribute] = dictionnary_of_babel[english_sentence][\"en\"] # ou sans \"en\"\n\nexpected_translated_object = {\n \"attribute1\": \"mot1\",\n \"attribute2\": \"word2\",\n \"attribute3\": \"Composition de l'eau de boisson\",\n}\n\nassert expected_translated_object == my_translated_object\n```\n\n```text\n# normal:\nmy_attribute: \"sentence\"\n\n# internationalized\nmy_attribute_internationalized: {\n sentence: {\n original_lang: \"sentence\"\n lang1: \"sentence_lang1\",\n lang2: \"sentence_lang2\",\n }\n}\n```\n\n```text\nCURRENT_MODULE_LANG = \"fr\"\n\ndef _(original_string: str) -> str:\n \"\"\"Switch from original_string to translation\"\"\"\n return dictionnary_of_babel[original_string][CURRENT_MODULE_LANG]\n```\n\n```text\n>>> print(_(\"word 1\"))\n\"mot 1\"\n```\n\n```text\n/api/v1/fr/...\n```\n\n```text\n/api/v1/en/...\n```\n\n```text\ndata structure\n```\n\n```text\n_()\n```\n\n========================================\n\nComments:\n- What's the rational behind the two models in the first place?\n- Can't you have a single Dataset class and define an extra field for the language?\n- I'm wondering if using a variable schema in a REST API is a good thing. In my opinion, that would be a new ressource \"representation\" thus the proposal of /lang/ prefix.\n- This is a very good proposal with Body and Query regex and a dictionnary to map models. This is a good and easy to implement proposal. As I can't accept two proposals (can I?) I will choose the more canonical one with class factory and routes factory but I keep in mind yours. BTW I'm not sure of Update2 I want to explicitly set specific validators instead of Enum I have dozen of properties that needs to be validated. This would results to a long list of conditionnal that could not very readable...","metadata":{"transformedAt":"2026-08-18T18:32:29.123Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":90,"totalLines":723,"estimatedTokens":3624}}331{"id":"stack-71873314","source":"stackoverflow","questionId":71873314,"title":"Getting error \"value is not a valid dict\" when using Pydantic models in FastAPI for model-based predictions","tags":["python","dataframe","fastapi","prediction","pydantic"],"text":"Title: Getting error \"value is not a valid dict\" when using Pydantic models in FastAPI for model-based predictions\nTags: python, dataframe, fastapi, prediction, pydantic\nSource: Stack Overflow\n\nQuestion:\nI'm trying to use `Pydantic` models with FastAPI to make multiple predictions (for a list of inputs). The problem is that one can't pass Pydantic models directly to `model.predict()` function, so I converted it to a dictionary, however, I'm getting the following error:\n\n`AttributeError: 'list' object has no attribute 'dict'`\n\nMy code:\n\n```\nfrom fastapi import FastAPI\nimport uvicorn\nfrom pydantic import BaseModel\nimport pandas as pd\nfrom typing import List\n\napp = FastAPI()\n\nclass Inputs(BaseModel):\n id: int\n f1: float\n f2: float\n f3: str\n\nclass InputsList(BaseModel):\n inputs: List[Inputs]\n\n@app.post('/predict')\ndef predict(input_list: InputsList):\n df = pd.DataFrame(input_list.inputs.dict())\n prediction = classifier.predict(df.loc[:, df.columns != 'id'])\n probability = classifier.predict_proba(df.loc[:, df.columns != 'id'])\n return {'id': df[\"id\"].tolist(), 'prediction': prediction.tolist(), 'probability': probability.tolist()}\n```\n\nI have also a problem with the **return**, I need the output to be something like :\n\n```\n[\n {\n \"id\": 123,\n \"prediction\": \"class1\",\n \"probability\": 0.89\n },\n {\n \"id\": 456,\n \"prediction\": \"class3\",\n \"probability\": 0.45\n }\n ]\n```\n\nPS: the `id` in `Inputs` class doesn't take place in the prediction (is not a feature), but I need it to be shown next to its prediction (to reference it).\n\n**Request**:\nhttps://i.sstatic.net/7GIfw.png\n\n========================================\n\nTop Answer:\nYour definition of the input schema for the view function does not match the content you're sending:\n\n```\nclass Inputs(BaseModel):\n id: int\n f1: float\n f2: float\n f3: str\n\nclass InputsList(BaseModel):\n inputs: List[Inputs]\n```\n\nThis matches a request body in the format of:\n\n```\n{\n \"inputs\": [\n {\n \"id\": 1,\n \"f1\": 1.0,\n \"f2\": 1.0,\n \"f3\": \"foo\"\n }, {\n \"id\": 2,\n \"f1\": 2.0,\n \"f2\": 2.0,\n \"f3\": \"bar\"\n }\n ]\n}\n```\n\nThe request body you're sending does not match the expected format, and thus, you get an 422 response back.\n\nEither change the object you're sending to match the format expected by FastAPI or drop the `InputsList` wrapper and set the input as `input_list: List[Inputs]` instead.\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI\nimport uvicorn\nfrom pydantic import BaseModel\nimport pandas as pd\nfrom typing import List\n\napp = FastAPI()\n\nclass Inputs(BaseModel):\n id: int\n f1: float\n f2: float\n f3: str\n\nclass InputsList(BaseModel):\n inputs: List[Inputs]\n\n@app.post('/predict')\ndef predict(input_list: InputsList):\n df = pd.DataFrame(input_list.inputs.dict())\n prediction = classifier.predict(df.loc[:, df.columns != 'id'])\n probability = classifier.predict_proba(df.loc[:, df.columns != 'id'])\n return {'id': df[\"id\"].tolist(), 'prediction': prediction.tolist(), 'probability': probability.tolist()}\n```\n\n```py\n[\n {\n \"id\": 123,\n \"prediction\": \"class1\",\n \"probability\": 0.89\n },\n {\n \"id\": 456,\n \"prediction\": \"class3\",\n \"probability\": 0.45\n }\n ]\n```\n\n```text\nPydantic\n```\n\n```text\nmodel.predict()\n```\n\n```text\nAttributeError: 'list' object has no attribute 'dict'\n```\n\n```text\nid\n```\n\n```text\nInputs\n```\n\n```py\nclass Inputs(BaseModel):\n id: int\n f1: float\n f2: float\n f3: str\n```\n\n```json\n{\n \"inputs\": [\n {\n \"id\": 1,\n \"f1\": 1.0,\n \"f2\": 1.0,\n \"f3\": \"text\"\n },\n {\n \"id\": 2,\n \"f1\": 2.0,\n \"f2\": 2.0,\n \"f3\": \"text\"\n }\n ]\n}\n```\n\n```py\ndf = pd.DataFrame([i.dict() for i in input_list.inputs])\n```\n\n```py\nresults = []\nfor (id, pred, prob) in zip(df[\"id\"].tolist(), prediction.tolist(), probability.tolist()):\n results.append({\"id\": id, \"prediction\": pred, \"probability\": prob})\nreturn results\n```\n\n```py\nresults = pd.DataFrame({'id': df[\"id\"].tolist(),'prediction': prediction.tolist(),'probability': probability.tolist()})\nreturn results.to_dict(orient=\"records\")\n```\n\n```text\n,\n```\n\n```text\nf1\n```\n\n```text\nf2\n```\n\n```text\nJSON\n```\n\n```text\n422\n```\n\n```text\nJSON\n```\n\n```text\nJSON\n```\n\n```text\ndict()\n```\n\n```text\nlist\n```\n\n```text\nAttributeError: 'list' object has no attribute 'dict'\n```\n\n```text\n.dict()\n```\n\n```text\nlist\n```\n\n```text\npredict_proba()\n```\n\n```text\ninput\n```\n\n```text\nprobability\n```\n\n```text\nprob[0]\n```\n\n```text\nto_dict()\n```\n\n```text\nprobability\n```\n\n```text\nlist\n```\n\n```text\nprob_list = [item[0] for item in probability.tolist()]\n```\n\n```text\noperator.itemgetter()\n```\n\n```text\nprob_list = list(map(itemgetter(0), probability.tolist()))\n```\n\n```text\nlist\n```\n\n```py\nclass Inputs(BaseModel):\n id: int\n f1: float\n f2: float\n f3: str\n\nclass InputsList(BaseModel):\n inputs: List[Inputs]\n```\n\n```json\n{\n \"inputs\": [\n {\n \"id\": 1,\n \"f1\": 1.0,\n \"f2\": 1.0,\n \"f3\": \"foo\"\n }, {\n \"id\": 2,\n \"f1\": 2.0,\n \"f2\": 2.0,\n \"f3\": \"bar\"\n }\n ]\n}\n```\n\n```text\nInputsList\n```\n\n```text\ninput_list: List[Inputs]\n```\n\n========================================\n\nComments:\n- The code you posted is *not* valid Python code, even when the indentations were fixed. Please update your code so that it can be run and post the full error that you are getting including the traceback.\n- @PaulP I updated the post with a picture f the error in FastAPI\n- How are you calling the endpoint? (Also, please try not to post screenshots but rather the actual content as text.)\n- @PaulP I'm using 127.0.0.1:8000/docs for testing the API, the error is : { \"detail\": [ { \"loc\": [ \"body\" ], \"msg\": \"value is not a valid dict\", \"type\": \"type_error.dict\" } ] }\n- What did you type in? Does it also say `application/json` on the right hand side?\n- @PaulP yes it does, please recheck my post for screenshot update regarding it\n- You have a comma at the end of both `\"f3\": \"test\",`. This isn't valid JSON, which might be why it's not working.\n- Thank you for your response, it does solve the error 422, but another error occurred saying : AttributeError: 'list' object has no attribute 'dict' , either using InputsList or input_list: List[Inputs] directly\n- please recheck my post for updated issue","metadata":{"transformedAt":"2026-08-18T18:32:29.123Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":39,"totalLines":347,"estimatedTokens":1567}}332{"id":"stack-68209344","source":"stackoverflow","questionId":68209344,"title":"FastAPI auth with jwt, but not OAuth2 - is it possible to customize built-in OAuth2PasswordBearer?","tags":["python","fastapi"],"text":"Title: FastAPI auth with jwt, but not OAuth2 - is it possible to customize built-in OAuth2PasswordBearer?\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nOn my frontend there is some custom auth flow with jwt, which differs from OAuth2 flow (clearly described in FastAPI docs), only by how credentials are sent to `/login` endpoint. Frontend makes `POST` with json in body `{\"email\": \"...\", \"password\": \"...\"}` instead of `username; password` in form data.\n\nIs there some way to customize `OAuth2PasswordBearer` or some other built-in security class to support this scenario? It will be nice to still have fully-functional SwaggerUI docs with Authorize form etc.\n\nI see there are many recipes, how to support jwt, but most of them are not integrated well with SwaggerUI docs and it will be nice to base solution on some class buit-into FastAPI itself.\n\n========================================\n\nCode:\n```text\n/login\n```\n\n```text\nPOST\n```\n\n```text\n{\"email\": \"...\", \"password\": \"...\"}\n```\n\n```text\nusername; password\n```\n\n```text\nOAuth2PasswordBearer\n```\n\n```py\nclass OAuth2PasswordRequestJSON(BaseModel):\n grant_type: str = Field(None, regex=\"password\")\n username: str = Field(...)\n password: str = Field(...)\n scope: List[str] = Field(default_factory=list)\n client_id: Optional[str] = None\n client_secret: Optional[str] = None\n\n @validator(\"scope\", pre=True)\n def scope_from_string(cls, v):\n return v.split() if isinstance(v, str) else v\n\n\n@app.post(\"/token\")\nasync def login(body_data: OAuth2PasswordRequestJSON):\n ...\n```\n\n```text\nauthActions.authorizeRequest({ body: buildFormData(form), url: schema.get(\"tokenUrl\"), name, headers, query, auth})\n```\n\n```text\nauthActions.authorizeRequest({ body: form, url: schema.get(\"tokenUrl\"), name, headers, query, auth})\n```\n\n```text\n\"Content-Type\": \"application/x-www-form-urlencoded\",\n```\n\n```text\n\"Content-Type\": \"application/json\",\n```\n\n```text\nlogin\n```\n\n```text\nOAuth2PasswordRequestForm\n```\n\n```text\napplication/json\n```\n\n```text\nswagger-ui-bundle.js\n```\n\n```text\nbuildFormData\n```\n\n```text\napplication/json\n```\n\n========================================\n\nComments:\n- This will not work with Authorization form on Swagger UI (when security is OAuth2PasswordBearer) :( Also I suppose it will not be rendered correctly in open api schema. That's the issue, I'd like to understand how this security class to be customized normally.","metadata":{"transformedAt":"2026-08-18T18:32:29.123Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":16,"totalLines":97,"estimatedTokens":605}}333{"id":"stack-66592114","source":"stackoverflow","questionId":66592114,"title":"React frontend sending image to fastapi backend","tags":["python","reactjs","python-3.x","fastapi"],"text":"Title: React frontend sending image to fastapi backend\nTags: python, reactjs, python-3.x, fastapi\nSource: Stack Overflow\n\nQuestion:\nFrontend = React, backend = FastApi.\nHow can I simply send an image from the frontend, and have the backend saving it to the local disk ?\nI've tried different ways: in an object, in a base64 string, etc.\nBut I can't manage to deserialize the image in FastApi.\nIt looks like an encoded string, I tried writing it to a file, or decoding it, but with no success.\n\n```\nconst [selectedFile, setSelectedFile] = useState(null);\nconst changeHandler = (event) => {setSelectedFile(event.target.files[0]); };\nconst handleSubmit = event => {\n\nconst formData2 = new FormData();\nformData2.append(\n\"file\",\nselectedFile,\nselectedFile.name\n);\n\nconst requestOptions = {\n method: 'POST',\n headers: { 'Content-Type': 'multipart/form-data' },\n body: formData2 // Also tried selectedFile\n};\n fetch('http://0.0.0.0:8000/task/upload_image/'+user_id, requestOptions)\n .then(response => response.json())\n}\n\nreturn ( \n \n upload picture\n\n \n\n \n \n\n Save\n \n\n);\n```\n\nAnd the backend:\n\n```\n@router.post(\"/upload_image/{user_id}\")\nasync def upload_image(user_id: int, request: Request):\n body = await request.body()\n \n # fails (TypeError)\n with open('/home/backend/test.png', 'wb') as fout:\n fout.writelines(body)\n```\n\nI also tried to simply mimic the client with something like this:\n`curl -F media=@/home/original.png http://0.0.0.0:8000/task/upload_image/3`\nbut same result...\n\n**----- [Solved]** Removing user_id for simplicity.\nThe server part must look like this:\n\n```\n@router.post(\"/uploadfile/\")\nasync def create_upload_file(file: UploadFile = File(...)):\n out_path = 'example/path/file'\n async with aiofiles.open(out_path, 'wb') as out_file:\n content = await file.read()\n await out_file.write(content)\n```\n\nAnd for some reason, the client part should *not* include the content-type in the headers:\n\n```\nfunction TestIt ( ) {\n const [selectedFile, setSelectedFile] = useState(null);\n const [isFilePicked, setIsFilePicked] = useState(false);\n \n const changeHandler = (event) => {\n setSelectedFile(event.target.files[0]);\n setIsFilePicked(true);\n };\n \n const handleSubmit = event => {\n event.preventDefault();\n const formData2 = new FormData();\n formData2.append(\n \"file\",\n selectedFile,\n selectedFile.name\n );\n \n const requestOptions = {\n method: 'POST',\n //headers: { 'Content-Type': 'multipart/form-data' }, // DO NOT INCLUDE HEADERS\n body: formData2\n };\n fetch('http://0.0.0.0:8000/task/uploadfile/', requestOptions)\n .then(response => response.json())\n .then(function (response) {\n console.log('response')\n console.log(response)\n });\n }\n return ( \n \n \n \n \n Save\n \n \n );\n}\n```\n\n========================================\n\nCode:\n```text\nconst [selectedFile, setSelectedFile] = useState(null);\nconst changeHandler = (event) => {setSelectedFile(event.target.files[0]); };\nconst handleSubmit = event => {\n\nconst formData2 = new FormData();\nformData2.append(\n\"file\",\nselectedFile,\nselectedFile.name\n);\n\nconst requestOptions = {\n method: 'POST',\n headers: { 'Content-Type': 'multipart/form-data' },\n body: formData2 // Also tried selectedFile\n};\n fetch('http://0.0.0.0:8000/task/upload_image/'+user_id, requestOptions)\n .then(response => response.json())\n}\n\nreturn ( <div\n <form onSubmit={handleSubmit}>\n <fieldset>\n <label htmlFor=\"image\">upload picture</label><br/>\n <input name=\"image\" type=\"file\" onChange={changeHandler} accept=\".jpeg, .png, .jpg\"/>\n\n </fieldset>\n <br/>\n <Button color=\"primary\" type=\"submit\">Save</Button>\n </form>\n</div>\n);\n```\n\n```text\n@router.post(\"/upload_image/{user_id}\")\nasync def upload_image(user_id: int, request: Request):\n body = await request.body()\n \n # fails (TypeError)\n with open('/home/backend/test.png', 'wb') as fout:\n fout.writelines(body)\n```\n\n```text\n@router.post(\"/uploadfile/\")\nasync def create_upload_file(file: UploadFile = File(...)):\n out_path = 'example/path/file'\n async with aiofiles.open(out_path, 'wb') as out_file:\n content = await file.read()\n await out_file.write(content)\n```\n\n```text\nfunction TestIt ( ) {\n const [selectedFile, setSelectedFile] = useState(null);\n const [isFilePicked, setIsFilePicked] = useState(false);\n \n const changeHandler = (event) => {\n setSelectedFile(event.target.files[0]);\n setIsFilePicked(true);\n };\n \n const handleSubmit = event => {\n event.preventDefault();\n const formData2 = new FormData();\n formData2.append(\n \"file\",\n selectedFile,\n selectedFile.name\n );\n \n const requestOptions = {\n method: 'POST',\n //headers: { 'Content-Type': 'multipart/form-data' }, // DO NOT INCLUDE HEADERS\n body: formData2\n };\n fetch('http://0.0.0.0:8000/task/uploadfile/', requestOptions)\n .then(response => response.json())\n .then(function (response) {\n console.log('response')\n console.log(response)\n });\n }\n return ( <div>\n <form onSubmit={handleSubmit}>\n <fieldset>\n <input name=\"image\" type=\"file\" onChange={changeHandler} accept=\".jpeg, .png, .jpg\"/>\n </fieldset>\n <Button type=\"submit\">Save</Button>\n </form>\n </div>\n );\n}\n```\n\n```text\ncurl -F media=@/home/original.png http://0.0.0.0:8000/task/upload_image/3\n```\n\n```text\nfrom fastapi import UploadFile, File\n\n@router.post(\"/upload_image/{user_id}\")\nasync def upload_image(user_id: int, file: UploadFile = File(...)):\n # Your code goes here\n```\n\n========================================\n\nComments:\n- Are you sending the file from the browser to the api, or to react which then forwards the request to the api? Also, that's not the proper way of accessing the file. See the docs on how to do it fastapi.tiangolo.com/tutorial/request-files/?h=file\n- I am using a react Form to send the request to the API. I also tried the UploadFile module in FastApi, but it was not working better. I'm surprised that there is no simple snippet example of JS-Fastapi for this usecase\n- Thanks, I actually spent some time on it since your comment yesterday. Updating the python function helps indeed, but I'm still not able to have it working. More precisely, it works with curl, but not from React. There is no much details as the FastApi part just raises a 400 Bad Request / There was an error parsing the body. I'll continue digging.\n- Can you post the entire error? It's not simple to identify the problem. Though, it could be due to cors activated\n- It is not due to CORS, the rest of my interaction (react-fastapi) works fine. I don't see any error message unfortunately, only \"400 Bad Request\" on the server side, and it returns \"There was an error parsing the body\". I'm trying to find how to get more details.\n- Ok I think I found how to fix it, from another post: stackoverflow.com/questions/39383861/… . For some reason, it works if we don't include Content-Type headers. I'll update my post. Thanks for the Python part. I'll edit my question with more details in case it helps someone else","metadata":{"transformedAt":"2026-08-18T18:32:29.123Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":6,"totalLines":241,"estimatedTokens":1802}}334{"id":"stack-79626334","source":"stackoverflow","questionId":79626334,"title":"What happens to the asyncio event loop when multiple CPU-bound tasks run concurrently in a ThreadPoolExecutor given Python’s GIL?","tags":["python","python-asyncio","fastapi","python-multithreading","gil"],"text":"Title: What happens to the asyncio event loop when multiple CPU-bound tasks run concurrently in a ThreadPoolExecutor given Python’s GIL?\nTags: python, python-asyncio, fastapi, python-multithreading, gil\nSource: Stack Overflow\n\nQuestion:\nI'm working on an asynchronous Python application (using FastAPI/Starlette/asyncio) that needs to offload synchronous, CPU-bound tasks to a thread pool (`ThreadPoolExecutor`) to avoid blocking the event loop.\n\nI understand that Python's Global Interpreter Lock (GIL) allows only one thread to execute Python bytecode at a time per process. But I want to clarify how this affects the asyncio event loop when **multiple** CPU-bound tasks (say 10) are submitted concurrently to the thread pool.\n\n### Scenario\n\n- The event loop runs in the main thread.\n\n- There is a thread pool with multiple worker threads (e.g., 10 threads).\n\n- Ten CPU-bound synchronous tasks are submitted almost simultaneously, each running Python code that holds the GIL while executing.\n\n- The event loop also needs the GIL to run coroutines, callbacks, and other async operations.\n\n### What I Understand\n\n- When a thread holds the GIL, no other thread or the event loop can run Python bytecode.\n\n- CPython periodically enforces time-slicing so that the GIL is released after a check interval, letting other threads acquire it.\n\n- The event loop and worker threads contend for the GIL.\n\n- If one worker thread holds the GIL, the event loop is effectively blocked from executing Python code.\n\n- When the GIL is released, any thread (another worker thread or the event loop) may acquire it next; there’s no guarantee the event loop will get immediate priority.\n\n- Therefore, multiple CPU-bound tasks running concurrently in the thread pool can serially monopolize the GIL, delaying the event loop and causing increased latency and reduced responsiveness.\n\n### My Questions\n\n- Is this understanding accurate regarding how the GIL contention affects the asyncio event loop?\n\n- Does Python’s GIL and time-slicing mechanism indeed cause the event loop to be “starved” or blocked temporarily when multiple CPU-bound threads are running?\n\n- Are there any internal scheduling mechanisms or priorities in CPython that favor the event loop thread over worker threads in such scenarios?\n\n- Are there recommended best practices or architectural patterns to avoid this problem, aside from moving CPU-bound tasks to `ProcessPoolExecutor` or external services?\n\n### Context\n\nI am considering using `ThreadPoolExecutor` in FastAPI to run some blocking CPU-bound tasks asynchronously but want to understand the implications on event loop responsiveness when multiple such tasks run concurrently.\n\nThank you in advance for any clarifications or insights!\n\n========================================\n\nTop Answer:\nAs mentioned in the comments and Chris's answer, your overall understanding is correct. But I believe there's a fairly simple solution both you and the other answer appear to be missing.\n\nAre there recommended best practices or architectural patterns to avoid this problem\n\nYes - reduce the worker count in the thread pool, so the switch to the event loop thread is always reasonably fast. That might not be a very sophisticated solution, but I believe it's the best option available given the constraints you've laid out: use of Python with GIL, and use of multi-threading rather than multi-processing.\n\nIf you're worried about latency, you could even use a thread pool with just one worker, created with `ThreadPoolExecutor(max_workers=1)`. That is the closest you'll get to a guarantee that the event loop gets serviced each time the worker's GIL time slot expires. And your CPU-bound tasks will run no slower - instead of being serialized by the GIL, they will be serialized by the executor.\n\n========================================\n\nCode:\n```text\nThreadPoolExecutor\n```\n\n```text\nProcessPoolExecutor\n```\n\n```text\nThreadPoolExecutor\n```\n\n```py\nimport sys\n\nprint(sys.getswitchinterval()) # 0.005\n```\n\n```py\npow(365,100000000000000) # this would not release the GIL\n```\n\n```py\nfrom fastapi import FastAPI\nimport concurrent.futures\nimport asyncio\nfrom multiprocessing import current_process\nfrom threading import current_thread\n\n\napp = FastAPI()\n\n\ndef cpu_bound_task():\n pid = current_process().pid\n tid = current_thread().ident\n thread_name = current_thread().name\n process_name = current_process().name\n print(f\"{pid} - {process_name} - {tid} - {thread_name}\")\n pow(365,100000000000000)\n\n\n# this WILL block the event loop (because of `pow()`)\n@app.get(\"/blocking\")\nasync def blocking():\n loop = asyncio.get_running_loop()\n with concurrent.futures.ThreadPoolExecutor() as pool:\n res = await loop.run_in_executor(pool, cpu_bound_task)\n return \"OK\"\n \n \n# this WON'T block the event loop\n@app.get(\"/non-blocking\")\nasync def non_blocking():\n loop = asyncio.get_running_loop()\n with concurrent.futures.ProcessPoolExecutor() as pool:\n res = await loop.run_in_executor(pool, cpu_bound_task)\n return \"OK\"\n \n \nif __name__ == \"__main__\":\n import uvicorn\n uvicorn.run(app)\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\n5ms\n```\n\n```text\n5ms\n```\n\n```text\nsys.setswitchinterval(interval)\n```\n\n```text\npow()\n```\n\n```text\nProcessPoolExecutor\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nProcessPoolExecutor\n```\n\n```text\nProcessPool\n```\n\n```text\ncpu_bound_task()\n```\n\n```text\npow()\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nqueue\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nmax_workers\n```\n\n```text\nNone\n```\n\n```text\nmin(32, os.cpu_count() + 4)\n```\n\n```text\nmin(32, (os.process_cpu_count() or 1) + 4)\n```\n\n```text\nProcessPoolExecutor\n```\n\n```text\nmax_workers\n```\n\n```text\nos.process_cpu_count()\n```\n\n```text\nProcessPoolExecutor\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nThreadPoolExecutor(max_workers=n)\n```\n\n```text\nwebsockets\n```\n\n```text\npython3.13t\n```\n\n```text\npython3.13t.exe\n```\n\n```text\n--disable-gil\n```\n\n```text\nThreadPoolExecutor(max_workers=1)\n```\n\n========================================\n\nComments:\n- Does this answer your question?\n- This should prove helpful as well.\n- Your understanding is correct, but if you are dealing with CPU-bound tasks, you should rather choose `ProcessPoolExecutor` or other related solutions provided in the linked answers above.\n- @Chris Thank you for confirming my understanding — I appreciate the clarity. Just to reconfirm one subtle point: If a worker thread executing a CPU-bound function (via ThreadPoolExecutor) is currently holding the GIL, is it correct that: - The asyncio event loop - even though it runs in the main thread - cannot execute any Python bytecode until that thread voluntarily releases the GIL or the GIL is forcefully yielded due to CPython's time-slicing? I just wanted to be sure I'm not missing any nuance around GIL scheduling. Thanks again!\n- @Chris also can you suggest me where and how can I learn about fastAPI and asyncio in depth... like any courses, books, article or tutorials that you found particularly helpful would be great.\n- You are correct that voluntarily releasing or timeouts are the only two ways the GIL switches owner. When the new GIL was proposed, there was a third way to make priority requests for threads that just returned from IO. That could have helped with the event loop but that was not merged.\n- @Homer512 Oh!! I see! So this kind of priority scheduling for the GIL isn't even implemented. I had assumed I might be able to achieve something similar by tweaking a few things, but looks like that's not possible after all. Anyways thanks for the info brother!!\n- Its not as simple as \"CPU bound\". If you can do your CPU intensive work using something like numpy and its native types, it will release the GIL letting the event loop run. And if there is some I/O, like saving to disk, it happens there. You can also pepper your CPU bound task to release the GIL. This was traditionally done with `sleep(0)` but I don't know if that's still the norm. You can the underlying platform threads (e.g., `win32process.SetThreadPriority`) to favor some threads when accessing the GIL.\n- ProcessPoolExecutor is one of many ways to use multiple processes and is likely not the best performer. On linux/mac you could fork processes and leverage the child's copy on write view of parent memory space. Or use shared memory and launch subprograms for the processing. Or use any of a number of existing parallelization toolkits that would even give you a chance to spread into a cluster of machines.\n- @tdelaney Mac Python has defaulted to spawn to start new processes since 3.8, and Linux Python will default to spawn from 3.14. Using fork on macOS has never been safe and leads to non-deterministic behaviour, and it should not be encouraged. MacOS now tries to detect programs that use fork (alone) to start processes, and will terminate such child processes if they do not promptly call exec.","metadata":{"transformedAt":"2026-08-18T18:32:29.123Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":36,"totalLines":261,"estimatedTokens":2244}}335{"id":"stack-63868275","source":"stackoverflow","questionId":63868275,"title":"FastAPI sharing SQLAlchemy session across threads when using synchronous functions","tags":["multithreading","sqlalchemy","fastapi"],"text":"Title: FastAPI sharing SQLAlchemy session across threads when using synchronous functions\nTags: multithreading, sqlalchemy, fastapi\nSource: Stack Overflow\n\nQuestion:\nNoob question about normal `def` path operations functions, dependencies and SQLAlchemy. Quoting the example here: https://fastapi.tiangolo.com/tutorial/sql-databases/#create-a-dependency, where the db sessions is created in `get_db()` (synchronous) and used in `create_user()` (synchronous). According to https://fastapi.tiangolo.com/async/#very-technical-details, synchronous dependencies and path operation functions are executed in a thread pool, so does this mean the same DB session object is effectively shared across 2 different threads (assuming it's not the same thread that gets re-used across the dependency and path operation function)? Could this be problematic since SQLAlchemy sessions are not thread-safe?\n\nI may be completely misunderstanding how this works, so any clarifications would be greatly appreciated.\n\nThanks!\n\n**EDIT**: After thinking about this more I think this should be fine because session is accessed sequentially (not concurrently) even though it's potentially by two different threads. But I'm assuming using the `session` like the following would be problematic?\n\n```\nasync def func(s: Session):\n loop = asyncio.get_running_loop()\n await loop.run_in_executor(None, some_func, s)\n await loop.run_in_executor(None, some_other_func, s)\n ...\n```\n\n========================================\n\nCode:\n```text\nasync def func(s: Session):\n loop = asyncio.get_running_loop()\n await loop.run_in_executor(None, some_func, s)\n await loop.run_in_executor(None, some_other_func, s)\n ...\n```\n\n```text\ndef\n```\n\n```text\nget_db()\n```\n\n```text\ncreate_user()\n```\n\n```text\nsession\n```\n\n```text\ndef get_db():\n db = SessionLocal()\n try:\n yield db\n finally:\n db.close()\n```\n\n========================================\n\nComments:\n- Thanks for the answer! So the problem I had was not really about whether a single session is shared by two requests (which as you explained above, is not), but rather whether a single session is shared by two threads that handle the same request (and think they do but it should be ok since the access is sequential).\n- @ljiatu Ups, i think this will explain the things perfectly, if it doesn't i 'll try my best again :)\n- Yeah I read that before, so I think it means the example I had at the end of my question would be unsafe, correct?\n- Exactly, if you want thread-safe session check out `scoped_sessions`","metadata":{"transformedAt":"2026-08-18T18:32:29.123Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":6,"totalLines":64,"estimatedTokens":636}}336{"id":"stack-73270890","source":"stackoverflow","questionId":73270890,"title":"How do I convert a torch tensor to an image to be returned by FastAPI?","tags":["python","pytorch","fastapi","starlette"],"text":"Title: How do I convert a torch tensor to an image to be returned by FastAPI?\nTags: python, pytorch, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nI have a torch tensor which I need to convert to a byte object so that I can pass it to starlette's `StreamingResponse` which will return a reconstructed image from the byte object. I am trying to convert the tensor and return it like so:\n\n```\ndef some_unimportant_function(params):\n return_image = io.BytesIO()\n torch.save(some_img, return_image)\n return_image.seek(0)\n return_img = return_image.read()\n \n return StreamingResponse(content=return_img, media_type=\"image/jpeg\")\n```\n\nThe below works fine on regular byte objects and my API returns the reconstructed image:\n\n```\ndef some_unimportant_function(params):\n image = Image.open(io.BytesIO(some_image))\n\n return_image = io.BytesIO()\n image.save(return_image, \"JPEG\")\n return_image.seek(0)\n return StreamingResponse(content=return_image, media_type=\"image/jpeg\")\n```\n\nUsing `PIL` library for this\n\nwhat am I doing wrong here?\n\n========================================\n\nCode:\n```py\ndef some_unimportant_function(params):\n return_image = io.BytesIO()\n torch.save(some_img, return_image)\n return_image.seek(0)\n return_img = return_image.read()\n \n return StreamingResponse(content=return_img, media_type=\"image/jpeg\")\n```\n\n```py\ndef some_unimportant_function(params):\n image = Image.open(io.BytesIO(some_image))\n\n return_image = io.BytesIO()\n image.save(return_image, \"JPEG\")\n return_image.seek(0)\n return StreamingResponse(content=return_image, media_type=\"image/jpeg\")\n```\n\n```text\nStreamingResponse\n```\n\n```text\nPIL\n```\n\n```py\ndef some_unimportant_function(params):\n tensor = # read the tensor from disk or whatever\n image = torchvision.transforms.ToPILImage()(tensor.unsqueeze(0))\n return_image = io.BytesIO()\n image.save(return_image, \"JPEG\")\n return_image.seek(0)\n return StreamingResponse(content=return_image, media_type=\"image/jpeg\")\n```\n\n========================================\n\nComments:\n- What error/behavior are you getting?\n- `TypeError: 'bytes' object is not an iterator` and when I try turning it into an iterator I get `AttributeError: 'int' object has no attribute 'encode'`\n- Why don't you convert the tensor into PIL Image object using `torchvision.transforms.ToPILImage()`?\n- It needs to be passed to the frontend as a byte object\n- Sure, you will just convert the tensor to PIL Image object then do what you have done in the PIL Image by saving it as byte object and sending it to the stream.\n- ahhh gotcha, Thanks! I also had to squeeze the tensor to get it into the correct shape as well.\n- Using a `StreamingResponse`, while the image bytes are already fully loaded into memory, makes little sense. You should instead use a custom `Response`, passing the image bytes and setting the `Content-Disposition` header, as described in **this** and **this** answer.","metadata":{"transformedAt":"2026-08-18T18:32:29.123Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":84,"estimatedTokens":735}}337{"id":"stack-72390581","source":"stackoverflow","questionId":72390581,"title":"FastAPI auth check before granting access to sub-applications","tags":["jwt","fastapi","http-authentication"],"text":"Title: FastAPI auth check before granting access to sub-applications\nTags: jwt, fastapi, http-authentication\nSource: Stack Overflow\n\nQuestion:\nI am mounting a Flask app as a sub-application in my root FastAPI app, as explained in the documentation\n\nNow I want to add an authentication layer using `HTTPAuthorizationCredentials` dependency, as nicely explained in this tutorial\n\ntutorial code\n\nHow can I do that?\n\nPreferably, I would like that any type of access attempt to my Flask sub-application goes first through a valid token authentication process implemented in my FastAPI root app. Is that possible?\n\n========================================\n\nCode:\n```text\nHTTPAuthorizationCredentials\n```\n\n```text\nfrom fastapi import FastAPI, Depends, HTTPException\nfrom fastapi.middleware.wsgi import WSGIMiddleware\nfrom flask import Flask, escape, request\nfrom starlette.routing import Mount\nfrom starlette.types import Scope, Receive, Send\n\nflask_app = Flask(__name__)\n\ndef authenticate(authorization: str = Header()):\n # Add logic to authorize user\n if authorization == \"VALID_TOKEN\":\n return\n else:\n raise HTTPException(status_code=401, detail=\"Not Authorized\")\n\nclass AuthWSGIMiddleware(WSGIMiddleware):\n\n async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:\n _, authorization = next((header for header in scope['headers'] if header[0] == b'authorization'), (b'authorization', \"\" ))\n authenticate(authorization.decode('utf-8'))\n await super().__call__(scope, receive, send)\n\nroutes = [\n Mount(\"/v1\", AuthWSGIMiddleware(flask_app)),\n ]\n\n# OR Optionally use this as you were doing\n# The above one is preferred as per starlette docs\n# app.mount(\"/v1\", WSGIMiddleware(flask_app))\n\n\n@flask_app.route(\"/\")\ndef flask_main():\n name = request.args.get(\"name\", \"World\")\n return f\"Hello, {escape(name)} from Flask!\"\n\napp = FastAPI(routes=routes, dependencies=[Depends(authenticate)])\n\n\n@app.get(\"/v2\")\ndef read_main():\n return {\"message\": \"Hello World\"}\n```\n\n```text\nWSGIMiddleware\n```\n\n```text\nauthenticate\n```\n\n```text\nAuthWSGIMiddleware->__call__()\n```\n\n```text\nAuthHandler().decode_toke(authorization)\n```\n\n========================================\n\nComments:\n- Thanks @John, that works! I would also like to mention here a similar solution applied to static files: github.com/tiangolo/fastapi/issues/858#issuecomment-87656402‌​0","metadata":{"transformedAt":"2026-08-18T18:32:29.123Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":6,"totalLines":87,"estimatedTokens":608}}338{"id":"stack-70632673","source":"stackoverflow","questionId":70632673,"title":"FastAPI is not loading static files","tags":["javascript","python","fastapi","static-files","starlette"],"text":"Title: FastAPI is not loading static files\nTags: javascript, python, fastapi, static-files, starlette\nSource: Stack Overflow\n\nQuestion:\nSo, I'm swapping my project from node.js to python FastAPI. Everything has been working fine with node, but here it says that my static files are not present, so here's the code:\n\n```\nfrom fastapi import FastAPI, Request, WebSocket\nfrom fastapi.responses import HTMLResponse\nfrom fastapi.staticfiles import StaticFiles\nfrom fastapi.templating import Jinja2Templates\n\napp = FastAPI()\n\napp.mount(\"/static\", StaticFiles(directory=\"../static\"), name=\"static\")\ntemplates = Jinja2Templates(directory='../templates')\n\n@app.get('/')\nasync def index_loader(request: Request):\n return templates.TemplateResponse('index.html', {\"request\": request})\n```\n\nThe project's structure looks like this: \n\nhttps://i.sstatic.net/179ag.png\n\nFiles are clearly where they should be, but when I connect to the website, the following error occurs:\n\n```\n←[32mINFO←[0m: connection closed\n←[32mINFO←[0m: 127.0.0.1:54295 - \"←[1mGET /img/separator.png HTTP/1.1←[0m\" ←[31m404 Not Found←[0m\n←[32mINFO←[0m: 127.0.0.1:54296 - \"←[1mGET /css/rajdhani.css HTTP/1.1←[0m\" ←[31m404 Not Found←[0m\n←[32mINFO←[0m: 127.0.0.1:54295 - \"←[1mGET /js/pixi.min.js HTTP/1.1←[0m\" ←[31m404 Not Found←[0m\n←[32mINFO←[0m: 127.0.0.1:54296 - \"←[1mGET /js/ease.js HTTP/1.1←[0m\" ←[31m404 Not Found←[0m\n←[32mINFO←[0m: 127.0.0.1:54298 - \"←[1mGET / HTTP/1.1←[0m\" ←[32m200 OK←[0m\n←[32mINFO←[0m: 127.0.0.1:54298 - \"←[1mGET /img/separator.png HTTP/1.1←[0m\" ←[31m404 Not Found←[0m\n←[32mINFO←[0m: 127.0.0.1:54299 - \"←[1mGET /css/rajdhani.css HTTP/1.1←[0m\" ←[31m404 Not Found←[0m\n←[32mINFO←[0m: 127.0.0.1:54298 - \"←[1mGET /js/pixi.min.js HTTP/1.1←[0m\" ←[31m404 Not Found←[0m\n←[32mINFO←[0m: 127.0.0.1:54299 - \"←[1mGET /js/ease.js HTTP/1.1←[0m\" ←[31m404 Not Found←[0m\n```\n\nSo, basically, any static file that I'm using is missing, and I have no idea what I am doing wrong. How to fix it?\n\n========================================\n\nTop Answer:\n### Mounting a `StaticFiles` instance\n\nTo mount a `StaticFiles` instance to a specific path, you could use the following example.\n\nGiven the structure of your project, as shown in the screenshot you provided in your question:\n\nhttps://i.sstatic.net/179ag.png\n\nthe `directory` of `StaticFiles` should be as follows:\n\n```\nfrom fastapi import FastAPI\nfrom fastapi.staticfiles import StaticFiles\n\napp = FastAPI()\n\napp.mount(\"/static\", StaticFiles(directory=\"../static\"), name=\"static\")\n```\n\n### Accessing `StaticFiles` within Jinja2 templates\n\nLinking to `static` files in your Jinja2 template could be achieved in the following way, as described in Starlette's documentation:\n\n```\n\n```\n\n**Alternatively**, you could directly use the pathname given when you mounted a `StaticFiles` instance. In this case, that is, `/static`. Hence, any path that starts with `/static` will be handled by the `StaticFiles` \"sub-application\":\n\n```\n\n```\n\nFor more details, please refer to this answer and this answer.\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI, Request, WebSocket\nfrom fastapi.responses import HTMLResponse\nfrom fastapi.staticfiles import StaticFiles\nfrom fastapi.templating import Jinja2Templates\n\napp = FastAPI()\n\napp.mount(\"/static\", StaticFiles(directory=\"../static\"), name=\"static\")\ntemplates = Jinja2Templates(directory='../templates')\n\n@app.get('/')\nasync def index_loader(request: Request):\n return templates.TemplateResponse('index.html', {\"request\": request})\n```\n\n```text\n←[32mINFO←[0m: connection closed\n←[32mINFO←[0m: 127.0.0.1:54295 - \"←[1mGET /img/separator.png HTTP/1.1←[0m\" ←[31m404 Not Found←[0m\n←[32mINFO←[0m: 127.0.0.1:54296 - \"←[1mGET /css/rajdhani.css HTTP/1.1←[0m\" ←[31m404 Not Found←[0m\n←[32mINFO←[0m: 127.0.0.1:54295 - \"←[1mGET /js/pixi.min.js HTTP/1.1←[0m\" ←[31m404 Not Found←[0m\n←[32mINFO←[0m: 127.0.0.1:54296 - \"←[1mGET /js/ease.js HTTP/1.1←[0m\" ←[31m404 Not Found←[0m\n←[32mINFO←[0m: 127.0.0.1:54298 - \"←[1mGET / HTTP/1.1←[0m\" ←[32m200 OK←[0m\n←[32mINFO←[0m: 127.0.0.1:54298 - \"←[1mGET /img/separator.png HTTP/1.1←[0m\" ←[31m404 Not Found←[0m\n←[32mINFO←[0m: 127.0.0.1:54299 - \"←[1mGET /css/rajdhani.css HTTP/1.1←[0m\" ←[31m404 Not Found←[0m\n←[32mINFO←[0m: 127.0.0.1:54298 - \"←[1mGET /js/pixi.min.js HTTP/1.1←[0m\" ←[31m404 Not Found←[0m\n←[32mINFO←[0m: 127.0.0.1:54299 - \"←[1mGET /js/ease.js HTTP/1.1←[0m\" ←[31m404 Not Found←[0m\n```\n\n```text\napp.mount(\"/static\", StaticFiles(directory=\"../static\"), name=\"static\")\n```\n\n```text\n/static\n```\n\n```text\nstatic\n```\n\n```text\n<img src=\"static/img/separator.png\"/>\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.staticfiles import StaticFiles\n\napp = FastAPI()\n\napp.mount(\"/static\", StaticFiles(directory=\"../static\"), name=\"static\")\n```\n\n```html\n<link href=\"{{ url_for('static', path='/css/rajdhani.css') }}\" rel=\"stylesheet\">\n```\n\n```html\n<link href=\"static/css/rajdhani.css'\" rel=\"stylesheet\">\n```\n\n```text\nStaticFiles\n```\n\n```text\nStaticFiles\n```\n\n```text\ndirectory\n```\n\n```text\nStaticFiles\n```\n\n```text\nStaticFiles\n```\n\n```text\nstatic\n```\n\n```text\nStaticFiles\n```\n\n```text\n/static\n```\n\n```text\n/static\n```\n\n```text\nStaticFiles\n```\n\n```text\nfolder = os.path.dirname(__file__)\napp.mount(\"/static\", StaticFiles(directory=folder+\"/../static\",html=True), name=\"static\")\n```\n\n```text\ndirectory=\"../static\"\n```\n\n```text\nhtml=True\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.124Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":22,"totalLines":199,"estimatedTokens":1346}}339{"id":"stack-73645294","source":"stackoverflow","questionId":73645294,"title":"return deeply nested json objects with response_model fastAPI and Pydantic","tags":["python","sqlalchemy","fastapi","pydantic"],"text":"Title: return deeply nested json objects with response_model fastAPI and Pydantic\nTags: python, sqlalchemy, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nThis is my schema file\n\n```\nfrom pydantic import BaseModel\nfrom typing import Optional\n\nclass HolidaySchema(BaseModel):\n year: int\n month: int\n country: str\n language: str\n\nclass HolidayDateSchema(BaseModel):\n name: str\n date: str\n holidays: HolidaySchema | None = None\n\n class Config:\n orm_mode = True\n```\n\nand this is the router that I have\n\n```\n@router.get(\"/holidays/\",response_model = List[HolidayDateSchema])\n```\n\nThe response I want to get is\n\n```\n[\n {\n \"date\": \"2021-08-14\",\n \"name\": \"Independence Day\",\n \"holidays\": { \"year\": 2022, \"month\":5, \"country\":\"pk\", \"language\":\"en\"},\n \"id\": 13\n },\n]\n```\n\nRight now it doesn't support the pydantic schema with response model, I don't know why and it gives error `pydantic.error_wrappers.ValidationError: 2 validation errors for HolidayDateSchema` and `value is not a valid dict`\n\nIt would be great if anyone can specify the best to get deeply nested JSON objects with response_model.\n\n========================================\n\nCode:\n```text\nfrom pydantic import BaseModel\nfrom typing import Optional\n\n\nclass HolidaySchema(BaseModel):\n year: int\n month: int\n country: str\n language: str\n\n\nclass HolidayDateSchema(BaseModel):\n name: str\n date: str\n holidays: HolidaySchema | None = None\n\n class Config:\n orm_mode = True\n```\n\n```text\n@router.get(\"/holidays/\",response_model = List[HolidayDateSchema])\n```\n\n```text\n[\n {\n \"date\": \"2021-08-14\",\n \"name\": \"Independence Day\",\n \"holidays\": { \"year\": 2022, \"month\":5, \"country\":\"pk\", \"language\":\"en\"},\n \"id\": 13\n },\n]\n```\n\n```text\npydantic.error_wrappers.ValidationError: 2 validation errors for HolidayDateSchema\n```\n\n```text\nvalue is not a valid dict\n```\n\n```py\nclass HolidaySchema(BaseModel):\n year: int\n month: int\n country: str\n language: str\n\n class Config:\n orm_mode = True\n```\n\n```text\norm_mode = True\n```\n\n========================================\n\nComments:\n- Error comes more probably from the definition of your function than from the router annotation. Please some code allowing to reproduce the error. Also, note that `{ year: 2022, month:5, country:pk, language:en}` is not a valid JSON: strings must be quoted, like `{\"year\": 2022, \"month\": 5, \"country\": \"pk\", \"language\": \"en\"}`\n- It works fine, I do not get any error at all. There is mistake if you are returning exactly same as what you have given as example response. The dict keys `year`, `month`, etc are not enclosed within quotes.\n- I'm not returning this at all, I'm returning sqlalchemy query object which would already be in the appropriate format.\n- `HolidaySchema` isn't configured with `orm_mode = True`. You need this for *all* the models that you want to automagically convert from SQLAlchemy model objects. You can configure that setting on a common BaseModel and inherit from that instead if you want the setting for all your models.","metadata":{"transformedAt":"2026-08-18T18:32:29.124Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":7,"totalLines":118,"estimatedTokens":764}}340{"id":"stack-72448405","source":"stackoverflow","questionId":72448405,"title":"Lots of ResourceWarning in FastApi with asyncpg","tags":["python-asyncio","fastapi","asyncpg"],"text":"Title: Lots of ResourceWarning in FastApi with asyncpg\nTags: python-asyncio, fastapi, asyncpg\nSource: Stack Overflow\n\nQuestion:\nI have an async FastApi application with async sqlalchemy, source code:\n\n### database.py\n\n```\nfrom sqlalchemy import (\n Column,\n String,\n)\nfrom sqlalchemy.ext.asyncio import AsyncSession, create_async_engine\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import sessionmaker\nfrom sqlalchemy.orm.decl_api import DeclarativeMeta\n\nfrom app.config import settings\n\nengine = create_async_engine(settings.DATABASE_URL, pool_per_ping=True)\nBase: DeclarativeMeta = declarative_base()\nasync_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)\n\nclass Titles(Base):\n __tablename__ = \"titles\"\n id = Column(String(100), primary_key=True)\n title = Column(String(100), unique=True)\n\nasync def get_session() -> AsyncSession:\n async with async_session() as session:\n yield session\n```\n\n### routers.py\n\n```\nimport .database\nfrom fastapi_utils.cbv import cbv\nfrom fastapi_utils.inferring_router import InferringRouter\n\nrouter = InferringRouter()\n\nasync def get_titles(session: AsyncSession):\n results = await session.execute(select(database.Titles)))\n return results.scalars().all()\n\n@cbv(router)\nclass TitlesView:\n session: AsyncSession = Depends(database.get_session)\n\n @router.get(\"/titles\", status_code=HTTP_200_OK)\n async def get(self) -> List[TitlesSchema]:\n results = await get_titles(self.session)\n return [TitlesSchema.from_orm(result) for result in results]\n```\n\n### main.py\n\n```\nfrom fastapi import FastAPI\n\nfrom app.routers import router \n\ndef create_app() -> FastAPI:\n fast_api_app = FastAPI()\n fast_api_app.include_router(router, prefix=\"/\", tags=[\"Titles\"])\n\n return fast_api_app\n\napp = create_app()\n```\n\n### manage.py\n\n```\nimport asyncio\nimport sys\n\nfrom .database import async_session, Base, engine\n\nasync def init_models():\n async with engine.begin() as conn:\n await conn.run_sync(Base.metadata.create_all, checkfirst=True)\n \nif __name__ == \"__main__\":\n asyncio.run(init_models())\n sys.stdout.write(\"Models initiated\\n\")\n```\n\nIt runs with docker:\n\n```\npython manage.py\nCMD [\"uvicorn\", \"main:app\", \"--reload\", \"--host\", \"0.0.0.0\", \"--port\", \"8000\", \"--limit-max-requests\", \"10000\"]\n```\n\nAnd right after i see message `Models initiated`, after `init_models() func` i see couple of warnings:\n\n```\napp_1 | Models initiated\napp_1 | /usr/local/lib/python3.9/site-packages/asyncpg/connection.py:131: ResourceWarning: unclosed connection ; run in asyncio debug mode to show the traceback of connection origin\napp_1 | /usr/local/lib/python3.9/asyncio/sslproto.py:320: ResourceWarning: unclosed transport \napp_1 | /usr/local/lib/python3.9/asyncio/selector_events.py:704: ResourceWarning: unclosed transport \napp_1 | INFO: Uvicorn running on http://0.0.0.0:5000 (Press CTRL+C to quit)\napp_1 | INFO: Started reloader process [15] using statreload\napp_1 | INFO: Started server process [17]\napp_1 | INFO: Waiting for application startup.\napp_1 | INFO: Application startup complete.\n```\n\nAnd after i make changes, i see a bunch of warnings:\n\n```\napp_1 | WARNING: StatReload detected file change in 'ref_info/main.py'. Reloading...\napp_1 | INFO: Shutting down\napp_1 | INFO: Waiting for application shutdown.\napp_1 | INFO: Application shutdown complete.\napp_1 | INFO: Finished server process [15]\napp_1 | sys:1: ResourceWarning: unclosed file \napp_1 | INFO: Started server process [16]\napp_1 | INFO: Waiting for application startup.\napp_1 | INFO: Application startup complete.\n```\n\nIs it ok, and i need to hide it? Or i setted up smth wrong?\n\n========================================\n\nCode:\n```text\nfrom sqlalchemy import (\n Column,\n String,\n)\nfrom sqlalchemy.ext.asyncio import AsyncSession, create_async_engine\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import sessionmaker\nfrom sqlalchemy.orm.decl_api import DeclarativeMeta\n\nfrom app.config import settings\n\n\nengine = create_async_engine(settings.DATABASE_URL, pool_per_ping=True)\nBase: DeclarativeMeta = declarative_base()\nasync_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)\n\n\nclass Titles(Base):\n __tablename__ = \"titles\"\n id = Column(String(100), primary_key=True)\n title = Column(String(100), unique=True)\n\n\nasync def get_session() -> AsyncSession:\n async with async_session() as session:\n yield session\n```\n\n```text\nimport .database\nfrom fastapi_utils.cbv import cbv\nfrom fastapi_utils.inferring_router import InferringRouter\n\n\nrouter = InferringRouter()\n\n\nasync def get_titles(session: AsyncSession):\n results = await session.execute(select(database.Titles)))\n return results.scalars().all()\n\n\n@cbv(router)\nclass TitlesView:\n session: AsyncSession = Depends(database.get_session)\n\n @router.get(\"/titles\", status_code=HTTP_200_OK)\n async def get(self) -> List[TitlesSchema]:\n results = await get_titles(self.session)\n return [TitlesSchema.from_orm(result) for result in results]\n```\n\n```text\nfrom fastapi import FastAPI\n\nfrom app.routers import router \n\n\ndef create_app() -> FastAPI:\n fast_api_app = FastAPI()\n fast_api_app.include_router(router, prefix=\"/\", tags=[\"Titles\"])\n\n return fast_api_app\n\n\napp = create_app()\n```\n\n```text\nimport asyncio\nimport sys\n\nfrom .database import async_session, Base, engine\n\n\nasync def init_models():\n async with engine.begin() as conn:\n await conn.run_sync(Base.metadata.create_all, checkfirst=True)\n \nif __name__ == \"__main__\":\n asyncio.run(init_models())\n sys.stdout.write(\"Models initiated\\n\")\n```\n\n```text\npython manage.py\nCMD [\"uvicorn\", \"main:app\", \"--reload\", \"--host\", \"0.0.0.0\", \"--port\", \"8000\", \"--limit-max-requests\", \"10000\"]\n```\n\n```text\napp_1 | Models initiated\napp_1 | /usr/local/lib/python3.9/site-packages/asyncpg/connection.py:131: ResourceWarning: unclosed connection <asyncpg.connection.Connection object at 0x7efe5a613c80>; run in asyncio debug mode to show the traceback of connection origin\napp_1 | /usr/local/lib/python3.9/asyncio/sslproto.py:320: ResourceWarning: unclosed transport <asyncio.sslproto._SSLProtocolTransport object at 0x7efe5a631700>\napp_1 | /usr/local/lib/python3.9/asyncio/selector_events.py:704: ResourceWarning: unclosed transport <_SelectorSocketTransport fd=6>\napp_1 | INFO: Uvicorn running on http://0.0.0.0:5000 (Press CTRL+C to quit)\napp_1 | INFO: Started reloader process [15] using statreload\napp_1 | INFO: Started server process [17]\napp_1 | INFO: Waiting for application startup.\napp_1 | INFO: Application startup complete.\n```\n\n```text\napp_1 | WARNING: StatReload detected file change in 'ref_info/main.py'. Reloading...\napp_1 | INFO: Shutting down\napp_1 | INFO: Waiting for application shutdown.\napp_1 | INFO: Application shutdown complete.\napp_1 | INFO: Finished server process [15]\napp_1 | sys:1: ResourceWarning: unclosed file <_io.TextIOWrapper name=0 mode='r' encoding='UTF-8'>\napp_1 | INFO: Started server process [16]\napp_1 | INFO: Waiting for application startup.\napp_1 | INFO: Application startup complete.\n```\n\n```text\nModels initiated\n```\n\n```text\ninit_models() func\n```\n\n```text\nengine = create_async_engine(\n settings.DATABASE_ASYNC_URI,\n echo=\"debug\" if settings.DEBUG else False,\n)\nasync_session = sessionmaker(\n bind=engine,\n class_=AsyncSession,\n autoflush=True,\n autocommit=False,\n expire_on_commit=False,\n)\n\n\nasync def get_session() -> AsyncGenerator[AsyncSession, None]:\n async with async_session() as session:\n assert isinstance(session, AsyncSession)\n yield session\n\n\nasync def connect() -> None:\n async with engine.begin() as conn:\n await conn.run_sync(Base.metadata.create_all, checkfirst=True)\n\n\nasync def disconnect() -> None:\n if engine:\n await engine.dispose()\n```\n\n```text\nconnect\n```\n\n```text\ndisconnect\n```\n\n========================================\n\nComments:\n- I'm debugging this myself now, but I think it might be related to this issue github.com/tiangolo/fastapi/issues/4719\n- Any success with this? Same problem started happening today can't find out the reason why.\n- Yes, i just recently solved it. See my answer\n- I have the same issue - what part was the problem? I have all my connections in context-managers but it still persists.\n- My problem fixed as I said in answer. Maybe you got smth different. Post your question, and I will try to help you\n- Ok. I saw your question. Your context-manager does not close any session, try to make session context manager that will yield session and then closing it\n- Would you mind explaining why my current solution does not work - maybe post an answer to the question (also for other future users) stackoverflow.com/questions/78528045/…","metadata":{"transformedAt":"2026-08-18T18:32:29.124Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":12,"totalLines":301,"estimatedTokens":2193}}341{"id":"stack-79864930","source":"stackoverflow","questionId":79864930,"title":"FastAPI backend always returns HTTP 200 on login (even with wrong credentials) and no cookie is set after deployment","tags":["python","nginx","cookies","fastapi","reverse-proxy"],"text":"Title: FastAPI backend always returns HTTP 200 on login (even with wrong credentials) and no cookie is set after deployment\nTags: python, nginx, cookies, fastapi, reverse-proxy\nSource: Stack Overflow\n\nQuestion:\nI have a React frontend communicating with a backend server. When I run and test both locally, authentication works correctly—failed login attempts return appropriate error statuses (e.g., 401 or 403). However, after deploying both to a remote host, the backend always returns HTTP 200 with a message saying “authentication successful,” regardless of whether the credentials are valid or not.\n\n**/admin.auth.py**\n\n```\nfrom fastapi.routing import APIRouter\nfrom fastapi.responses import JSONResponse, Response\nfrom fastapi import Form, Request, Depends\nfrom typing import Annotated\nimport bcrypt\nimport uuid\n\nfrom admin.model import LoginFormData, UserSession\nfrom database.depends import get_SQLManager\n\nauth_router = APIRouter(prefix=\"/auth\", tags=[\"admin\"])\n\n@auth_router.post(\"/login\")\nasync def login(request: Request, \n form_data: Annotated[LoginFormData, Form()],\n db_manager=Depends(get_SQLManager)):\n \n if request.session and request.session[\"role\"] == \"admin\":\n response = {\"status\": \"success\", \"message\": \"login successful\"}\n return JSONResponse(content=response, status_code=200)\n\n username = form_data.username\n password = form_data.password\n \n user = await db_manager.UserTable.get_user(username)\n await db_manager.close()\n \n if not user:\n response = {\"status\": \"fail\", \"message\": \"user does not exist\"}\n return JSONResponse(content=response, status_code=404)\n\n password_encoded = password.encode(\"utf-8\")\n password_stored_encoded = user.password.encode(\"utf-8\")\n verified = bcrypt.checkpw(password_encoded, password_stored_encoded)\n\n if not verified:\n response = {\"status\": \"fail\", \"message\": \"login failed\"}\n return JSONResponse(content=response, status_code=404)\n \n request.session[\"role\"] = \"admin\"\n response = {\"status\": \"success\", \"message\": \"login successful\"}\n return JSONResponse(content=response, status_code=200)\n\n@auth_router.post(\"/session\")\nasync def login(request: Request):\n if request.session and request.session[\"role\"] == \"admin\":\n response = {\"status\": \"success\", \"message\": \"login successful\"}\n return JSONResponse(content=response, status_code=200)\n\n return Response(status_code=403)\n```\n\n**nginx.conf**\n\n```\nserver {\n listen 80;\n server_name www.tomanshome.com tomanshome.com backend.tomanshome.com;\n return 301 https://$server_name$request_uri;\n}\n\nserver {\n listen 443 ssl;\n ssl_protocols TLSv1.2 TLSv1.3;\n server_name www.tomanshome.com tomanshome.com;\n\n ssl_certificate /etc/letsencrypt/live/www.tomanshome.com/fullchain.pem;\n ssl_certificate_key /etc/letsencrypt/live/www.tomanshome.com/privkey.pem;\n\n add_header Content-Security-Policy \"upgrade-insecure-requests;\";\n\n access_log /var/log/nginx/tomanshome.com.access.log;\n error_log /var/log/nginx/tomanshome.com.error.log;\n \n root /home/deploy/tomanshome.com; \n index index.html;\n\n add_header X-XSS-Protection \"1; mode=block\" always; \n\n location / {\n try_files $uri $uri/ /index.html;\n }\n}\n\nserver {\n listen 443 ssl;\n ssl_protocols TLSv1.2 TLSv1.3;\n server_name backend.tomanshome.com;\n\n ssl_certificate /etc/letsencrypt/live/backend.tomanshome.com/fullchain.pem; \n ssl_certificate_key /etc/letsencrypt/live/backend.tomanshome.com/privkey.pem; \n\n access_log /var/log/nginx/backend.tomanshome.com.access.log;\n error_log /var/log/nginx/backend.tomanshome.com.error.log;\n\n set $allowed_origin 'https://tomanshome.com';\n proxy_intercept_errors off;\n\n location / {\n if ($request_method = 'OPTIONS') {\n add_header 'Access-Control-Allow-Origin' $allowed_origin always;\n add_header 'Access-Control-Allow-Methods' 'GET, POST, DELETE, PATCH, OPTIONS' always;\n add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization' always;\n add_header 'Access-Control-Allow-Credentials' 'true' always;\n return 204;\n }\n\n proxy_pass http://127.0.0.1:8000;\n\n proxy_pass_header Set-Cookie;\n proxy_set_header Cookie $http_cookie;\n\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header X-Forwarded-Proto $scheme;\n\n add_header 'Access-Control-Allow-Origin' 'https://tomanshome.com' always;\n add_header 'Access-Control-Allow-Credentials' 'true' always;\n\n }\n}\n```\n\n- What could cause FastAPI to always return HTTP 200 with an authentication success message regardless of credentials after deployment?\n\n- why would cookies not be set even on what should be successful authentication?\n\nI could not find any viable solution for the issue, so any help will be greatly appreciated!\n\n========================================\n\nCode:\n```text\nfrom fastapi.routing import APIRouter\nfrom fastapi.responses import JSONResponse, Response\nfrom fastapi import Form, Request, Depends\nfrom typing import Annotated\nimport bcrypt\nimport uuid\n\nfrom admin.model import LoginFormData, UserSession\nfrom database.depends import get_SQLManager\n\nauth_router = APIRouter(prefix=\"/auth\", tags=[\"admin\"])\n\n@auth_router.post(\"/login\")\nasync def login(request: Request, \n form_data: Annotated[LoginFormData, Form()],\n db_manager=Depends(get_SQLManager)):\n \n if request.session and request.session[\"role\"] == \"admin\":\n response = {\"status\": \"success\", \"message\": \"login successful\"}\n return JSONResponse(content=response, status_code=200)\n\n username = form_data.username\n password = form_data.password\n \n user = await db_manager.UserTable.get_user(username)\n await db_manager.close()\n \n if not user:\n response = {\"status\": \"fail\", \"message\": \"user does not exist\"}\n return JSONResponse(content=response, status_code=404)\n\n password_encoded = password.encode(\"utf-8\")\n password_stored_encoded = user.password.encode(\"utf-8\")\n verified = bcrypt.checkpw(password_encoded, password_stored_encoded)\n\n if not verified:\n response = {\"status\": \"fail\", \"message\": \"login failed\"}\n return JSONResponse(content=response, status_code=404)\n \n request.session[\"role\"] = \"admin\"\n response = {\"status\": \"success\", \"message\": \"login successful\"}\n return JSONResponse(content=response, status_code=200)\n\n@auth_router.post(\"/session\")\nasync def login(request: Request):\n if request.session and request.session[\"role\"] == \"admin\":\n response = {\"status\": \"success\", \"message\": \"login successful\"}\n return JSONResponse(content=response, status_code=200)\n\n return Response(status_code=403)\n```\n\n```text\nserver {\n listen 80;\n server_name www.tomanshome.com tomanshome.com backend.tomanshome.com;\n return 301 https://$server_name$request_uri;\n}\n\nserver {\n listen 443 ssl;\n ssl_protocols TLSv1.2 TLSv1.3;\n server_name www.tomanshome.com tomanshome.com;\n\n ssl_certificate /etc/letsencrypt/live/www.tomanshome.com/fullchain.pem;\n ssl_certificate_key /etc/letsencrypt/live/www.tomanshome.com/privkey.pem;\n\n add_header Content-Security-Policy \"upgrade-insecure-requests;\";\n\n access_log /var/log/nginx/tomanshome.com.access.log;\n error_log /var/log/nginx/tomanshome.com.error.log;\n \n root /home/deploy/tomanshome.com; \n index index.html;\n\n add_header X-XSS-Protection \"1; mode=block\" always; \n\n location / {\n try_files $uri $uri/ /index.html;\n }\n}\n\nserver {\n listen 443 ssl;\n ssl_protocols TLSv1.2 TLSv1.3;\n server_name backend.tomanshome.com;\n\n ssl_certificate /etc/letsencrypt/live/backend.tomanshome.com/fullchain.pem; \n ssl_certificate_key /etc/letsencrypt/live/backend.tomanshome.com/privkey.pem; \n\n access_log /var/log/nginx/backend.tomanshome.com.access.log;\n error_log /var/log/nginx/backend.tomanshome.com.error.log;\n\n set $allowed_origin 'https://tomanshome.com';\n proxy_intercept_errors off;\n\n location / {\n if ($request_method = 'OPTIONS') {\n add_header 'Access-Control-Allow-Origin' $allowed_origin always;\n add_header 'Access-Control-Allow-Methods' 'GET, POST, DELETE, PATCH, OPTIONS' always;\n add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization' always;\n add_header 'Access-Control-Allow-Credentials' 'true' always;\n return 204;\n }\n\n proxy_pass http://127.0.0.1:8000;\n\n proxy_pass_header Set-Cookie;\n proxy_set_header Cookie $http_cookie;\n\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header X-Forwarded-Proto $scheme;\n\n add_header 'Access-Control-Allow-Origin' 'https://tomanshome.com' always;\n add_header 'Access-Control-Allow-Credentials' 'true' always;\n\n }\n}\n```\n\n```text\nif request.session and request.session[\"role\"] == \"admin\":\n response = {\"status\": \"success\", \"message\": \"login successful\"}\n return JSONResponse(content=response, status_code=200)\n```\n\n```text\nrequest.session\n```\n\n```text\nSessionMiddleware\n```\n\n```text\n200\n```\n\n```text\nSessionMiddleware\n```\n\n```text\nsame_site=\"none\"\n```\n\n```text\nhttps_only=True\n```\n\n```text\ncredentials: \"include\"\n```\n\n========================================\n\nComments:\n- Thank you! Your answer was a great help!","metadata":{"transformedAt":"2026-08-18T18:32:29.124Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":10,"totalLines":304,"estimatedTokens":2322}}342{"id":"stack-68981869","source":"stackoverflow","questionId":68981869,"title":"How to upload a single file to FastAPI server using CURL","tags":["python","curl","fastapi"],"text":"Title: How to upload a single file to FastAPI server using CURL\nTags: python, curl, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm trying to set up a FastAPI server that can **receive** a **single file upload** from the command line using **curl**.\n\nI'm following the FastAPI Tutorial here:\n\nhttps://fastapi.tiangolo.com/tutorial/request-files/?h=upload+file\n\n```\nfrom typing import List\nfrom fastapi import FastAPI, File, UploadFile\nfrom fastapi.responses import HTMLResponse\napp = FastAPI()\n\n@app.post(\"/file/\")\nasync def create_file(file: bytes = File(...)):\n return {\"file_size\": len(file)}\n\n@app.post(\"/uploadfile/\")\nasync def create_upload_file(file: UploadFile = File(...)):\n return {\"filename\": file.filename}\n\n@app.post(\"/files/\")\nasync def create_files(files: List[bytes] = File(...)):\n return {\"file_sizes\": [len(file) for file in files]}\n\n@app.post(\"/uploadfiles/\")\nasync def create_upload_files(files: List[UploadFile] = File(...)):\n return {\"filenames\": [file.filename for file in files]}\n```\n\nRunning this code and then opening \"http://127.0.0.1:5094\" in a browser gives me a upload form with four ways of selecting files and uploading\n\nI followed this tutorial:\nhttps://medium.com/@petehouston/upload-files-with-curl-93064dcccc76\n\nI tried uploading a file \"1.json\" in the current directory like this\n\n```\ncurl -F \"file=@1.json\" http://127.0.0.1:5094/uploadfiles\n```\n\non the server side I get this result\n\n```\nINFO: 127.0.0.1:58772 - \"POST /uploadfiles HTTP/1.1\" 307 Temporary Redirect\n```\n\nI do not understand why a redirect happens.\n\nI need help on how to either guess the correct curl syntax or fix this on the FastAPI side.\n\n========================================\n\nCode:\n```text\nfrom typing import List\nfrom fastapi import FastAPI, File, UploadFile\nfrom fastapi.responses import HTMLResponse\napp = FastAPI()\n\n@app.post(\"/file/\")\nasync def create_file(file: bytes = File(...)):\n return {\"file_size\": len(file)}\n\n@app.post(\"/uploadfile/\")\nasync def create_upload_file(file: UploadFile = File(...)):\n return {\"filename\": file.filename}\n\n@app.post(\"/files/\")\nasync def create_files(files: List[bytes] = File(...)):\n return {\"file_sizes\": [len(file) for file in files]}\n\n@app.post(\"/uploadfiles/\")\nasync def create_upload_files(files: List[UploadFile] = File(...)):\n return {\"filenames\": [file.filename for file in files]}\n```\n\n```text\ncurl -F \"file=@1.json\" http://127.0.0.1:5094/uploadfiles\n```\n\n```text\nINFO: 127.0.0.1:58772 - \"POST /uploadfiles HTTP/1.1\" 307 Temporary Redirect\n```\n\n```text\ncurl -L -F \"file=@1.json\" http://127.0.0.1:5094/uploadfile\n```\n\n========================================\n\nComments:\n- Alternatively adding trailing slash to the URL should also do `curl -F \"file=@1.json\" http://127.0.0.1:5094/uploadfiles/`","metadata":{"transformedAt":"2026-08-18T18:32:29.124Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":97,"estimatedTokens":696}}343{"id":"stack-76910226","source":"stackoverflow","questionId":76910226,"title":"Why isn't my class attribute preserved when using multiprocessing?","tags":["python","multiprocessing","fastapi","event-loop","class-variables"],"text":"Title: Why isn't my class attribute preserved when using multiprocessing?\nTags: python, multiprocessing, fastapi, event-loop, class-variables\nSource: Stack Overflow\n\nQuestion:\nI have the following class in a FastAPI application:\n\n```\nimport asyncio\nimport logging\nfrom multiprocessing import Lock, Process\n\nfrom .production_status import Job as ProductionStatusJob\n\nclass JobScheduler:\n loop = None\n logger = logging.getLogger(\"job_scheduler\")\n process_lock = Lock()\n JOBS = [ProductionStatusJob]\n\n @classmethod\n def start(cls) -> None:\n cls.logger.info(\"Starting Up (1/2)\")\n Process(target=cls._loop).start()\n \n @classmethod\n def _loop(cls) -> None:\n cls.loop = asyncio.get_event_loop()\n cls.loop.create_task(cls._run())\n cls.logger.info(\"Startup Complete (2/2)\")\n cls.loop.run_forever()\n cls.loop.close()\n\n @classmethod\n async def _run(cls) -> None:\n while True:\n ...\n\n @classmethod\n async def stop(cls) -> None:\n cls.logger.info(\"Shutting Down (1/2)\")\n with cls.process_lock:\n cls.loop.stop() # On the `startup` and `shutdown` events of the FastAPI application, the `JobScheduler.start()` and `JobScheduler.stop()` methods will be called.\n\nThe `start` method works smoothly, but in `stop` I get an error:\n\n```\nFile \"/backend/app/main.py\", line 146, in stop_job_scheduler\n2023-08-16 11:46:27 await job_scheduler.stop()\n2023-08-16 11:46:27 File \"/backend/app/jobs/__init__.py\", line 59, in stop\n2023-08-16 11:46:27 cls.loop.stop()\n2023-08-16 11:46:27 AttributeError: 'NoneType' object has no attribute 'stop'\n```\n\nBut `cls.loop` is set during the `_loop` method (which is executed at the end of `start`) - so why does `cls.loop` still have its initial `None` value when the `stop` method is called?\n\nAre there any better approaches to clean up the background processes when the FastAPI application calls `shutdown`?\n\n========================================\n\nTop Answer:\nThanks to Silvio and Selcuk the root cause of the issue was found. For anyone who's wondering how I solved this in practice, here it is:\n\nI stored the `Process` *before the forking* and killed it at the `stop`:\n\n```\nclass JobScheduler:\n manager = None\n loop = None\n logger = _logger\n process_lock = Lock()\n JOBS = [ProductionStatusJob]\n\n @classmethod\n def start(cls) -> None:\n cls.logger.info(\"Starting Up (1/2)\")\n cls.loop = Process(target=cls._loop)\n cls.loop.start()\n \n @classmethod\n def _loop(cls) -> None:\n loop = asyncio.get_event_loop()\n loop.create_task(cls._run())\n cls.logger.info(\"Startup Complete (2/2)\")\n loop.run_forever()\n loop.close() # None:\n cls.logger.info(\"Shutting Down (1/2)\")\n with cls.process_lock:\n cls.loop.kill()\n cls.logger.info(\"Shutdown Complete (2/2)\")\n cls.loop = None\n```\n\n========================================\n\nCode:\n```py\nimport asyncio\nimport logging\nfrom multiprocessing import Lock, Process\n\nfrom .production_status import Job as ProductionStatusJob\n\n\nclass JobScheduler:\n loop = None\n logger = logging.getLogger(\"job_scheduler\")\n process_lock = Lock()\n JOBS = [ProductionStatusJob]\n\n @classmethod\n def start(cls) -> None:\n cls.logger.info(\"Starting Up (1/2)\")\n Process(target=cls._loop).start()\n \n @classmethod\n def _loop(cls) -> None:\n cls.loop = asyncio.get_event_loop()\n cls.loop.create_task(cls._run())\n cls.logger.info(\"Startup Complete (2/2)\")\n cls.loop.run_forever()\n cls.loop.close()\n\n @classmethod\n async def _run(cls) -> None:\n while True:\n ...\n\n @classmethod\n async def stop(cls) -> None:\n cls.logger.info(\"Shutting Down (1/2)\")\n with cls.process_lock:\n cls.loop.stop() # <= This Line\n cls.loop.close()\n cls.logger.info(\"Shutdown Complete (2/2)\")\n cls.loop = None\n```\n\n```text\nFile \"/backend/app/main.py\", line 146, in stop_job_scheduler\n2023-08-16 11:46:27 await job_scheduler.stop()\n2023-08-16 11:46:27 File \"/backend/app/jobs/__init__.py\", line 59, in stop\n2023-08-16 11:46:27 cls.loop.stop()\n2023-08-16 11:46:27 AttributeError: 'NoneType' object has no attribute 'stop'\n```\n\n```text\nstartup\n```\n\n```text\nshutdown\n```\n\n```text\nJobScheduler.start()\n```\n\n```text\nJobScheduler.stop()\n```\n\n```text\nstart\n```\n\n```text\nstop\n```\n\n```text\ncls.loop\n```\n\n```text\n_loop\n```\n\n```text\nstart\n```\n\n```text\ncls.loop\n```\n\n```text\nNone\n```\n\n```text\nstop\n```\n\n```text\nshutdown\n```\n\n```text\nmultiprocessing\n```\n\n```text\nmultiprocessing\n```\n\n```text\nManager\n```\n\n```text\nQueue\n```\n\n```text\nclass JobScheduler:\n manager = None\n loop = None\n logger = _logger\n process_lock = Lock()\n JOBS = [ProductionStatusJob]\n\n @classmethod\n def start(cls) -> None:\n cls.logger.info(\"Starting Up (1/2)\")\n cls.loop = Process(target=cls._loop)\n cls.loop.start()\n \n @classmethod\n def _loop(cls) -> None:\n loop = asyncio.get_event_loop()\n loop.create_task(cls._run())\n cls.logger.info(\"Startup Complete (2/2)\")\n loop.run_forever()\n loop.close() # <= is probably never called\n...\n\n @classmethod\n async def stop(cls) -> None:\n cls.logger.info(\"Shutting Down (1/2)\")\n with cls.process_lock:\n cls.loop.kill()\n cls.logger.info(\"Shutdown Complete (2/2)\")\n cls.loop = None\n```\n\n```text\nProcess\n```\n\n```text\nstop\n```\n\n========================================\n\nComments:\n- You are not setting `cls.loop` in `start()`. You're setting it in `_loop()`. Are you one hundred thousand percent sure that `_loop()` is being called *before* `stop()` is executed?\n- I guess the problem is multiprocessing will fork, and create a separate copy of `cls`, and it will set the `loop` attribute for the copy, not for the one you called `.stop` from.\n- @SilvioMayolo Oops. It was a typing error, I'll fix it right away. Yes, I'm positive that the `_loop()` is called before `stop()` because I can verify that both `cls.logger.info(\"Startup Complete (2/2)\")` and the processes in `_run()` are completed before I stop the application (hence calling the `stop()`)\n- @Selcuk but that's stupid. Why would I want to use a Class Variable, unless I want it to stay the same for everytime the class variable is called/used? I guess I'll try to use a `mutliprocess.Manager` object and see how it goes! Thanks for the tip!\n- Class variables are singletons, but only for the current process. Think of multiprocessing as if you are spinning up a new `python` interpreter every time you fork/spawn (it is smarter than this, but you get the idea). Consider using multithreading since you need to memory in this case.\n- Oops! I didn't see the `Process` part. Selcuk is right, you get a new copy for each process.\n- Does multiprocessing: sharing a large read-only object between processes? answer your question?\n- The only word of warning with *forking* behavior is that it's Unix-specific. You can't fork a process on Windows, unfortunately. Other than that, it's *insanely* convenient.","metadata":{"transformedAt":"2026-08-18T18:32:29.124Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":22,"totalLines":265,"estimatedTokens":1740}}344{"id":"stack-65230997","source":"stackoverflow","questionId":65230997,"title":"When I use fastapi and pydantic to build POST API, appear a TypeError: Object of type is not JSON serializable","tags":["python","fastapi","pydantic"],"text":"Title: When I use fastapi and pydantic to build POST API, appear a TypeError: Object of type is not JSON serializable\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI use FastAPi and Pydantic to model the requests and responses to an POST API.\n\nI defined three class:\n\n```\nfrom pydantic import BaseModel, Field\nfrom typing import List, Optional, Dict\n\nclass RolesSchema(BaseModel):\n roles_id: List[str]\n\nclass HRSchema(BaseModel):\n pk: int\n user_id: str\n worker_id: str\n worker_name: str\n worker_email: str\n schedulable: bool\n roles: RolesSchema\n state: dict\n\nclass CreateHR(BaseModel):\n user_id: str\n worker_id: str\n worker_name: str\n worker_email: str\n schedulable: bool\n roles: RolesSchema\n```\n\nAnd My API's program:\n\n```\n@router.post(\"/humanResource\", response_model=HRSchema)\nasync def create_humanResource(create: CreateHR):\nquery = HumanResourceModel.insert().values(\n user_id=create.user_id, \n worker_id=create.worker_id, \n worker_name=create.worker_name,\n worker_email=create.worker_email,\n schedulable=create.schedulable,\n roles=create.roles\n)\nlast_record_id = await database.execute(query)\nreturn {\"status\": \"Successfully Created!\"}\n```\n\nInput data format is json:\n\n```\n{\n \"user_id\": \"123\",\n \"worker_id\": \"010\",\n \"worker_name\": \"Amos\",\n \"worker_email\": \"Amos@mail.com\",\n \"schedulable\": true,\n \"roles\": {\"roles_id\": [\"001\"]}\n}\n```\n\nWhen I executed, I got TypeError: Object of type RolesSchema is not JSON serializable.\n\nHow can I fix the program to normal operation?\n\n========================================\n\nTop Answer:\nIf someone came here with the error message.\n\nIn my case:\n\n```\ndata = MyBaseModel(**data) \n\n# bad - TypeError: Object of type is not JSON serializable\njson.dumps(data)\n\n# good\ndata.json()\n```\n\n========================================\n\nCode:\n```text\nfrom pydantic import BaseModel, Field\nfrom typing import List, Optional, Dict\n\nclass RolesSchema(BaseModel):\n roles_id: List[str]\n\nclass HRSchema(BaseModel):\n pk: int\n user_id: str\n worker_id: str\n worker_name: str\n worker_email: str\n schedulable: bool\n roles: RolesSchema\n state: dict\n\nclass CreateHR(BaseModel):\n user_id: str\n worker_id: str\n worker_name: str\n worker_email: str\n schedulable: bool\n roles: RolesSchema\n```\n\n```text\n@router.post(\"/humanResource\", response_model=HRSchema)\nasync def create_humanResource(create: CreateHR):\nquery = HumanResourceModel.insert().values(\n user_id=create.user_id, \n worker_id=create.worker_id, \n worker_name=create.worker_name,\n worker_email=create.worker_email,\n schedulable=create.schedulable,\n roles=create.roles\n)\nlast_record_id = await database.execute(query)\nreturn {\"status\": \"Successfully Created!\"}\n```\n\n```text\n{\n \"user_id\": \"123\",\n \"worker_id\": \"010\",\n \"worker_name\": \"Amos\",\n \"worker_email\": \"Amos@mail.com\",\n \"schedulable\": true,\n \"roles\": {\"roles_id\": [\"001\"]}\n}\n```\n\n```text\nroles=create.roles.dict()\n```\n\n```text\nquery\n```\n\n```text\nroles=create.roles\n```\n\n```text\ndata = MyBaseModel(**data) \n\n# bad - TypeError: Object of type is not JSON serializable\njson.dumps(data)\n\n# good\ndata.json()\n```\n\n========================================\n\nComments:\n- Does this answer your question? How to specify the response_model in FastAPI on a non-default return?\n- See related answers here and here.\n- In my case I did load the json of the object and then converted back to an object.... `raise HTTPException(status_code=404, detail=json.loads(resp.json()))`","metadata":{"transformedAt":"2026-08-18T18:32:29.124Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":7,"totalLines":169,"estimatedTokens":873}}345{"id":"stack-79023460","source":"stackoverflow","questionId":79023460,"title":"Handling Circular Imports in Pydantic models with FastAPI","tags":["python","sqlalchemy","fastapi","pydantic","circular-dependency"],"text":"Title: Handling Circular Imports in Pydantic models with FastAPI\nTags: python, sqlalchemy, fastapi, pydantic, circular-dependency\nSource: Stack Overflow\n\nQuestion:\nI'm developing a **FastAPI** application organized with the following module structure.\n\n```\n...\n│ ├── modules\n│ │ ├── box\n│ │ │ ├── routes.py\n│ │ │ ├── services.py\n│ │ │ ├── models.py # the sqlalchemy classes\n│ │ │ ├── schemas.py # the pydantic schemas\n│ │ ├── toy\n│ │ │ ├── routes.py\n│ │ │ ├── services.py\n│ │ │ ├── models.py\n│ │ │ ├── schemas.py\n```\n\nEach module contains **SQLAlchemy** models, **Pydantic** models (also called schemas), FastAPI routes, and services that handle the business logic.\n\nIn this example, I am using two modules that represent boxes and toys. Each toy is stored in one box, and each box contains multiple toys, following a classic `1 x N` relationship.\n\nWith **SQLAlchemy** everything goes well, defining relationships is straightforward by using `TYPE_CHECKING` to handle circular dependencies:\n\n```\n# my_app.modules.box.models.py\n\nfrom sqlalchemy.orm import Mapped, mapped_column, relationship\nif TYPE_CHECKING:\n from my_app.modules.toy.models import Toy\n\nclass Box(Base):\n __tablename__ = \"box\"\n id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)\n\n toys: Mapped[list[\"Toy\"]] = relationship(back_populates=\"box\")\n```\n\n```\n# my_app.modules.toy.models.py\n\nfrom sqlalchemy.orm import Mapped, mapped_column, relationship\nif TYPE_CHECKING:\n from my_app.modules.box.models import Box\n\nclass Toy(Base):\n __tablename__ = \"toy\"\n id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)\n box: Mapped[\"Box\"] = relationship(back_populates=\"toys\")\n```\n\nThis setup works perfectly without raising any circular import errors. However, I encounter issues when defining the same relationships between **Pydantic** schemas. If I import directly the modules on my schemas.py,\n\n```\n# my_app.modules.box.schemas.py\nfrom my_app.modules.toy.schemas import ToyBase\n\nclass BoxBase(BaseModel):\n id: int\n\nclass BoxResponse(BoxBase):\n toys: list[ToyBase]\n```\n\n```\n# my_app.modules.toy.schemas.py\nfrom my_app.modules.box.schemas import BoxBase\n\nclass ToyBase(BaseModel):\n id: int\n \nclass ToyResponse(ToyBase):\n box: BoxBase\n```\n\nI recieve the circular import error:\n\n```\nImportError: cannot import name 'ToyBase' from partially initialized module 'my_app.modules.toy.schemas' (most likely due to a circular import)...\n```\n\nI also try the **SQLAlchemy** approach of `TYPE_CHECKING` and string declaration:\n\n```\n# my_app.modules.box.schemas.py\nif TYPE_CHECKING:\n from my_app.modules.toy.schemas import ToyBase\n\nclass BoxBase(BaseModel):\n id: int\n\nclass BoxResponse(BoxBase):\n toys: list[\"ToyBase\"]\n```\n\n```\n# my_app.modules.toy.schemas.py\nif TYPE_CHECKING:\n from my_app.modules.box.schemas import BoxBase\n\nclass ToyBase(BaseModel):\n id: int\n \nclass ToyResponse(ToyBase):\n box: \"BoxBase\"\n```\n\nBut apparently, pydantic doesn't support this:\n\n```\nraise PydanticUndefinedAnnotation.from_name_error(e) from e\npydantic.errors.PydanticUndefinedAnnotation: name 'ToyBase' is not defined\n```\n\n(Some answers) suggest that the issue comes from a poor module organization. (Others) suggest, too complex and hard to understand solutions.\n\nMaybe I'm wrong but I consider the relationship between `Box` and `Toy` something trivial and fundamental that should be manageable in any moderately complex project. For example, a straightforward use case would be to request a toy along with its containing box and vice versa, a box with all its toys. Aren't they legitimate requests?\n\n### So, my question\n\nHow can I define interrelated **Pydantic** schemas (`BoxResponse` and `ToyResponse`) that reference each other without encountering circular import errors? I'm looking for an clear and maintainable solution that preserves the independence of the box and toy modules, similar to how relationships are handled in **SQLAlchemy** models. Any suggestions or at least an explanation of why this is so difficult to achieve?\n\n========================================\n\nTop Answer:\nPydantic can't construct infinitely recursive models.\nAs`ToyResponse` is written the data you receive would have to be infinitely recursive.\n\n```\n{\nid: \"x\"\nbox: {\n id: \"a\"\n toys: [{\n id: \"x\"\n box: {\n id: \"a\"\n toys: ... and so on\n }]\n }\n}\n```\n\nThis seems like a case where SQLAlchemy doesn't attempt to process the type annotations at run time, but Pydantic is when it tries to construct the class objects causing a circular import.\n\nOne way to break the recursive definition would be to define a `Toy` model that doesn't have a reference to `BoxResponse` in the definition and use that in `BoxResponse`\n\n```\nclass BoxResponse(BaseModel):\n id: int\n toys: list[ToyWithoutNestedBox]\n```\n\nEDIT in response to question edits:\nNow that the models are split into `Base` and `Response` classes, you'll remove the circular import if you define the `Base` and `Response` classes in separate files from eachother. This is because the `Base` classes require no imports from other models so the `Response` classes are free to import them without the risk of circular imports.\n\n========================================\n\nCode:\n```text\n...\n│ ├── modules\n│ │ ├── box\n│ │ │ ├── routes.py\n│ │ │ ├── services.py\n│ │ │ ├── models.py # the sqlalchemy classes\n│ │ │ ├── schemas.py # the pydantic schemas\n│ │ ├── toy\n│ │ │ ├── routes.py\n│ │ │ ├── services.py\n│ │ │ ├── models.py\n│ │ │ ├── schemas.py\n```\n\n```py\n# my_app.modules.box.models.py\n\nfrom sqlalchemy.orm import Mapped, mapped_column, relationship\nif TYPE_CHECKING:\n from my_app.modules.toy.models import Toy\n\nclass Box(Base):\n __tablename__ = \"box\"\n id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)\n\n toys: Mapped[list[\"Toy\"]] = relationship(back_populates=\"box\")\n```\n\n```py\n# my_app.modules.toy.models.py\n\nfrom sqlalchemy.orm import Mapped, mapped_column, relationship\nif TYPE_CHECKING:\n from my_app.modules.box.models import Box\n\nclass Toy(Base):\n __tablename__ = \"toy\"\n id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)\n box: Mapped[\"Box\"] = relationship(back_populates=\"toys\")\n```\n\n```py\n# my_app.modules.box.schemas.py\nfrom my_app.modules.toy.schemas import ToyBase\n\nclass BoxBase(BaseModel):\n id: int\n\nclass BoxResponse(BoxBase):\n toys: list[ToyBase]\n```\n\n```py\n# my_app.modules.toy.schemas.py\nfrom my_app.modules.box.schemas import BoxBase\n\nclass ToyBase(BaseModel):\n id: int\n \nclass ToyResponse(ToyBase):\n box: BoxBase\n```\n\n```text\nImportError: cannot import name 'ToyBase' from partially initialized module 'my_app.modules.toy.schemas' (most likely due to a circular import)...\n```\n\n```py\n# my_app.modules.box.schemas.py\nif TYPE_CHECKING:\n from my_app.modules.toy.schemas import ToyBase\n\nclass BoxBase(BaseModel):\n id: int\n\nclass BoxResponse(BoxBase):\n toys: list[\"ToyBase\"]\n```\n\n```py\n# my_app.modules.toy.schemas.py\nif TYPE_CHECKING:\n from my_app.modules.box.schemas import BoxBase\n\nclass ToyBase(BaseModel):\n id: int\n \nclass ToyResponse(ToyBase):\n box: \"BoxBase\"\n```\n\n```text\nraise PydanticUndefinedAnnotation.from_name_error(e) from e\npydantic.errors.PydanticUndefinedAnnotation: name 'ToyBase' is not defined\n```\n\n```text\n1 x N\n```\n\n```text\nTYPE_CHECKING\n```\n\n```text\nTYPE_CHECKING\n```\n\n```text\nBox\n```\n\n```text\nToy\n```\n\n```text\nBoxResponse\n```\n\n```text\nToyResponse\n```\n\n```py\n# my_app.modules.box.schemas.py\nfrom pydantic import BaseModel\nfrom my_app.modules.toy.schemas import ToyResponse\n\nclass BoxResponse(BaseModel):\n id: int\n toys: list[\"ToyResponse\"] # Type check not required here since this is the parent class\n```\n\n```py\n# my_app.modules.toy.schemas.py\nfrom typing import TYPE_CHECKING\nfrom pydantic import BaseModel\n\nif TYPE_CHECKING:\n from my_app.modules.box.schemas import BoxResponse\n\nclass ToyResponse(BaseModel):\n id: int\n if TYPE_CHECKING:\n box: \"BoxResponse\"\n else:\n box\n```\n\n```text\ntoys:[\"ToyResponse\"]\n```\n\n```text\nTYPE_CHECK\n```\n\n```text\nTYPE_CHECK\n```\n\n```text\n__future__ import annotations\n```\n\n```text\n{\nid: \"x\"\nbox: {\n id: \"a\"\n toys: [{\n id: \"x\"\n box: {\n id: \"a\"\n toys: ... and so on\n }]\n }\n}\n```\n\n```py\nclass BoxResponse(BaseModel):\n id: int\n toys: list[ToyWithoutNestedBox]\n```\n\n```text\nToyResponse\n```\n\n```text\nToy\n```\n\n```text\nBoxResponse\n```\n\n```text\nBoxResponse\n```\n\n```text\nBase\n```\n\n```text\nResponse\n```\n\n```text\nBase\n```\n\n```text\nResponse\n```\n\n```text\nBase\n```\n\n```text\nResponse\n```\n\n========================================\n\nComments:\n- Wow, I tried it, and you're right, the program runs now, I can't believe it! But I have another question: if you don't annotate the circular imports, how do you validate the response object? I don't feel very satisfied validating some endpoints (most of them) with pydantic and others with a different technique.\n- I might be wrong but you should still be able to validate your data as usual with the above solution.\n- You are right, your solution works well during validation! I am asking because you mentioned that you don't type annotate the circular imports, so how do you perform the validation?\n- We create separate classes in our fast api with the mirrored data points when we are unable to validate due to circular imports.\n- @KevinHernandez I tried the proposed solution but it does not work for me. I have effectively the same setup as \"Biowav\" in my project but when I try this solution with the `if` and `else` clause I still get `NameError: name 'box' is not defined`. If I type `pass` inside the `else` clause it runs without an error but it just ignores the object completely as if `TYPE_CHECKING` is always `False` for some reason.\n- My mistake, you're right :), it was an infinite recursion, but that wasn’t my actual issue. I edited the post fixing that.\n- See my edit now :). Fixing the recursive definition was the first step to getting rid of the circular import, now you just need to split the files.","metadata":{"transformedAt":"2026-08-18T18:32:29.124Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":34,"totalLines":401,"estimatedTokens":2505}}346{"id":"stack-74689457","source":"stackoverflow","questionId":74689457,"title":"Overriding FastAPI dependencies that have parameters","tags":["python","dependency-injection","pytest","fastapi"],"text":"Title: Overriding FastAPI dependencies that have parameters\nTags: python, dependency-injection, pytest, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm trying to test my FastAPI endpoints by overriding the injected database using the officially recommended method in the FastAPI documentation.\n\nThe function I'm injecting the db with is a closure that allows me to build any desired database from a MongoClient by giving it the database name whilst (I assume) still working with FastAPI depends as it returns a closure function's signature. No error is thrown so I think this method is correct:\n\n```\n# app\ndef build_db(name: str):\n def close():\n return build_singleton_whatever(MongoClient, args....)\n return close\n```\n\nAdding it to the endpoint:\n\n```\n# endpoint\n@app.post(\"/notification/feed\")\nasync def route_receive_notifications(db: Database = Depends(build_db(\"someDB\"))):\n ...\n```\n\nAnd finally, attempting to override it in the tests:\n\n```\n# pytest\n# test_endpoint.py\nfastapi_app.dependency_overrides[app.build_db] = lambda x: lambda: x\n```\n\nHowever, the dependency doesn't seem to override at all and the test ends up creating a MongoClient with the IP of the production database as in normal execution.\n\n**So**, any ideas on overriding FastAPI dependencies that are given parameters in their endpoints?\n\nI have tried creating a mock closure function with no success:\n\n```\ndef mock_closure(*args):\n def close():\n return args\n return close\n\napp.dependency_overrides[app.build_db] = mock_closure('otherDB')\n```\n\nAnd I have also tried providing the same signature, including the parameter, with still no success:\n\n```\napp.dependency_overrides[app.build_db('someDB')] = mock_closure('otherDB')\n```\n\n*Edit note* I'm also aware I can create a separate function that creates my desired database and use that as the dependency, but I would much prefer to use this dynamic version as it's more scalable to using more databases in my apps and avoids me writing essentially repeated functions just so they can be cleanly injected.\n\n========================================\n\nTop Answer:\nThere are two issues with your implementation getting in your way:\n\n- As you are *calling* `build_db` right in the `route_receive_notifications` function definition, the latter receives nested `close` function as a dependency. And it's impossible to override it. To fix this you would need to avoid calling your dependency right away and still provide it with db name. For that you can either define a new dependency to inject name into `build_db`:\n\n```\n# app\ndef get_db_name():\n return \"someDB\"\n\ndef build_db(name: str = Depends(get_db_name)):\n ...\n\n# endpoint\n@app.post(\"/notification/feed\")\nasync def route_receive_notifications(db: Database = Depends(build_db)):\n ...\n```\n\nor use `functools.partial` (shorter but less elegant):\n\n```\n# endpoint\nfrom functools import partial\n\n@app.post(\"/notification/feed\")\nasync def route_receive_notifications(db: Database = Depends(partial(build_db, \"someDB\"))):\n ...\n```\n\n- FastAPI requires dependency overriding function to have the same signature as the original dependency. Simply switching from `*args` to a single parameter is enough, although using the same argument name and type makes it easier to support in future. Of course you need to provide the function itself as a value for `dependency_overrides` *without calling it*:\n\n```\ndef mock_closure(name: str):\n def close():\n return name\n return close\n\napp.dependency_overrides[app.build_db] = mock_closure\n```\n\n========================================\n\nCode:\n```python\n# app\ndef build_db(name: str):\n def close():\n return build_singleton_whatever(MongoClient, args....)\n return close\n```\n\n```python\n# endpoint\n@app.post(\"/notification/feed\")\nasync def route_receive_notifications(db: Database = Depends(build_db(\"someDB\"))):\n ...\n```\n\n```python\n# pytest\n# test_endpoint.py\nfastapi_app.dependency_overrides[app.build_db] = lambda x: lambda: x\n```\n\n```python\ndef mock_closure(*args):\n def close():\n return args\n return close\n\napp.dependency_overrides[app.build_db] = mock_closure('otherDB')\n```\n\n```python\napp.dependency_overrides[app.build_db('someDB')] = mock_closure('otherDB')\n```\n\n```py\n@router.get(\"/{foo}\")\nasync def get(foo, client = Depends(get_client)): # get_client is the key to override\n client = get_client()\n return await client.request(foo)\n```\n\n```py\nclass Client:\n def __init__(request):\n self._request = request\n \n async def request(self, params):\n return await self._request(params)\n```\n\n```py\ndef get_client_getter(response):\n async def request_mock(*args, **kwargs):\n return response\n\n def get_client():\n return Client(request=request_mock)\n\n return get_client()\n```\n\n```py\ndef test_1():\n app.dependency_overrides[get_client] = get_client_getter(1)\n ...\n\ndef test_true():\n app.dependency_overrides[get_client] = get_client_getter(True)\n ...\n\ndef test_none():\n app.dependency_overrides[get_client] = get_client_getter(None)\n ...\n```\n\n```text\nget_client\n```\n\n```text\nClient\n```\n\n```text\naiohttp\n```\n\n```text\nClient\n```\n\n```text\nfrom sqlalchemy.ext.asyncio import AsyncSession, create_async_engine\n\nfrom settings import get_settings\n\n\n@pytest.fixture()\nasync def get_engine():\n engine = create_async_engine(get_settings().test_db_url)\n yield engine\n await engine.dispose()\n\n\n@pytest.fixture()\nasync def db_session(get_engine) -> AsyncSession:\n async with get_engine.begin() as connection:\n async with async_session(bind=connection) as session:\n yield session\n await session.close()\n\n\n@pytest.fixture()\ndef override_get_async_session(db_session: AsyncSession) -> Callable:\n async def _override_get_async_session():\n yield db_session\n\n return _override_get_async_session\n```\n\n```text\n# app\ndef get_db_name():\n return \"someDB\"\n\ndef build_db(name: str = Depends(get_db_name)):\n ...\n\n# endpoint\n@app.post(\"/notification/feed\")\nasync def route_receive_notifications(db: Database = Depends(build_db)):\n ...\n```\n\n```text\n# endpoint\nfrom functools import partial\n\n@app.post(\"/notification/feed\")\nasync def route_receive_notifications(db: Database = Depends(partial(build_db, \"someDB\"))):\n ...\n```\n\n```text\ndef mock_closure(name: str):\n def close():\n return name\n return close\n\napp.dependency_overrides[app.build_db] = mock_closure\n```\n\n```text\nbuild_db\n```\n\n```text\nroute_receive_notifications\n```\n\n```text\nclose\n```\n\n```text\nbuild_db\n```\n\n```text\nfunctools.partial\n```\n\n```text\n*args\n```\n\n```text\ndependency_overrides\n```\n\n========================================\n\nComments:\n- Initial guess would be to either move the inner function out from function to be a separate function (which then would have a unique reference you can register in your overrides), or try to resolve it by having it returned: `app.dependency_overrides[app.build_db(\"dummy\")]`; since what is *actually* registered in the dependency hierarchy is the inner function (which is why registering the override for `app.build_db` doesn't work - as that just returns the inner function when the dependency gets resolved). I'm unsure if Python would return the same function in that case (I'd guess no).\n- @MatsLindh I had a go at this because the logic makes sense but it didn't seem to have any effect either. I think it's definitely some sort of problem with the mapping as it doesn't affect the endpoint's dependency at all, which means the app dependency overriding isn't doing anything in this specific case. Find it weird the docs don't talk about this scenario, so maybe it's just not supported.\n- @JoeMoon did you find a solution to this question? I have a similar problem here stackoverflow.com/questions/76796168/…\n- I like this suggestion but going to wait for an answer that might match my strategy more closely. Thank you!\n- I am going the same approach but it is not working stackoverflow.com/questions/76796168/…","metadata":{"transformedAt":"2026-08-18T18:32:29.124Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":24,"totalLines":291,"estimatedTokens":1986}}347{"id":"stack-70183853","source":"stackoverflow","questionId":70183853,"title":"Send pathlib.Path data to FastAPI: PosixPath is not JSON serializable","tags":["python","json","fastapi","pydantic"],"text":"Title: Send pathlib.Path data to FastAPI: PosixPath is not JSON serializable\nTags: python, json, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI have built an API using FastAPI and am trying to send data to it from a client.\n\nBoth the API and the client use a similar Pydantic model for the data that I want to submit. This includes a field that contains a file path, which I store in a field of type pathlib.path.\n\nHowever, FastAPI does not accept the submission because it apparently cannot handle the path object:\n\n`TypeError: Object of type PosixPath is not JSON serializable`\n\nHere's a minimal test file that shows the problem:\n\n```\nimport pathlib\nfrom pydantic import BaseModel\nfrom fastapi import FastAPI\nfrom fastapi.testclient import TestClient\n\napi = FastAPI()\nclient = TestClient(api)\n\nclass Submission(BaseModel):\n file_path: pathlib.Path\n\n@api.post(\"/\", response_model=Submission)\nasync def add_submission(subm: Submission):\n print(subm)\n # add submission to database\n return subm\n\ndef test_add_submission():\n data = {\"file_path\": \"/my/path/to/file.csv\"}\n print(\"original data:\", data)\n\n # create a Submission object, which casts filePath to pathlib.Path:\n submission = Submission(**data) \n print(\"submission object:\", submission)\n\n payload = submission.dict()\n print(\"payload:\", payload)\n\n response = client.post(\"/\", json=payload) # this throws the error\n assert response.ok\n\ntest_add_submission()\n```\n\nWhen I change the model on the client side to use a string instead of a Path for `file_path`, things go through. But then I lose the pydantic power of casting the input to a Path when a Submission object is created, and then having a Path attribute with all its possibilities. Surely, there must be better way?\n\n**What is the correct way to send a pathlib.PosixPath object to a FastAPI API as part of the payload?**\n\n(This is Python 3.8.9, fastapi 0.68.1, pydantic 1.8.2 on Ubuntu)\n\n========================================\n\nCode:\n```text\nimport pathlib\nfrom pydantic import BaseModel\nfrom fastapi import FastAPI\nfrom fastapi.testclient import TestClient\n\n\napi = FastAPI()\nclient = TestClient(api)\n\nclass Submission(BaseModel):\n file_path: pathlib.Path\n\n@api.post(\"/\", response_model=Submission)\nasync def add_submission(subm: Submission):\n print(subm)\n # add submission to database\n return subm\n\n\ndef test_add_submission():\n data = {\"file_path\": \"/my/path/to/file.csv\"}\n print(\"original data:\", data)\n\n # create a Submission object, which casts filePath to pathlib.Path:\n submission = Submission(**data) \n print(\"submission object:\", submission)\n\n payload = submission.dict()\n print(\"payload:\", payload)\n\n response = client.post(\"/\", json=payload) # this throws the error\n assert response.ok\n\ntest_add_submission()\n```\n\n```text\nTypeError: Object of type PosixPath is not JSON serializable\n```\n\n```text\nfile_path\n```\n\n```py\nresponse = client.post(\"/\", data=submission.json())\n```\n\n```text\nsubmission.dict()\n```\n\n```text\nclient.post(\"/\", json=payload)\n```\n\n```text\nrequests\n```\n\n```text\npathlib.Path\n```\n\n```text\njson()\n```\n\n```text\njson\n```\n\n```text\ndata\n```\n\n========================================\n\nComments:\n- The error message means that JSON doesn't know how to turn the data into a JSON object like a string, boolean, dictionary, or list etc. You have to specify a serialization format, or just turn it into a structure which JSON understands. Trivially, `str(pathlib.Path(...))` produces the file name as a string; presumably that's what you actually want here. It's not clear where in your `submission` data you have a `pathlib.Path` so you will have to figure that out yourself, or provide a minimal reproducible example which shows how this structure looks so that we can help you with that.\n- Possible duplicate of stackoverflow.com/questions/3768895/…\n- @tripleee The above is an MRE. It's a valid pytest file that recreates the error... I have added the call to `test_add_submission()`, so now it runs as a normal python file.\n- Yes, I want to keep it as a Path object. That's why I stated in the question that I know casting it to string would solve the error but dows not help me.\n- Without information about what else is in `submission` we would have to investigate how `pydantic` defines it, etc. But the straightforward solution is probably to accept this as a duplicate. This unfortunately requires you to override some of the convenient functionality from `pydantic`.\n- @tripleee The rest of `submission` does not have any impact on the issue. The code above is a complete Python file and throws the described error. It is complete as it is. Adding other information to `submission` would delute the MRE without adding anything of value. Yes, pydantic models are that simple. As FastAPI is built on pydantic, I'm hoping there is a more elegant solution than having to build a `.toJSON()` method into a class that already provides a `.json()` out of the box (but that produces a string, and `post` does not accept it, it wants a dict).\n- Maybe also look at stackoverflow.com/questions/66687244/… ... though I agree that the ideal would be if `pydantic` offered a solution; I'm not familiar enough with it to tell you whether that is actually the case.\n- @CodingCat The example is fine. Have you seen how pydantic handles JSON encoding? github.com/samuelcolvin/pydantic/blob/… - this lead me to this question about extending the pydantic json encoding functionality:stackoverflow.com/questions/62311401/… .. you should be able to modify the ENCODERS_BY_TYPE and insert the path class there.\n- @MatsLindh thanks for the pointer. The pydantic-code you linked looks like `pathlib.Path` objects should already be encoded as `str`, though, doesn't it?","metadata":{"transformedAt":"2026-08-18T18:32:29.125Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":11,"totalLines":148,"estimatedTokens":1440}}348{"id":"stack-56996170","source":"stackoverflow","questionId":56996170,"title":"What is Body? `from fastapi import Body`","tags":["python","python-3.x","fastapi"],"text":"Title: What is Body? `from fastapi import Body`\nTags: python, python-3.x, fastapi\nSource: Stack Overflow\n\nQuestion:\nIn the documentation and elsewhere I have seen `Body` used but don't know what it is.\n\nCan someone explain what these three options mean?\n\n```\nfrom fastapi import Body\nfrom pydantic import BaseModel\n\nclass MyModel(BaseModel):\n body1: None\n body2: Body(None)\n body3: Body(...)\n```\n\n========================================\n\nCode:\n```py\nfrom fastapi import Body\nfrom pydantic import BaseModel\n\nclass MyModel(BaseModel):\n body1: None\n body2: Body(None)\n body3: Body(...)\n```\n\n```text\nBody\n```\n\n```text\nfrom pydantic import BaseModel, Schema\n\nclass MyModel(BaseModel):\n body1: None\n body2: Schema(None)\n body3: Schema(...)\n```\n\n```text\nBody\n```\n\n```text\nBody\n```\n\n```text\nBody\n```\n\n```text\nint\n```\n\n```text\nstr\n```\n\n```text\nBody\n```\n\n```text\nBody\n```\n\n========================================\n\nComments:\n- Thanks. OK, I just tested out a few things....and it seems that Body is the only one of Body/Schema that a path operation which won't yield an error, but it seems for when I have something like Schema in MyModel, that the `schema_json` is identical for when I use Body.\n- What is the advantage of using Schema as opposed to Body in my models? It seems that I can provide the same set of arguments and the docs look the same.\n- github.com/tiangolo/fastapi/blob/…\n- OK -- seems like the above shows the only difference is the presence of `embed` and `media_type` ... very cool. And those are not necessary or relevant for Pydantic. Thanks!","metadata":{"transformedAt":"2026-08-18T18:32:29.125Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":10,"totalLines":80,"estimatedTokens":395}}349{"id":"stack-71905671","source":"stackoverflow","questionId":71905671,"title":"How to go through all Pydantic validators even if one fails, and then raise multiple ValueErrors in a FastAPI response?","tags":["python","python-3.x","fastapi","pydantic"],"text":"Title: How to go through all Pydantic validators even if one fails, and then raise multiple ValueErrors in a FastAPI response?\nTags: python, python-3.x, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nIs it possible to call all validators to get back a full list of errors?\n\n```\n@validator('password', always=True)\ndef validate_password1(cls, value):\n password = value.get_secret_value()\n\n min_length = 8\n if len(password) The current behavior seems to call one validator at a time.\n\nMy Pydantic class:\n\n```\nclass User(BaseModel):\n email: EmailStr\n password: SecretStr\n```\n\nIf I did not include the `email`, or `password`, field on a request then I would get both validation failures in an array, which is what I want to do for the `password` field, but the current behavior seems to call one, and if it fails then throws the error immediately.\n\n========================================\n\nTop Answer:\nYou cannot use Pydantic's validators like that; it always looks one of them.\n\nTo achieve your answer, you can use following 2 methods\n\n1 - You can use one main validator which checks all conditions\n\n```\n@validator('password', always=True)\ndef validate_password(cls, value):\n password = value.get_secret_value()\n\n validate_password1(password)\n validate_password2(password)\n\n return value\n \ndef validate_password1(password):\n\n min_length = 8\n if len(password) 2 - You can use duplicate variable in model to check condition\n\n```\nclass User(BaseModel):\n email: EmailStr\n password: SecretStr\n password2: SecretStr\n```\n\nand obviously, your decorators should be:\n\n```\n@validator('password', always=True)\ndef validate_password1(cls, value):\n```\n\nand\n\n```\n@validator('password2', always=True)\ndef validate_password2(cls, value):\n```\n\n**UPDATE:** The OP wants to raise all errors, so the updated answer as follows.\n\nIn addition to 1st bullet, you may try something like that:\n\n```\n@validator('password', always=True)\ndef validate_password(cls, value):\n password = value.get_secret_value()\n\n try:\n validate_password1(password)\n except Exception as e:\n print('First error: ' + str(e))\n \n try:\n validate_password2(password)\n except Exception as e:\n print('Second error: ' + str(e))\n\n return value\n \ndef validate_password1(password):\n\n min_length = 8\n if len(password) However, be careful when returning the `value`. You may try to add one more custom exception in your main code.\n\n========================================\n\nCode:\n```text\n@validator('password', always=True)\ndef validate_password1(cls, value):\n password = value.get_secret_value()\n\n min_length = 8\n if len(password) < min_length:\n raise ValueError('Password must be at least 8 characters long.')\n\n return value\n\n@validator('password', always=True)\ndef validate_password2(cls, value):\n password = value.get_secret_value()\n\n if not any(character.islower() for character in password):\n raise ValueError('Password should contain at least one lowercase character.')\n\n return value\n```\n\n```text\nclass User(BaseModel):\n email: EmailStr\n password: SecretStr\n```\n\n```text\nemail\n```\n\n```text\npassword\n```\n\n```text\npassword\n```\n\n```py\n@validator('password', always=True)\ndef validate_password1(cls, value):\n password = value.get_secret_value()\n min_length = 8\n errors = ''\n if len(password) < min_length:\n errors += 'Password must be at least 8 characters long. '\n if not any(character.islower() for character in password):\n errors += 'Password should contain at least one lowercase character.'\n if errors:\n raise ValueError(errors)\n \n return value\n```\n\n```json\n{\n \"detail\": [\n {\n \"loc\": [\n \"body\",\n \"password\"\n ],\n \"msg\": \"Password must be at least 8 characters long. Password should contain at least one lowercase character.\",\n \"type\": \"value_error\"\n }\n ]\n}\n```\n\n```py\nfrom pydantic import ValidationError\nfrom pydantic.error_wrappers import ErrorWrapper\n\n@validator('password', always=True)\ndef validate_password1(cls, value):\n password = value.get_secret_value()\n min_length = 8\n errors = []\n if len(password) < min_length:\n errors.append(ErrorWrapper(ValueError('Password must be at least 8 characters long.'), loc=None))\n if not any(character.islower() for character in password):\n errors.append(ErrorWrapper(ValueError('Password should contain at least one lowercase character.'), loc=None))\n if errors:\n raise ValidationError(errors, model=User)\n \n return value\n```\n\n```py\nfrom fastapi import Request, status\nfrom fastapi.encoders import jsonable_encoder\nfrom fastapi.exceptions import RequestValidationError\nfrom fastapi.responses import JSONResponse\n\n@app.exception_handler(RequestValidationError)\nasync def validation_exception_handler(request: Request, exc: RequestValidationError):\n for error in exc.errors(): \n error['loc'] = [x for x in error['loc'] if x] # remove null attributes\n \n return JSONResponse(content=jsonable_encoder({\"detail\": exc.errors()}), status_code=status.HTTP_422_UNPROCESSABLE_ENTITY)\n```\n\n```json\n{\n \"detail\": [\n {\n \"loc\": [\n \"body\",\n \"password\"\n ],\n \"msg\": \"Password must be at least 8 characters long.\",\n \"type\": \"value_error\"\n },\n {\n \"loc\": [\n \"body\",\n \"password\"\n ],\n \"msg\": \"Password should contain at least one lowercase character.\",\n \"type\": \"value_error\"\n }\n ]\n}\n```\n\n```text\n@validator\n```\n\n```text\n@field_validator\n```\n\n```text\nValueError\n```\n\n```text\nErrorWrapper\n```\n\n```text\nerror_wrappers.py\n```\n\n```text\n@validator\n```\n\n```text\n@field_validator\n```\n\n```text\nValidationError\n```\n\n```text\nErrorWrapper\n```\n\n```text\nloc\n```\n\n```text\nloc\n```\n\n```text\nfield\n```\n\n```text\npassword\n```\n\n```text\nErrorWrapper\n```\n\n```text\nloc\n```\n\n```text\nNone\n```\n\n```text\n@validator('password', always=True)\ndef validate_password(cls, value):\n password = value.get_secret_value()\n\n validate_password1(password)\n validate_password2(password)\n\n return value\n \ndef validate_password1(password):\n\n min_length = 8\n if len(password) < min_length:\n raise ValueError('Password must be at least 8 characters long.')\n\n\ndef validate_password2(password):\n\n if not any(character.islower() for character in password):\n raise ValueError('Password should contain at least one lowercase character.')\n```\n\n```text\nclass User(BaseModel):\n email: EmailStr\n password: SecretStr\n password2: SecretStr\n```\n\n```text\n@validator('password', always=True)\ndef validate_password1(cls, value):\n```\n\n```text\n@validator('password2', always=True)\ndef validate_password2(cls, value):\n```\n\n```text\n@validator('password', always=True)\ndef validate_password(cls, value):\n password = value.get_secret_value()\n\n try:\n validate_password1(password)\n except Exception as e:\n print('First error: ' + str(e))\n \n try:\n validate_password2(password)\n except Exception as e:\n print('Second error: ' + str(e))\n\n return value\n \ndef validate_password1(password):\n\n min_length = 8\n if len(password) < min_length:\n raise ValueError('Password must be at least 8 characters long.')\n\n\ndef validate_password2(password):\n\n if not any(character.islower() for character in password):\n raise ValueError('Password should contain at least one lowercase character.')\n```\n\n```text\nvalue\n```\n\n========================================\n\nComments:\n- @OrenIshShalom I cant seem to get pydantic or fastapi to return all errors in one go\n- You can use one main validator which checks other validator conditions.\n- @stuck do you have an example, or could you some quick sudo code of what you mean?\n- I have not tested option 2, but option 1 doesn't work. It still returns the first validation, which is the password length validator @stuck\n- You removed `@validator` from other methods, right?\n- By the way, I deleted the return statements from validate_password1 and 2\n- Does not work. raise returns the first error I believe. I've implemented it as you suggested\n- Oh, you want to raise both errors?\n- Yep! If possible, I'd like to get all validation errors in one api call\n- Well, Instead of raising each of them, you can collect them in a list. Or, you can call the sub-functions inside the try-except block. Because when you \"raise\" something, it breaks all steps inside the block. I will update the answer.\n- for v2 this does not work anymore.\n- A few changes are required in Pydantic v2, but essentially it's a case of switching `ErrorWrapper` for `ValidationError.from_exception_data()`. See the following comment for a comprehensive example, that also validates the model before returning. github.com/pydantic/pydantic/discussions/…","metadata":{"transformedAt":"2026-08-18T18:32:29.125Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":32,"totalLines":378,"estimatedTokens":2190}}350{"id":"stack-62359413","source":"stackoverflow","questionId":62359413,"title":"How to return an image in FastAPI after processing it with OpenCV?","tags":["python","image","opencv","fastapi"],"text":"Title: How to return an image in FastAPI after processing it with OpenCV?\nTags: python, image, opencv, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to return an image in FastAPI after comparing two images using Opencv.\n\nHere's what I have done so far:\n\n```\nfrom fastapi import FastAPI , File, UploadFile\nimport numpy as np\nfrom cv2 import *\nimport os\nimport base64\n\napp = FastAPI(debug = True)\n\n \n@app.post(\"/uploadfile/\")\nasync def create_upload_file(file: UploadFile = File(...),file1: UploadFile = File(...)):\n content = await file.read()\n nparr = np.fromstring(content, np.uint8)\n img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)\n\n content1 = await file1.read()\n nparr1 = np.fromstring(content1, np.uint8)\n img1 = cv2.imdecode(nparr1, cv2.IMREAD_COLOR)\n\n akaze = cv2.AKAZE_create()\n kpts1, desc1 = akaze.detectAndCompute(img, None)\n kpts2, desc2 = akaze.detectAndCompute(img1, None)\n matcher = cv2.DescriptorMatcher_create(cv2.DescriptorMatcher_BRUTEFORCE_HAMMING)\n matches_1 = matcher.knnMatch(desc1, desc2, 2)\n good_points = []\n for m,n in matches_1:\n if m.distance #where I am getting an error\n\n```\nreturn_img = cv2.processImage(img)\n _, encoded_img = cv2.imencode('.PNG', return_img)\n encoded_img = base64.b64encode(return_img)\n\n return {\"The similarity is\": mat,'encoded_img': endcoded_img}\n```\n\nWhat am I doing wrong?\n\n========================================\n\nTop Answer:\nThe solution can be found here. You are converting the Opencv Image before encoding it in the 3rd line.\n\n```\nreturn_img = cv2.processImage(img)\n _, encoded_img = cv2.imencode('.PNG', return_img)\n encoded_img = base64.b64encode(return_img)\n\n return {\"The similarity is\": mat,'encoded_img': endcoded_img}\n```\n\nReplace `return_img` with `encoded_img` and everything should be working as expected.\n\n```\nreturn_img = cv2.processImage(img)\n _, encoded_img = cv2.imencode('.PNG', return_img)\n encoded_img = base64.b64encode(encoded_img)\n\n return {\"The similarity is\": mat,'encoded_img': endcoded_img}\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI , File, UploadFile\nimport numpy as np\nfrom cv2 import *\nimport os\nimport base64\n\n\napp = FastAPI(debug = True)\n\n \n@app.post(\"/uploadfile/\")\nasync def create_upload_file(file: UploadFile = File(...),file1: UploadFile = File(...)):\n content = await file.read()\n nparr = np.fromstring(content, np.uint8)\n img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)\n\n content1 = await file1.read()\n nparr1 = np.fromstring(content1, np.uint8)\n img1 = cv2.imdecode(nparr1, cv2.IMREAD_COLOR)\n\n akaze = cv2.AKAZE_create()\n kpts1, desc1 = akaze.detectAndCompute(img, None)\n kpts2, desc2 = akaze.detectAndCompute(img1, None)\n matcher = cv2.DescriptorMatcher_create(cv2.DescriptorMatcher_BRUTEFORCE_HAMMING)\n matches_1 = matcher.knnMatch(desc1, desc2, 2)\n good_points = []\n for m,n in matches_1:\n if m.distance < 0.7 * n.distance:\n good_points.append(m)\n mat = (round(len(kpts2)/len(good_points),2))\n```\n\n```text\nreturn_img = cv2.processImage(img)\n _, encoded_img = cv2.imencode('.PNG', return_img)\n encoded_img = base64.b64encode(return_img)\n\n return {\"The similarity is\": mat,'encoded_img': endcoded_img}\n```\n\n```text\nfrom fastapi import FastAPI\nfrom fastapi.responses import FileResponse\n\nsome_file_path = \"some_image.jpeg\"\napp = FastAPI()\n\n\n@app.get(\"/\")\nasync def main():\n return FileResponse(some_file_path)\n```\n\n```text\nAssertionError: 'aiofiles' must be installed to use FileResponse\n```\n\n```py\nfrom io import BytesIO\n\n@app.post(\"/send_image\")\nasync def send():\n image = BytesIO()\n img = # Do something here to create an image\n img.save(image, format='JPEG', quality=85) # Save image to BytesIO\n image.seek(0) # Return cursor to starting point\n return StreamingResponse(image.read(), media_type=\"image/jpeg\")\n```\n\n```text\naiofiles\n```\n\n```text\npip install aiofiles\n```\n\n```text\nStreamingResponse\n```\n\n```text\nreturn_img = cv2.processImage(img)\n _, encoded_img = cv2.imencode('.PNG', return_img)\n encoded_img = base64.b64encode(return_img)\n\n return {\"The similarity is\": mat,'encoded_img': endcoded_img}\n```\n\n```text\nreturn_img = cv2.processImage(img)\n _, encoded_img = cv2.imencode('.PNG', return_img)\n encoded_img = base64.b64encode(encoded_img)\n\n return {\"The similarity is\": mat,'encoded_img': endcoded_img}\n```\n\n```text\nreturn_img\n```\n\n```text\nencoded_img\n```\n\n========================================\n\nComments:\n- Do you mind pasting the requirements?\n- @MarceloTrylesinski , I want to return an image using fastapi , is that possible?\n- Does How do I return an image in fastAPI? answer your question?\n- Does this answer your question? How do I return an image in fastAPI?\n- i did install aiofiles, but still getting the same error","metadata":{"transformedAt":"2026-08-18T18:32:29.125Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":12,"totalLines":188,"estimatedTokens":1219}}351{"id":"stack-71194918","source":"stackoverflow","questionId":71194918,"title":"when i use docker-compose to install a fastapi project, i got AssertionError:","tags":["python","python-3.x","docker","fastapi"],"text":"Title: when i use docker-compose to install a fastapi project, i got AssertionError:\nTags: python, python-3.x, docker, fastapi\nSource: Stack Overflow\n\nQuestion:\nwhen I use docker-compose to install a fastapi project, I got `AssertionError: jinja2 must be installed to use Jinja2Templates`\n\nbut when I use env to install it, that will be run well.\n\nmy OS:\n\nUbuntu18.04STL\n\nmy requirements.txt:\n\n```\nfastapi~=0.68.2\nstarlette==0.14.2\npydantic~=1.8.1\n\nuvicorn~=0.12.3\nSQLAlchemy~=1.4.23\n\n# WSGI\nWerkzeug==1.0.1\n\npyjwt~=1.7.0\n\n# async-exit-stack~=1.0.1\n# async-generator~=1.10\n\njinja2~=2.11.2\n\n# assert aiofiles is not None, \"'aiofiles' must be installed to use FileResponse\"\naiofiles~=0.6.0\npython-multipart~=0.0.5\n\nrequests~=2.25.0\npyyaml~=5.3.1\n# html-builder==0.0.6\nloguru~=0.5.3\napscheduler==3.7.0\n\npytest~=6.1.2\nhtml2text==2020.1.16\nmkdocs==1.2.1\n```\n\nDockerfile\n\n```\nFROM python:3.8\nENV PYTHONDONTWRITEBYTECODE 1\nENV PYTHONUNBUFFERED 1\n\nWORKDIR /server\nCOPY requirements.txt /server/\nRUN pip install -r requirements.txt\nCOPY . /server/\n```\n\ndocker-compose.yml\n\n```\nversion: '3.7'\n\nservices:\n figbox_api:\n build:\n context: .\n dockerfile: Dockerfile\n command: uvicorn app.main:app --port 8773 --host 0.0.0.0 --reload\n volumes:\n - .:/server\n ports:\n - 8773:8773\n```\n\nDo I need to provide some other information?\n\nThanks\n\n========================================\n\nTop Answer:\nHave had same issue, using Jinja2 (without version annotation) solved it.\n\n========================================\n\nCode:\n```text\nfastapi~=0.68.2\nstarlette==0.14.2\npydantic~=1.8.1\n\nuvicorn~=0.12.3\nSQLAlchemy~=1.4.23\n\n# WSGI\nWerkzeug==1.0.1\n\npyjwt~=1.7.0\n\n# async-exit-stack~=1.0.1\n# async-generator~=1.10\n\njinja2~=2.11.2\n\n# assert aiofiles is not None, \"'aiofiles' must be installed to use FileResponse\"\naiofiles~=0.6.0\npython-multipart~=0.0.5\n\nrequests~=2.25.0\npyyaml~=5.3.1\n# html-builder==0.0.6\nloguru~=0.5.3\napscheduler==3.7.0\n\npytest~=6.1.2\nhtml2text==2020.1.16\nmkdocs==1.2.1\n```\n\n```text\nFROM python:3.8\nENV PYTHONDONTWRITEBYTECODE 1\nENV PYTHONUNBUFFERED 1\n\nWORKDIR /server\nCOPY requirements.txt /server/\nRUN pip install -r requirements.txt\nCOPY . /server/\n```\n\n```text\nversion: '3.7'\n\nservices:\n figbox_api:\n build:\n context: .\n dockerfile: Dockerfile\n command: uvicorn app.main:app --port 8773 --host 0.0.0.0 --reload\n volumes:\n - .:/server\n ports:\n - 8773:8773\n```\n\n```text\nAssertionError: jinja2 must be installed to use Jinja2Templates\n```\n\n```text\npip install Jinja2==3.1.2\nor \npip install Jinja2 --upgrade\n```\n\n========================================\n\nComments:\n- That seems like it should work. If you `docker-compose run figbox_api pip list`, is `jinja2` listed in the installed packages?\n- I'm seeing the same problem. when I did pip list jinja2 was listed as `Jinja2 2.11.2`\n- should I install another jinja2 version?\n- I had the same problem and resolved when install both latest jinja2 and fastapi. (Not enough to install only latest jinja2.)\n- This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker. - From Review","metadata":{"transformedAt":"2026-08-18T18:32:29.125Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":5,"totalLines":167,"estimatedTokens":797}}352{"id":"stack-74936196","source":"stackoverflow","questionId":74936196,"title":"How should I organize my path operations in FastAPI?","tags":["python","crud","fastapi","endpoint"],"text":"Title: How should I organize my path operations in FastAPI?\nTags: python, crud, fastapi, endpoint\nSource: Stack Overflow\n\nQuestion:\nI am creating an application with FastAPI and so far it goes like this:\n\nhttps://i.sstatic.net/WqEtw.png\n\nBut I'm having a problem with the endpoints. The /api/items/filter route has two query parameters: name and category.\nHowever, it gives me the impression that it is being taken as if it were api/items/{user_id}/filter, since when I do the validation in the documentation it throws me an error saying that I have not passed a value for user_id. (Also, previously it asked me to be authenticated (the only route that needed authentication was api/items/{user_id}.\nThe problems are fixed when I define this endpoint first as shown below:\n\nhttps://i.sstatic.net/NnYaG.png\n\nWhy is this happening? Is there a concept that I am not clear?\n\n========================================\n\nCode:\n```text\napi/items/user_a\n```\n\n```text\napi/items/{user_id}\n```\n\n```text\napi/items/filter\n```\n\n```text\napi/items/{user_id}\n```\n\n```text\nfilter\n```\n\n```text\n{user_id}\n```\n\n```text\n{user_id}\n```\n\n```text\n\"filter\"\n```\n\n========================================\n\nComments:\n- Does this answer your question? How to define multiple API endpoints in FastAPI with different paths but the same path parameter?\n- Related answer can also be found here. On a side note, if you would like to customise the order for the API methods in Swagger UI, please take a look at this answer.\n- Thank you very much for your answer! Could you help me with something else? Currently I have the endpoints as in the second image: api/items/filter -- api/items/{user_id} -- api/items/{name} --. As you can imagine now I have the problem with api/items/{user_id} and api/items/{name} since when I access api/items/{name} actually api/items/{user_id} is being evaluated. Both endpoints have path parameters so there is no point in ordering them. What should I do in those cases? should i change the last endpoint to something like api/items/byname/{name}? Thank you!\n- You have two options: you could use different types if you can, like so: {user_id:int} and {name:str} and make sure the user_id is in front of the name endpoint (in order) because “123” can be evaluated to string but “onetwothree” not to an int. This only works if your user_id is an int though, if both are strings then you must indeed change one of the endpoints to be more unique.\n- Thanks a lot! I have opted for the solution of using different types and it has worked for me!","metadata":{"transformedAt":"2026-08-18T18:32:29.125Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":8,"totalLines":60,"estimatedTokens":634}}353{"id":"stack-66037643","source":"stackoverflow","questionId":66037643,"title":"How to mock a method within an async unit test?","tags":["python","pytest","fastapi","python-3.9"],"text":"Title: How to mock a method within an async unit test?\nTags: python, pytest, fastapi, python-3.9\nSource: Stack Overflow\n\nQuestion:\nI have a class called database.py with a function called generate_token().\nI would like to mock it and return a fixed value `321`. So that I can see that the method was called and the return value returned.\n\nHow do I mock that? This is what I have tried.\n\n```\n@pytest.mark.asyncio\nasync def test_successful_register_returns_device_token(monkeypatch):\n async def mock_generate_token():\n return \"321\"\n\n m = AsyncMock(mock_generate_token)\n m.return_value = \"321\"\n async with AsyncClient(app=app, base_url=\"http://127.0.0.1\") as ac:\n monkeypatch.setattr(database, \"generate_token\", m)\n response = await ac.post(\n \"/register/\",\n headers={},\n json={},\n )\n assert response.status_code == 201\n assert \"device_token\" in response.json()\n assert response.json()[\"device_token\"] == \"321\"\n```\n\n========================================\n\nCode:\n```text\n@pytest.mark.asyncio\nasync def test_successful_register_returns_device_token(monkeypatch):\n async def mock_generate_token():\n return \"321\"\n\n m = AsyncMock(mock_generate_token)\n m.return_value = \"321\"\n async with AsyncClient(app=app, base_url=\"http://127.0.0.1\") as ac:\n monkeypatch.setattr(database, \"generate_token\", m)\n response = await ac.post(\n \"/register/\",\n headers={},\n json={},\n )\n assert response.status_code == 201\n assert \"device_token\" in response.json()\n assert response.json()[\"device_token\"] == \"321\"\n```\n\n```text\n321\n```\n\n```text\n@pytest.mark.asyncio\n@patch(\"service.auth_service.AuthService.generate_token\")\nasync def test_successful_register_returns_device_token(self, mock_token):\n mock_token.return_value = \"321\"\n async with AsyncClient(app=app, base_url=\"http://testserver\") as ac:\n response = await ac.post(\n \"/register/\",\n headers={},\n json={},\n )\n assert response.status_code == 201\n assert \"device_token\" in response.json()\n assert response.json()[\"device_token\"] == \"321\"\n```\n\n```text\nfrom unittest.mock import patch\n```\n\n========================================\n\nComments:\n- Can you provide a minimal reproducible example? The code doesn't contain any errors, but without seeing the error, it's hard to say what's wrong.","metadata":{"transformedAt":"2026-08-18T18:32:29.125Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":81,"estimatedTokens":606}}354{"id":"stack-74289869","source":"stackoverflow","questionId":74289869,"title":"How to unit test a pure ASGI middleware in python","tags":["python","fastapi","middleware","asgi"],"text":"Title: How to unit test a pure ASGI middleware in python\nTags: python, fastapi, middleware, asgi\nSource: Stack Overflow\n\nQuestion:\nI have an ASGI middleware that adds fields to the POST request body before it hits the route in my fastapi app.\n\n```\nfrom starlette.types import ASGIApp, Message, Scope, Receive, Send\n\nclass MyMiddleware:\n \"\"\"\n This middleware implements a raw ASGI middleware instead of a starlette.middleware.base.BaseHTTPMiddleware\n because the BaseHTTPMiddleware does not allow us to modify the request body.\n For documentation see https://www.starlette.io/middleware/#pure-asgi-middleware\n \"\"\"\n def __init__(self, app: ASGIApp):\n self.app = app\n\n async def __call__(self, scope: Scope, receive: Receive, send: Send):\n if scope[\"type\"] != \"http\":\n await self.app(scope, receive, send)\n return \"\"\n\n async def modify_message():\n message: dict = await receive()\n if message.get(\"type\", \"\") != \"http.request\":\n return message\n if not message.get(\"body\", None):\n return message\n body: dict = json.loads(message.get(\"body\", b\"'{}'\").decode(\"utf-8\"))\n body[\"some_field\"] = \"foobar\"\n message[\"body\"] = json.dumps(body).encode(\"utf-8\")\n return message\n\n await self.app(scope, modify_message, send)\n```\n\nIs there an example on how to unit test an ASGI middleware? I would like to test directly the `__call__` part which is difficult as it does not return anything. Do I need to use a test api client (e.g. `TestClient` from fastapi) to then create some dummy endpoint which returns the request as response and thereby check if the middleware was successful or is there a more \"direct\" way?\n\n========================================\n\nCode:\n```text\nfrom starlette.types import ASGIApp, Message, Scope, Receive, Send\n\nclass MyMiddleware:\n \"\"\"\n This middleware implements a raw ASGI middleware instead of a starlette.middleware.base.BaseHTTPMiddleware\n because the BaseHTTPMiddleware does not allow us to modify the request body.\n For documentation see https://www.starlette.io/middleware/#pure-asgi-middleware\n \"\"\"\n def __init__(self, app: ASGIApp):\n self.app = app\n\n async def __call__(self, scope: Scope, receive: Receive, send: Send):\n if scope[\"type\"] != \"http\":\n await self.app(scope, receive, send)\n return \"\"\n\n async def modify_message():\n message: dict = await receive()\n if message.get(\"type\", \"\") != \"http.request\":\n return message\n if not message.get(\"body\", None):\n return message\n body: dict = json.loads(message.get(\"body\", b\"'{}'\").decode(\"utf-8\"))\n body[\"some_field\"] = \"foobar\"\n message[\"body\"] = json.dumps(body).encode(\"utf-8\")\n return message\n\n await self.app(scope, modify_message, send)\n```\n\n```text\n__call__\n```\n\n```text\nTestClient\n```\n\n```text\n# middlewares.py\nimport logging\n\nfrom starlette.types import ASGIApp, Scope, Receive, Send\n\n\nlogger = logging.getLogger(\"app\")\n\n\nclass LogRequestsMiddleware:\n def __init__(self, app: ASGIApp) -> None:\n self.app = app\n\n async def __call__(\n self, scope: Scope, receive: Receive, send: Send\n ) -> None:\n async def send_with_logs(message):\n \"\"\"Log every request info and response status code.\"\"\"\n if message[\"type\"] == \"http.response.start\":\n # request info is stored in the scope\n # status code is stored in the message\n logger.info(\n f'{scope[\"client\"][0]}:{scope[\"client\"][1]} - '\n f'\"{scope[\"method\"]} {scope[\"path\"]} '\n f'{scope[\"scheme\"]}/{scope[\"http_version\"]}\" '\n f'{message[\"status\"]}'\n )\n await send(message)\n\n await self.app(scope, receive, send_with_logs)\n```\n\n```text\n# conftest.py\nimport pytest\n\nfrom fastapi.testclient import TestClient\n\n\n@pytest.fixture\ndef test_client_factory() -> TestClient:\n return TestClient\n```\n\n```text\n# test_middlewares.py\nfrom unittest import mock\nfrom fastapi.testclient import TestClient\nfrom fastapi import FastAPI\nfrom .middlewares import LogRequestsMiddleware\n\n# mock logger call within the pure middleware\n@mock.patch(\"path.to.middlewares.logger.info\")\ndef test_log_requests_middleware(\n mock_logger, test_client_factory: TestClient\n):\n # create a fresh app instance to isolate tested middlewares\n app = FastAPI()\n app.add_middleware(LogRequestsMiddleware)\n \n # create an endpoint to test middlewares\n @app.get(\"/\")\n def homepage():\n return {\"hello\": \"world\"}\n\n # create a client for the app using fixure\n client = test_client_factory(app)\n\n # call an endpoint\n response = client.get(\"/\")\n\n # sanity check\n assert response.status_code == 200\n # check if the logger was called\n mock_logger.assert_called_once()\n```\n\n```text\nfastapi\n```\n\n```text\npytest\n```\n\n```text\nlogger.info()\n```\n\n========================================\n\nComments:\n- One way would be to create a `TestClient`, apply the middleware, send some requests through and assert that `\"some_field\"` is set in the body.\n- @M.O. that's what I ended up doing, and I can live with that\n- You can look at the Starlette's test suite.\n- can we log the request body and response body?","metadata":{"transformedAt":"2026-08-18T18:32:29.125Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":179,"estimatedTokens":1325}}355{"id":"stack-76913406","source":"stackoverflow","questionId":76913406,"title":"How allow FastAPI to handle multiple requests at the same time?","tags":["python","asynchronous","fastapi"],"text":"Title: How allow FastAPI to handle multiple requests at the same time?\nTags: python, asynchronous, fastapi\nSource: Stack Overflow\n\nQuestion:\nFor some reason FastAPI doesn't respond to any requests while a request is handled. I would expect FastAPI to be able to handle multiple requests at the same time. I would like to allow multiple calls at the same time as multiple users might be accessing the REST API.\n\n### Minimal Example: Asynchronous Processes\n\nAfter starting the server: `uvicorn minimal:app --reload`, running the request_test `run request_test` and executing `test()`, I get as expected `{'message': 'Done'}`. However, when I execute it again within the 20 second frame of the first request, the request is not being processed until the `sleep_async` from the first call is finished.\n\n### Without asynchronous Processes\n\nThe same problem (that I describe below) exists even if I don't use asynchronous calls and wait directly within async def info. That doesn't make sense to me.\n\n### FastAPI: minimal\n\n```\n#!/usr/bin/env python3\nfrom fastapi import FastAPI\nfrom fastapi.responses import JSONResponse\nimport time\nimport asyncio\n\napp = FastAPI()\n\n@app.get(\"/test/info/\")\nasync def info():\n async def sleep_async():\n time.sleep(20)\n print(\"Task completed!\")\n asyncio.create_task(sleep_async())\n return JSONResponse(content={\"message\": \"Done\"})\n```\n\n### Test: request_test\n\n```\n#!/usr/bin/env python3\n\nimport requests\n\ndef test():\n print(\"Before\")\n response = requests.get(f\"http://localhost:8000/test/info\")\n print(\"After\")\n response_data = response.json()\n print(response_data)\n```\n\n========================================\n\nTop Answer:\nIt is because while you have indeed written an async function, the time.sleep() method called inside that is not asynchronous. Async functions shouldn't have methods that block the thread inside them. You can fix this by simply modifying the code to use `asyncio.sleep()` instead:\n\n```\n#!/usr/bin/env python3\nfrom fastapi import FastAPI\nfrom fastapi.responses import JSONResponse\nimport time\nimport asyncio\n\napp = FastAPI()\n\n@app.get(\"/test/info/\")\nasync def info():\n async def sleep_async():\n await asyncio.sleep(20)\n print(\"Task completed!\")\n asyncio.create_task(sleep_async())\n return JSONResponse(content={\"message\": \"Done\"})\n```\n\nAs you can see below, the requests are getting processed concurrently;\nhttps://i.sstatic.net/kIw5k.png\n\n========================================\n\nCode:\n```py\n#!/usr/bin/env python3\nfrom fastapi import FastAPI\nfrom fastapi.responses import JSONResponse\nimport time\nimport asyncio\n\napp = FastAPI()\n\n@app.get(\"/test/info/\")\nasync def info():\n async def sleep_async():\n time.sleep(20)\n print(\"Task completed!\")\n asyncio.create_task(sleep_async())\n return JSONResponse(content={\"message\": \"Done\"})\n```\n\n```py\n#!/usr/bin/env python3\n\nimport requests\n\ndef test():\n print(\"Before\")\n response = requests.get(f\"http://localhost:8000/test/info\")\n print(\"After\")\n response_data = response.json()\n print(response_data)\n```\n\n```text\nuvicorn minimal:app --reload\n```\n\n```text\nrun request_test\n```\n\n```text\ntest()\n```\n\n```text\n{'message': 'Done'}\n```\n\n```text\nsleep_async\n```\n\n```text\n--workers <int>\n```\n\n```py\n#!/usr/bin/env python3\nfrom fastapi import FastAPI\nfrom fastapi.responses import JSONResponse\nimport time\nimport asyncio\n\napp = FastAPI()\n\n@app.get(\"/test/info/\")\nasync def info():\n async def sleep_async():\n await asyncio.sleep(20)\n print(\"Task completed!\")\n asyncio.create_task(sleep_async())\n return JSONResponse(content={\"message\": \"Done\"})\n```\n\n```text\nasyncio.sleep()\n```\n\n========================================\n\nComments:\n- `async` does not mean parallel. It means \"give up time for other things to run while I'm waiting for something\" - if you never give up time, nothing else can run in the same time. You can make starlette/fastapi use threading instead by dropping the `async` part of your function definition.\n- Yes, it does. I read that before, but was missing the information that async doesn't mean parallel. Thank you.\n- It does not help with multiple requests to be run at the same time.\n- How? This allows multiple workers to receive multiple requests in parallel. Can you give more details about your issue\n- I tried it with uvicorn ... --workers with different ns. As much As, I observed there was not any parallel task, and all tasks were excecated sequentially.\n- I am of course using a different time consuming program during that time instead of `sleep`.\n- In that case you should add the actual method you are using because it's not worthwhile to anyone otherwise. What I currently added makes sense in the scenario you've provided.\n- In general, no matter what CPU-bounded (time consuming in your word) operation you have in the code. You need to make sure it is executed in a different thread other than the main thread. The asyncio.create_task method create task which will run later, but still within the main thread, therefore blocks subsequent requests.","metadata":{"transformedAt":"2026-08-18T18:32:29.125Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":10,"totalLines":167,"estimatedTokens":1257}}356{"id":"stack-70207122","source":"stackoverflow","questionId":70207122,"title":"FastAPI: Some requests are failing due to 10s timeout","tags":["python","rest","fastapi","starlette"],"text":"Title: FastAPI: Some requests are failing due to 10s timeout\nTags: python, rest, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nWe have deployed a model prediction service in production that is using FastAPI and unfortunately, some of the requests are failing due to a 10s timeout. In terms of concurrent requests, we typically only load about 2/3 requests per second, so I wouldn't think that would be too much strain on FastAPI. The first thing we tried to do is isolate the FastAPI framework from the model itself, and when we performed some tracing, we noticed that a lot of time (6 seconds) was spent on this segment: `starlette.exceptions:ExceptionMiddleware.__call__`.\n\nThe gunicorn configuration we are using didn't seem to help either:\n\n```\n\"\"\"gunicorn server configuration.\"\"\"\nimport os\n\nthreads = 2\nworkers = 4\ntimeout = 60\nkeepalive = 1800\ngraceful_timeout = 1800\nbind = f\":{os.environ.get('PORT', '80')}\"\nworker_class = \"uvicorn.workers.UvicornWorker\"\n```\n\nWould really appreciate some guidance on what the above segment implies and what is causing timeout issues for some requests under a not too strenuous load.\n\nhttps://i.sstatic.net/CLRPU.png\n\nhttps://i.sstatic.net/LNk1P.png\n\n========================================\n\nCode:\n```text\n\"\"\"gunicorn server configuration.\"\"\"\nimport os\n\nthreads = 2\nworkers = 4\ntimeout = 60\nkeepalive = 1800\ngraceful_timeout = 1800\nbind = f\":{os.environ.get('PORT', '80')}\"\nworker_class = \"uvicorn.workers.UvicornWorker\"\n```\n\n```text\nstarlette.exceptions:ExceptionMiddleware.__call__\n```\n\n========================================\n\nComments:\n- Hi Riley, I'm facing the same issue now and wondering if you had this issue solved? Thanks in advance\n- Hello Leo, it only becomes an issue when using large NLP models. We solved the issue by using GPU instead of CPU. Additionally, as indicated below, celery and redis is meant for these types of tasks with long runtimes\n- Thanks for response, glad to hear it solved by switching to GPU, just wondering what really is `starlette.exceptions:ExceptionMiddleware.__call__` doing, is that actually a wrapper of the application code?\n- This is super helpful - thank you! What is `starlette.exceptions:ExceptionMiddleware.__call__` though? That is also taking 6 seconds. Looks like an application-level issue.\n- @Riley From the starlette doc => starlette.io/middleware: ExceptionMiddleware - Adds exception handlers, so that particular types of expected exception cases can be associated with handler functions. For example raising HTTPException(status_code=404) within an endpoint will end up rendering a custom 404 page.","metadata":{"transformedAt":"2026-08-18T18:32:29.125Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":2,"totalLines":56,"estimatedTokens":653}}357{"id":"stack-60760649","source":"stackoverflow","questionId":60760649,"title":"What is the best way to handle conditionally required arguments in a FastAPI app?","tags":["python","rest","web-development-server","fastapi","pydantic"],"text":"Title: What is the best way to handle conditionally required arguments in a FastAPI app?\nTags: python, rest, web-development-server, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI am developing a FastAPI application. I have with the following schema\n\n```\nclass Address(BaseModel):\n address_string: str = Field(None)\n address_street: str = Field(None)\n addres_number: str = Field(None)\n```\n\nI like to have the field address_string conditionally required if address_street and addres_number are not present, and vice-versa, address_street and address_number are required if address_street is not present.\n\nCurrently I manage this by making all fields optional and using a root_validator to check the consistency, and documenting this conditional requirement in the description of the involved fields.\n\nIs there a cleaner way to manage this built-in on FastAPI?\n\n========================================\n\nCode:\n```text\nclass Address(BaseModel):\n address_string: str = Field(None)\n address_street: str = Field(None)\n addres_number: str = Field(None)\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.125Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":1,"totalLines":29,"estimatedTokens":267}}358{"id":"stack-61333907","source":"stackoverflow","questionId":61333907,"title":"Receiving an image with Fast API, processing it with cv2 then returning it","tags":["python","opencv","fastapi"],"text":"Title: Receiving an image with Fast API, processing it with cv2 then returning it\nTags: python, opencv, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to build an API which receives an image and does some basic processing on it, then returns an updated copy of it using Open CV and Fast API. So far, I have the receiver working just fine, but when I try to base64 encode the processed image and send it back my mobile front end times out. \n\nAs a debugging practice I've tried just printing the encoded string and making the API call using Insomnia, but after 5 solid minutes of printing data I killed the application. Is returning a base64 encoded string the right move here? Is there an easier way to send an Open CV image via Fast API? \n\n```\nclass Analyzer(BaseModel):\n filename: str\n img_dimensions: str\n encoded_img: str\n\n@app.post(\"/analyze\", response_model=Analyzer)\nasync def analyze_route(file: UploadFile = File(...)):\n contents = await file.read()\n nparr = np.fromstring(contents, np.uint8)\n img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)\n\n img_dimensions = str(img.shape)\n return_img = processImage(img)\n\n encoded_img = base64.b64encode(return_img)\n\n return{\n 'filename': file.filename,\n 'dimensions': img_dimensions,\n 'encoded_img': endcoded_img,\n }\n```\n\n========================================\n\nCode:\n```text\nclass Analyzer(BaseModel):\n filename: str\n img_dimensions: str\n encoded_img: str\n\n@app.post(\"/analyze\", response_model=Analyzer)\nasync def analyze_route(file: UploadFile = File(...)):\n contents = await file.read()\n nparr = np.fromstring(contents, np.uint8)\n img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)\n\n img_dimensions = str(img.shape)\n return_img = processImage(img)\n\n encoded_img = base64.b64encode(return_img)\n\n return{\n 'filename': file.filename,\n 'dimensions': img_dimensions,\n 'encoded_img': endcoded_img,\n }\n```\n\n```text\nclass Analyzer(BaseModel):\n filename: str\n img_dimensions: str\n encoded_img: str\n\n@app.post(\"/analyze\", response_model=Analyzer)\nasync def analyze_route(file: UploadFile = File(...)):\n contents = await file.read()\n nparr = np.fromstring(contents, np.uint8)\n img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)\n\n img_dimensions = str(img.shape)\n return_img = processImage(img)\n\n # line that fixed it\n _, encoded_img = cv2.imencode('.PNG', return_img)\n\n encoded_img = base64.b64encode(encoded_img)\n\n return{\n 'filename': file.filename,\n 'dimensions': img_dimensions,\n 'encoded_img': endcoded_img,\n }\n```\n\n========================================\n\nComments:\n- Are you encoding the image to either `.png` or `.jpg` compression format in your `processImage` method ?\n- You can send other types of response in fastapi maybe a StreamingResponse or File Response might be more suitable? Have a look at fastapi.tiangolo.com/advanced/custom-response\n- @ZdaR Basically my API takes base64 gif as input and It is a gif basw64 string.\n- @user368604 I have tried with other responses bit didn't work. The main problem is input my input base64 string is too big.","metadata":{"transformedAt":"2026-08-18T18:32:29.125Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":2,"totalLines":94,"estimatedTokens":777}}359{"id":"stack-72217828","source":"stackoverflow","questionId":72217828,"title":"How to get the raw URL path from request in FastAPI?","tags":["python","url-routing","fastapi","starlette"],"text":"Title: How to get the raw URL path from request in FastAPI?\nTags: python, url-routing, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nI have a `GET` method with requested parameter in path:\n\n```\n@router.get('/users/{user_id}')\nasync def get_user_from_string(user_id: str):\n return User(user_id)\n```\n\nIs it possible to get base url raw path (i.e., `'/users/{user_id}'`) from the request?\n\nI have tried to use the following way:\n\n```\npath = [route for route in request.scope['router'].routes if\n route.endpoint == request.scope['endpoint']][0].path\n```\n\nBut it doesn't work and I get:\n\nAttributeError: 'Mount' object has no attribute 'endpoint'\n\n========================================\n\nTop Answer:\n### Update\n\nIf what you need is the original route path defined in the endpoint's decorator, i.e., `/users/{user_id}`, you could then use the example below. The way it works is by getting the `root_path` first—which would normally be an empty string, unless you have mounted sub-application(s) to the top-level app (e.g., `app.mount(\"/subapi\", subapi)`), and hence, you would need the result to be prefixed with that specific path `/subapi`—and then append to it the route's path , which you could get from the APIRoute object. Example:\n\n```\nfrom fastapi import Request\n \n@app.get('/users/{user_id}')\ndef get_user(user_id: str, request: Request):\n path = request.scope['root_path'] + request.scope['route'].path\n return path\n```\n\n**Output**:\n\n```\n/users/{user_id}\n```\n\n### Original answer\n\nAs per FastAPI documentation:\n\nAs FastAPI is actually Starlette underneath, with a layer of several\ntools on top, you can use Starlette's `Request` object directly when you\nneed to.\n\nThus, you can use `Request` object to get the URL path. For instance:\n\n```\nfrom fastapi import Request\n\n@app.get('/users/{user_id}')\ndef get_user(user_id: str, request: Request):\n return request.url.path\n```\n\n**Output** (if the received `user_id` was `1`):\n\n```\n/users/1\n```\n\n========================================\n\nCode:\n```text\n@router.get('/users/{user_id}')\nasync def get_user_from_string(user_id: str):\n return User(user_id)\n```\n\n```text\npath = [route for route in request.scope['router'].routes if\n route.endpoint == request.scope['endpoint']][0].path\n```\n\n```text\nGET\n```\n\n```text\n'/users/{user_id}'\n```\n\n```text\nraw_path = request.scope['route'].path \n#'/user/{id}'\n```\n\n```py\nfrom fastapi import Request\n \n@app.get('/users/{user_id}')\ndef get_user(user_id: str, request: Request):\n path = request.scope['root_path'] + request.scope['route'].path\n return path\n```\n\n```text\n/users/{user_id}\n```\n\n```py\nfrom fastapi import Request\n\n@app.get('/users/{user_id}')\ndef get_user(user_id: str, request: Request):\n return request.url.path\n```\n\n```text\n/users/1\n```\n\n```text\n/users/{user_id}\n```\n\n```text\nroot_path\n```\n\n```text\napp.mount(\"/subapi\", subapi)\n```\n\n```text\n/subapi\n```\n\n```text\nRequest\n```\n\n```text\nRequest\n```\n\n```text\nuser_id\n```\n\n```text\n1\n```\n\n```text\npath = request.url.path\nfor key, val in request.path_params.items():\n path = path.replace(val, F'{{{key}}}')\n```\n\n```text\ndef get_route_from_request(req: Request):\n root_path = req.scope.get(\"root_path\", \"\")\n\n route = scope.get(\"route\")\n if not route:\n return None\n path_format = getattr(route, \"path_format\", None)\n if path_format:\n return f\"{root_path}{path_format}\"\n\n return None\n```\n\n```py\ndef get_raw_path(request):\n path = request.url.path\n for key, val in request.path_params.items():\n path = path.replace(val, F'{{{key}}}',1)\n return path\n```\n\n```text\ncount\n```\n\n```text\nrequest.path_params\n```\n\n========================================\n\nComments:\n- github.com/tiangolo/fastapi/issues/828\n- The question was, to get the raw path, that would be in the format of {user_id} for the path parameters\n- For reference: `scope[\"route\"]` was added in FastAPI 0.74.1 (fastapi.tiangolo.com/release-notes/?h=route#0741)\n- in the above example, what's the purpose of setting the `root_path` variable?\n- @therightstuff I just edited the answer to use root_path in the result, code there now worked for me","metadata":{"transformedAt":"2026-08-18T18:32:29.125Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":22,"totalLines":200,"estimatedTokens":1025}}360{"id":"stack-67619287","source":"stackoverflow","questionId":67619287,"title":"How do I consume query parameters from POST in FastAPI?","tags":["python","fastapi"],"text":"Title: How do I consume query parameters from POST in FastAPI?\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI want to write a route in FastAPI to consume a POST request. I have the following URL example:\n\n```\nhttps://URL.com/api/FlexfoneCall/outgoing?AccountId=1234&TimeStamp=2021-05-20+08%3a30%3a56&UniqueCallId=SIP%2f%2b4512345678-0000e4a81463430317&EmployeeLocalNumber=200&ANumber=12345678&BNumber=87654321&PhoneLocalNumber=123456\n```\n\nHowever, I'm only used to consuming the body from request. How do I \"fetch\" the path parameter data from the above example?\n\nEDIT:\n\nI'm trying to write a service that receives the above URL from an external service. I tried doing the following because I thougth that since it was a POST my route should look like this:\n\n```\n@app.post('/callout', response_model=CallIn)\nasync def create_call_out(callout: CallOut, db: Session = Depends(get_db)):\n db_write_call_out = write_call_out(db, callout)\n\n return db_write_call_out\n```\n\nWith the following Pydantic model:\n\n```\nclass CallOut(BaseModel):\n accountid: str = None\n timestamp: str = None\n uniquecallid: str = None\n employeelocalnumber: str = None\n anumber: str = None\n bnumber: str = None\n phonelocalnumber: str = None\n\n class Config:\n orm_mode = True\n```\n\nAnd CRUD function:\n\n```\ndef write_call_out(db: Session, callout: CallOut):\n db_write_call_out = DBCallOut(**callout.dict())\n db.add(db_write_call_out)\n db.commit()\n db.refresh(db_write_call_out)\n\n return db_write_call_out\n```\n\nSQLAlchemy ORM model for writing the query params to a SQL DB:\n\n```\nclass DBCallOut(Base):\n __tablename__ = \"call_out\"\n\n accountid = Column('AccountId', String(250))\n uniquecallid = Column('UniqueCallId', String(250))\n employeelocalnumber = Column('EmployeeLocalNumber', String(250))\n anumber = Column('ANumber', String(250))\n timestamp = Column('TimeStamp', String(250))\n phonelocalnumber = Column('PhoneLocalNumber', String(250))\n bnumber = Column('BNumber', String(250))\n ID = Column(Integer, primary_key=True, index=True, autoincrement=True)\n```\n\nBut I keep getting a 422 Error.\n\nEDIT 2:\n\nEnded up changing my route to the following:\n\n```\n@app.get('/call')\nasync def outgoing(AccountId: str,\n TimeStamp: str,\n UniqueCallId: str,\n EmployeeLocalNumber: str,\n ANumber: str,\n BNumber: str,\n PhoneLocalNumber: str, db: Session = Depends(get_db)):\n callout = {\"AccountId\": AccountId,\n \"TimeStamp\": TimeStamp,\n \"UniqueCallId\": UniqueCallId,\n \"EmployeeLocalNumber\": EmployeeLocalNumber,\n \"ANumber\": ANumber,\n \"BNumber\": BNumber,\n \"PhoneLocalNumber\": PhoneLocalNumber}\n db_write_call_out = write_call_out(db, callout)\n\n return db_write_call_out\n```\n\nThis is working, but it's somewhat clunky.\n\n========================================\n\nCode:\n```text\nhttps://URL.com/api/FlexfoneCall/outgoing?AccountId=1234&TimeStamp=2021-05-20+08%3a30%3a56&UniqueCallId=SIP%2f%2b4512345678-0000e4a81463430317&EmployeeLocalNumber=200&ANumber=12345678&BNumber=87654321&PhoneLocalNumber=123456\n```\n\n```text\n@app.post('/callout', response_model=CallIn)\nasync def create_call_out(callout: CallOut, db: Session = Depends(get_db)):\n db_write_call_out = write_call_out(db, callout)\n\n return db_write_call_out\n```\n\n```text\nclass CallOut(BaseModel):\n accountid: str = None\n timestamp: str = None\n uniquecallid: str = None\n employeelocalnumber: str = None\n anumber: str = None\n bnumber: str = None\n phonelocalnumber: str = None\n\n class Config:\n orm_mode = True\n```\n\n```text\ndef write_call_out(db: Session, callout: CallOut):\n db_write_call_out = DBCallOut(**callout.dict())\n db.add(db_write_call_out)\n db.commit()\n db.refresh(db_write_call_out)\n\n return db_write_call_out\n```\n\n```text\nclass DBCallOut(Base):\n __tablename__ = \"call_out\"\n\n accountid = Column('AccountId', String(250))\n uniquecallid = Column('UniqueCallId', String(250))\n employeelocalnumber = Column('EmployeeLocalNumber', String(250))\n anumber = Column('ANumber', String(250))\n timestamp = Column('TimeStamp', String(250))\n phonelocalnumber = Column('PhoneLocalNumber', String(250))\n bnumber = Column('BNumber', String(250))\n ID = Column(Integer, primary_key=True, index=True, autoincrement=True)\n```\n\n```text\n@app.get('/call')\nasync def outgoing(AccountId: str,\n TimeStamp: str,\n UniqueCallId: str,\n EmployeeLocalNumber: str,\n ANumber: str,\n BNumber: str,\n PhoneLocalNumber: str, db: Session = Depends(get_db)):\n callout = {\"AccountId\": AccountId,\n \"TimeStamp\": TimeStamp,\n \"UniqueCallId\": UniqueCallId,\n \"EmployeeLocalNumber\": EmployeeLocalNumber,\n \"ANumber\": ANumber,\n \"BNumber\": BNumber,\n \"PhoneLocalNumber\": PhoneLocalNumber}\n db_write_call_out = write_call_out(db, callout)\n\n return db_write_call_out\n```\n\n```text\n@app.post(\"outgoing/\")\nasync def do_something(\n AccountId: int, \n TimeStamp: str, \n UniqueCallId: str, \n EmployeeLocalNumber: str,\n ANumber: int,\n BNumber: int,\n PhoneLocalNumber: int\n ):\n # do some stuff\n save_to_db(owner=AccountId,time=TimeStamp,contact=PhoneLocalNumber)\n```\n\n```text\n@app.post(\"video/{video_id}\")\nasync def do_something(video_id):\n # do something\n save_to_db(video_id)\n```\n\n```text\ngoogle.co/youtube/videos/1\n```\n\n```text\ngoogle.co?video=1\n```\n\n```text\n@app(params)\n```\n\n```text\ndef get_video(params)\n```\n\n========================================\n\nComments:\n- fastapi.tiangolo.com/tutorial/query-params ?\n- unsure of what ? What have you tried ? The code in the documentaion is pretty easy\n- your actual code that handles `/api/FlexfoneCall/outgoing` please\n- I haven't written anything, because I'm rather confused about the type of route I need to use, and why the example is sending parameters in the URL directly.\n- For the example with `video_id` you miss the method parameters, it's SAME as query param, see fastapi.tiangolo.com/tutorial/query-params/…\n- What does you request body look like @Artem? it seems you are either missing a variable or misspelling one in your POST request. if accountid is the DB key I suggest you make it an optional variable in a supper class `Callout(BaseModel)`, then inherit from it in `CallOutPost(CallOut)` where the rest of the mandatory variables sit\n- @azro I intentionally left them out to avoid confusion. I made an example the *ONLY* uses path parameters so the distinction can be clear and nonconfusing\n- Made all variables optional in the BaseModel. Still keep getting a 422.\n- @ItIsEntropy If I replace the BaseModel in `create_call_out()` with the query params, the request goes through. Is the BaseModel/Pydantic model case sensitive or anything?\n- Yes it is. Pydantic uses JSON which is case sensitive. do you post anything in the request body? if you don't then that's your problem. you are posting information in the query params, but the `callout: CallOut` part is telling fastAPI to look for content in the request body; content which does not exist. Edit: HTTP: 422 means that your request is valid, but semantically makes no sense, so in this case everything about your request was right, but you were asking it to parse an empty JSON request\n- @Artem if this answer helped you out please accept it and give an upcote. Thanks\n- @ItIsEntropy So yes, the request body is empty for some reason. I've updated the question with the new route that works. I think it's somewhat clunky though. Pydantic is only for the body, when I guess? Essentially, if the URL had 20 query parameters, would I then have to declare all 20 in the function?\n- Yes you would have to declare all 20 params cos that's the only way to consume them. and yes Pydantic is only for the body. if you are sending JSON objects to the route use it, otherwise use query or form parameters and it's not needed, also no need to make models off of its `BaseModel` class.\n- to use the old one simply send a JSON object to the endpoint as it was.. i find using Postman to test my requests very useful, but if you're on javascript it has a builtin JSON object so make the model, then post it with JSON stringify, thn you'll have cleaner code","metadata":{"transformedAt":"2026-08-18T18:32:29.125Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":12,"totalLines":227,"estimatedTokens":2068}}361{"id":"stack-67629028","source":"stackoverflow","questionId":67629028,"title":"FastAPI authentication injection","tags":["python","authentication","fastapi"],"text":"Title: FastAPI authentication injection\nTags: python, authentication, fastapi\nSource: Stack Overflow\n\nQuestion:\nMy application has an `AuthenticateService` implemented as follows:\n\n```\nfrom domain.ports.repositories import ISalesmanRepository\nfrom fastapi import HTTPException, status\nfrom fastapi_jwt_auth import AuthJWT\nfrom fastapi_jwt_auth.exceptions import JWTDecodeError\nfrom shared.exceptions import EntityNotFound\nfrom adapters.api.authentication.config import User\n\nclass AuthenticateService:\n def __init__(self, user_repo: ISalesmanRepository):\n self._repo = user_repo\n\n def __call__(self, auth: AuthJWT) -> User:\n credentials_exception = HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Could not validate credentials\",\n headers={\"WWW-Authenticate\": \"Bearer\"},\n )\n try:\n auth.jwt_required()\n user_id = auth.get_jwt_subject()\n except JWTDecodeError:\n raise credentials_exception\n\n try:\n user = self._repo.get_by_id(user_id)\n return user\n except EntityNotFound:\n raise credentials_exception\n```\n\nSo the behavior is basically:\n\n- Is jwt is valid, get user from repository and returns\n\n- Raise 401 if jwt is invalid\n\nThe problem is that in every controller implemented I have to repeat the process. I tried to implement a decorator that injects the user into the controller in case of success but I couldn't. I'm sure that the best way to implement this is to use fastAPI's `Depends` dependency injector.\nToday, a controller looks something like this:\n\n```\nfrom typing import Optional\n\nfrom adapters.api.services import authenticate_service, create_sale_service\nfrom fastapi import APIRouter, Depends\nfrom fastapi_jwt_auth import AuthJWT\nfrom pydantic import BaseModel\n\nrouter = APIRouter()\n\nclass Request(BaseModel):\n code: str\n value: float\n date: str\n status: Optional[str] = None\n\n@router.post('/sale')\ndef create_sale(request: Request, auth: AuthJWT = Depends()):\n user = authenticate_service(auth)\n result = create_sale_service.handle(\n {\"salesman\": user, \"sale\": request.dict()}\n )\n return result.dict()\n```\n\nHow can I abstract my authentication so that my controllers look like any of the versions below:\n\n```\n# Option 1: decorator\n\n@router.post('/sale')\n@authentication_required\ndef create_sale(request: Request, user: User): # User is the `__call__` response from `AuthenticateService` class\n result = create_sale_service.handle(\n {\"salesman\": user, \"sale\": request.dict()}\n )\n return result.dict()\n\n# Option 2:\n@router.post('/sale')\ndef create_sale(request: Request, user: User = Depends(authenticate_service)): # Something like that, using the depends to inject User to me\n result = create_sale_service.handle(\n {\"salesman\": user, \"sale\": request.dict()}\n )\n return result.dict()\n```\n\n========================================\n\nCode:\n```py\nfrom domain.ports.repositories import ISalesmanRepository\nfrom fastapi import HTTPException, status\nfrom fastapi_jwt_auth import AuthJWT\nfrom fastapi_jwt_auth.exceptions import JWTDecodeError\nfrom shared.exceptions import EntityNotFound\nfrom adapters.api.authentication.config import User\n\n\nclass AuthenticateService:\n def __init__(self, user_repo: ISalesmanRepository):\n self._repo = user_repo\n\n def __call__(self, auth: AuthJWT) -> User:\n credentials_exception = HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Could not validate credentials\",\n headers={\"WWW-Authenticate\": \"Bearer\"},\n )\n try:\n auth.jwt_required()\n user_id = auth.get_jwt_subject()\n except JWTDecodeError:\n raise credentials_exception\n\n try:\n user = self._repo.get_by_id(user_id)\n return user\n except EntityNotFound:\n raise credentials_exception\n```\n\n```py\nfrom typing import Optional\n\nfrom adapters.api.services import authenticate_service, create_sale_service\nfrom fastapi import APIRouter, Depends\nfrom fastapi_jwt_auth import AuthJWT\nfrom pydantic import BaseModel\n\nrouter = APIRouter()\n\n\nclass Request(BaseModel):\n code: str\n value: float\n date: str\n status: Optional[str] = None\n\n\n@router.post('/sale')\ndef create_sale(request: Request, auth: AuthJWT = Depends()):\n user = authenticate_service(auth)\n result = create_sale_service.handle(\n {\"salesman\": user, \"sale\": request.dict()}\n )\n return result.dict()\n```\n\n```py\n# Option 1: decorator\n\n@router.post('/sale')\n@authentication_required\ndef create_sale(request: Request, user: User): # User is the `__call__` response from `AuthenticateService` class\n result = create_sale_service.handle(\n {\"salesman\": user, \"sale\": request.dict()}\n )\n return result.dict()\n\n\n# Option 2:\n@router.post('/sale')\ndef create_sale(request: Request, user: User = Depends(authenticate_service)): # Something like that, using the depends to inject User to me\n result = create_sale_service.handle(\n {\"salesman\": user, \"sale\": request.dict()}\n )\n return result.dict()\n```\n\n```text\nAuthenticateService\n```\n\n```text\nDepends\n```\n\n```py\n# > AuthService class\n\nclass AuthenticateService:\n def __init__(self, user_repo: ISalesmanRepository):\n self._repo = user_repo\n\n def __call__(self, auth: AuthJWT = Depends()) -> User:\n ...\n\nauthenticate_service = AuthenticateService(user_repository)\n```\n\n```py\n# > Controller\n\n@router.post('/sale')\ndef create_sale(request: Request, user: User = Depends(authenticate_service)):\n result = create_sale_service.handle(\n {\"salesman\": user, \"sale\": request.dict()}\n )\n return result.dict()\n```\n\n```text\nDepends\n```\n\n========================================\n\nComments:\n- You can also add it to your `router` as a dependency for all routes, that way you won't suddenly make an endpoint unauthenticated because you forgot to add the `user` parameter. You can then have one `APIRouter` for unauthenticated calls and one for authenticated calls if you need some endpoints to be unauthenticated.\n- An \"AuthenticatedRouter\" is a great idea. I will read more about Router in the FastAPI documentation and probably implement it that way. As soon as I do I update my answer here with the router approach.\n- We have two APIRouters in our main app.py, which we then add our subrouters (from the different views) to - one for unauthenticated and one for authenticated routes. It works perfectly fine and gives good readability; you can easily see in both the views and the app router setup what the security context for the routes are.","metadata":{"transformedAt":"2026-08-18T18:32:29.126Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":8,"totalLines":219,"estimatedTokens":1624}}362{"id":"stack-71984078","source":"stackoverflow","questionId":71984078,"title":"FastAPI application as an AWS lambda function URL gets stuck in eternal redirect loop","tags":["fastapi"],"text":"Title: FastAPI application as an AWS lambda function URL gets stuck in eternal redirect loop\nTags: fastapi\nSource: Stack Overflow\n\nQuestion:\nI have a FastAPI app that I use as an AWS Lambda function. It is configured so that its URL is directly callable (using the recent AWS function URL functionality).\n\nFastAPI functions that are set directly with the app (eg `@app.get(\"/\")`) work fine, but calling endpoints that are loaded in via `app.include_router()` are stuck in an endless 307 loop.\n\nThe app layout is (simplified):\n\n```\n+ app\n|-- main.py\n|-- routers\n|---- ingest.py\n```\n\n`main.py` contents (simplified):\n\n```\napp = FastAPI()\napp.include_router(ingest.router)\n\n@app.get(\"/\", response_class=HTMLResponse)\nasync def home(request: Request):\n return templates.TemplateResponse(\"home.html\", {\"request\": request})\n\n@app.get(\"/login\", response_class=HTMLResponse)\nasync def home(request: Request):\n return templates.TemplateResponse(\"login.html\", {\"request\": request})\n\nhandler = Mangum(app)\n```\n\n`ingest.py` contents (simplified):\n\n```\n...\nrouter = APIRouter(prefix=\"/ingest\")\n@router.post(\"/\")\nasync def ingest(meal: str):\n ...\n```\n\nIt seems this has something to do with appending slashes, but the strange thing is that I don't get a 307 redirect when I do any of these:\n\n```\nGET https://xxxxxxxxxxxx.lambda-url.eu-west-1.on.aws/\nGET https://xxxxxxxxxxxx.lambda-url.eu-west-1.on.aws/login (while the call gets stuck in a 307 redirect loop when I do any of these:\n\n```\nGET https://xxxxxxxxxxxx.lambda-url.eu-west-1.on.aws/ingest (I don't have this issue locally, nor when I deploy the app to a local docker container.\n\nWhat could be causing this behaviour?\n\n========================================\n\nCode:\n```text\n+ app\n|-- main.py\n|-- routers\n|---- ingest.py\n```\n\n```py\napp = FastAPI()\napp.include_router(ingest.router)\n\n@app.get(\"/\", response_class=HTMLResponse)\nasync def home(request: Request):\n return templates.TemplateResponse(\"home.html\", {\"request\": request})\n\n@app.get(\"/login\", response_class=HTMLResponse)\nasync def home(request: Request):\n return templates.TemplateResponse(\"login.html\", {\"request\": request})\n\nhandler = Mangum(app)\n```\n\n```py\n...\nrouter = APIRouter(prefix=\"/ingest\")\n@router.post(\"/\")\nasync def ingest(meal: str):\n ...\n```\n\n```text\nGET https://xxxxxxxxxxxx.lambda-url.eu-west-1.on.aws/\nGET https://xxxxxxxxxxxx.lambda-url.eu-west-1.on.aws/login (<- missing slash)\nGET https://xxxxxxxxxxxx.lambda-url.eu-west-1.on.aws/login/ (<- note the slash)\n```\n\n```text\nGET https://xxxxxxxxxxxx.lambda-url.eu-west-1.on.aws/ingest (<- missing slash)\nGET https://xxxxxxxxxxxx.lambda-url.eu-west-1.on.aws/ingest/ (<- note the slash)\nPOST https://xxxxxxxxxxxx.lambda-url.eu-west-1.on.aws/ingest (<- missing slash)\nPOST https://xxxxxxxxxxxx.lambda-url.eu-west-1.on.aws/ingest/ (<- note the slash)\n```\n\n```text\n@app.get(\"/\")\n```\n\n```text\napp.include_router()\n```\n\n```text\nmain.py\n```\n\n```text\ningest.py\n```\n\n```text\nrouter = APIRouter(prefix=\"/ingest\")\n@router.post(\"/\")\n@router.post(\"\")\nasync def ingest(meal: str):\n...\n```\n\n```text\ningest.py\n```\n\n========================================\n\nComments:\n- I had the same problem and can confirm that removing the trailing `/` on my endpoint route did fix the issue. I had `@router.get(\"/\")` and changed it to `@router.get(\"\")` to make it work.","metadata":{"transformedAt":"2026-08-18T18:32:29.126Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":11,"totalLines":134,"estimatedTokens":833}}363{"id":"stack-65130770","source":"stackoverflow","questionId":65130770,"title":"How to handle large amount of json data response payload in fastapi?","tags":["node.js","json","get","fastapi"],"text":"Title: How to handle large amount of json data response payload in fastapi?\nTags: node.js, json, get, fastapi\nSource: Stack Overflow\n\nQuestion:\na get call which has many lines of json respone gets some time to respond in swagger ui.\n\nhow can reduce this time ; but, i want each response attrebute from my big responds model!.\n\ni have tried `gzip` content encoading. but, it does not solved my problem; because of the large number of line response;\n\nfor eg: while getting all job details (note:one job responds 36000 line response)\n\nI'm a beginner\n\n========================================\n\nCode:\n```text\ngzip\n```\n\n========================================\n\nComments:\n- ThankYou.but,how can i get fast response while consuming this type of api call while using it in js?\n- @KalingaRaj, no this will be perfectly fine when you call it through JS, it's just related to the Swagger. That's why I said use an API testing tool. They are great and exactly designed for this purpose.","metadata":{"transformedAt":"2026-08-18T18:32:29.126Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":1,"totalLines":27,"estimatedTokens":244}}364{"id":"stack-69840223","source":"stackoverflow","questionId":69840223,"title":"Way to pass arguments to FastAPI app via command line","tags":["python","fastapi","gunicorn","systemd","uvicorn"],"text":"Title: Way to pass arguments to FastAPI app via command line\nTags: python, fastapi, gunicorn, systemd, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI'm using python 3.8.0 for my FastAPI app.\nIt uses the `.env` file located on the root of a project directory. I am using the dotenv package, and the location of the `.env` file is hardcoded within the app. Here is my unit file\n\n```\n[Unit]\nDescription=Gunicorn instance for my_app\nAfter=network.target\n\n[Service]\nUser=nginx\nGroup=nginx\nWorkingDirectory=/usr//nginx/html/my_app/\nEnvironment=\"PATH=/usr//nginx/html/my_app/venv/bin\"\nExecStart=/usr//nginx/html/my_app/venv/bin/gunicorn --bind unix:/usr//nginx/html/my_app/my_app.sock -w 4 -k uvicorn.workers.UvicornWorker app.main:app\n\n[Install]\nWantedBy=multi-user.target\n```\n\nThe challenge is to run two versions (production and test) of the same app using two different `.env` on two different ports. I'll have to create a second unit file. But how can I pass the name of two diffeent env file names to the app for further usage. These files contain database connections, etc.\nI imagine it roughly like this\n1st unit file\n\n```\nExecStart=/usr//nginx/html/my_app/venv/bin/gunicorn \n--bind unix:/usr//nginx/html/my_app/my_app.sock -w 4 -k uvicorn.workers.UvicornWorker app.main:app --env_file_name=\".env.prod\"\n```\n\n2nd unit file\n\n```\nExecStart=/usr//nginx/html/my_app/venv/bin/gunicorn \n--bind unix:/usr//nginx/html/my_app/my_app.sock -w 4 -k uvicorn.workers.UvicornWorker app.main:app --env_file_name=\".env.dev\"\n```\n\n========================================\n\nCode:\n```text\n[Unit]\nDescription=Gunicorn instance for my_app\nAfter=network.target\n\n[Service]\nUser=nginx\nGroup=nginx\nWorkingDirectory=/usr/share/nginx/html/my_app/\nEnvironment=\"PATH=/usr/share/nginx/html/my_app/venv/bin\"\nExecStart=/usr/share/nginx/html/my_app/venv/bin/gunicorn --bind unix:/usr/share/nginx/html/my_app/my_app.sock -w 4 -k uvicorn.workers.UvicornWorker app.main:app\n\n[Install]\nWantedBy=multi-user.target\n```\n\n```text\nExecStart=/usr/share/nginx/html/my_app/venv/bin/gunicorn \n--bind unix:/usr/share/nginx/html/my_app/my_app.sock -w 4 -k uvicorn.workers.UvicornWorker app.main:app --env_file_name=\".env.prod\"\n```\n\n```text\nExecStart=/usr/share/nginx/html/my_app/venv/bin/gunicorn \n--bind unix:/usr/share/nginx/html/my_app/my_app.sock -w 4 -k uvicorn.workers.UvicornWorker app.main:app --env_file_name=\".env.dev\"\n```\n\n```text\n.env\n```\n\n```text\n.env\n```\n\n```text\n.env\n```\n\n```text\nEnvironmentFile=\n```\n\n```text\n.env.prod\n```\n\n```text\n.env.test\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.126Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":92,"estimatedTokens":628}}365{"id":"stack-76540270","source":"stackoverflow","questionId":76540270,"title":"Uvicorn reload : kill all created sub process when auto reloading","tags":["python","multithreading","fastapi","uvicorn"],"text":"Title: Uvicorn reload : kill all created sub process when auto reloading\nTags: python, multithreading, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI currently have a fastapi deployed with uvicorn that starts a thread on initialisation (among other things) using `threading`.\nThis thread is infinite (it's a routine that updates every x seconds).\nBefore I updated to python 3.10, everything was working fine, everytime I changed the code, the server would detect change and reload, killing and creating a new thread at init.\n\nBut now, when I modify my code, the server detects change and try to reload but the created thread isn't killed (print still continue to flow in the console) refraining the server to fully reload.\n\n```\nmy print from my thread\nWARNING: StatReload detected changes in 'app\\api.py'. Reloading...\nINFO: Shutting down\nINFO: Waiting for application shutdown.\nINFO: Application shutdown complete.\nINFO: Finished server process [3736]\nmy print from my thread\nmy print from my thread\n...\n```\n\nThis works the same way if I ctrl+C in the console. The thread stays alive\nMy solution for the moment is to `kill PID`everytime I want to refresh but that's a bit annoying.\n\nI tried to get back to python 3.7.9 but the problem remains.\nI also tried to implement `atexit` and manually kill the process but it didn't work.\n\nAny lead on how to properly handle this ?\n\n========================================\n\nCode:\n```text\nmy print from my thread\nWARNING: StatReload detected changes in 'app\\api.py'. Reloading...\nINFO: Shutting down\nINFO: Waiting for application shutdown.\nINFO: Application shutdown complete.\nINFO: Finished server process [3736]\nmy print from my thread\nmy print from my thread\n...\n```\n\n```text\nthreading\n```\n\n```text\nkill PID\n```\n\n```text\natexit\n```\n\n========================================\n\nComments:\n- I posted similar question here.\n- Looks that 0.19 is a last stable version. Up from 0.21.1 to 0.30 issue with reloading exist within PyCharm.","metadata":{"transformedAt":"2026-08-18T18:32:29.126Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":63,"estimatedTokens":499}}366{"id":"stack-67402767","source":"stackoverflow","questionId":67402767,"title":"Can't see FastAPI documentation with 2 main.py and 1 nginx reverse proxy","tags":["python","nginx","fastapi"],"text":"Title: Can't see FastAPI documentation with 2 main.py and 1 nginx reverse proxy\nTags: python, nginx, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm using fastAPI together with nginx, as a reverse proxy. I split APIs into 2 different main.py with different endpoints:\n\n- main.py -> main location/endopoint of APIs: `/` (port 5010)\n\n- main_slow.py -> main location/endopoint of APIs: `/slow_api` (port 5011)\n\nto run them on different ports (5010,5011). This because one API is very slow and requesting APIs in series i need one to be separate from the others (in main_slow.py). Using nginx as a reverse proxy, I can call the APIs with their own endpoints under a single port (8000), then nginx will take care of passing them to the correct port of fastAPI.\n\nAll works well, the only problem is that i can't see all API documentations in /docs, but only endpoints of the first main.py (location `/`).\n\nin `/nginx/conf.d/` i have `py_api.conf` and i have configured it like this:\n\n```\nserver {\n\n listen 8000;\n\n location / {\n\n proxy_redirect off;\n proxy_set_header Host $host;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n\n proxy_http_version 1.1;\n proxy_set_header Connection \"\";\n\n add_header 'Access-Control-Allow-Origin' '*';\n add_header 'Access-Control-Allow-Methods' 'GET, POST, PATCH, PUT, DELETE, OPTIONS';\n add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Origin,X-Auth-Token';\n add_header 'Access-Control-Allow-Credentials' 'true';\n\n if ($request_method = OPTIONS ) {\n return 200;\n }\n\n proxy_pass http://localhost:5010;\n proxy_set_header Connection \"Keep-Alive\";\n proxy_set_header Proxy-Connection \"Keep-Alive\";\n\n auth_basic \"Restricted\"; #For Basic Auth\n auth_basic_user_file /etc/nginx/.htpasswd-pyapi; #For Basic Auth\n }\n location /slow_api{\n\n proxy_redirect off;\n proxy_set_header Host $host;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n\n proxy_http_version 1.1;\n proxy_set_header Connection \"\";\n\n add_header 'Access-Control-Allow-Origin' '*';\n add_header 'Access-Control-Allow-Methods' 'GET, POST, PATCH, PUT, DELETE, OPTIONS';\n add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Origin,X-Auth-Token';\n add_header 'Access-Control-Allow-Credentials' 'true';\n\n if ($request_method = OPTIONS ) {\n return 200;\n }\n\n proxy_pass http://localhost:5011;\n proxy_set_header Connection \"Keep-Alive\";\n proxy_set_header Proxy-Connection \"Keep-Alive\";\n\n auth_basic \"Restricted\"; #For Basic Auth\n auth_basic_user_file /etc/nginx/.htpasswd-pyapi; #For Basic Auth\n }\n}\n```\n\nDid I do something wrong to be able to see the documentation of both locations? Or do I have to do something about python and fastAPI?\n\nSOLVED\n\nTo see all two documentation (for now in two different path) i added in my fastAPI project main_slow.py\n\n```\napp = FastAPI( title='slow API',\n docs_url='/slow_api/docs', \n redoc_url='/slow_api/redoc',\n openapi_url='/slow_api/openapi.json')\n```\n\ninstead only\n\n```\napp = FastAPI()\n```\n\n========================================\n\nTop Answer:\nYou have to change the order of location blocks. Nginx terminates location matching at the first successful match. In your case, all requests to `/slow_api` are matched to the first location block and the second block is never checked.\nYou can check the official documentation for more details.\n\nDocs\n\n========================================\n\nCode:\n```text\nserver {\n\n listen 8000;\n\n location / {\n\n proxy_redirect off;\n proxy_set_header Host $host;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n\n proxy_http_version 1.1;\n proxy_set_header Connection \"\";\n\n add_header 'Access-Control-Allow-Origin' '*';\n add_header 'Access-Control-Allow-Methods' 'GET, POST, PATCH, PUT, DELETE, OPTIONS';\n add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Origin,X-Auth-Token';\n add_header 'Access-Control-Allow-Credentials' 'true';\n\n if ($request_method = OPTIONS ) {\n return 200;\n }\n\n proxy_pass http://localhost:5010;\n proxy_set_header Connection \"Keep-Alive\";\n proxy_set_header Proxy-Connection \"Keep-Alive\";\n\n auth_basic \"Restricted\"; #For Basic Auth\n auth_basic_user_file /etc/nginx/.htpasswd-pyapi; #For Basic Auth\n }\n location /slow_api{\n\n proxy_redirect off;\n proxy_set_header Host $host;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n\n proxy_http_version 1.1;\n proxy_set_header Connection \"\";\n\n add_header 'Access-Control-Allow-Origin' '*';\n add_header 'Access-Control-Allow-Methods' 'GET, POST, PATCH, PUT, DELETE, OPTIONS';\n add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Origin,X-Auth-Token';\n add_header 'Access-Control-Allow-Credentials' 'true';\n\n if ($request_method = OPTIONS ) {\n return 200;\n }\n\n proxy_pass http://localhost:5011;\n proxy_set_header Connection \"Keep-Alive\";\n proxy_set_header Proxy-Connection \"Keep-Alive\";\n\n auth_basic \"Restricted\"; #For Basic Auth\n auth_basic_user_file /etc/nginx/.htpasswd-pyapi; #For Basic Auth\n }\n}\n```\n\n```text\napp = FastAPI( title='slow API',\n docs_url='/slow_api/docs', \n redoc_url='/slow_api/redoc',\n openapi_url='/slow_api/openapi.json')\n```\n\n```text\napp = FastAPI()\n```\n\n```text\n/\n```\n\n```text\n/slow_api\n```\n\n```text\n/\n```\n\n```text\n/nginx/conf.d/\n```\n\n```text\npy_api.conf\n```\n\n```text\n/slow_api\n```\n\n========================================\n\nComments:\n- Thanks, i just change the order but it doesn't work.. Maybe it's also fault of some configuration of fastAPI. Do you think it's bettere change the location '/' with another path? like '/other_api/'?\n- could you please tail of the access and error logs after applying this fix. Be sure logs are for the appropriate test.","metadata":{"transformedAt":"2026-08-18T18:32:29.126Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":9,"totalLines":203,"estimatedTokens":1571}}367{"id":"stack-71102658","source":"stackoverflow","questionId":71102658,"title":"How can I return a NumPy array using FastAPI?","tags":["python","numpy","tensorflow","opencv","fastapi"],"text":"Title: How can I return a NumPy array using FastAPI?\nTags: python, numpy, tensorflow, opencv, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have a TensorFlow Keras deep learning model in the form of an h5 file.\n\nHow can I upload an image and return a NumPy array in FastAPI?\n\n```\nimport numpy as np\nimport cv2\nfrom fastapi import FastAPI, File, UploadFile\nimport numpy as np\nfrom tensorflow.keras.models import load_model\nimport tensorflow as tf\n\nmodel=load_model(\"complete_model.h5\")\napp = FastAPI()\n\ndef prepare(image):\n IMG_SIZE = 224\n new_array = cv2.resize(image, (IMG_SIZE, IMG_SIZE))\n return new_array.reshape(-1, IMG_SIZE,IMG_SIZE,3)\n\n@app.post(\"/\")\nasync def root(file: UploadFile = File(...)):\n global model\n content = await file.read()\n nparr = np.fromstring(content, np.uint8)\n img = cv2.imdecode(nparr, cv2.IMREAD_COLOR).astype(np.float32)\n prediction = model.predict(prepare(img))\n return prediction\n```\n\nWhen uploading the image using Swagger UI, I get the following error:\n\n```\nline 137, in jsonable_encoder\ndata = dict(obj)\nTypeError: 'numpy.float32' object is not iterable\n```\n\nWorking code without FastAPI:\n\n```\nimport numpy as np\nimport numpy as np\nfrom tensorflow.keras.models import load_model\nimport tensorflow as tf\nimport cv2\n\nmodel=load_model(\"complete_model.h5\")\n\ndef prepare(image):\n IMG_SIZE = 224\n new_array = cv2.resize(image, (IMG_SIZE, IMG_SIZE))\n return new_array.reshape(-1, IMG_SIZE,IMG_SIZE,3)\n\nimg = cv2.imread(\"./test.jpeg\").astype(np.float32)\nprediction = model.predict(prepare(img))\nprint(prediction)\n```\n\nResult in the terminal:\n\n```\n[[0.25442022 0.74557984]]\n```\n\nHow can I get the same result while using FastAPI?\n\n========================================\n\nTop Answer:\nYou can also convert NumPy types to Python types.\n\n```\nreturn {str(key): value for key, value in prediction.items()}\n```\n\n========================================\n\nCode:\n```text\nimport numpy as np\nimport cv2\nfrom fastapi import FastAPI, File, UploadFile\nimport numpy as np\nfrom tensorflow.keras.models import load_model\nimport tensorflow as tf\n\nmodel=load_model(\"complete_model.h5\")\napp = FastAPI()\n\ndef prepare(image):\n IMG_SIZE = 224\n new_array = cv2.resize(image, (IMG_SIZE, IMG_SIZE))\n return new_array.reshape(-1, IMG_SIZE,IMG_SIZE,3)\n\n@app.post(\"/\")\nasync def root(file: UploadFile = File(...)):\n global model\n content = await file.read()\n nparr = np.fromstring(content, np.uint8)\n img = cv2.imdecode(nparr, cv2.IMREAD_COLOR).astype(np.float32)\n prediction = model.predict(prepare(img))\n return prediction\n```\n\n```text\nline 137, in jsonable_encoder\ndata = dict(obj)\nTypeError: 'numpy.float32' object is not iterable\n```\n\n```text\nimport numpy as np\nimport numpy as np\nfrom tensorflow.keras.models import load_model\nimport tensorflow as tf\nimport cv2\n\nmodel=load_model(\"complete_model.h5\")\n\ndef prepare(image):\n IMG_SIZE = 224\n new_array = cv2.resize(image, (IMG_SIZE, IMG_SIZE))\n return new_array.reshape(-1, IMG_SIZE,IMG_SIZE,3)\n\nimg = cv2.imread(\"./test.jpeg\").astype(np.float32)\nprediction = model.predict(prepare(img))\nprint(prediction)\n```\n\n```text\n[[0.25442022 0.74557984]]\n```\n\n```py\nreturn json.dumps(prediction.tolist())\n```\n\n```py\narr = np.asarray(json.loads(resp.json())) # resp.json() if using Python requests\n```\n\n```text\nresponse\n```\n\n```text\nprediction\n```\n\n```text\ndict\n```\n\n```text\njsonable_encoder\n```\n\n```text\nvars()\n```\n\n```text\nlist\n```\n\n```text\nJSON\n```\n\n```text\nResponse\n```\n\n```text\n/docs\n```\n\n```text\nreturn {str(key): value for key, value in prediction.items()}\n```\n\n========================================\n\nComments:\n- It doesn't, just shows this ERROR: Exception in ASGI application Traceback (most recent call last): File \"c:\\users\\ranveer\\anaconda3\\envs\\tfjs\\lib\\site-packages\\fast‌​api\\encoders.py\", line 137, in jsonable_encoder data = dict(obj) TypeError: 'numpy.float32' object is not iterable During the handling of the above exception, another exception occurred: Traceback (most recent call last): File \"c:\\users\\ranveer\\anaconda3\\envs\\tfjs\\lib\\site-packages\\fast‌​api\\encoders.py\", line 141, in jsonable_encoder data = vars(obj) TypeError: vars() argument must have **dict** attribute","metadata":{"transformedAt":"2026-08-18T18:32:29.126Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":16,"totalLines":191,"estimatedTokens":1050}}368{"id":"stack-67312219","source":"stackoverflow","questionId":67312219,"title":"Problem with combining fastapi with plotly.dash and adding token dependency as auth","tags":["python","dependency-injection","plotly-dash","fastapi"],"text":"Title: Problem with combining fastapi with plotly.dash and adding token dependency as auth\nTags: python, dependency-injection, plotly-dash, fastapi\nSource: Stack Overflow\n\nQuestion:\nSo this is an example dash app mounted to fastapi. I'm using app.mount based on this example from official docs fastapi-adcanced-wsgi. Now I'm stuck because I don't see a way where I can mount this dash app and add fastapi dependency\n\nI would like to add a token or even basic auth to this dash sub app in way you add single dependency to fastapi routes:\n\n```\nfrom fastapi import Depends, FastAPI\nfrom fastapi.security import HTTPBasic, HTTPBasicCredentials\n\napp = FastAPI()\n\nsecurity = HTTPBasic()\n\n@app.get(\"/users/me\")\ndef read_current_user(credentials: HTTPBasicCredentials = Depends(security)):\n return {\"username\": credentials.username, \"password\": credentials.password}\n```\n\nFastAPI example with working dash app.\n\n```\nfrom fastapi import FastAPI\nfrom fastapi.middleware.wsgi import WSGIMiddleware\nimport dash\nimport dash_core_components as dcc\nimport dash_html_components as html\nimport pandas as pd\nfrom datetime import datetime\n\n# Create the Dash application, make sure to adjust requests_pathname_prefx\nexternal_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']\n\napp_dash = dash.Dash(__name__, external_stylesheets=external_stylesheets, requests_pathname_prefix='/dash/')\n\napp_dash.layout = html.Div([\n html.Label('Dropdown'),\n dcc.Dropdown(\n options=[\n {'label': 'New York City', 'value': 'NYC'},\n {'label': u'Montréal', 'value': 'MTL'},\n {'label': 'San Francisco', 'value': 'SF'}\n ],\n value='MTL'\n ),\n\n html.Label('Multi-Select Dropdown'),\n dcc.Dropdown(\n options=[\n {'label': 'New York City', 'value': 'NYC'},\n {'label': u'Montréal', 'value': 'MTL'},\n {'label': 'San Francisco', 'value': 'SF'}\n ],\n value=['MTL', 'SF'],\n multi=True\n ),\n\n html.Label('Radio Items'),\n dcc.RadioItems(\n options=[\n {'label': 'New York City', 'value': 'NYC'},\n {'label': u'Montréal', 'value': 'MTL'},\n {'label': 'San Francisco', 'value': 'SF'}\n ],\n value='MTL'\n ),\n\n html.Label('Checkboxes'),\n dcc.Checklist(\n options=[\n {'label': 'New York City', 'value': 'NYC'},\n {'label': u'Montréal', 'value': 'MTL'},\n {'label': 'San Francisco', 'value': 'SF'}\n ],\n value=['MTL', 'SF']\n ),\n\n html.Label('Text Input'),\n dcc.Input(value='MTL', type='text'),\n\n html.Label('Slider'),\n dcc.Slider(\n min=0,\n max=9,\n marks={i: 'Label {}'.format(i) if i == 1 else str(i) for i in range(1, 6)},\n value=5,\n ),\n], style={'columnCount': 2})\n\n# Now create your regular FASTAPI application\n\napp = FastAPI()\n\n@app.get(\"/hello_fastapi\")\ndef read_main():\n return {\"message\": \"Hello World\"}\n\n# Now mount you dash server into main fastapi application\napp.mount(\"/dash\", WSGIMiddleware(app_dash.server))\n```\n\n========================================\n\nCode:\n```py\nfrom fastapi import Depends, FastAPI\nfrom fastapi.security import HTTPBasic, HTTPBasicCredentials\n\napp = FastAPI()\n\nsecurity = HTTPBasic()\n\n\n@app.get(\"/users/me\")\ndef read_current_user(credentials: HTTPBasicCredentials = Depends(security)):\n return {\"username\": credentials.username, \"password\": credentials.password}\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.middleware.wsgi import WSGIMiddleware\nimport dash\nimport dash_core_components as dcc\nimport dash_html_components as html\nimport pandas as pd\nfrom datetime import datetime\n\n# Create the Dash application, make sure to adjust requests_pathname_prefx\nexternal_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']\n\napp_dash = dash.Dash(__name__, external_stylesheets=external_stylesheets, requests_pathname_prefix='/dash/')\n\napp_dash.layout = html.Div([\n html.Label('Dropdown'),\n dcc.Dropdown(\n options=[\n {'label': 'New York City', 'value': 'NYC'},\n {'label': u'Montréal', 'value': 'MTL'},\n {'label': 'San Francisco', 'value': 'SF'}\n ],\n value='MTL'\n ),\n\n html.Label('Multi-Select Dropdown'),\n dcc.Dropdown(\n options=[\n {'label': 'New York City', 'value': 'NYC'},\n {'label': u'Montréal', 'value': 'MTL'},\n {'label': 'San Francisco', 'value': 'SF'}\n ],\n value=['MTL', 'SF'],\n multi=True\n ),\n\n html.Label('Radio Items'),\n dcc.RadioItems(\n options=[\n {'label': 'New York City', 'value': 'NYC'},\n {'label': u'Montréal', 'value': 'MTL'},\n {'label': 'San Francisco', 'value': 'SF'}\n ],\n value='MTL'\n ),\n\n html.Label('Checkboxes'),\n dcc.Checklist(\n options=[\n {'label': 'New York City', 'value': 'NYC'},\n {'label': u'Montréal', 'value': 'MTL'},\n {'label': 'San Francisco', 'value': 'SF'}\n ],\n value=['MTL', 'SF']\n ),\n\n html.Label('Text Input'),\n dcc.Input(value='MTL', type='text'),\n\n html.Label('Slider'),\n dcc.Slider(\n min=0,\n max=9,\n marks={i: 'Label {}'.format(i) if i == 1 else str(i) for i in range(1, 6)},\n value=5,\n ),\n], style={'columnCount': 2})\n\n# Now create your regular FASTAPI application\n\napp = FastAPI()\n\n@app.get(\"/hello_fastapi\")\ndef read_main():\n return {\"message\": \"Hello World\"}\n\n# Now mount you dash server into main fastapi application\napp.mount(\"/dash\", WSGIMiddleware(app_dash.server))\n```\n\n```text\nfrom fastapi import FastAPI, Request\nfrom fastapi.middleware.wsgi import WSGIMiddleware\nfrom flask import Flask, escape, request\nfrom starlette.responses import JSONResponse\n\nflask_app = Flask(__name__)\n\n\n@flask_app.route(\"/\")\ndef flask_main():\n name = request.args.get(\"name\", \"World\")\n return f\"Hello, {escape(name)} from Flask!\"\n\n\napp = FastAPI()\n\n\n@app.middleware(\"http\")\nasync def auth_middleware(request: Request, call_next):\n if (request.url.path.startswith(\"/v1\") and\n request.headers.get('X-Token', None) != \"expected_token\"):\n return JSONResponse(status_code=403)\n response = await call_next(request)\n return response\n\n\n@app.get(\"/v2\")\ndef read_main():\n return {\"message\": \"Hello World\"}\n\n\napp.mount(\"/v1\", WSGIMiddleware(flask_app))\n```\n\n========================================\n\nComments:\n- Omitting FastAPI, is there a similar pattern that would be appropriate for Django + Dash?","metadata":{"transformedAt":"2026-08-18T18:32:29.126Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":3,"totalLines":240,"estimatedTokens":1561}}369{"id":"stack-63038345","source":"stackoverflow","questionId":63038345,"title":"How to make FASTAPI pickup changes in an API routing file automatically while running inside a docker container?","tags":["python","docker","fastapi"],"text":"Title: How to make FASTAPI pickup changes in an API routing file automatically while running inside a docker container?\nTags: python, docker, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am running FastApi via docker by creating a sevice called ingestion-data in docker-compose. My Dockerfile :\n\n```\nFROM tiangolo/uvicorn-gunicorn-fastapi:python3.7\n\n# Environment variable for directory containing our app\nENV APP /var/www/app\nENV PYTHONUNBUFFERED 1\n\n# Define working directory\nRUN mkdir -p $APP\nWORKDIR $APP\nCOPY . $APP\n\n# Install missing dependencies\nRUN pip install -r requirements.txt\n```\n\nAND my docker-compose.yml file\n\n```\nversion: '3.8'\n\nservices:\n ingestion-service:\n build:\n context: ./app\n dockerfile: Dockerfile\n ports:\n - \"80:80\"\n volumes:\n - .:/app\n restart: always\n```\n\nI am not sure why this is not picking up any change automatically when I make any change in any endpoint of my application. I have to rebuild my images and container every time.\n\n========================================\n\nCode:\n```text\nFROM tiangolo/uvicorn-gunicorn-fastapi:python3.7\n\n# Environment variable for directory containing our app\nENV APP /var/www/app\nENV PYTHONUNBUFFERED 1\n\n# Define working directory\nRUN mkdir -p $APP\nWORKDIR $APP\nCOPY . $APP\n\n# Install missing dependencies\nRUN pip install -r requirements.txt\n```\n\n```text\nversion: '3.8'\n\nservices:\n ingestion-service:\n build:\n context: ./app\n dockerfile: Dockerfile\n ports:\n - \"80:80\"\n volumes:\n - .:/app\n restart: always\n```\n\n```text\nvolumes:\n - .:/var/www/app\n```\n\n```text\ndocker build -t <imgName>:<tag>\n```\n\n```text\ndocker run\n```\n\n```text\ndocker-compose up\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.126Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":6,"totalLines":92,"estimatedTokens":423}}370{"id":"stack-63273028","source":"stackoverflow","questionId":63273028,"title":"FastAPI get user ID from API key","tags":["python","python-3.x","python-asyncio","fastapi"],"text":"Title: FastAPI get user ID from API key\nTags: python, python-3.x, python-asyncio, fastapi\nSource: Stack Overflow\n\nQuestion:\nIn fastAPI one can simply write a security dependency at the router level and secure an entire part of the URLs.\n\n```\nrouter.include_router(\n my_router,\n prefix=\"/mypath\",\n dependencies=[Depends(auth.oauth2_scheme)]\n)\n```\n\nThis avoids repeating a lot of code.\n\nThe only problem is that I would like to protect a part of URLs with a router level dependency that checks the validity of the user token and retrieve the user id for that token.\n\nThe only way I found, is to add another dependency to all the functions, but this leads to repeating the code that I just saved.\n\nLong story short, is there a way to add the dependency at the router level, retrieve and return the user id, and pass the returned value to the handling function? Something like\n\n**router.py**\n\n```\nrouter.include_router(\n my_router,\n prefix=\"/mypath\",\n dependencies=[user_id = Depends(auth.oauth2_scheme)]\n )\n```\n\n**my_router.py**\n\n```\nmy_router = APIRouter()\n\n@my_router.get(\"/my_path\")\nasync def get_my_path(**kwargs):\n user_id = kwargs[\"user_id\"]\n # Do stuff with the user_id\n return {}\n```\n\n========================================\n\nTop Answer:\n**You can the below steps to solve your problem**\n\n- First change on router.py file(because I can add prefixes and dependencies on my_router.py)\n\n```\nrouter.include_router(my_router)\n```\n\n- Second on change on my_router.py\n\n```\nmy_router = APIRouter(prefix=\"/mypath\",dependencies=[user_id:=Depends(auth.oauth2_scheme))\n\n @my_router.get(\"/my_path\")\n async def get_my_path(userId=user_id):\n return userId\n```\n\n========================================\n\nCode:\n```text\nrouter.include_router(\n my_router,\n prefix=\"/mypath\",\n dependencies=[Depends(auth.oauth2_scheme)]\n)\n```\n\n```text\nrouter.include_router(\n my_router,\n prefix=\"/mypath\",\n dependencies=[user_id = Depends(auth.oauth2_scheme)]\n )\n```\n\n```text\nmy_router = APIRouter()\n\n@my_router.get(\"/my_path\")\nasync def get_my_path(**kwargs):\n user_id = kwargs[\"user_id\"]\n # Do stuff with the user_id\n return {}\n```\n\n```py\nasync def oauth2_scheme(request: Request):\n request.state.user_id = \"foo\"\n\nmy_router = APIRouter()\n\n@my_router .get(\"/\")\nasync def hello(request: Request):\n print(request.state.user_id)\n\napp.include_router(\n my_router,\n dependencies=[Depends(oauth2_scheme)]\n)\n```\n\n```text\nrequest.state\n```\n\n```text\nrouter.include_router(my_router)\n```\n\n```text\nmy_router = APIRouter(prefix=\"/mypath\",dependencies=[user_id:=Depends(auth.oauth2_scheme))\n\n @my_router.get(\"/my_path\")\n async def get_my_path(userId=user_id):\n return userId\n```\n\n========================================\n\nComments:\n- Thanks, did not think about accessing directly the request.\n- It is worth to add that route dependencies and normal dependencies have two different scopes and can be duplicated (one checks the auth key, the other gets the data) with no performance losses thanks to caching, as discussed in github.com/tiangolo/fastapi/issues/424 Don't know why I didn't find it at the time of asking the question...","metadata":{"transformedAt":"2026-08-18T18:32:29.126Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":7,"totalLines":132,"estimatedTokens":788}}371{"id":"stack-70685203","source":"stackoverflow","questionId":70685203,"title":"How to get the origin URL in FastAPI?","tags":["python","http","httprequest","fastapi","http-referer"],"text":"Title: How to get the origin URL in FastAPI?\nTags: python, http, httprequest, fastapi, http-referer\nSource: Stack Overflow\n\nQuestion:\nIs it possible to get the URL that a request came from in FastAPI?\n\nFor example, if I have an endpoint that is requested at `api.mysite.com/endpoint` and a request is made to this endpoint from `www.othersite.com`, is there a way that I can retrieve the string \"www.othersite.com\" in my endpoint function?\n\n========================================\n\nTop Answer:\n### Update\n\nAs mentioned by @jub0bs, HTTP requests usually carry the `Referer` header that contains the address from which a resource has been requested—even though, you should always **be aware** that the `Referer` header, like every other header, could easily be modified/spoofed on client side, in order to prevent the server from obtaining accurate data on the identity of the website visited by the user. As per MDN's documentation:\n\nThe `Referer` HTTP request header contains the absolute or partial\naddress from which a resource has been requested. The `Referer` header\nallows a server to **identify referring pages** that people are\nvisiting from or where requested resources are being used. This data\ncan be used for analytics, logging, optimized caching, and more.\n\nWhen you click a link, the `Referer` contains the address of the page\nthat includes the link. When you make resource requests to another\ndomain, the `Referer` contains the address of the page that uses the\nrequested resource.\n\nIn FastAPI, you could retrieve the request headers, as demonstrated here. Hence, you could obtain the `Referer` URL in the following way:\n\n```\nfrom fastapi import FastAPI, Request\n\napp = FastAPI()\n\n@app.get('/')\ndef main(request: Request):\n referer = request.headers.get('referer')\n return referer\n```\n\n### Original Answer\n\nAs per FastAPI documentation, and hence Starlette's:\n\nLet's imagine you want to get the **client's IP address/host** inside of\nyour path operation function.\n\n```\n@app.get(\"/items/{item_id}\")\ndef read_root(item_id: str, request: Request):\n client_host = request.client.host\n return {\"client_host\": client_host, \"item_id\": item_id}\n```\n\nPlease note that if you are running behind a reverse proxy server such as nginx, you would need to run Uvicorn with `--proxy-headers` flag (see the relevant implementation) to accept such headers (it is already enabled by default, but is restricted to only trusting connecting IPs in the `forwarded-allow-ips` configuration), as well as with `--forwarded-allow-ips='*'` flag to ensure that the domain socket is trusted as a source from which to proxy headers (**Note:** instead of trusting headers from all IPs using the `'*'` wildcard, it would be more safe to trust **only** proxy headers from the IP of your reverse proxy server). As per Uvicorn's docs:\n\n`--proxy-headers / --no-proxy-headers` - Enable/Disable `X-Forwarded-Proto`, `X-Forwarded-For`, `X-Forwarded-Port` to populate remote address info. Defaults to **enabled**, but is restricted to **only** trusting connecting IPs in the `forwarded-allow-ips` configuration.\n\n`--forwarded-allow-ips` - Comma separated **list of IPs to trust with proxy headers**. Defaults to the `$FORWARDED_ALLOW_IPS` environment variable if available, or `'127.0.0.1'`. A wildcard `'*'` means **always** trust.\n\nTo programmatically set the uvicorn configurations above instead of using the command line interface (see the relevant implementation as well), one might do that as follows (`'127.0.0.1,[::1]'` will catch both IPv4 and IIPv6 on localhost):\n\n```\nuvicorn.run(\"main:app\", proxy_headers=True, forwarded_allow_ips=\"127.0.0.1,[::1]\")\n```\n\nTo ensure that the proxy server forwards them, you should make sure that the `X-Forwarded-For` and `X-Forwarded-Proto` headers are set by the proxy (see Uvicorn's documentation for more details):\n\n```\nserver {\n listen 80;\n server_name yourdomain.com;\n\n location / {\n proxy_pass http://localhost:8000;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header X-Forwarded-Proto $scheme;\n }\n}\n```\n\nAssuming that requests to your API are **handled in the backend** of the website that you are trying to retrieve its URL/domain, and not by allowing users to issue requests to your API directly from their frontend—and hence, in that case, the client's IP address would be the website's (server/backend) IP address, and not the user's IP address, who is browsing the website—once you obtain the website's IP address (using `request.client.host`, as described earlier), you can perform a reverse DNS lookup to get the website's hostname (doesn't always exist though, or does not have a meaningful name), as shown in the example below. From there, you can look up for information on the hostname or the IP address itself online. You could also create a database with every IP address (or better, hostname) you resolve for future reference.\n\n```\nimport socket\n#address = '2001:4860:4860::8888' # Google's Public DNS IPv6 address\naddress = '216.58.214.14' # a Google's IP address\nprint(socket.gethostbyaddr(address)[0])\n```\n\n========================================\n\nCode:\n```text\napi.mysite.com/endpoint\n```\n\n```text\nwww.othersite.com\n```\n\n```text\nOrigin\n```\n\n```text\nReferer\n```\n\n```text\nForwarded\n```\n\n```py\nfrom fastapi import FastAPI, Request\n\napp = FastAPI()\n\n@app.get('/')\ndef main(request: Request):\n referer = request.headers.get('referer')\n return referer\n```\n\n```py\n@app.get(\"/items/{item_id}\")\ndef read_root(item_id: str, request: Request):\n client_host = request.client.host\n return {\"client_host\": client_host, \"item_id\": item_id}\n```\n\n```py\nuvicorn.run(\"main:app\", proxy_headers=True, forwarded_allow_ips=\"127.0.0.1,[::1]\")\n```\n\n```text\nserver {\n listen 80;\n server_name yourdomain.com;\n\n location / {\n proxy_pass http://localhost:8000;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header X-Forwarded-Proto $scheme;\n }\n}\n```\n\n```py\nimport socket\n#address = '2001:4860:4860::8888' # Google's Public DNS IPv6 address\naddress = '216.58.214.14' # a Google's IP address\nprint(socket.gethostbyaddr(address)[0])\n```\n\n```text\nReferer\n```\n\n```text\nReferer\n```\n\n```text\nReferer\n```\n\n```text\nReferer\n```\n\n```text\nReferer\n```\n\n```text\nReferer\n```\n\n```text\nReferer\n```\n\n```text\n--proxy-headers\n```\n\n```text\nforwarded-allow-ips\n```\n\n```text\n--forwarded-allow-ips='*'\n```\n\n```text\n'*'\n```\n\n```text\n--proxy-headers / --no-proxy-headers\n```\n\n```text\nX-Forwarded-Proto\n```\n\n```text\nX-Forwarded-For\n```\n\n```text\nX-Forwarded-Port\n```\n\n```text\nforwarded-allow-ips\n```\n\n```text\n--forwarded-allow-ips\n```\n\n```text\n$FORWARDED_ALLOW_IPS\n```\n\n```text\n'127.0.0.1'\n```\n\n```text\n'*'\n```\n\n```text\n'127.0.0.1,[::1]'\n```\n\n```text\nX-Forwarded-For\n```\n\n```text\nX-Forwarded-Proto\n```\n\n```text\nrequest.client.host\n```\n\n========================================\n\nComments:\n- Thanks for the explanation on how it may always not be present. I ended up retrieving this in FastAPI like `origin_url = dict(request.scope[\"headers\"]).get(b\"referer\", b\"\").decode()`. My requirement for this is to know whether the request is coming from our dev or prod frontend server, and, from testing, it appears that this header will always be there in our case.\n- This will give the IP of the device that is running the site that makes the request to my API, not the domain of the site itself.\n- Thanks, but again, the problem here would be that the IP address is the IP address of the client device, not the domain that the client is browsing. In your example, you used Google as an example, but the IP adddress from `request.client.host` would not be Google's IP address but instead the device's IP address that is browsing www.google.com.","metadata":{"transformedAt":"2026-08-18T18:32:29.126Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":34,"totalLines":261,"estimatedTokens":1971}}372{"id":"stack-62264787","source":"stackoverflow","questionId":62264787,"title":"Mypy + FastAPI response_model","tags":["python","fastapi","python-typing","mypy"],"text":"Title: Mypy + FastAPI response_model\nTags: python, fastapi, python-typing, mypy\nSource: Stack Overflow\n\nQuestion:\nI've been tasked with handling the update from Mypy 0.770 to 0.870 in our FastAPI project, and this has produced an error that I can't quite wrap my head around. My endpoint can return two different models based on some condition, and this was denoted as follows the endpont decorator:\n\n```\n@router.get(\"/\", response_model=Union[Model1, Model2])\n```\n\nMypy 0.870 now complains about this, stating that\n\n```\nArgument \"response_model\" to \"get\" of \"APIRouter\" has incompatible type \"object\"; expected \"Optional[Type[Any]]\"\n```\n\nSetting it to single types, such as `Model1` or even `str` removes the error. `Any` however, does *not* work.\n\nNow, looking into the `get` method, I see that the `response_model` argument is typed as `Type[Any]`, which I assume must be a pointer.\n\nHow I can define non-simple return models for my API, and make Mypy happy?\n\nedit: I tried to reproduce the problem in a smaller frame, but couldn't. The following code works fine:\n\n```\nfrom typing import Any, Type, Union\n\ndef test1(var, response_model: Type[Any]):\n print(f\"Accepted Type[Any], {var}\")\n\ndef test2(var, response_model: Union[dict, set]):\n print(f\"Accepted Union, {var}\")\n\ndef main():\n test1('test1', response_model=Union[dict, set])\n test2('test2', response_model=Union[dict, set])\n\nif __name__ == '__main__':\n main()\n```\n\n========================================\n\nTop Answer:\n`Type[]` of something means a not instantiated class of this type, while `Model1` here will mean an instance of a `Model1` class or an instance of anything that inherits from `Model1`.\n\nNonetheless, the error message is enigmatic.\n\nWhat `python -v` are you using? Typing is a new thing in a python world and things might change between python versions as well. If you bumped `mypy` version it might be good to upgrade `python` as well as they go together.\n\nAlso, what `fastapi` version are you using? I'd try bump it to the latest, `0.55.1`, as well. Tiangolo himself wrote they have had a bug with typing\n\nsource\n\n========================================\n\nCode:\n```text\n@router.get(\"/\", response_model=Union[Model1, Model2])\n```\n\n```text\nArgument \"response_model\" to \"get\" of \"APIRouter\" has incompatible type \"object\"; expected \"Optional[Type[Any]]\"\n```\n\n```text\nfrom typing import Any, Type, Union\n\n\ndef test1(var, response_model: Type[Any]):\n print(f\"Accepted Type[Any], {var}\")\n\ndef test2(var, response_model: Union[dict, set]):\n print(f\"Accepted Union, {var}\")\n\ndef main():\n test1('test1', response_model=Union[dict, set])\n test2('test2', response_model=Union[dict, set])\n\nif __name__ == '__main__':\n main()\n```\n\n```text\nModel1\n```\n\n```text\nstr\n```\n\n```text\nAny\n```\n\n```text\nget\n```\n\n```text\nresponse_model\n```\n\n```text\nType[Any]\n```\n\n```text\nclass NewModel(BaseModel):\n __root__: Union[Model1, Model2]\n```\n\n```text\nNewModel = TypeVar('NewModel',Model1,Model2)\n```\n\n```text\nType[]\n```\n\n```text\nModel1\n```\n\n```text\nModel1\n```\n\n```text\nModel1\n```\n\n```text\npython -v\n```\n\n```text\nmypy\n```\n\n```text\npython\n```\n\n```text\nfastapi\n```\n\n```text\n0.55.1\n```\n\n========================================\n\nComments:\n- Have you figured this out @oyblix?\n- Unfortunately, no :( I ended up Using MyPy's `type: ignore` feature, but as this problem seemingly arose after a mypy (or FastAPI, can't remember) update, it might just be a fixable incompatibility issue. Feel free to report an issue to FastAPI - I don't recall doing that.\n- We're using FastApi 0.52.0 and python 3.8.3. I tried updating to FastApi 0.55.1, but that didn't seem to help :/","metadata":{"transformedAt":"2026-08-18T18:32:29.126Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":20,"totalLines":159,"estimatedTokens":908}}373{"id":"stack-70257170","source":"stackoverflow","questionId":70257170,"title":"How to debug FastAPI openapi generation error","tags":["python","swagger","fastapi","openapi-generator"],"text":"Title: How to debug FastAPI openapi generation error\nTags: python, swagger, fastapi, openapi-generator\nSource: Stack Overflow\n\nQuestion:\nI spend some time going over this error but had no success.\n\nFile \"C:\\Users\\ebara.conda\\envs\\asci\\lib\\site-packages\\fastapi\\openapi\\utils.py\", line 388, in get_openapi\nflat_models=flat_models, model_name_map=model_name_map\n\nFile \"C:\\Users\\ebara.conda\\envs\\asci\\lib\\site-packages\\fastapi\\utils.py\", line 28, in get_model_definitions\nmodel_name = model_name_map[model]\n\nKeyError: \n\nThe problem is that I'm trying to build a project with user authentication from OpenAPI form to create new users in database.\n\nI've used backend part of this template project https://github.com/tiangolo/full-stack-fastapi-postgresql\n\nEverything works except for Authentication like here.\n\n```\n@router.post(\"/login/access-token\", response_model=schemas.Token)\ndef login_access_token(\n db: Session = Depends(deps.get_db), form_data: OAuth2PasswordRequestForm = Depends()) -> Any:\n```\n\nWhen I add this part `form_data: OAuth2PasswordRequestForm = Depends()` - and go to /docs page - this error appears (Failed to load API definition. Fetch error. Internal Server Error /openapi.json)\n\nhttps://i.sstatic.net/gxPjs.png .\n\nThe server itself runs in normal mode, but it can't load the open API. If I remove the aforementioned formdata part - then everything works smoothly, but without Authorisation. I tried to debug it, but I have no success. I think it might be connected to a dependency graph or some start-up issues, but have no guess how to trace it back.\n\nHere is the full working example which will reproduce the error. The link points out the code which causes the problem. If you will comment out lines 18-39 - the docs will open without any problems.\nhttps://github.com/BEEugene/fastapi_error_demo/blob/master/fastapi_service/api/api_v1/endpoints/login.py\n\nAny ideas on how to debug or why this error happens?\n\n========================================\n\nTop Answer:\nI had the same problem. For me it was because I had code like this\n\n```\nfrom pydantic import BaseModel\n\nclass A(BaseModel):\n b: B\n\nclass B(BaseModel):\n c: int\n```\n\nbut instead, `Class B` **should have been defined above class A**. This fixed it:\n\n```\nfrom pydantic import BaseModel\n\nclass B(BaseModel):\n c: int\n\nclass A(BaseModel):\n b: B\n```\n\nMore info: https://stackoverflow.com/a/70384637/9439097\n\n### Regarding your original question on how to debug these or similar errors:\n\nYou probably have your routes defined somewhere. Comment all of your routers/routes out, then the openapi docs should generate (and they should show you have no routes. Then, enable the routes one by one and see which one causes the error. THis is how I debuged my situation.\n\n========================================\n\nCode:\n```text\n@router.post(\"/login/access-token\", response_model=schemas.Token)\ndef login_access_token(\n db: Session = Depends(deps.get_db), form_data: OAuth2PasswordRequestForm = Depends()) -> Any:\n```\n\n```text\nform_data: OAuth2PasswordRequestForm = Depends()\n```\n\n```text\nimport logging\nfrom fastapi import FastAPI\nfrom starlette.middleware.cors import CORSMiddleware\n\nfrom fastapi_service.api.api_v1.api import api_router\nfrom fastapi_service.core.config import settings\nfrom fastapi_service.core.event_handlers import (start_app_handler,\n stop_app_handler)\n\nlog = logging.getLogger(__name__)\n\ndef get_app(mode=\"prod\") -> FastAPI:\n\n fast_app = FastAPI(title=settings.PROJECT_NAME,\n version=settings.APP_VERSION,\n debug=settings.IS_DEBUG)\n # openapi_url=f\"{settings.API_V1_STR}/openapi.json\")\n # first time when I included the router\n fast_app.include_router(api_router, prefix=f\"{settings.API_V1_STR}\")\n fast_app.mode = mode\n logger = log.getChild(\"get_app\")\n logger.info(\"adding startup\")\n fast_app.add_event_handler(\"startup\", start_app_handler(fast_app))\n logger.info(\"adding shutdown\")\n fast_app.add_event_handler(\"shutdown\", stop_app_handler(fast_app))\n\n return fast_app\n\n\napp = get_app()\n\n# Set all CORS enabled origins\nif settings.BACKEND_CORS_ORIGINS:\n app.add_middleware(\n CORSMiddleware,\n allow_origins=[str(origin) for origin in settings.BACKEND_CORS_ORIGINS],\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n )\n# second time when I included the router\napp.include_router(api_router, prefix=settings.API_V1_STR)\n```\n\n```text\nfrom fastapi.security import OAuth2PasswordRequestForm\n```\n\n```text\nform_data: OAuth2PasswordRequestForm = Depends(OAuth2PasswordRequestForm)\n```\n\n```py\nfrom pydantic import BaseModel\n\nclass A(BaseModel):\n b: B\n\nclass B(BaseModel):\n c: int\n```\n\n```py\nfrom pydantic import BaseModel\n\nclass B(BaseModel):\n c: int\n\nclass A(BaseModel):\n b: B\n```\n\n```text\nClass B\n```\n\n```py\nKeyError: <class 'pydantic.main.Body_post_message_post_QA_chat_post'>\n```\n\n```text\nBody_post_message_post_QA_chat_post\n```\n\n```text\nBody_function-name_endpoint\n```\n\n```text\nfastapi[standard]==0.118.3\n```\n\n========================================\n\nComments:\n- How are you running the app?\n- @niko, I run it with this command `uvicorn app.main:app --reload --log-level debug --port 6008`\n- Have you tried running it via docker? I.e. `docker-compose up --build -d` (This is the intended usage afaik) If so, does the error persist?\n- @Chris, thank you for the comment. I added the link to the GitHub repository. This can be reproduced within a service, so I added the full version to test it.\n- Hi! Thank you, unfortunately, it didn't work.\n- @Alexander, Depends can be use both ways,when you use a fastapi class like `OAuth2PasswordRequestForm` you can use ``` form_data: OAuth2PasswordRequestForm = Depends() ``` it is what is suggest by the doc btw. Example: github.com/Bastien-BO/fastapi-RBAC-microservice/blob/main/ap‌​p/…\n- I will try that mode, if I am not mistaken I got an error when i used that way you suggest. Thanks for the link to read about it.\n- How should it help?","metadata":{"transformedAt":"2026-08-18T18:32:29.126Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":12,"totalLines":188,"estimatedTokens":1527}}374{"id":"stack-70694787","source":"stackoverflow","questionId":70694787,"title":"fastapi fastapi-users with Database adapter for SQLModel users table is not created","tags":["python","sqlalchemy","python-asyncio","fastapi","sqlmodel"],"text":"Title: fastapi fastapi-users with Database adapter for SQLModel users table is not created\nTags: python, sqlalchemy, python-asyncio, fastapi, sqlmodel\nSource: Stack Overflow\n\nQuestion:\nI was trying to use fastapi users package to quickly Add a registration and authentication system to my FastAPI project which uses the PostgreSQL database. I am using `asyncio` to be able to create asynchronous functions.\n\nIn the beginning, I used only sqlAlchemy and I have tried their example here. And I added those line of codes to my app/app.py to create the database at the starting of the server. and everything worked like a charm. the table users was created on my database.\n\n```\n@app.on_event(\"startup\")\nasync def on_startup():\n await create_db_and_tables()\n```\n\nSince I am using SQLModel I added FastAPI Users - Database adapter for SQLModel to my virtual en packages. And I added those lines to `fastapi_users/db/__init__.py` to be able to use the SQL model database.\n\n```\ntry:\n from fastapi_users_db_sqlmodel import ( # noqa: F401\n SQLModelBaseOAuthAccount,\n SQLModelBaseUserDB,\n SQLModelUserDatabase,\n )\nexcept ImportError: # pragma: no cover\n pass\n```\n\nI have also modified `app/users.py`, to use `SQLModelUserDatabase` instead of sqlAchemy one.\n\n```\nasync def get_user_manager(user_db: SQLModelUserDatabase = Depends(get_user_db)):\n yield UserManager(user_db)\n```\n\nand the `app/dp.py` to use `SQLModelUserDatabase`, `SQLModelBaseUserDB`, here is the full code of `app/db.py`\n\n```\nimport os\nfrom typing import AsyncGenerator\n\nfrom fastapi import Depends\nfrom sqlalchemy.ext.asyncio import AsyncSession, create_async_engine\nfrom sqlalchemy.orm import sessionmaker\n\nfrom fastapi_users.db import SQLModelUserDatabase, SQLModelBaseUserDB\nfrom sqlmodel import SQLModel\n\nfrom app.models import UserDB\n\nDATABASE_URL = os.environ.get(\"DATABASE_URL\")\n\nengine = create_async_engine(DATABASE_URL)\n\nasync_session_maker = sessionmaker(\n engine, class_=AsyncSession, expire_on_commit=False)\n\nasync def create_db_and_tables():\n async with engine.begin() as conn:\n await conn.run_sync(SQLModel.metadata.create_all)\n\nasync def get_async_session() -> AsyncSession:\n async_session = sessionmaker(\n engine, class_=AsyncSession, expire_on_commit=False\n )\n async with async_session() as session:\n yield session\n\nasync def get_user_db(session: AsyncSession = Depends(get_async_session)):\n yield SQLModelUserDatabase(UserDB, session, SQLModelBaseUserDB)\n```\n\nOnce I run the code, the table is not created at all. I wonder what could be the issue. I could not understand. Any idea?\n\n========================================\n\nTop Answer:\nI had the same problem, but managed to make it work by making a couple changes\n\nThe changes that I needed to make (code is based on the full example in the documentation):\n\n- In models.py, make `UserDB` inherit from `SQLModelBaseUserDB, User`, and add `table=True` for sqlmodel to create the table:\n\n```\nclass UserDB(SQLModelBaseUserDB, User, table=True):\n pass\n```\n\nIt's important that `SQLModelBaseUserDB` is inherited from first, because otherwise `User.id` trumps `SQLModelBaseUserDB.id` and sqlmodel cannot find `primary_key` column\n\n- Use `SQLModelUserDatabaseAsync` in `get_user_db`, like this (as far as I understand, you don't need to pass in SQLModelBaseUserDB in SQLModelUserDatabase. The third argument is for oauth account model):\n\n```\nasync def get_user_db(session: AsyncSession = Depends(get_async_session)):\n yield SQLModelUserDatabaseAsync(UserDB, session)\n```\n\n========================================\n\nCode:\n```py\n@app.on_event(\"startup\")\nasync def on_startup():\n await create_db_and_tables()\n```\n\n```py\ntry:\n from fastapi_users_db_sqlmodel import ( # noqa: F401\n SQLModelBaseOAuthAccount,\n SQLModelBaseUserDB,\n SQLModelUserDatabase,\n )\nexcept ImportError: # pragma: no cover\n pass\n```\n\n```py\nasync def get_user_manager(user_db: SQLModelUserDatabase = Depends(get_user_db)):\n yield UserManager(user_db)\n```\n\n```py\nimport os\nfrom typing import AsyncGenerator\n\nfrom fastapi import Depends\nfrom sqlalchemy.ext.asyncio import AsyncSession, create_async_engine\nfrom sqlalchemy.orm import sessionmaker\n\nfrom fastapi_users.db import SQLModelUserDatabase, SQLModelBaseUserDB\nfrom sqlmodel import SQLModel\n\n\nfrom app.models import UserDB\n\nDATABASE_URL = os.environ.get(\"DATABASE_URL\")\n\n\nengine = create_async_engine(DATABASE_URL)\n\nasync_session_maker = sessionmaker(\n engine, class_=AsyncSession, expire_on_commit=False)\n\n\nasync def create_db_and_tables():\n async with engine.begin() as conn:\n await conn.run_sync(SQLModel.metadata.create_all)\n\n\nasync def get_async_session() -> AsyncSession:\n async_session = sessionmaker(\n engine, class_=AsyncSession, expire_on_commit=False\n )\n async with async_session() as session:\n yield session\n\n\nasync def get_user_db(session: AsyncSession = Depends(get_async_session)):\n yield SQLModelUserDatabase(UserDB, session, SQLModelBaseUserDB)\n```\n\n```text\nasyncio\n```\n\n```text\nfastapi_users/db/__init__.py\n```\n\n```text\napp/users.py\n```\n\n```text\nSQLModelUserDatabase\n```\n\n```text\napp/dp.py\n```\n\n```text\nSQLModelUserDatabase\n```\n\n```text\nSQLModelBaseUserDB\n```\n\n```text\napp/db.py\n```\n\n```text\nfastapi-users\n```\n\n```text\nsqlAlchemy\n```\n\n```text\nUserDB\n```\n\n```text\nSQLModelBaseUserDB\n```\n\n```text\nSQLModel\n```\n\n```text\nfastapi-users-db-sqlmodel\n```\n\n```text\nSQLModel\n```\n\n```text\nUUID\n```\n\n```text\nclass UserDB(SQLModelBaseUserDB, User, table=True):\n pass\n```\n\n```text\nasync def get_user_db(session: AsyncSession = Depends(get_async_session)):\n yield SQLModelUserDatabaseAsync(UserDB, session)\n```\n\n```text\nUserDB\n```\n\n```text\nSQLModelBaseUserDB, User\n```\n\n```text\ntable=True\n```\n\n```text\nSQLModelBaseUserDB\n```\n\n```text\nUser.id\n```\n\n```text\nSQLModelBaseUserDB.id\n```\n\n```text\nprimary_key\n```\n\n```text\nSQLModelUserDatabaseAsync\n```\n\n```text\nget_user_db\n```\n\n========================================\n\nComments:\n- I'm having the same problem. Does `UserDB` inherit from the example `User` class defined in the `app/db.py` file from full example? (Which then inherits from `SQLAlchemyBaseUserTableUUID`)\n- Check my answer and the provided link please\n- I am getting an exception `type object 'User' has no attribute '__config__'` occurring when `app.database.User` is being imported. Is it correct to assume `class User(SQLAlchemyBaseUserTableUUID, Base)` here? Thanks.","metadata":{"transformedAt":"2026-08-18T18:32:29.127Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":31,"totalLines":278,"estimatedTokens":1603}}375{"id":"stack-75692370","source":"stackoverflow","questionId":75692370,"title":"FastAPI: How to customise 422 exception for specific route?","tags":["python","fastapi","pydantic","http-status-code-422"],"text":"Title: FastAPI: How to customise 422 exception for specific route?\nTags: python, fastapi, pydantic, http-status-code-422\nSource: Stack Overflow\n\nQuestion:\nHow to replace 422 standard exception with custom exception only for one route in FastAPI?\n\nI don't want to replace for the application project, just for one route. I read many docs, and I don't understand how to do this.\n\nExample of route that I need to change the `422` exception:\n\n```\nfrom fastapi import APIRouter\nfrom pydantic import BaseModel\n\nrouter = APIRouter()\n\nclass PayloadSchema(BaseModel):\n value_int: int\n value_str: str\n\n@router.post('/custom')\nasync def custom_route(payload: PayloadSchema):\n return payload\n```\n\n========================================\n\nTop Answer:\nDon't forget to register the custom exception handler only for the specific route:\n\n```\nfrom fastapi import APIRouter, FastAPI, HTTPException, Request\nfrom fastapi.exceptions import RequestValidationError\nfrom fastapi.responses import JSONResponse\nfrom pydantic import BaseModel\n\nrouter = APIRouter()\n\nclass PayloadSchema(BaseModel):\n value_int: int\n value_str: str\n\n@router.post('/custom')\nasync def custom_route(payload: PayloadSchema):\n return payload\n\nasync def custom_exception_handler(request: Request, exc: RequestValidationError):\n return JSONResponse({\"error\": \"Custom validation error message\"}, status_code=400)\n\napp = FastAPI()\napp.include_router(router)\n\napp.add_exception_handler(RequestValidationError, custom_exception_handler)\n```\n\n========================================\n\nCode:\n```py\nfrom fastapi import APIRouter\nfrom pydantic import BaseModel\n\nrouter = APIRouter()\n\n\nclass PayloadSchema(BaseModel):\n value_int: int\n value_str: str\n\n\n@router.post('/custom')\nasync def custom_route(payload: PayloadSchema):\n return payload\n```\n\n```text\n422\n```\n\n```text\nclass PayloadSchema(BaseModel):\n value_int: int\n value_str: str\n\nrouter = APIRouter()\n\n@router.post('/standard')\nasync def standard_route(payload: PayloadSchema):\n return payload\n\n@app.exception_handler(RequestValidationError)\nasync def standard_validation_exception_handler(request: Request, exc: RequestValidationError):\n return JSONResponse(\n status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,\n content=jsonable_encoder({\"detail\": exc.errors(), \"body\": exc.body}),\n )\n\n@router.post('/custom')\nasync def custom_route(payload: PayloadSchema):\n return payload\n\n@app.exception_handler(RequestValidationError)\nasync def custom_exception_handler(request: Request, exc: RequestValidationError):\n if (request.url.path == '/custom'):\n return JSONResponse({\"error\": \"Bad request, must be a valid PayloadSchema format\"}, status_code=400)\n else:\n return await standard_validation_exception_handler(request, exc)\n\napp = FastAPI()\napp.include_router(router)\napp.add_exception_handler(RequestValidationError, custom_exception_handler)\n```\n\n```text\n@app.exception_handler\n```\n\n```text\nfrom fastapi import APIRouter, FastAPI, HTTPException, Request\nfrom fastapi.exceptions import RequestValidationError\nfrom fastapi.responses import JSONResponse\nfrom pydantic import BaseModel\n\nrouter = APIRouter()\n\n\nclass PayloadSchema(BaseModel):\n value_int: int\n value_str: str\n\n\n@router.post('/custom')\nasync def custom_route(payload: PayloadSchema):\n return payload\n\n\nasync def custom_exception_handler(request: Request, exc: RequestValidationError):\n return JSONResponse({\"error\": \"Custom validation error message\"}, status_code=400)\n\n\napp = FastAPI()\napp.include_router(router)\n\napp.add_exception_handler(RequestValidationError, custom_exception_handler)\n```\n\n========================================\n\nComments:\n- I POST request to /custom route with no validation data, and response 422 error.\n- Ah, I see, didn't realize it was a validation error you were having the problem with. See update.\n- Interestingly in my test, removing that line made it stop working. Not sure why. But you're right, it should be redundant. Slightly disagree that it's a duplicate – even though the answers are similar, this is about custom error handling for a specific route.","metadata":{"transformedAt":"2026-08-18T18:32:29.127Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":5,"totalLines":153,"estimatedTokens":1029}}376{"id":"stack-71027304","source":"stackoverflow","questionId":71027304,"title":"Show description or comments for variables in FastAPI autodocs (Swagger UI)","tags":["swagger-ui","fastapi","openapi","pydantic"],"text":"Title: Show description or comments for variables in FastAPI autodocs (Swagger UI)\nTags: swagger-ui, fastapi, openapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI'm making a function and class for it with `POST` method.\n\nSince I use FastAPI, it automatically generates API docs (using OpenAPI specification and Swagger UI), where I can see the function's description or example data there.\n\nMy class and function are like below:\n\n```\nfrom pydantic import BaseModel, Field\nfrom typing import Optional, List\n\n@app.post(\"/user/item\")\ndef func1(args1: User, args2: Item):\n ...\n\nclass User(BaseModel):\n name: str\n state: List[str]\n\n class Config:\n schema_extra = {\n \"example\": {\n \"name\": \"Mike\",\n \"state\": [\"Texas\", \"Arizona\"]\n }\n }\n\n class Item(BaseModel):\n _id: int = Field(..., example=3, description=\"item id\")\n```\n\nThrough `schema_extra` and `example` attribute in `Field`, I can see the example value in `Request body` of function description.\n\nIt shows like\n\n```\n{\n \"args1\": {\n \"name\": \"Mike\",\n \"state\": [\"Texas\", \"Arizona\"] # state user visits. However, I'd like to add description or comments to `example value`, like # state user visits above.\n\nI've tried to add `description` attribute of `pydantic Field`, but I think it shows only for parameters of get method.\n\nIs there any way to do this? Any help will be appreciated.\n\n========================================\n\nCode:\n```py\nfrom pydantic import BaseModel, Field\nfrom typing import Optional, List\n\n\n@app.post(\"/user/item\")\ndef func1(args1: User, args2: Item):\n ...\n\n\nclass User(BaseModel):\n name: str\n state: List[str]\n\n class Config:\n schema_extra = {\n \"example\": {\n \"name\": \"Mike\",\n \"state\": [\"Texas\", \"Arizona\"]\n }\n }\n\n\n class Item(BaseModel):\n _id: int = Field(..., example=3, description=\"item id\")\n```\n\n```text\n{\n \"args1\": {\n \"name\": \"Mike\",\n \"state\": [\"Texas\", \"Arizona\"] # state user visits. <-- I'd like to add this here or in other place.\n },\n \"args2: {\n \"_id\": 3 <-- Here I can't description 'item id'\n }\n}\n```\n\n```text\nPOST\n```\n\n```text\nschema_extra\n```\n\n```text\nexample\n```\n\n```text\nField\n```\n\n```text\nRequest body\n```\n\n```text\nexample value\n```\n\n```text\ndescription\n```\n\n```text\npydantic Field\n```\n\n```python\nclass User(BaseModel):\n name: str = Field(..., description=\"Add user name\")\n state: List[str] = Field(..., description=\"State user visits\")\n\n class Config:\n schema_extra = {\n \"example\": {\n \"name\": \"Mike\",\n \"state\": [\"Texas\", \"Arizona\"]\n }\n }\n```\n\n```python\n@app.post(\"/user/item\")\nasync def update_item(\n user: User = Body(\n ...,\n examples={\n \"normal\": {\n \"summary\": \"A normal example\",\n \"description\": \"**name**: Add user name. **state**: State user vistis. \",\n \"value\": {\n \"name\": \"Mike\",\n \"state\": [\"Texas\", \"Arizona\"]\n },\n }\n }\n ),\n):\n return {\"user\": user}\n```\n\n```text\nJSON\n```\n\n```text\ndescription\n```\n\n```text\nBody\n```\n\n```text\nexample\n```\n\n```text\nexamples\n```\n\n```text\nQuery()\n```\n\n```text\nBody()\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.127Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":19,"totalLines":184,"estimatedTokens":812}}377{"id":"stack-76406637","source":"stackoverflow","questionId":76406637,"title":"How to add custom HTML content to FastAPI Swagger UI docs?","tags":["python","swagger","fastapi","swagger-ui","openapi"],"text":"Title: How to add custom HTML content to FastAPI Swagger UI docs?\nTags: python, swagger, fastapi, swagger-ui, openapi\nSource: Stack Overflow\n\nQuestion:\nI need to add a custom button in Swagger UI of my FastAPI application. I found this answer which suggest a good solution to add custom javascript to Swagger UI along with this documentations from FastAPI. But this solution only works for adding custom javascript code. I tried to add some HTML code for adding a new button to it using the swagger UI Authorise button style:\n\n```\ncustom_html = 'Authorize Google'\n\n@app.get(\"/docs\", include_in_schema=False)\nasync def custom_swagger_ui_html():\n return get_swagger_ui_html(\n openapi_url=app.openapi_url,\n title=app.title + \" - Swagger UI\",\n oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url,\n swagger_js_url=\"/static/swagger-ui-bundle.js\",\n swagger_css_url=\"/static/swagger-ui.css\",\n custom_js_url=google_custom_button,\n custom_html=custom_html,\n )\n\ndef get_swagger_ui_html(\n *,\n ...\n custom_html: Optional[str] = None,\n) -> HTMLResponse:\n\n ...\n\n html = f\"\"\"\n \n \n \n \n \n {title}\n \n \n \n {custom_html if custom_html else \"\"} # \n \"\"\"\n ....\n```\n\nBut looks like whatever I put between `` gets overwritten somehow and won't make it in the Swagger UI.\n\nHow to add custom HTML (in this case, buttons like Swagger's Authorise button) for specific needs in Swagger UI using FastAPI?\n\n**Update**\n\nIf I add the custom HTML outside of the `` I can see my custom button in Swagger UI like this:\n\nhttps://i.sstatic.net/dSZD4.png\n\nBut I would like to add my button where the original Authorise button is.\n\n========================================\n\nCode:\n```text\ncustom_html = '<div class=\"scheme-containerr\"><section class=\"schemes wrapper block col-12\"><div class=\"auth-wrapper\"><button class=\"btn authorize\"><span>Authorize Google</span><svg width=\"20\" height=\"20\"><use href=\"#unlocked\" xlink:href=\"#unlocked\"></use></svg></button></div></section></div>'\n\n@app.get(\"/docs\", include_in_schema=False)\nasync def custom_swagger_ui_html():\n return get_swagger_ui_html(\n openapi_url=app.openapi_url,\n title=app.title + \" - Swagger UI\",\n oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url,\n swagger_js_url=\"/static/swagger-ui-bundle.js\",\n swagger_css_url=\"/static/swagger-ui.css\",\n custom_js_url=google_custom_button,\n custom_html=custom_html,\n )\n\ndef get_swagger_ui_html(\n *,\n ...\n custom_html: Optional[str] = None,\n) -> HTMLResponse:\n\n ...\n\n html = f\"\"\"\n <!DOCTYPE html>\n <html>\n <head>\n <link type=\"text/css\" rel=\"stylesheet\" href=\"{swagger_css_url}\">\n <link rel=\"shortcut icon\" href=\"{swagger_favicon_url}\">\n <title>{title}</title>\n </head>\n <body>\n <div id=\"swagger-ui\">\n {custom_html if custom_html else \"\"} # <-- I added the HTML code here\n </div>\n \"\"\"\n ....\n```\n\n```text\n<div id=\"swagger-ui\"></div>\n```\n\n```text\n<div id=\"swagger-ui\"></div>\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi import Depends\nfrom fastapi.security import OpenIdConnect\nfrom fastapi.staticfiles import StaticFiles\nfrom fastapi.openapi.docs import (\n get_redoc_html,\n get_swagger_ui_oauth2_redirect_html,\n)\nfrom custom_swagger import get_swagger_ui_html\n\n\napp = FastAPI(docs_url=None) \napp.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")\noidc_google = OpenIdConnect(openIdConnectUrl='https://accounts.google.com/.well-known/openid-configuration')\n\n\n@app.get(\"/docs\", include_in_schema=False)\nasync def custom_swagger_ui_html():\n return get_swagger_ui_html(\n openapi_url=app.openapi_url,\n title=\"My API\",\n oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url,\n #swagger_js_url=\"/static/swagger-ui-bundle.js\", # Optional\n #swagger_css_url=\"/static/swagger-ui.css\", # Optional\n #swagger_favicon_url=\"/static/favicon-32x32.png\", # Optional\n custom_js_url=\"/static/custom_script.js\",\n )\n\n\n@app.get('/')\ndef main(token: str = Depends(oidc_google)):\n return \"You are Authenticated\"\n```\n\n```py\nimport json\nfrom typing import Any, Dict, Optional\nfrom fastapi.encoders import jsonable_encoder\nfrom fastapi.openapi.docs import swagger_ui_default_parameters\nfrom starlette.responses import HTMLResponse\n\ndef get_swagger_ui_html(\n *,\n openapi_url: str,\n title: str,\n swagger_js_url: str = \"https://cdn.jsdelivr.net/npm/swagger-ui-dist@4/swagger-ui-bundle.js\",\n swagger_css_url: str = \"https://cdn.jsdelivr.net/npm/swagger-ui-dist@4/swagger-ui.css\",\n swagger_favicon_url: str = \"https://fastapi.tiangolo.com/img/favicon.png\",\n oauth2_redirect_url: Optional[str] = None,\n init_oauth: Optional[Dict[str, Any]] = None,\n swagger_ui_parameters: Optional[Dict[str, Any]] = None,\n custom_js_url: Optional[str] = None,\n) -> HTMLResponse:\n current_swagger_ui_parameters = swagger_ui_default_parameters.copy()\n if swagger_ui_parameters:\n current_swagger_ui_parameters.update(swagger_ui_parameters)\n\n html = f\"\"\"\n <!DOCTYPE html>\n <html>\n <head>\n <link type=\"text/css\" rel=\"stylesheet\" href=\"{swagger_css_url}\">\n <link rel=\"shortcut icon\" href=\"{swagger_favicon_url}\">\n <title>{title}</title>\n </head>\n <body>\n <div id=\"swagger-ui\">\n </div>\n \"\"\"\n \n if custom_js_url:\n html += f\"\"\"\n <script src=\"{custom_js_url}\"></script>\n \"\"\"\n\n html += f\"\"\"\n <script src=\"{swagger_js_url}\"></script>\n <!-- `SwaggerUIBundle` is now available on the page -->\n <script>\n const ui = SwaggerUIBundle({{\n url: '{openapi_url}',\n \"\"\"\n\n for key, value in current_swagger_ui_parameters.items():\n html += f\"{json.dumps(key)}: {json.dumps(jsonable_encoder(value))},\\n\"\n\n if oauth2_redirect_url:\n html += f\"oauth2RedirectUrl: window.location.origin + '{oauth2_redirect_url}',\"\n\n html += \"\"\"\n presets: [\n SwaggerUIBundle.presets.apis,\n SwaggerUIBundle.SwaggerUIStandalonePreset\n ],\n })\"\"\"\n\n if init_oauth:\n html += f\"\"\"\n ui.initOAuth({json.dumps(jsonable_encoder(init_oauth))})\n \"\"\"\n\n html += \"\"\"\n </script>\n </body>\n </html>\n \"\"\"\n return HTMLResponse(html)\n```\n\n```js\nfunction waitForElm(selector) {\n return new Promise(resolve => {\n if (document.querySelector(selector)) {\n return resolve(document.querySelector(selector));\n }\n\n const observer = new MutationObserver(mutations => {\n if (document.querySelector(selector)) {\n resolve(document.querySelector(selector));\n observer.disconnect();\n }\n });\n\n observer.observe(document.body, {\n childList: true,\n subtree: true\n });\n });\n}\n\nwaitForElm('.auth-wrapper').then((elm) => {\n var authWrapper = document.getElementsByClassName(\"auth-wrapper\")[0];\n var btn = document.createElement(\"BUTTON\");\n btn.innerHTML = \"Click me\";\n btn.id = \"btn-id\";\n btn.onclick = function() {\n alert(\"button is clicked\");\n };\n authWrapper.append(btn);\n});\n```\n\n```js\nfunction waitForElm(selector) {\n // same as in the previous code snippet\n}\n\nwaitForElm('.auth-wrapper').then((elm) => {\n var authWrapper = document.getElementsByClassName(\"auth-wrapper\")[0];\n fetch('/static/button.html')\n .then(response => response.text())\n .then(text => {\n const newDiv = document.createElement(\"div\");\n newDiv.innerHTML = text;\n authWrapper.append(newDiv);\n });\n});\n```\n\n```html\n<button onclick=\"alert('button is clicked');\" class=\"btn authorize unlocked Google\">\n <span>Authorize Google</span>\n <svg width=\"20\" height=\"20\">\n <use href=\"#unlocked\" xlink:href=\"#unlocked\"></use>\n </svg>\n</button>\n```\n\n```py\n# ...\nfrom jinja2 import Environment, FileSystemLoader\n\ndef get_template():\n env = Environment(loader=FileSystemLoader('./static'))\n template = env.get_template('custom_script.js')\n context = {'msg': 'button is clicked!'}\n html = template.render(context)\n return html\n\n@app.get(\"/docs\", include_in_schema=False)\nasync def custom_swagger_ui_html():\n return get_swagger_ui_html(\n openapi_url=app.openapi_url,\n title=\"My API\",\n oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url,\n custom_js_content=get_template()\n )\n```\n\n```py\ndef get_swagger_ui_html(\n *,\n # ...\n custom_js_content: Optional[str] = None,\n) -> HTMLResponse:\n # ...\n \n if custom_js_content:\n html += f\"\"\"\n <script>{custom_js_content}</script>\n \"\"\"\n # ...\n```\n\n```js\nfunction waitForElm(selector) {\n // ...\n}\n\nwaitForElm('.auth-wrapper').then((elm) => {\n var authWrapper = document.getElementsByClassName(\"auth-wrapper\")[0];\n var btn = document.createElement(\"BUTTON\");\n btn.innerHTML = `\n <span>Authorize Google</span>\n <svg width=\"20\" height=\"20\">\n <use href=\"#unlocked\" xlink:href=\"#unlocked\"></use>\n </svg>\n `;\n btn.className = \"btn authorize unlocked Google\";\n btn.onclick = function() {\n alert(\"{{msg}}\");\n };\n authWrapper.append(btn);\n});\n```\n\n```js\nfunction waitForElm(selector) {\n // ...\n}\n\nwaitForElm('.auth-wrapper').then((elm) => {\n var authWrapper = document.getElementsByClassName(\"auth-wrapper\")[0];\n var html = `\n <button onclick=\"alert('{{msg}}');\" class=\"btn authorize unlocked Google\">\n <span>Authorize Google</span>\n <svg width=\"20\" height=\"20\">\n <use href=\"#unlocked\" xlink:href=\"#unlocked\"></use>\n </svg>\n </button>\n `;\n var newDiv = document.createElement(\"div\");\n newDiv.innerHTML = html;\n authWrapper.append(newDiv);\n});\n```\n\n```text\nget_swagger_ui_html()\n```\n\n```text\ncustom_script.js\n```\n\n```text\nAuthorize\n```\n\n```text\nWindow.load\n```\n\n```text\nget_swagger_ui_html()\n```\n\n```text\nmsg\n```\n\n========================================\n\nComments:\n- I think the original answer would work for you if you replace the click-handler on the `Authorize` button.\n- @MaximilianBurszley But I need multiple buttons\n- I believe FastAPI packages HTML that makes up the SwaggerUI. You could download that same file and make your changes to serve your custom version instead. Here is the relevant documentation.\n- @MaximilianBurszley Thanks, but that document only mentions the `js` and `css` files\n- Yes, that is why I mentioned \"packages HTML\". It looks like the actual HTML is an implementation detail within FastAPI, but you could grab that HTML using `get_swagger_ui_html()` and then modify *that* with the elements you need via XPath or other mechanisms.\n- What is the \"Authorize Google\" button in your example supposed to do? If the idea is to authorize API endpoints using Google OAuth or Google OpenID Connect, you might be able to achieve this behavior using OpenAPI's standard security scheme syntax (or whatever the FastAPI equivalent is).\n- For arbitrary customizations, you'll probably need to either write a Swagger UI plugin, or fork and modify Swagger UI code for your own use. In either case, you'll need to configure FastAPI to use your custom Swagger UI version instead of the bundled version.\n- @Helen Thanks for the tip. The problem with the standard security flow is you can only use one oidc provider because swagger supports only one `client_id`. but anyway that's another discussion\n- I gave it a try, it's working but needs a little change, because `.auth-wrapper` won't exists if you don't add any built-in authorise button from Swagger UI. So I had to find the div with `.information-container` class and insert a div with `.scheme-container` class after it.","metadata":{"transformedAt":"2026-08-18T18:32:29.127Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":18,"totalLines":391,"estimatedTokens":2913}}378{"id":"stack-75308496","source":"stackoverflow","questionId":75308496,"title":"How do I run uvicorn in a docker container that exposes the port?","tags":["python","docker","fastapi","uvicorn"],"text":"Title: How do I run uvicorn in a docker container that exposes the port?\nTags: python, docker, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI am developing a fastapi inside a docker container in windows/ubuntu (code below). When I test the app outside the container by running *python -m uvicorn app:app --reload* in the terminal and then navigating to *127.0.0.1:8000/home* everything works fine:\n\n```\n{\n Data: \"Test\"\n}\n```\n\nHowever, when I *docker-compose up* I can neither run *python -m uvicorn app:app --reload* in the container (due to the port already being used), nor see anything returned in the browser. I have tried 127.0.0.1:8000/home, host.docker.internal:8000/home and localhost:8000/home and I always receive:\n\n```\n{\n detail: \"Not Found\"\n}\n```\n\nWhat step am I missing?\n\nDockerfile:\n\n```\nFROM python:3.8-slim\n\nEXPOSE 8000\n\nENV PYTHONDONTWRITEBYTECODE=1\n\nENV PYTHONUNBUFFERED=1\n\nCOPY requirements.txt .\nRUN python -m pip install -r requirements.txt\n\nWORKDIR /app\nCOPY . /app\n\nRUN adduser -u nnnn --disabled-password --gecos \"\" appuser && chown -R appuser /app\nUSER appuser\n\nCMD [\"gunicorn\", \"--bind\", \"0.0.0.0:8000\", \"-k\", \"uvicorn.workers.UvicornWorker\", \"app:app\"]\n```\n\nDocker-compose:\n\n```\nversion: '3.9'\n\nservices:\n fastapitest:\n image: fastapitest\n build:\n context: .\n dockerfile: ./Dockerfile\n ports:\n - 8000:8000\n extra_hosts:\n - \"host.docker.internal:host-gateway\"\n```\n\napp.py:\n\n```\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/home\") #must be one line above the function fro the route\ndef home():\n return {\"Data\": \"Test\"}\n\nif __name__ == '__main__':\n import uvicorn\n uvicorn.run(app, host=\"127.0.0.1\", port=8000)\n```\n\n========================================\n\nCode:\n```text\n{\n Data: \"Test\"\n}\n```\n\n```text\n{\n detail: \"Not Found\"\n}\n```\n\n```text\nFROM python:3.8-slim\n\nEXPOSE 8000\n\nENV PYTHONDONTWRITEBYTECODE=1\n\nENV PYTHONUNBUFFERED=1\n\nCOPY requirements.txt .\nRUN python -m pip install -r requirements.txt\n\nWORKDIR /app\nCOPY . /app\n\nRUN adduser -u nnnn --disabled-password --gecos \"\" appuser && chown -R appuser /app\nUSER appuser\n\nCMD [\"gunicorn\", \"--bind\", \"0.0.0.0:8000\", \"-k\", \"uvicorn.workers.UvicornWorker\", \"app:app\"]\n```\n\n```text\nversion: '3.9'\n\nservices:\n fastapitest:\n image: fastapitest\n build:\n context: .\n dockerfile: ./Dockerfile\n ports:\n - 8000:8000\n extra_hosts:\n - \"host.docker.internal:host-gateway\"\n```\n\n```text\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/home\") #must be one line above the function fro the route\ndef home():\n return {\"Data\": \"Test\"}\n\nif __name__ == '__main__':\n import uvicorn\n uvicorn.run(app, host=\"127.0.0.1\", port=8000)\n```\n\n```text\nhost=\"127.0.0.1\"\n```\n\n```text\nuvicorn\n```\n\n```text\nhost=\"0.0.0.0\"\n```\n\n```text\nhttp://localhost:8000\n```\n\n========================================\n\nComments:\n- I am using docker version 20.10.22","metadata":{"transformedAt":"2026-08-18T18:32:29.127Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":164,"estimatedTokens":716}}379{"id":"stack-65263792","source":"stackoverflow","questionId":65263792,"title":"Replace server name with fake server name in response header in fastapi","tags":["python-3.x","fastapi"],"text":"Title: Replace server name with fake server name in response header in fastapi\nTags: python-3.x, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am using uvicorn as server to run app using fast api. While executing endpoint url in Swagger, following message is shown in response header of server response.\n\n```\ncontent-length: 122 \n content-type: application/json \n date: Sat12 Dec 2020 10:18:55 GMT \n server: uvicorn\n```\n\nHow to change server name to new name as server : firstproject?\nFollowing code concatenates server name unciorn with new name\n\n```\n@app.middleware(\"http\")\nasync def add_custom_header(request, call_next):\n response = await call_next(request)\n response.headers['server'] = 'firstproject'\n return response\n```\n\nThis gives the following output\n\n```\ncontent-length: 122 \n content-type: application/json \n date: Sat12 Dec 2020 10:19:33 GMT \n server: uvicornfirstproject\n```\n\nHow to change server name to server : firstproject in response header?\n\n**EDIT**\n\nIn start_server.py\n\n```\nimport uvicorn\n\nfrom app.main import app\n\nif __name__ == \"__main__\":\n uvicorn.run(\"start_server:app --header server:firstproject\", host=\"0.0.0.0\", port=8000, reload=True)\n```\n\ngives following error\n\n```\nINFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)\nINFO: Started reloader process [15256] using statreload\nERROR: Error loading ASGI app. Attribute \"app --header server:firstproject\" not found in module \"start_server\".\n```\n\nI run the code from Visual studio\n\n========================================\n\nTop Answer:\nIn case of you need to \"delete\" the \"server\" header, you can use option `--no-server-header`\n\n```\nuvicorn my_app:app --no-server-header\n```\n\nIf you are running uvicorn from a python file:\n\n```\nif __name__ == '__main__':\n uvicorn.run('my_app:app', server_header=False)\n```\n\n========================================\n\nCode:\n```text\ncontent-length: 122 \n content-type: application/json \n date: Sat12 Dec 2020 10:18:55 GMT \n server: uvicorn\n```\n\n```text\n@app.middleware(\"http\")\nasync def add_custom_header(request, call_next):\n response = await call_next(request)\n response.headers['server'] = 'firstproject'\n return response\n```\n\n```text\ncontent-length: 122 \n content-type: application/json \n date: Sat12 Dec 2020 10:19:33 GMT \n server: uvicornfirstproject\n```\n\n```text\nimport uvicorn\n\nfrom app.main import app\n\nif __name__ == \"__main__\":\n uvicorn.run(\"start_server:app --header server:firstproject\", host=\"0.0.0.0\", port=8000, reload=True)\n```\n\n```text\nINFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)\nINFO: Started reloader process [15256] using statreload\nERROR: Error loading ASGI app. Attribute \"app --header server:firstproject\" not found in module \"start_server\".\n```\n\n```sh\nuvicorn my_app:app --header server:firstproject\n```\n\n```py\nif __name__ == \"__main__\":\n uvicorn.run(\"my_app:app\", headers=[(\"server\", \"firstproject\")])\n```\n\n```text\n--header TEXT\n```\n\n```text\nuvicorn my_app:app --no-server-header\n```\n\n```text\nif __name__ == '__main__':\n uvicorn.run('my_app:app', server_header=False)\n```\n\n```text\n--no-server-header\n```\n\n========================================\n\nComments:\n- I have edited question to show error after adding as you suggest .\n- You are running it wrong, i updated my answer.\n- It worked in localhost. When I push same code to Linode and run then again uvicorn is shown in server name instead of fake server name firstproject\n- Hmm, it's strange. Are you load balancing the traffic between two revisions?\n- Sorry .I got response in linode too after adding both passing tuple (python code) and uvicorn my_app:app --header server:firstproject (during run) Thank you for quick response","metadata":{"transformedAt":"2026-08-18T18:32:29.127Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":11,"totalLines":149,"estimatedTokens":921}}380{"id":"stack-75165351","source":"stackoverflow","questionId":75165351,"title":"How can I return progress_hook for yt_dlp using FastAPI to end user?","tags":["python","fastapi","yt-dlp"],"text":"Title: How can I return progress_hook for yt_dlp using FastAPI to end user?\nTags: python, fastapi, yt-dlp\nSource: Stack Overflow\n\nQuestion:\nRelevant portion of my code looks something like this:\n\n```\n@directory_router.get(\"/youtube-dl/{relative_path:path}\", tags=[\"directory\"])\ndef youtube_dl(relative_path, url, name=\"\"):\n \"\"\"\n Download\n \"\"\"\n\n relative_path, _ = set_path(relative_path)\n\n logger.info(f\"{DATA_PATH}{relative_path}\")\n\n if name:\n name = f\"{DATA_PATH}{relative_path}/{name}.%(ext)s\"\n else:\n name = f\"{DATA_PATH}{relative_path}/%(title)s.%(ext)s\"\n\n ydl_opts = {\n \"outtmpl\": name,\n # \"quiet\": True\n \"logger\": logger,\n \"progress_hooks\": [yt_dlp_hook],\n # \"force-overwrites\": True\n }\n\n with yt.YoutubeDL(ydl_opts) as ydl:\n try:\n ydl.download([url])\n except Exception as exp:\n logger.info(exp)\n return str(exp)\n```\n\nI am using this webhook/end point to allow an angular app to accept url/name input and download file to folder. I am able to logger.info .. etc. output the values of the yt_dlp_hook, something like this:\n\n```\ndef yt_dlp_hook(download):\n \"\"\"\n download Hook\n\n Args:\n download (_type_): _description_\n \"\"\"\n\n global TMP_KEYS\n\n if download.keys() != TMP_KEYS:\n logger.info(f'Status: {download[\"status\"]}')\n logger.info(f'Dict Keys: {download.keys()}')\n TMP_KEYS = download.keys()\n logger.info(download)\n```\n\nIs there a way to stream a string of relevant variables like ETA, download speed etc. etc. to the front end? Is there a better way to do this?\n\n========================================\n\nCode:\n```text\n@directory_router.get(\"/youtube-dl/{relative_path:path}\", tags=[\"directory\"])\ndef youtube_dl(relative_path, url, name=\"\"):\n \"\"\"\n Download\n \"\"\"\n\n relative_path, _ = set_path(relative_path)\n\n logger.info(f\"{DATA_PATH}{relative_path}\")\n\n if name:\n name = f\"{DATA_PATH}{relative_path}/{name}.%(ext)s\"\n else:\n name = f\"{DATA_PATH}{relative_path}/%(title)s.%(ext)s\"\n\n ydl_opts = {\n \"outtmpl\": name,\n # \"quiet\": True\n \"logger\": logger,\n \"progress_hooks\": [yt_dlp_hook],\n # \"force-overwrites\": True\n }\n\n with yt.YoutubeDL(ydl_opts) as ydl:\n try:\n ydl.download([url])\n except Exception as exp:\n logger.info(exp)\n return str(exp)\n```\n\n```text\ndef yt_dlp_hook(download):\n \"\"\"\n download Hook\n\n Args:\n download (_type_): _description_\n \"\"\"\n\n global TMP_KEYS\n\n if download.keys() != TMP_KEYS:\n logger.info(f'Status: {download[\"status\"]}')\n logger.info(f'Dict Keys: {download.keys()}')\n TMP_KEYS = download.keys()\n logger.info(download)\n```\n\n```py\nimport asyncio\nfrom functools import partial\nimport threading\nfrom youtube_dl import YoutubeDL\nfrom queue import LifoQueue, Empty\n\n\ndef main():\n # Set the url to download\n url = \"https://www.youtube.com/watch?v=dQw4w9WgXcQ\"\n\n # Get the current event loop\n loop = asyncio.get_event_loop()\n\n # Create a Last In First Out Queue to communicate between the threads\n queue = LifoQueue()\n\n # Create the future which will be marked as done once the file is downloaded\n coros = [youtube_dl(url, queue)]\n future = asyncio.gather(*coros)\n\n # Start a new thread to run the loop_in_thread function (with the positional arguments passed to it)\n t = threading.Thread(target=loop_in_thread, args=[loop, future])\n t.start()\n\n # While the future isn't finished yet continue\n while not future.done():\n try:\n # Get the latest status update from the que and print it\n data = queue.get_nowait()\n print(data)\n except Empty as e:\n print(\"no status updates available\")\n finally:\n # Sleep between checking for updates\n asyncio.run(asyncio.sleep(0.1))\n\n\ndef loop_in_thread(loop, future):\n loop.run_until_complete(future)\n\n\nasync def youtube_dl(url, queue, name=\"temp.mp4\"):\n \"\"\"\n Download\n \"\"\"\n\n yt_dlp_hook_partial = partial(yt_dlp_hook, queue)\n\n ydl_opts = {\n \"outtmpl\": name,\n \"progress_hooks\": [yt_dlp_hook_partial],\n }\n with YoutubeDL(ydl_opts) as ydl:\n return ydl.download([url])\n\n\ndef yt_dlp_hook(queue: LifoQueue, download):\n \"\"\"\n download Hook\n\n Args:\n download (_type_): _description_\n \"\"\"\n # Instead of logging the data just add the latest data to the queue\n queue.put(download)\n\n\nif __name__ == \"__main__\":\n main()\n```\n\n========================================\n\nComments:\n- youtube.com/watch?v=dQw4w9WgXcQ Also, what do I do with the queue?\n- You can get the most recent item with queue.get and then process that data to display it on the front-end. It really depends what your setup looks from after this point. Essentially you'll want to pass in the queue and run it in the background while polling queue to get the status updates and update some value on the front end. If you want it livestreamed back to the user then you can look at this answer stackoverflow.com/questions/73913032/…\n- This may be a more applicable example shows how to stream content between flask and angular, so you open a socket and send a download start message of some sort and then stream back the status updates educba.com/flask-websocket","metadata":{"transformedAt":"2026-08-18T18:32:29.127Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":3,"totalLines":193,"estimatedTokens":1314}}381{"id":"stack-74654845","source":"stackoverflow","questionId":74654845,"title":"FastAPI RuntimeError: Use params or add_pagination","tags":["fastapi"],"text":"Title: FastAPI RuntimeError: Use params or add_pagination\nTags: fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm writing my second project on FastAPI. And I got this error.\nFor example I have this code in my routers.users.py:\n\n```\n@router.get('/', response_model=Page[Users])\nasync def get_all_users(db: Session = Depends(get_db)):\n return paginate(db.query(models.User).order_by(models.User.id))\n```\n\nAnd it works. It has fields limit and page in swagger documentation.\nI tried to write the same for routers.recipes.py, but in this case I have no fields for pagination(limit, page) in swagger. Ok, I googled and found out that adding dependencies could help me. And now I see pagination parameters in swagger, but error is still the same.\n\nrouters.recipes:\n\n```\n@router.get('/', response_model=Page[PostRecipes], dependencies=[Depends(Params)])\nasync def get_all_recipes(db: Session = Depends(get_db)):\n return paginate(db.query(models.Recipe).order_by(models.Recipe.id))\n```\n\npagination:\n\n```\nclass Params(BaseModel, AbstractParams):\n page: int = Query(1, ge=1, description=\"Page number\")\n limit: int = Query(50, ge=1, le=100, description=\"Page size\")\n\n def to_raw_params(self) -> RawParams:\n return RawParams(\n limit=self.limit,\n offset=self.limit * (self.page - 1),\n )\n\nclass Page(BasePage[T], Generic[T]):\n page: conint(ge=1) # type: ignore\n limit: conint(ge=1) # type: ignore\n\n __params_type__ = Params\n\n @classmethod\n def create(\n cls,\n items: Sequence[T],\n total: int,\n params: AbstractParams,\n ) -> Page[T]:\n if not isinstance(params, Params):\n raise ValueError(\"Page should be used with Params\")\n\n return cls(\n total=total,\n items=items,\n page=params.page,\n limit=params.limit,\n )\n\n__all__ = [\n \"Params\",\n \"Page\",\n]\n```\n\nSo, does anyone have ideas about it?\n\n========================================\n\nTop Answer:\nI ran into this problem earlier. In my case, I forgot to update the response_model for the paginated endpoint.\n\n```\n@router.get(\n \"\",\n summary=\"\",\n description=\"\",\n response_model=List[DealerModel], # type error here\n)\nasync def filter_companies(db: Session = Depends(get_db)):\n return paginate(crud.filter_companies(db))\n```\n\nShould be `response_model=Page[DealerModel],`\n\n========================================\n\nCode:\n```py\n@router.get('/', response_model=Page[Users])\nasync def get_all_users(db: Session = Depends(get_db)):\n return paginate(db.query(models.User).order_by(models.User.id))\n```\n\n```py\n@router.get('/', response_model=Page[PostRecipes], dependencies=[Depends(Params)])\nasync def get_all_recipes(db: Session = Depends(get_db)):\n return paginate(db.query(models.Recipe).order_by(models.Recipe.id))\n```\n\n```py\nclass Params(BaseModel, AbstractParams):\n page: int = Query(1, ge=1, description=\"Page number\")\n limit: int = Query(50, ge=1, le=100, description=\"Page size\")\n\n def to_raw_params(self) -> RawParams:\n return RawParams(\n limit=self.limit,\n offset=self.limit * (self.page - 1),\n )\n\n\nclass Page(BasePage[T], Generic[T]):\n page: conint(ge=1) # type: ignore\n limit: conint(ge=1) # type: ignore\n\n __params_type__ = Params\n\n @classmethod\n def create(\n cls,\n items: Sequence[T],\n total: int,\n params: AbstractParams,\n ) -> Page[T]:\n if not isinstance(params, Params):\n raise ValueError(\"Page should be used with Params\")\n\n return cls(\n total=total,\n items=items,\n page=params.page,\n limit=params.limit,\n )\n\n\n__all__ = [\n \"Params\",\n \"Page\",\n]\n```\n\n```py\napp = FastAPI()\n\napp.include_router(some_router)\n\n# This should be done after all calls to app.include_router()\nadd_pagination(app)\n```\n\n```text\nadd_pagination(app)\n```\n\n```text\npaginate(iterable, params)\n```\n\n```py\n@router.get(\n \"\",\n summary=\"\",\n description=\"\",\n response_model=List[DealerModel], # type error here\n)\nasync def filter_companies(db: Session = Depends(get_db)):\n return paginate(crud.filter_companies(db))\n```\n\n```text\nresponse_model=Page[DealerModel],\n```\n\n========================================\n\nComments:\n- same mistake here","metadata":{"transformedAt":"2026-08-18T18:32:29.127Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":8,"totalLines":180,"estimatedTokens":1033}}382{"id":"stack-70711245","source":"stackoverflow","questionId":70711245,"title":"Changing schema name in OpenAPI docs generated by FastAPI","tags":["python","openapi","fastapi","pydantic"],"text":"Title: Changing schema name in OpenAPI docs generated by FastAPI\nTags: python, openapi, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI'm using FastAPI to create backend for my project. I have a method that allows to upload a file. I implemented it as follows:\n\n```\nfrom fastapi import APIRouter, UploadFile, File\n\nfrom app.models.schemas.files import FileInResponse\n\nrouter = APIRouter()\n\n@router.post(\"\", name=\"files:create-file\", response_model=FileInResponse)\nasync def create(file: UploadFile = File(...)) -> FileInResponse:\n pass\n```\n\nAs you can see, I use a dedicated pydantic model for a method result—`FileInResponse`:\n\n```\nfrom pathlib import Path\n\nfrom pydantic import BaseModel\n\nclass FileInResponse(BaseModel):\n path: Path\n```\n\nAnd I this naming pattern for models (naming models as `InCreate`, `InResponse`, and so on) throughout the API. However, I couldn't create a pydantic model with a field of the type `File`, so I had to declare it directly in the route definition (i.e. without a model containing it). As a result, I have this long auto generated name `Body_files_create_file_api_files_post` in the OpenAPI docs:\n\nhttps://i.sstatic.net/6I4E7.png\n\nIs there a way to change the schema name?\n\n========================================\n\nTop Answer:\nI'm curious why you could not create a Pydantic model for the request (just like you did for the response). Something like this seems to work:\n\n```\nclass MyRequest(BaseModel):\n uploaded_file: UploadFile\n\n@router.post(\"\", name=\"files:create-file\", response_model=FileInResponse)\ndef create(req: typing.Annotated[MyRequest, Form()] -> FileInResponse: \n req.uploaded_file # get file...\n```\n\nThe OpenAPI schema name is now `MyRequest`.\n\n========================================\n\nCode:\n```py\nfrom fastapi import APIRouter, UploadFile, File\n\nfrom app.models.schemas.files import FileInResponse\n\nrouter = APIRouter()\n\n\n@router.post(\"\", name=\"files:create-file\", response_model=FileInResponse)\nasync def create(file: UploadFile = File(...)) -> FileInResponse:\n pass\n```\n\n```py\nfrom pathlib import Path\n\nfrom pydantic import BaseModel\n\n\nclass FileInResponse(BaseModel):\n path: Path\n```\n\n```text\nFileInResponse\n```\n\n```text\n<Entity>InCreate\n```\n\n```text\n<Entity>InResponse\n```\n\n```text\nFile\n```\n\n```text\nBody_files_create_file_api_files_post\n```\n\n```py\n@router.post(\n \"/{opportunity_id}/files\",\n status_code=status.HTTP_201_CREATED,\n)\nasync def attach_opportunity_file(\n db: Database,\n uploaded_file: UploadFile = File(title=\"File to upload\"),\n) -> OpportunityFile:\n pass\n```\n\n```py\n@router.post(\n \"/{opportunity_id}/files\",\n status_code=status.HTTP_201_CREATED,\n operation_id=\"attach_opportunity_file\", # New operation_id added \n)\nasync def attach_opportunity_file(\n db: Database,\n uploaded_file: UploadFile = File(title=\"File to upload\"),\n) -> OpportunityFile:\n pass\n```\n\n```text\noperation_id\n```\n\n```text\nclass MyRequest(BaseModel):\n uploaded_file: UploadFile\n\n@router.post(\"\", name=\"files:create-file\", response_model=FileInResponse)\ndef create(req: typing.Annotated[MyRequest, Form()] -> FileInResponse: \n req.uploaded_file # get file...\n```\n\n```text\nMyRequest\n```\n\n```py\nimport json\nfrom typing import Annotated\n\nfrom fastapi import FastAPI, Depends\nfrom fastapi.openapi.utils import get_openapi\nfrom fastapi.security import OAuth2PasswordRequestForm\nfrom pydantic import BaseModel\n\napp = FastAPI()\n\n\nclass AuthTokenOutMdl(BaseModel):\n access_token: str\n token_type: str\n\n\n@app.post(\"/auth/token\")\nasync def login(form_data: Annotated[OAuth2PasswordRequestForm, Depends()]) -> AuthTokenOutMdl:\n return AuthTokenOutMdl(access_token='XXXXX', token_type='bearer')\n\n\n# https://fastapi.tiangolo.com/how-to/extending-openapi/#overriding-the-defaults\ndef custom_openapi():\n if app.openapi_schema:\n return app.openapi_schema\n\n openapi_schema = get_openapi(\n title=\"Example\",\n version=\"0.1.0\",\n routes=app.routes\n )\n\n stupid_schema_name = 'Body_login_auth_token_post'\n better_schema_name = 'AuthTokenInMdl'\n\n # Dict to json string, replace the schema name, and back to dict\n openapi_schema = json.loads(json.dumps(openapi_schema).replace(stupid_schema_name, better_schema_name))\n\n # Sort the components schemas, because new name could not be sorted correctly\n openapi_schema['components']['schemas'] = dict(sorted(openapi_schema['components']['schemas'].items()))\n\n app.openapi_schema = openapi_schema\n\n return app.openapi_schema\n\n\napp.openapi = custom_openapi\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.127Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":13,"totalLines":189,"estimatedTokens":1135}}383{"id":"stack-76590705","source":"stackoverflow","questionId":76590705,"title":"Format string output to JSON","tags":["python","fastapi","structlog"],"text":"Title: Format string output to JSON\nTags: python, fastapi, structlog\nSource: Stack Overflow\n\nQuestion:\nI'm playing around with FastAPI and Structlog and wanted to test and convert log format from plain text/string to JSON format for better readability and processing by the log aggregator platforms. Facing a case where certain log output are available in JSON but rest in plain string.\n\nCurrent Output\n\n```\nINFO: 127.0.0.1:62154 - \"GET /api/preface HTTP/1.1\" 200 OK\nINFO: 127.0.0.1:62154 - \"GET /loader.json HTTP/1.1\" 200 OK\nINFO: 127.0.0.1:62155 - \"GET /hello_world HTTP/1.1\" 200 OK\n{\"key\":\"test_key\",\"message\":\"Push to NFS Success\",\"event\":\"Testing Fast API..\",\"logger\":\"test_my_api\",\"filename\":\"main.py\",\"func_name\":\"Hello_World\",\"process\":23760,\"module\":\"docker\",\"thread\":23140,\"pathname\":\"D:\\\\my_work\\\\fast_api\\\\main.py\",\"process_name\":\"SpawnProcess-1\",\"level\":\"info\",\"time-iso\":\"2023-06-30T15:25:03.113400Z\"}\n```\n\nExpected Output:\n\n```\n{\n \"level\": \"INFO\",\n \"IP\": \"127.0 .0 .1: 62154\",\n \"method\": \"GET\",\n \"endpoint\": \"/loader.json\",\n \"protocol\": \"HTTP / 1.1\",\n \"status_code\": 200,\n \"status\": \"OK\"\n}\n {\n \"level\": \"INFO\",\n \"IP\": \"127.0 .0 .1: 62155\",\n \"method\": \"GET\",\n \"endpoint\": \"/api/preface\",\n \"protocol\": \"HTTP / 1.1\",\n \"status_code\": 200,\n \"status\": \"OK\"\n}\n\n {\n \"level\": \"INFO\",\n \"IP\": \"127.0 .0 .1: 62155\",\n \"method\": \"GET\",\n \"endpoint\": \"/hello_world\",\n \"protocol\": \"HTTP / 1.1\",\n \"status_code\": 200,\n \"status\": \"OK\"\n}\n {\"key\":\"test_key\",\"message\":\"Push to NFS Success\",\"event\":\"Testing Fast API..\",\"logger\":\"test_my_api\",\"filename\":\"main.py\",\"func_name\":\"Hello_World\",\"process\":23760,\"module\":\"docker\",\"thread\":23140,\"pathname\":\"D:\\\\my_work\\\\fast_api\\\\main.py\",\"process_name\":\"SpawnProcess-1\",\"level\":\"info\",\"time-iso\":\"2023-06-30T15:25:03.113400Z\"}\n```\n\nWhat am I missing here ? thanks !\n\nstruct.py\n\n```\nimport orjson\nimport structlog\nimport logging\n\n## Added only the necessary context.\nclass StructLogTest:\n def __init__(self, logging_level=logging.DEBUG, logger_name=\"test\"):\n self.logging_level = logging_level\n self.logger_name = logger_name\n StructLogTest.logger_name_var = self.logger_name\n self.configure_structlog(self.logging_level, self.logger_name)\n\n def logger_name(_, __, event_dict):\n event_dict[\"test_log\"] = StructLogTest.logger_name_var\n return event_dict\n\n @staticmethod\n def configure_structlog(logging_level, logger_name):\n structlog.configure(\n processors=[\n StructLogTest.logger_name,\n structlog.threadlocal.merge_threadlocal,\n structlog.processors.CallsiteParameterAdder(),\n structlog.processors.add_log_level,\n structlog.stdlib.PositionalArgumentsFormatter(),\n structlog.processors.StackInfoRenderer(),\n structlog.processors.format_exc_info,\n structlog.processors.TimeStamper(fmt=\"iso\", utc=True, key=\"time-iso\"),\n structlog.processors.JSONRenderer(serializer=orjson.dumps),\n ],\n wrapper_class=structlog.make_filtering_bound_logger(logging_level),\n context_class=dict,\n logger_factory=structlog.BytesLoggerFactory(),\n )\n return structlog\n\n def define_Logger(self, *args, **kwargs):\n return structlog.get_logger(*args, **kwargs)\n\n def info(self, message, *args, **kwargs):\n return structlog.get_logger().info(message, *args, **kwargs)\n \n and other methods so on..\n```\n\nmain.py\n\n```\nfrom struct import StructLogTest\nfrom fastapi import APIRouter\nimport requests\nfrom requests.auth import HTTPBasicAuth\nfrom requests import Response\n\nlog = StructLogTest(logger_name=\"test_my_api\")\nlog = log.get_Logger()\n\n@router.get(\"/hello_world\")\ndef Hello_World():\n logg = log.bind(key=test_key)\n logg.info(\n \"Testing Fast API..\",\n message=some_other_meaningful_function.dump(),\n )\n return {\" Hello World !! \"}\n```\n\n========================================\n\nCode:\n```text\nINFO: 127.0.0.1:62154 - \"GET /api/preface HTTP/1.1\" 200 OK\nINFO: 127.0.0.1:62154 - \"GET /loader.json HTTP/1.1\" 200 OK\nINFO: 127.0.0.1:62155 - \"GET /hello_world HTTP/1.1\" 200 OK\n{\"key\":\"test_key\",\"message\":\"Push to NFS Success\",\"event\":\"Testing Fast API..\",\"logger\":\"test_my_api\",\"filename\":\"main.py\",\"func_name\":\"Hello_World\",\"process\":23760,\"module\":\"docker\",\"thread\":23140,\"pathname\":\"D:\\\\my_work\\\\fast_api\\\\main.py\",\"process_name\":\"SpawnProcess-1\",\"level\":\"info\",\"time-iso\":\"2023-06-30T15:25:03.113400Z\"}\n```\n\n```text\n{\n \"level\": \"INFO\",\n \"IP\": \"127.0 .0 .1: 62154\",\n \"method\": \"GET\",\n \"endpoint\": \"/loader.json\",\n \"protocol\": \"HTTP / 1.1\",\n \"status_code\": 200,\n \"status\": \"OK\"\n}\n {\n \"level\": \"INFO\",\n \"IP\": \"127.0 .0 .1: 62155\",\n \"method\": \"GET\",\n \"endpoint\": \"/api/preface\",\n \"protocol\": \"HTTP / 1.1\",\n \"status_code\": 200,\n \"status\": \"OK\"\n}\n\n {\n \"level\": \"INFO\",\n \"IP\": \"127.0 .0 .1: 62155\",\n \"method\": \"GET\",\n \"endpoint\": \"/hello_world\",\n \"protocol\": \"HTTP / 1.1\",\n \"status_code\": 200,\n \"status\": \"OK\"\n}\n {\"key\":\"test_key\",\"message\":\"Push to NFS Success\",\"event\":\"Testing Fast API..\",\"logger\":\"test_my_api\",\"filename\":\"main.py\",\"func_name\":\"Hello_World\",\"process\":23760,\"module\":\"docker\",\"thread\":23140,\"pathname\":\"D:\\\\my_work\\\\fast_api\\\\main.py\",\"process_name\":\"SpawnProcess-1\",\"level\":\"info\",\"time-iso\":\"2023-06-30T15:25:03.113400Z\"}\n```\n\n```text\nimport orjson\nimport structlog\nimport logging\n\n## Added only the necessary context.\nclass StructLogTest:\n def __init__(self, logging_level=logging.DEBUG, logger_name=\"test\"):\n self.logging_level = logging_level\n self.logger_name = logger_name\n StructLogTest.logger_name_var = self.logger_name\n self.configure_structlog(self.logging_level, self.logger_name)\n\n def logger_name(_, __, event_dict):\n event_dict[\"test_log\"] = StructLogTest.logger_name_var\n return event_dict\n\n\n @staticmethod\n def configure_structlog(logging_level, logger_name):\n structlog.configure(\n processors=[\n StructLogTest.logger_name,\n structlog.threadlocal.merge_threadlocal,\n structlog.processors.CallsiteParameterAdder(),\n structlog.processors.add_log_level,\n structlog.stdlib.PositionalArgumentsFormatter(),\n structlog.processors.StackInfoRenderer(),\n structlog.processors.format_exc_info,\n structlog.processors.TimeStamper(fmt=\"iso\", utc=True, key=\"time-iso\"),\n structlog.processors.JSONRenderer(serializer=orjson.dumps),\n ],\n wrapper_class=structlog.make_filtering_bound_logger(logging_level),\n context_class=dict,\n logger_factory=structlog.BytesLoggerFactory(),\n )\n return structlog\n\n def define_Logger(self, *args, **kwargs):\n return structlog.get_logger(*args, **kwargs)\n\n def info(self, message, *args, **kwargs):\n return structlog.get_logger().info(message, *args, **kwargs)\n \n and other methods so on..\n```\n\n```text\nfrom struct import StructLogTest\nfrom fastapi import APIRouter\nimport requests\nfrom requests.auth import HTTPBasicAuth\nfrom requests import Response\n\nlog = StructLogTest(logger_name=\"test_my_api\")\nlog = log.get_Logger()\n\n@router.get(\"/hello_world\")\ndef Hello_World():\n logg = log.bind(key=test_key)\n logg.info(\n \"Testing Fast API..\",\n message=some_other_meaningful_function.dump(),\n )\n return {\" Hello World !! \"}\n```\n\n```ini\n[loggers]\nkeys=root, uvicorn, gunicorn\n\n[handlers]\nkeys=access_handler\n\n[formatters]\nkeys=json\n\n[logger_root]\nlevel=INFO\nhandlers=access_handler\npropagate=1\n\n[logger_gunicorn]\nlevel=INFO\nhandlers=access_handler\npropagate=0\nqualname=gunicorn\n\n[logger_uvicorn]\nlevel=INFO\nhandlers=access_handler\npropagate=0\nqualname=uvicorn\n\n[handler_access_handler]\nclass=logging.StreamHandler\nformatter=json\nargs=()\n\n[formatter_json]\nclass=pythonjsonlogger.jsonlogger.JsonFormatter\n```\n\n```bash\nuvicorn --log-config=uvicorn-logconfig.ini main:router\n```\n\n```bash\n$ uvicorn --log-config=uvicorn-logconfig.ini main:router\n{\"message\": \"Started server process [54894]\", \"color_message\": \"Started server process [\\u001b[36m%d\\u001b[0m]\"}\n{\"message\": \"Waiting for application startup.\"}\n{\"message\": \"Application startup complete.\"}\n{\"message\": \"Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\", \"color_message\": \"Uvicorn running on \\u001b[1m%s://%s:%d\\u001b[0m (Press CTRL+C to quit)\"}\n{\"test_key\":\"test_val\",\"message\":\"some_message\",\"event\":\"Testing Fast API..\",\"pathname\":\"/private/tmp/s/main.py\",\"lineno\":42,\"process_name\":\"MainProcess\",\"func_name\":\"Hello_World\",\"filename\":\"main.py\",\"thread_name\":\"AnyIO worker thread\",\"thread\":12930912256,\"module\":\"main\",\"process\":54894,\"level\":\"info\",\"time-iso\":\"2023-07-02T19:22:58.085382Z\"}\n{\"message\": \"127.0.0.1:58519 - \\\"GET /hello_world HTTP/1.1\\\" 200\"}\n^C{\"message\": \"Shutting down\"}\n{\"message\": \"Waiting for application shutdown.\"}\n{\"message\": \"Application shutdown complete.\"}\n{\"message\": \"Finished server process [54894]\", \"color_message\": \"Finished server process [\\u001b[36m%d\\u001b[0m]\"}\n```\n\n```text\nlogging\n```\n\n```text\nuvicorn-logconfig.ini\n```\n\n```text\nlogging\n```\n\n```text\nlogging\n```\n\n========================================\n\nComments:\n- Does this answer your question?\n- @Chris : Thanks for the link, I'm trying to use structlog library. Expected output is not possible using structlog for the uvicorn logs ??\n- I'm not sure what your goal is, but the \"expected output\" you provide is not JSON. That means that regular JSON-processing tools won't work with it.\n- @UlrichEckhardt : I have formatted the expected output. Goal is to print the logs in JSON format instead of string based format, which is a default behavior Uvicorn. Catch is , whether it is possible using `structlog` logging framework ?\n- @Goku This is I bet the biggest gotcha of structlog, your application is using structlog but 3rd party libraries are using standard python logger. There is a way to workaround it as explained here: structlog.org/en/stable/…, pay special attention to this sentence: 'If you want all your log entries (i.e. also those not from your application / structlog) to be formatted as JSON, you can use the python-json-logger library:`. I.e. first configure your structlog, then configure standard logging to output via jsonformmater.\n- thanks that gave me an idea to develop further.","metadata":{"transformedAt":"2026-08-18T18:32:29.127Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":11,"totalLines":310,"estimatedTokens":2553}}384{"id":"stack-73968566","source":"stackoverflow","questionId":73968566,"title":"with Pydantic, how can i create my own ValidationError reason","tags":["python","fastapi","pydantic"],"text":"Title: with Pydantic, how can i create my own ValidationError reason\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nit seems impossible to set a regex constraint with a `__root__` field like this one:\n\n```\nclass Cars(BaseModel):\n __root__: Dict[str, CarData]\n```\n\nso, i've resorted to doing it at the endpoint:\n\n```\n@app.post(\"/cars\")\nasync def get_cars(cars: Cars = Body(...)):\n x = cars.json()\n y = json.loads(x)\n keys = list(y.keys())\n try:\n if any([re.search(r'^\\d+$', i) is None for i in keys]):\n raise ValidationError\n except ValidationError as ex:\n return 'wrong type'\n return 'works'\n```\n\nthis works well in that i get `wrong type` returned if i dont use a digit in the request body.\n\nbut i'd like to return something similar to what pydantic returns but with a custom message:\n\n```\n{\n \"detail\": [\n {\n \"loc\": [\n \"body\",\n \"__root__\",\n ],\n \"msg\": \"hey there, you can only use digits!\",\n \"type\": \"type_error.???\"\n }\n ]\n}\n```\n\n========================================\n\nTop Answer:\nThis will do:\n\n```\nfrom pydantic import ValidationError\nfrom pydantic.error_wrappers import ErrorWrapper\n\nprint(ValidationError(\n [\n ErrorWrapper(ValueError('Wrong car error 1.'), '/cars'), \n ErrorWrapper(ValueError('Wrong car error 2.'), '/cars')\n ], \n Cars\n))\n```\n\nYou should provide a list of python exceptions wrapped in `ErrorWrapper` as the first argument and validated model's class as the second. This way `pydantic` will generate the expected message for you:\n\n```\n2 validation errors for Cars\n/cars\n Wrong car error 1. (type=value_error)\n/cars\n Wrong car error 2. (type=value_error)\n```\n\n========================================\n\nCode:\n```text\nclass Cars(BaseModel):\n __root__: Dict[str, CarData]\n```\n\n```text\n@app.post(\"/cars\")\nasync def get_cars(cars: Cars = Body(...)):\n x = cars.json()\n y = json.loads(x)\n keys = list(y.keys())\n try:\n if any([re.search(r'^\\d+$', i) is None for i in keys]):\n raise ValidationError\n except ValidationError as ex:\n return 'wrong type'\n return 'works'\n```\n\n```text\n{\n \"detail\": [\n {\n \"loc\": [\n \"body\",\n \"__root__\",\n ],\n \"msg\": \"hey there, you can only use digits!\",\n \"type\": \"type_error.???\"\n }\n ]\n}\n```\n\n```text\n__root__\n```\n\n```text\nwrong type\n```\n\n```text\nraise ValidationError(\"Wrong data type\")\n```\n\n```text\nclass Cars(BaseModel):\n __root__: Dict[str, CarData]\n \n @pydantic.root_validator(pre=True)\n @classmethod\n def car_id_is_digit(cls, fields):\n car_ids = list(list(fields.values())[0].keys())\n print(car_ids)\n if any([bool(re.search(r'^\\d+$', car_id)) == False for car_id in car_ids]):\n raise ValueError(\"car_id must be a string that is a digit.\")\n else:\n return fields\n```\n\n```text\nvalidator\n```\n\n```text\nroot_validator\n```\n\n```text\n__root__\n```\n\n```text\n__root__\n```\n\n```text\nfrom pydantic import ValidationError\nfrom pydantic.error_wrappers import ErrorWrapper\n\nprint(ValidationError(\n [\n ErrorWrapper(ValueError('Wrong car error 1.'), '/cars'), \n ErrorWrapper(ValueError('Wrong car error 2.'), '/cars')\n ], \n Cars\n))\n```\n\n```text\n2 validation errors for Cars\n/cars\n Wrong car error 1. (type=value_error)\n/cars\n Wrong car error 2. (type=value_error)\n```\n\n```text\nErrorWrapper\n```\n\n```text\npydantic\n```\n\n```text\nclass ValidationError(ValueError):\n \"\"\"\n `ValidationError` is the exception raised by `pydantic-core` when validation fails, it contains a list of errors\n which detail why validation failed.\n \"\"\"\n @classmethod\n def from_exception_data(\n cls,\n title: str,\n line_errors: list[InitErrorDetails],\n input_type: Literal['python', 'json'] = 'python',\n hide_input: bool = False,\n ) -> Self:\n \"\"\"\n Python constructor for a Validation Error.\n\n The API for constructing validation errors will probably change in the future,\n hence the static method rather than `__init__`.\n\n Arguments:\n title: The title of the error, as used in the heading of `str(validation_error)`\n line_errors: A list of [`InitErrorDetails`][pydantic_core.InitErrorDetails] which contain information\n about errors that occurred during validation.\n input_type: Whether the error is for a Python object or JSON.\n hide_input: Whether to hide the input value in the error message.\n \"\"\"\n```\n\n```text\nclass InitErrorDetails(_TypedDict):\n type: str | PydanticCustomError\n \"\"\"The type of error that occurred, this should be a \"slug\" identifier that changes rarely or never.\"\"\"\n loc: _NotRequired[tuple[int | str, ...]]\n \"\"\"Tuple of strings and ints identifying where in the schema the error occurred.\"\"\"\n input: _Any\n \"\"\"The input data at this `loc` that caused the error.\"\"\"\n ctx: _NotRequired[dict[str, _Any]]\n \"\"\"\n Values which are required to render the error message, and could hence be useful in rendering custom error messages.\n Also useful for passing custom error data forward.\n \"\"\"\n```\n\n```text\nclass PydanticCustomError(ValueError):\n \"\"\" [...skipping docstring] \"\"\"\ndef __init__(\n self, error_type: LiteralString, message_template: LiteralString, context: dict[str, Any] | None = None\n ) -> None:\n \"\"\"Initializes the `PydanticCustomError`.\n\n Arguments:\n error_type: The error type.\n message_template: The message template.\n context: The data to inject into the message template.\n \"\"\"\n```\n\n```text\nfrom pydantic import ValidationError\nfrom pydantic_core import PydanticCustomError\n\nraise ValidationError.from_exception_data(\n title='ErrorTitle',\n line_errors=[\n {'type': PydanticCustomError('CustomError', 'CustomMessage'), 'input': None}\n ]\n)\n```\n\n```text\nTraceback (most recent call last):\nFile \"/home/marco/temp.py\", line 4, in <module>\nraise ValidationError.from_exception_data(\n...<2 lines>...\n)\npydantic_core._pydantic_core.ValidationError: 1 validation error for ErrorTitle\nCustomMessage [type=CustomError, input_value=None, input_type=NoneType]\n```\n\n```text\nValidationError\n```\n\n```text\npydantic\n```\n\n```text\n__init__\n```\n\n```text\nValidationError.from_exception_data\n```\n\n```text\nline_errors\n```\n\n```text\nlist[InitErrorDetails]\n```\n\n```text\nInitErrorDetails\n```\n\n```text\nTypedDict\n```\n\n```text\ninput\n```\n\n```text\ntype\n```\n\n```text\nPydanticCustomError\n```\n\n```text\nerror_type\n```\n\n```text\nmessage_template\n```\n\n```text\nValidationError\n```\n\n========================================\n\nComments:\n- Do you have an example of *what problem you're actually trying to solve*? i.e. it's unclear to me what `__root__: Dict[str, CarData]` is trying to do or validate.\n- Please have a look at related answers here, here, as well as here and here.\n- @MatsLindh basically trying to make sure that `str` is a digit (but really, testing regex), for example something like this `class Cars(BaseModel): __root__: Dict[str, CarData] @pydantic.validator(__root__) @classmethod def car_id_is_digit(cls, value): if re.search(r'^\\d+$', value): raise ValueError(\"car_id must be a string that is a digit.\")`\n- @Chris i appreciate this, and its helpful in general - but in this case i'm not sure it's possible to validate a `__root__` variable... unless you can point me in a better direction\n- This is incorrect. The Pydantic ValidationError class accepts a sequence of errors and the model which is getting validated. Your solution will raise a validation error, but it will be misleading and will not contain the string that you passed in.\n- `ErrorWrapper` is deprecated in Pydantic v2\n- @SaberHayati topic starter wasn't implying that he used Pydantic v2.\n- You should be able to get the same catching facilities with the `except*` notation from Python 3.11 docs.python.org/3/tutorial/…","metadata":{"transformedAt":"2026-08-18T18:32:29.127Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":34,"totalLines":332,"estimatedTokens":1964}}385{"id":"stack-72422403","source":"stackoverflow","questionId":72422403,"title":"Python SyntaxError: f-string: unmatched '['","tags":["python","fastapi"],"text":"Title: Python SyntaxError: f-string: unmatched '['\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\n```\nfrom fastapi import FastAPI\nfrom fastapi.params import Body\n\napp = FastAPI()\n\n@app.post(\"/createposts\")\ndef create_posts(payload: dict = Body(...)):\n print(payload)\n return {\"new_post\" : f\"title {payload[\"title\"]} content: {payload[\"content\"]}\"}\n```\n\nI'm trying to create an API with Fastapi, but every time I run the code I get this error related to the return statement: SyntaxError: f-string: unmatched '['\n\nThank you!\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nfrom fastapi.params import Body\n\napp = FastAPI()\n\n@app.post(\"/createposts\")\ndef create_posts(payload: dict = Body(...)):\n print(payload)\n return {\"new_post\" : f\"title {payload[\"title\"]} content: {payload[\"content\"]}\"}\n```\n\n```text\nreturn {\"new_post\" : f\"title {payload[\"title\"]} content: {payload[\"content\"]}\"}\n```\n\n```text\nreturn {\"new_post\" : f\"title {payload['title']} content: {payload['content']}\"}\n```\n\n```text\n\"\n```\n\n```text\nf\"...\"\n```\n\n```text\n[\n```\n\n========================================\n\nComments:\n- You could use `f'title ...'`. Just replace the double quotes with single at the start and end.\n- This is correct, however I did not expect such constraints to apply inside the curly brackets. It is code there after all.","metadata":{"transformedAt":"2026-08-18T18:32:29.127Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":6,"totalLines":61,"estimatedTokens":339}}386{"id":"stack-66596151","source":"stackoverflow","questionId":66596151,"title":"How to access APP properties inside my endpoint view function in FastAPI?","tags":["python","python-3.x","rest","fastapi"],"text":"Title: How to access APP properties inside my endpoint view function in FastAPI?\nTags: python, python-3.x, rest, fastapi\nSource: Stack Overflow\n\nQuestion:\nHere is my project structure:\n\n```\n│ .gitignore\n│ README.md\n│ requirements.txt\n│ start.py\n│\n├───app\n│ │ main.py\n│ │\n│ ├───apis\n│ │ └───v1\n│ │ │ __init__.py\n│ │ │\n│ │ │\n│ │ ├───routes\n│ │ │ │ evaluation_essentials.py\n│ │ │ │ training_essentials.py\n│ │ │\n│ │\n│ ├───models\n│ │ │ request_response_models.py\n│ │ │ __init__.py\n│ │ │\n```\n\nThis is what the outermost, `start.py` looks like:\n\n```\nimport uvicorn\n\nif __name__ == \"__main__\":\n\n from fastapi import Depends, FastAPI\n from app.apis.v1 import training_essentials, evaluation_essentials\n\n app = FastAPI(\n title=\"Some ML-API\",\n version=\"0.1\",\n description=\"API Contract for Some ML API\",\n extra=some_important_variable\n )\n\n app.include_router(training_essentials.router)\n app.include_router(evaluation_essentials.router)\n\n uvicorn.run(app, host=\"0.0.0.0\", port=60096)\n```\n\nAnd, all my endpoints and viewfunctions have been created in training_essentials.py and evaluation_essentials.py\nfor example, this is what training_essentials.py looks like:\n\n```\nfrom fastapi import APIRouter\nfrom fastapi import FastAPI, HTTPException, Query, Path\nfrom app.models import (\n TrainingCommencement,\n TrainingCommencementResponse,\n)\n\nrouter = APIRouter(\n tags=[\"Training Essentials\"],\n)\n\n@router.post(\"/startTraining\", response_model=TrainingCommencementResponse)\nasync def start_training(request_body: TrainingCommencement):\n logger.info(\"Starting the training process\")\n\n ## HOW TO ACCESS APP HERE?\n ## I WANT TO DO SOMETHING LIKE:\n ## some_important_variable = app.extra\n ## OR SOMETHING LIKE\n ## title = app.title\n\n return {\n \"status_url\": \"some-status-url\",\n }\n```\n\nHow do I access APP properties, its variables inside that viewfunction in my endpoint?\n\n========================================\n\nCode:\n```text\n│ .gitignore\n│ README.md\n│ requirements.txt\n│ start.py\n│\n├───app\n│ │ main.py\n│ │\n│ ├───apis\n│ │ └───v1\n│ │ │ __init__.py\n│ │ │\n│ │ │\n│ │ ├───routes\n│ │ │ │ evaluation_essentials.py\n│ │ │ │ training_essentials.py\n│ │ │\n│ │\n│ ├───models\n│ │ │ request_response_models.py\n│ │ │ __init__.py\n│ │ │\n```\n\n```py\nimport uvicorn\n\nif __name__ == \"__main__\":\n\n from fastapi import Depends, FastAPI\n from app.apis.v1 import training_essentials, evaluation_essentials\n\n app = FastAPI(\n title=\"Some ML-API\",\n version=\"0.1\",\n description=\"API Contract for Some ML API\",\n extra=some_important_variable\n )\n\n app.include_router(training_essentials.router)\n app.include_router(evaluation_essentials.router)\n\n uvicorn.run(app, host=\"0.0.0.0\", port=60096)\n```\n\n```py\nfrom fastapi import APIRouter\nfrom fastapi import FastAPI, HTTPException, Query, Path\nfrom app.models import (\n TrainingCommencement,\n TrainingCommencementResponse,\n)\n\nrouter = APIRouter(\n tags=[\"Training Essentials\"],\n)\n\n@router.post(\"/startTraining\", response_model=TrainingCommencementResponse)\nasync def start_training(request_body: TrainingCommencement):\n logger.info(\"Starting the training process\")\n\n ## HOW TO ACCESS APP HERE?\n ## I WANT TO DO SOMETHING LIKE:\n ## some_important_variable = app.extra\n ## OR SOMETHING LIKE\n ## title = app.title\n\n return {\n \"status_url\": \"some-status-url\",\n }\n```\n\n```text\nstart.py\n```\n\n```text\nfrom fastapi import Request\n\n\n@router.post(\"something\")\ndef some_view_function(request: Request):\n fast_api_app = request.app\n return {\"something\": \"foo\"}\n```\n\n```text\nrequest.app\n```\n\n========================================\n\nComments:\n- And if you want to access the app outside the function? like, just before `some_view_function`\n- Does that matter? It is not clear from where the arbitrary function `foo_bar(..)` gets called. Can you elaborate on the scenario?\n- Yes, for example, in main.app you set a variable. then in your entities folder, you declared a model of a object, where one of the fields have a default value equal to the value set in the main.app. For example `Item.name: str = Field(..., default=)`","metadata":{"transformedAt":"2026-08-18T18:32:29.128Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":6,"totalLines":187,"estimatedTokens":1052}}387{"id":"stack-71311507","source":"stackoverflow","questionId":71311507,"title":"ModuleNotFoundError: No module named 'app' fastapi docker","tags":["python","docker","fastapi"],"text":"Title: ModuleNotFoundError: No module named 'app' fastapi docker\nTags: python, docker, fastapi\nSource: Stack Overflow\n\nQuestion:\n```\nFROM python:3.8\nWORKDIR /app \n\nCOPY requirements.txt /\nRUN pip install --requirement /requirements.txt\n\nCOPY ./app /app\n\nEXPOSE 8000\nCMD [\"uvicorn\", \"app.main:app\", \"--host=0.0.0.0\" , \"--reload\" , \"--port\", \"8000\"]\n```\n\nwhen i used\n\n**docker-compose up -d**\n\nModuleNotFoundError: No module named 'app'\n\nthe folders in Fastapi framework:\n\nfastapi\n\napp\n\n-main.py\n\n```\nlanguage_detector.py\n```\n\nDockerfile\n\ndocker-compose\n\n========================================\n\nTop Answer:\nTry creating the /app folder before\n\n```\nFROM python:3.8\nRUN mkdir -p /app\nWORKDIR /app \n\nCOPY requirements.txt /\nRUN pip install --requirement /requirements.txt\n\nCOPY ./app /app\n\nEXPOSE 8000\nCMD [\"uvicorn\", \"app.main:app\", \"--host=0.0.0.0\" , \"--reload\" , \"--port\", \"8000\"]\n```\n\nAnd launching it:\n\ndocker-compose up --build\n\n========================================\n\nCode:\n```text\nFROM python:3.8\nWORKDIR /app \n\nCOPY requirements.txt /\nRUN pip install --requirement /requirements.txt\n\nCOPY ./app /app\n\nEXPOSE 8000\nCMD [\"uvicorn\", \"app.main:app\", \"--host=0.0.0.0\" , \"--reload\" , \"--port\", \"8000\"]\n```\n\n```text\nlanguage_detector.py\n```\n\n```text\nCMD [\"uvicorn\", \"main:app\", \"--host=0.0.0.0\" , \"--reload\" , \"--port\", \"8000\"]\n```\n\n```text\nFROM python:3.8\nRUN mkdir -p /app\nWORKDIR /app \n\nCOPY requirements.txt /\nRUN pip install --requirement /requirements.txt\n\nCOPY ./app /app\n\nEXPOSE 8000\nCMD [\"uvicorn\", \"app.main:app\", \"--host=0.0.0.0\" , \"--reload\" , \"--port\", \"8000\"]\n```\n\n========================================\n\nComments:\n- you need an `__index__.py` in your app folder i think ...\n- Can you show your docker-compose file?\n- the same error .","metadata":{"transformedAt":"2026-08-18T18:32:29.128Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":4,"totalLines":107,"estimatedTokens":438}}388{"id":"stack-63954442","source":"stackoverflow","questionId":63954442,"title":"How to parse unix timestamp into datetime without timezone in Fast API","tags":["python","python-datetime","fastapi","pydantic"],"text":"Title: How to parse unix timestamp into datetime without timezone in Fast API\nTags: python, python-datetime, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nAssume I have a pydantic model\n\n```\nclass EventEditRequest(BaseModel):\n uid: UUID\n name: str\n start_dt: datetime\n end_dt: datetime\n```\n\nI send request with body `b'{\"uid\":\"a38a7543-20ca-4a50-ab4e-e6a3ae379d3c\",\"name\":\"test event2222\",\"start_dt\":1600414328,\"end_dt\":1600450327}'`\n\nSo both `start_dt` and `end_dt` are unix timestamps. But in endpoint they become datetimes with timezones.\n\n```\n@app.put('...')\ndef edit_event(event_data: EventEditRequest):\n event_data.start_dt.tzinfo is not None # True\n```\n\nI don't want to manually edit `start_dt` and `end_dt` in the endpoint function to get rid of timezones. How can I set up my pydantic model so it will make datetime without timezones?\n\n========================================\n\nTop Answer:\nLike sashaaero mentions in their answer, you can achieve this with a custom type. But instead of creating your own validation, you could just use the existing validator from Pydantic and then just remove the timezone info.\n\n```\nfrom pydantic.datetime_parse import parse_datetime\n\nclass OffsetNaiveDatetime(datetime):\n\n @classmethod\n def __get_validators__(cls):\n yield cls.validate\n\n @classmethod\n def validate(cls, v):\n v = parse_datetime(v)\n v = v.replace(tzinfo=None)\n return v\n```\n\nBut be careful to only use it where timezone information is not needed at all or doesn't apply.\n\n========================================\n\nCode:\n```text\nclass EventEditRequest(BaseModel):\n uid: UUID\n name: str\n start_dt: datetime\n end_dt: datetime\n```\n\n```text\n@app.put('...')\ndef edit_event(event_data: EventEditRequest):\n event_data.start_dt.tzinfo is not None # True\n```\n\n```text\nb'{\"uid\":\"a38a7543-20ca-4a50-ab4e-e6a3ae379d3c\",\"name\":\"test event2222\",\"start_dt\":1600414328,\"end_dt\":1600450327}'\n```\n\n```text\nstart_dt\n```\n\n```text\nend_dt\n```\n\n```text\nstart_dt\n```\n\n```text\nend_dt\n```\n\n```text\nfrom datetime import datetime\n\nfrom pydantic import BaseModel, validator\n\n\nclass Model(BaseModel):\n dt: datetime = None\n\n\nclass ModelNaiveDt(BaseModel):\n dt: datetime = None\n\n @validator(\"dt\", pre=True)\n def dt_validate(cls, dt):\n return datetime.fromtimestamp(dt)\n\n\nprint(Model(dt=1600414328))\nprint(ModelNaiveDt(dt=1600414328))\n```\n\n```text\ndt=datetime.datetime(2020, 9, 18, 7, 32, 8, tzinfo=datetime.timezone.utc)\ndt=datetime.datetime(2020, 9, 18, 10, 32, 8)\n```\n\n```text\ndatetime\n```\n\n```text\nclass UnixDatetime(datetime):\n @classmethod\n def __get_validators__(cls):\n yield cls.validate\n\n @classmethod\n def validate(cls, v):\n if isinstance(v, datetime):\n print('Some request sends datetime not in UNIX format', file=sys.stderr)\n return v.replace(tzinfo=None)\n elif isinstance(v, int):\n return datetime.fromtimestamp(v)\n assert False, 'Datetime came of %s type' % type(v)\n```\n\n```py\nfrom pydantic.datetime_parse import parse_datetime\n\n\nclass OffsetNaiveDatetime(datetime):\n\n @classmethod\n def __get_validators__(cls):\n yield cls.validate\n\n @classmethod\n def validate(cls, v):\n v = parse_datetime(v)\n v = v.replace(tzinfo=None)\n return v\n```\n\n```text\nfrom datetime import datetime\nfrom pydantic import BaseModel, field_validator\n\nclass ModelWithDate(BaseModel):\n dt: datetime = None\n\n @field_validator('dt')\n @classmethod\n def remove_timezone(cls, dt) -> datetime:\n return dt.replace(tzinfo=None)\n```\n\n```text\ndatetime\n```\n\n```text\ntzinfo\n```\n\n========================================\n\nComments:\n- One solution I came to is to make middleware that will replace unix timestamp to datetime w/o timezone before it will become pydantic object. But it doesn't look the best solution to me.","metadata":{"transformedAt":"2026-08-18T18:32:29.128Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":15,"totalLines":176,"estimatedTokens":960}}389{"id":"stack-73564771","source":"stackoverflow","questionId":73564771,"title":"FastAPI is very slow in returning a large amount of JSON data","tags":["python","json","pandas","dataframe","fastapi"],"text":"Title: FastAPI is very slow in returning a large amount of JSON data\nTags: python, json, pandas, dataframe, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have a FastAPI `GET` endpoint that is returning a large amount of JSON data (~160,000 rows and 45 columns). Unsurprisingly, it is *extremely* slow to return the data using `json.dumps()`. I am first reading the data from a file using `json.loads()` and filtering it per the inputted parameters. Is there a faster way to return the data to the user than using `return data`? It takes nearly a minute in the current state.\n\nMy code currently looks like this:\n\n```\n# helper function to parse parquet file (where data is stored)\ndef parse_parquet(file_path):\n df = pd.read_parquet(file_path)\n result = df.to_json(orient = 'records')\n parsed = json.loads(result)\n return parsed\n \n\n@app.get('/endpoint')\n# has several more parameters\nasync def some_function(year = int | None = None, id = str | None = None):\n if year is None:\n data = parse_parquet(f'path/{year}_data.parquet')\n # no year\n if year is not None:\n data = parse_parquet(f'path/all_data.parquet')\n if id is not None:\n data = [d for d in data if d['id'] == id]\n return data\n```\n\n========================================\n\nTop Answer:\nI guess the `json.loads(result)` will return a dict data type in your case, and you are filtering the dict data type. You can send the dict data type as JSON as follows:\n\n```\nfrom fastapi.responses import JSONResponse\n\n@app.get('/endpoint')\n# has several more parameters\nasync def some_function(year = int | None = None, id = str | None = None):\n if year is None:\n data = parse_parquet(f'path/{year}_data.parquet')\n # no year\n if year is not None:\n data = parse_parquet(f'path/all_data.parquet')\n if id is not None:\n data = [d for d in data if d['id'] == id]\n return JSONResponse(content=json_compatible_item_data)\n```\n\n========================================\n\nCode:\n```py\n# helper function to parse parquet file (where data is stored)\ndef parse_parquet(file_path):\n df = pd.read_parquet(file_path)\n result = df.to_json(orient = 'records')\n parsed = json.loads(result)\n return parsed\n \n\n@app.get('/endpoint')\n# has several more parameters\nasync def some_function(year = int | None = None, id = str | None = None):\n if year is None:\n data = parse_parquet(f'path/{year}_data.parquet')\n # no year\n if year is not None:\n data = parse_parquet(f'path/all_data.parquet')\n if id is not None:\n data = [d for d in data if d['id'] == id]\n return data\n```\n\n```text\nGET\n```\n\n```text\njson.dumps()\n```\n\n```text\njson.loads()\n```\n\n```text\nreturn data\n```\n\n```py\nimport pandas as pd\nimport numpy as np\n\ncolumns = ['C' + str(i) for i in range(1, 46)]\ndf = pd.DataFrame(data=np.random.randint(99999, 99999999, size=(160000,45)),columns=columns)\ndf.to_parquet('data.parquet')\n```\n\n```py\nfrom fastapi import FastAPI, APIRouter, Response, Request\nfrom fastapi.routing import APIRoute\nfrom typing import Callable\nimport pandas as pd\nimport json\nimport time\nimport ujson\nimport orjson\n\n\nclass TimedRoute(APIRoute):\n def get_route_handler(self) -> Callable:\n original_route_handler = super().get_route_handler()\n\n async def custom_route_handler(request: Request) -> Response:\n before = time.time()\n response: Response = await original_route_handler(request)\n duration = time.time() - before\n response.headers[\"Response-Time\"] = str(duration)\n print(f\"route duration: {duration}\")\n return response\n\n return custom_route_handler\n\napp = FastAPI()\nrouter = APIRouter(route_class=TimedRoute)\n\n@router.get(\"/defaultFastAPIencoder\")\ndef get_data_default():\n df = pd.read_parquet('data.parquet') \n return df.to_dict(orient=\"records\")\n \n@router.get(\"/orjson\")\ndef get_data_orjson():\n df = pd.read_parquet('data.parquet')\n return Response(orjson.dumps(df.to_dict(orient='records')), media_type=\"application/json\")\n\n@router.get(\"/ujson\")\ndef get_data_ujson():\n df = pd.read_parquet('data.parquet') \n return Response(ujson.dumps(df.to_dict(orient='records')), media_type=\"application/json\")\n\n# Preferred way \n@router.get(\"/pandasJSON\")\ndef get_data_pandasJSON():\n df = pd.read_parquet('data.parquet') \n return Response(df.to_json(orient=\"records\"), media_type=\"application/json\") \n\napp.include_router(router)\n```\n\n```py\n@router.get(\"/download\")\ndef get_data():\n df = pd.read_parquet('data.parquet')\n headers = {'Content-Disposition': 'attachment; filename=\"data.json\"'}\n return Response(df.to_json(orient=\"records\"), headers=headers, media_type='application/json')\n```\n\n```text\nparse_parquet()\n```\n\n```text\ndf.to_json()\n```\n\n```text\njson.loads()\n```\n\n```text\njsonable_encoder\n```\n\n```text\njson.dumps()\n```\n\n```text\njsonable_encoder\n```\n\n```text\njson.dumps()\n```\n\n```text\nto_json()\n```\n\n```text\nResponse\n```\n\n```text\nAPIRoute\n```\n\n```text\n/pandasJSON\n```\n\n```text\nContent-Disposition\n```\n\n```text\nResponse\n```\n\n```text\nattachment\n```\n\n```text\nfilename\n```\n\n```text\nDask\n```\n\n```text\n.read_parquet()\n```\n\n```text\n.to_json()\n```\n\n```text\ndf.compute()\n```\n\n```text\ndf.to_json()\n```\n\n```text\n.to_json()\n```\n\n```text\n.to_csv()\n```\n\n```text\nfrom fastapi.responses import JSONResponse\n\n@app.get('/endpoint')\n# has several more parameters\nasync def some_function(year = int | None = None, id = str | None = None):\n if year is None:\n data = parse_parquet(f'path/{year}_data.parquet')\n # no year\n if year is not None:\n data = parse_parquet(f'path/all_data.parquet')\n if id is not None:\n data = [d for d in data if d['id'] == id]\n return JSONResponse(content=json_compatible_item_data)\n```\n\n```text\njson.loads(result)\n```\n\n========================================\n\nComments:\n- How much time does your `parse_parquet` function take?\n- @Jeril negligible time. The timing issue is on returning the data as a json\n- Have you seen stackoverflow.com/questions/72221272/… about how to use alternative json encoders?","metadata":{"transformedAt":"2026-08-18T18:32:29.128Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":32,"totalLines":276,"estimatedTokens":1507}}390{"id":"stack-64782008","source":"stackoverflow","questionId":64782008,"title":"How to use FastAPI Depends for endpoint/route in separate file?","tags":["python","dependency-injection","websocket","web-frameworks","fastapi"],"text":"Title: How to use FastAPI Depends for endpoint/route in separate file?\nTags: python, dependency-injection, websocket, web-frameworks, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have an Websocket endpoint defined in separate file, like:\n\n```\nfrom starlette.endpoints import WebSocketEndpoint\nfrom connection_service import ConnectionService\n\nclass WSEndpoint(WebSocketEndpoint):\n \"\"\"Handles Websocket connections\"\"\"\n\n async def on_connect(self,\n websocket: WebSocket,\n connectionService: ConnectionService = Depends(ConnectionService)):\n \"\"\"Handles new connection\"\"\"\n self.connectionService = connectionService\n ...\n```\n\nand in the `main.py` I register endpoint as:\n\n```\nfrom fastapi import FastAPI\nfrom starlette.routing import WebSocketRoute\nfrom ws_endpoint import WSEndpoint\n\napp = FastAPI(routes=[ WebSocketRoute(\"/ws\", WSEndpoint) ])\n```\n\nBut `Depends` for my endpoint is never resolved. Is there a way to make it work?\n\nPlus, what is even the purpose of this mechanism in FastAPI? Cannot we just use local/global variables?\n\n========================================\n\nTop Answer:\nAfter hours learning playing around with Dependency Injection and routes/endpoints in FastAPI here is what I found.\n\n### Route vs Endpoint\n\nFirst of all want to point out that `Endpoint` is a concept that exists in **Starlette** and no in **FastAPI**. In my question I show code where I use `WebSocketEndpoint` class and Dependency Injection will not work in FastAPI. Read further to understand why.\n\n### Dependency injection (DI)\n\nDI in FastAPI is not a classic pattern that we know, it is not resolving magically all dependencies everywhere.\n\n`Depends` is only resolved for FastAPI routes, meaning using methods: `add_api_route` and `add_api_websocket_route`, or their decorator analogs: `api_route` and `websocket`, which are just wrappers around first two.\n\nThen dependencies are going to be resolved when request comes to the route by FastAPI. This is important to understand that FastAPI is resolving dependencies and not Starlette. FastAPI is build on top of Starlette and you may want to use also some \"raw\" Starlette features, like: `add_route` or `add_websocket_route`, but then you **will not have `Depends` resolution** for those.\n\nAlso, DI in FastAPI can be used to resolve instances of classes but it's not its main purpose + it makes no sense in Python because you can just use **CLOSURE**. Where `Depends` shine is when you need some sort of request validation (what Django accomplishes with decorators). In this usage `Depends` is great, because it resolves `route` dependencies and those sub dependencies. Check out my code below and I use `auth_check`.\n\n### Code example\n\nAs a bonus I want to have websocket route as a class in separate file with separated methods for connect, disconnect and receive. Also, I want to have authentication check in separate file to be able to swap it in easily.\n\n```\n# main.py\nfrom fastapi import FastAPI\nfrom ws_route import WSRoute\n\napp = FastAPI()\napp.add_api_websocket_route(\"/ws\", WSRoute)\n```\n\n```\n# auth.py\nfrom fastapi import WebSocket\n\ndef auth_check(websocket: WebSocket):\n # `websocket` instance is resolved automatically\n # and other `Depends` as well. They are what's called sub dependencies.\n # Implement your authentication logic here:\n # Parse Headers or query parameters (which is usually a way for websockets)\n # and perform verification\n return True\n```\n\n```\n# ws_route.py\nimport typing\n\nimport starlette.status as status\nfrom fastapi import WebSocket, WebSocketDisconnect, Depends\n\nfrom auth import auth_check\n\nclass WSRoute:\n\n def __init__(self,\n websocket: WebSocket,\n is_authenticated: bool = Depends(auth_check)):\n self._websocket = websocket\n\n def __await__(self) -> typing.Generator:\n return self.dispatch().__await__()\n\n async def dispatch(self) -> None:\n # Websocket lifecycle\n await self._on_connect()\n\n close_code: int = status.WS_1000_NORMAL_CLOSURE\n try:\n while True:\n data = await self._websocket.receive_text()\n await self._on_receive(data)\n except WebSocketDisconnect:\n # Handle client normal disconnect here\n pass\n except Exception as exc:\n # Handle other types of errors here\n close_code = status.WS_1011_INTERNAL_ERROR\n raise exc from None\n finally:\n await self._on_disconnect(close_code)\n\n async def _on_connect(self):\n # Handle your new connection here\n await self._websocket.accept()\n pass\n\n async def _on_disconnect(self, close_code: int):\n # Handle client disconnect here\n pass\n\n async def _on_receive(self, msg: typing.Any):\n # Handle client messaging here\n pass\n```\n\n========================================\n\nCode:\n```py\nfrom starlette.endpoints import WebSocketEndpoint\nfrom connection_service import ConnectionService\n\n\nclass WSEndpoint(WebSocketEndpoint):\n \"\"\"Handles Websocket connections\"\"\"\n\n async def on_connect(self,\n websocket: WebSocket,\n connectionService: ConnectionService = Depends(ConnectionService)):\n \"\"\"Handles new connection\"\"\"\n self.connectionService = connectionService\n ...\n```\n\n```py\nfrom fastapi import FastAPI\nfrom starlette.routing import WebSocketRoute\nfrom ws_endpoint import WSEndpoint\n\napp = FastAPI(routes=[ WebSocketRoute(\"/ws\", WSEndpoint) ])\n```\n\n```text\nmain.py\n```\n\n```text\nDepends\n```\n\n```text\nfrom fastapi import Depends, FastAPI\n\napp = FastAPI()\n\n\nasync def foo_func():\n return \"This is from foo\"\n\n\nasync def test_depends(foo: str = Depends(foo_func)):\n return foo\n\n\n@app.get(\"/\")\nasync def read_items():\n depends_result = await test_depends()\n return depends_result\n```\n\n```text\nfrom starlette.endpoints import WebSocketEndpoint\nfrom connection_service import ConnectionService\n\n\nclass WSEndpoint(WebSocketEndpoint):\n async def on_connect(\n self,\n websocket: WebSocket,\n connectionService=None\n ):\n if connectionService is None:\n connectionService = ConnectionService() # calling the depend function\n\n self.connectionService = connectionService\n```\n\n```text\nDepends\n```\n\n```text\nDepends(...)\n```\n\n```py\n# main.py\nfrom fastapi import FastAPI\nfrom ws_route import WSRoute\n\napp = FastAPI()\napp.add_api_websocket_route(\"/ws\", WSRoute)\n```\n\n```py\n# auth.py\nfrom fastapi import WebSocket\n\ndef auth_check(websocket: WebSocket):\n # `websocket` instance is resolved automatically\n # and other `Depends` as well. They are what's called sub dependencies.\n # Implement your authentication logic here:\n # Parse Headers or query parameters (which is usually a way for websockets)\n # and perform verification\n return True\n```\n\n```py\n# ws_route.py\nimport typing\n\nimport starlette.status as status\nfrom fastapi import WebSocket, WebSocketDisconnect, Depends\n\nfrom auth import auth_check\n\nclass WSRoute:\n\n def __init__(self,\n websocket: WebSocket,\n is_authenticated: bool = Depends(auth_check)):\n self._websocket = websocket\n\n def __await__(self) -> typing.Generator:\n return self.dispatch().__await__()\n\n async def dispatch(self) -> None:\n # Websocket lifecycle\n await self._on_connect()\n\n close_code: int = status.WS_1000_NORMAL_CLOSURE\n try:\n while True:\n data = await self._websocket.receive_text()\n await self._on_receive(data)\n except WebSocketDisconnect:\n # Handle client normal disconnect here\n pass\n except Exception as exc:\n # Handle other types of errors here\n close_code = status.WS_1011_INTERNAL_ERROR\n raise exc from None\n finally:\n await self._on_disconnect(close_code)\n\n async def _on_connect(self):\n # Handle your new connection here\n await self._websocket.accept()\n pass\n\n async def _on_disconnect(self, close_code: int):\n # Handle client disconnect here\n pass\n\n async def _on_receive(self, msg: typing.Any):\n # Handle client messaging here\n pass\n```\n\n```text\nEndpoint\n```\n\n```text\nWebSocketEndpoint\n```\n\n```text\nDepends\n```\n\n```text\nadd_api_route\n```\n\n```text\nadd_api_websocket_route\n```\n\n```text\napi_route\n```\n\n```text\nwebsocket\n```\n\n```text\nadd_route\n```\n\n```text\nadd_websocket_route\n```\n\n```text\nDepends\n```\n\n```text\nDepends\n```\n\n```text\nDepends\n```\n\n```text\nroute\n```\n\n```text\nauth_check\n```\n\n```text\n# @app.websocket(\"/ws/hello/token\")\nasync def websocket_hello_endpoint_with_token(websocket: WebSocket, client_id: str = Query(..., alias=\"token\")):\n #on_connect\n await websocket.accept()\n try:\n while True:\n data = await websocket.receive_text()\n #on_receive\n await websocket.send_text(f\"Token: {client_id} & Message text was: {data}\")\n except WebSocketDisconnect:\n #on_disconnect\n pass\n```\n\n```text\napp = FastAPI()\napp.add_api_websocket_route(\"/ws/hello/token\", socket.websocket_hello_endpoint_with_token)\n```\n\n```text\n<!DOCTYPE html>\n<html>\n <head>\n <title>Chat</title>\n </head>\n <body>\n <h1>WebSocket Chat</h1>\n <form action=\"\" onsubmit=\"sendMessage(event)\">\n <label>Token: <input type=\"text\" id=\"token\" autocomplete=\"off\" value=\"some-key-token\"/></label>\n <button onclick=\"connect(event)\">Connect</button>\n <hr>\n <label>Message: <input type=\"text\" id=\"messageText\" autocomplete=\"off\"/></label>\n <button>Send</button>\n </form>\n <ul id='messages'>\n </ul>\n <script>\n var ws = null;\n function connect(event) {\n var token = document.getElementById(\"token\")\n ws = new WebSocket(\"ws://localhost:6003/ws/hello/token?token=\" + token.value);\n \n ws.onopen = function () {\n console.log('socket opened'); \n };\n ws.onmessage = function(event) {\n var messages = document.getElementById('messages')\n var message = document.createElement('li')\n var content = document.createTextNode(event.data)\n <!-- var data = document.createTextNode(event.data) -->\n <!-- var content = \"message:\" + data.message -->\n message.appendChild(content)\n messages.appendChild(message)\n };\n \n ws.onclose = function(e) { \n console.log('socket closed from server'); \n }\n\n ws.onerror = function(err) {\n console.error(err)\n };\n \n event.preventDefault()\n }\n function sendMessage(event) {\n var input = document.getElementById(\"messageText\")\n ws.send(input.value)\n input.value = ''\n event.preventDefault()\n }\n </script>\n </body>\n</html>\n```\n\n========================================\n\nComments:\n- Ooh, thank you, so it is mentioned in the documentation? I didn't pay attention to that. So, yes, you're right, the only place where Dependencies are resolved is in FastAPI add_api_route and add_api_websocket_route, or if used their decorator analogs. And you can define a function in one file and then register it in main and it will work fine. __ Although, I don't understand the purpose of this \"Dependency Injection\" mechanism in scope of FastAPI then, what does it solve?\n- I don't think they mentioned using `Depends()` ***only with requests***, but, I couldn't find any example that shows the opposite. So, I reached the above conclusion. Also, the example I have tried made me believe so.\n- They don't mention it, but this is the only way it works now as far as I saw. I can see it source code in `fastapi.applications.py` and if to put a breakpoint in `fastpi.dependencies.utils.get_dependant`\n- Actually, your code doesn't make much sense because there will be separate `WSEndpoint` instance per connection, so you always will hit `is None` check. Plus I wanted to use `ConnectionService` as singleton for all connections, but of course I can implement it separately with decorator or other methods.\n- *\"...I wanted to use ConnectionService as singleton for all connections\"* If you want to make it a singleton, can't it possible to define it out of the class?\n- Also, I was focusing on saying that the `Depends` won't work as you intended.\n- Thanks for the explanation. I was confused at first with FastAPI bc when I hear dependency injection, I think of containers and dependencies being injected/resolved anywhere but as you explained the dependency injection only works when starting at a FastAPI path operation, on a per-request basis. Being this is a server, it's not really a limitation as I first thought, it's just a pattern I am not used to.\n- You can find my answer below where I describe how I have managed design solution with working websocket endpoint. At the end it looks quite elegant I think.\n- @andnik WSRoute was auto disconnected, after connection\n- I need to look into your code, we are successfully using WSRoute on our project and it works fine. Maybe there is some syntax error. Try to debug to find what actually causing the disconnect. But if you want to use my version I can assure you it works.","metadata":{"transformedAt":"2026-08-18T18:32:29.128Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":28,"totalLines":433,"estimatedTokens":3329}}391{"id":"stack-63465155","source":"stackoverflow","questionId":63465155,"title":"How to return file from memory in fastapi StreamingResponse?","tags":["python-3.x","xlsxwriter","fastapi","bytesio"],"text":"Title: How to return file from memory in fastapi StreamingResponse?\nTags: python-3.x, xlsxwriter, fastapi, bytesio\nSource: Stack Overflow\n\nQuestion:\nI want to give xlsx on request. With using `BytesIO` and `xlsxwriter` I create a file.\n\nUsing the code below, I can download an empty(!) `.txt` file:\n\n```\n@router.get(\"/payments/xlsx\", response_description='xlsx')\nasync def payments():\n \"\"\"sss\"\"\"\n output = BytesIO()\n workbook = xlsxwriter.Workbook(output)\n worksheet = workbook.add_worksheet()\n worksheet.write(0, 0, 'ISBN')\n worksheet.write(0, 1, 'Name')\n worksheet.write(0, 2, 'Takedown date')\n worksheet.write(0, 3, 'Last updated')\n workbook.close()\n output.seek(0)\n return StreamingResponse(output)\n```\n\nIf I add `headers={'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}` I get this error in browser:\n\n```\nUnable to open file\nYou may be having a problem connecting with the server, or the file that you wanted to open was corrupted.\n```\n\nHow I can fix this?\n\n========================================\n\nCode:\n```text\n@router.get(\"/payments/xlsx\", response_description='xlsx')\nasync def payments():\n \"\"\"sss\"\"\"\n output = BytesIO()\n workbook = xlsxwriter.Workbook(output)\n worksheet = workbook.add_worksheet()\n worksheet.write(0, 0, 'ISBN')\n worksheet.write(0, 1, 'Name')\n worksheet.write(0, 2, 'Takedown date')\n worksheet.write(0, 3, 'Last updated')\n workbook.close()\n output.seek(0)\n return StreamingResponse(output)\n```\n\n```text\nUnable to open file\nYou may be having a problem connecting with the server, or the file that you wanted to open was corrupted.\n```\n\n```text\nBytesIO\n```\n\n```text\nxlsxwriter\n```\n\n```text\n.txt\n```\n\n```text\nheaders={'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}\n```\n\n```text\n@router.get(\"/payments/xlsx\", response_description='xlsx')\nasync def payments():\n output = BytesIO()\n workbook = xlsxwriter.Workbook(output)\n worksheet = workbook.add_worksheet()\n worksheet.write(0, 0, 'ISBN')\n worksheet.write(0, 1, 'Name')\n worksheet.write(0, 2, 'Takedown date')\n worksheet.write(0, 3, 'Last updated')\n workbook.close()\n output.seek(0)\n\n headers = {\n 'Content-Disposition': 'attachment; filename=\"filename.xlsx\"'\n }\n return StreamingResponse(output, headers=headers)\n```\n\n```text\nContent-Disposition\n```\n\n========================================\n\nComments:\n- Since the entire file data are already loaded into memory, you shouldn't be using `StreamingResponse`. Please have a look at this answer and that answer on how to return a custom `Response` and set the `Content-Disposition` header.\n- When does the \"output\" in-memory object get closed ?","metadata":{"transformedAt":"2026-08-18T18:32:29.128Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":8,"totalLines":102,"estimatedTokens":680}}392{"id":"stack-68278162","source":"stackoverflow","questionId":68278162,"title":"How to return a response with a line break using FastAPI?","tags":["python","python-3.x","fastapi"],"text":"Title: How to return a response with a line break using FastAPI?\nTags: python, python-3.x, fastapi\nSource: Stack Overflow\n\nQuestion:\n```\n@app.get('/status')\ndef get_func(request: Request):\n output = 'this output should have a line break'\n return output\n```\n\nThings I've tried:\n\n- `output = this output should \\n have a line break`\n`output = this output should \n have a line break`\n\nThe text itself is returned and I don't get the line break.\n\n========================================\n\nTop Answer:\nUse **response_class=PlainTextResponse**\n\n```\nfrom fastapi.responses import PlainTextResponse\n@app_fastapi.get(\"/get_log\", response_class=PlainTextResponse)\nasync def get_log():\n return \"hello\\nbye\\n\"\n```\n\n========================================\n\nCode:\n```text\n@app.get('/status')\ndef get_func(request: Request):\n output = 'this output should have a line break'\n return output\n```\n\n```text\noutput = this output should \\n have a line break\n```\n\n```text\noutput = this output should <br /> have a line break\n```\n\n```text\nfrom fastapi import FastAPI\nfrom fastapi.responses import HTMLResponse\n\napp = FastAPI()\n\n@app.get('/status', response_class=HTMLResponse)\ndef get_func():\n output = 'this output should <br> have a line break'\n return output\n```\n\n```html\n<html>\n<head>\n</head>\n<body>\n <p>This output should have a <br>line break.</p>\n <p>Other stuff: {{ stuff }}</p>\n</body>\n</html>\n```\n\n```py\nfrom fastapi import FastAPI, Request\nfrom fastapi.responses import HTMLResponse\nfrom fastapi.templating import Jinja2Templates\n\napp = FastAPI()\n\ntemplates = Jinja2Templates(directory=\"templates\")\n\n@app.get('/status', response_class=HTMLResponse)\ndef get_func(request: Request):\n return templates.TemplateResponse(\"output.html\", {\"request\": request, \"stuff\": 123})\n```\n\n```text\n\\n\n```\n\n```text\n<br>\n```\n\n```text\nJSONResponse\n```\n\n```text\napplication/json\n```\n\n```text\nHTMLResponse\n```\n\n```text\nresponse_class\n```\n\n```text\nfrom fastapi.responses import PlainTextResponse\n@app_fastapi.get(\"/get_log\", response_class=PlainTextResponse)\nasync def get_log():\n return \"hello\\nbye\\n\"\n```\n\n========================================\n\nComments:\n- i used this for displaying GraphQL schema, and it actually showed (in OpenAPI) not just correctly indented, but also colourized!","metadata":{"transformedAt":"2026-08-18T18:32:29.128Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":13,"totalLines":122,"estimatedTokens":569}}393{"id":"stack-67783530","source":"stackoverflow","questionId":67783530,"title":"Is there a way to pretty print / prettify a JSON response in FastAPI?","tags":["python","json","fastapi","pretty-print"],"text":"Title: Is there a way to pretty print / prettify a JSON response in FastAPI?\nTags: python, json, fastapi, pretty-print\nSource: Stack Overflow\n\nQuestion:\nI'm looking for something that is similar to Flask's `app.config['JSONIFY_PRETTYPRINT_REGULAR'] = True`.\n\n========================================\n\nTop Answer:\nIn order to avoid blocking the event loop for large lists of models, I ended up with a solution like the one below.\n\nThis should:\n\n- Not block the event loop\n\n- Stream results (much faster)\n\n- Release event loop in between model dict actions\n\n```\nasync def streaming_output_json(content: List[BaseModel]) -> StreamingResponse:\n \"\"\"\n Convert a list of Pydantic models to a JSON StreamingResponse.\n \"\"\"\n async def jsonify_async(models: List[BaseModel]) -> AsyncIterable[str]:\n yield '['\n for i, model in enumerate(models):\n await asyncio.sleep(0)\n if i > 0:\n yield ','\n result_dict = jsonable_encoder(model)\n serialized_dict = json.dumps(result_dict)\n yield serialized_dict\n yield ']'\n\n return StreamingResponse(jsonify_async(models=content), media_type='application/json')\n\n@router.get(\"\")\nasync def get_huge_result():\n results = [model1, model2, ...]\n return await streaming_output_json(results)\n```\n\n========================================\n\nCode:\n```text\napp.config['JSONIFY_PRETTYPRINT_REGULAR'] = True\n```\n\n```text\n@app.get(\"/config\", response_class=PrettyJSONResponse)\ndef get_config() -> MyConfigClass:\n return app.state.config\n```\n\n```text\nimport json, typing\nfrom starlette.responses import Response\n\nclass PrettyJSONResponse(Response):\n media_type = \"application/json\"\n\n def render(self, content: typing.Any) -> bytes:\n return json.dumps(\n content,\n ensure_ascii=False,\n allow_nan=False,\n indent=4,\n separators=(\", \", \": \"),\n ).encode(\"utf-8\")\n```\n\n```text\nPrettyJSONResponse\n```\n\n```text\nindent=4\n```\n\n```py\nasync def streaming_output_json(content: List[BaseModel]) -> StreamingResponse:\n \"\"\"\n Convert a list of Pydantic models to a JSON StreamingResponse.\n \"\"\"\n async def jsonify_async(models: List[BaseModel]) -> AsyncIterable[str]:\n yield '['\n for i, model in enumerate(models):\n await asyncio.sleep(0)\n if i > 0:\n yield ','\n result_dict = jsonable_encoder(model)\n serialized_dict = json.dumps(result_dict)\n yield serialized_dict\n yield ']'\n\n return StreamingResponse(jsonify_async(models=content), media_type='application/json')\n\n@router.get(\"\")\nasync def get_huge_result():\n results = [model1, model2, ...]\n return await streaming_output_json(results)\n```\n\n========================================\n\nComments:\n- Keep in mind, PrettyJSONResponse BLOCKS async functions on large data sets, so this needs to be used carefully or will cause performance issues in certain cases.\n- @EricLongstreet nice catch. How does one fix that? Simply adding async to the def render() won't work. Mypy won't like it.\n- @BrandonStivers, added an answer example.\n- Also please note this nukes the OpenAPI documentation entry. Now your output value is just \"string\".\n- Thanks for the example. I am developing a FastAPI version of httpbin (with a few extra features), and this should come in handy. Hopefully I can adapt it to a `ORJSONResponse`. It should work by just tossing the output into `ORJSONResponse(streaming_output_json(results))`. Hopefully `ORJSONResponse` doesn't reformat it back into a single line. lol\n- keep in mind if orjsonresponse isn't async, you will have the same issue. if you want to use it, you'd be better off switching it out in the for loop.\n- trolling the FastAPI source code, it looks like the underlying orjson calls aren't async (like most of its other code). However, orjson is 5 to 6 times faster than regular json. So I don't think it'll bottleneck most things in the given dev environment this will be used for.","metadata":{"transformedAt":"2026-08-18T18:32:29.128Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":6,"totalLines":116,"estimatedTokens":987}}394{"id":"stack-66849929","source":"stackoverflow","questionId":66849929,"title":"FastAPI redirect gives method not allowed error","tags":["python","http","fastapi","starlette"],"text":"Title: FastAPI redirect gives method not allowed error\nTags: python, http, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nI have created a route for login, where I post my form data and set a cookie. After setting the cookie I redirect to \"/main\" where I get `{detail:\"Method Not Allowed\"}` as a response.\n\n```\n@app.post(\"/login\")\nasync def login(request:Request):\n response = RedirectResponse(url=\"/main\")\n response.set_cookie(key=\"cookie\",value=\"key-value\")\n return response\n\n@app.get(\"/main\")\nasync def root(request:Request, cookie: Optional[str] = Cookie(None)):\n if cookie:\n answer = \"set to %s\" % cookie\n else:\n answer = \"not set\"\n\n return {\"value\": answer}\n```\n\nI furthered checked the console to find that a POST request is made to \"/main\" during the redirect and hence causing the error. When I change it to `app.post(\"/main\")` it works fine. How do I avoid this error? I don't want to make post request to access \"/main\" everytime. Thanks in advance.\n\n========================================\n\nCode:\n```text\n@app.post(\"/login\")\nasync def login(request:Request):\n response = RedirectResponse(url=\"/main\")\n response.set_cookie(key=\"cookie\",value=\"key-value\")\n return response\n\n@app.get(\"/main\")\nasync def root(request:Request, cookie: Optional[str] = Cookie(None)):\n if cookie:\n answer = \"set to %s\" % cookie\n else:\n answer = \"not set\"\n\n return {\"value\": answer}\n```\n\n```text\n{detail:\"Method Not Allowed\"}\n```\n\n```text\napp.post(\"/main\")\n```\n\n```text\nresponse.status_code = 302\n```\n\n========================================\n\nComments:\n- `status_code=status.HTTP_303_SEE_OTHER` make more sense to me. 302 status code is for not found redirection.","metadata":{"transformedAt":"2026-08-18T18:32:29.128Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":62,"estimatedTokens":425}}395{"id":"stack-63232724","source":"stackoverflow","questionId":63232724,"title":"How to add documentation for required query parameters?","tags":["python","fastapi"],"text":"Title: How to add documentation for required query parameters?\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm trying to create a fastapi API endpoint that relies on HTTP GET parameters, has them documented and uses fastapi's validation capabilities. Consider the following minimal example:\n\n```\nimport fastapi\n\napp = fastapi.FastAPI(\n)\n\n@app.get(\"/endpoint\")\ndef example_endpoint(\n par1: int = fastapi.Query(\n None,\n description=\"example documentation1\",\n ),\n\n par2: int = fastapi.Query(\n None,\n description=\"example documentation2\",\n ),\n):\n return {\"test\": par1 + par2}\n```\n\nThis has the documentation support and works over HTTP GET parameters, but doesn't validate them - http://localhost:8000/endpoint?par1=2&par2=3 works fine, but http://localhost:8000/endpoint crashes with an internal server error, instead of notifying the user that a parameter was expected. Is there a way to make par1 and par2 required and keep the documentation feature?\n\n========================================\n\nCode:\n```text\nimport fastapi\n\napp = fastapi.FastAPI(\n)\n\n@app.get(\"/endpoint\")\ndef example_endpoint(\n par1: int = fastapi.Query(\n None,\n description=\"example documentation1\",\n ),\n\n par2: int = fastapi.Query(\n None,\n description=\"example documentation2\",\n ),\n):\n return {\"test\": par1 + par2}\n```\n\n```text\nfrom fastapi import Query\n\nQuery(...,description=\"example documentation1\")\n```\n\n```text\n@app.get(\"/endpoint\")\ndef example_endpoint(\n par1: int = fastapi.Query(..., description=\"example documentation1\",),\n par2: int = fastapi.Query(..., description=\"example documentation2\",),\n):\n\n if par1 and par2:\n return {\"test\": par1 + par2}\n\n raise ValueError(\"Missing query parameters\")\n```\n\n```text\nQuery(..., description=\"example documentation2\", example=1)\n```\n\n```text\n...\n```\n\n```text\nexample=1\n```\n\n========================================\n\nComments:\n- What is the `example=1` in `Query(...)` ?\n- It's a great question. Simply it adds example value like default, that query will be 1 if it's empty, kinda like when you open the Body of an **POST** endpoint there will be the same example values by default, for str there will be \"string\", for int there will be 0 etc.\n- But it's just an example when you send a request to the `/endpoint` without any query parameter's you 'll be still getting an error `{\"detail\":[{\"loc\":[\"query\",\"par1\"],\"msg\":\"field required\",\"type\":\"value_error.missing\"}`","metadata":{"transformedAt":"2026-08-18T18:32:29.128Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":6,"totalLines":91,"estimatedTokens":615}}396{"id":"stack-76758415","source":"stackoverflow","questionId":76758415,"title":"Pydantic issue for tuple length","tags":["python","fastapi","pydantic"],"text":"Title: Pydantic issue for tuple length\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI have the following model in pydantic (Version 2.0.3)\n\n```\nfrom typing import Tuple\nfrom pydantic import BaseModel\n\nclass Model(BaseModel):\n test_field: Tuple[int]\n```\n\nBut when I enter\n\n```\nmodel = Model(test_field=(1,2))\n```\n\nI get as error:\n\n```\nTraceback (most recent call last):\n File \"/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/code.py\", line 90, in runcode\n exec(code, self.locals)\n File \"\", line 1, in \n File \"/Users/tobi/Documents/scraiber/z_legacy/fastapi_test_app/venv/lib/python3.10/site-packages/pydantic/main.py\", line 150, in __init__\n __pydantic_self__.__pydantic_validator__.validate_python(data, self_instance=__pydantic_self__)\npydantic_core._pydantic_core.ValidationError: 1 validation error for Model\ntest_field\n Tuple should have at most 1 item after validation, not 2 [type=too_long, input_value=(1, 2), input_type=tuple]\n For further information visit https://errors.pydantic.dev/2.0.3/v/too_long\n```\n\nDo you know how I can fix that?\n\n========================================\n\nTop Answer:\nVariable-length tuples are not supported. There's a bug report about it. `Sequence` can be used as a workaround.\n\nhttps://github.com/pydantic/pydantic/issues/495\n\n========================================\n\nCode:\n```text\nfrom typing import Tuple\nfrom pydantic import BaseModel\n\nclass Model(BaseModel):\n test_field: Tuple[int]\n```\n\n```text\nmodel = Model(test_field=(1,2))\n```\n\n```text\nTraceback (most recent call last):\n File \"/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/code.py\", line 90, in runcode\n exec(code, self.locals)\n File \"<input>\", line 1, in <module>\n File \"/Users/tobi/Documents/scraiber/z_legacy/fastapi_test_app/venv/lib/python3.10/site-packages/pydantic/main.py\", line 150, in __init__\n __pydantic_self__.__pydantic_validator__.validate_python(data, self_instance=__pydantic_self__)\npydantic_core._pydantic_core.ValidationError: 1 validation error for Model\ntest_field\n Tuple should have at most 1 item after validation, not 2 [type=too_long, input_value=(1, 2), input_type=tuple]\n For further information visit https://errors.pydantic.dev/2.0.3/v/too_long\n```\n\n```py\nclass Model(BaseModel):\n test_field: Tuple[int, ...]\n```\n\n```py\n>>> Model(test_field=(1,2))\nModel(test_field=(1, 2))\n```\n\n```py\ncount = 5\nclass Model_Five(BaseModel):\n test_field: Tuple[*([int]*count)]\n```\n\n```text\n>>> Model_Five(test_field=(1,2,3,4,5))\nModel_Five(test_field=(1, 2, 3, 4, 5))\n>>> Model_Five(test_field=(1,2,3,4))\n[..] omitted\ntest_field.4\n Field required [type=missing, input_value=(1, 2, 3, 4), input_type=tuple]\n For further information visit https://docs.pydantic.dev/dev/errors/validation_errors/#missing\n```\n\n```text\n...\n```\n\n```text\n*(cls for _ in range(count))\n```\n\n```text\n*(some_class_factory() for _ in range(count))\n```\n\n```text\nSequence\n```\n\n========================================\n\nComments:\n- You missed the fact that this issue has been closed as fixed by this commit a few years ago. Variable length tuples **are** supported.\n- Many thanks for it. Assume, for instance, I have 100 `int` in a tuple. Is there a more elegant way to do instead of the two you mentioned?\n- I think the general advice is \"don't do that\" and a lot of fields is probably a bad design .. but if you do have a lot of fields, consider a NamedTuple stackoverflow.com/a/44833864/4541045 (which at least annotates the values).. you'll have to either provide every field (`[int, int, int, int, int]`), create a custom Type with that many fields, or use `...` and an `@field_validator` to assert the length docs.pydantic.dev/latest/usage/validators","metadata":{"transformedAt":"2026-08-18T18:32:29.128Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":11,"totalLines":121,"estimatedTokens":931}}397{"id":"stack-62970006","source":"stackoverflow","questionId":62970006,"title":"FastAPI OAuth2PasswordRequestForm dependency causing request failure","tags":["python","authentication","oauth","jwt","fastapi"],"text":"Title: FastAPI OAuth2PasswordRequestForm dependency causing request failure\nTags: python, authentication, oauth, jwt, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm using the auth scheme detailed in FastAPI's user guide (JWT/Bearer token). When I try to get a token from the `/token` endpoint the request fails before the path operation function ever runs. Here's the function in question:\n\n```\nasync def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends(), session: SessionLocal = Depends(get_db)):\n user = authenticate_user(session, form_data.username, form_data.password)\n if not user:\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Incorrect username or password\",\n headers={\"WWW-Authenticate\": \"Bearer\"},\n )\n access_token = create_access_token(data={\"sub\": user.id})\n return {\"access_token\": access_token, \"token_type\": \"bearer\"}\n```\n\nI normally use breakpoints to help figure out what's going wrong in these situations, but the call fails before any code in the function actually runs, leading me to believe the problem is with the `OAuth2PasswordRequestForm` dependency. I verified that this was the problem by disabling the `form_data parameter` and was able to execute the full request.\n\nThe errors I'm getting are pretty sparse on details. Here's what I'm getting in the console: `INFO: 127.0.0.1:52261 - \"POST /token HTTP/1.1\" 400 Bad Request`\n\nAnd here's what I see in the Swagger UI:\n\nhttps://i.sstatic.net/t849h.png\n\nThis was working for me in the single-file format used in the tutorial, but I've since broken things out into different files to keep my larger project organized. I have a feeling that I just missed something somewhere along the line while reorganizing this code but can't seem to figure out what is causing this.\n\n========================================\n\nTop Answer:\nin the docs, you have to provide the login token path for OAuth2PasswordBearer\n\n```\noauth2_scheme = OAuth2PasswordBearer(tokenUrl=\"token\")\n```\n\nin case your are breaking your app into different modules, where your endpoint paths begins with a prefix, include the prefix. so it looks like this:\n\n```\noauth2_scheme = OAuth2PasswordBearer(tokenUrl=\"/prefix/token\")\n```\n\n========================================\n\nCode:\n```text\nasync def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends(), session: SessionLocal = Depends(get_db)):\n user = authenticate_user(session, form_data.username, form_data.password)\n if not user:\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Incorrect username or password\",\n headers={\"WWW-Authenticate\": \"Bearer\"},\n )\n access_token = create_access_token(data={\"sub\": user.id})\n return {\"access_token\": access_token, \"token_type\": \"bearer\"}\n```\n\n```text\n/token\n```\n\n```text\nOAuth2PasswordRequestForm\n```\n\n```text\nform_data parameter\n```\n\n```text\nINFO: 127.0.0.1:52261 - \"POST /token HTTP/1.1\" 400 Bad Request\n```\n\n```text\npython-multipart\n```\n\n```text\npip install python-multipart\n```\n\n```text\nclass Token(BaseModel):\n access_token: str\n token_type: str\n```\n\n```text\n@router.post('/token', response_body=Token)\n```\n\n```text\noauth2_scheme = OAuth2PasswordBearer(tokenUrl=\"token\")\n```\n\n```text\noauth2_scheme = OAuth2PasswordBearer(tokenUrl=\"/prefix/token\")\n```\n\n========================================\n\nComments:\n- I have already installed this but still have the very same issue! any ideas?\n- it should be response_model= Token\n- The prefix detail fixed it for me. Also, you may need to create a johndoe instance to use it.","metadata":{"transformedAt":"2026-08-18T18:32:29.128Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":11,"totalLines":109,"estimatedTokens":902}}398{"id":"stack-73110208","source":"stackoverflow","questionId":73110208,"title":"How to load a different file than index.html in FastAPI root path while using StaticFiles?","tags":["python","fastapi","static-files","starlette","fileresponse"],"text":"Title: How to load a different file than index.html in FastAPI root path while using StaticFiles?\nTags: python, fastapi, static-files, starlette, fileresponse\nSource: Stack Overflow\n\nQuestion:\nHere is a simple static FastAPI app. With this setup even though the root path is expected to return a `FileResponse` of `custom.html`, the app still returns `index.html`. How can I get the root path work and render `custom.html`?\n\n```\nfrom fastapi import FastAPI\nfrom fastapi.staticfiles import StaticFiles\nfrom fastapi.responses import FileResponse\n\napp = FastAPI()\n\napp.mount(\n \"/\",\n StaticFiles(directory=\"static\", html=True),\n name=\"static\",\n)\n\n@app.get(\"/\")\nasync def index() -> FileResponse:\n return FileResponse(\"custom.html\", media_type=\"html\")\n```\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI\nfrom fastapi.staticfiles import StaticFiles\nfrom fastapi.responses import FileResponse\n\napp = FastAPI()\n\n\napp.mount(\n \"/\",\n StaticFiles(directory=\"static\", html=True),\n name=\"static\",\n)\n\n@app.get(\"/\")\nasync def index() -> FileResponse:\n return FileResponse(\"custom.html\", media_type=\"html\")\n```\n\n```text\nFileResponse\n```\n\n```text\ncustom.html\n```\n\n```text\nindex.html\n```\n\n```text\ncustom.html\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.staticfiles import StaticFiles\n\napp = FastAPI()\n\napp.mount('/', StaticFiles(directory='static', html=True), name='static')\n```\n\n```py\napp.mount('/static', StaticFiles(directory='static', html=True), name='static')\n```\n\n```py\napp.mount('/', StaticFiles(directory='static'), name='static')\n\n@app.post('/register')\nasync def register():\n pass\n\n@app.post('/login')\nasync def login():\n pass\n\n@app.get('/hello')\nasync def hello():\n pass\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.staticfiles import StaticFiles\nfrom fastapi.responses import FileResponse\n\napp = FastAPI()\n\n\n@app.post('/register')\nasync def register():\n pass\n\n\n@app.post('/login')\nasync def login():\n pass\n\n\n@app.get('/hello')\nasync def hello():\n pass\n\n\n@app.get('/')\nasync def index():\n return FileResponse('static/custom.html')\n \n \napp.mount('/',StaticFiles(directory='static', html=True), name='static')\n```\n\n```text\nStaticFiles(directory=None, packages=None, html=False, check_dir=True, follow_symlink=False)\n```\n\n```text\nhtml\n```\n\n```text\nindex.html\n```\n\n```text\nStaticFiles\n```\n\n```text\n/\n```\n\n```text\n/static\n```\n\n```text\n/\n```\n\n```text\nStaticFiles\n```\n\n```text\nhtml=True\n```\n\n```text\nindex.html\n```\n\n```text\n/\n```\n\n```text\napp.mount(\"/\",StaticFiles(...\n```\n\n```text\n@app.get(\"/\")\n```\n\n```text\nindex.html\n```\n\n```text\nInternal Server Error\n```\n\n```text\n@app.get(\"/\")\n```\n\n```text\ncustom.html\n```\n\n```text\n/\n```\n\n```text\n/static\n```\n\n```text\nFile does not exist\n```\n\n```text\nFileResponse('static/custom.html')\n```\n\n```text\nhtml=True\n```\n\n```text\nStaticFiles\n```\n\n```text\n/\n```\n\n```text\n{\"detail\":\"Not Found\"}\n```\n\n```text\nhttp://localhost:8000/\n```\n\n```text\n/\n```\n\n```text\nStaticFiles\n```\n\n```text\nhtml=True\n```\n\n```text\nhttp://localhost:8000/index.html\n```\n\n```text\n/register\n```\n\n```text\n/login\n```\n\n```text\n/hello\n```\n\n```text\nStaticFiles\n```\n\n```text\n/\n```\n\n```text\nStaticFiles\n```\n\n```text\n{\"detail\":\"Not Found\"}\n```\n\n```text\nGET\n```\n\n```text\nstatic\n```\n\n```text\n{detail\": \"Method Not Allowed\"}\n```\n\n```text\nPOST\n```\n\n```text\nStaticFiles\n```\n\n```text\nStaticFiles\n```\n\n```text\n404 Not found\n```\n\n```text\n405 Method not allowed\n```\n\n```text\n404.html\n```\n\n```text\nStaticFiles\n```\n\n```text\n/static\n```\n\n```text\napp.mount('/static', ...\n```\n\n```text\nStaticFiles\n```\n\n```text\n/\n```\n\n```text\nStaticFiles\n```\n\n```text\nStaticFiles\n```\n\n```text\nStaticFiles\n```\n\n```text\nstatic/index.html\n```\n\n```text\nstatic/custom.html\n```\n\n```text\nhttp://localhost:8000/\n```\n\n```text\nhtml=True\n```\n\n```text\nhtml\n```\n\n```text\nStaticFiles\n```\n\n```text\nTrue\n```\n\n```text\nhtml=True\n```\n\n```text\nTemplates\n```\n\n```text\nFileResponse\n```\n\n```text\nStaticFiles\n```\n\n```text\n/static\n```\n\n```text\nhtml=True\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.128Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":76,"totalLines":390,"estimatedTokens":991}}399{"id":"stack-62882830","source":"stackoverflow","questionId":62882830,"title":"FastApi middleware on different folder not working","tags":["python","rest","middleware","fastapi"],"text":"Title: FastApi middleware on different folder not working\nTags: python, rest, middleware, fastapi\nSource: Stack Overflow\n\nQuestion:\nI,m getting this error when I try to run my FastApi api.\n\napp = cls(app=app, **options)\nTypeError: 'module' object is not callable\n\nI'm trying to add a middleware on other folder separeted from main.py and don't know why isn't working. Otherwise when I add the middleware code into main.py works without problems. Here is my code, thank you for your help and excuse my english.\n\nmain.py\n\n```\nfrom fastapi import FastAPI\nfrom fastapi import Depends, FastAPI, HTTPException\nfrom fastapi import Request\nfrom routers import rutas\nfrom utils import CheckApiKey\nfrom utils.CheckApiKey import check_api_key\n\napp = FastAPI()\napp.add_middleware(CheckApiKey, dispatch=check_api_key) Middleware\n\n```\nfrom fastapi import Request\n\nasync def check_api_key(request: Request, call_next): \n\n print(\"ok\")\n response = await call_next(request) \n\n return response\n```\n\n========================================\n\nTop Answer:\nThe **`CheckApiKey`** seems like a ***python module*** in your case and `check_api_key` is the middleware function.\n\nThe issue was, the **`add_middleware()`** method expects the first argument as a ***callable function or callable class***. But in your case, you were given a ***module***.\n\nSo,\n\nChange your statement as,\n\n```\napp.add_middleware(**check_api_key**)\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nfrom fastapi import Depends, FastAPI, HTTPException\nfrom fastapi import Request\nfrom routers import rutas\nfrom utils import CheckApiKey\nfrom utils.CheckApiKey import check_api_key\n\napp = FastAPI()\napp.add_middleware(CheckApiKey, dispatch=check_api_key) <--- Here calling middleware\napp.include_router(rutas.router)\n\n\nif __name__ == \"__main__\":\n import uvicorn\n\n uvicorn.run(\"main:app\", host=\"127.0.0.1\", port=8000, reload=True)\n```\n\n```text\nfrom fastapi import Request\n\nasync def check_api_key(request: Request, call_next): \n\n print(\"ok\")\n response = await call_next(request) \n\n return response\n```\n\n```text\nfrom starlette.middleware.base import BaseHTTPMiddleware\n\n\nclass CheckApiKey(BaseHTTPMiddleware):\n async def dispatch(self, request, call_next):\n print(\"ok\")\n response = await call_next(request)\n\n return response\n```\n\n```text\napp.add_middleware(check_api_key)\n```\n\n```text\nCheckApiKey\n```\n\n```text\ncheck_api_key\n```\n\n```text\nadd_middleware()\n```\n\n========================================\n\nComments:\n- is `CheckApiKey` is a module (a python file) ?\n- @ArakkalAbu yeah...is the name of the file\n- So, that's the issue.\n- Thanks for the answer!...I try your suggestion and I'm getting this error \"TypeError: check_api_key() got an unexpected keyword argument 'app' \"\n- Can you add your ***complete error traceback*** to OP?\n- Found a solution!!..I will post it\n- Thanks for your help!","metadata":{"transformedAt":"2026-08-18T18:32:29.128Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":7,"totalLines":122,"estimatedTokens":724}}400{"id":"stack-68331493","source":"stackoverflow","questionId":68331493,"title":"Count number of requests with global variable using FastAPI","tags":["python","python-asyncio","fastapi","uvicorn","asgi"],"text":"Title: Count number of requests with global variable using FastAPI\nTags: python, python-asyncio, fastapi, uvicorn, asgi\nSource: Stack Overflow\n\nQuestion:\nI want to count the number of requests in a specific URL path.\n\n```\napp = FastAPI()\ncounter = 0\n\n@app.get(\"/do_something\")\nasync def do_something():\n global counter\n counter += 1\n return {\"message\": \"Hello World\"}\n```\n\nIs this code ok?\nThe counter should be thread safe? asincio safe?\nIs that the right way to count requests (Without DB)?\nIs there a meaning for the \"async\" in the \"do_something\" function in this situation?\nAnd how to make it work with several workers?\n\n========================================\n\nTop Answer:\nThis code is unsafe because you are not using locks. I think you thought that the += operation is atomic, so it's safe to use without locks, but it's not. To protect your state you need locks. The asyncio library provides locks https://docs.python.org/3/library/asyncio-sync.html.\n\n```\nimport asyncio\n\napp = FastAPI()\ncounter = 0\nlock = asyncio.Lock()\n\n@app.get(\"/do_something\")\nasync def do_something():\n global counter\n\n async with lock:\n counter += 1\n # some other thread-safe code here\n\n return {\"message\": \"Hello World\"}\n```\n\n========================================\n\nCode:\n```text\napp = FastAPI()\ncounter = 0\n\n@app.get(\"/do_something\")\nasync def do_something():\n global counter\n counter += 1\n return {\"message\": \"Hello World\"}\n```\n\n```text\nimport asyncio\n\napp = FastAPI()\ncounter_lock = asyncio.Lock()\ncounter = 0\n\n@app.get(\"/do_something\")\nasync def do_something():\n global counter\n\n async with counter_lock:\n counter += 1\n\n return {\"message\": \"Hello World\"}\n```\n\n```py\nimport threading\n\napp = FastAPI()\ncounter = 0\nlock = threading.Lock()\n\n@app.get(\"/do_something\")\ndef do_something():\n global counter\n\n with lock:\n counter += 1\n # some other thread-safe code here\n\n return {\"message\": \"Hello World\"}\n```\n\n```text\nimport asyncio\n\napp = FastAPI()\ncounter = 0\nlock = asyncio.Lock()\n\n@app.get(\"/do_something\")\nasync def do_something():\n global counter\n\n async with lock:\n counter += 1\n # some other thread-safe code here\n\n return {\"message\": \"Hello World\"}\n```\n\n========================================\n\nComments:\n- FastAPI is based on asyncio, not threads.\n- Related stackoverflow.com/questions/65686318/…\n- Thanks, the asycio.Lock() version worked well, even in an async endpoint handler. 👍","metadata":{"transformedAt":"2026-08-18T18:32:29.128Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":4,"totalLines":120,"estimatedTokens":614}}401{"id":"stack-69201995","source":"stackoverflow","questionId":69201995,"title":"Getting CORS error instead of Error 500 (No 'Access-Control-Allow-Origin' header is present)","tags":["angular","cors","backend","fastapi"],"text":"Title: Getting CORS error instead of Error 500 (No 'Access-Control-Allow-Origin' header is present)\nTags: angular, cors, backend, fastapi\nSource: Stack Overflow\n\nQuestion:\nYesterday I asked a question about CORS error that I was getting when trying to do a POST request to FastApi backend from Angular app. After a few comments I decided to delete the question to re-check everything better.\n\nSo things are a bit weird. In my FastApi backend I have the following functions:\n\n```\n@app.post(\"/hello\")\ndef read_root(request: Request):\n print(request)\n client_host = request.client.host\n return {\"client_host\": client_host}\n\n@app.post(\"/pattern-data\")\ndef pattern_input(payload: PatternReconData) -> Dict:\n # Does stuff and falls over tragically\n return result # this doesn't happen of course\n```\n\nand in my front-end I'm trying both of these:\n\n```\nthis.apiService.sendRequest('hello', 'howdy').subscribe(\n (response) => {\n console.log(response);\n },\n (error: any) => {\n console.log(error);\n },\n () => {\n console.log('done');\n }\n );\n this.apiService.sendRequest('pattern-data', payload).subscribe(\n (response: SuccessResponse) => {\n console.log(response);\n /* do stuff */\n },\n (error: any) => {\n console.log(error);\n },\n () => {\n console.log('done');\n },\n );\n```\n\nWhat's strange is that if I test sending some values to `'pattern-data'` in Swagger UI it comes back with Error 500 since the script falls over. The `'hello'` works just fine.\n\nhttps://i.sstatic.net/0FdHZ.png\n\nSimilarly, going from the front-end app if I poke the `.../hello` I get the expected response:\n\n```\n{client_host: ''}\n```\n\nbut when trying to send values to `.../pattern-data` results in CORS error:\n\n```\nAccess to XMLHttpRequest at 'http:///pattern-data' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.\n```\n\nYet I know that the backend had successfully received the payload because if I look at backend logs I see this.:\n\n```\n2021-09-16 02:42:38.0130,main,DEBUG,Pattern name received from front-end {data}\n```\n\nSo this suggests that the pre-flight check was successful and web app was allowed to communicate with the backend so it all has nothing to do with CORS.\n\nThis is a bit confusing and caused me quite a lot of grief having spent time researching CORS and how to deal with CORS errors, while in reality my issue has nothing to do with it.\n\nI don't understand why I'm not getting an Error 500 but a CORS error instead. Is this because the back-end simply fails to send a response and browser (Chrome) interprets no response as not having necessary headers and shows CORS error?\n\nThis is from Chrome dev tools Headers section. Poking `/hello`:\n\n```\nRequest URL: http:///hello\nRequest Method: POST\nStatus Code: 200 OK\nRemote Address: \nReferrer Policy: strict-origin-when-cross-origin\naccess-control-allow-credentials: true\naccess-control-allow-origin: http://localhost:4200\ncontent-length: 31\ncontent-type: application/json\ndate: Thu, 16 Sep 2021 02:43:09 GMT\nserver: uvicorn\nvary: Origin\n```\n\nsending data to `/pattern-data`:\n\n```\nRequest URL: http:///pattern-data\nReferrer Policy: strict-origin-when-cross-origin\ncontent-length: 21\ncontent-type: text/plain; charset=utf-8\ndate: Thu, 16 Sep 2021 02:43:09 GMT\nserver: uvicorn\n```\n\n========================================\n\nCode:\n```py\n@app.post(\"/hello\")\ndef read_root(request: Request):\n print(request)\n client_host = request.client.host\n return {\"client_host\": client_host}\n\n@app.post(\"/pattern-data\")\ndef pattern_input(payload: PatternReconData) -> Dict:\n # Does stuff and falls over tragically\n return result # this doesn't happen of course\n```\n\n```js\nthis.apiService.sendRequest('hello', 'howdy').subscribe(\n (response) => {\n console.log(response);\n },\n (error: any) => {\n console.log(error);\n },\n () => {\n console.log('done');\n }\n );\n this.apiService.sendRequest('pattern-data', payload).subscribe(\n (response: SuccessResponse) => {\n console.log(response);\n /* do stuff */\n },\n (error: any) => {\n console.log(error);\n },\n () => {\n console.log('done');\n },\n );\n```\n\n```text\n{client_host: '<some valid ip>'}\n```\n\n```text\nAccess to XMLHttpRequest at 'http://<my-backend-server>/pattern-data' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.\n```\n\n```text\n2021-09-16 02:42:38.0130,main,DEBUG,Pattern name received from front-end {data}\n```\n\n```text\nRequest URL: http://<my-backend-server>/hello\nRequest Method: POST\nStatus Code: 200 OK\nRemote Address: <some valid ip>\nReferrer Policy: strict-origin-when-cross-origin\naccess-control-allow-credentials: true\naccess-control-allow-origin: http://localhost:4200\ncontent-length: 31\ncontent-type: application/json\ndate: Thu, 16 Sep 2021 02:43:09 GMT\nserver: uvicorn\nvary: Origin\n```\n\n```text\nRequest URL: http://<my-backend-server>/pattern-data\nReferrer Policy: strict-origin-when-cross-origin\ncontent-length: 21\ncontent-type: text/plain; charset=utf-8\ndate: Thu, 16 Sep 2021 02:43:09 GMT\nserver: uvicorn\n```\n\n```text\n'pattern-data'\n```\n\n```text\n'hello'\n```\n\n```text\n.../hello\n```\n\n```text\n.../pattern-data\n```\n\n```text\n/hello\n```\n\n```text\n/pattern-data\n```\n\n========================================\n\nComments:\n- Well, the error says it all, the cors headers are missing in the response from the service. In the swagger UI it's probably working because this is served by swagger themselves (thus there is no cross origin). When you are requesting from your localhost, the server does not send any cors headers, thus your browser rejects to access the data in the response.\n- @derpirscher fair enough but as I understood it, CORS is meant to be a pre-flight check that's conducted *before* front-end is allowed to communicate with the back-end. But what I have is that backend is successfully receiving the data, which to me means that there was a handshake and the POST method was allowed to go through.\n- CORS does not guide anything about a POST method going through - it's only relevant to whether the client is allowed to read the response (i.e. the request still happens as long as the the OPTIONS call (preflight) is OK-ed - this happens without running the view code where the 500 error occurs).\n- @MatsLindh, sorry my understanding might be a bit off. But then I need to specify in FastApi CORS middleware that for example POST and GET methods are allowed. So CORS should be allowing or rejecting the method coming through. Otherwise it would be a pointless security feature if malicious code can be sent anyway and only thing monitored is the ability to get response.\n- I'm not sure what you think the goal of CORS is - it will verify that the `Origin` header that a browser sends is among the accepted origins, and it will tell the requesting browser that it is allowed to read the response from the service. If you make an explicit HTTP request, it'll pass regardless of any CORS restrictions (for example using `curl` or similar). It protects you from 3rd party sites making requests to a resource on behalf of the browser of the user (the `Origin:` would be different than what you expected).\n- @MatsLindh, this is what I see on Wiki page: \"...the specification mandates that browsers \"preflight\" the request, soliciting supported methods from the server with an HTTP OPTIONS request method, and then, upon \"approval\" from the server, sending the actual request with the actual HTTP request method.\" So in my case this means that preflight succeeded, then front-end sent the data but when backend failed a CORS error was reported by the browser. Just seems weird.\n- When the error happens, the expected CORS headers on the *response* is not present (since an exception happened, the middleware does not run). Since the expected CORS headers are not present, the browser returns a CORS error, even if the underlying error is a 500 error - since the request doesn't have the required CORS headers, the browser can't reporting anything else than a CORS error (since it would otherwise leak information that it hasn't been allowed to provide).\n- @MatsLindh, ok cool. I get it now. Would you mind submitting it as an answer so I can accept it?","metadata":{"transformedAt":"2026-08-18T18:32:29.129Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":13,"totalLines":219,"estimatedTokens":2088}}402{"id":"stack-75019496","source":"stackoverflow","questionId":75019496,"title":"Enable \"Try it out\" in OpenAPI so that no need to click","tags":["python","swagger","fastapi","swagger-ui","openapi"],"text":"Title: Enable \"Try it out\" in OpenAPI so that no need to click\nTags: python, swagger, fastapi, swagger-ui, openapi\nSource: Stack Overflow\n\nQuestion:\nI'm using FastAPI and OpenAPI/Swagger UI to see and test my endpoints.\n\nEach time I use an endpoint for the first time, in order to test it, I have to first click the Try it out button, which is getting tedious.\n\nIs there a way to make it disappear and be able to test the endpoint instantly?\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI\n\napp = FastAPI(swagger_ui_parameters={\"tryItOutEnabled\": True})\n```\n\n```text\n\"swagger_ui_parameters\"\n```\n\n```text\nFastAPI\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.129Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":3,"totalLines":27,"estimatedTokens":163}}403{"id":"stack-78905921","source":"stackoverflow","questionId":78905921,"title":"How to properly annotate the `call_next` parameter to a FastAPI middleware?","tags":["python","fastapi","python-typing","mypy"],"text":"Title: How to properly annotate the `call_next` parameter to a FastAPI middleware?\nTags: python, fastapi, python-typing, mypy\nSource: Stack Overflow\n\nQuestion:\nI'm trying to adapt an example from the FastAPI docs to create a middleware:\n\n```\n@app.middleware(\"http\")\nasync def add_process_time_header(request: Request, call_next):\n start_time = time.time()\n response = await call_next(request)\n process_time = time.time() - start_time\n response.headers[\"X-Process-Time\"] = str(process_time)\n return response\n```\n\nHowever, the `call_next` parameter here is not annotated. When I use just `typing.Callable` for that, I get an error from `mypy`:\n\n```\nerror: Missing type parameters for generic type \"Callable\" [type-arg]\n```\n\nWhat's the precise way to annotate the parameter?\n\n========================================\n\nCode:\n```text\n@app.middleware(\"http\")\nasync def add_process_time_header(request: Request, call_next):\n start_time = time.time()\n response = await call_next(request)\n process_time = time.time() - start_time\n response.headers[\"X-Process-Time\"] = str(process_time)\n return response\n```\n\n```text\nerror: Missing type parameters for generic type \"Callable\" [type-arg]\n```\n\n```text\ncall_next\n```\n\n```text\ntyping.Callable\n```\n\n```text\nmypy\n```\n\n```py\nfrom typing import Awaitable, Callable\n\nfrom fastapi import FastAPI, Request, Response\n\napp = FastAPI()\n\n@app.middleware(\"http\")\nasync def add_process_time_header(\n request: Request, call_next: Callable[[Request], Awaitable[Response]]\n):\n ...\n```\n\n```text\ncall_next\n```\n\n```text\nRequest\n```\n\n```text\nResponse\n```\n\n```text\nCallable[[Request], Awaitable[Response]]\n```\n\n========================================\n\nComments:\n- You can see the type *in your own usage*, but here it is in Starlette too github.com/encode/starlette/blob/…\n- @jonrsharpe What do you mean by `see the type in your own usage` ?\n- I mean you call it, pass it a Request, await the result and get a Response.\n- fair enough :-)","metadata":{"transformedAt":"2026-08-18T18:32:29.129Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":10,"totalLines":91,"estimatedTokens":496}}404{"id":"stack-72727007","source":"stackoverflow","questionId":72727007,"title":"Alembic is giving me `RuntimeWarning: coroutine 'connect' was never awaited`","tags":["python-3.x","fastapi","alembic"],"text":"Title: Alembic is giving me `RuntimeWarning: coroutine 'connect' was never awaited`\nTags: python-3.x, fastapi, alembic\nSource: Stack Overflow\n\nQuestion:\nI switched to using SQLAlchemy from TortoiseORM and thought I'd look into Alembic to handle its migrations. After editing the *env.py* and *alembic.ini* files I still can't get alembic to generate any migrations.\n\nThe error `sqlalchemy.exc.MissingGreenlet: greenlet_spawn has not been called; can't call await_only() here. Was IO attempted in an unexpected place? (Background on this error at: https://sqlalche.me/e/14/xd2s) sys:1: RuntimeWarning: coroutine 'connect' was never awaited` is self-explanatory but I have no idea what exactly to change.\n\nI'm following directions in the FastAPI-Users docs but am completely lost.\n\nWhat I've tried:\n\n- Setting `run_migrations_offline()` and `run_migrations_online()` as `async`\n\n- Using `asyncio.run()` to so I can run them\n\n**models.py**\n\n```\nimport os\nfrom typing import AsyncGenerator\nfrom fastapi import Depends\nfrom fastapi_users.db import SQLAlchemyBaseUserTableUUID, SQLAlchemyUserDatabase\nfrom sqlalchemy.ext.asyncio import AsyncSession, create_async_engine\nfrom sqlalchemy.ext.declarative import DeclarativeMeta, declarative_base\nfrom sqlalchemy.orm import sessionmaker, relationship\nfrom sqlalchemy import Column, String, Integer, DateTime\n\nDATABASE_URL = os.getenv('DATABASE_URL')\nBase: DeclarativeMeta = declarative_base()\n\nclass Account(Base):\n __tablename__ = 'app_account'\n id = Column(Integer, primary_key=True, nullable=False)\n timezone = Column(String(5), default='+0800')\n\nengine = create_async_engine(DATABASE_URL)\nasync_session_maker = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)\n\nasync def create_db_and_tables():\n async with engine.begin() as conn:\n await conn.run_sync(Base.metadata.create_all) # noqa\n\nasync def get_async_session() -> AsyncGenerator[AsyncSession, None]:\n async with async_session_maker() as session:\n yield session\n```\n\n**alembic.ini**\n\n```\nsqlalchemy.url = postgresql+asyncpg://foo:pass123@127.0.0.1:5432/foo\n```\n\n**env.py**\n\n```\n# add your model's MetaData object here\n# for 'autogenerate' support\nfrom models import Base\ntarget_metadata = Base.metadata\n```\n\nRunning `alembic revision --autogenerate`:\n\n```\nTraceback (most recent call last):\n File \"/home/dever/venv/systemapp-ne8n42/bin/alembic\", line 8, in \n sys.exit(main())\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/alembic/config.py\", line 590, in main\n CommandLine(prog=prog).main(argv=argv)\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/alembic/config.py\", line 584, in main\n self.run_cmd(cfg, options)\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/alembic/config.py\", line 561, in run_cmd\n fn(\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/alembic/command.py\", line 229, in revision\n script_directory.run_env()\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/alembic/script/base.py\", line 569, in run_env\n util.load_python_file(self.dir, \"env.py\")\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/alembic/util/pyfiles.py\", line 94, in load_python_file\n module = load_module_py(module_id, path)\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/alembic/util/pyfiles.py\", line 110, in load_module_py\n spec.loader.exec_module(module) # type: ignore\n File \"\", line 850, in exec_module\n File \"\", line 228, in _call_with_frames_removed\n File \"migrations/env.py\", line 77, in \n run_migrations_online()\n File \"migrations/env.py\", line 65, in run_migrations_online\n with connectable.connect() as connection:\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/engine/base.py\", line 3234, in connect\n return self._connection_cls(self, close_with_result=close_with_result)\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/engine/base.py\", line 96, in __init__\n else engine.raw_connection()\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/engine/base.py\", line 3313, in raw_connection\n return self._wrap_pool_connect(self.pool.connect, _connection)\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/engine/base.py\", line 3280, in _wrap_pool_connect\n return fn()\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/pool/base.py\", line 310, in connect\n return _ConnectionFairy._checkout(self)\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/pool/base.py\", line 868, in _checkout\n fairy = _ConnectionRecord.checkout(pool)\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/pool/base.py\", line 476, in checkout\n rec = pool._do_get()\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/pool/impl.py\", line 256, in _do_get\n return self._create_connection()\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/pool/base.py\", line 256, in _create_connection\n return _ConnectionRecord(self)\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/pool/base.py\", line 371, in __init__\n self.__connect()\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/pool/base.py\", line 666, in __connect\n pool.logger.debug(\"Error on connect(): %s\", e)\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/util/langhelpers.py\", line 70, in __exit__\n compat.raise_(\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/util/compat.py\", line 208, in raise_\n raise exception\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/pool/base.py\", line 661, in __connect\n self.dbapi_connection = connection = pool._invoke_creator(self)\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/engine/create.py\", line 590, in connect\n return dialect.connect(*cargs, **cparams)\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/engine/default.py\", line 597, in connect\n return self.dbapi.connect(*cargs, **cparams)\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py\", line 777, in connect\n await_only(self.asyncpg.connect(*arg, **kw)),\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/util/_concurrency_py3k.py\", line 59, in await_only\n raise exc.MissingGreenlet(\nsqlalchemy.exc.MissingGreenlet: greenlet_spawn has not been called; can't call await_only() here. Was IO attempted in an unexpected place? (Background on this error at: https://sqlalche.me/e/14/xd2s)\nsys:1: RuntimeWarning: coroutine 'connect' was never awaited\n```\n\nWhat can I try next?\n\n========================================\n\nCode:\n```py\nimport os\nfrom typing import AsyncGenerator\nfrom fastapi import Depends\nfrom fastapi_users.db import SQLAlchemyBaseUserTableUUID, SQLAlchemyUserDatabase\nfrom sqlalchemy.ext.asyncio import AsyncSession, create_async_engine\nfrom sqlalchemy.ext.declarative import DeclarativeMeta, declarative_base\nfrom sqlalchemy.orm import sessionmaker, relationship\nfrom sqlalchemy import Column, String, Integer, DateTime\n\n\nDATABASE_URL = os.getenv('DATABASE_URL')\nBase: DeclarativeMeta = declarative_base()\n\n\nclass Account(Base):\n __tablename__ = 'app_account'\n id = Column(Integer, primary_key=True, nullable=False)\n timezone = Column(String(5), default='+0800')\n\n\nengine = create_async_engine(DATABASE_URL)\nasync_session_maker = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)\n\n\nasync def create_db_and_tables():\n async with engine.begin() as conn:\n await conn.run_sync(Base.metadata.create_all) # noqa\n\n\nasync def get_async_session() -> AsyncGenerator[AsyncSession, None]:\n async with async_session_maker() as session:\n yield session\n```\n\n```ini\nsqlalchemy.url = postgresql+asyncpg://foo:pass123@127.0.0.1:5432/foo\n```\n\n```py\n# add your model's MetaData object here\n# for 'autogenerate' support\nfrom models import Base\ntarget_metadata = Base.metadata\n```\n\n```bash\nTraceback (most recent call last):\n File \"/home/dever/venv/systemapp-ne8n42/bin/alembic\", line 8, in <module>\n sys.exit(main())\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/alembic/config.py\", line 590, in main\n CommandLine(prog=prog).main(argv=argv)\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/alembic/config.py\", line 584, in main\n self.run_cmd(cfg, options)\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/alembic/config.py\", line 561, in run_cmd\n fn(\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/alembic/command.py\", line 229, in revision\n script_directory.run_env()\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/alembic/script/base.py\", line 569, in run_env\n util.load_python_file(self.dir, \"env.py\")\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/alembic/util/pyfiles.py\", line 94, in load_python_file\n module = load_module_py(module_id, path)\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/alembic/util/pyfiles.py\", line 110, in load_module_py\n spec.loader.exec_module(module) # type: ignore\n File \"<frozen importlib._bootstrap_external>\", line 850, in exec_module\n File \"<frozen importlib._bootstrap>\", line 228, in _call_with_frames_removed\n File \"migrations/env.py\", line 77, in <module>\n run_migrations_online()\n File \"migrations/env.py\", line 65, in run_migrations_online\n with connectable.connect() as connection:\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/engine/base.py\", line 3234, in connect\n return self._connection_cls(self, close_with_result=close_with_result)\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/engine/base.py\", line 96, in __init__\n else engine.raw_connection()\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/engine/base.py\", line 3313, in raw_connection\n return self._wrap_pool_connect(self.pool.connect, _connection)\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/engine/base.py\", line 3280, in _wrap_pool_connect\n return fn()\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/pool/base.py\", line 310, in connect\n return _ConnectionFairy._checkout(self)\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/pool/base.py\", line 868, in _checkout\n fairy = _ConnectionRecord.checkout(pool)\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/pool/base.py\", line 476, in checkout\n rec = pool._do_get()\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/pool/impl.py\", line 256, in _do_get\n return self._create_connection()\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/pool/base.py\", line 256, in _create_connection\n return _ConnectionRecord(self)\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/pool/base.py\", line 371, in __init__\n self.__connect()\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/pool/base.py\", line 666, in __connect\n pool.logger.debug(\"Error on connect(): %s\", e)\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/util/langhelpers.py\", line 70, in __exit__\n compat.raise_(\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/util/compat.py\", line 208, in raise_\n raise exception\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/pool/base.py\", line 661, in __connect\n self.dbapi_connection = connection = pool._invoke_creator(self)\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/engine/create.py\", line 590, in connect\n return dialect.connect(*cargs, **cparams)\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/engine/default.py\", line 597, in connect\n return self.dbapi.connect(*cargs, **cparams)\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py\", line 777, in connect\n await_only(self.asyncpg.connect(*arg, **kw)),\n File \"/home/dever/venv/systemapp-ne8n42/lib/python3.9/site-packages/sqlalchemy/util/_concurrency_py3k.py\", line 59, in await_only\n raise exc.MissingGreenlet(\nsqlalchemy.exc.MissingGreenlet: greenlet_spawn has not been called; can't call await_only() here. Was IO attempted in an unexpected place? (Background on this error at: https://sqlalche.me/e/14/xd2s)\nsys:1: RuntimeWarning: coroutine 'connect' was never awaited\n```\n\n```text\nsqlalchemy.exc.MissingGreenlet: greenlet_spawn has not been called; can't call await_only() here. Was IO attempted in an unexpected place? (Background on this error at: https://sqlalche.me/e/14/xd2s) sys:1: RuntimeWarning: coroutine 'connect' was never awaited\n```\n\n```text\nrun_migrations_offline()\n```\n\n```text\nrun_migrations_online()\n```\n\n```text\nasync\n```\n\n```text\nasyncio.run()\n```\n\n```text\nalembic revision --autogenerate\n```\n\n```bash\nalembic init -t async migrations\n```\n\n```text\nasync\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.129Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":12,"totalLines":276,"estimatedTokens":3364}}405{"id":"stack-62724697","source":"stackoverflow","questionId":62724697,"title":"Python Fastapi with existing database?","tags":["python","postgresql","fastapi","rest"],"text":"Title: Python Fastapi with existing database?\nTags: python, postgresql, fastapi, rest\nSource: Stack Overflow\n\nQuestion:\nI'm learning to use fastapi with postgresql. I have a huge database from other project and its already complete as postgre database... so I try to add fastapi but don't know how can I do this... it seems that you must create all the db schemas with fastapi right from the start... I can't find any helpfull example so I hope you can guide me. Thank you for your time and excuse my english","metadata":{"transformedAt":"2026-08-18T18:32:29.129Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":0,"totalLines":6,"estimatedTokens":127}}406{"id":"stack-64168340","source":"stackoverflow","questionId":64168340,"title":"How to send a file (docx, doc, pdf or json) to fastapi and predict on it without UI (i.e., HTML)?","tags":["python","python-3.x","fastapi"],"text":"Title: How to send a file (docx, doc, pdf or json) to fastapi and predict on it without UI (i.e., HTML)?\nTags: python, python-3.x, fastapi\nSource: Stack Overflow\n\nQuestion:\nIf you know how to send a file to FastAPI server and access it in /predict endpoint for prediction using my models please help me out.\n\nI have deployed the model using /predict endpoint and done `uvicorn main:app` and it's deployed but the only thing is input that is a document is in my local pc so how can I sent it to FastAPI?\n\nI have went through the documentation of FastAPI and I have found this example code there, but the challenge is that this code creates an UI for uploading file which is not what I\"m looking for.\n\n```\nfrom typing import Optional\nfrom fastapi import FastAPI\nfrom fastapi import FastAPI, File, UploadFile\nfrom pydantic import BaseModel\nfrom typing import List\nfrom fastapi.responses import HTMLResponse\n\napp = FastAPI()\n\nclass User(BaseModel):\n user_name: dict\n\n@app.post(\"/files/\")\nasync def create_files(files: List[bytes] = File(...)):\n return {\"file_sizes\": [len(file) for file in files]}\n\n@app.post(\"/uploadfiles/\")\nasync def create_upload_files(files: List[UploadFile] = File(...)):\n return {\"filenames\": [file.filename for file in files]}\n\n@app.get(\"/\")\nasync def main():\n content = \"\"\"\n\n \"\"\"\n return HTMLResponse(content=content)\n```\n\n========================================\n\nCode:\n```text\nfrom typing import Optional\nfrom fastapi import FastAPI\nfrom fastapi import FastAPI, File, UploadFile\nfrom pydantic import BaseModel\nfrom typing import List\nfrom fastapi.responses import HTMLResponse\n\n\napp = FastAPI()\n\nclass User(BaseModel):\n user_name: dict\n\n@app.post(\"/files/\")\nasync def create_files(files: List[bytes] = File(...)):\n return {\"file_sizes\": [len(file) for file in files]}\n\n\n@app.post(\"/uploadfiles/\")\nasync def create_upload_files(files: List[UploadFile] = File(...)):\n return {\"filenames\": [file.filename for file in files]}\n\n\n@app.get(\"/\")\nasync def main():\n content = \"\"\"\n<body>\n<form action=\"/files/\" enctype=\"multipart/form-data\" method=\"post\">\n<input name=\"files\" type=\"file\" multiple>\n<input type=\"submit\">\n</form>\n</body>\n \"\"\"\n return HTMLResponse(content=content)\n```\n\n```text\nuvicorn main:app\n```\n\n```text\nfrom fastapi import FastAPI, UploadFile, File\n\n\napp = FastAPI()\n\n\n@app.post(\"/file\")\nasync def upload_file(file: UploadFile = File(...)):\n # Do here your stuff with the file\n return {\"filename\": file.filename}\n```\n\n```text\nform = new FormData();\nform.append(\"file\", myFile);\nlet response = await fetch('/file', {\n method: 'POST',\n body: form\n });\n\n let result = await response.json();\n```\n\n```text\nimport httpx\n# Create a dict with a key that has the same name as your file parameter and the file in binary form (the \"b\" in \"rb\")\nf = {'file': open('foo.png', 'rb')}\nr = httpx.post(\"your_url/file\", files=f)\n```\n\n```text\nhttpx\n```\n\n```text\nrequests\n```\n\n```text\nhttpx\n```\n\n========================================\n\nComments:\n- You need to upload one file or multiple files at once?\n- @Isabi Currently I just need to know how to send one file at once without UI page and access that file in /predict endpoint.\n- Future readers may also find this answer, as well as this answer and this answer helpful.\n- Thank you so much for helping out. I'll test it out with my code.\n- Take my code with a grain of salt, it's not perfect, but should be enough for you to get the idea of what and how your code could look like. FastAPI docs are good, keep an eye on them\n- The docs are a good source to be checked first. You can simply use uploadedFile.file to access the file content. See reference fastapi.tiangolo.com/tutorial/request-files/#uploadfile\n- Thank you `uploadedFile.file` worked for me but that is not the main issue for me, I have an another endpoint called `@app.post(\"/predict\")` predict function so how can I access the output from /file endpoint in predict function\n- You have to save the uploaded file and then read it when the \"predict\" endpoint gets called. Although my suggestion is to not defer the ML training and to do it immediately. Also, if you still have questions different from the currently asked one, please open another question with details","metadata":{"transformedAt":"2026-08-18T18:32:29.129Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":8,"totalLines":138,"estimatedTokens":1060}}407{"id":"stack-75711757","source":"stackoverflow","questionId":75711757,"title":"FastAPI GET endpoint returns \"405 method not allowed\" response","tags":["python","rest","fastapi","http-status-code-405"],"text":"Title: FastAPI GET endpoint returns \"405 method not allowed\" response\nTags: python, rest, fastapi, http-status-code-405\nSource: Stack Overflow\n\nQuestion:\nA `GET` endpoint in FastAPI is returning correct result, but returns `405 method not allowed` when `curl -I` is used. This is happening with all the `GET` endpoints. As a result, the application is working, but health check on application from a load balancer is failing.\n\nAny suggestions what could be wrong?\n\n**code**\n\n```\n@app.get('/health')\nasync def health():\n \"\"\"\n Returns health status\n \"\"\"\n return JSONResponse({'status': 'ok'})\n```\n\n**result**\n\n```\ncurl http://172.xx.xx.xx:8080\n```\n\nhttps://i.sstatic.net/YHbiN.png\n\n**return header**\n\n```\ncurl -I http://172.xx.xx.xx:8080\n```\n\nhttps://i.sstatic.net/qFSo0.png\n\n========================================\n\nTop Answer:\nFastAPI has a bug. It allows a `GET` method on that path, not a `HEAD` method.\n\nThe `curl -I` option is equivalent to the `--head`. It sends an HTTP `HEAD` request.\n\nBecause the FastAPI server does not support the HEAD method, only the GET it correctly responds with a HTTP-405.\n\nThere is a workaround - to add manually defined `@app.head()`.\n\n========================================\n\nCode:\n```text\n@app.get('/health')\nasync def health():\n \"\"\"\n Returns health status\n \"\"\"\n return JSONResponse({'status': 'ok'})\n```\n\n```text\ncurl http://172.xx.xx.xx:8080\n```\n\n```text\ncurl -I http://172.xx.xx.xx:8080\n```\n\n```text\nGET\n```\n\n```text\n405 method not allowed\n```\n\n```text\ncurl -I\n```\n\n```text\nGET\n```\n\n```py\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get('/')\nasync def main():\n return {'Hello': 'World'}\n```\n\n```py\nimport requests\n\n# Making a GET request\n# r = requests.get('http://127.0.0.1:8000')\n \n# Making a HEAD request\nr = requests.head('http://127.0.0.1:8000')\n \n# check status code for response received\nprint(r.status_code, r.reason)\n \n# print headers of request\nprint(r.headers)\n \n# checking if request contains any content\nprint(r.content)\n```\n\n```json\n405 Method Not Allowed\n{'date': 'Sun, 12 Mar 2023', 'server': 'uvicorn', 'allow': 'GET', 'content-length': '31', 'content-type': 'application/json'}\nb''\n```\n\n```json\n200 OK\n{'date': 'Sun, 12 Mar 2023', 'server': 'uvicorn', 'content-length': '17', 'content-type': 'application/json'}\nb'{\"Hello\":\"World\"}'\n```\n\n```py\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.head('/')\nasync def main_1():\n pass\n\n\n@app.get('/')\nasync def main_2():\n pass\n```\n\n```py\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.head('/')\n@app.get('/')\nasync def main():\n return {'msg': 'Hello World'}\n```\n\n```py\nfrom fastapi import FastAPI\n\napp = FastAPI()\n \n@app.api_route('/', methods=['GET', 'HEAD'])\nasync def main():\n return {'msg': 'Hello World'}\n```\n\n```json\n200 OK\n{'date': 'Sun, 12 Mar 2023', 'server': 'uvicorn', 'content-length': '17', 'content-type': 'application/json'}\nb''\n```\n\n```py\nfrom fastapi import FastAPI, Request\n\napp = FastAPI()\n \n@app.api_route('/', methods=['GET', 'HEAD'])\nasync def main(request: Request):\n if request.method == 'GET':\n print('GET method was used')\n elif request.method == 'HEAD':\n print('HEAD method was used')\n \n return {'msg': 'Hello World'}\n```\n\n```text\ncurl -I\n```\n\n```text\ncurl --head\n```\n\n```text\nHEAD\n```\n\n```text\nHEAD\n```\n\n```text\nHEAD\n```\n\n```text\nGET\n```\n\n```text\nHEAD\n```\n\n```text\nContent-Length\n```\n\n```text\nGET\n```\n\n```text\n405 Method Not Allowed\n```\n\n```text\ncurl -I http://127.0.0.1:8000\n```\n\n```text\nallow\n```\n\n```text\nGET\n```\n\n```text\nGET\n```\n\n```text\nGET\n```\n\n```text\nHEAD\n```\n\n```text\ncurl\n```\n\n```text\ncurl http://127.0.0.1:8000\n```\n\n```text\nGET\n```\n\n```text\nHEAD\n```\n\n```text\n@app.head()\n```\n\n```text\n@app.get()\n```\n\n```text\n@app.api_route()\n```\n\n```text\nHEAD\n```\n\n```text\n.method\n```\n\n```text\nRequest\n```\n\n```text\njson()\n```\n\n```text\nHEAD\n```\n\n```text\nHEAD\n```\n\n```text\nr.json()\n```\n\n```text\nprint(r.content)\n```\n\n```text\nHEAD\n```\n\n```text\n405 Method Not Allowed\n```\n\n```text\nGET\n```\n\n```text\nHEAD\n```\n\n```text\ncurl -I\n```\n\n```text\n--head\n```\n\n```text\nHEAD\n```\n\n```text\n@app.head()\n```\n\n========================================\n\nComments:\n- Does this answer your question? FastAPI rejecting POST request from javascript code but not from a 3rd party request application (insomnia)\n- Please have a look at related answers here, as well as here and here.\n- @Chris thanks. all your suggestions here are pertaining to PUT request being passed as GET. My request is GET to begin with and despite that i am seeing issues.","metadata":{"transformedAt":"2026-08-18T18:32:29.129Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":55,"totalLines":343,"estimatedTokens":1128}}408{"id":"stack-74366289","source":"stackoverflow","questionId":74366289,"title":"How to add drop down menu to Swagger UI autodocs based on BaseModel using FastAPI?","tags":["python","swagger","fastapi","swagger-ui","openapi"],"text":"Title: How to add drop down menu to Swagger UI autodocs based on BaseModel using FastAPI?\nTags: python, swagger, fastapi, swagger-ui, openapi\nSource: Stack Overflow\n\nQuestion:\nI have this following class:\n\n```\nclass Quiz(BaseModel):\n question: str\n subject: str\n choice: str = Query(choices=('eu', 'us', 'cn', 'ru'))\n```\n\nI can render the form bases on this class like this\n\n```\n@api.post(\"/postdata\")\ndef post_data(form_data: Quiz = Depends()):\n return form_data\n```\n\nHow can I display a drop down list for choice field ?\n\n========================================\n\nCode:\n```text\nclass Quiz(BaseModel):\n question: str\n subject: str\n choice: str = Query(choices=('eu', 'us', 'cn', 'ru'))\n```\n\n```text\n@api.post(\"/postdata\")\ndef post_data(form_data: Quiz = Depends()):\n return form_data\n```\n\n```py\nfrom fastapi import FastAPI, Depends\nfrom pydantic import BaseModel\nfrom typing import Literal\n\napp = FastAPI()\n \nclass Quiz(BaseModel):\n question: str\n subject: str\n choice: Literal['eu', 'us', 'cn', 'ru'] = 'us'\n\n@app.post('/submit')\ndef post_data(data: Quiz = Depends()):\n return data\n```\n\n```py\nfrom fastapi import FastAPI, Depends\nfrom pydantic import BaseModel\nfrom enum import Enum\n\napp = FastAPI()\n\nclass Country(str, Enum):\n eu = 'eu'\n us = 'us'\n cn = 'cn'\n ru = 'ru'\n \nclass Quiz(BaseModel):\n question: str\n subject: str\n choice: Country = Country.us\n \n@app.post('/submit')\ndef post_data(data: Quiz = Depends()):\n return data\n```\n\n```text\nLiteral\n```\n\n```text\nEnums\n```\n\n```text\nenum\n```\n\n```text\nEnum\n```\n\n```text\nstr\n```\n\n```text\nstring\n```\n\n========================================\n\nComments:\n- what is your frontend framework?\n- I am using OpenAPI (/docs)\n- but in this way, by using `data: Quiz = Depends()` all attributes turn into query parameters, and without `Depends()` they turn into a body without any drop-down menu in swagger. So is there any approach to having a body with a drop-down for the `choice` attribute?! or how can I have a query drop-down just for `choice` and a body for the rest attributes? I think I should have two pydantic schema, isn't it?","metadata":{"transformedAt":"2026-08-18T18:32:29.129Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":10,"totalLines":110,"estimatedTokens":534}}409{"id":"stack-79158433","source":"stackoverflow","questionId":79158433,"title":"FastAPI & Pytest. Got Future attached to a different loop","tags":["sqlalchemy","pytest","python-asyncio","fastapi","pytest-asyncio"],"text":"Title: FastAPI & Pytest. Got Future attached to a different loop\nTags: sqlalchemy, pytest, python-asyncio, fastapi, pytest-asyncio\nSource: Stack Overflow\n\nQuestion:\nThe problem is this. I get an error when I try to make tests for my FastAPI application.\n\n```\nFAILED tests/test_users_api.py::test_create_jwt - RuntimeError: Task cb=[_run_until_complete_cb() at /usr/local/lib/python3.12/asyncio/base_events.py:182]> got Future attached to a different loop\nFAILED tests/test_users_api.py::test_create_user_with_valid_data - RuntimeError: Task cb=[_run_until_complete_cb() at /usr/local/lib/python3.12/asyncio/base_events.py:182]> got Future attached to a different loop\n```\n\nThe error occurs when testing those functions where I work with the database via sqlalchemy.\n\nHere is the code for my db sessions and dependency_override for FastAPI:\n\n```\n@pytest_asyncio.fixture(scope=\"session\")\nasync def engine(app_database_url, migrations) -> AsyncEngine:\n engine = create_async_engine(app_database_url)\n yield engine\n await engine.dispose()\n\n@pytest_asyncio.fixture\nasync def db_session(engine) -> AsyncGenerator[AsyncSession, None]:\n async with engine.connect() as connection:\n transaction = await connection.begin()\n session = AsyncSession(bind=connection, join_transaction_mode=\"create_savepoint\", expire_on_commit=False)\n try:\n yield session\n except Exception:\n await session.rollback()\n raise\n finally:\n await session.close()\n await transaction.rollback()\n await connection.close()\n\n@pytest.fixture\ndef session_override(db_session):\n\n async def get_session_override() -> AsyncGenerator[AsyncSession, None]:\n yield db_session\n\n main_app.dependency_overrides[db_helper.get_session] = get_session_override\n```\n\nMy AsyncClient\n\n```\n@pytest_asyncio.fixture\nasync def client(session_override) -> AsyncGenerator[AsyncClient, None]:\n async with AsyncClient(app=main_app, base_url=\"http://localhost:8000\") as ac:\n yield ac\n```\n\nI tried making my fixture for event_loop\n\n```\n@pytest.fixture(scope=\"session\")\ndef event_loop():\n loop = asyncio.get_event_loop_policy().new_event_loop()\n yield loop\n loop.close()\n```\n\nBut this did not change the situation\n\nMy pyproject.toml section with pytest settings\n\n```\n[tool.pytest.ini_options]\naddopts = [\n \"-vvv\",\n \"--cov=app\", \n \"--cov-report=term-missing\", \n \"--cov-config=pyproject.toml\"\n]\npython_files = \"test_*.py\"\nfilterwarnings = [\n \"ignore::DeprecationWarning\",\n \"ignore::SyntaxWarning\",\n]\npythonpath = [\n \".\", \"backend\",\n]\n\nasyncio_mode=\"auto\"\nasyncio_default_fixture_loop_scope = \"session\"\n```\n\nProject github https://github.com/DenisMaslennikov/to-do-list-FastAPI\n\n========================================\n\nTop Answer:\nsolved this problem by adding `asyncio` decorator with `loop_scope=\"session\"` for each test case, like:\n\n```\nimport pytest\n\n@pytest.mark.asyncio(loop_scope=\"session\")\nasync def test_some_func():\n pass\n```\n\n========================================\n\nCode:\n```text\nFAILED tests/test_users_api.py::test_create_jwt - RuntimeError: Task <Task pending name='Task-153' coro=<test_create_jwt() running at /backend/tests/test_users_api.py:22> cb=[_run_until_complete_cb() at /usr/local/lib/python3.12/asyncio/base_events.py:182]> got Future <Future pending cb=[BaseProtocol._on_waiter_completed()]> attached to a different loop\nFAILED tests/test_users_api.py::test_create_user_with_valid_data - RuntimeError: Task <Task pending name='Task-179' coro=<test_create_user_with_valid_data() running at /backend/tests/test_users_api.py:122> cb=[_run_until_complete_cb() at /usr/local/lib/python3.12/asyncio/base_events.py:182]> got Future <Future pending cb=[BaseProtocol._on_waiter_completed()]> attached to a different loop\n```\n\n```text\n@pytest_asyncio.fixture(scope=\"session\")\nasync def engine(app_database_url, migrations) -> AsyncEngine:\n engine = create_async_engine(app_database_url)\n yield engine\n await engine.dispose()\n\n\n@pytest_asyncio.fixture\nasync def db_session(engine) -> AsyncGenerator[AsyncSession, None]:\n async with engine.connect() as connection:\n transaction = await connection.begin()\n session = AsyncSession(bind=connection, join_transaction_mode=\"create_savepoint\", expire_on_commit=False)\n try:\n yield session\n except Exception:\n await session.rollback()\n raise\n finally:\n await session.close()\n await transaction.rollback()\n await connection.close()\n\n\n@pytest.fixture\ndef session_override(db_session):\n\n async def get_session_override() -> AsyncGenerator[AsyncSession, None]:\n yield db_session\n\n main_app.dependency_overrides[db_helper.get_session] = get_session_override\n```\n\n```text\n@pytest_asyncio.fixture\nasync def client(session_override) -> AsyncGenerator[AsyncClient, None]:\n async with AsyncClient(app=main_app, base_url=\"http://localhost:8000\") as ac:\n yield ac\n```\n\n```text\n@pytest.fixture(scope=\"session\")\ndef event_loop():\n loop = asyncio.get_event_loop_policy().new_event_loop()\n yield loop\n loop.close()\n```\n\n```text\n[tool.pytest.ini_options]\naddopts = [\n \"-vvv\",\n \"--cov=app\", \n \"--cov-report=term-missing\", \n \"--cov-config=pyproject.toml\"\n]\npython_files = \"test_*.py\"\nfilterwarnings = [\n \"ignore::DeprecationWarning\",\n \"ignore::SyntaxWarning\",\n]\npythonpath = [\n \".\", \"backend\",\n]\n\nasyncio_mode=\"auto\"\nasyncio_default_fixture_loop_scope = \"session\"\n```\n\n```text\n@pytest_asyncio.fixture(scope=\"session\")\nasync def engine(app_database_url, migrations) -> AsyncEngine:\n\"\"\"Creates a SQLAlchemy engine to interact with the database.\"\"\"\n\nengine = create_async_engine(app_database_url)\nyield engine\nawait engine.dispose()\n```\n\n```text\nscope=\"session\"\n```\n\n```text\n@pytest.fixture(scope='session')\ndef event_loop():\n loop = asyncio.new_event_loop()\n asyncio.set_event_loop(loop)\n yield loop\n loop.close()\n```\n\n```text\n@asynccontextmanager\nasync def get_root_engine():\n engine = create_async_engine(ROOT_DATABASE_URL, echo=True)\n try:\n yield engine\n finally:\n await engine.dispose()\n\n@asynccontextmanager\nasync def get_root_async_session():\n engine = create_async_engine(ROOT_DATABASE_URL, echo=True)\n async_session = sessionmaker(engine, expire_on_commit=False, class_=AsyncSession)\n async with async_session() as session:\n try:\n yield session\n finally:\n await session.close()\n await engine.dispose()\n```\n\n```text\n# pytest.ini\n[pytest]\nasyncio_mode=auto\n```\n\n```text\nimport pytest\n\npytestmark = pytest.mark.asyncio\n\n# Your tests go here\n```\n\n```text\nconftest.py\n```\n\n```text\n@pytest.fixture(scope='session', autouse=True)\ndef event_loop():\n loop = asyncio.new_event_loop()\n asyncio.set_event_loop(loop)\n yield loop\n loop.close()\n```\n\n```text\nautouse=True\n```\n\n```text\n@pytest.mark.asyncio(loop_scope=\"session\")\nclass MyTestGroup:\n async def test_A(self):\n ...\n\n async def test_B(self):\n ...\n```\n\n```text\nevent_loop\n```\n\n```text\npytest-asyncio\n```\n\n```text\nloop_scope\n```\n\n```text\nimport pytest\n\n@pytest.mark.asyncio(loop_scope=\"session\")\nasync def test_some_func():\n pass\n```\n\n```text\nasyncio\n```\n\n```text\nloop_scope=\"session\"\n```\n\n```text\ncreate_async_engine(\n ...\n poolclass=NullPool\n ...\n)\n```\n\n```text\n@pytest.fixture(scope=\"session\")\ndef event_loop():\n policy = asyncio.get_event_loop_policy()\n loop = policy.new_event_loop()\n yield loop\n loop.close()\n```\n\n```text\n@pytest_asyncio.fixture(loop_scope=\"session\", scope=\"session\", autouse=True)\nasync def prepare_db():\n```\n\n```text\npoolclass=AsyncAdaptedQueuePool\n```\n\n```text\npool_size\n```\n\n```text\nmax_overflow\n```\n\n```text\ncreate_async_engine\n```\n\n```text\nNullPool\n```\n\n```text\nAsyncAdaptedQueuePool\n```\n\n```text\nloop_scope=\"session\"\n```\n\n```text\n@pytest_asyncio.fixture(scope=\"session\", autouse=True)\n```\n\n```text\nengine\n```\n\n```text\nsession\n```\n\n```text\nsqlalchemy\n```\n\n```text\nasync def func()\n```\n\n```text\ndef event_loop()\n```\n\n========================================\n\nComments:\n- Thanks for the answer. I tried adding your fixture and unfortunately I still get the same error.\n- @DenisMaslennikov updated the comment take a look again if that helps\n- Thanks again. But unfortunately this won't help. 1) I have asyncio_mode=auto set 2) I have pytest.mark.asyncio on all tests. 3) I do not reuse the session from the app, but this is necessary to correctly rollback changes from tests and ensure test isolation (I don't think that's the problem).\n- Unfortunately it didn't help. Could you provide your pytest.ini? I noticed that changing the setting \"asyncio_default_fixture_loop_scope = \"session\"\" changes the error when using your fixture to \"RuntimeError: There is no current event loop in thread 'MainThread'.\" Maybe the problem is with my settings file.\n- I'm using pyproject.toml with config for pytest: ~~~ [tool.pytest.ini_options] addopts = \"--maxfail=2 -vv\" testpaths = \"tests\" filterwarnings = [ \"ignore::DeprecationWarning\", ] asyncio_mode = \"auto\" asyncio_default_fixture_loop_scope = \"session\" ~~~ my versions: ``` pytest version = 8.3.4 pytest-asyncio=0.25.0 ```\n- Thanks. Maybe this is a step in the right direction. Now I have another error: ERROR tests/test_users_api.py - pytest_asyncio.plugin.MultipleEventLoopsRequestedError: Multiple asyncio event loops with different scopes have been requested by tests/test_users_api.py::test_create_jwt. The test explicitly requests the event_loop fixture, while another event loop with session scope is provided by . ... I'll look for where another event loop is created in my fixtures.\n- Glad to see your problem is resolved! Thanks for the advice, I have removed the fixture and test functions scopes and it works as well. Also updated asyncio_default_fixture_loop_scope=\"function\" in the pyproject.toml configuration file\n- Thanks. Had to come to stack-overflow when LLM didnot resolved the issue😄😄","metadata":{"transformedAt":"2026-08-18T18:32:29.129Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":37,"totalLines":381,"estimatedTokens":2479}}410{"id":"stack-70952692","source":"stackoverflow","questionId":70952692,"title":"How to customize error response in FastAPI?","tags":["python","json","error-handling","fastapi","pydantic"],"text":"Title: How to customize error response in FastAPI?\nTags: python, json, error-handling, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI have the following FastAPI backend:\n\n```\nfrom fastapi import FastAPI\n\napp = FastAPI\n\nclass Demo(BaseModel):\n content: str = None\n \n@app.post(\"/demo\")\nasync def demoFunc(d:Demo):\n return d.content\n```\n\nThe issue is that when I send a request to this API with extra data like:\n\n```\ndata = {\"content\":\"some text here\"}aaaa\n```\n\nor\n\n```\ndata = {\"content\":\"some text here\"aaaaaa}\n\nresp = requests.post(url, json=data)\n```\n\nit throws an error with status code `422 unprocessable entity` error with Actual(\"some text here\") and Extra(\"aaaaa\") data in the return field in case of `data = {\"content\":\"some text here\"}aaaa`:\n\n```\n{\n \"detail\": [\n {\n \"loc\": [\n \"body\",\n 47\n ],\n \"msg\": \"Extra data: line 4 column 2 (char 47)\",\n \"type\": \"value_error.jsondecode\",\n \"ctx\": {\n \"msg\": \"Extra data\",\n \"doc\": \"{\\n \\\"content\\\": \\\"some text here\\\"}aaaaa\",\n \"pos\": 47,\n \"lineno\": 4,\n \"colno\": 2\n }\n }\n ]\n}\n```\n\nI tried to put the line `app=FastAPI()` in a try-catch block, however, it doesn't work. Is there any way I can handle this issue with own response instead of the above mentioned auto response?\nSomething like this:\n\n```\n{\"error\": {\"message\": \"Invalid JSON body\"},\n \"status\": 0}\n```\n\n========================================\n\nTop Answer:\nI personally use this code to translate error messages into Farsi (Persian) and Spanish:\n\n```\nfrom logging import getLogger\nfrom re import subn\nfrom traceback import format_exc\n\nfrom fastapi import (\n FastAPI,\n Request,\n status,\n Response,\n)\nfrom fastapi.exceptions import RequestValidationError\n\nlogger = getLogger(__name__)\nvalidation_error_message_cache = {}\n\napp = FastAPI()\n\n@app.exception_handler(RequestValidationError)\nasync def handler_for_validation_error(\n request: Request,\n exc: RequestValidationError,\n) -> Response:\n exe_error = exc.errors()\n try:\n for i in exe_error:\n i['msg'] = translate(\n error_msg=i['msg'],\n error_language='farsi',\n )\n except Exception:\n logger.warning(\n \"Exception occurred when translating this error message: %s \\n %s\",\n exe_error,\n format_exc(),\n )\n\n return Response(\n status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,\n content={\n \"success\": False,\n \"data\": None,\n \"error\": exe_error,\n \"message\": 'یه چیزی کز خورد!',\n }\n )\n\ndef translate(\n error_msg: str,\n error_language: str,\n):\n cache_key = f\"{error_language}_{error_msg}\"\n if cache_key in validation_error_message_cache:\n return validation_error_message_cache[cache_key]\n\n for key, value in VALIDATION_REGEX_MESSAGE_DICT.items():\n try:\n output_msg, count = subn(\n key,\n value[error_language],\n error_msg,\n )\n if count:\n validation_error_message_cache[cache_key] = output_msg\n return output_msg\n\n except Exception:\n logger.warning(\n \"Exception occurred when translating by this regex: %s \\n %s\",\n key,\n format_exc(),\n )\n\n logger.warning(\"Cannot find translation for this error message: %s\", error_msg)\n\n return error_msg\n\nVALIDATION_REGEX_MESSAGE_DICT = {\n r'^String should have at least (?P.+) characters$': {\n 'farsi': r\"متن باید حداقل \\g حرف داشته باشد.\",\n 'spanish': r\"La cadena debe tener al menos (?P.+) caracteres.\",\n },\n \n r'^String should have at most (?P.+) characters$': {\n 'farsi': r\"متن میتواند حداکثر \\g حرف داشته باشد.\",\n 'spanish': r\"La cadena debe tener como máximo (?P.+) caracteres.\",\n },\n\n r'^String should match pattern (?P.+)$': {\n 'farsi': r\"متن باید متناسب با این الگو باشد: \\g\",\n 'spanish': r\"La cadena debe coincidir con el patrón (?P.+).\",\n },\n}\n```\n\nPlease consider that:\n\n- `VALIDATION_REGEX_MESSAGE_DICT` can be changed and extended to include other types of error messages.\n\n- This solution is almost suggested by pydantic.\n\n- Other keys and values like `ctx`,`input`,`loc`,`type` and `url` can also change by this method.\n\n- Python regex is fast enough, but I use a cache dictionary `validation_error_message_cache` to make this handler faster.\n\n- Some errors can be found in `pydantic.v1.errors`\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\n\napp = FastAPI\n\nclass Demo(BaseModel):\n content: str = None\n \n@app.post(\"/demo\")\nasync def demoFunc(d:Demo):\n return d.content\n```\n\n```text\ndata = {\"content\":\"some text here\"}aaaa\n```\n\n```text\ndata = {\"content\":\"some text here\"aaaaaa}\n\nresp = requests.post(url, json=data)\n```\n\n```text\n{\n \"detail\": [\n {\n \"loc\": [\n \"body\",\n 47\n ],\n \"msg\": \"Extra data: line 4 column 2 (char 47)\",\n \"type\": \"value_error.jsondecode\",\n \"ctx\": {\n \"msg\": \"Extra data\",\n \"doc\": \"{\\n \\\"content\\\": \\\"some text here\\\"}aaaaa\",\n \"pos\": 47,\n \"lineno\": 4,\n \"colno\": 2\n }\n }\n ]\n}\n```\n\n```text\n{\"error\": {\"message\": \"Invalid JSON body\"},\n \"status\": 0}\n```\n\n```text\n422 unprocessable entity\n```\n\n```text\ndata = {\"content\":\"some text here\"}aaaa\n```\n\n```text\napp=FastAPI()\n```\n\n```py\nfrom fastapi import FastAPI, Body, Request, status\nfrom fastapi.encoders import jsonable_encoder\nfrom fastapi.exceptions import RequestValidationError\nfrom fastapi.responses import JSONResponse\nfrom pydantic import BaseModel\n\napp = FastAPI()\n\n\nclass Demo(BaseModel):\n content: str = None\n\n\n@app.exception_handler(RequestValidationError)\nasync def validation_exception_handler(request: Request, exc: RequestValidationError):\n return JSONResponse(\n status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,\n content=jsonable_encoder({\"detail\": exc.errors(), # optionally include the errors\n \"body\": exc.body,\n \"custom msg\": {\"Your error message\"}}),\n )\n\n\n@app.post(\"/demo\")\nasync def some_func(d: Demo):\n return d.content\n```\n\n```py\nfrom fastapi.responses import PlainTextResponse\n\n@app.exception_handler(RequestValidationError)\nasync def validation_exception_handler(request, exc):\n return PlainTextResponse(str(exc), status_code=422)\n```\n\n```text\n422 Unprocessable Entity\n```\n\n```text\ninvalid syntax\n```\n\n```text\n/docs\n```\n\n```text\nRequestValidationError\n```\n\n```text\nPlainTextResponse\n```\n\n```py\nfrom fastapi import status\nfrom fastapi.responses import JSONResponse\nfrom fastapi.exceptions import RequestValidationError\n\n\napp = FastAPI()\n\n@app.exception_handler(RequestValidationError)\nasync def validation_exception_handler(request: Request, exc: RequestValidationError):\n errors = exc.errors()\n response = []\n for error in errors:\n if error['type'] == 'value_error.jsondecode':\n response.append({'error': {'message': 'Invalid JSON body'}, 'status': 0})\n else:\n response.append(error)\n return JSONResponse(content=response, status_code=status.HTTP_422_UNPROCESSABLE_ENTITY)\n```\n\n```text\nloads\n```\n\n```text\njson\n```\n\n```py\nfrom logging import getLogger\nfrom re import subn\nfrom traceback import format_exc\n\nfrom fastapi import (\n FastAPI,\n Request,\n status,\n Response,\n)\nfrom fastapi.exceptions import RequestValidationError\n\nlogger = getLogger(__name__)\nvalidation_error_message_cache = {}\n\napp = FastAPI()\n\n\n@app.exception_handler(RequestValidationError)\nasync def handler_for_validation_error(\n request: Request,\n exc: RequestValidationError,\n) -> Response:\n exe_error = exc.errors()\n try:\n for i in exe_error:\n i['msg'] = translate(\n error_msg=i['msg'],\n error_language='farsi',\n )\n except Exception:\n logger.warning(\n \"Exception occurred when translating this error message: %s \\n %s\",\n exe_error,\n format_exc(),\n )\n\n return Response(\n status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,\n content={\n \"success\": False,\n \"data\": None,\n \"error\": exe_error,\n \"message\": 'یه چیزی کز خورد!',\n }\n )\n\n\ndef translate(\n error_msg: str,\n error_language: str,\n):\n cache_key = f\"{error_language}_{error_msg}\"\n if cache_key in validation_error_message_cache:\n return validation_error_message_cache[cache_key]\n\n for key, value in VALIDATION_REGEX_MESSAGE_DICT.items():\n try:\n output_msg, count = subn(\n key,\n value[error_language],\n error_msg,\n )\n if count:\n validation_error_message_cache[cache_key] = output_msg\n return output_msg\n\n except Exception:\n logger.warning(\n \"Exception occurred when translating by this regex: %s \\n %s\",\n key,\n format_exc(),\n )\n\n logger.warning(\"Cannot find translation for this error message: %s\", error_msg)\n\n return error_msg\n\n\nVALIDATION_REGEX_MESSAGE_DICT = {\n r'^String should have at least (?P<length>.+) characters$': {\n 'farsi': r\"متن باید حداقل \\g<length> حرف داشته باشد.\",\n 'spanish': r\"La cadena debe tener al menos (?P<longitud>.+) caracteres.\",\n },\n \n r'^String should have at most (?P<length>.+) characters$': {\n 'farsi': r\"متن میتواند حداکثر \\g<length> حرف داشته باشد.\",\n 'spanish': r\"La cadena debe tener como máximo (?P<longitud>.+) caracteres.\",\n },\n\n r'^String should match pattern (?P<pattern>.+)$': {\n 'farsi': r\"متن باید متناسب با این الگو باشد: \\g<pattern>\",\n 'spanish': r\"La cadena debe coincidir con el patrón (?P<patrón>.+).\",\n },\n}\n```\n\n```text\nVALIDATION_REGEX_MESSAGE_DICT\n```\n\n```text\nctx\n```\n\n```text\ninput\n```\n\n```text\nloc\n```\n\n```text\ntype\n```\n\n```text\nurl\n```\n\n```text\nvalidation_error_message_cache\n```\n\n```text\npydantic.v1.errors\n```\n\n========================================\n\nComments:\n- What do you expect the result to be? This is invalid JSON, so how do you want to parse that?\n- I want to show custom response instead of the auto response from the api itself.\n- Have you seen fastapi.tiangolo.com/tutorial/handling-errors - it tells you how to override specific errors and handle the response yourself.\n- I saw that but was not able to get it properly. But It is solved now thanks to Chris, Thank you too @MatsLindh\n- I know its a invalid JSON data and that is the whole point. Actually it is the case of Cross-Site Scripting test, where a tester uses different method to get information in using the request body itself. For example one can put a script in request body like : `{\"content\":\"some text\"}/*+Bad+script+here...+*/` So, I know that the API will throw 422 error, but it also returns the request body itself which I don't want to show. That's why I asked how can I catch this and display my own error msg","metadata":{"transformedAt":"2026-08-18T18:32:29.129Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":27,"totalLines":466,"estimatedTokens":2653}}411{"id":"stack-69031990","source":"stackoverflow","questionId":69031990,"title":"How can I use both required and optional path parameters in a FastAPI endpoint?","tags":["python","fastapi"],"text":"Title: How can I use both required and optional path parameters in a FastAPI endpoint?\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI've read through the documentation and this doesn't seem to be working for me. I followed this doc. But I'm not sure if it's related to what I'm trying to do, I think this doc is for passing queries like this - `site.com/endpoint?keyword=test`\n\nHere's my goal: `api.site.com/test/(optional_field)`\n\nSo, if someone goes to the `/test` endpoint then it defaults the optional field to a parameter but if they add something there then it takes that as a input.\n\nWith that said, here's my code:\n\n```\n@app.get(\"/company/{company_ticker}/model/{financialColumn}\", dependencies=[Depends(api_counter)])\n async def myendpoint(\n company_ticker: str,\n financialColumn: Optional[str] = 'netincome',\n ..\n\n myFunction(company_ticker, financialColumn)\n```\n\nwhat I'm trying to do is if they just go to the endpoint without the optional flag then it defaults to 'netincome' but if they add something then financialColumn is set to that value.\n\nIs there something I can do?\n\n========================================\n\nCode:\n```text\n@app.get(\"/company/{company_ticker}/model/{financialColumn}\", dependencies=[Depends(api_counter)])\n async def myendpoint(\n company_ticker: str,\n financialColumn: Optional[str] = 'netincome',\n ..\n\n myFunction(company_ticker, financialColumn)\n```\n\n```text\nsite.com/endpoint?keyword=test\n```\n\n```text\napi.site.com/test/(optional_field)\n```\n\n```text\n/test\n```\n\n```text\n@app.get(\"/company/{company_ticker}/model/\", dependencies=[Depends(api_counter)])\n@app.get(\"/company/{company_ticker}/model/{financialColumn}\", dependencies=[Depends(api_counter)])\n async def myendpoint(\n company_ticker: str,\n financialColumn: Optional[str] = 'netincome'\n ):\n\n myFunction(company_ticker, financialColumn)\n```\n\n```text\n\"/company/{company_ticker}/model/\"\n```\n\n```text\n\"/company/{company_ticker}/model/blabla\"\n```\n\n```text\nmyendpoint\n```\n\n========================================\n\nComments:\n- I don't know if this helps. But did you tried this?. This is something I found in the test case, Not on the documentation.\n- In FastAPI, `path` parameters are **always** *required*, that is why FastAPI would respond with `{\"detail\":\"Not Found\"}` error, if you sent a request, for instance, to `/company/some_value/model` without including a value for the `financialColumn` parameter at the end. Please have a look at this answer and this answer for more details and solutions.\n- **Note** that in the case of `/company/{company_ticker}/model` route, `financialColumn` would become an optional **query** parameter (one could confirm that in Swagger UI autodocs at `/docs`); hence, depending on the requirements of one's project, that may or may not be an issue (Part 1/2).\n- If it is so critical for `financialColumn` to default to `netincome`, when `/company/{company_ticker}/model` route is called, as OP mentioned, then one should take precautions and perform a check on the route that was called, and then act accordingly, similar to the approach demonstrated in this answer, as a user could \"maliciously\" change that parameter's value by passing it in the query string, e.g., `.../model?financialColumn=whatever` (Part 2/2).","metadata":{"transformedAt":"2026-08-18T18:32:29.129Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":8,"totalLines":82,"estimatedTokens":841}}412{"id":"stack-73396611","source":"stackoverflow","questionId":73396611,"title":"How can you include path parameters in nested router w/ FastAPI?","tags":["python","fastapi"],"text":"Title: How can you include path parameters in nested router w/ FastAPI?\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nHow can I include one `APIRouter` inside another AND specify that some path param is a required prefix?\n\nFor context:\nLet's say I have the concept of an organization and a user. A user only belongs to one organization. My web app could be structured as follows:\n\n```\n├── web_app\n ├── endpoints\n ├── __init__.py # produces main_router by including other routers inside each other\n ├── organization.py # contains endpoints relevant to the organization\n ├── user.py # contains endpoints relevant to the user\n └── main.py # includes main_router in app\n```\n\nLet's assume I want to achieve basic CRUD functionality for organizations and users. My endpoints could look something like this:\n\nFor orgs:\n\n```\nGET /api/latest/org/{org_id}\nPOST /api/latest/org/{org_id}\nPUT /api/latest/org/{org_id}\nDELETE /api/latest/org/{org_id}\n```\n\nFor users:\n\n```\nGET /api/latest/org/{org_id}/users/{user_id}\nPOST /api/latest/org/{org_id}/users/{user_id}\nPUT /api/latest/org/{org_id}/users/{user_id}\nDELETE /api/latest/org/{org_id}/users/{user_id}\n```\n\nSince users are nested under orgs, within `user.py`, I *could* write all of my endpoints like this:\n\n```\nuser_router = APIRouter()\n@user_router.get(\"/org/{org_id}/users/{user_id}\")\nasync def get_user(org_id, user_id):\n ...\n```\n\nBut that gets gross really quick. The `user_router` is completely disjointed from the `org_router` even though one should be nested inside the other. If I make a change to the org router, I now need to change every single user router endpoint. God forbid I have something nested under users....\n\nSo as per my question, I was hoping something like this would work:\n\n```\n# user.py\nuser_router = APIRouter(prefix=\"/org/{org_id}/users\")\n@user_router.get(\"/{user_id}\")\nasync def get_user(org_id, user_id):\n```\n\n```\n# __init__.py\norg_router.include_router(user_router)\nmain_router = APIRouter(prefix=\"/api/latest/\")\nmain_router.include_router(org_router)\n```\n\nbut that gives me the following error:\n`AssertionError: Path params must be of one of the supported types`. I don't get the error if I remove `{org_id}` from the prefix, so I know `APIRouter(prefix=\"/org/{org_id}/users\")` is the problem.\n\nThis is the only documentation we get from FastAPI on the matter: https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-in-another\n\nIs what I'm looking for even possible? This seems like an extremely common situation so I'm curious what other folks do.\n\n========================================\n\nCode:\n```text\n├── web_app\n ├── endpoints\n ├── __init__.py # produces main_router by including other routers inside each other\n ├── organization.py # contains endpoints relevant to the organization\n ├── user.py # contains endpoints relevant to the user\n └── main.py # includes main_router in app\n```\n\n```text\nGET /api/latest/org/{org_id}\nPOST /api/latest/org/{org_id}\nPUT /api/latest/org/{org_id}\nDELETE /api/latest/org/{org_id}\n```\n\n```text\nGET /api/latest/org/{org_id}/users/{user_id}\nPOST /api/latest/org/{org_id}/users/{user_id}\nPUT /api/latest/org/{org_id}/users/{user_id}\nDELETE /api/latest/org/{org_id}/users/{user_id}\n```\n\n```py\nuser_router = APIRouter()\n@user_router.get(\"/org/{org_id}/users/{user_id}\")\nasync def get_user(org_id, user_id):\n ...\n```\n\n```py\n# user.py\nuser_router = APIRouter(prefix=\"/org/{org_id}/users\")\n@user_router.get(\"/{user_id}\")\nasync def get_user(org_id, user_id):\n```\n\n```text\n# __init__.py\norg_router.include_router(user_router)\nmain_router = APIRouter(prefix=\"/api/latest/\")\nmain_router.include_router(org_router)\n```\n\n```text\nAPIRouter\n```\n\n```text\nuser.py\n```\n\n```text\nuser_router\n```\n\n```text\norg_router\n```\n\n```text\nAssertionError: Path params must be of one of the supported types\n```\n\n```text\n{org_id}\n```\n\n```text\nAPIRouter(prefix=\"/org/{org_id}/users\")\n```\n\n```py\nfrom fastapi import APIRouter, FastAPI\n\napp = FastAPI()\n\n\n@app.get(\"/\")\nasync def root():\n return {\"hello\": \"world\"}\n\n\nrouter = APIRouter(prefix=\"/org/{org_id}\")\n\n\n@router.get(\"/users/{user_id}\")\ndef get_user(org_id: int, user_id: int):\n return {\"org\": org_id, \"user:\": user_id}\n\n\napp.include_router(router)\n\nif __name__ == \"__main__\":\n import uvicorn\n\n uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n```\n\n```text\n% curl localhost:8000/org/1/users/2\n{\"org\":1,\"user:\":2}%\n```\n\n```text\nAPIRoute\n```\n\n```text\nAPIRoute\n```\n\n```text\nAPIRoute\n```\n\n```text\nAPIRoute\n```\n\n```text\napp = FastAPI()\n```\n\n========================================\n\nComments:\n- Thank you for the reply! You're right this is totally doable. The `AssertionError` I was getting was because the path params *were* actually doing their job. I had some endpoints that were not yet expecting the new param types.","metadata":{"transformedAt":"2026-08-18T18:32:29.131Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":20,"totalLines":204,"estimatedTokens":1205}}413{"id":"stack-71731924","source":"stackoverflow","questionId":71731924,"title":"How to avoid blocking the asyncio event loop with looping functions","tags":["multithreading","websocket","multiprocessing","python-asyncio","fastapi"],"text":"Title: How to avoid blocking the asyncio event loop with looping functions\nTags: multithreading, websocket, multiprocessing, python-asyncio, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm using FastAPI with `WebSockets` to \"push\" SVGs to the client. **The problem is:** If iterations run continuously, they block the `async` event loop and the `socket` therefore can't listen to other messages.\n\nRunning the loop as a background task is not suitable, because each iteration is CPU heavy and the data must be returned to the client.\n\nIs there a different approach, or will I need to trigger each step from the client? I thought `multiprocessing` could work but not sure how this would work with *asynchronous* code like `await websocket.send_text()`.\n\n```\n@app.websocket(\"/ws\")\nasync def read_websocket(websocket: WebSocket) -> None:\n await websocket.accept()\n while True:\n data = await websocket.receive_text()\n\n async def run_continuous_iterations():\n #needed to run the steps until the user sends \"stop\"\n while True:\n svg_string = get_step_data()\n await websocket.send_text(svg_string) \n\n if data == \"status\":\n await run_continuous_iterations()\n #this code can't run if the event loop is blocked by run_continuous_iterations\n if data == \"stop\":\n is_running = False\n print(\"Stopping process\")\n```\n\n========================================\n\nCode:\n```py\n@app.websocket(\"/ws\")\nasync def read_websocket(websocket: WebSocket) -> None:\n await websocket.accept()\n while True:\n data = await websocket.receive_text()\n\n async def run_continuous_iterations():\n #needed to run the steps until the user sends \"stop\"\n while True:\n svg_string = get_step_data()\n await websocket.send_text(svg_string) \n\n if data == \"status\":\n await run_continuous_iterations()\n #this code can't run if the event loop is blocked by run_continuous_iterations\n if data == \"stop\":\n is_running = False\n print(\"Stopping process\")\n```\n\n```text\nWebSockets\n```\n\n```text\nasync\n```\n\n```text\nsocket\n```\n\n```text\nmultiprocessing\n```\n\n```text\nawait websocket.send_text()\n```\n\n```py\nfrom fastapi import WebSocket, WebSocketDisconnect\nfrom websockets.exceptions import ConnectionClosed\nimport asyncio\n\n@app.websocket(\"/ws\")\nasync def websocket_endpoint(websocket: WebSocket):\n is_running = True\n await websocket.accept()\n \n try:\n while True:\n data = await websocket.receive_text()\n\n async def run_continuous_iterations():\n while is_running:\n svg_string = get_step_data() # synchronous/blocking function\n await websocket.send_text(svg_string)\n \n if data == \"status\":\n is_running = True\n loop = asyncio.get_running_loop()\n loop.run_in_executor(None, lambda: asyncio.run(run_continuous_iterations()))\n\n if data == \"stop\":\n is_running = False\n print(\"Stopping process\")\n \n except (WebSocketDisconnect, ConnectionClosed):\n is_running = False\n print(\"Client disconnected\")\n```\n\n```py\nimport concurrent.futures\n\n#... rest of the code is the same as above\n\n@app.on_event(\"startup\")\ndef startup_event():\n # instantiate the ThreadPool\n app.state.pool = concurrent.futures.ThreadPoolExecutor()\n\n@app.on_event(\"shutdown\")\ndef shutdown_event(): \n # terminate the ThreadPool\n app.state.pool.shutdown()\n \n@app.websocket(\"/ws\")\nasync def websocket_endpoint(websocket: WebSocket):\n #... rest of the code is the same as above\n try:\n while True:\n #... rest of the code is the same as above\n\n if data == \"status\":\n is_running = True\n loop = asyncio.get_running_loop()\n loop.run_in_executor(app.state.pool, lambda: asyncio.run(run_continuous_iterations()))\n\n #... rest of the code is the same as above\n\n except (WebSocketDisconnect, ConnectionClosed):\n #... rest of the code is the same as above\n```\n\n```py\nfrom contextlib import asynccontextmanager\nimport concurrent.futures\n\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI): \n pool = concurrent.futures.ThreadPoolExecutor(max_workers=20)\n yield {'pool': pool}\n pool.shutdown()\n\n\napp = FastAPI(lifespan=lifespan)\n\n\n@app.websocket(\"/ws\")\nasync def websocket_endpoint(websocket: WebSocket):\n #... rest of the code is the same as above\n try:\n while True:\n #... rest of the code is the same as above\n\n if data == \"status\":\n is_running = True\n loop = asyncio.get_running_loop()\n loop.run_in_executor(websocket.state.pool, lambda: asyncio.run(run_continuous_iterations()))\n\n #... rest of the code is the same as above\n\n except (WebSocketDisconnect, ConnectionClosed):\n #... rest of the code is the same as above\n```\n\n```py\nimport threading\n\n#... rest of the code is the same as above\n \nif data == \"status\":\n is_running = True\n thread = threading.Thread(target=lambda: asyncio.run(run_continuous_iterations()))\n thread.start()\n\n#... rest of the code is the same as above\n```\n\n```text\nawait\n```\n\n```text\nI/O-bound\n```\n\n```text\nI/O-bound\n```\n\n```text\nFile\n```\n\n```text\nasync\n```\n\n```text\nrun_in_threadpool()\n```\n\n```text\nawait\n```\n\n```text\nFile\n```\n\n```text\nasync def\n```\n\n```text\nawait file.read()\n```\n\n```text\nI/O-bound\n```\n\n```text\nCPU-bound\n```\n\n```text\nasync def\n```\n\n```text\nawait\n```\n\n```text\nawait\n```\n\n```text\nasyncio\n```\n\n```text\nloop.run_in_executor()\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nNone\n```\n\n```text\nloop.run_in_executor()\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nasyncio\n```\n\n```text\nloop.run_in_executor()\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nstartup\n```\n\n```text\nshutdown\n```\n\n```text\nlifespan\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nrequest.state\n```\n\n```text\nrequest.state\n```\n\n```text\nwebsockets\n```\n\n```text\nwebscoket.state\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nthreading\n```\n\n```text\nThread\n```\n\n========================================\n\nComments:\n- Does this answer your question? FastAPI runs api-calls in serial instead of parallel fashion\n- Someone has kindly sent this: stackoverflow.com/questions/71516140/… But I'm not sure what to make of this. For instance, if I place run_continuous_iterations into run_in_threadpool it will throw the not awaited error because run_continuous_iterations is async. I'm not sure how this can be solved with threading\n- Perhaps I need to run the websocket with run_in_executor so it has it's own thread and then manage it from there","metadata":{"transformedAt":"2026-08-18T18:32:29.131Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":46,"totalLines":338,"estimatedTokens":1695}}414{"id":"stack-65900707","source":"stackoverflow","questionId":65900707,"title":"FastAPI swaggerUI shows nested routes twice","tags":["python","swagger-ui","openapi","fastapi"],"text":"Title: FastAPI swaggerUI shows nested routes twice\nTags: python, swagger-ui, openapi, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have a configuration like this in the `routes/__init__.py`\n\n```\n## api/routes/__init__.py\nrouter = APIRouter()\nrouter.include_router(models_router, prefix=\"/models\", tags=[\"models\"])\n...\n```\n\nAnd here is the `main.py` that includes them.\n\n```\n## main.py\nfrom api.routes import router as api_router\ndef get_app():\n app = FastAPI()\n app.include_router(api_router, prefix = \"/api\")\n ...\n\napp = get_app()\n```\n\nNow inside the models router I have two more nested routes like this:\n\n```\n## api/routes/models.py\nrouter.include_router(\n fields_router, \n prefix=\"/{model_id}/fields\", \n tags=[\"fields\"],\n dependencies=[Depends(pre_model_validation)]\n)\nrouter.include_router(\n model_data_router, \n prefix=\"/{model_id}/data\", \n tags=[\"model_data\"],\n dependencies=[Depends(pre_model_validation)]\n)\n```\n\nWhile this works, when I open the localhost and use the generated SwaggerUI docs, it shows something like this\n\nhttps://i.sstatic.net/AWfgj.png:\n\nThe nested endpoints are also appearing from inside the `/models` API as well as from their separate `/fields` and `/model_data` APIs. How do I isolate the nested routes in a way that they appear as separate API in swagger docs but stay defined inside the `/models` API?\n\n========================================\n\nTop Answer:\nSome workaround can be implemented having the following structure. For demonstration purposes everything is put together:\n\n```\nfields_router = APIRouter()\n...\n\nmodel_data_router = APIRouter()\n...\n\nmodels_router = APIRouter()\n...\n\naggregated_models_router = APIRouter()\naggregated_models_router.include_router(\n fields_router, \n prefix=\"/{model_id}/fields\", \n tags=[\"fields\"],\n dependencies=[Depends(pre_model_validation)]\n)\naggregated_models_router.include_router(\n model_data_router, \n prefix=\"/{model_id}/data\", \n tags=[\"model_data\"],\n dependencies=[Depends(pre_model_validation)]\n)\naggregated_models_router.include_router(\n models_router, \n prefix=\"\", \n tags=[\"models\"]\n)\n...\n\nrouter = APIRouter()\nrouter.include_router(aggregated_models_router, prefix=\"/models\")\n...\n```\n\nWithout the `tags` argument in the main router you'll get only `fields`, `model_data` and `models` sections without any duplicates\n\n========================================\n\nCode:\n```text\n## api/routes/__init__.py\nrouter = APIRouter()\nrouter.include_router(models_router, prefix=\"/models\", tags=[\"models\"])\n...\n```\n\n```text\n## main.py\nfrom api.routes import router as api_router\ndef get_app():\n app = FastAPI()\n app.include_router(api_router, prefix = \"/api\")\n ...\n\napp = get_app()\n```\n\n```text\n## api/routes/models.py\nrouter.include_router(\n fields_router, \n prefix=\"/{model_id}/fields\", \n tags=[\"fields\"],\n dependencies=[Depends(pre_model_validation)]\n)\nrouter.include_router(\n model_data_router, \n prefix=\"/{model_id}/data\", \n tags=[\"model_data\"],\n dependencies=[Depends(pre_model_validation)]\n)\n```\n\n```text\nroutes/__init__.py\n```\n\n```text\nmain.py\n```\n\n```text\n/models\n```\n\n```text\n/fields\n```\n\n```text\n/model_data\n```\n\n```text\n/models\n```\n\n```py\n# api/routes/__init__.py\nrouter = APIRouter()\n\nrouter.include_router(\n models_router, \n prefix=\"/models\", \n tags=[\"models\"]\n)\n\nrouter.include_router(\n fields_router, \n prefix=\"/models/{model_id}/fields\", \n tags=[\"fields\"]\n)\n\nrouter.include_router(\n models_router, \n prefix=\"/models/{model_id}/data\", \n tags=[\"model_data\"]\n)\n```\n\n```text\n/api/models/\n```\n\n```text\nfields_router = APIRouter()\n...\n\nmodel_data_router = APIRouter()\n...\n\nmodels_router = APIRouter()\n...\n\n\naggregated_models_router = APIRouter()\naggregated_models_router.include_router(\n fields_router, \n prefix=\"/{model_id}/fields\", \n tags=[\"fields\"],\n dependencies=[Depends(pre_model_validation)]\n)\naggregated_models_router.include_router(\n model_data_router, \n prefix=\"/{model_id}/data\", \n tags=[\"model_data\"],\n dependencies=[Depends(pre_model_validation)]\n)\naggregated_models_router.include_router(\n models_router, \n prefix=\"\", \n tags=[\"models\"]\n)\n...\n\nrouter = APIRouter()\nrouter.include_router(aggregated_models_router, prefix=\"/models\")\n...\n```\n\n```text\ntags\n```\n\n```text\nfields\n```\n\n```text\nmodel_data\n```\n\n```text\nmodels\n```\n\n========================================\n\nComments:\n- This one helped me. Setting the tags only for the endpoints you want to see in the docs seems to be helping. All it takes is to remove the tags from other routers.\n- yup the last statement here is the key for me!","metadata":{"transformedAt":"2026-08-18T18:32:29.132Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":16,"totalLines":238,"estimatedTokens":1144}}415{"id":"stack-61660586","source":"stackoverflow","questionId":61660586,"title":"Python3.8 - FastAPI and Serverless (AWS Lambda) - Unable to process files sent to api endpoint","tags":["python","amazon-web-services","aws-lambda","serverless","fastapi"],"text":"Title: Python3.8 - FastAPI and Serverless (AWS Lambda) - Unable to process files sent to api endpoint\nTags: python, amazon-web-services, aws-lambda, serverless, fastapi\nSource: Stack Overflow\n\nQuestion:\nI've been using FastAPI with Serverless through AWS Lambda functions for a couple of months now and it works perfectly.\n\nI'm creating a new api endpoint which requires one file to be sent.\n\nIt works perfectly when using on my local machine, but when I deploy to AWS Lambda, I have the following error when I try to call my endpoint, with the exact same file that is working locally. I'm doing this at the moment as a test through the swagger UI and nothing changes between my serverless or my local machine beside the \"machine\" the code is run on.\n\nWould you have any idea what is going on ?\n\nPython 3.8\nFastAPI 0.54.1\n\nMy code:\n\n```\nfrom fastapi import FastAPI, File, UploadFile\nimport pandas as pd\n\napp = FastAPI()\n\n@app.post('/process_data_import_quote_file')\ndef process_data_import_quote_file(file: UploadFile = File(...)): # same error if I put bytes instead of UploadFile\n file = file.file.read()\n print(f\"file {file}\")\n quote_number = pd.read_excel(file, sheet_name='Data').iloc[:, 0].dropna()\n```\n\nIt fails on the last line\n\nI've tried to print the file, when I compare the data printed with what I read locally, it is different. I swear it's the same file I'm using on the 2 so I don't know what could explain that ?\nIt's a very basic excel file, nothing special about it.\n\n```\n[ERROR] 2020-05-07T14:25:17.878Z 25ff37a5-e313-4db5-8763-1227e8244457 Exception in ASGI application\n\nTraceback (most recent call last):\n File \"/var/task/mangum/protocols/http.py\", line 39, in run\n await app(self.scope, self.receive, self.send)\n File \"/var/task/fastapi/applications.py\", line 149, in __call__\n await super().__call__(scope, receive, send)\n File \"/var/task/starlette/applications.py\", line 102, in __call__\n await self.middleware_stack(scope, receive, send)\n File \"/var/task/starlette/middleware/errors.py\", line 181, in __call__\n raise exc from None\n File \"/var/task/starlette/middleware/errors.py\", line 159, in __call__\n await self.app(scope, receive, _send)\n File \"/var/task/starlette/exceptions.py\", line 82, in __call__\n raise exc from None\n File \"/var/task/starlette/exceptions.py\", line 71, in __call__\n await self.app(scope, receive, sender)\n File \"/var/task/starlette/routing.py\", line 550, in __call__\n await route.handle(scope, receive, send)\n File \"/var/task/starlette/routing.py\", line 227, in handle\n await self.app(scope, receive, send)\n File \"/var/task/starlette/routing.py\", line 41, in app\n response = await func(request)\n File \"/var/task/fastapi/routing.py\", line 196, in app\n raw_response = await run_endpoint_function(\n File \"/var/task/fastapi/routing.py\", line 150, in run_endpoint_function\n return await run_in_threadpool(dependant.call, **values)\n File \"/var/task/starlette/concurrency.py\", line 34, in run_in_threadpool\n return await loop.run_in_executor(None, func, *args)\n File \"/var/lang/lib/python3.8/concurrent/futures/thread.py\", line 57, in run\n result = self.fn(*self.args, **self.kwargs)\n File \"/var/task/app/quote/processing.py\", line 100, in process_data_import_quote_file\n quote_number = pd.read_excel(file, sheet_name='Data').iloc[:, 0].dropna()\n File \"/var/task/pandas/io/excel/_base.py\", line 304, in read_excel\n io = ExcelFile(io, engine=engine)\n File \"/var/task/pandas/io/excel/_base.py\", line 821, in __init__\n self._reader = self._engines[engine](self._io)\n File \"/var/task/pandas/io/excel/_xlrd.py\", line 21, in __init__\n super().__init__(filepath_or_buffer)\n File \"/var/task/pandas/io/excel/_base.py\", line 355, in __init__\n self.book = self.load_workbook(BytesIO(filepath_or_buffer))\n File \"/var/task/pandas/io/excel/_xlrd.py\", line 34, in load_workbook\n return open_workbook(file_contents=data)\n File \"/var/task/xlrd/__init__.py\", line 115, in open_workbook\n zf = zipfile.ZipFile(timemachine.BYTES_IO(file_contents))\n File \"/var/lang/lib/python3.8/zipfile.py\", line 1269, in __init__\n self._RealGetContents()\n File \"/var/lang/lib/python3.8/zipfile.py\", line 1354, in _RealGetContents\n fp.seek(self.start_dir, 0)\nValueError: negative seek value -62703616\n```\n\n========================================\n\nTop Answer:\nThis is typically caused by binary data being converted to text in the API Gateway. To resolve this add the following to your `serverless.yml` file under the `provider` section:\n\n```\napiGateway:\n binaryMediaTypes:\n - 'multipart/form-data'\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI, File, UploadFile\nimport pandas as pd\n\napp = FastAPI()\n\n@app.post('/process_data_import_quote_file')\ndef process_data_import_quote_file(file: UploadFile = File(...)): # same error if I put bytes instead of UploadFile\n file = file.file.read()\n print(f\"file {file}\")\n quote_number = pd.read_excel(file, sheet_name='Data').iloc[:, 0].dropna()\n```\n\n```text\n[ERROR] 2020-05-07T14:25:17.878Z 25ff37a5-e313-4db5-8763-1227e8244457 Exception in ASGI application\n\nTraceback (most recent call last):\n File \"/var/task/mangum/protocols/http.py\", line 39, in run\n await app(self.scope, self.receive, self.send)\n File \"/var/task/fastapi/applications.py\", line 149, in __call__\n await super().__call__(scope, receive, send)\n File \"/var/task/starlette/applications.py\", line 102, in __call__\n await self.middleware_stack(scope, receive, send)\n File \"/var/task/starlette/middleware/errors.py\", line 181, in __call__\n raise exc from None\n File \"/var/task/starlette/middleware/errors.py\", line 159, in __call__\n await self.app(scope, receive, _send)\n File \"/var/task/starlette/exceptions.py\", line 82, in __call__\n raise exc from None\n File \"/var/task/starlette/exceptions.py\", line 71, in __call__\n await self.app(scope, receive, sender)\n File \"/var/task/starlette/routing.py\", line 550, in __call__\n await route.handle(scope, receive, send)\n File \"/var/task/starlette/routing.py\", line 227, in handle\n await self.app(scope, receive, send)\n File \"/var/task/starlette/routing.py\", line 41, in app\n response = await func(request)\n File \"/var/task/fastapi/routing.py\", line 196, in app\n raw_response = await run_endpoint_function(\n File \"/var/task/fastapi/routing.py\", line 150, in run_endpoint_function\n return await run_in_threadpool(dependant.call, **values)\n File \"/var/task/starlette/concurrency.py\", line 34, in run_in_threadpool\n return await loop.run_in_executor(None, func, *args)\n File \"/var/lang/lib/python3.8/concurrent/futures/thread.py\", line 57, in run\n result = self.fn(*self.args, **self.kwargs)\n File \"/var/task/app/quote/processing.py\", line 100, in process_data_import_quote_file\n quote_number = pd.read_excel(file, sheet_name='Data').iloc[:, 0].dropna()\n File \"/var/task/pandas/io/excel/_base.py\", line 304, in read_excel\n io = ExcelFile(io, engine=engine)\n File \"/var/task/pandas/io/excel/_base.py\", line 821, in __init__\n self._reader = self._engines[engine](self._io)\n File \"/var/task/pandas/io/excel/_xlrd.py\", line 21, in __init__\n super().__init__(filepath_or_buffer)\n File \"/var/task/pandas/io/excel/_base.py\", line 355, in __init__\n self.book = self.load_workbook(BytesIO(filepath_or_buffer))\n File \"/var/task/pandas/io/excel/_xlrd.py\", line 34, in load_workbook\n return open_workbook(file_contents=data)\n File \"/var/task/xlrd/__init__.py\", line 115, in open_workbook\n zf = zipfile.ZipFile(timemachine.BYTES_IO(file_contents))\n File \"/var/lang/lib/python3.8/zipfile.py\", line 1269, in __init__\n self._RealGetContents()\n File \"/var/lang/lib/python3.8/zipfile.py\", line 1354, in _RealGetContents\n fp.seek(self.start_dir, 0)\nValueError: negative seek value -62703616\n```\n\n```text\nfile = BytesIO(file).read()\n```\n\n```yaml\napiGateway:\n binaryMediaTypes:\n - 'multipart/form-data'\n```\n\n```text\nserverless.yml\n```\n\n```text\nprovider\n```\n\n```text\nconst api = new apigateway.LambdaRestApi(\n this,\n resourceMap.getId(apigateway.LambdaRestApi.name),\n {\n handler: restLambda,\n proxy: true,\n defaultCorsPreflightOptions: {\n allowOrigins: apigateway.Cors.ALL_ORIGINS,\n allowMethods: [\"GET\", \"POST\", \"PUT\", \"DELETE\", \"OPTIONS\"],\n allowHeaders: [\n \"Content-Type\",\n \"X-Amz-Date\",\n \"Authorization\",\n \"X-Api-Key\",\n \"X-Amz-Security-Token\",\n \"x_referred\" \n ],\n }, \n binaryMediaTypes: [\"multipart/form-data\"],\n }\n );\n```\n\n========================================\n\nComments:\n- Can you try `file: bytes = File(...)` than `file: UploadFile = File(...)` and then pass the byte stream directly to the read excel function\n- no, this changes nothging whether I do like this with bytes or UploadFile, same error","metadata":{"transformedAt":"2026-08-18T18:32:29.132Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":7,"totalLines":216,"estimatedTokens":2219}}416{"id":"stack-72103585","source":"stackoverflow","questionId":72103585,"title":"How to pass File object to HTTPX request in FastAPI endpoint","tags":["python","fastapi"],"text":"Title: How to pass File object to HTTPX request in FastAPI endpoint\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nThe idea is to get file object from one endpoint and send it to other endpoints to work with it without saving it.\nLet's have this expample code:\n\n```\nimport httpx\nfrom fastapi import Request, UploadFile, File\n\napp = FastAPI()\nclient = httpx.AsyncClient()\n\n@app.post(\"/endpoint/\")\nasync def foo(request: Request, file: UploadFile = File(...))\n urls = [\"/some/other/endpoint\", \"/another/endpoint/\"]\n for url in urls:\n response = await client.post(url) # here I need to send the file to the other endpoint \n return {\"bar\": \"baz\"}\n\n@app.post(\"/some/other/endpoint/\")\nasync def baz(request: Request, file: UploadFile = File(...)): # and here to use it\n # Do something with the file object\n return {\"file\": file.filename}\n\n@app.post(\"/another/endpoint/\")\nasync def baz(request: Request, file: UploadFile = File(...)): # and here to use it too\n # Do something with the file object\n return {\"file\": file.content_type}\n```\n\nAs stated here I tried to do something like this:\n\n```\ndata = {'file': file}\nresponse = await client.post(url, data=data)\n```\n\nBut it errored with\n\n```\n'{\"detail\":[{\"loc\":[\"body\",\"file\"],\"msg\":\"Expected UploadFile, received: \",\"type\":\"value_error\"}]}'\n```\n\nExample curl request:\n\n```\ncurl -X 'POST' -F 'file=@somefile' someserver/endpoint/\n```\n\n========================================\n\nCode:\n```text\nimport httpx\nfrom fastapi import Request, UploadFile, File\n\n\napp = FastAPI()\nclient = httpx.AsyncClient()\n\n@app.post(\"/endpoint/\")\nasync def foo(request: Request, file: UploadFile = File(...))\n urls = [\"/some/other/endpoint\", \"/another/endpoint/\"]\n for url in urls:\n response = await client.post(url) # here I need to send the file to the other endpoint \n return {\"bar\": \"baz\"}\n\n\n@app.post(\"/some/other/endpoint/\")\nasync def baz(request: Request, file: UploadFile = File(...)): # and here to use it\n # Do something with the file object\n return {\"file\": file.filename}\n\n\n@app.post(\"/another/endpoint/\")\nasync def baz(request: Request, file: UploadFile = File(...)): # and here to use it too\n # Do something with the file object\n return {\"file\": file.content_type}\n```\n\n```text\ndata = {'file': file}\nresponse = await client.post(url, data=data)\n```\n\n```text\n'{\"detail\":[{\"loc\":[\"body\",\"file\"],\"msg\":\"Expected UploadFile, received: <class \\'str\\'>\",\"type\":\"value_error\"}]}'\n```\n\n```text\ncurl -X 'POST' -F 'file=@somefile' someserver/endpoint/\n```\n\n```text\npost(..., files={'file': file.file}, ...)\n```\n\n```text\npost(..., files={'file': (file.filename, file.file)}, ...)\n```\n\n```text\nfile.file.seek(0)\n```\n\n```text\nawait file.seek(0)\n```\n\n```text\nfrom fastapi import FastAPI, Request, UploadFile, File\nimport httpx\n\napp = FastAPI()\nclient = httpx.AsyncClient()\n\n\n@app.post(\"/endpoint/\")\nasync def foo(request: Request, file: UploadFile = File(...)):\n print('/endpoint/')\n \n urls = [\"/some/other/endpoint/\", \"/another/endpoint/\"]\n \n results = []\n \n for url in urls:\n response = await client.post('http://localhost:8000' + url, files={'file': (file.filename, file.file)})\n #file.file.seek(0) # move back at the beginning of file after sending to other URL\n await file.seek(0) # move back at the beginning of file after sending to other URL\n results.append(response)\n \n results = [item.text for item in results]\n \n print('results:', results)\n \n return {\"bar\": \"baz\"}\n\n\n@app.post(\"/some/other/endpoint/\")\nasync def baz(request: Request, file: UploadFile = File(...)):\n print('/some/other/endpoint/')\n \n print('filename:', file.filename)\n print('content_type:', file.content_type)\n \n # Do something with the file object\n \n return {\"file\": file.filename}\n\n\n@app.post(\"/another/endpoint/\")\nasync def baz(request: Request, file: UploadFile = File(...)): \n print('/another/endpoint/')\n \n print('filename:', file.filename)\n print('content_type:', file.content_type)\n \n # Do something with the file object\n \n return {\"file\": file.content_type}\n```\n\n```text\nhttpx\n```\n\n```text\nrequests\n```\n\n```text\nfiles=....\n```\n\n========================================\n\nComments:\n- maybe you should use `post(..., file=...)` instead of `post(..., data=...)`\n- @furas I tried but `AsyncClient.post() got an unexpected keyword argument 'file'` error shows\n- maybe it has to be `files=` with `s` at the end.\n- @furas this is the correct answer. Please post it below to get your internet points\n- Thanks for the question, I am trying to do the same without any luck.\n- Future readers should have a look at this answer and this answer as well.\n- Thanks for the answer it saved my week. I was not finding anything useful and the question & answer are from yesterday (LOL). Thanks both!!","metadata":{"transformedAt":"2026-08-18T18:32:29.132Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":12,"totalLines":187,"estimatedTokens":1212}}417{"id":"stack-71800133","source":"stackoverflow","questionId":71800133,"title":"How to return a custom 404 Not Found page using FastAPI?","tags":["python","exception","http-status-code-404","fastapi","starlette"],"text":"Title: How to return a custom 404 Not Found page using FastAPI?\nTags: python, exception, http-status-code-404, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nI am making a rick roll site for Discord and I would like to redirect users to the rick roll page on `404` response status code.\n\nI've tried the following, but didn't work:\n\n```\n@app.exception_handler(fastapi.HTTPException)\n async def http_exception_handler(request, exc):\n ...\n```\n\n========================================\n\nTop Answer:\n```\nfrom fastapi import FastAPI\nfrom fastapi.templating import Jinja2Templates\nfrom starlette.exceptions import HTTPException\n\n# --- Constants --- #\n\ntemplates = Jinja2Templates(directory=\"./templates\")\n\n# --- Error handler --- #\n\ndef lost_page(request, exception):\n headers = {\"Content-Type\": \"text/html\"}\n\n if isinstance(exception, HTTPException):\n status_code = exception.status_code\n detail = exception.detail\n elif isinstance(exception, Exception):\n status_code = 500\n detail = \"Server Error\"\n headers[\"X-Error-Message\"] = exception.__class__.__name__\n headers[\"X-Error-Line\"] = str(exception.__traceback__.tb_lineno)\n else:\n status_code = 500\n detail = f\"Server Error\\n\\nDetails: {exception}\"\n\n return templates.TemplateResponse(\n \"404.html\",\n {\"request\": request, \"status_code\": status_code, \"detail\": detail},\n status_code=status_code,\n headers=headers,\n )\n\nexception_handlers = {num: lost_page for num in range(400, 599)}\napp = FastAPI(exception_handlers=exception_handlers)\n```\n\nThis is a snippet I've used across a few projects, it's essentially a catch-all for all 400 and 500 status codes.\n\n```\nfrom fastapi import FastAPI\nfrom fastapi.templating import Jinja2Templates\nfrom starlette.exceptions import HTTPException\n\n# --- Constants --- #\n\ntemplates = Jinja2Templates(directory=\"./templates\")\n```\n\nThis block imports relevant libraries and initializes Jinja2Templates, which allows us to render HTML using FastAPI. Docs.\n\nLet's dissect\n\n```\ndef lost_page(request, exception):\n headers = {\"Content-Type\": \"text/html\"}\n\n if isinstance(exception, HTTPException):\n status_code = exception.status_code\n detail = exception.detail\n elif isinstance(exception, Exception):\n status_code = 500\n detail = \"Server Error\"\n headers[\"X-Error-Message\"] = exception.__class__.__name__\n headers[\"X-Error-Line\"] = str(exception.__traceback__.tb_lineno)\n else:\n status_code = 500\n detail = f\"Server Error\\n\\nDetails: {exception}\"\n\n return templates.TemplateResponse(\n \"404.html\",\n {\"request\": request, \"status_code\": status_code, \"detail\": detail},\n status_code=status_code,\n headers=headers,\n )\n```\n\nFastAPI's exception handler provides two parameters, the request object that caused the exception, and the exception that was raised.\n\n```\ndef lost_page(request, exception):\n```\n\n^^ Our function takes these two parameters.\n\n```\nheaders = {\"Content-Type\": \"text/html\"}\n```\n\nThese are the headers we're going to send back along with the request.\n\n```\nif isinstance(exception, HTTPException):\n status_code = exception.status_code\n detail = exception.detail\n\n elif isinstance(exception, Exception):\n status_code = 500\n detail = \"Server Error\"\n headers[\"X-Error-Name\"] = exception.__class__.__name__\n\n else:\n status_code = 500\n detail = f\"Server Error\\n\\nDetails: {exception}\"\n```\n\nIf the `exception` parameter is a HTTPException (raised by Starlette/FastAPI), then we're going to set the status_code and detail appropriately. An example of an HTTPException is a 404 error, if you try accessing an endpoint that doesn't exist, a HTTPException is raised and handled automatically by FastAPI.\n\nThen, we check if it's an instance of `Exception`, which is one of Python's in-built exception classes. This covers exceptions such as `ZeroDivisionError`, `FileNotFoundError`, etc. This usually means that it's an issue with our code, such as trying to open a file that doesn't exist, dividing by zero, using an unknown attribute, or something else that raised an exception which wasn't handled inside of the endpoint function.\n\nThe `else` block shouldn't trigger in any case, and can be removed, it's just something I keep to appease my conscience.\n\nAfter the `status_code`, `detail` and headers are set,\n\n```\nreturn templates.TemplateResponse(\n \"404.html\",\n {\"request\": request, \"status_code\": status_code, \"detail\": detail},\n status_code=status_code,\n headers=headers,\n )\n```\n\nWe return our 404 template, the TemplateResponse function takes in a few parameters, `\"404.html\"` being the file we want to return, `{\"request\": request, \"status_code\": status_code, \"detail\": detail}` being the request object and the values for embeds we want to fill (embeds are a way to pass information between jinja2 and Python). Then we define the status code of the response, along with its headers.\n\nThis is a 404 html template I use alongside the error handler.\n\n```\nexception_handlers = {num: lost_page for num in range(400, 599)}\napp = FastAPI(exception_handlers=exception_handlers)\n```\n\nException handlers uses dict comprehension to create a dictionary of status codes, and the functions that should be called,\n\n```\nexception_handlers = {400: lost_page, 401: lost_page, 402: lost_page, ...}\n```\n\nIs how it'll look after the comprehension, until 599.\n\nFastAPI Allows us to pass this dict as a parameter of the `FastAPI` class,\n\n```\napp = FastAPI(exception_handlers=exception_handlers)\n```\n\nThis tells FastAPI to run the following functions when the endpoint function returns a particular status code.\n\nTo conclude, the snippet above and this error template should help you handle all FastAPI errors in a nice, user-friendly and clean way.\n\n========================================\n\nCode:\n```py\n@app.exception_handler(fastapi.HTTPException)\n async def http_exception_handler(request, exc):\n ...\n```\n\n```text\n404\n```\n\n```py\nfrom fastapi.responses import RedirectResponse\nfrom fastapi.exceptions import HTTPException\n\n@app.exception_handler(404)\nasync def not_found_exception_handler(request: Request, exc: HTTPException):\n return RedirectResponse('https://fastapi.tiangolo.com')\n```\n\n```py\nasync def not_found_error(request: Request, exc: HTTPException):\n return RedirectResponse('https://fastapi.tiangolo.com')\n\nexception_handlers = {404: not_found_error}\napp = FastAPI(exception_handlers=exception_handlers)\n```\n\n```py\nfrom fastapi import FastAPI, Request\nfrom fastapi.templating import Jinja2Templates\nfrom fastapi.exceptions import HTTPException\n\n\nasync def not_found_error(request: Request, exc: HTTPException):\n return templates.TemplateResponse('404.html', {'request': request}, status_code=404)\n\n\nasync def internal_error(request: Request, exc: HTTPException):\n return templates.TemplateResponse('500.html', {'request': request}, status_code=500)\n\n \ntemplates = Jinja2Templates(directory='templates')\n\nexception_handlers = {\n 404: not_found_error,\n 500: internal_error\n}\n\napp = FastAPI(exception_handlers=exception_handlers)\n```\n\n```html\n<!DOCTYPE html>\n<html>\n <title>Not Found</title>\n <body>\n <h1>Not Found</h1>\n <p>The requested resource was not found on this server.</p>\n </body>\n</html>\n```\n\n```html\n<!DOCTYPE html>\n<html>\n <title>Internal Server Error</title>\n <body>\n <h1>Internal Server Error</h1>\n <p>The server encountered an internal error or \n misconfiguration and was unable to complete your request.\n </p>\n </body>\n</html>\n```\n\n```py\nfrom fastapi import Request\nfrom fastapi.responses import RedirectResponse\n\n@app.middleware(\"http\")\nasync def redirect_on_not_found(request: Request, call_next):\n response = await call_next(request)\n if response.status_code == 404:\n return RedirectResponse(\"https://fastapi.tiangolo.com\")\n else:\n return response\n```\n\n```py\nfrom fastapi import FastAPI, Request\nfrom fastapi.responses import RedirectResponse\nfrom starlette.middleware.base import BaseHTTPMiddleware\n\n\nclass ResourceNotFoundMiddleware(BaseHTTPMiddleware):\n async def dispatch(self, request: Request, call_next): \n response = await call_next(request)\n if response.status_code == 404:\n return RedirectResponse(\"https://fastapi.tiangolo.com\")\n else:\n return response\n\n\napp = FastAPI()\napp.add_middleware(ResourceNotFoundMiddleware)\n```\n\n```text\nexception_handlers\n```\n\n```text\nRedirectResponse\n```\n\n```text\nResponse\n```\n\n```text\nJSONResponse\n```\n\n```text\nHTMLResponse\n```\n\n```text\nJinja2 TemplateResponse\n```\n\n```text\nmiddleware\n```\n\n```text\nstatus_code\n```\n\n```text\nresponse\n```\n\n```text\n404\n```\n\n```text\nRedirectResponse\n```\n\n```text\nResponse\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.templating import Jinja2Templates\nfrom starlette.exceptions import HTTPException\n\n# --- Constants --- #\n\ntemplates = Jinja2Templates(directory=\"./templates\")\n\n# --- Error handler --- #\n\ndef lost_page(request, exception):\n headers = {\"Content-Type\": \"text/html\"}\n\n if isinstance(exception, HTTPException):\n status_code = exception.status_code\n detail = exception.detail\n elif isinstance(exception, Exception):\n status_code = 500\n detail = \"Server Error\"\n headers[\"X-Error-Message\"] = exception.__class__.__name__\n headers[\"X-Error-Line\"] = str(exception.__traceback__.tb_lineno)\n else:\n status_code = 500\n detail = f\"Server Error\\n\\nDetails: {exception}\"\n\n return templates.TemplateResponse(\n \"404.html\",\n {\"request\": request, \"status_code\": status_code, \"detail\": detail},\n status_code=status_code,\n headers=headers,\n )\n\n\nexception_handlers = {num: lost_page for num in range(400, 599)}\napp = FastAPI(exception_handlers=exception_handlers)\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.templating import Jinja2Templates\nfrom starlette.exceptions import HTTPException\n\n# --- Constants --- #\n\ntemplates = Jinja2Templates(directory=\"./templates\")\n```\n\n```py\ndef lost_page(request, exception):\n headers = {\"Content-Type\": \"text/html\"}\n\n if isinstance(exception, HTTPException):\n status_code = exception.status_code\n detail = exception.detail\n elif isinstance(exception, Exception):\n status_code = 500\n detail = \"Server Error\"\n headers[\"X-Error-Message\"] = exception.__class__.__name__\n headers[\"X-Error-Line\"] = str(exception.__traceback__.tb_lineno)\n else:\n status_code = 500\n detail = f\"Server Error\\n\\nDetails: {exception}\"\n\n return templates.TemplateResponse(\n \"404.html\",\n {\"request\": request, \"status_code\": status_code, \"detail\": detail},\n status_code=status_code,\n headers=headers,\n )\n```\n\n```py\ndef lost_page(request, exception):\n```\n\n```py\nheaders = {\"Content-Type\": \"text/html\"}\n```\n\n```py\nif isinstance(exception, HTTPException):\n status_code = exception.status_code\n detail = exception.detail\n\n elif isinstance(exception, Exception):\n status_code = 500\n detail = \"Server Error\"\n headers[\"X-Error-Name\"] = exception.__class__.__name__\n\n else:\n status_code = 500\n detail = f\"Server Error\\n\\nDetails: {exception}\"\n```\n\n```py\nreturn templates.TemplateResponse(\n \"404.html\",\n {\"request\": request, \"status_code\": status_code, \"detail\": detail},\n status_code=status_code,\n headers=headers,\n )\n```\n\n```py\nexception_handlers = {num: lost_page for num in range(400, 599)}\napp = FastAPI(exception_handlers=exception_handlers)\n```\n\n```py\nexception_handlers = {400: lost_page, 401: lost_page, 402: lost_page, ...}\n```\n\n```py\napp = FastAPI(exception_handlers=exception_handlers)\n```\n\n```text\nexception\n```\n\n```text\nException\n```\n\n```text\nZeroDivisionError\n```\n\n```text\nFileNotFoundError\n```\n\n```text\nelse\n```\n\n```text\nstatus_code\n```\n\n```text\ndetail\n```\n\n```text\n\"404.html\"\n```\n\n```text\n{\"request\": request, \"status_code\": status_code, \"detail\": detail}\n```\n\n```text\nFastAPI\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.132Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":41,"totalLines":482,"estimatedTokens":2974}}418{"id":"stack-74261401","source":"stackoverflow","questionId":74261401,"title":"How to get route's name using FastAPI/Starlette?","tags":["python","fastapi","middleware","starlette"],"text":"Title: How to get route's name using FastAPI/Starlette?\nTags: python, fastapi, middleware, starlette\nSource: Stack Overflow\n\nQuestion:\nHow can I get the `name` of a route/endpoint using FastAPI/Starlette? I have access to the `Request` object and I need this information in one of my middlewares. For example, if I hit `services/1`, I should then be able to get the `abc` name. Is this possible in FastAPI?\n\n```\n@app.get(\"/services/{service}\", name=\"abc\")\nasync def list_services() -> dict:\n do something\n```\n\nUpdate 1: Output of `request.scope`\n\n```\n{'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8001), 'client': ('127.0.0.1', 56670), 'scheme': 'http', 'root_path': '', 'headers': [(b'user-agent', b'PostmanRuntime/7.29.2'), (b'accept', b'*/*'), (b'postman-token', b'f2da2d0f-e721-44c8-b14f-e19750ea8a68'), (b'host', b'localhost:8001'), (b'accept-encoding', b'gzip, deflate, br'), (b'connection', b'keep-alive')], 'method': 'GET', 'path': '/health', 'raw_path': b'/health', 'query_string': b'', 'app': }\n```\n\nUpdate 2:\nProviding middleware code where `request.scope[\"route\"]` is breaking.\n\n```\nfrom fastapi import FastAPI,Request\n \napp = FastAPI()\n\n@app.middleware(\"http\")\nasync def logging_middleware(request: Request, call_next):\n print(request.scope['route'].name)\n response = await call_next(request)\n return response\n\n@app.get('/', name='abc')\ndef get_name(request: Request):\n return request.scope['route'].name\n```\n\n========================================\n\nCode:\n```text\n@app.get(\"/services/{service}\", name=\"abc\")\nasync def list_services() -> dict:\n do something\n```\n\n```text\n{'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8001), 'client': ('127.0.0.1', 56670), 'scheme': 'http', 'root_path': '', 'headers': [(b'user-agent', b'PostmanRuntime/7.29.2'), (b'accept', b'*/*'), (b'postman-token', b'f2da2d0f-e721-44c8-b14f-e19750ea8a68'), (b'host', b'localhost:8001'), (b'accept-encoding', b'gzip, deflate, br'), (b'connection', b'keep-alive')], 'method': 'GET', 'path': '/health', 'raw_path': b'/health', 'query_string': b'', 'app': <fastapi.applications.FastAPI object at 0x1036d5790>}\n```\n\n```text\nfrom fastapi import FastAPI,Request\n \napp = FastAPI()\n\n\n@app.middleware(\"http\")\nasync def logging_middleware(request: Request, call_next):\n print(request.scope['route'].name)\n response = await call_next(request)\n return response\n\n@app.get('/', name='abc')\ndef get_name(request: Request):\n return request.scope['route'].name\n```\n\n```text\nname\n```\n\n```text\nRequest\n```\n\n```text\nservices/1\n```\n\n```text\nabc\n```\n\n```text\nrequest.scope\n```\n\n```text\nrequest.scope[\"route\"]\n```\n\n```py\nfrom fastapi import FastAPI,Request\n \napp = FastAPI()\n\n\n@app.get('/', name='abc')\ndef get_name(request: Request):\n return request.scope['route'].name\n```\n\n```py\n@app.middleware(\"http\")\nasync def some_middleware(request: Request, call_next):\n response = await call_next(request)\n print(request.scope['route'].name)\n return response\n```\n\n```py\nfrom fastapi import APIRouter, FastAPI, Request, Response\nfrom typing import Callable\nfrom fastapi.routing import APIRoute\n\n\nclass CheckNameRoute(APIRoute):\n def get_route_handler(self) -> Callable:\n original_route_handler = super().get_route_handler()\n\n async def custom_route_handler(request: Request) -> Response:\n print(request.scope['route'].name)\n response = await original_route_handler(request)\n return response\n\n return custom_route_handler\n\n\napp = FastAPI()\nrouter = APIRouter(route_class=CheckNameRoute)\n\n \n@router.get('/', name='abc')\ndef get_name(request: Request):\n return request.scope['route'].name\n\n\napp.include_router(router)\n```\n\n```text\nname\n```\n\n```text\nname\n```\n\n```text\ncall_next(request)\n```\n\n```text\nKeyError: 'route'\n```\n\n```text\nroute\n```\n\n```text\nscope\n```\n\n```text\nAPIRoute\n```\n\n```text\nname\n```\n\n```text\nrequest\n```\n\n```text\nresponse\n```\n\n```text\nAPIRoute\n```\n\n```text\n@<name_of_router_instance>\n```\n\n```text\n@app\n```\n\n```text\n@router.get('/', name='abc')\n```\n\n========================================\n\nComments:\n- If one has access to the request object, why not use `request.url_for(\"route-name-here\")`?","metadata":{"transformedAt":"2026-08-18T18:32:29.132Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":26,"totalLines":201,"estimatedTokens":1073}}419{"id":"stack-68848853","source":"stackoverflow","questionId":68848853,"title":"How can I set a number of default values for many FastAPI endpoints","tags":["python","fastapi"],"text":"Title: How can I set a number of default values for many FastAPI endpoints\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am using FastAPI and I have a number of endpoints that look like this:\n\n```\n@app.get(\"/REDS/\")\ndef query_REDS( request: Request, lighter: Optional[bool] = False, darker: Optional[bool] = False, inverse: Optional[bool] = False, amount: Optional[int] = 10):\n pass # Work done here\n\n@app.get(\"/BLUES/\")\ndef query_BLUES( request: Request, lighter: Optional[bool] = False, darker: Optional[bool] = False, inverse: Optional[bool] = False, amount: Optional[int] = 10):\n pass # Work done here\n\n@app.get(\"/GREENS/\")\ndef query_GREENS( request: Request, lighter: Optional[bool] = False, darker: Optional[bool] = False, inverse: Optional[bool] = False, amount: Optional[int] = 10):\n pass # Work done here\n```\n\nThis looks like this in the swagger UI:\nhttps://i.sstatic.net/lGILq.png\n\nThe real config is passed in the request and parsed manually. Whenever I need to update the signature of these endpoints, I need to update it in like 20 different places. Is there a way to define those specific default arguments in one place?\n\nI tried using the `pydantic` `BaseModel` to define an input model:\n\n```\nclass Arguments(BaseModel):\n lighter: Optional[bool] = False\n darker: Optional[bool] = False\n inverse: Optional[bool] = False\n amount: Optional[int] = 10\n\n@app.get(\"/REDS/\")\ndef query_REDS( request: Request, arguments: Arguments):\n pass # Work done here\n\n@app.get(\"/BLUES/\")\ndef query_BLUES( request: Request, arguments: Arguments):\n pass # Work done here\n\n@app.get(\"/GREENS/\")\ndef query_GREENS( request: Request, arguments: Arguments):\n pass # Work done here.\n```\n\nBut this is not what I am after, first of all because using a body in a get request is not recommended and not supported everywhere and second of all because it is not that useful in the swagger UI:\n\nhttps://i.sstatic.net/on2JS.png\n\nIs there a way to define a sort of default signature to a number of different enpoints?\n\n========================================\n\nCode:\n```text\n@app.get(\"/REDS/\")\ndef query_REDS( request: Request, lighter: Optional[bool] = False, darker: Optional[bool] = False, inverse: Optional[bool] = False, amount: Optional[int] = 10):\n pass # Work done here\n\n@app.get(\"/BLUES/\")\ndef query_BLUES( request: Request, lighter: Optional[bool] = False, darker: Optional[bool] = False, inverse: Optional[bool] = False, amount: Optional[int] = 10):\n pass # Work done here\n\n@app.get(\"/GREENS/\")\ndef query_GREENS( request: Request, lighter: Optional[bool] = False, darker: Optional[bool] = False, inverse: Optional[bool] = False, amount: Optional[int] = 10):\n pass # Work done here\n```\n\n```text\nclass Arguments(BaseModel):\n lighter: Optional[bool] = False\n darker: Optional[bool] = False\n inverse: Optional[bool] = False\n amount: Optional[int] = 10\n\n@app.get(\"/REDS/\")\ndef query_REDS( request: Request, arguments: Arguments):\n pass # Work done here\n\n@app.get(\"/BLUES/\")\ndef query_BLUES( request: Request, arguments: Arguments):\n pass # Work done here\n\n@app.get(\"/GREENS/\")\ndef query_GREENS( request: Request, arguments: Arguments):\n pass # Work done here.\n```\n\n```text\npydantic\n```\n\n```text\nBaseModel\n```\n\n```text\nclass CommonParams:\n def __init__(self, request: Request, lighter: Optional[bool] = False, darker: Optional[bool] = False, inverse: Optional[bool] = False, amount: Optional[int] = 10):\n self.request = request\n self.lighter = lighter\n self.darker = darker\n self.inverse = inverse\n self.amount = amount\n\nclass Arguments(BaseModel):\n lighter: Optional[bool] = False\n darker: Optional[bool] = False\n inverse: Optional[bool] = False\n amount: Optional[int] = 10\n\n@app.get(\"/REDS/\")\ndef query_REDS(params=Depends(CommonParams)):\n pass # Work done here\n\n@app.get(\"/BLUES/\")\ndef query_BLUES(params=Depends(Arguments)):\n pass # Work done here\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.132Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":122,"estimatedTokens":986}}420{"id":"stack-68336259","source":"stackoverflow","questionId":68336259,"title":"\"FastAPIError: Invalid args for response field! Hint: check that is a valid pydantic field type\"","tags":["python","fastapi","pydantic"],"text":"Title: \"FastAPIError: Invalid args for response field! Hint: check that is a valid pydantic field type\"\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI have the following Pydantic schema for a FastAPI app.\n\nIn the following schema, whenever I have `ParameterSchema` as the schema validator for `params`, it gives me the following error:\n\n```\nfastapi.exceptions.FastAPIError: Invalid args for response field! Hint: check that is a valid pydantic field type\n```\n\nI have no idea what's going on!\n\n```\nclass ParameterSchema(BaseModel):\n expiryDate = Optional[datetime]\n\n class Config:\n arbitrary_types_allowed = True\n\nclass RequestProvisioningEventData(BaseModel):\n some_attribute: List[str]\n other_attribute: Optional[List[str]] = []\n bool_attribute: bool\n params: ParameterSchema\n\n class Config:\n use_enum_values = True\n```\n\n========================================\n\nCode:\n```text\nfastapi.exceptions.FastAPIError: Invalid args for response field! Hint: check that <class 'typing._GenericAlias'> is a valid pydantic field type\n```\n\n```text\nclass ParameterSchema(BaseModel):\n expiryDate = Optional[datetime]\n\n class Config:\n arbitrary_types_allowed = True\n\n\nclass RequestProvisioningEventData(BaseModel):\n some_attribute: List[str]\n other_attribute: Optional[List[str]] = []\n bool_attribute: bool\n params: ParameterSchema\n\n class Config:\n use_enum_values = True\n```\n\n```text\nParameterSchema\n```\n\n```text\nparams\n```\n\n```text\nclass ParameterSchema(BaseModel):\n expiryDate = Optional[datetime]\n```\n\n```text\nclass ParameterSchema(BaseModel):\n expiryDate: Optional[datetime]\n```\n\n```text\nexpiryDate\n```\n\n```text\n=\n```\n\n```text\n:\n```\n\n```text\n:\n```\n\n```text\n=\n```\n\n========================================\n\nComments:\n- shouldn't that assignment in your ParameterSchema be a colon? `expiryDate: Optional[datetime]`","metadata":{"transformedAt":"2026-08-18T18:32:29.132Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":11,"totalLines":99,"estimatedTokens":466}}421{"id":"stack-73178664","source":"stackoverflow","questionId":73178664,"title":"Why doesn't FastAPI handle types derived from int and Enum correctly?","tags":["validation","fastapi","pydantic"],"text":"Title: Why doesn't FastAPI handle types derived from int and Enum correctly?\nTags: validation, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nWith the following FastAPI backend:\n\n```\nfrom enum import Enum\nfrom fastapi import FastAPI\n\nclass MyNumber(int, Enum):\n ONE = 1\n TWO = 2\n THREE = 3\n\napp = FastAPI()\n\n@app.get(\"/add/{a}/{b}\")\nasync def get_model(a: MyNumber, b: MyNumber):\n return {\"sum\": a + b}\n```\n\nWhen a `GET` operation is done:\n\n```\ncurl -X 'GET' \\\n 'http://127.0.0.1:8000/add/2/3' \\\n -H 'accept: application/json'\n```\n\nReturns the following:\n\n```\n{\n \"detail\": [\n {\n \"loc\": [\n \"path\",\n \"a\"\n ],\n \"msg\": \"value is not a valid enumeration member; permitted: 1, 2, 3\",\n \"type\": \"type_error.enum\",\n \"ctx\": {\n \"enum_values\": [\n 1,\n 2,\n 3\n ]\n }\n },\n {\n \"loc\": [\n \"path\",\n \"b\"\n ],\n \"msg\": \"value is not a valid enumeration member; permitted: 1, 2, 3\",\n \"type\": \"type_error.enum\",\n \"ctx\": {\n \"enum_values\": [\n 1,\n 2,\n 3\n ]\n }\n }\n ]\n}\n```\n\nWhy is this the case? Even the Swagger UI does recognize the possible values as integers:\n\nhttps://i.sstatic.net/Pm3gfl.png\n\nI have tried the solution of using `IntEnum` instead (source), and I can confirm that it works, but still - why does it have to be this way?\n\nThe enum.py source code defines `IntEnum` as:\n\n```\nclass IntEnum(int, Enum):\n \"\"\"Enum where members are also (and must be) ints\"\"\"\n```\n\n========================================\n\nCode:\n```py\nfrom enum import Enum\nfrom fastapi import FastAPI\n\nclass MyNumber(int, Enum):\n ONE = 1\n TWO = 2\n THREE = 3\n\napp = FastAPI()\n\n@app.get(\"/add/{a}/{b}\")\nasync def get_model(a: MyNumber, b: MyNumber):\n return {\"sum\": a + b}\n```\n\n```text\ncurl -X 'GET' \\\n 'http://127.0.0.1:8000/add/2/3' \\\n -H 'accept: application/json'\n```\n\n```text\n{\n \"detail\": [\n {\n \"loc\": [\n \"path\",\n \"a\"\n ],\n \"msg\": \"value is not a valid enumeration member; permitted: 1, 2, 3\",\n \"type\": \"type_error.enum\",\n \"ctx\": {\n \"enum_values\": [\n 1,\n 2,\n 3\n ]\n }\n },\n {\n \"loc\": [\n \"path\",\n \"b\"\n ],\n \"msg\": \"value is not a valid enumeration member; permitted: 1, 2, 3\",\n \"type\": \"type_error.enum\",\n \"ctx\": {\n \"enum_values\": [\n 1,\n 2,\n 3\n ]\n }\n }\n ]\n}\n```\n\n```py\nclass IntEnum(int, Enum):\n \"\"\"Enum where members are also (and must be) ints\"\"\"\n```\n\n```text\nGET\n```\n\n```text\nIntEnum\n```\n\n```text\nIntEnum\n```\n\n```py\n@app.get(\"/add/{a:int}/{b:int}\")\n```\n\n```text\nRouter\n```\n\n```text\nAPIRouter\n```\n\n```text\npath_params\n```\n\n```text\nRequest\n```\n\n```text\n{\"a\":\"1\", \"b\":\"2\"}\n```\n\n```text\n\"1\" is not 1\n```\n\n```text\nMyNumber\n```\n\n```text\n{\"a\":1, \"b\":2}\n```\n\n```text\n1\n```\n\n```text\n2\n```\n\n```text\nMyNumber(IntEnum)\n```\n\n```text\nMyNumber(int, Enum)\n```\n\n```text\nModelField\n```\n\n```text\nutils.py -> create_response_field()\n```\n\n```text\nvalidators\n```\n\n```text\nint\n```\n\n```text\nIntEnum\n```\n\n```text\nModelField\n```\n\n```text\nfunctools.partial()\n```\n\n```text\na\n```\n\n```text\nb\n```\n\n```text\nint\n```\n\n```text\n{a:int}\n```\n\n```text\nIntEnum\n```\n\n========================================\n\nComments:\n- Because Enum can be anything, including not subclasses of int. That is why IntEnum exists, it ensures that it’s members are int or a subclass of int. As FastAPI doesn’t check what kind of member it is, it doesn’t just assume it’s a int. Use IntEnum in this case.\n- @JarroVGIT MyNumber is a subclass of int and Enum\n- Actually: github.com/python/cpython/blob/3.10/Lib/enum.py states that IntEnum is defined as `class IntEnum(int, Enum)`\n- I did some digging, too: In `pydantic/validators.py` there is the global `_VALIDATORS` which defines validators for each type. Seems like validators are just hardcoded for `IntEnum` to be an integer validator + enum validator, and the integer validator converts from string to int. This also means that a class `MyFloats(float, Enum)` as path parameter is also not possible (?), for example.\n- @JarroVGIT Please confirm that `{a:int}` is a working solution, as it doesn't seem to be. It leads to `unsupported operand type(s) for +: 'MyNumber' and 'MyNumber'` error.\n- @Chris that definitely works. Don't forget to also change path param `b`, so full decorator is `@app.get(\"/add/{a:int}/{b:int}\")`. I get a `{\"sum\": 3}` response when calling localhost:8000/add/1/2. See here for full working code: github.com/JarroVGIT/fastapi-github-issues/blob/master/SO/…\n- I tested this on python 3.10.5, FastAPI 0.79 and uvicorn 0.18.2\n- It might have to do with Python version. Tested it on Python 3.8.6.\n- That's strange, as this is a documented Starlette feature: starlette.io/routing/#path-parameters I can't test it on that version (I am on apple silicon and first version with support was 3.8.10). Can confirm it working on 3.8.13 though.\n- tested on Python 3.10.4","metadata":{"transformedAt":"2026-08-18T18:32:29.132Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":32,"totalLines":275,"estimatedTokens":1214}}422{"id":"stack-63099843","source":"stackoverflow","questionId":63099843,"title":"How can I fix FastAPI application error on Apache WSGI?","tags":["apache2","mod-wsgi","fastapi"],"text":"Title: How can I fix FastAPI application error on Apache WSGI?\nTags: apache2, mod-wsgi, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to run FastAPI application on Apache running server.\n\n \nI have configured Apache virtual host file accordingly\n\n```\n\n ServerAdmin admin@example.com\n ServerName fastapi.example.com\n ServerAlias fastapi.example.com\n DocumentRoot /var/www/fastapi\n ErrorLog ${APACHE_LOG_DIR}/fastapi_error.log\n CustomLog ${APACHE_LOG_DIR}/fastapi_access.log combined\n WSGIScriptAlias / /var/www/fastapi/main.wsgi\n \n AllowOverride All\n \n\n```\n\nand created main.wsgi and main.py files.\n\n**main.wsgi**\n\n```\n#! /usr/bin/python3.7\n\nimport logging\nimport sys\nlogging.basicConfig(stream=sys.stderr)\nsys.path.insert(0, '/var/www/fastapi/')\nfrom main import app as application\napplication.secret_key = 'alibaba'\n```\n\n**main.py**\n\n```\nfrom typing import Optional\nfrom fastapi import FastAPI\napp = FastAPI()\n\n@app.get(\"/\")\ndef read_root():\n return {\"Hello\": \"World\"}\n\n@app.get(\"/items/{item_id}\")\ndef read_item(item_id: int, q: Optional[str] = None):\n return {\"item_id\": item_id, \"q\": q}\n```\n\nWhen i am trying to access the web, I got the **500 Internal server Error** with the following log in fastapi_access.log\n\n```\nmod_wsgi (pid=24946): Exception occurred processing WSGI script '/var/www/fastapi/main.wsgi'.\nTypeError: __call__() missing 1 required positional argument: 'send'\n```\n\nCould you please advice, how can I fix this problem and what am I doing wrong?\n\nThanks in advance.\n\n========================================\n\nCode:\n```text\n<VirtualHost *:80>\n ServerAdmin admin@example.com\n ServerName fastapi.example.com\n ServerAlias fastapi.example.com\n DocumentRoot /var/www/fastapi\n ErrorLog ${APACHE_LOG_DIR}/fastapi_error.log\n CustomLog ${APACHE_LOG_DIR}/fastapi_access.log combined\n WSGIScriptAlias / /var/www/fastapi/main.wsgi\n <Directory \"/var/www/fastapi\">\n AllowOverride All\n </Directory>\n</VirtualHost>\n```\n\n```text\n#! /usr/bin/python3.7\n\nimport logging\nimport sys\nlogging.basicConfig(stream=sys.stderr)\nsys.path.insert(0, '/var/www/fastapi/')\nfrom main import app as application\napplication.secret_key = 'alibaba'\n```\n\n```text\nfrom typing import Optional\nfrom fastapi import FastAPI\napp = FastAPI()\n\n@app.get(\"/\")\ndef read_root():\n return {\"Hello\": \"World\"}\n\n@app.get(\"/items/{item_id}\")\ndef read_item(item_id: int, q: Optional[str] = None):\n return {\"item_id\": item_id, \"q\": q}\n```\n\n```text\nmod_wsgi (pid=24946): Exception occurred processing WSGI script '/var/www/fastapi/main.wsgi'.\nTypeError: __call__() missing 1 required positional argument: 'send'\n```\n\n========================================\n\nComments:\n- So, is there any solution to run uvicorn with virtualhosts?\n- Does this helps? Routing for Hosts and Subdomains","metadata":{"transformedAt":"2026-08-18T18:32:29.132Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":120,"estimatedTokens":709}}423{"id":"stack-68815761","source":"stackoverflow","questionId":68815761,"title":"How to customize FastAPI request body documentation","tags":["python","fastapi","pydantic"],"text":"Title: How to customize FastAPI request body documentation\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI'm using FastAPI to serve ML models. My endpoint receives and sends JSON data of the form:\n\n```\n[\n {\"id\": 1, \"data\": [{\"code\": \"foo\", \"value\": 0.1}, {\"code\": \"bar\", \"value\": 0.2}, ...]},\n {\"id\": 2, \"data\": [{\"code\": \"baz\", \"value\": 0.3}, {\"code\": \"foo\", \"value\": 0.4}, ...]},\n ...\n]\n```\n\nMy models and app look as follows:\n\n```\nfrom typing import Dict, List\n \nfrom fastapi import Body\nfrom fastapi.responses import JSONResponse\nfrom pydantic import BaseModel\nimport pandas as pd\n\nclass Item(BaseModel):\n code: str\n value: float\n\nclass Sample(BaseModel):\n id: int\n data: List[Item]\n\napp = FastAPI()\n\n@app.post(\"/score\", response_model=List[Sample]) # correct response documentation\ndef score(input_data: List[Sample] = Body(...)): # 1. conversion dict -> Pydantic models, slow\n input_df: pd.DataFrame = models_to_df(input_data) # 2. conversion Pydantic models -> df\n\n output_df: pd.DataFrame = predict(input_df)\n\n output_data: Dict = df_to_dict(output_df) # direct conversion df -> dict, fast\n return JSONResponse(output_data)\n```\n\nEverything works fine and the automated documentation looks good, but the performance is bad. Since the data can be quite large, Pydantic conversion and validation can take a lot of time.\n\nThis can easily be solved by writing direct conversion functions between JSON data and data frames, skipping the intermediary representation of Pydantic models. This is what I did for the response, achieving a 10x speedup, at the same time preserving the automated API documentation with the `response_model=List[Sample]` argument.\n\nI would like to achieve the same with the request: being able to use custom JSON input parsing, while at the same time preserving API documentation using Pydantic models. Sadly I can't find a way to do it in the FastAPI docs. How can I accomplish this?\n\n========================================\n\nCode:\n```json\n[\n {\"id\": 1, \"data\": [{\"code\": \"foo\", \"value\": 0.1}, {\"code\": \"bar\", \"value\": 0.2}, ...]},\n {\"id\": 2, \"data\": [{\"code\": \"baz\", \"value\": 0.3}, {\"code\": \"foo\", \"value\": 0.4}, ...]},\n ...\n]\n```\n\n```py\nfrom typing import Dict, List\n \nfrom fastapi import Body\nfrom fastapi.responses import JSONResponse\nfrom pydantic import BaseModel\nimport pandas as pd\n\n\nclass Item(BaseModel):\n code: str\n value: float\n\n\nclass Sample(BaseModel):\n id: int\n data: List[Item]\n\n\napp = FastAPI()\n\n\n@app.post(\"/score\", response_model=List[Sample]) # correct response documentation\ndef score(input_data: List[Sample] = Body(...)): # 1. conversion dict -> Pydantic models, slow\n input_df: pd.DataFrame = models_to_df(input_data) # 2. conversion Pydantic models -> df\n\n output_df: pd.DataFrame = predict(input_df)\n\n output_data: Dict = df_to_dict(output_df) # direct conversion df -> dict, fast\n return JSONResponse(output_data)\n```\n\n```text\nresponse_model=List[Sample]\n```\n\n```py\n@app.post(\n \"/score\",\n response_model=List[Sample],\n openapi_extra={\n \"requestBody\": {\n \"content\": {\n \"application/json\": {\n \"schema\": {\n \"type\": \"array\",\n \"items\": Sample.schema(ref_template=\"#/components/schemas/{model}\"),\n }\n }\n }\n }\n },\n)\nasync def score(request: Request):\n raw_body = await request.body()\n # parse the `raw_body` request data (bytes) into your DF directly.\n```\n\n```text\ndata = await request.json()\n```\n\n```text\nparser = ... # something that can be fed chunks of data\nasync for chunk in request.stream():\n parser.feed(chunk)\n```\n\n```text\nrequest.body()\n```\n\n```text\nbytes\n```\n\n```text\nopenapi_extra\n```\n\n```text\n@app.post()\n```\n\n```text\nopenapi_extra\n```\n\n```text\nresponse_model\n```\n\n```text\nSample\n```\n\n```text\nRequest\n```\n\n```text\nRequest\n```\n\n```text\nRequest\n```\n\n========================================\n\nComments:\n- Thanks a lot for this detailed answer, that's exactly what I needed! I just had to add a `ref_template=\"#/components/schemas/{model}\"` argument to the `.schema()` method in your code sample to have correct openapi references. I suggested an edit to your answer.\n- @Macfli: darn, I had made a mental note to verify the `ref_template` argument but other priorities interfered. Edit applied!","metadata":{"transformedAt":"2026-08-18T18:32:29.132Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":16,"totalLines":175,"estimatedTokens":1097}}424{"id":"stack-73195338","source":"stackoverflow","questionId":73195338,"title":"How to avoid database connection pool from being exhausted when using FastAPI in threaded mode ( with `def` instead of `async def`)","tags":["python","python-multithreading","fastapi","connection-pool"],"text":"Title: How to avoid database connection pool from being exhausted when using FastAPI in threaded mode ( with `def` instead of `async def`)\nTags: python, python-multithreading, fastapi, connection-pool\nSource: Stack Overflow\n\nQuestion:\nI use FastAPI for a production application that uses asyncio almost entirely except when hitting the database. The database still relies on synchronous SQLAlchemy as the async version was still in alpha (or early beta) at the time.\n\nWhile our services do end up making synchronous blocking calls when it hits the database it's still wrapped in async functions. We do run multiple workers and several instances of the app to ensure we don't hit serious bottlenecks.\n\n### Concurrency with Threads\n\nI understand that FastAPI offers concurrency using threads when using the `def controller_method` approach but I can't seem to find any details around how it controls the environment. Could somebody help me understand how to control the maximum threads a process can generate. What if it hits system limits?\n\n### Database connections\n\nWhen I use the async await model I create database connection objects in the middleware which is injected into the controller actions.\n\n```\n@app.middleware(\"http\")\nasync def db_session_middleware(request: Request, call_next):\n \n await _set_request_id()\n\n try:\n request.state.db = get_sessionmaker(scope_func=None)\n response = await call_next(request)\n finally:\n if request.state.db.is_active:\n request.state.db.close()\n return response\n```\n\nWhen it's done via threads is the controller already getting called in a separate thread, ensuring a separate connection for each request?\n\nNow if I can't limit the number of threads that are being spawned by the main process, if my application gets a sudden surge of requests won't it overshoot the database connection pool limit and eventually blocking my application?\n\nIs there a central threadpool used by FastAPI that I can configure or is this controlled by Uvicorn?\n\n### Uvicorn\n\nI see that Uvicorn has a configuration that let's it limit the concurrency using the `--limit-concurrency 60` flag. Is this governing the number of concurrent threads created in the threaded mode?\n\nIf so, should this always be a lower than my connection pool ( connection pool + max_overflow=40)\n\nSo in the scenario, where I'm allowing a uvicorn concurrency limit of 60 my db connection pool configurations should be something like this?\n\n```\nengine = sqlalchemy.create_engine(\n cfg(\"DB_URL\"), \n pool_size=40, \n max_overflow=20, \n echo=False, \n pool_use_lifo=False,\n pool_recycle=120\n)\n```\n\nIs there a central threadpool that is being used in this case? Are there any sample projects that I can look at to see how this could be configured when deployed at scale.\n\nI've used Netflix Dispatch as a reference but if there are other projects I'd definitely want to look at those.\n\n========================================\n\nCode:\n```py\n@app.middleware(\"http\")\nasync def db_session_middleware(request: Request, call_next):\n \n await _set_request_id()\n\n try:\n request.state.db = get_sessionmaker(scope_func=None)\n response = await call_next(request)\n finally:\n if request.state.db.is_active:\n request.state.db.close()\n return response\n```\n\n```py\nengine = sqlalchemy.create_engine(\n cfg(\"DB_URL\"), \n pool_size=40, \n max_overflow=20, \n echo=False, \n pool_use_lifo=False,\n pool_recycle=120\n)\n```\n\n```text\ndef controller_method\n```\n\n```text\n--limit-concurrency 60\n```\n\n```py\nimport threading\nimport anyio\nimport uvicorn\nfrom fastapi import FastAPI\nimport time\nimport logging\n\nTHREADS_LIMIT = 5\n\nlogging.basicConfig(level=logging.DEBUG)\napp = FastAPI()\n\n\nclass Counter(object):\n def __init__(self):\n self._value = 0\n self._lock = threading.Lock()\n\n def increment(self):\n with self._lock:\n self._value += 1\n\n def decrement(self):\n with self._lock:\n self._value -= 1\n\n def value(self):\n with self._lock:\n return self._value\n\n\ncounter = Counter()\n\n\n@app.get(\"/start_task\")\ndef start_task():\n counter.increment()\n logging.info(\"Route started. Counter: %d\", counter.value())\n time.sleep(10)\n counter.decrement()\n logging.info(\"Route stopped. Counter: %d\", counter.value())\n return \"Task done\"\n\n\n@app.on_event(\"startup\")\nasync def startup_event():\n limiter = anyio.to_thread.current_default_thread_limiter()\n limiter.total_tokens = THREADS_LIMIT\n\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", port=8000, log_level=\"debug\")\n```\n\n```text\nseq 1 50 | xargs -n1 -P50 curl \"http://localhost:8000/start_task\"\n```\n\n```text\nINFO:root:Route started. Counter: 1\nINFO:root:Route started. Counter: 2\nINFO:root:Route started. Counter: 3\nINFO:root:Route started. Counter: 4\nINFO:root:Route started. Counter: 5\nINFO:root:Route stopped. Counter: 4\nINFO:uvicorn.access:127.0.0.1:60830 - \"GET /start_task HTTP/1.1\" 200\nINFO:root:Route stopped. Counter: 3\nINFO:root:Route started. Counter: 4\nINFO:uvicorn.access:127.0.0.1:60832 - \"GET /start_task HTTP/1.1\" 200\nINFO:root:Route started. Counter: 5\n...\n```\n\n```text\ndef\n```\n\n```text\nCapacityLimiter\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.132Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":179,"estimatedTokens":1299}}425{"id":"stack-70486911","source":"stackoverflow","questionId":70486911,"title":"How can I install fastapi properly?","tags":["python","pip","fastapi"],"text":"Title: How can I install fastapi properly?\nTags: python, pip, fastapi\nSource: Stack Overflow\n\nQuestion:\nI want to install fastapi using pip in VsCode using\n\n```\npip install fastapi[all]\n```\n\nbut I am getting this huge error. What am I doing wrong?\n\n```\nERROR: Command errored out with exit status 1:\n command: 'C:\\Users\\krish\\Desktop\\Codes\\API\\venv\\Scripts\\python.exe' -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '\"'\"'C:\\\\Users\\\\krish\\\\AppData\\\\Local\\\\Temp\\\\pip-install-eqmneh6a\\\\httptools_b8491d7c29264d1c9eb72c9367d56d7a\\\\setup.py'\"'\"'; __file__='\"'\"'C:\\\\Users\\\\krish\\\\AppData\\\\Local\\\\Temp\\\\pip-install-eqmneh6a\\\\httptools_b8491d7c29264d1c9eb72c9367d56d7a\\\\setup.py'\"'\"';f = getattr(tokenize, '\"'\"'open'\"'\"', open)(__file__) if os.path.exists(__file__) else io.StringIO('\"'\"'from setuptools import setup; setup()'\"'\"');code = f.read().replace('\"'\"'\\r\\n'\"'\"', '\"'\"'\\n'\"'\"');f.close();exec(compile(code, __file__, '\"'\"'exec'\"'\"'))' install --record 'C:\\Users\\krish\\AppData\\Local\\Temp\\pip-record-wvba_iw2\\install-record.txt' --single-version-externally-managed --compile --install-headers 'C:\\Users\\krish\\Desktop\\Codes\\API\\venv\\include\\site\\python3.10\\httptools'\n cwd: C:\\Users\\krish\\AppData\\Local\\Temp\\pip-install-eqmneh6a\\httptools_b8491d7c29264d1c9eb72c9367d56d7a\\\n Complete output (25 lines):\n running install\n running build\n running build_py\n creating build\n creating build\\lib.win-amd64-3.10\n creating build\\lib.win-amd64-3.10\\httptools\n copying httptools\\_version.py -> build\\lib.win-amd64-3.10\\httptools\n copying httptools\\__init__.py -> build\\lib.win-amd64-3.10\\httptools\n creating build\\lib.win-amd64-3.10\\httptools\\parser\n copying httptools\\parser\\errors.py -> build\\lib.win-amd64-3.10\\httptools\\parser\n copying httptools\\parser\\__init__.py -> build\\lib.win-amd64-3.10\\httptools\\parser\n running egg_info\n writing httptools.egg-info\\PKG-INFO\n writing dependency_links to httptools.egg-info\\dependency_links.txt\n writing requirements to httptools.egg-info\\requires.txt\n writing top-level names to httptools.egg-info\\top_level.txt\n reading manifest file 'httptools.egg-info\\SOURCES.txt'\n reading manifest template 'MANIFEST.in'\n adding license file 'LICENSE'\n writing manifest file 'httptools.egg-info\\SOURCES.txt'\n copying httptools\\parser\\parser.c -> build\\lib.win-amd64-3.10\\httptools\\parser\n copying httptools\\parser\\url_parser.c -> build\\lib.win-amd64-3.10\\httptools\\parser\n running build_ext\n building 'httptools.parser.parser' extension\n error: Microsoft Visual C++ 14.0 or greater is required. Get it with \"Microsoft C++ Build Tools\": https://visualstudio.microsoft.com/visual-cpp-build-tools/\n ----------------------------------------\nERROR: Command errored out with exit status 1: 'C:\\Users\\krish\\Desktop\\Codes\\API\\venv\\Scripts\\python.exe' -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '\"'\"'C:\\\\Users\\\\krish\\\\AppData\\\\Local\\\\Temp\\\\pip-install-eqmneh6a\\\\httptools_b8491d7c29264d1c9eb72c9367d56d7a\\\\setup.py'\"'\"'; __file__='\"'\"'C:\\\\Users\\\\krish\\\\AppData\\\\Local\\\\Temp\\\\pip-install-eqmneh6a\\\\httptools_b8491d7c29264d1c9eb72c9367d56d7a\\\\setup.py'\"'\"';f = getattr(tokenize, '\"'\"'open'\"'\"', open)(__file__) if os.path.exists(__file__) else io.StringIO('\"'\"'from setuptools import setup; setup()'\"'\"');code = f.read().replace('\"'\"'\\r\\n'\"'\"', '\"'\"'\\n'\"'\"');f.close();exec(compile(code, __file__, '\"'\"'exec'\"'\"'))' install --record 'C:\\Users\\krish\\AppData\\Local\\Temp\\pip-record-wvba_iw2\\install-record.txt' --single-version-externally-managed --compile --install-headers 'C:\\Users\\krish\\Desktop\\Codes\\API\\venv\\include\\site\\python3.10\\httptools' Check the logs for full command output.\n```\n\n========================================\n\nTop Answer:\nu install 'uvicorn' differently?\n\nTry to do these commands :\n\npip install \"uvicorn[standard]\"\n\nThe library needs the VC v14+ runtime library, not VS build tools. You can get the runtime from the MS downloads page. Install the VS 2015/2017/2019 redist as it is the latest version.\n\n========================================\n\nCode:\n```none\npip install fastapi[all]\n```\n\n```none\nERROR: Command errored out with exit status 1:\n command: 'C:\\Users\\krish\\Desktop\\Codes\\API\\venv\\Scripts\\python.exe' -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '\"'\"'C:\\\\Users\\\\krish\\\\AppData\\\\Local\\\\Temp\\\\pip-install-eqmneh6a\\\\httptools_b8491d7c29264d1c9eb72c9367d56d7a\\\\setup.py'\"'\"'; __file__='\"'\"'C:\\\\Users\\\\krish\\\\AppData\\\\Local\\\\Temp\\\\pip-install-eqmneh6a\\\\httptools_b8491d7c29264d1c9eb72c9367d56d7a\\\\setup.py'\"'\"';f = getattr(tokenize, '\"'\"'open'\"'\"', open)(__file__) if os.path.exists(__file__) else io.StringIO('\"'\"'from setuptools import setup; setup()'\"'\"');code = f.read().replace('\"'\"'\\r\\n'\"'\"', '\"'\"'\\n'\"'\"');f.close();exec(compile(code, __file__, '\"'\"'exec'\"'\"'))' install --record 'C:\\Users\\krish\\AppData\\Local\\Temp\\pip-record-wvba_iw2\\install-record.txt' --single-version-externally-managed --compile --install-headers 'C:\\Users\\krish\\Desktop\\Codes\\API\\venv\\include\\site\\python3.10\\httptools'\n cwd: C:\\Users\\krish\\AppData\\Local\\Temp\\pip-install-eqmneh6a\\httptools_b8491d7c29264d1c9eb72c9367d56d7a\\\n Complete output (25 lines):\n running install\n running build\n running build_py\n creating build\n creating build\\lib.win-amd64-3.10\n creating build\\lib.win-amd64-3.10\\httptools\n copying httptools\\_version.py -> build\\lib.win-amd64-3.10\\httptools\n copying httptools\\__init__.py -> build\\lib.win-amd64-3.10\\httptools\n creating build\\lib.win-amd64-3.10\\httptools\\parser\n copying httptools\\parser\\errors.py -> build\\lib.win-amd64-3.10\\httptools\\parser\n copying httptools\\parser\\__init__.py -> build\\lib.win-amd64-3.10\\httptools\\parser\n running egg_info\n writing httptools.egg-info\\PKG-INFO\n writing dependency_links to httptools.egg-info\\dependency_links.txt\n writing requirements to httptools.egg-info\\requires.txt\n writing top-level names to httptools.egg-info\\top_level.txt\n reading manifest file 'httptools.egg-info\\SOURCES.txt'\n reading manifest template 'MANIFEST.in'\n adding license file 'LICENSE'\n writing manifest file 'httptools.egg-info\\SOURCES.txt'\n copying httptools\\parser\\parser.c -> build\\lib.win-amd64-3.10\\httptools\\parser\n copying httptools\\parser\\url_parser.c -> build\\lib.win-amd64-3.10\\httptools\\parser\n running build_ext\n building 'httptools.parser.parser' extension\n error: Microsoft Visual C++ 14.0 or greater is required. Get it with \"Microsoft C++ Build Tools\": https://visualstudio.microsoft.com/visual-cpp-build-tools/\n ----------------------------------------\nERROR: Command errored out with exit status 1: 'C:\\Users\\krish\\Desktop\\Codes\\API\\venv\\Scripts\\python.exe' -u -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '\"'\"'C:\\\\Users\\\\krish\\\\AppData\\\\Local\\\\Temp\\\\pip-install-eqmneh6a\\\\httptools_b8491d7c29264d1c9eb72c9367d56d7a\\\\setup.py'\"'\"'; __file__='\"'\"'C:\\\\Users\\\\krish\\\\AppData\\\\Local\\\\Temp\\\\pip-install-eqmneh6a\\\\httptools_b8491d7c29264d1c9eb72c9367d56d7a\\\\setup.py'\"'\"';f = getattr(tokenize, '\"'\"'open'\"'\"', open)(__file__) if os.path.exists(__file__) else io.StringIO('\"'\"'from setuptools import setup; setup()'\"'\"');code = f.read().replace('\"'\"'\\r\\n'\"'\"', '\"'\"'\\n'\"'\"');f.close();exec(compile(code, __file__, '\"'\"'exec'\"'\"'))' install --record 'C:\\Users\\krish\\AppData\\Local\\Temp\\pip-record-wvba_iw2\\install-record.txt' --single-version-externally-managed --compile --install-headers 'C:\\Users\\krish\\Desktop\\Codes\\API\\venv\\include\\site\\python3.10\\httptools' Check the logs for full command output.\n```\n\n```none\npip install --only-binary :all: fastapi[all]\n```\n\n```text\n# install command pip install poetry\n\n# Verify the installed version poetry --version\n\npoetry add fastapi uvicorn[standard]\n# zsh USE: poetry add fastapi \"uvicorn[standard]\"\n```\n\n```text\npip install \"fastapi[standard]\"\n```\n\n========================================\n\nComments:\n- The error message says \"Microsoft Visual C++ 14.0 or greater is required. Get it with Microsoft C++ Build Tools\". Have you done that?\n- I installed Microsoft Visual C++ 19 and I'm getting the same error.\n- Did you specifically select/enable the Build Tools as part of the installation? See: stackoverflow.com/a/55575792/2745495\n- Does this answer your question? Microsoft Visual C++ 14.0 is required (Unable to find vcvarsall.bat)\n- The question was about fastapi, and from the error message it is about missing \"*Microsoft C++ Build Tools*\"\n- I don't want to install everything separately. The fastapi documentation says to use fastapi[all] to install everything at once. BTW It still gives the same error.\n- poetry or pipenv and most other package managers still use pip internally. The issue is with this part of the error message: \"*error: Microsoft Visual C++ 14.0 or greater is required.*\" which will still happen with poetry. The OP is trying to install `fastapi[all]` which seems to require compiling from source.\n- No, I don't agree with you, I just provided the viable solution and I use it all the time. Thanks.\n- The question was \"What am I doing wrong?\" he didn't ask tell me how to do this differently, or how you do it.","metadata":{"transformedAt":"2026-08-18T18:32:29.132Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":5,"totalLines":128,"estimatedTokens":2279}}426{"id":"stack-65675907","source":"stackoverflow","questionId":65675907,"title":"How do I call another path on FastAPI?","tags":["python","request","fastapi"],"text":"Title: How do I call another path on FastAPI?\nTags: python, request, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm working on an API that returns some files from a local folder, to simulate a system that we have for the developer environment.\n\nMost of the system works by putting the code that identifies the person and returning his file. but, one path of this system has a unique behavior: It uses a POST method (with the request body containing the Id code), and I'm struggling to make it work.\n\nThis is my current code:\n\n```\nimport json\nfrom pathlib import Path\n\nimport yaml\nfrom fastapi import FastAPI\nfrom pydantic.main import BaseModel\n\napp = FastAPI()\n\nclass RequestModel(BaseModel):\n assetId: str\n\n@app.get(\"/{group}/{service}/{assetId}\")\nasync def return_json(group: str, service: str, assetId: str):\n with open(\"application-dev.yml\", \"r\") as config_file:\n output_dir = yaml.load(config_file)['path']\n path = Path(output_dir + f\"{group}/{service}/\")\n\n file = [f for f in path.iterdir() if f.stem == assetId][0]\n\n if file.exists():\n with file.open() as target_file:\n return json.load(target_file)\n\n@app.post(\"/DataService/ServiceProtocol\")\nasync def return_post_path(request: RequestModel):\n return return_json(\"DataService\", \"ServiceProtocol\", request.msisdn)\n```\n\nI had the idea to call another path/function from the API itself to return the desired value, but I'm getting this error:\n\n```\nValueError: [TypeError(\"'coroutine' object is not iterable\"), TypeError('vars() argument must have __dict__ attribute')]\n```\n\n========================================\n\nCode:\n```text\nimport json\nfrom pathlib import Path\n\nimport yaml\nfrom fastapi import FastAPI\nfrom pydantic.main import BaseModel\n\n\napp = FastAPI()\n\nclass RequestModel(BaseModel):\n assetId: str\n\n\n@app.get(\"/{group}/{service}/{assetId}\")\nasync def return_json(group: str, service: str, assetId: str):\n with open(\"application-dev.yml\", \"r\") as config_file:\n output_dir = yaml.load(config_file)['path']\n path = Path(output_dir + f\"{group}/{service}/\")\n\n file = [f for f in path.iterdir() if f.stem == assetId][0]\n\n if file.exists():\n with file.open() as target_file:\n return json.load(target_file)\n\n\n@app.post(\"/DataService/ServiceProtocol\")\nasync def return_post_path(request: RequestModel):\n return return_json(\"DataService\", \"ServiceProtocol\", request.msisdn)\n```\n\n```text\nValueError: [TypeError(\"'coroutine' object is not iterable\"), TypeError('vars() argument must have __dict__ attribute')]\n```\n\n```text\n@app.post(\"/DataService/ServiceProtocol\")\nasync def return_post_path(request: RequestModel):\n # unpack return_json into a non-coroutine object before returning it\n return await return_json(\"DataService\", \"ServiceProtocol\", request.msisdn)\n```\n\n```text\n@app.post(\"/DataService/ServiceProtocol\")\ndef return_post_path(request: RequestModel):\n # return the coroutine directly because we're inside a normal function\n return return_json(\"DataService\", \"ServiceProtocol\", request.msisdn)\n```\n\n```text\nreturn_json\n```\n\n```text\nasync\n```\n\n```text\n@app.post(...)\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.132Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":7,"totalLines":112,"estimatedTokens":773}}427{"id":"stack-64545132","source":"stackoverflow","questionId":64545132,"title":"Will run_in_executor ever block?","tags":["python","multithreading","asynchronous","python-asyncio","fastapi"],"text":"Title: Will run_in_executor ever block?\nTags: python, multithreading, asynchronous, python-asyncio, fastapi\nSource: Stack Overflow\n\nQuestion:\nsuppose if I have a web server like this:\n\n```\nfrom fastapi import FastAPI\nimport uvicorn\nimport asyncio\n\napp = FastAPI()\n\ndef blocking_function():\n import time\n time.sleep(5)\n return 42\n\n@app.get(\"/\")\nasync def root():\n loop = asyncio.get_running_loop()\n\n result = await loop.run_in_executor(None, blocking_function)\n return result\n\n@app.get(\"/ok\")\nasync def ok():\n return {\"ok\": 1}\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", workers=1)\n```\n\nAs I understand, the code will spawn another thread in the default ThreadExecutorPool and then execute the blocking function in the thread pool. On the other side, thinking about how the GIL works, the CPython interpreter will only execute a thread for 100 `ticks` and then it will switch to another thread to be fair and give other threads a chance to progress. In this case, what if the Python interpreter decides to switch to the threads where the blocking_function is executing? Will it block the who interpreter to wait for whatever remaining on the `time.sleep(5)`?\n\nThe reason I am asking this is that I have observed sometimes my application will block on the `blocking_function`, however I am not entirely sure what's in play here as my `blocking_function` is quite special -- it talks to a COM API object through the win32com library. I am trying to rule out that this is some GIL pitfalls I am falling into.\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI\nimport uvicorn\nimport asyncio\n\napp = FastAPI()\n\ndef blocking_function():\n import time\n time.sleep(5)\n return 42\n\n@app.get(\"/\")\nasync def root():\n loop = asyncio.get_running_loop()\n\n result = await loop.run_in_executor(None, blocking_function)\n return result\n\n@app.get(\"/ok\")\nasync def ok():\n return {\"ok\": 1}\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", workers=1)\n```\n\n```text\nticks\n```\n\n```text\ntime.sleep(5)\n```\n\n```text\nblocking_function\n```\n\n```text\nblocking_function\n```\n\n```text\ntime.sleep\n```\n\n```text\nwin32com\n```\n\n```text\nrun_in_executor\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\nrun_in_executor\n```\n\n========================================\n\nComments:\n- Great, that clarified a lot then. Thanks!","metadata":{"transformedAt":"2026-08-18T18:32:29.132Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":10,"totalLines":108,"estimatedTokens":589}}428{"id":"stack-72468241","source":"stackoverflow","questionId":72468241,"title":"Exception closing connection using sqlalchemy with asyncio and postgresql","tags":["python","sqlalchemy","python-asyncio","fastapi","asyncpg"],"text":"Title: Exception closing connection using sqlalchemy with asyncio and postgresql\nTags: python, sqlalchemy, python-asyncio, fastapi, asyncpg\nSource: Stack Overflow\n\nQuestion:\nI have an API server using Python 3.7.10. I am using the FastAPI framework with sqlalchemy, asyncio, psycopg2-binary, asyncpg along with postgresql. I am deploying this using aws elasticbeanstalk. The application seems to work fine but everytime my frontend calls an endpoint, it seems like the connection is not closing correctly.\n\n**Error**\n\n```\nJun 1 21:17:33 web: ERROR:sqlalchemy.pool.impl.AsyncAdaptedQueuePool:Exception closing connection >\nJun 1 21:17:33 web: Traceback (most recent call last):\nJun 1 21:17:33 web: File \"/var/app/venv/staging-LQM1lest/lib64/python3.7/site-packages/sqlalchemy/pool/base.py\", line 247, in _close_connection\nJun 1 21:17:33 web: self._dialect.do_close(connection)\nJun 1 21:17:33 web: File \"/var/app/venv/staging-LQM1lest/lib64/python3.7/site-packages/sqlalchemy/engine/default.py\", line 688, in do_close\nJun 1 21:17:33 web: dbapi_connection.close()\nJun 1 21:17:33 web: File \"/var/app/venv/staging-LQM1lest/lib64/python3.7/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py\", line 749, in close\nJun 1 21:17:33 web: self.await_(self._connection.close())\nJun 1 21:17:33 web: File \"/var/app/venv/staging-LQM1lest/lib64/python3.7/site-packages/sqlalchemy/util/_concurrency_py3k.py\", line 68, in await_only\nJun 1 21:17:33 web: return current.driver.switch(awaitable)\nJun 1 21:17:33 web: File \"/var/app/venv/staging-LQM1lest/lib64/python3.7/site-packages/sqlalchemy/util/_concurrency_py3k.py\", line 121, in greenlet_spawn\nJun 1 21:17:33 web: value = await result\nJun 1 21:17:33 web: File \"/var/app/venv/staging-LQM1lest/lib64/python3.7/site-packages/asyncpg/connection.py\", line 1334, in close\nJun 1 21:17:33 web: await self._protocol.close(timeout)\nJun 1 21:17:33 web: File \"asyncpg/protocol/protocol.pyx\", line 581, in close\nJun 1 21:17:33 web: concurrent.futures._base.CancelledError\n```\n\nHere is my setup for the engine and session:\n\n```\nfrom sqlalchemy.ext.asyncio import AsyncSession, create_async_engine\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import sessionmaker\n\nfrom app.model.base import CustomBase\nfrom app.core.config import SQLALCHEMY_DATABASE_URI\n\nengine = create_async_engine(SQLALCHEMY_DATABASE_URI)\n\nSessionLocal = sessionmaker(\n autocommit=False,\n autoflush=False,\n class_=AsyncSession,\n bind=engine,\n expire_on_commit=False,\n)\n```\n\nI am using FastAPI's dependency injection to get the session with the following:\n\n```\nasync def get_db() -> AsyncSession:\n async with SessionLocal() as session:\n yield session\n```\n\nThis error only shows up in my deployment and not my local environment, and seems to only when using sqlalchemy asynchronously with asyncio. Thanks for the help!\n\n========================================\n\nTop Answer:\nIt's quite an old post, but just in case anyone would go around this...\n\nYou are yielding sessions, but you are not closing them. If you use the get_db() as dependency, FastAPI will take care to execute the code after the yield (at the end of the request lifetime), so if you do something like this:\n\n```\nasync def get_db() -> AsyncSession:\n async with SessionLocal() as session:\n yield session\n session.close()\n```\n\nit will close (return to the pool) the connection for you.\n\n========================================\n\nCode:\n```text\nJun 1 21:17:33 web: ERROR:sqlalchemy.pool.impl.AsyncAdaptedQueuePool:Exception closing connection <AdaptedConnection <asyncpg.connection.Connection object at 0x7fd8b005cb90>>\nJun 1 21:17:33 web: Traceback (most recent call last):\nJun 1 21:17:33 web: File \"/var/app/venv/staging-LQM1lest/lib64/python3.7/site-packages/sqlalchemy/pool/base.py\", line 247, in _close_connection\nJun 1 21:17:33 web: self._dialect.do_close(connection)\nJun 1 21:17:33 web: File \"/var/app/venv/staging-LQM1lest/lib64/python3.7/site-packages/sqlalchemy/engine/default.py\", line 688, in do_close\nJun 1 21:17:33 web: dbapi_connection.close()\nJun 1 21:17:33 web: File \"/var/app/venv/staging-LQM1lest/lib64/python3.7/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py\", line 749, in close\nJun 1 21:17:33 web: self.await_(self._connection.close())\nJun 1 21:17:33 web: File \"/var/app/venv/staging-LQM1lest/lib64/python3.7/site-packages/sqlalchemy/util/_concurrency_py3k.py\", line 68, in await_only\nJun 1 21:17:33 web: return current.driver.switch(awaitable)\nJun 1 21:17:33 web: File \"/var/app/venv/staging-LQM1lest/lib64/python3.7/site-packages/sqlalchemy/util/_concurrency_py3k.py\", line 121, in greenlet_spawn\nJun 1 21:17:33 web: value = await result\nJun 1 21:17:33 web: File \"/var/app/venv/staging-LQM1lest/lib64/python3.7/site-packages/asyncpg/connection.py\", line 1334, in close\nJun 1 21:17:33 web: await self._protocol.close(timeout)\nJun 1 21:17:33 web: File \"asyncpg/protocol/protocol.pyx\", line 581, in close\nJun 1 21:17:33 web: concurrent.futures._base.CancelledError\n```\n\n```py\nfrom sqlalchemy.ext.asyncio import AsyncSession, create_async_engine\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import sessionmaker\n\nfrom app.model.base import CustomBase\nfrom app.core.config import SQLALCHEMY_DATABASE_URI\n\nengine = create_async_engine(SQLALCHEMY_DATABASE_URI)\n\nSessionLocal = sessionmaker(\n autocommit=False,\n autoflush=False,\n class_=AsyncSession,\n bind=engine,\n expire_on_commit=False,\n)\n```\n\n```py\nasync def get_db() -> AsyncSession:\n async with SessionLocal() as session:\n yield session\n```\n\n```py\nfrom sqlalchemy.pool import NullPool\nfrom sqlalchemy.ext.asyncio import AsyncSession, create_async_engine\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import sessionmaker\n\nfrom app.model.base import CustomBase\nfrom app.core.config import SQLALCHEMY_DATABASE_URI\n\nengine = create_async_engine(\n SQLALCHEMY_DATABASE_URI, pool_pre_ping=True, poolclass=NullPool\n)\n\nSessionLocal = sessionmaker(\n autocommit=False,\n autoflush=False,\n class_=AsyncSession,\n bind=engine,\n expire_on_commit=False,\n)\n```\n\n```text\n@app.middleware(\"http\")\nasync def add_process_time_header(request: fastapi.Request, call_next):\n```\n\n```py\nasync def get_db() -> AsyncSession:\n async with SessionLocal() as session:\n yield session\n session.close()\n```\n\n```text\nfrom sqlalchemy.pool import StaticPool\nfrom sqlalchemy.ext.asyncio import AsyncSession, create_async_engine\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import sessionmaker\n\nfrom app.model.base import CustomBase\nfrom app.core.config import SQLALCHEMY_DATABASE_URI\n\nengine = create_async_engine(\n SQLALCHEMY_DATABASE_URI, pool_pre_ping=True, poolclass=StaticPool\n)\n\nSessionLocal = sessionmaker(\n autocommit=False,\n autoflush=False,\n class_=AsyncSession,\n bind=engine,\n expire_on_commit=False,\n)\n```\n\n========================================\n\nComments:\n- Wow, I started getting this error after I added same http middleware. Did you found out what it was?","metadata":{"transformedAt":"2026-08-18T18:32:29.133Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":7,"totalLines":182,"estimatedTokens":1771}}429{"id":"stack-69224622","source":"stackoverflow","questionId":69224622,"title":"Get FastAPI to handle requests in parallel","tags":["python","python-asyncio","fastapi"],"text":"Title: Get FastAPI to handle requests in parallel\nTags: python, python-asyncio, fastapi\nSource: Stack Overflow\n\nQuestion:\nHere is my trivial `fastapi` app:\n\n```\nfrom datetime import datetime\nimport asyncio\n\nimport uvicorn\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/delayed\")\nasync def get_delayed():\n started = datetime.now()\n print(f\"Starting at: {started}\")\n await asyncio.sleep(10)\n ended = datetime.now()\n print(f\"Ending at: {ended}\")\n return {\"started\": f\"{started}\", \"ended\": f\"{ended}\"}\n\nif __name__ == \"__main__\":\n uvicorn.run(\"fastapitest.main:app\", host=\"0.0.0.0\", port=8000, reload=True, workers=2)\n```\n\nWhen I make 2 consecutive calls to it, the code in the function for the second one doesn't start executing until the first request finishes, producing an output like:\n\n```\nStarting at: 2021-09-17 14:52:40.317915\nEnding at: 2021-09-17 14:52:50.321557\nINFO: 127.0.0.1:58539 - \"GET /delayed HTTP/1.1\" 200 OK\nStarting at: 2021-09-17 14:52:50.328359\nEnding at: 2021-09-17 14:53:00.333032\nINFO: 127.0.0.1:58539 - \"GET /delayed HTTP/1.1\" 200 OK\n```\n\nGiven that the function is marked `async` and I am `await`ing the `sleep`, I would expect a different output, like:\n\n```\nStarting at: ...\nStarting at: ...\nEnding at: ...\nINFO: 127.0.0.1:58539 - \"GET /delayed HTTP/1.1\" 200 OK\nEnding at: ...\nINFO: 127.0.0.1:58539 - \"GET /delayed HTTP/1.1\" 200 OK\n```\n\n[for the calls\nI just opened up 2 browser tabs at localhost:8000/delayed ]\n\nWhat am I missing?\n\n========================================\n\nCode:\n```text\nfrom datetime import datetime\nimport asyncio\n\nimport uvicorn\nfrom fastapi import FastAPI\n\n\napp = FastAPI()\n\n@app.get(\"/delayed\")\nasync def get_delayed():\n started = datetime.now()\n print(f\"Starting at: {started}\")\n await asyncio.sleep(10)\n ended = datetime.now()\n print(f\"Ending at: {ended}\")\n return {\"started\": f\"{started}\", \"ended\": f\"{ended}\"}\n\nif __name__ == \"__main__\":\n uvicorn.run(\"fastapitest.main:app\", host=\"0.0.0.0\", port=8000, reload=True, workers=2)\n```\n\n```text\nStarting at: 2021-09-17 14:52:40.317915\nEnding at: 2021-09-17 14:52:50.321557\nINFO: 127.0.0.1:58539 - \"GET /delayed HTTP/1.1\" 200 OK\nStarting at: 2021-09-17 14:52:50.328359\nEnding at: 2021-09-17 14:53:00.333032\nINFO: 127.0.0.1:58539 - \"GET /delayed HTTP/1.1\" 200 OK\n```\n\n```text\nStarting at: ...\nStarting at: ...\nEnding at: ...\nINFO: 127.0.0.1:58539 - \"GET /delayed HTTP/1.1\" 200 OK\nEnding at: ...\nINFO: 127.0.0.1:58539 - \"GET /delayed HTTP/1.1\" 200 OK\n```\n\n```text\nfastapi\n```\n\n```text\nasync\n```\n\n```text\nawait\n```\n\n```text\nsleep\n```\n\n```text\ncontent-length: 77\ncontent-type: application/json\ndate: Fri, 17 Sep 2021 19:51:39 GMT\nserver: uvicorn\n\n{\n \"ended\": \"2021-09-17 16:51:49.956629\",\n \"started\": \"2021-09-17 16:51:39.955487\"\n}\n\n\nHTTP/1.1 200 OK\ncontent-length: 77\ncontent-type: application/json\ndate: Fri, 17 Sep 2021 19:51:39 GMT\nserver: uvicorn\n\n{\n \"ended\": \"2021-09-17 16:51:49.961173\",\n \"started\": \"2021-09-17 16:51:39.960850\"\n}\n\n\nHTTP/1.1 200 OK\ncontent-length: 77\ncontent-type: application/json\ndate: Fri, 17 Sep 2021 19:51:39 GMT\nserver: uvicorn\n\n{\n \"ended\": \"2021-09-17 16:51:49.964156\",\n \"started\": \"2021-09-17 16:51:39.963510\"\n}\n```\n\n========================================\n\nComments:\n- How do you make calls ?\n- @alex_noname I just opened up 2 browser tabs at localhost:8000/delayed\n- !! this should be easier, but I see the pain. Not working out of the box, no hint on the docs.\n- I saw after I posted that it works if I make the requests from different browsers, and thought it was something on the server side, making some kind of hash from headers and query params and preventing multiple identical requests at the same time. Seems that I was wrong. Thanks for the explanation\n- I have a question, Do FastAPI/uvicorn create seperate python process for each request and handle them parallely or all the request are handled in the same python process, which means we have to be very specific of our global variables. Pls help, ive been trying to find solution of this for quite sometime.\n- It is the same process, and sam e thread - otherwise there would be no point in using async, to start with. You should not use global variables conventionally, but in async projects you *can't* at all!! Ensure all data your functions need is passed by parameters, or try to use \"contextvars\" (which are messy to use) - docs.python.org/3/library/contextvars.html","metadata":{"transformedAt":"2026-08-18T18:32:29.133Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":8,"totalLines":161,"estimatedTokens":1107}}430{"id":"stack-62854314","source":"stackoverflow","questionId":62854314,"title":"FastAPI: Cannot get error handling to work as expected","tags":["python","vue.js","fastapi"],"text":"Title: FastAPI: Cannot get error handling to work as expected\nTags: python, vue.js, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am just learning FastAPI (and loving it), so it is quite likely I am doing something wrong. But here is my problem:\n\nIn the code snippet below, I am creating a new user, *if* there is no user already.\n\nThe code works fine, but it is the error handling that I am having trouble with. The errors are properly being pushed forward to FastAPI's internal docs or to an API client like Postman, but not back to the actual client that I am using or the command line.\n\n```\n@app.post(\"/users/\", response_model=schemas.User)\ndef create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):\n db_user = crud.get_user_by_username(db, username=user.username)\n if db_user:\n raise HTTPException(\n status_code=400, detail=f\"Username '{user.username}' already registered\"\n )\n return crud.create_user(db=db, user=user)\n```\n\nIf I use the auto-generated FastAPI docs (or Postman) and monitor the response in that way, I get the error I am expecting:\n\nhttps://i.sstatic.net/ZjNJO.png\n\nBut when I look at what I am receiving **at the client end (Vue)** or what the **`uvicorn` server is logging**, it does not contain that information:\n\nhttps://i.sstatic.net/zW4Ol.png\n\nAs you can see, it just says `Bad Request` instead of responding with the JSON dict of `{\"detail\": \"Username 'miketest' already registered\"}`\n\nWhat am I doing wrong? What can I do to make sure that the full `HTTPException` information is being returned? I am pretty sure the problem is on the FastAPI end, because the client is receiving exactly what the server is outputting as well.\n\n========================================\n\nTop Answer:\nThis screenshot belongs to console log and it will not contain the API response, the JSON response.\n\nYou can see the actual response if you send the request the API using some client, like POSTMAN.\n\n========================================\n\nCode:\n```py\n@app.post(\"/users/\", response_model=schemas.User)\ndef create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):\n db_user = crud.get_user_by_username(db, username=user.username)\n if db_user:\n raise HTTPException(\n status_code=400, detail=f\"Username '{user.username}' already registered\"\n )\n return crud.create_user(db=db, user=user)\n```\n\n```text\nuvicorn\n```\n\n```text\nBad Request\n```\n\n```text\n{\"detail\": \"Username 'miketest' already registered\"}\n```\n\n```text\nHTTPException\n```\n\n```text\ntry {\n await api().post('register',JSON.stringify(data);\n } catch (err) {\n error = err.response.data.detail;\n }\n```\n\n```text\nresponse\n```\n\n```text\ndata\n```\n\n```text\ndetail\n```\n\n```text\ndetail\n```\n\n```text\ndata\n```\n\n========================================\n\nComments:\n- Yes, @Arakkal. I guess I did not make my point clear enough: Yes, whether I use FastAPI docs or Postman, the API is returning the information of interest. But when I use an *actual client*, or the command line, as I showed in my image, the information is being lost. I updated the question to clarify this. But, how do I get the resonse to the actual client (Vue) properly? Do you know?\n- I am not familiar with *vue.js\", but, interestingly, you said the response is being lost when you try with the command line. How did you try? Can you add the same in OP?\n- Sorry, when I said \"command line\", I meant the output that I get from the server when I launch it from the command line. That is what I put in the question above; that's the screenshot with the blue background.\n- Are you expecting the json response here?\n- Yes. I guess I do not know now it works. I have used Flask (Python) and Express (JS) as backends before, but I will admit I am not an expert. I do not understand why FastAPI is providing complete output to Postman and to its internal API, but not to the server log nor back to Vue.\n- Usualy, none of the frameworks will not emit logs to **stdout**. If your vue does not received any JSON response but the POSTMAN does, it means the problem likely in your vue code base.","metadata":{"transformedAt":"2026-08-18T18:32:29.133Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":11,"totalLines":108,"estimatedTokens":1020}}431{"id":"stack-62780646","source":"stackoverflow","questionId":62780646,"title":"fastapi - import config from main.py","tags":["python","python-3.x","python-import","fastapi"],"text":"Title: fastapi - import config from main.py\nTags: python, python-3.x, python-import, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm new to fastapi, which is really great so far, but I struggle to find a clean way to import my app config to in another module.\n\nEDIT: I need to be able to change the config when running unit test\n\nHere is my dir tree:\n\n```\n/app\n| __init__.py\n| /router\n| | __init__.py\n| | my_router.py\n| /test\n| | test_api.py\n| config.py\n| main.py\n```\n\nHere is my `main.py` file:\n\n```\nfrom functools import lru_cache\n\nfrom fastapi import FastAPI\n\nfrom .router import my_router\nfrom . import config\n\napp = FastAPI()\n\napp.include_router(\n my_router.router,\n prefix=\"/r\",\n tags=[\"my-router\"],\n)\n\n@lru_cache()\ndef get_setting():\n return config.Settings(admin_email=\"admin@domain.com\")\n\n@app.get('/')\ndef hello():\n return 'Hello world'\n```\n\nHere is the `router.py`:\n\n```\nfrom fastapi import APIRouter\n\nfrom ..main import get_setting\n\nrouter = APIRouter()\n\n@router.get('/test')\ndef get_param_list(user_id: int):\n config = get_setting()\n return 'Import Ok'\n```\n\nAnd here is the config file\n\n```\nfrom pydantic import BaseSettings\n\nclass Settings(BaseSettings):\n param_folder: str = \"param\"\n result_folder: str = \"output\"\n\n class Config:\n env_prefix = \"APP_\"\n```\n\nThen runing `uvicorn app.main:app --reload` I got : `ERROR: Error loading ASGI app. Could not import module \"app.main\".`\nI guess because of a kind of circular import. But then I don't how to pass my config to my router ?\n\nThanks for your help :)\n\n========================================\n\nTop Answer:\nThe only draw back with this is that I must add the setting: config.Setting = Depends(config.get_setting), which is quite \"heavy\", to every function call that needs the setting.\n\nYou can use Class Based Views from the fastapi_utils package:\n\n```\nfrom fastapi import APIRouter, Depends\nfrom fastapi_utils.cbv import cbv\nfrom starlette import requests\nfrom logging import Logger\nfrom .. import config\n\nrouter = APIRouter()\n\n@cbv(router)\nclass MyQueryCBV:\n settings: config.Setting = Depends(config.get_setting) # you can introduce settings dependency here\n\n def __init__(self, r: requests.Request): # called for each query\n self.logger: Logger = self.settings.logger\n self.logger.warning(str(r.headers))\n\n @router.get('/test')\n def get_param_list(self, user_id: int)\n self.logger.warning(f\"get_param_list: {user_id}\")\n return self.settings\n\n @router.get(\"/test2\")\n def get_param_list2(self):\n self.logger.warning(f\"get_param_list2\")\n return self.settings\n```\n\n========================================\n\nCode:\n```text\n/app\n| __init__.py\n| /router\n| | __init__.py\n| | my_router.py\n| /test\n| | test_api.py\n| config.py\n| main.py\n```\n\n```text\nfrom functools import lru_cache\n\nfrom fastapi import FastAPI\n\nfrom .router import my_router\nfrom . import config\n\napp = FastAPI()\n\napp.include_router(\n my_router.router,\n prefix=\"/r\",\n tags=[\"my-router\"],\n)\n\n\n@lru_cache()\ndef get_setting():\n return config.Settings(admin_email=\"admin@domain.com\")\n\n\n@app.get('/')\ndef hello():\n return 'Hello world'\n```\n\n```text\nfrom fastapi import APIRouter\n\nfrom ..main import get_setting\n\nrouter = APIRouter()\n\n@router.get('/test')\ndef get_param_list(user_id: int):\n config = get_setting()\n return 'Import Ok'\n```\n\n```text\nfrom pydantic import BaseSettings\n\n\nclass Settings(BaseSettings):\n param_folder: str = \"param\"\n result_folder: str = \"output\"\n\n class Config:\n env_prefix = \"APP_\"\n```\n\n```text\nmain.py\n```\n\n```text\nrouter.py\n```\n\n```text\nuvicorn app.main:app --reload\n```\n\n```text\nERROR: Error loading ASGI app. Could not import module \"app.main\".\n```\n\n```text\nfrom functools import lru_cache\nfrom pydantic import BaseSettings\n\n\nclass Settings(BaseSettings):\n admin_email: str = \"admin@example.com\"\n param_folder: str = \"param\"\n result_folder: str = \"output\"\n\n class Config:\n env_prefix = \"APP_\"\n\n@lru_cache()\ndef get_setting():\n return Settings()\n```\n\n```text\nfrom fastapi import APIRouter, Depends\n\nfrom ..config import Settings, get_setting\n\nrouter = APIRouter()\n\n@router.get('/test')\ndef get_param_list(config: Settings = Depends(get_setting)):\n return config\n```\n\n```text\nfrom fastapi.testclient import TestClient\n\nfrom . import config, main\n\nclient = TestClient(main.app)\n\n\ndef get_settings_override():\n return config.Settings(admin_email=\"testing_admin@example.com\")\n\n\nmain.app.dependency_overrides[config.get_settings] = get_settings_override\n\ndef test_app():\n response = client.get(\"/r/test\")\n data = response.json()\n assert data == config.Settings(admin_email=\"testing_admin@example.com\")\n```\n\n```text\nconfig.py\n```\n\n```text\nmy_router.py\n```\n\n```text\ntest.py\n```\n\n```text\nfrom pydantic import BaseSettings\n\n\nclass Settings(BaseSettings):\n param_folder: str = \"param\"\n result_folder: str = \"output\"\n\n class Config:\n env_prefix = \"APP_\"\n\n@lru_cache()\ndef get_setting():\n return config.Settings(admin_email=\"admin@domain.com\")\n```\n\n```text\nfrom functools import lru_cache\n\nfrom fastapi import FastAPI\n\nfrom .router import my_router\n\napp = FastAPI()\n\napp.include_router(\n my_router.router,\n prefix=\"/r\",\n tags=[\"my-router\"],\n)\n\n@app.get('/')\ndef hello():\n return 'Hello world'\n```\n\n```text\nfrom fastapi import APIRouter, Depends\n\nfrom .. import config\n\nrouter = APIRouter()\n\n@router.get('/test')\ndef get_param_list(user_id: int, setting: config.Setting = Depends(config.get_setting)):\n return setting\n```\n\n```text\nfrom fastapi.testclient import TestClient\n\nfrom .. import config, server\n\nclient = TestClient(server.app)\n\nTEST_PARAM_FOLDER = 'server/test/param'\nTEST_RESULT_FOLDER = 'server/test/result'\n\ndef get_setting_override():\n return config.Setting(param_folder=TEST_PARAM_FOLDER, result_folder=TEST_RESULT_FOLDER)\n\n\nserver.app.dependency_overrides[config.get_setting] = get_setting_override\n\ndef test_1():\n ...\n```\n\n```text\nconfig.py\n```\n\n```text\nsetting: config.Setting = Depends(config.get_setting)\n```\n\n```text\nconfig.py\n```\n\n```text\nmain.py\n```\n\n```text\nrouter.py\n```\n\n```text\ndependency_overrides\n```\n\n```text\ntest_api.py\n```\n\n```text\nfrom fastapi import APIRouter, Depends\nfrom fastapi_utils.cbv import cbv\nfrom starlette import requests\nfrom logging import Logger\nfrom .. import config\n\nrouter = APIRouter()\n\n@cbv(router)\nclass MyQueryCBV:\n settings: config.Setting = Depends(config.get_setting) # you can introduce settings dependency here\n\n def __init__(self, r: requests.Request): # called for each query\n self.logger: Logger = self.settings.logger\n self.logger.warning(str(r.headers))\n\n @router.get('/test')\n def get_param_list(self, user_id: int)\n self.logger.warning(f\"get_param_list: {user_id}\")\n return self.settings\n\n @router.get(\"/test2\")\n def get_param_list2(self):\n self.logger.warning(f\"get_param_list2\")\n return self.settings\n```\n\n========================================\n\nComments:\n- This is indeed how I was doing it but then I can't use the `dependency_overrides` to change config for my unit test as they do in the tutorial: fastapi.tiangolo.com/advanced/settings/#settings-and-testing\n- Isn't it just a matter of setting the dependency override to point to the right place? See updated.","metadata":{"transformedAt":"2026-08-18T18:32:29.133Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":26,"totalLines":392,"estimatedTokens":1813}}432{"id":"stack-79352184","source":"stackoverflow","questionId":79352184,"title":"Why does my FastAPI application redirect to HTTP and not HTTPS?","tags":["azure","fastapi","uvicorn","starlette"],"text":"Title: Why does my FastAPI application redirect to HTTP and not HTTPS?\nTags: azure, fastapi, uvicorn, starlette\nSource: Stack Overflow\n\nQuestion:\nI'm using FastAPI, running via Uvicorn, with the below (default) config:\n\n`app = FastAPI(..., redirect_slashes=True)`\n\nThis should reroute e.g. https://example.com/test/ to https://example.com/test.\n\nWhen running locally via HTTPS, FastAPI (Starlette / Uvicorn) redirect routes successfully from HTTPS to HTTPS, and from HTTP to HTTP.\n\nWhen I run the application on Azure App Service via HTTPs, the `Location` header returned in the `307 Temporary Redirect` response uses HTTP. For example, instead of redirecting https://example.com/test/ to https://example.com/test, I am redirected incorrectly to http://example.com/test.\n\nThis breaks my application as it's not running on HTTP with the browser also blocking the request:\n\nMixed Content: The page at '' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint ''. This request has been blocked; the content must be served over HTTPS.\n\nWhy is the redirect working locally but not when I have deployed the application?\n\n========================================\n\nTop Answer:\nIn my case adding nginx headers and fastapi config for the proxy headers did not work.\n\nI had to hardcode the replacement of http to https in the 307 redirect responses (through a middleware) as follows:\n\n```\nif response.status_code == 307 \n and request.headers.get(\"x-forwarded-proto\") == \"https\":\n response.headers[\"Location\"] = response.headers[\"Location\"].replace('http://', 'https://')\n```\n\n========================================\n\nCode:\n```text\napp = FastAPI(..., redirect_slashes=True)\n```\n\n```text\nLocation\n```\n\n```text\n307 Temporary Redirect\n```\n\n```py\ndef __init__(self, app: ASGI3Application, trusted_hosts: list[str] | str = \"127.0.0.1\") -> None:\n self.app = app\n self.trusted_hosts = _TrustedHosts(trusted_hosts)\n\n...\n\nif client_host in self.trusted_hosts:\n headers = dict(scope[\"headers\"])\n\n if b\"x-forwarded-proto\" in headers:\n x_forwarded_proto = headers[b\"x-forwarded-proto\"].decode(\"latin1\").strip()\n\n if x_forwarded_proto in {\"http\", \"https\", \"ws\", \"wss\"}:\n if scope[\"type\"] == \"websocket\":\n scope[\"scheme\"] = x_forwarded_proto.replace(\"http\", \"ws\")\n else:\n scope[\"scheme\"] = x_forwarded_proto\n```\n\n```text\nuvicorn ... --forwarded-allow-ips *\n```\n\n```text\nuvicorn.run('xxx', forwarded_allow_ips='*')\n```\n\n```text\nX-Forwarded-Proto\n```\n\n```text\nURL\n```\n\n```text\n--proxy-headers\n```\n\n```text\nx-forwarded-proto\n```\n\n```text\nx-forwarded-for\n```\n\n```text\nuvicorn.run\n```\n\n```text\nProxyHeadersMiddleware\n```\n\n```text\n--forwarded-allow-ips *\n```\n\n```text\nforwarded_allow_ips='*'\n```\n\n```text\nuvicorn.run('xxx', forwarded_allow_ips='*')\n```\n\n```text\nFORWARDED_ALLOW_IPS\n```\n\n```text\nX-Forwarded-Proto\n```\n\n```text\n--forwarded-allow-ips\n```\n\n```py\nif response.status_code == 307 \n and request.headers.get(\"x-forwarded-proto\") == \"https\":\n response.headers[\"Location\"] = response.headers[\"Location\"].replace('http://', 'https://')\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.133Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":20,"totalLines":134,"estimatedTokens":779}}433{"id":"stack-76226696","source":"stackoverflow","questionId":76226696,"title":"FastAPI + Uvicorn + multithreading. How to make web app to work with many requests in parallel?","tags":["python","multithreading","fastapi","uvicorn"],"text":"Title: FastAPI + Uvicorn + multithreading. How to make web app to work with many requests in parallel?\nTags: python, multithreading, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI'm new to Python development. (But I have doenet background)\nI do have a simple FastAPI application\n\n```\nfrom fastapi import FastAPI\nimport time\nimport logging\nimport asyncio\nimport random\n\napp = FastAPI()\nr = random.randint(1, 100)\nlogging.basicConfig(level=\"INFO\", format='%(levelname)s | %(asctime)s | %(name)s | %(message)s')\nlogging.info(f\"Starting app {r}\")\n\n@app.get(\"/\")\nasync def long_operation():\n logging.info(f\"Starting long operation {r}\")\n await asyncio.sleep(1)\n time.sleep(4) # I know this is blocking and the endpoint marked as async, but I actually do have some blocking requests in my code.\n return r\n```\n\nAnd I run the app using this comand:\n\n```\nuvicorn \"main:app\" --workers 4\n```\n\nAnd the app starts 4 instances in different processes:\n\n```\nINFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\nINFO: Started parent process [22112]\nINFO | 2023-05-11 12:32:43,544 | root | Starting app 17\nINFO: Started server process [10180] \nINFO: Waiting for application startup.\nINFO: Application startup complete. \nINFO | 2023-05-11 12:32:43,579 | root | Starting app 58\nINFO: Started server process [29592]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\nINFO | 2023-05-11 12:32:43,587 | root | Starting app 12\nINFO: Started server process [7296]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\nINFO | 2023-05-11 12:32:43,605 | root | Starting app 29\nINFO: Started server process [15208]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\n```\n\nThen I open the 3 browser tabs and start sending requests to the app as parallel as possible. And here is the log:\n\n```\nINFO | 2023-05-11 12:32:50,770 | root | Starting long operation 29\nINFO: 127.0.0.1:55031 - \"GET / HTTP/1.1\" 200 OK\nINFO | 2023-05-11 12:32:55,774 | root | Starting long operation 29\nINFO: 127.0.0.1:55031 - \"GET / HTTP/1.1\" 200 OK\nINFO | 2023-05-11 12:33:00,772 | root | Starting long operation 29\nINFO: 127.0.0.1:55031 - \"GET / HTTP/1.1\" 200 OK\nINFO | 2023-05-11 12:33:05,770 | root | Starting long operation 29\nINFO: 127.0.0.1:55031 - \"GET / HTTP/1.1\" 200 OK\nINFO | 2023-05-11 12:33:10,790 | root | Starting long operation 29\nINFO: 127.0.0.1:55031 - \"GET / HTTP/1.1\" 200 OK\nINFO | 2023-05-11 12:33:15,779 | root | Starting long operation 29\nINFO: 127.0.0.1:55031 - \"GET / HTTP/1.1\" 200 OK\nINFO | 2023-05-11 12:33:20,799 | root | Starting long operation 29\nINFO: 127.0.0.1:55031 - \"GET / HTTP/1.1\" 200 OK\nINFO | 2023-05-11 12:33:25,814 | root | Starting long operation 29\nINFO: 127.0.0.1:55031 - \"GET / HTTP/1.1\" 200 OK\nINFO | 2023-05-11 12:33:30,856 | root | Starting long operation 29\nINFO: 127.0.0.1:55031 - \"GET / HTTP/1.1\" 200 OK\n```\n\nMy observations:\n\n- Only 1 process is working. Others do not handle requests (I have tried many times. It is always like that.)\n\n- 4 different instances are created.\n\nMy questions:\n\n- Why only one process does work and others don't?\n\n- If I want to have an in-memory cache. Can I achieve that?\n\n- Can I run 1 process which can handle some amount of requests in parallel?\n\n- Can this be somehow related to the fact that I do tests on Windows?\n\n**UPDATE+SOLUTION:**\n\nMy real problem was the def/async def behavior (which I find very confusing). I was trying to solve the problem with a blocked thread using multiple workers which worked wired for my case as well (only 1 actually worked) and that's probably because I used a single browser with many tabs. Once I tested the service using JMeter it showed me that all workers were used. But the solution with multiple processes was not the right one for me. The better one was to try to unblock the single thread in a single process. At first, I used the following approach because I used an external library with SYNC IO function. However I have found an ASYNC variant of that function. So the problem was solved by using the correct library.\nThank you all for your help.\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nimport time\nimport logging\nimport asyncio\nimport random\n\napp = FastAPI()\nr = random.randint(1, 100)\nlogging.basicConfig(level=\"INFO\", format='%(levelname)s | %(asctime)s | %(name)s | %(message)s')\nlogging.info(f\"Starting app {r}\")\n\n@app.get(\"/\")\nasync def long_operation():\n logging.info(f\"Starting long operation {r}\")\n await asyncio.sleep(1)\n time.sleep(4) # I know this is blocking and the endpoint marked as async, but I actually do have some blocking requests in my code.\n return r\n```\n\n```text\nuvicorn \"main:app\" --workers 4\n```\n\n```text\nINFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\nINFO: Started parent process [22112]\nINFO | 2023-05-11 12:32:43,544 | root | Starting app 17\nINFO: Started server process [10180] \nINFO: Waiting for application startup.\nINFO: Application startup complete. \nINFO | 2023-05-11 12:32:43,579 | root | Starting app 58\nINFO: Started server process [29592]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\nINFO | 2023-05-11 12:32:43,587 | root | Starting app 12\nINFO: Started server process [7296]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\nINFO | 2023-05-11 12:32:43,605 | root | Starting app 29\nINFO: Started server process [15208]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\n```\n\n```text\nINFO | 2023-05-11 12:32:50,770 | root | Starting long operation 29\nINFO: 127.0.0.1:55031 - \"GET / HTTP/1.1\" 200 OK\nINFO | 2023-05-11 12:32:55,774 | root | Starting long operation 29\nINFO: 127.0.0.1:55031 - \"GET / HTTP/1.1\" 200 OK\nINFO | 2023-05-11 12:33:00,772 | root | Starting long operation 29\nINFO: 127.0.0.1:55031 - \"GET / HTTP/1.1\" 200 OK\nINFO | 2023-05-11 12:33:05,770 | root | Starting long operation 29\nINFO: 127.0.0.1:55031 - \"GET / HTTP/1.1\" 200 OK\nINFO | 2023-05-11 12:33:10,790 | root | Starting long operation 29\nINFO: 127.0.0.1:55031 - \"GET / HTTP/1.1\" 200 OK\nINFO | 2023-05-11 12:33:15,779 | root | Starting long operation 29\nINFO: 127.0.0.1:55031 - \"GET / HTTP/1.1\" 200 OK\nINFO | 2023-05-11 12:33:20,799 | root | Starting long operation 29\nINFO: 127.0.0.1:55031 - \"GET / HTTP/1.1\" 200 OK\nINFO | 2023-05-11 12:33:25,814 | root | Starting long operation 29\nINFO: 127.0.0.1:55031 - \"GET / HTTP/1.1\" 200 OK\nINFO | 2023-05-11 12:33:30,856 | root | Starting long operation 29\nINFO: 127.0.0.1:55031 - \"GET / HTTP/1.1\" 200 OK\n```\n\n```py\nlogging.basicConfig(level=\"INFO\", format='%(process)d | %(levelname)s | %(asctime)s | %(name)s | %(message)s')\n```\n\n```text\n19968 | INFO | 2023-05-11 12:45:53,297 | root | Starting long operation 35\n21368 | INFO | 2023-05-11 12:45:56,112 | root | Starting long operation 90\n5268 | INFO | 2023-05-11 12:45:56,626 | root | Starting long operation 3\n22024 | INFO | 2023-05-11 12:45:57,032 | root | Starting long operation 19\n5268 | INFO | 2023-05-11 12:45:57,416 | root | Starting long operation 3\n22024 | INFO | 2023-05-11 12:45:57,992 | root | Starting long operation 19\n```\n\n```text\n%(process)d\n```\n\n```text\n--workers 1\n```\n\n```text\ntime.sleep\n```\n\n```text\nasyncio.sleep\n```\n\n========================================\n\nComments:\n- \"This question already has answers here\" — that question is completely unrelated. Who added this?","metadata":{"transformedAt":"2026-08-18T18:32:29.133Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":10,"totalLines":203,"estimatedTokens":1879}}434{"id":"stack-65933711","source":"stackoverflow","questionId":65933711,"title":"FastAPI masking field","tags":["python-3.x","openapi","fastapi"],"text":"Title: FastAPI masking field\nTags: python-3.x, openapi, fastapi\nSource: Stack Overflow\n\nQuestion:\nI the tutorial about Security on FastAPI web site\n\nEnding by having the following endpoint:\n\n```\n@app.post(\"/token\", response_model= Token)\nasync def login(form_data: OAuth2PasswordRequestForm = Depends()):\n user = authenticate_user(fake_users_db, form_data.username, form_data.password)\n if not user:\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Incorrect username or password\",\n headers={\"WWW-Authenticate\": \"Bearer\"},\n )\n access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)\n access_token = create_access_token(\n data={\"sub\": user.username}, expires_delta=access_token_expires\n )\n return {\"access_token\": access_token, \"token_type\": \"bearer\"}\n```\n\nResulting in the following swagger:\n\nhttps://i.sstatic.net/QolIj.png\n\n**My question:**\nIs there a simple way to mask the password field? So I do not see it in plain text?\nLike we can do with authorize button.\n\n========================================\n\nTop Answer:\nAccording to @Yagiz answer, this works:\n\n```\nclass CustomOAuth2PasswordRequestForm(OAuth2PasswordRequestForm):\n def __init__(\n self,\n grant_type: str = Form(..., regex=\"password\"),\n username: str = Form(...),\n password: SecretStr = Form(...),\n scope: str = Form(\"\"),\n client_id: Optional[str] = Form(None),\n client_secret: Optional[str] = Form(None),\n ):\n super().__init__(\n grant_type=grant_type,\n username=username,\n password=password,\n scope=scope,\n client_id=client_id,\n client_secret=client_secret,\n )\n```\n\n========================================\n\nCode:\n```py\n@app.post(\"/token\", response_model= Token)\nasync def login(form_data: OAuth2PasswordRequestForm = Depends()):\n user = authenticate_user(fake_users_db, form_data.username, form_data.password)\n if not user:\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Incorrect username or password\",\n headers={\"WWW-Authenticate\": \"Bearer\"},\n )\n access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)\n access_token = create_access_token(\n data={\"sub\": user.username}, expires_delta=access_token_expires\n )\n return {\"access_token\": access_token, \"token_type\": \"bearer\"}\n```\n\n```py\nfrom fastapi import FastAPI, Depends\nfrom pydantic import BaseModel, SecretStr\n\n\nclass User(BaseModel):\n username: str\n password: SecretStr \n\napp = FastAPI()\n\n\n@app.post(\"/user\")\nasync def create_user(user: User = Depends()):\n print(user.password.get_secret_value())\n```\n\n```text\nSecretStr\n```\n\n```text\n{\"format\": \"password\"}\n```\n\n```py\nclass CustomOAuth2PasswordRequestForm(OAuth2PasswordRequestForm):\n def __init__(\n self,\n grant_type: str = Form(..., regex=\"password\"),\n username: str = Form(...),\n password: SecretStr = Form(...),\n scope: str = Form(\"\"),\n client_id: Optional[str] = Form(None),\n client_secret: Optional[str] = Form(None),\n ):\n super().__init__(\n grant_type=grant_type,\n username=username,\n password=password,\n scope=scope,\n client_id=client_id,\n client_secret=client_secret,\n )\n```\n\n========================================\n\nComments:\n- Also, you can click the \"Authorize\" button in the top right corner, instead of using the /login route directly which will mask the password form input.\n- Thank you for your answer, but the endpoint depends on OAuth2PasswordRequestForm, so do I need to superseed the class? and super **init** method with password: SecretStr = Form(...)?\n- Thanx for this post. However you could experience validation errors with `mypy` since password is expected to be a string, not a SecretStr","metadata":{"transformedAt":"2026-08-18T18:32:29.133Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":5,"totalLines":132,"estimatedTokens":953}}435{"id":"stack-68935072","source":"stackoverflow","questionId":68935072,"title":"How to RAM efficiently load spacy models into fastapi with gunicorn?","tags":["gunicorn","spacy","fastapi"],"text":"Title: How to RAM efficiently load spacy models into fastapi with gunicorn?\nTags: gunicorn, spacy, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am having challenges with my fastapi server running out of RAM after updating to use the `spacy_en_core_web_lg` from the small model.\n\nWhen running fastapi 4 gunicorn workers are spawned and based on the memory usage I think each worker is loading in the model. Is there a way I can the model across workers so I don't need to load it in each?\n\n========================================\n\nCode:\n```text\nspacy_en_core_web_lg\n```\n\n```text\npreload_app = True\n```\n\n```text\nfork()\n```\n\n```text\nmodel.eval()\n```\n\n```text\nmodel.share_memory()\n```\n\n```text\nmax_requests\n```\n\n========================================\n\nComments:\n- Make a separate thread or whatever with the model and have everyone talk to it. If that's complicated, set up a separate server with the model and one worker and have everyone talk to that.\n- Yeah I was thinking about having a dedicated server for the model -- definitely complicates things\n- Great idea to limit the worker lifetime with `max_requests` long running spacy models used to leak memory! Looking at the gunicorn docs, I have set preload to true and it has already helped!\n- That's awesome! Glad I could be of help @swartchris8","metadata":{"transformedAt":"2026-08-18T18:32:29.133Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":6,"totalLines":43,"estimatedTokens":325}}436{"id":"stack-67029960","source":"stackoverflow","questionId":67029960,"title":"HTTPS with nginx, fastAPI, docker","tags":["reactjs","docker","nginx","fastapi"],"text":"Title: HTTPS with nginx, fastAPI, docker\nTags: reactjs, docker, nginx, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm using nginx for my FARM stack app. I'm running into an issue with my APIs not going through HTTPS it works on HTTP. I've tried removing the server 80 block still getting the same issue.\n\nHere's the error\n\n```\ndocker-fastapi | [2021-04-10 01:02:36 +0000] [9] [WARNING] Invalid HTTP request received. proxy-app | 2021/04/10 01:02:36 [error] 22#22: *15 peer closed connection in SSL handshake while SSL handshaking to upstream, client: 192.168.249.11, server: xxxx, request: \"GET /api/ HTTP/1.1\", upstream: \"https://192.168.160.2:8080/api/\", host: \"xxx\"\n```\n\nHeres the nginx conf file\n\n```\nupstream docker_fastapi {\n server docker-fastapi:8080;\n}\n\nserver {\n listen 80;\n\n location ~ /api/ {\n proxy_pass http://docker_fastapi;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header X-Forwarded-Host $server_name;\n }\n\n location / {\n root /usr//nginx/html;\n index index.html index.htm;\n try_files $uri $uri/ /index.html;\n }\n\n error_page 500 502 503 504 /50x.html;\n\n location = /50x.html {\n root /usr//nginx/html;\n }\n}\n\nserver {\n listen 443 ssl default_server;\n server_name xxxx;\n client_max_body_size 12m;\n listen [::]:443 ssl http2;\n ssl_certificate /etc/ssl/nginx.crt;\n ssl_certificate_key /etc/ssl/nginx.key;\n server_tokens off;\n add_header X-Frame-Options sameorigin always;\n add_header X-Content-Type-Options nosniff;\n add_header Cache-Control \"no-cache\";\n add_header X-XSS-Protection \"1; mode=block\";\n add_header Set-Cookie \"lcid=1043; Max-Age=60\";\n\n ssl_protocols TLSv1.2;\n ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;\n ssl_prefer_server_ciphers off;\n\n location / {\n root /usr//nginx/html;\n index index.html index.htm;\n try_files $uri $uri/ /index.html;\n }\n\n location ~ /api/ {\n proxy_pass https://docker_fastapi;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header X-Forwarded-Host $server_name;\n proxy_ssl_server_name on;\n }\n\n error_page 500 502 503 504 /50x.html;\n\n location = /50x.html {\n root /usr//nginx/html;\n }\n}\n```\n\nI pretty much copied this repo to try to get HTTPS to work\nhttps://github.com/geekyjaat/fastapi-react\n\n========================================\n\nCode:\n```text\ndocker-fastapi | [2021-04-10 01:02:36 +0000] [9] [WARNING] Invalid HTTP request received. proxy-app | 2021/04/10 01:02:36 [error] 22#22: *15 peer closed connection in SSL handshake while SSL handshaking to upstream, client: 192.168.249.11, server: xxxx, request: \"GET /api/ HTTP/1.1\", upstream: \"https://192.168.160.2:8080/api/\", host: \"xxx\"\n```\n\n```text\nupstream docker_fastapi {\n server docker-fastapi:8080;\n}\n\nserver {\n listen 80;\n\n location ~ /api/ {\n proxy_pass http://docker_fastapi;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header X-Forwarded-Host $server_name;\n }\n\n location / {\n root /usr/share/nginx/html;\n index index.html index.htm;\n try_files $uri $uri/ /index.html;\n }\n\n error_page 500 502 503 504 /50x.html;\n\n location = /50x.html {\n root /usr/share/nginx/html;\n }\n}\n\nserver {\n listen 443 ssl default_server;\n server_name xxxx;\n client_max_body_size 12m;\n listen [::]:443 ssl http2;\n ssl_certificate /etc/ssl/nginx.crt;\n ssl_certificate_key /etc/ssl/nginx.key;\n server_tokens off;\n add_header X-Frame-Options sameorigin always;\n add_header X-Content-Type-Options nosniff;\n add_header Cache-Control \"no-cache\";\n add_header X-XSS-Protection \"1; mode=block\";\n add_header Set-Cookie \"lcid=1043; Max-Age=60\";\n\n ssl_protocols TLSv1.2;\n ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;\n ssl_prefer_server_ciphers off;\n\n location / {\n root /usr/share/nginx/html;\n index index.html index.htm;\n try_files $uri $uri/ /index.html;\n }\n\n location ~ /api/ {\n proxy_pass https://docker_fastapi;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header X-Forwarded-Host $server_name;\n proxy_ssl_server_name on;\n }\n\n error_page 500 502 503 504 /50x.html;\n\n location = /50x.html {\n root /usr/share/nginx/html;\n }\n}\n```\n\n```text\nclosed connection in SSL handshake while SSL handshaking to upstream\n```\n\n```text\nproxy_pass https://docker_fastapi;\n```\n\n```text\nproxy_pass http://docker_fastapi;\n```\n\n========================================\n\nComments:\n- I've tried that but then I get an error from the browser about mixed content since the API call is through HTTP Mixed Content: The page at 'xxxx' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'xxx/api/reports/xxx'. This request has been blocked; the content must be served over HTTPS. Edit: One more thing. The site is an internal site with a self signed cert. Would that be the issue there?\n- You can call API using HTTPS. I mean, you send the request to the address of NGINX server 443 block, then the request will be pass to your API. It is how a reverse proxy works\n- I figured it out after all wasn't nginx issue. Was my API calls had a trailing slash and it was rerouting to HTTPS. Without the trailing forward slash it called correctly. Thanks!","metadata":{"transformedAt":"2026-08-18T18:32:29.133Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":183,"estimatedTokens":1494}}437{"id":"stack-71528875","source":"stackoverflow","questionId":71528875,"title":"Signal handling in Uvicorn with FastAPI","tags":["python","signals","fastapi","uvicorn","starlette"],"text":"Title: Signal handling in Uvicorn with FastAPI\nTags: python, signals, fastapi, uvicorn, starlette\nSource: Stack Overflow\n\nQuestion:\nI have an app using `Uvicorn` with `FastAPI`. I have also some connections open (e.g. to `MongoDB`). I want to gracefully close these connections once some signal occurs (`SIGINT`, `SIGTERM` and `SIGKILL`).\n\nMy `server.py` file:\n\n```\nimport uvicorn\nimport fastapi\nimport signal\nimport asyncio\n\nfrom source.gql import gql\n\napp = fastapi.FastAPI()\n\napp.add_middleware(CORSMiddleware, allow_origins=[\"*\"], allow_methods=[\"*\"], allow_headers=[\"*\"])\napp.mount(\"/graphql\", gql)\n\n# handle signals\nHANDLED_SIGNALS = (\n signal.SIGINT,\n signal.SIGTERM\n)\n\nloop = asyncio.get_event_loop()\nfor sig in HANDLED_SIGNALS:\n loop.add_signal_handler(sig, _some_callback_func)\n\nif __name__ == \"__main__\":\n uvicorn.run(app, port=6900)\n```\n\nUnfortunately, the way I try to achieve this is not working. When I try to `Ctrl+C` in terminal, nothing happens. I believe it is caused because `Uvicorn` is started in different thread...\n\nWhat is the correct way of doing this? I have noticed `uvicorn.Server.install_signal_handlers()` function, but wasn't lucky in using it...\n\n========================================\n\nTop Answer:\n```\nimport signal\nimport sys\n\ndef handle_sigterm(signum, frame):\n \"\"\"\n Signal handler for graceful shutdown.\n Triggered when the process receives SIGTERM or SIGINT.\n \"\"\"\n print(\"Received shutdown signal, cleaning up...\")\n\n # Attempt to stop running browser processes gracefully.\n # You can extend this list with any other browser names you use.\n for b in (\"firefox\",\"edge\"):\n try:\n stop_function(b) # user-defined cleanup function\n except Exception:\n # Ignore any errors during cleanup to ensure shutdown continues\n pass\n\n # Exit the process cleanly\n sys.exit(0)\n\n# Register the handler for termination (SIGTERM) and interrupt (SIGINT / Ctrl+C)\nsignal.signal(signal.SIGTERM, handle_sigterm)\nsignal.signal(signal.SIGINT, handle_sigterm)\n```\n\n========================================\n\nCode:\n```py\nimport uvicorn\nimport fastapi\nimport signal\nimport asyncio\n\nfrom source.gql import gql\n\n\napp = fastapi.FastAPI()\n\napp.add_middleware(CORSMiddleware, allow_origins=[\"*\"], allow_methods=[\"*\"], allow_headers=[\"*\"])\napp.mount(\"/graphql\", gql)\n\n# handle signals\nHANDLED_SIGNALS = (\n signal.SIGINT,\n signal.SIGTERM\n)\n\nloop = asyncio.get_event_loop()\nfor sig in HANDLED_SIGNALS:\n loop.add_signal_handler(sig, _some_callback_func)\n\nif __name__ == \"__main__\":\n uvicorn.run(app, port=6900)\n```\n\n```text\nUvicorn\n```\n\n```text\nFastAPI\n```\n\n```text\nMongoDB\n```\n\n```text\nSIGINT\n```\n\n```text\nSIGTERM\n```\n\n```text\nSIGKILL\n```\n\n```text\nserver.py\n```\n\n```text\nCtrl+C\n```\n\n```text\nUvicorn\n```\n\n```text\nuvicorn.Server.install_signal_handlers()\n```\n\n```text\n@app.on_event(\"shutdown\")\ndef shutdown_event():\n # close connections here\n```\n\n```text\nshutdown\n```\n\n```text\nstartup\n```\n\n```text\nshutdown\n```\n\n```text\nlifespan\n```\n\n```text\nimport signal\nimport sys\n\ndef handle_sigterm(signum, frame):\n \"\"\"\n Signal handler for graceful shutdown.\n Triggered when the process receives SIGTERM or SIGINT.\n \"\"\"\n print(\"Received shutdown signal, cleaning up...\")\n\n # Attempt to stop running browser processes gracefully.\n # You can extend this list with any other browser names you use.\n for b in (\"firefox\",\"edge\"):\n try:\n stop_function(b) # user-defined cleanup function\n except Exception:\n # Ignore any errors during cleanup to ensure shutdown continues\n pass\n\n # Exit the process cleanly\n sys.exit(0)\n\n# Register the handler for termination (SIGTERM) and interrupt (SIGINT / Ctrl+C)\nsignal.signal(signal.SIGTERM, handle_sigterm)\nsignal.signal(signal.SIGINT, handle_sigterm)\n```\n\n========================================\n\nComments:\n- More about how those events work here: asgi.readthedocs.io/en/latest/specs/lifespan.html\n- Keep in mind that a `shutdown` event is only called after all active connections are closed. From the ASGI Shutdown documentation: *\"Sent to the application when the server has stopped accepting connections and closed all active connections.\"*\n- As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.","metadata":{"transformedAt":"2026-08-18T18:32:29.133Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":17,"totalLines":198,"estimatedTokens":1100}}438{"id":"stack-65594905","source":"stackoverflow","questionId":65594905,"title":"How can I deploy FastAPI manually on a Ubuntu Server?","tags":["python","fastapi"],"text":"Title: How can I deploy FastAPI manually on a Ubuntu Server?\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have a very simple API (2 routes) which just has GET requests, and doesnt need any authentication or anything for now.\n\nI want to know what is the best and appropariate way to deploy my API for production. I am unable to use docker, and would like to do it the server way.\n\nSo i have a few questions:\n\n- On the fastapi documentation it says you can do `uvicorn main:app --host 0.0.0.0 --port 80` but i was thinking if that is the correct way for production? Do i just enter that command, and will the API automatically start listening on the servers IP address? Also is this method efficient and will it be able to handle all the requests? Or what would i change for it to be faster?\n\n- When should i use a process manager?\n\n- When should i use multiple workers? And what benefits do they provide?\n\n- When should i use Gunicorn as mentioned here? https://www.uvicorn.org/deployment/#gunicorn\n\nI am just a little confused on how to deploy this because one article says do this, another says do this.\n\n========================================\n\nTop Answer:\nTo answer your Question:\n\nHow can I deploy FastAPI manually on a Ubuntu Server?\n\nYou can check out this video tutorial on how to\nDeploy FastAPI on Ubuntu\n\nThe deployment has the following architecture within a single Ubuntu VM.\n\nhttps://i.sstatic.net/n2MI6.png\n\nAs you take a look at the Architectural diagram above for FastAPI Deployment, it shows a single VM deployment.\n\nWithin the Ubuntu VM, there are two systemd services namely `caddy.service` and `gunicorn.service` up and running. The `gunicorn.service` runs the FastAPI application and the `caddy.service` exposes the FastAPI application running on Gunicorn as a reverse proxy with the help of `uvicorn.workers.UvicornWorker` worker class. In addition to this, our FastAPI communicates to PostgreSQL database server in an asynchronous fashion with the help of databases package that provides simple `asyncio` support for PostgreSQL database.\n\n========================================\n\nCode:\n```text\nuvicorn main:app --host 0.0.0.0 --port 80\n```\n\n```text\nsystemd-service\n```\n\n```text\nwgsi\n```\n\n```text\ngunicorn\n```\n\n```text\ncaddy.service\n```\n\n```text\ngunicorn.service\n```\n\n```text\ngunicorn.service\n```\n\n```text\ncaddy.service\n```\n\n```text\nuvicorn.workers.UvicornWorker\n```\n\n```text\nasyncio\n```\n\n========================================\n\nComments:\n- Please ask one question per question only and make sure it is related to programming (writing code)!\n- Thanks for the response. What do you mean by i need to config unicorn? What benefit does configuring it provide? Or what happens if i dont?\n- By configuration I mean whether you use docker or systemd-service, you need to pass on options like amount of workers and so on, probably nginx + systemd-service + gunicron will help ya serve your app the best way possible by the assumption that you don't want to use docker. check this: docs.gunicorn.org/en/stable/deploy.html\n- Thanks a lot, for this info. You helped me find my answer. Also if i use nginx i probably dont need a systemd service because nginx would be it.\n- You welcome, just remember that nginx will be your web server, you will need to keep your web application alive, sometimes the web application goes down for many reasons, note that you need docker compose or a systemd-unit with `restart on failure` option.","metadata":{"transformedAt":"2026-08-18T18:32:29.133Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":10,"totalLines":90,"estimatedTokens":865}}439{"id":"stack-68903084","source":"stackoverflow","questionId":68903084,"title":"Pydantic - Validation Does not Happen","tags":["python","python-3.x","fastapi","pydantic"],"text":"Title: Pydantic - Validation Does not Happen\nTags: python, python-3.x, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI am quite new to using Pydantic.\n\nThe Issue I am facing right now is that the Model Below is not raising the Expected Exception when the value is out of range.\n\nFor example, if you pass -1 into this model it should ideally raise an HTTPException. but nothing happens\n\nI am not sure where I might be going wrong.\n\nAny Advice would be great.\n\n```\nclass GetInput:\n \"\"\"\n for the fields endpoint\n \"\"\"\n\n def __init__(self,\n rank: Optional[int] = None,\n interval: Optional[int] = None):\n\n self.rank = rank\n self.interval = interval\n\n @validator('rank')\n def check_if_rank_in_range(cls, v):\n \"\"\"\n check if input rank is within range\n \"\"\"\n if not 0 The FastAPI Endpoint\n\n```\n@router.get('fields/',status_code=200)\ndef get_data(params: GetInput = Depends()):\n \n if params.rank:\n result = get_info_by_rank(params.rank)\n\n elif params.interval:\n\n result = get_info_by_interval(params.interval)\n \n return result\n```\n\n========================================\n\nTop Answer:\nFor pydantic 2.7.1, validator has been deprecated for field_validator\n\nHeres an example :\n\n```\n#!/usr/bin/env python3\n# Python imports\nfrom typing import Optional\n# Packages imports\nfrom pydantic import BaseModel, field_validator\n\nclass B(BaseModel):\n var3: str\n var4: str\n\nclass A(BaseModel):\n var1: int\n var2: Optional[B] = None\n\n @field_validator('var2', mode='before')\n def check_empty(cls, value):\n print(\"check_empty\", cls, value)\n return value or None\n\nif __name__ == \"__main__\":\n data = {\n \"var1\": 1,\n \"var2\": {}\n }\n result = A.model_validate(data)\n print(result)\n```\n\n========================================\n\nCode:\n```text\nclass GetInput:\n \"\"\"\n for the fields endpoint\n \"\"\"\n\n def __init__(self,\n rank: Optional[int] = None,\n interval: Optional[int] = None):\n\n self.rank = rank\n self.interval = interval\n\n @validator('rank')\n def check_if_rank_in_range(cls, v):\n \"\"\"\n check if input rank is within range\n \"\"\"\n if not 0 < v < 1000001:\n\n raise HTTPException(\n status_code=400, detail=\"Rank Value Must be within range (0,1000000)\")\n return v\n\n @validator('interval')\n def check_if_interval_in_range(cls, v):\n \"\"\"\n check if input rank is within range\n \"\"\"\n if not 0 < v < 1000001:\n\n raise HTTPException(\n status_code=400, detail=\"Interval Value Must be within range (0,1000000)\")\n return v\n```\n\n```text\n@router.get('fields/',status_code=200)\ndef get_data(params: GetInput = Depends()):\n \n if params.rank:\n result = get_info_by_rank(params.rank)\n\n elif params.interval:\n\n result = get_info_by_interval(params.interval)\n \n return result\n```\n\n```text\nclass GetInput(BaseModel):\n\n rank: Optional[int]=None\n interval: Optional[int]=None\n \n @validator(\"*\")\n def check_range(cls, v):\n if v: \n if not 0 < v < 1000001:\n raise HTTPException(status_code=400, detail=\"Value Must be within range (0,1000000)\")\n return v\n```\n\n```text\n#!/usr/bin/env python3\n# Python imports\nfrom typing import Optional\n# Packages imports\nfrom pydantic import BaseModel, field_validator\n\nclass B(BaseModel):\n var3: str\n var4: str\n\nclass A(BaseModel):\n var1: int\n var2: Optional[B] = None\n\n @field_validator('var2', mode='before')\n def check_empty(cls, value):\n print(\"check_empty\", cls, value)\n return value or None\n\nif __name__ == \"__main__\":\n data = {\n \"var1\": 1,\n \"var2\": {}\n }\n result = A.model_validate(data)\n print(result)\n```\n\n========================================\n\nComments:\n- you aren't inheriting from `BaseModel`...\n- When I inherit the BaseModel This is the Error I run into `pydantic.errors.ConfigError: Validators defined with incorrect fields: check_if_interval_in_range, check_if_rank_in_range (use check_fields=False if you're inheriting from the model and intended this)`\n- Because you didn't annotate your fields.\n- The Validations did not happen even after I annotated the fields","metadata":{"transformedAt":"2026-08-18T18:32:29.133Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":4,"totalLines":188,"estimatedTokens":1049}}440{"id":"stack-62833004","source":"stackoverflow","questionId":62833004,"title":"How to make POST/GET curl request with token authentication?","tags":["curl","fastapi"],"text":"Title: How to make POST/GET curl request with token authentication?\nTags: curl, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have APIKeyHeader description\n\nApi is made with FastApi.\n\nI've tried different ways like\n\n```\ncurl -X GET -H \"X-Access-Token: \" \"https://example/v1/method/\"\n\ncurl -X GET \"https://example/v1/method/\" --header '{\"X-Access-Token\": \"token\"}'\n```\n\nAnd the answer is the same: {\"detail\": \"Could not validate credentials\"} but I know that token is correct.\n\nP.S. new to curl, please could you describe my mistake in detail\n\n========================================\n\nCode:\n```text\ncurl -X GET -H \"X-Access-Token: <token>\" \"https://example/v1/method/\"\n\ncurl -X GET \"https://example/v1/method/\" --header '{\"X-Access-Token\": \"token\"}'\n```\n\n```text\ncurl -X GET \"http://127.0.0.1:8000/users/me\" -H \"Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiMDY1ODQwNDEtYzYwYi00NDg4LWEyYzctZmRkZmQxNWI0NDNkIiwiYXVkIjoiZmFzdGFwaS11c2VyczphdXRoIiwiZXhwIjoxNTk1NzA3ODYyfQ.yutytBX0hmv0MJy5BMSfGSBqrPvFzKqLq_-quEgNyF4\"\n```\n\n```text\nOut: {\"id\":\"06584041-c60b-4488-a2c7-fddfd15b443d\",\"email\":\"user@gmail.com\",\"is_active\":true,\"is_superuser\":false}\n```\n\n```text\ncurl -X GET \"https://example/v1/method/\" -H \"Authorization: Bearer TOKEN_HERE\"\n```\n\n```text\n/users/me\n```\n\n========================================\n\nComments:\n- Can you add your code samples?\n- Apart from, try this curl request, `curl -X GET -H \"Authorization: Bearer \" \"https://example/v1/method/\"`","metadata":{"transformedAt":"2026-08-18T18:32:29.133Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":51,"estimatedTokens":376}}441{"id":"stack-76097512","source":"stackoverflow","questionId":76097512,"title":"Detail not found error using FastAPI's APIRouter","tags":["python","fastapi"],"text":"Title: Detail not found error using FastAPI's APIRouter\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have a directory structure as follows:\n\n```\napp\n >routers\n >items.py\n __init__.py\n main.py\n```\n\nInside main I have the following code:\n\n```\nfrom typing import Union\nimport uvicorn\nfrom fastapi import FastAPI, APIRouter\nfrom routers import items\n\napp = FastAPI()\napp.include_router(items.router, prefix='/items', tags=['items'])\n\n@app.get(\"/\")\nasync def root():\n return {\"message\": \"World World\"}\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n```\n\nWithin `items.py` I have the following:\n\n```\nfrom fastapi import APIRouter\n\nrouter = APIRouter(\n prefix=\"/items\",\n tags=[\"items\"]\n)\n\n@router.api_route(\"/items\")\nasync def items():\n return {\"test\": \"items\"}\n```\n\nWhen I run the code, I can go to my url http:127.0.0.0:8000/ and I get the Hello world message. But when i go to http:127.0.0.0:8000/items I'm seeing an error:\n\n```\n{\"detail\": \"not found\"}\n```\n\nHow do I fix this? I tried debugging this but when I hit my debugger, and type items.router it tells me that I'm correctly importing from the right path.\n\n========================================\n\nCode:\n```text\napp\n >routers\n >items.py\n __init__.py\n main.py\n```\n\n```text\nfrom typing import Union\nimport uvicorn\nfrom fastapi import FastAPI, APIRouter\nfrom routers import items\n\n\n\napp = FastAPI()\napp.include_router(items.router, prefix='/items', tags=['items'])\n\n@app.get(\"/\")\nasync def root():\n return {\"message\": \"World World\"}\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n```\n\n```text\nfrom fastapi import APIRouter\n\nrouter = APIRouter(\n prefix=\"/items\",\n tags=[\"items\"]\n)\n\n@router.api_route(\"/items\")\nasync def items():\n return {\"test\": \"items\"}\n```\n\n```text\n{\"detail\": \"not found\"}\n```\n\n```text\nitems.py\n```\n\n```text\nrouter = APIRouter(prefix=\"/items\", tags=[\"items\"])\n# ^^^^^^^^\n...\n@router.api_route(\"/items\")\n# ^^^^^^^^\n...\napp.include_router(items.router, prefix='/items', tags=['items'])\n# ^^^^^^^^\n```\n\n```text\nrouter = APIRouter(prefix=\"/items\", tags=[\"items\"])\n...\n@router.api_route(\"/\")\n...\napp.include_router(items.router)\n```\n\n```text\nimport uvicorn\nfrom fastapi import FastAPI, APIRouter\n\nrouter = APIRouter(prefix=\"/items\", tags=[\"items\"])\n\n\n@router.api_route(\"/\")\nasync def items():\n return {\"test\": \"items\"}\n\n\napp = FastAPI()\napp.include_router(router)\n\n\n@app.get(\"/\")\nasync def root():\n return {\"message\": \"World World\"}\n\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n```\n\n```text\n/items\n```\n\n```text\nhttp://127.0.0.1:8000/items/items/items\n```\n\n========================================\n\nComments:\n- im dont quite understand the `@router.api_route(\"/\")`. how do you then declare a method as get or post? also reading the first part of the documentation here: fastapi.tiangolo.com/tutorial/bigger-applications, leaves the impression that we dont need to the `include_router` line in the main if we have the Router definition in the submodules. Am i missing something? i think i need to continue reading...\n- @mike01010 `api_route` method is the generic version of the `get`, `post`, etc, helper methods. By default it acts as a GET route, but you can use the `methods` kwarg to specify the verb (or verbs) you want to support. I'm not aware of anything with `include_router` being dynamic on package paths. The examples also show usage of this fastapi.tiangolo.com/tutorial/bigger-applications/…","metadata":{"transformedAt":"2026-08-18T18:32:29.133Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":10,"totalLines":165,"estimatedTokens":895}}442{"id":"stack-65796467","source":"stackoverflow","questionId":65796467,"title":"FastAPI: datetime with timezone in request doesn't work","tags":["python","datetime","fastapi","pydantic"],"text":"Title: FastAPI: datetime with timezone in request doesn't work\nTags: python, datetime, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\n```\nfrom fastapi import FastAPI\nfrom datetime import datetime\nfrom ..models import Contact\nfrom ..database import Database\n\napp = FastAPI()\n\n# Dependency\ndef get_db():\n db = Database()\n try:\n yield db\n finally:\n db.disconnect()\n\n@app.get(\"/contacts/\", response_model=List[Contact])\nasync def get_contacts(address: int, start_time: datetime, end_time: datetime, duration: int, distance: int, db: Database = Depends(get_db)):\n contacts = detect_contacts(db, address, start_time, end_time, duration, distance)\n return contacts\n```\n\nI'm trying to get query parameters start_time and end_time as datetime values with timezone, based on ISO 8601 or RFC 3339.\nIt works fine without timezone, for example, \"2021-01-19 16:00:00\" or \"2021-01-19T16:00:00\", but not with timezone, for example, \"2021-01-19 16:00:00+05:00\" or \"2021-01-19T16:00:00+05:00\", returning such error:\n\n```\n{\n \"detail\": [\n {\n \"loc\": [\n \"query\",\n \"start_time\"\n ],\n \"msg\": \"invalid datetime format\",\n \"type\": \"value_error.datetime\"\n }\n ]\n}\n```\n\nFYI, it's explicitly mentioned in the documentation that it supports ISO 8601 format for datetime.datetime type:\n\nExtra Data Type - FastAPI\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nfrom datetime import datetime\nfrom ..models import Contact\nfrom ..database import Database\n\n\napp = FastAPI()\n\n# Dependency\ndef get_db():\n db = Database()\n try:\n yield db\n finally:\n db.disconnect()\n\n@app.get(\"/contacts/\", response_model=List[Contact])\nasync def get_contacts(address: int, start_time: datetime, end_time: datetime, duration: int, distance: int, db: Database = Depends(get_db)):\n contacts = detect_contacts(db, address, start_time, end_time, duration, distance)\n return contacts\n```\n\n```text\n{\n \"detail\": [\n {\n \"loc\": [\n \"query\",\n \"start_time\"\n ],\n \"msg\": \"invalid datetime format\",\n \"type\": \"value_error.datetime\"\n }\n ]\n}\n```\n\n```text\n+\n```\n\n```text\ngoogle.com/search?q=datetime+not+working\n```\n\n========================================\n\nComments:\n- @MrFuppes Yeah, I tried that too without a luck\n- You query parameter looks like this `?start_time=2021-01-19%2016%3A00%3A00%2B05%3A00` ?\n- @alex_noname No, what's that?\n- `start_time` is a query parameter in your case. How do you send it?\n- Could it be that you are forgetting the `T` of timezone in the `datetime`? Have you tried with `2021-01-19T16:00:00+05:00` ?\n- @alex_noname As I said another case without timezone specified is working fine so it's not something related to query parameter encoding/decoding\n- @lsabi Yeah I tried that too with no luck. I updated the question to include that info as well\n- My bad, I was thinking it's being url-encoded.","metadata":{"transformedAt":"2026-08-18T18:32:29.134Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":109,"estimatedTokens":730}}443{"id":"stack-67111921","source":"stackoverflow","questionId":67111921,"title":"FastAPI download a file to client with a POST request","tags":["python-3.x","fastapi"],"text":"Title: FastAPI download a file to client with a POST request\nTags: python-3.x, fastapi\nSource: Stack Overflow\n\nQuestion:\nCurrently I'm struggling a bit with FastAPI and file serving.\n\nIn my project I have the following workflow. Client sends a payload containing the necessary payload to download a file from a third party provider.\n\nI need to send a payload to the backend, it's necessary and since a resource is created (file downloaded), I assumed that POST would be the Method for this endpoint, but let me show you an example.\n\n```\nfrom fastapi import FastAPI, Form\nfrom fastapi.responses import FileResponse\n\nimport os\n\napp = FastAPI()\n\n@app.post(\"/download_file\")\nasync def download():\n \n url = 'https://file-examples-com.github.io/uploads/2017/10/file-sample_150kB.pdf'\n os.system('wget %s'%url)\n \n\n return FileResponse(\"file-sample_150kB.pdf\")\n\n@app.get(\"/get_file\")\nasync def get_file():\n return FileResponse(\"/home/josec/stackoverflow_q/file-sample_150kB.pdf\")\n```\n\nIf I go to http://localhost:8000/get_file, I get the file displayed on the web page!\nHowever that's not what I'm looking for! I want the file to be downloaded on the client side, either be via a browser or via cli!\n\nThe following script does not download any file, except when you paste it in the browser where you can look at it.\n\n```\nimport requests\n\nurl = \"http://localhost:8000/get_file\"\n\nresponse = requests.request(\"GET\", url)\n\nprint(response.json())\n```\n\nThis one is not working as well!\n\n```\nimport requests\n\nurl = \"http://localhost:8000/download_file\"\n\nresponse = requests.request(\"POST\", url)\n\nprint(response.json())\n```\n\nMy questions are:\n\nShould I just use GET? If yes how would I pass parameters, on the url? some strings that I'm sending with the post request can be very long, don't know if that could be an issue.\n\nHow can I return a file to the user? Download it immediatly to the user in a return statement of the function endpoint!\n\nCan I do it with POST?\n\nIf you guys need anything else from me please do tell :-)\n\nBest,\n\nJose\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI, Form\nfrom fastapi.responses import FileResponse\n\nimport os\n\napp = FastAPI()\n\n\n\n@app.post(\"/download_file\")\nasync def download():\n \n url = 'https://file-examples-com.github.io/uploads/2017/10/file-sample_150kB.pdf'\n os.system('wget %s'%url)\n \n\n return FileResponse(\"file-sample_150kB.pdf\")\n\n\n@app.get(\"/get_file\")\nasync def get_file():\n return FileResponse(\"/home/josec/stackoverflow_q/file-sample_150kB.pdf\")\n```\n\n```text\nimport requests\n\nurl = \"http://localhost:8000/get_file\"\n\n\nresponse = requests.request(\"GET\", url)\n\nprint(response.json())\n```\n\n```text\nimport requests\n\nurl = \"http://localhost:8000/download_file\"\n\n\nresponse = requests.request(\"POST\", url)\n\nprint(response.json())\n```\n\n```text\n@app.get(\n \"/items/{item_id}\",\n response_model=Item,\n responses={\n 200: {\n \"content\": {\"image/png\": {}},\n \"description\": \"Return the JSON item or an image.\",\n }\n },\n)\nasync def read_item(item_id: str, img: Optional[bool] = None):\n if img:\n return FileResponse(\"image.png\", media_type=\"image/png\")\n else:\n return {\"id\": \"foo\", \"value\": \"there goes my hero\"}\n```\n\n```text\nFileResponse\n```\n\n========================================\n\nComments:\n- I tried with an image this time, and the same thing is happening .... Just shows in browser\n- @JoséRodrigues try to specify the `filename` in the `FileResponse`, if you don't by default your browser will try to visualize the file if it is a supported file type.","metadata":{"transformedAt":"2026-08-18T18:32:29.134Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":151,"estimatedTokens":901}}444{"id":"stack-75539007","source":"stackoverflow","questionId":75539007,"title":"Custom validation for FastAPI's query parameter using pydatinc causes Internal Server Error","tags":["python","exception","fastapi","valueerror","pydantic"],"text":"Title: Custom validation for FastAPI's query parameter using pydatinc causes Internal Server Error\nTags: python, exception, fastapi, valueerror, pydantic\nSource: Stack Overflow\n\nQuestion:\nMy `GET` endpoint receives a query parameter that needs to meet the following criteria:\n\n- be an `int` between 0 and 10\n\n- be even number\n\n`1.` is straight forward using `Query(gt=0, lt=10)`. However, it is not quiet clear to me how to extend `Query` to do extra custom validation such as `2.`. The documentation ultimately leads to pydantic. But, my application runs into internal server error when the second validation `2.` fails.\n\nBelow is a minimal scoped example\n\n```\nfrom fastapi import FastAPI, Depends, Query\nfrom pydantic import BaseModel, ValidationError, validator\n\napp = FastAPI()\n\nclass CommonParams(BaseModel):\n n: int = Query(default=..., gt=0, lt=10)\n\n @validator('n')\n def validate(cls, v):\n if v%2 != 0:\n raise ValueError(\"Number is not even :( \")\n return v\n\n@app.get(\"/\")\nasync def root(common: CommonParams = Depends()):\n return {\"n\": common.n}\n```\n\nBelow are requests that work as expected and ones that break:\n\n```\n# requsts that work as expected\nlocalhost:8000?n=-4\nlocalhost:8000?n=-3\nlocalhost:8000?n=2\nlocalhost:8000?n=8\nlocalhost:8000?n=99\n\n# request that break server\nlocalhost:8000?n=1\nlocalhost:8000?n=3\nlocalhost:8000?n=5\n```\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI, Depends, Query\nfrom pydantic import BaseModel, ValidationError, validator\n\napp = FastAPI()\n\nclass CommonParams(BaseModel):\n n: int = Query(default=..., gt=0, lt=10)\n\n @validator('n')\n def validate(cls, v):\n if v%2 != 0:\n raise ValueError(\"Number is not even :( \")\n return v\n\n\n@app.get(\"/\")\nasync def root(common: CommonParams = Depends()):\n return {\"n\": common.n}\n```\n\n```text\n# requsts that work as expected\nlocalhost:8000?n=-4\nlocalhost:8000?n=-3\nlocalhost:8000?n=2\nlocalhost:8000?n=8\nlocalhost:8000?n=99\n\n# request that break server\nlocalhost:8000?n=1\nlocalhost:8000?n=3\nlocalhost:8000?n=5\n```\n\n```text\nGET\n```\n\n```text\nint\n```\n\n```text\n1.\n```\n\n```text\nQuery(gt=0, lt=10)\n```\n\n```text\nQuery\n```\n\n```text\n2.\n```\n\n```text\n2.\n```\n\n```py\nfrom fastapi import FastAPI, Depends, Query, HTTPException\nfrom pydantic import BaseModel, validator\n\napp = FastAPI()\n\nclass CommonParams(BaseModel):\n n: int = Query(default=..., gt=0, lt=10)\n\n @validator('n')\n def prevent_odd_numbers(cls, v):\n if v % 2 != 0:\n raise HTTPException(status_code=422, detail='Input number is not even')\n return v\n\n\n@app.get('/')\nasync def root(common: CommonParams = Depends()):\n return {'n': common.n}\n```\n\n```json\n# 422 Error: Unprocessable Entity\n\n{\n \"detail\": \"Input number is not even\"\n}\n```\n\n```py\nfrom fastapi import FastAPI, Request, Depends, Query, status\nfrom fastapi.responses import JSONResponse\nfrom fastapi.encoders import jsonable_encoder\nfrom pydantic import BaseModel, validator\n\napp = FastAPI()\n\n@app.exception_handler(ValueError)\nasync def validation_exception_handler(request: Request, exc: ValueError):\n return JSONResponse(\n status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,\n content=jsonable_encoder({\"detail\": exc.errors(), # optionally, include the pydantic errors\n \"custom msg\": {\"Your error message\"}}), # optionally, return a custom message\n )\n \nclass CommonParams(BaseModel):\n n: int = Query(default=..., gt=0, lt=10)\n\n @validator('n')\n def prevent_odd_numbers(cls, v):\n if v % 2 != 0:\n raise ValueError('Input number is not even')\n return v\n\n\n@app.get('/')\nasync def root(common: CommonParams = Depends()):\n return {'n': common.n}\n```\n\n```json\n# 422 Error: Unprocessable Entity\n\n{\n \"detail\": [\n {\n \"loc\": [\n \"n\"\n ],\n \"msg\": \"Input number is not even\",\n \"type\": \"value_error\"\n }\n ],\n \"custom msg\": [\n \"Your error message\"\n ]\n}\n```\n\n```text\nHTTPException\n```\n\n```text\nValueError\n```\n\n```text\nn = 1\n```\n\n```text\nValueError\n```\n\n```text\nn = 1\n```\n\n```text\n@validator\n```\n\n```text\n@field_validator\n```\n\n========================================\n\nComments:\n- Can you clarify \"break server\"? What error message do you get in the terminal?\n- You raise a ValueError, while fastapi raises a RequestValidationError when validation fails. Try raising a RequestValidationError instead and see if that is handled by the fastapi logic.\n- Does this answer your question? FastAPI - Pydantic - Value Error Raises Internal Server Error\n- Thank you for your input. This is not quiet what I am looking for. What I am looking for is behaviour that is similar to the `lt` and 'gt' validators but instead of checking if number is less than, it checks if number is even. For example, if input is 99 (which is not between 0 and 10) my endpoint response is `{\"detail\":[{\"loc\":[\"query\",\"n\"],\"msg\":\"ensure this value is greater than 0\",\"type\":\"value_error.number.not_gt\",\"ctx\":{\"limit_value\":0‌​}}]}` I would like to achieve similar behaviour for checking if input is even.","metadata":{"transformedAt":"2026-08-18T18:32:29.134Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":20,"totalLines":231,"estimatedTokens":1269}}445{"id":"stack-77390826","source":"stackoverflow","questionId":77390826,"title":"SQLAlchemy Error: InvalidRequestError - Can't operate on closed transaction inside context manager","tags":["python","sqlalchemy","orm","fastapi"],"text":"Title: SQLAlchemy Error: InvalidRequestError - Can't operate on closed transaction inside context manager\nTags: python, sqlalchemy, orm, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm encountering an issue while working with SQLAlchemy in a FastAPI project. I've set up a route that's supposed to add items to a database using a context manager and nested transactions. If a single item is failed to be added (due to constraints or any reason) it should not be included in the commit. However the remaining items, added both before or after, should be included.\n\nWhen using nested transactions, I would expect to be able to keep track of my failed and succesful additions. However, I keep running into the following error:\n\n`sqlalchemy.exc.InvalidRequestError: Can't operate on a closed transaction inside a context manager.`\n\nI've provided the relevant code below:\n\n```\nrouter = APIRouter()\n\n@lru_cache()\ndef get_session_maker() -> sessionmaker:\n # create a reusable factory for new AsyncSession instances\n engine = create_engine(SQLALCHEMY_DATABASE_URI, echo=True)\n return sessionmaker(engine)\n\ndef get_session() -> Generator[Session, None, None]:\n cached_sessionmaker = get_session_maker()\n with cached_sessionmaker.begin() as session:\n yield session\n\n@router.post(\"/items\")\ndef add_items(\n session: Session = Depends(get_database.get_session),\n) -> Dict[str, Any]:\n\n request_inputs = [\n RequestInput(name=\"chair\", used_for=\"sitting\"),\n RequestInput(name=\"table\", used_for=\"dining\"),\n RequestInput(name=\"tv\", used_for=\"watching\"),\n ]\n\n uploaded_items = []\n failed_items = []\n for request_input in request_inputs:\n try:\n with session.begin_nested():\n item= Item(\n **request_input.dict()\n )\n session.add(item)\n session.refresh(item)\n\n uploaded_items += 1\n\n except IntegrityError as e:\n # Handle any integrity constraint violations here\n session.rollback()\n failed_items += 1\n except Exception as e:\n # Handle other exceptions\n session.rollback()\n failed_items += 1\n\n session.commit()\n\n return {\n \"uploaded\": uploaded_items,\n \"failed\": failed_items,\n }\n```\n\nIt is obviously caused by my session to be closed prematurely, however I cannot figure out where I am closing the transaction to early, whilst trying to add all non failed items to my db. Can someone please help me understand why I'm encountering this error and how to fix it?\n\nThank you in advance for your assistance.\n\nI tried to use session.begin_nested() to keep track of the status of my transaction, however it seems to close somewhere. if not used the begin_nested(), I only commit the items before the failed instance. All items afterwards are excluded.\n\n========================================\n\nTop Answer:\nIn my case i ran into this when trying to access an attribute of a managed entity after calling `commit` inside a transaction context:\n\n```\nsession = DatabaseService.get_session()\nwith session.begin():\n t = MyModel(name='test')\n session.add(t)\n session.commit()\n p = t.id\n```\n\nThe solution here is simply to use `flush` instead of `commit` :)\n\n========================================\n\nCode:\n```text\nrouter = APIRouter()\n\n@lru_cache()\ndef get_session_maker() -> sessionmaker:\n # create a reusable factory for new AsyncSession instances\n engine = create_engine(SQLALCHEMY_DATABASE_URI, echo=True)\n return sessionmaker(engine)\n\ndef get_session() -> Generator[Session, None, None]:\n cached_sessionmaker = get_session_maker()\n with cached_sessionmaker.begin() as session:\n yield session\n\n@router.post(\"/items\")\ndef add_items(\n session: Session = Depends(get_database.get_session),\n) -> Dict[str, Any]:\n\n request_inputs = [\n RequestInput(name=\"chair\", used_for=\"sitting\"),\n RequestInput(name=\"table\", used_for=\"dining\"),\n RequestInput(name=\"tv\", used_for=\"watching\"),\n ]\n\n uploaded_items = []\n failed_items = []\n for request_input in request_inputs:\n try:\n with session.begin_nested():\n item= Item(\n **request_input.dict()\n )\n session.add(item)\n session.refresh(item)\n\n uploaded_items += 1\n\n except IntegrityError as e:\n # Handle any integrity constraint violations here\n session.rollback()\n failed_items += 1\n except Exception as e:\n # Handle other exceptions\n session.rollback()\n failed_items += 1\n\n session.commit()\n\n return {\n \"uploaded\": uploaded_items,\n \"failed\": failed_items,\n }\n```\n\n```text\nsqlalchemy.exc.InvalidRequestError: Can't operate on a closed transaction inside a context manager.\n```\n\n```py\nsession.refresh(item)\n```\n\n```py\nimport sqlalchemy as sa\nfrom sqlalchemy import orm\nfrom sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column\n\nclass Base(DeclarativeBase):\n pass\n\nclass Item(Base):\n __tablename__ = \"items\"\n\n id: Mapped[int] = mapped_column(primary_key=True)\n name: Mapped[str] = mapped_column(unique=True)\n used_for: Mapped[str]\n\nengine = sa.create_engine(\"sqlite://\", echo=True)\nBase.metadata.create_all(engine)\nSession = orm.sessionmaker(engine)\n\nwith Session.begin() as session:\n request_inputs = [\n dict(name=\"chair\", used_for=\"sitting\"),\n dict(name=\"table\", used_for=\"dining\"),\n dict(name=\"chair\", used_for=\"sitting\"), # Force an IntegrityError\n ]\n\n uploaded_items = failed_items = 0\n for request_input in request_inputs:\n try:\n with session.begin_nested():\n item = Item(**request_input)\n session.add(item)\n uploaded_items += 1\n\n # If an exception is raised inside the begin_nested() method\n # the inner transaction will be rolled back and the exception\n # will be re-raised. Trap it inside the outer session to prevent\n # the outer session from being rolled back.\n except sa.exc.IntegrityError as e:\n # Handle any integrity constraint violations here\n failed_items += 1\n except Exception as e:\n # Handle other exceptions\n failed_items += 1\n\n result = {\n \"uploaded\": uploaded_items,\n \"failed\": failed_items,\n }\n print(f\"{result = }\")\n```\n\n```text\nexcept\n```\n\n```text\nbegin_nested()\n```\n\n```text\nexcept\n```\n\n```text\nrollback()\n```\n\n```text\ncommit()\n```\n\n```text\nbegin()\n```\n\n```py\nsession = DatabaseService.get_session()\nwith session.begin():\n t = MyModel(name='test')\n session.add(t)\n session.commit()\n p = t.id\n```\n\n```text\ncommit\n```\n\n```text\nflush\n```\n\n```text\ncommit\n```\n\n========================================\n\nComments:\n- (For me the call to `.refresh` also raises an error - I'm not sure what its purpose is in your code.\n- Thanks, that was indeed the problem. Regarding the `.refresh`, it is used to eventually update my local Item with the item_id given in the database, to return to the user.","metadata":{"transformedAt":"2026-08-18T18:32:29.134Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":14,"totalLines":258,"estimatedTokens":1732}}446{"id":"stack-74116435","source":"stackoverflow","questionId":74116435,"title":"FastAPI is not quitting when pressing Ctr+c","tags":["python","fastapi","uvicorn","asgi"],"text":"Title: FastAPI is not quitting when pressing Ctr+c\nTags: python, fastapi, uvicorn, asgi\nSource: Stack Overflow\n\nQuestion:\nI am finding a difficulty with quitting FastAPI. `Ctr+c` does not work.\nHere is my `pyproject.toml`\n\n```\n[tool.pyright]\nexclude = [\"app/worker\"]\nignore = [\"app/worker\"]\n\n[tool.poetry]\nname = \"api\"\nversion = \"0.1.0\"\ndescription = \"\"\nauthors = [\"SamiAlsubhi \"]\n\n[tool.poetry.dependencies]\npython = \">=3.8,=1.0.0\"]\nbuild-backend = \"poetry.core.masonry.api\"\n```\n\nhere is my entry point\n\n```\n\"\"\"running API in a local dev environment\"\"\"\nimport os\nimport uvicorn\nfrom dotenv import load_dotenv\n\n# laoding env values\nload_dotenv(\"../.env\")\n\nif __name__ == \"__main__\":\n port = os.getenv(\"FASTAPI_PORT\")\n port = int(port) if port else None\n uvicorn.run(\"app.main:app\", host=os.getenv(\"FASTAPI_HOST\"),\n port=port, reload=True)\n```\n\nThis what I get when I run it and then try to quit, the process hangs and does not go back to terminal:\n\n```\n(trendr) sami@Samis-MBP backend % python run.py\nINFO: Will watch for changes in these directories: ['/Users/name/Desktop/etc']\nINFO: Uvicorn running on http://0.0.0.0:1000 (Press CTRL+C to quit)\nINFO: Started reloader process [70087] using watchgod\nINFO: Started server process [70089]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\n^CINFO: Shutting down\nINFO: Finished server process [70089]\nINFO: ASGI 'lifespan' protocol appears unsupported.\n```\n\n========================================\n\nTop Answer:\nI've read about this problem in using `uvicorn` and I found the below code snippet to resolve that:\n\n```\n# Add the below code snippet to your app.py module after the app initialization.\n\ndef receive_signal(signalNumber, frame):\n print('Received:', signalNumber)\n sys.exit()\n\n@app.on_event(\"startup\")\nasync def startup_event():\n import signal\n signal.signal(signal.SIGINT, receive_signal)\n # startup tasks\n```\n\nReference:\n\nCTRL^C doesn't work while startup in progress\n\n========================================\n\nCode:\n```ini\n[tool.pyright]\nexclude = [\"app/worker\"]\nignore = [\"app/worker\"]\n\n[tool.poetry]\nname = \"api\"\nversion = \"0.1.0\"\ndescription = \"\"\nauthors = [\"SamiAlsubhi <sami@alsubhi.me>\"]\n\n[tool.poetry.dependencies]\npython = \">=3.8,<3.9\"\nfastapi = \"^0.65.2\"\ntortoise-orm = \"^0.17.4\"\nasyncpg = \"^0.23.0\"\naerich = \"^0.5.3\"\nnetworkx = \"^2.5.1\"\nnumpy = \"^1.21.0\"\nldap3 = \"^2.9.1\"\nfastapi-jwt-auth = \"^0.5.0\"\npython-multipart = \"^0.0.5\"\ntorch = \"1.7.1\"\npyts = \"0.11.0\"\nPint = \"^0.17\"\nCython = \"^0.29.24\"\npython-dotenv = \"^0.19.0\"\narq = \"^0.22\"\nuvicorn = {extras = [\"standard\"], version = \"^0.15.0\"}\n\n\n[tool.poetry.dev-dependencies]\npytest = \"^6.2.4\"\nrequests = \"^2.25.1\"\nasynctest = \"^0.13.0\"\ncoverage = \"^5.5\"\npytest-html = \"^3.1.1\"\npytest-sugar = \"^0.9.4\"\npytest-json-report = \"^1.4.0\"\npytest-cov = \"^2.12.1\"\npylint = \"^2.11.1\"\nautopep8 = \"^1.5.7\"\nblack = \"^22.3.0\"\naiosqlite = \"^0.17.0\"\n\n[build-system]\nrequires = [\"poetry-core>=1.0.0\"]\nbuild-backend = \"poetry.core.masonry.api\"\n```\n\n```py\n\"\"\"running API in a local dev environment\"\"\"\nimport os\nimport uvicorn\nfrom dotenv import load_dotenv\n\n# laoding env values\nload_dotenv(\"../.env\")\n\nif __name__ == \"__main__\":\n port = os.getenv(\"FASTAPI_PORT\")\n port = int(port) if port else None\n uvicorn.run(\"app.main:app\", host=os.getenv(\"FASTAPI_HOST\"),\n port=port, reload=True)\n```\n\n```text\n(trendr) sami@Samis-MBP backend % python run.py\nINFO: Will watch for changes in these directories: ['/Users/name/Desktop/etc']\nINFO: Uvicorn running on http://0.0.0.0:1000 (Press CTRL+C to quit)\nINFO: Started reloader process [70087] using watchgod\nINFO: Started server process [70089]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\n^CINFO: Shutting down\nINFO: Finished server process [70089]\nINFO: ASGI 'lifespan' protocol appears unsupported.\n```\n\n```text\nCtr+c\n```\n\n```text\npyproject.toml\n```\n\n```py\n# Add the below code snippet to your app.py module after the app initialization.\n\n\ndef receive_signal(signalNumber, frame):\n print('Received:', signalNumber)\n sys.exit()\n\n\n@app.on_event(\"startup\")\nasync def startup_event():\n import signal\n signal.signal(signal.SIGINT, receive_signal)\n # startup tasks\n```\n\n```text\nuvicorn\n```\n\n========================================\n\nComments:\n- Does this answer your question? Signal handling in Uvicorn with FastAPI - there are other SO questions/answers that might apply to your case. Googling is always the best first course of action.\n- That does not solve the issue. It is not related. I did Google the issue. I could find the answer. There is something related to `uvicorn`.\n- So your problem is that after you get the output you show, your app doesn't quit, right? You don't say so explicitly.\n- Anyways, It looks like something was not compatible between uvicorn, FastAPI and starlette around those versions. I updated them and that fixed it.\n- Still does not solve the issue, it does print `Received: 2` but the output is the same as in the question.\n- Thank you! Adding `-U` when installing `fastapi[standard]` did the trick!","metadata":{"transformedAt":"2026-08-18T18:32:29.134Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":7,"totalLines":199,"estimatedTokens":1276}}447{"id":"stack-73818557","source":"stackoverflow","questionId":73818557,"title":"uvicorn shutting down after 1-2 minutes on AWS Fargate","tags":["amazon-web-services","fastapi","aws-fargate","aws-application-load-balancer","uvicorn"],"text":"Title: uvicorn shutting down after 1-2 minutes on AWS Fargate\nTags: amazon-web-services, fastapi, aws-fargate, aws-application-load-balancer, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI have a deployment of FastAPI 0.81.0 + uvicorn 0.18.3 using Python 3.10.1 on AWS Fargate with an Application Load Balancer. The server runs (as expected) indefinitely in my local Docker, however on AWS the application always shuts down after 1-2 minutes.\n\nThis is the uvicorn invocation in Docker:\n\n```\nCMD [\"uvicorn\", \"--host\", \"0.0.0.0\", \"--port\", \"8000\", \"--log-level\", \"trace\", \"app.main:app\"]\n```\n\nMy FastAPI application looks like this:\n\n```\nfrom fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware\n\napp = FastAPI()\n\napp = FastAPI()\norigins = [\n \"*\"\n]\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=origins,\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n\n@app.get(\"/\")\nasync def root():\n return {\"Hello\": \"World\"}\n```\n\nIt might have something to do with the Load Balancer, since RAM usage of my Fargate service is not too high:\n\nhttps://i.sstatic.net/06AB0.png\n\nThe usual suspect seems to be health checks via TCP instead of HTTP, however AFAIK the health checks are already via HTTP per default in the Fargate task definition or the EC2 target group, respectively.\n\nHere are the logs of my Fargate Task:\n\n```\n2022-09-22 18:43:46 INFO: Finished server process [1]\n2022-09-22 18:43:46 INFO: Waiting for application shutdown.\n2022-09-22 18:43:46 TRACE: ASGI [1] Receive {'type': 'lifespan.shutdown'}\n2022-09-22 18:43:46 TRACE: ASGI [1] Send {'type': 'lifespan.shutdown.complete'}\n2022-09-22 18:43:46 TRACE: ASGI [1] Completed\n2022-09-22 18:43:46 INFO: Application shutdown complete.\n2022-09-22 18:43:45 INFO: Shutting down\n2022-09-22 18:43:39 TRACE: 172.31.21.3:16662 - ASGI [7] Send {'type': 'http.response.body', 'body': ''}\n2022-09-22 18:43:39 TRACE: 172.31.21.3:16662 - ASGI [7] Completed\n2022-09-22 18:43:39 TRACE: 172.31.21.3:16662 - HTTP connection lost\n2022-09-22 18:43:39 INFO: 172.31.21.3:16662 - \"GET / HTTP/1.1\" 200 OK\n2022-09-22 18:43:39 TRACE: 172.31.21.3:16662 - HTTP connection made\n2022-09-22 18:43:39 TRACE: 172.31.21.3:16662 - ASGI [7] Started scope={'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('172.31.30.157', 8000), 'client': ('172.31.21.3', 16662), 'scheme': 'http', 'method': 'GET', 'root_path': '', 'path': '/', 'raw_path': b'/', 'query_string': b'', 'headers': ''}\n2022-09-22 18:43:39 TRACE: 172.31.21.3:16662 - ASGI [7] Send {'type': 'http.response.start', 'status': 200, 'headers': ''}\n2022-09-22 18:43:39 INFO: 172.31.47.71:3856 - \"GET / HTTP/1.1\" 200 OK\n2022-09-22 18:43:39 TRACE: 172.31.47.71:3856 - ASGI [6] Send {'type': 'http.response.body', 'body': ''}\n2022-09-22 18:43:39 TRACE: 172.31.47.71:3856 - ASGI [6] Completed\n2022-09-22 18:43:39 TRACE: 172.31.47.71:3856 - HTTP connection lost\n2022-09-22 18:43:39 TRACE: 172.31.47.71:3856 - HTTP connection made\n2022-09-22 18:43:39 TRACE: 172.31.47.71:3856 - ASGI [6] Started scope={'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('172.31.30.157', 8000), 'client': ('172.31.47.71', 3856), 'scheme': 'http', 'method': 'GET', 'root_path': '', 'path': '/', 'raw_path': b'/', 'query_string': b'', 'headers': ''}\n2022-09-22 18:43:39 TRACE: 172.31.47.71:3856 - ASGI [6] Send {'type': 'http.response.start', 'status': 200, 'headers': ''}\n2022-09-22 18:43:09 TRACE: 172.31.21.3:39448 - ASGI [5] Completed\n2022-09-22 18:43:09 TRACE: 172.31.21.3:39448 - HTTP connection lost\n2022-09-22 18:43:09 TRACE: 172.31.21.3:39448 - ASGI [5] Send {'type': 'http.response.body', 'body': ''}\n2022-09-22 18:43:09 TRACE: 172.31.21.3:39448 - HTTP connection made\n2022-09-22 18:43:09 TRACE: 172.31.21.3:39448 - ASGI [5] Started scope={'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('172.31.30.157', 8000), 'client': ('172.31.21.3', 39448), 'scheme': 'http', 'method': 'GET', 'root_path': '', 'path': '/', 'raw_path': b'/', 'query_string': b'', 'headers': ''}\n2022-09-22 18:43:09 TRACE: 172.31.21.3:39448 - ASGI [5] Send {'type': 'http.response.start', 'status': 200, 'headers': ''}\n2022-09-22 18:43:09 INFO: 172.31.21.3:39448 - \"GET / HTTP/1.1\" 200 OK\n2022-09-22 18:43:09 TRACE: 172.31.47.71:50778 - ASGI [4] Completed\n2022-09-22 18:43:09 TRACE: 172.31.47.71:50778 - HTTP connection lost\n2022-09-22 18:43:09 TRACE: 172.31.47.71:50778 - ASGI [4] Send {'type': 'http.response.start', 'status': 200, 'headers': ''}\n2022-09-22 18:43:09 INFO: 172.31.47.71:50778 - \"GET / HTTP/1.1\" 200 OK\n2022-09-22 18:43:09 TRACE: 172.31.47.71:50778 - ASGI [4] Send {'type': 'http.response.body', 'body': ''}\n2022-09-22 18:43:09 TRACE: 172.31.47.71:50778 - HTTP connection made\n2022-09-22 18:43:09 TRACE: 172.31.47.71:50778 - ASGI [4] Started scope={'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('172.31.30.157', 8000), 'client': ('172.31.47.71', 50778), 'scheme': 'http', 'method': 'GET', 'root_path': '', 'path': '/', 'raw_path': b'/', 'query_string': b'', 'headers': ''}\n2022-09-22 18:42:39 INFO: 172.31.47.71:55984 - \"GET / HTTP/1.1\" 200 OK\n2022-09-22 18:42:39 TRACE: 172.31.47.71:55984 - ASGI [3] Send {'type': 'http.response.start', 'status': 200, 'headers': ''}\n2022-09-22 18:42:39 TRACE: 172.31.47.71:55984 - ASGI [3] Send {'type': 'http.response.body', 'body': ''}\n2022-09-22 18:42:39 TRACE: 172.31.47.71:55984 - ASGI [3] Completed\n2022-09-22 18:42:39 TRACE: 172.31.47.71:55984 - HTTP connection lost\n2022-09-22 18:42:39 TRACE: 172.31.21.3:59240 - HTTP connection lost\n2022-09-22 18:42:39 TRACE: 172.31.47.71:55984 - ASGI [3] Started scope={'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('172.31.30.157', 8000), 'client': ('172.31.47.71', 55984), 'scheme': 'http', 'method': 'GET', 'root_path': '', 'path': '/', 'raw_path': b'/', 'query_string': b'', 'headers': ''}\n2022-09-22 18:42:39 TRACE: 172.31.21.3:59240 - ASGI [2] Completed\n2022-09-22 18:42:39 TRACE: 172.31.47.71:55984 - HTTP connection made\n2022-09-22 18:42:39 INFO: 172.31.21.3:59240 - \"GET / HTTP/1.1\" 200 OK\n2022-09-22 18:42:39 TRACE: 172.31.21.3:59240 - ASGI [2] Send {'type': 'http.response.body', 'body': ''}\n2022-09-22 18:42:39 TRACE: 172.31.21.3:59240 - ASGI [2] Started scope={'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('172.31.30.157', 8000), 'client': ('172.31.21.3', 59240), 'scheme': 'http', 'method': 'GET', 'root_path': '', 'path': '/', 'raw_path': b'/', 'query_string': b'', 'headers': ''}\n2022-09-22 18:42:39 TRACE: 172.31.21.3:59240 - ASGI [2] Send {'type': 'http.response.start', 'status': 200, 'headers': ''}\n2022-09-22 18:42:39 TRACE: 172.31.21.3:59240 - HTTP connection made\n2022-09-22 18:42:30 INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)\n2022-09-22 18:42:30 INFO: Waiting for application startup.\n2022-09-22 18:42:30 TRACE: ASGI [1] Started scope={'type': 'lifespan', 'asgi': {'version': '3.0', 'spec_version': '2.0'}}\n2022-09-22 18:42:30 TRACE: ASGI [1] Receive {'type': 'lifespan.startup'}\n2022-09-22 18:42:30 TRACE: ASGI [1] Send {'type': 'lifespan.startup.complete'}\n2022-09-22 18:42:30 INFO: Application startup complete.\n2022-09-22 18:42:30 INFO: Started server process [1]\n```\n\nAny suggestions on how to solve this problem? Thanks!\n\n========================================\n\nTop Answer:\nHave you tried tuning the uvicorn keep alive value as suggested in the other answer you linked?\n\n```\nCMD [\"uvicorn\", \"--host\", \"0.0.0.0\", \"--port\", \"8000\", \"--log-level\", \"trace\", \"--timeout-keep-alive\", \"65\", \"app.main:app\"]\n```\n\n========================================\n\nCode:\n```text\nCMD [\"uvicorn\", \"--host\", \"0.0.0.0\", \"--port\", \"8000\", \"--log-level\", \"trace\", \"app.main:app\"]\n```\n\n```text\nfrom fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware\n\napp = FastAPI()\n\napp = FastAPI()\norigins = [\n \"*\"\n]\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=origins,\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n\n@app.get(\"/\")\nasync def root():\n return {\"Hello\": \"World\"}\n```\n\n```text\n2022-09-22 18:43:46 INFO: Finished server process [1]\n2022-09-22 18:43:46 INFO: Waiting for application shutdown.\n2022-09-22 18:43:46 TRACE: ASGI [1] Receive {'type': 'lifespan.shutdown'}\n2022-09-22 18:43:46 TRACE: ASGI [1] Send {'type': 'lifespan.shutdown.complete'}\n2022-09-22 18:43:46 TRACE: ASGI [1] Completed\n2022-09-22 18:43:46 INFO: Application shutdown complete.\n2022-09-22 18:43:45 INFO: Shutting down\n2022-09-22 18:43:39 TRACE: 172.31.21.3:16662 - ASGI [7] Send {'type': 'http.response.body', 'body': '<17 bytes>'}\n2022-09-22 18:43:39 TRACE: 172.31.21.3:16662 - ASGI [7] Completed\n2022-09-22 18:43:39 TRACE: 172.31.21.3:16662 - HTTP connection lost\n2022-09-22 18:43:39 INFO: 172.31.21.3:16662 - \"GET / HTTP/1.1\" 200 OK\n2022-09-22 18:43:39 TRACE: 172.31.21.3:16662 - HTTP connection made\n2022-09-22 18:43:39 TRACE: 172.31.21.3:16662 - ASGI [7] Started scope={'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('172.31.30.157', 8000), 'client': ('172.31.21.3', 16662), 'scheme': 'http', 'method': 'GET', 'root_path': '', 'path': '/', 'raw_path': b'/', 'query_string': b'', 'headers': '<...>'}\n2022-09-22 18:43:39 TRACE: 172.31.21.3:16662 - ASGI [7] Send {'type': 'http.response.start', 'status': 200, 'headers': '<...>'}\n2022-09-22 18:43:39 INFO: 172.31.47.71:3856 - \"GET / HTTP/1.1\" 200 OK\n2022-09-22 18:43:39 TRACE: 172.31.47.71:3856 - ASGI [6] Send {'type': 'http.response.body', 'body': '<17 bytes>'}\n2022-09-22 18:43:39 TRACE: 172.31.47.71:3856 - ASGI [6] Completed\n2022-09-22 18:43:39 TRACE: 172.31.47.71:3856 - HTTP connection lost\n2022-09-22 18:43:39 TRACE: 172.31.47.71:3856 - HTTP connection made\n2022-09-22 18:43:39 TRACE: 172.31.47.71:3856 - ASGI [6] Started scope={'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('172.31.30.157', 8000), 'client': ('172.31.47.71', 3856), 'scheme': 'http', 'method': 'GET', 'root_path': '', 'path': '/', 'raw_path': b'/', 'query_string': b'', 'headers': '<...>'}\n2022-09-22 18:43:39 TRACE: 172.31.47.71:3856 - ASGI [6] Send {'type': 'http.response.start', 'status': 200, 'headers': '<...>'}\n2022-09-22 18:43:09 TRACE: 172.31.21.3:39448 - ASGI [5] Completed\n2022-09-22 18:43:09 TRACE: 172.31.21.3:39448 - HTTP connection lost\n2022-09-22 18:43:09 TRACE: 172.31.21.3:39448 - ASGI [5] Send {'type': 'http.response.body', 'body': '<17 bytes>'}\n2022-09-22 18:43:09 TRACE: 172.31.21.3:39448 - HTTP connection made\n2022-09-22 18:43:09 TRACE: 172.31.21.3:39448 - ASGI [5] Started scope={'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('172.31.30.157', 8000), 'client': ('172.31.21.3', 39448), 'scheme': 'http', 'method': 'GET', 'root_path': '', 'path': '/', 'raw_path': b'/', 'query_string': b'', 'headers': '<...>'}\n2022-09-22 18:43:09 TRACE: 172.31.21.3:39448 - ASGI [5] Send {'type': 'http.response.start', 'status': 200, 'headers': '<...>'}\n2022-09-22 18:43:09 INFO: 172.31.21.3:39448 - \"GET / HTTP/1.1\" 200 OK\n2022-09-22 18:43:09 TRACE: 172.31.47.71:50778 - ASGI [4] Completed\n2022-09-22 18:43:09 TRACE: 172.31.47.71:50778 - HTTP connection lost\n2022-09-22 18:43:09 TRACE: 172.31.47.71:50778 - ASGI [4] Send {'type': 'http.response.start', 'status': 200, 'headers': '<...>'}\n2022-09-22 18:43:09 INFO: 172.31.47.71:50778 - \"GET / HTTP/1.1\" 200 OK\n2022-09-22 18:43:09 TRACE: 172.31.47.71:50778 - ASGI [4] Send {'type': 'http.response.body', 'body': '<17 bytes>'}\n2022-09-22 18:43:09 TRACE: 172.31.47.71:50778 - HTTP connection made\n2022-09-22 18:43:09 TRACE: 172.31.47.71:50778 - ASGI [4] Started scope={'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('172.31.30.157', 8000), 'client': ('172.31.47.71', 50778), 'scheme': 'http', 'method': 'GET', 'root_path': '', 'path': '/', 'raw_path': b'/', 'query_string': b'', 'headers': '<...>'}\n2022-09-22 18:42:39 INFO: 172.31.47.71:55984 - \"GET / HTTP/1.1\" 200 OK\n2022-09-22 18:42:39 TRACE: 172.31.47.71:55984 - ASGI [3] Send {'type': 'http.response.start', 'status': 200, 'headers': '<...>'}\n2022-09-22 18:42:39 TRACE: 172.31.47.71:55984 - ASGI [3] Send {'type': 'http.response.body', 'body': '<17 bytes>'}\n2022-09-22 18:42:39 TRACE: 172.31.47.71:55984 - ASGI [3] Completed\n2022-09-22 18:42:39 TRACE: 172.31.47.71:55984 - HTTP connection lost\n2022-09-22 18:42:39 TRACE: 172.31.21.3:59240 - HTTP connection lost\n2022-09-22 18:42:39 TRACE: 172.31.47.71:55984 - ASGI [3] Started scope={'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('172.31.30.157', 8000), 'client': ('172.31.47.71', 55984), 'scheme': 'http', 'method': 'GET', 'root_path': '', 'path': '/', 'raw_path': b'/', 'query_string': b'', 'headers': '<...>'}\n2022-09-22 18:42:39 TRACE: 172.31.21.3:59240 - ASGI [2] Completed\n2022-09-22 18:42:39 TRACE: 172.31.47.71:55984 - HTTP connection made\n2022-09-22 18:42:39 INFO: 172.31.21.3:59240 - \"GET / HTTP/1.1\" 200 OK\n2022-09-22 18:42:39 TRACE: 172.31.21.3:59240 - ASGI [2] Send {'type': 'http.response.body', 'body': '<17 bytes>'}\n2022-09-22 18:42:39 TRACE: 172.31.21.3:59240 - ASGI [2] Started scope={'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('172.31.30.157', 8000), 'client': ('172.31.21.3', 59240), 'scheme': 'http', 'method': 'GET', 'root_path': '', 'path': '/', 'raw_path': b'/', 'query_string': b'', 'headers': '<...>'}\n2022-09-22 18:42:39 TRACE: 172.31.21.3:59240 - ASGI [2] Send {'type': 'http.response.start', 'status': 200, 'headers': '<...>'}\n2022-09-22 18:42:39 TRACE: 172.31.21.3:59240 - HTTP connection made\n2022-09-22 18:42:30 INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)\n2022-09-22 18:42:30 INFO: Waiting for application startup.\n2022-09-22 18:42:30 TRACE: ASGI [1] Started scope={'type': 'lifespan', 'asgi': {'version': '3.0', 'spec_version': '2.0'}}\n2022-09-22 18:42:30 TRACE: ASGI [1] Receive {'type': 'lifespan.startup'}\n2022-09-22 18:42:30 TRACE: ASGI [1] Send {'type': 'lifespan.startup.complete'}\n2022-09-22 18:42:30 INFO: Application startup complete.\n2022-09-22 18:42:30 INFO: Started server process [1]\n```\n\n```text\nCMD-SHELL curl -f http://0.0.0.0:8000 || exit 1\n```\n\n```text\ngunicorn \\\n --log-config 'logging.conf'\n --timeout 6000\n```\n\n```text\n--timeout\n```\n\n```text\nCMD [\"uvicorn\", \"--host\", \"0.0.0.0\", \"--port\", \"8000\", \"--log-level\", \"trace\", \"--timeout-keep-alive\", \"65\", \"app.main:app\"]\n```\n\n========================================\n\nComments:\n- Do you mind providing your python version and your complete Dockerbuild file?\n- I run it under `python:3.10.1`. The Dockerbuild file contains additionally only pip and poetry installs.\n- Yes. The maximum never exceeds 30%.\n- Thanks for your suggestion. I checked that once more with 8GB RAM and more CPU: Max Utilization was at 6% and 3%. The behaviour didn't change.\n- Shouldn't the `--timeout` flag behaviour have the same purpose as `--timeout-keep-alive`? If so, it unfortunately does not help either...\n- Looks like the `--timeout` parameter is only for `gunicorn` and not for `uvicorn`, which is the focus of this question.\n- Thanks for your answer. Yes, I tried that; even with `--timeout-keep-alive 1000` nothing changed.\n- Where are you running that command? CMD-SHELL curl -f 0.0.0.0:8000 || exit 1, it doesn't seem to match the Dockerfile available commands.","metadata":{"transformedAt":"2026-08-18T18:32:29.134Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":7,"totalLines":236,"estimatedTokens":3915}}448{"id":"stack-70824033","source":"stackoverflow","questionId":70824033,"title":"Upload single image from axios to FastAPI: \"Expected UploadFile, received: \"","tags":["javascript","typescript","axios","fastapi","react-admin"],"text":"Title: Upload single image from axios to FastAPI: \"Expected UploadFile, received: \"\nTags: javascript, typescript, axios, fastapi, react-admin\nSource: Stack Overflow\n\nQuestion:\nI try to upload an image from my `react-admin` app to FastAPI using axios. The `ImageInput` component returns a `File` object which I cast to a `Blob` and try to upload using `axios`.\n\nThe API client I am using has been generated by orval.\n\nThe response I receive after sending the `POST`:\n\n```\n{\n \"detail\":[\n {\n \"loc\":[\n \"body\",\n \"file\"\n ],\n \"msg\":\"Expected UploadFile, received: \",\n \"type\":\"value_error\"\n }\n ]\n}\n```\n\n`axios` request function:\n\n```\n/**\n * @summary Create Image\n */\nexport const createImage = (\n bodyCreateImageImagesPost: BodyCreateImageImagesPost,\n options?: AxiosRequestConfig\n): Promise> => {\n const formData = new FormData();\n formData.append(\n \"classified_id\",\n bodyCreateImageImagesPost.classified_id.toString()\n );\n formData.append(\"file\", bodyCreateImageImagesPost.file);\n\n return axios.post(`/images`, formData, options);\n};\n```\n\n`axios` request headers:\n\n```\nPOST /images HTTP/1.1\nHost: localhost:8000\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:96.0) Gecko/20100101 Firefox/96.0\nAccept: application/json, text/plain, */*\nAccept-Language: pl,en-US;q=0.7,en;q=0.3\nAccept-Encoding: gzip, deflate\nAuthorization: bearer xxx\nContent-Type: multipart/form-data; boundary=---------------------------41197619542060894471320873154\nContent-Length: 305\nOrigin: http://localhost:3000\nDNT: 1\nConnection: keep-alive\nReferer: http://localhost:3000/\nSec-Fetch-Dest: empty\nSec-Fetch-Mode: cors\nSec-Fetch-Site: same-site\nSec-GPC: 1\n```\n\nRequest data object:\n\n```\n{\n \"classified_id\": 2,\n \"file\": {\n \"rawFile\": {...},\n \"src\": \"blob:http://localhost:3000/9826efb4-875d-42f9-9554-49a6b13204be\",\n \"name\": \"Screenshot_2019-10-16-18-04-03.png\"\n }\n}\n```\n\nFastAPI endpoint:\n\n```\ndef create_image(\n classified_id: int = Form(...),\n file: UploadFile = File(...),\n db: Session = Depends(get_db),\n user: User = Security(manager, scopes=[\"images_create\"]),\n) -> Any:\n # ...\n```\n\nIn the \"Network\" section of the developer tools in a browser, it shows the `file` field as `[object Object]` but I guess that's just a problem with no string representation of the `Blob`?\n\nWhen I try to upload an image through the Swagger UI, it works as expected and the `curl` request looks like this:\n\n```\ncurl -X 'POST' \\\n 'http://localhost:8000/images' \\\n -H 'accept: application/json' \\\n -H 'content-length: 3099363' \\\n -H 'Authorization: Bearer xxx' \\\n -H 'Content-Type: multipart/form-data' \\\n -F 'classified_id=2' \\\n -F 'file=@Screenshot_2019-10-16-18-04-03.png;type=image/png'\n```\n\nAny ideas what is wrong in here? How should the proper `axios` request look like?\n\n========================================\n\nCode:\n```json\n{\n \"detail\":[\n {\n \"loc\":[\n \"body\",\n \"file\"\n ],\n \"msg\":\"Expected UploadFile, received: <class 'str'>\",\n \"type\":\"value_error\"\n }\n ]\n}\n```\n\n```js\n/**\n * @summary Create Image\n */\nexport const createImage = (\n bodyCreateImageImagesPost: BodyCreateImageImagesPost,\n options?: AxiosRequestConfig\n): Promise<AxiosResponse<Image>> => {\n const formData = new FormData();\n formData.append(\n \"classified_id\",\n bodyCreateImageImagesPost.classified_id.toString()\n );\n formData.append(\"file\", bodyCreateImageImagesPost.file);\n\n return axios.post(`/images`, formData, options);\n};\n```\n\n```text\nPOST /images HTTP/1.1\nHost: localhost:8000\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:96.0) Gecko/20100101 Firefox/96.0\nAccept: application/json, text/plain, */*\nAccept-Language: pl,en-US;q=0.7,en;q=0.3\nAccept-Encoding: gzip, deflate\nAuthorization: bearer xxx\nContent-Type: multipart/form-data; boundary=---------------------------41197619542060894471320873154\nContent-Length: 305\nOrigin: http://localhost:3000\nDNT: 1\nConnection: keep-alive\nReferer: http://localhost:3000/\nSec-Fetch-Dest: empty\nSec-Fetch-Mode: cors\nSec-Fetch-Site: same-site\nSec-GPC: 1\n```\n\n```json\n{\n \"classified_id\": 2,\n \"file\": {\n \"rawFile\": {...},\n \"src\": \"blob:http://localhost:3000/9826efb4-875d-42f9-9554-49a6b13204be\",\n \"name\": \"Screenshot_2019-10-16-18-04-03.png\"\n }\n}\n```\n\n```py\ndef create_image(\n classified_id: int = Form(...),\n file: UploadFile = File(...),\n db: Session = Depends(get_db),\n user: User = Security(manager, scopes=[\"images_create\"]),\n) -> Any:\n # ...\n```\n\n```text\ncurl -X 'POST' \\\n 'http://localhost:8000/images' \\\n -H 'accept: application/json' \\\n -H 'content-length: 3099363' \\\n -H 'Authorization: Bearer xxx' \\\n -H 'Content-Type: multipart/form-data' \\\n -F 'classified_id=2' \\\n -F 'file=@Screenshot_2019-10-16-18-04-03.png;type=image/png'\n```\n\n```text\nreact-admin\n```\n\n```text\nImageInput\n```\n\n```text\nFile\n```\n\n```text\nBlob\n```\n\n```text\naxios\n```\n\n```text\nPOST\n```\n\n```text\naxios\n```\n\n```text\naxios\n```\n\n```text\nfile\n```\n\n```text\n[object Object]\n```\n\n```text\nBlob\n```\n\n```text\ncurl\n```\n\n```text\naxios\n```\n\n```html\n<script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/axios/0.27.2/axios.min.js\"></script>\n<script type=\"text/javascript\">\nfunction uploadFile() {\n var formData = new FormData();\n var fileInput = document.getElementById('fileInput');\n if (fileInput.files[0]) {\n formData.append(\"classified_id\", 2);\n formData.append(\"file\", fileInput.files[0]);\n axios({\n method: 'post',\n url: '/upload',\n data: formData,\n headers: {\n 'Accept': 'application/json',\n 'Content-Type': 'multipart/form-data'\n },\n })\n .then(response => {\n console.log(response);\n })\n .catch(error => {\n console.error(error);\n });\n }\n}\n</script>\n<input type=\"file\" id=\"fileInput\" name=\"file\"><br>\n<input type=\"button\" value=\"submit\" onclick=\"uploadFile()\">\n```\n\n```text\nurl\n```\n\n```text\nAccept\n```\n\n========================================\n\nComments:\n- I've changed the `file` parameter of the query to the `File` type instead of `Blob` and added the `Content-Type` header as in your code but nothing changed. I can't see any other differences comparing to my code provided.\n- Yes, after I've added the `Authorization` header (btw. you have a typo in the `headers` property name) and used your code for input it works as expected. The problem is that the framework I am using (`react-admin`) does not return files as the `files` property of the `input` but as `File` objects which are not available by checking the property mentioned as they are dynamically changed to the `img` elements with the `src` attributes containing `blob` like: `blob:http://localhost:3000/aece2967-4f9a-4c18-acb0-ad9aac1c8‌​336`.\n- I don't have an idea how to get it working with the functionality that the framework mentioned provides. I can see that when using your code, in the request body there is actual content of the image instead of the `[object Object]` string.\n- I didn't, but your suggestion gave me an idea what can be an issue in this case. I've checked the type of the `Object` that the `react-admin` gives me and it turned out that the property of it (`rawFile`) is the actual `File` object - it's not the main object as I thought. After changing the type of the `file` parameter in orval-generated `interface` it works! Thanks Chris.","metadata":{"transformedAt":"2026-08-18T18:32:29.134Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":22,"totalLines":298,"estimatedTokens":1876}}449{"id":"stack-63138497","source":"stackoverflow","questionId":63138497,"title":"uploading multiple files UploadFiles FastAPI","tags":["python","python-asyncio","fastapi","httpx"],"text":"Title: uploading multiple files UploadFiles FastAPI\nTags: python, python-asyncio, fastapi, httpx\nSource: Stack Overflow\n\nQuestion:\n### Example\n\nHere's my code:\n\n```\nfrom typing import List\nfrom fastapi import FastAPI, File, UploadFile\nimport asyncio\nimport concurrent.futures\n\napp = FastAPI()\n@app.post(\"/send_images\")\nasync def update_item(\n files: List[UploadFile] = File(...),\n):\n return {\"res\": len(files)}\n```\n\nAnd I send requests to this server with (these specific urls are just for example here):\n\n```\nimport requests\nimport os \nimport json\nimport numpy as np\nimport time\nimport io\nimport httpx\nimport asyncio\nfrom datetime import datetime\nimport pandas as pd\n\nfrom random import shuffle\nimport pandas as pd\nimport urllib\nimport io\nfrom PIL import Image\nfrom matplotlib import pyplot as plt\nimport concurrent.futures\n\nurls = ['https://sun9-63.userapi.com/c638920/v638920705/1a54d/xSREwpakJD4.jpg',\n 'https://sun9-28.userapi.com/c854024/v854024084/1160d8/LDMVHYgguAw.jpg',\n 'https://sun9-54.userapi.com/c854220/v854220084/111f66/LdcbEpPR6tg.jpg',\n 'https://sun9-40.userapi.com/c841420/v841420283/4c8bb/Mii6GSCrmpo.jpg',\n 'https://sun6-16.userapi.com/CPQpllJ0KtaArvQKkPsHTZDCupqjRJ_8l07ejA/iyg2hRR_kM4.jpg',\n 'https://sun9-1.userapi.com/c638920/v638920705/1a53b/SMta6Bv-k7s.jpg',\n 'https://sun9-36.userapi.com/c857332/v857332580/56ad/rJCGKFw03FQ.jpg',\n 'https://sun6-14.userapi.com/iPsfmW0ibE8RsMh0k2lUFdRxHZ4Q41yctB7L3A/ajJHY3WN6Xg.jpg',\n 'https://sun9-28.userapi.com/c854324/v854324383/1c1dc3/UuFigBF7WDI.jpg',\n 'https://sun6-16.userapi.com/UVXVAT-tYudG5_24FMaBWTB9vyW8daSrO2WPFQ/RMjv7JZvowA.jpg']\n\nos.environ['NO_PROXY'] = '127.0.0.1'\n\nasync def request_get_4(list_urls):\n async with httpx.AsyncClient() as client:\n r = httpx.post(\"http://127.0.0.1:8001/send_images\", files={f'num_{ind}': el for ind, el in enumerate(list_urls)})\n print(r.text)\n return r\n\nasync def request_get_3(url):\n async with httpx.AsyncClient() as client:\n return await client.get(url)\n \nfrom collections import defaultdict\n\nasync def main():\n start = datetime.now()\n tasks = [asyncio.create_task(request_get_3(url)) for url in urls[0:10]]\n result = await asyncio.gather(*tasks)\n \n data_to_send = []\n for ind, resp in enumerate(result):\n if resp.status_code == 200:\n image_bytes = io.BytesIO(resp.content)\n image_bytes.seek(0)\n data_to_send.append(image_bytes)\n \n end = datetime.now()\n print(result)\n print(len(data_to_send))\n\n batch_size = 2\n batch_num = len(data_to_send) // batch_size\n tasks = [asyncio.create_task(request_get_4(data_to_send[i * batch_size: (i+1) * batch_size])) for i in range(batch_num)]\n result = await asyncio.gather(*tasks)\n \n left_data = data_to_send[batch_size*(batch_num):]\n print(len(left_data))\n print(result)\n\nasyncio.run(main())\n```\n\nI am trying to load image which are contained in urls, then form batches of them and send them to FastAPI server. But it doesn't work.\nI get the following error:\n\n```\n{\"detail\":[{\"loc\":[\"body\",\"files\"],\"msg\":\"field required\",\"type\":\"value_error.missing\"}]}\n```\n\nHow can I fix my problem and be able to send multiple files through httpx to FastAPI?\n\n========================================\n\nTop Answer:\nThis example will pass multiple files under the **files** field.\n\n```\nasync with httpx.AsyncClient(timeout=httpx.Timeout(100.0)) as client: \n response = await client.post(f\"/api/v1/upload-files\",\n files=[(\"files\", (\"image.png\", b\"{}\", \"image/png\")), (\"files\", (\"image2.png\", b\"{}\", \"image/png\"))],\n )\n```\n\n========================================\n\nCode:\n```text\nfrom typing import List\nfrom fastapi import FastAPI, File, UploadFile\nimport asyncio\nimport concurrent.futures\n\napp = FastAPI()\n@app.post(\"/send_images\")\nasync def update_item(\n files: List[UploadFile] = File(...),\n):\n return {\"res\": len(files)}\n```\n\n```text\nimport requests\nimport os \nimport json\nimport numpy as np\nimport time\nimport io\nimport httpx\nimport asyncio\nfrom datetime import datetime\nimport pandas as pd\n\nfrom random import shuffle\nimport pandas as pd\nimport urllib\nimport io\nfrom PIL import Image\nfrom matplotlib import pyplot as plt\nimport concurrent.futures\n\nurls = ['https://sun9-63.userapi.com/c638920/v638920705/1a54d/xSREwpakJD4.jpg',\n 'https://sun9-28.userapi.com/c854024/v854024084/1160d8/LDMVHYgguAw.jpg',\n 'https://sun9-54.userapi.com/c854220/v854220084/111f66/LdcbEpPR6tg.jpg',\n 'https://sun9-40.userapi.com/c841420/v841420283/4c8bb/Mii6GSCrmpo.jpg',\n 'https://sun6-16.userapi.com/CPQpllJ0KtaArvQKkPsHTZDCupqjRJ_8l07ejA/iyg2hRR_kM4.jpg',\n 'https://sun9-1.userapi.com/c638920/v638920705/1a53b/SMta6Bv-k7s.jpg',\n 'https://sun9-36.userapi.com/c857332/v857332580/56ad/rJCGKFw03FQ.jpg',\n 'https://sun6-14.userapi.com/iPsfmW0ibE8RsMh0k2lUFdRxHZ4Q41yctB7L3A/ajJHY3WN6Xg.jpg',\n 'https://sun9-28.userapi.com/c854324/v854324383/1c1dc3/UuFigBF7WDI.jpg',\n 'https://sun6-16.userapi.com/UVXVAT-tYudG5_24FMaBWTB9vyW8daSrO2WPFQ/RMjv7JZvowA.jpg']\n\nos.environ['NO_PROXY'] = '127.0.0.1'\n\nasync def request_get_4(list_urls):\n async with httpx.AsyncClient() as client:\n r = httpx.post(\"http://127.0.0.1:8001/send_images\", files={f'num_{ind}': el for ind, el in enumerate(list_urls)})\n print(r.text)\n return r\n\nasync def request_get_3(url):\n async with httpx.AsyncClient() as client:\n return await client.get(url)\n \nfrom collections import defaultdict\n\nasync def main():\n start = datetime.now()\n tasks = [asyncio.create_task(request_get_3(url)) for url in urls[0:10]]\n result = await asyncio.gather(*tasks)\n \n data_to_send = []\n for ind, resp in enumerate(result):\n if resp.status_code == 200:\n image_bytes = io.BytesIO(resp.content)\n image_bytes.seek(0)\n data_to_send.append(image_bytes)\n \n end = datetime.now()\n print(result)\n print(len(data_to_send))\n\n batch_size = 2\n batch_num = len(data_to_send) // batch_size\n tasks = [asyncio.create_task(request_get_4(data_to_send[i * batch_size: (i+1) * batch_size])) for i in range(batch_num)]\n result = await asyncio.gather(*tasks)\n \n left_data = data_to_send[batch_size*(batch_num):]\n print(len(left_data))\n print(result)\n\nasyncio.run(main())\n```\n\n```text\n{\"detail\":[{\"loc\":[\"body\",\"files\"],\"msg\":\"field required\",\"type\":\"value_error.missing\"}]}\n```\n\n```text\nasync def request_post_batch(fastapi_url: str, url_content_batch: List[BinaryIO]) -> httpx.Response:\n \"\"\"\n Send batch to FastAPI server.\n \"\"\"\n async with httpx.AsyncClient(timeout=httpx.Timeout(100.0)) as client:\n r = await client.post(\n fastapi_url,\n files=[('bytes_image', url_content) for url_content in url_content_batch]\n )\n return r\n\n\nasync def request_post_logs(logstash_url: str, logs: List[Dict]) -> httpx.Response:\n \"\"\"\n Send logs to logstash\n \"\"\"\n async with httpx.AsyncClient(timeout=httpx.Timeout(100.0)) as client:\n r = await client.post(\n logstash_url,\n json=logs\n )\n return r\n```\n\n```text\nasync with httpx.AsyncClient(timeout=httpx.Timeout(100.0)) as client: \n response = await client.post(f\"/api/v1/upload-files\",\n files=[(\"files\", (\"image.png\", b\"{}\", \"image/png\")), (\"files\", (\"image2.png\", b\"{}\", \"image/png\"))],\n )\n```\n\n========================================\n\nComments:\n- My guess is that your endpoint expects a `list` of files, while you are passing a dictionary via the `httpx.post` request. Try something like `files=[f for f in downloaded_files]` , which, BTW, does not seem you are downloading them before sending them\n- in https.post files argument expects dictionary.\n- and why do you think that I don't download urls? I use httpx.get.\n- so, yeah, this is httpx module limitation! right now it can't send more than one file in post request!\n- Sorry, I misread and though that list_urls was still the list above. Also, I don't think it's httpx's limitation. python-httpx.org/advanced/#multipart-file-encoding says that it accepts a dictionary with tuples. Does that work?\n- Please, look up the url I mentioned in my answer link It has all the information.\n- Now that I have enough time to read it thoughtfully, I see it's not been released yet. Though the docs said something different.. Sorry, my bad\n- Future readers should have a look at this answer, as well as this answer and this answer\n- Example, example, example :-) please :-)\n- what example do you want?\n- [('images', ('foo.png', open('foo.png', 'rb'), 'image/png')), ('images', ('bar.png', open('bar.png', 'rb'), 'image/png'))]","metadata":{"transformedAt":"2026-08-18T18:32:29.134Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":5,"totalLines":259,"estimatedTokens":2131}}450{"id":"stack-70489306","source":"stackoverflow","questionId":70489306,"title":"Kill a python subprocess that does not return","tags":["python","subprocess","fastapi"],"text":"Title: Kill a python subprocess that does not return\nTags: python, subprocess, fastapi\nSource: Stack Overflow\n\nQuestion:\nTLDR I want to kill a subprocess like top while it is still running\n\nI am using Fastapi to run a command on input. For example if I enter top my program runs the command but since it does not return, at the moment I have to use a time delay then kill/terminate it. However I want to be able to kill it while it is still running. However at the moment it won't run my kill command until the time runs out.\nHere is the current code for running a process:\n\n```\n@app.put(\"/command/{command}\")\nasync def run_command(command: str):\n subprocess.run([command], shell=True, timeout=10)\n return {\"run command\"}\n```\n\nand to kill it\n\n```\n@app.get(\"/stop\")\nasync def stop():\n proc.kill()\n return{\"Stop\"}\n```\n\nI am new to fastapi so I would be grateful for any help\n\n========================================\n\nCode:\n```text\n@app.put(\"/command/{command}\")\nasync def run_command(command: str):\n subprocess.run([command], shell=True, timeout=10)\n return {\"run command\"}\n```\n\n```text\n@app.get(\"/stop\")\nasync def stop():\n proc.kill()\n return{\"Stop\"}\n```\n\n```text\nimport asyncio\n\nprocess = None\n@app.get(\"/command/{command}\")\nasync def run_command(command: str):\n global process\n process = await asyncio.create_subprocess_exec(\n command, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE\n )\n return {\"run command\"}\n\n@app.get(\"/stop\")\nasync def stop():\n process.kill()\n return {\"Stop\"}\n```\n\n```text\nfrom subprocess import Popen\n\nprocess = None\n@app.get(\"/command/{command}\")\nasync def run_command(command: str):\n global process\n process = Popen([command]) # something long running\n return {\"run command\"}\n```\n\n```text\n@app.get(\"/command/{command}\")\nasync def run_command(command: str):\n global process\n process = await asyncio.create_subprocess_exec(\n command, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE\n )\n loop = asyncio.get_event_loop()\n # We schedule here stop coroutine execution that runs after TIMEOUT seconds\n loop.call_later(TIMEOUT, asyncio.create_task, stop(process.pid))\n\n return {\"run command\"}\n\n@app.get(\"/stop\")\nasync def stop(pid=None):\n global process\n # We need to make sure we won't kill different process\n if process and (pid is None or process.pid == pid):\n process.kill()\n process = None\n return {\"Stop\"}\n```\n\n```text\nsubprocess.run\n```\n\n========================================\n\nComments:\n- So how would it stop after say 10 seconds as if I tell it to sleep the program will wait until after the sleep to run the stop?\n- You mean you would like to kill process if it lasts longer that some arbitrary time?\n- Yes exactly. For example if I run top I want it to stop automatically after 30 seconds but if I use the kill command as before that stops it sooner. However I cant use time.sleep(30) as my kill command will not work until after the 30seconds.\n- @CodingNewbie Sorry for delay, I updated answer. Let me know does it work for you!","metadata":{"transformedAt":"2026-08-18T18:32:29.134Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":6,"totalLines":108,"estimatedTokens":773}}451{"id":"stack-77031847","source":"stackoverflow","questionId":77031847,"title":"Sending request from React to FastAPI causes \"origin http://localhost:5173 has been blocked by CORS policy\" error","tags":["python","reactjs","axios","cors","fastapi"],"text":"Title: Sending request from React to FastAPI causes \"origin http://localhost:5173 has been blocked by CORS policy\" error\nTags: python, reactjs, axios, cors, fastapi\nSource: Stack Overflow\n\nQuestion:\nI was making a POST request which sends an image file from my UI to the backend server.\n\nBackend Server:\n\n```\nfrom fastapi import FastAPI, UploadFile\nfrom fastapi.middleware.cors import CORSMiddleware\nimport numpy as np\nimport tensorflow as tf\nfrom io import BytesIO\nfrom PIL import Image\n\napp = FastAPI()\n\norigins = [\"http://localhost:5173/\"]\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=origins,\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n\nmodel = tf.keras.models.load_model(\"../models/1\")\nclass_names = [\"Normal\", \"Tuberculosis\"]\n\ndef convert_image_to_np_array(bytes):\n # Read bytes as PIL image and convert it to np array\n np_array = np.array(Image.open(BytesIO(bytes)))\n return np_array\n\n@app.post(\"/predict\")\nasync def predict_tuberculosis(file: UploadFile):\n bytes = await file.read()\n np_array = convert_image_to_np_array(bytes)\n batch_image = np.expand_dims(np_array, axis=0)\n resized_batch_image = np.resize(batch_image, (1,256,256,3))\n prediction = model.predict(resized_batch_image)\n label = class_names[np.argmax(prediction)]\n accuracy = np.max(prediction)\n print(accuracy)\n return label\n```\n\nFrontend:\n\n```\nimport React from \"react\"\nimport { useState } from \"react\"\nimport axios from \"axios\"\nimport \"./App.css\"\n\nfunction App() {\n function callPrediction(file) {\n const formData = new FormData()\n formData.append(\"file\", file)\n axios.post(\"http://localhost:8000/predict\", formData)\n .then(res => setResult(res.data))\n .catch(err => console.log(err))\n }\n\n ...\n```\n\n**Note:** The `file` input from `callPrediction` has the format like this\n\nhttps://i.sstatic.net/SDOkL.png\n\nWhen I call the function `callPrediction` to send an image file as an input to the function `predict_tuberculosis` , I got this error popping up\n\nhttps://i.sstatic.net/Y9S1j.png\n\nI did go searching for this but all the solutions I got was just adding CORS to my backend (which I have already done).\n\nI really appreciate any helps! Thank you\n\n========================================\n\nTop Answer:\nThe origins array in your backend server should contain the client url: http://localhost:8000.\nso make sure to add it to your origins array.\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI, UploadFile\nfrom fastapi.middleware.cors import CORSMiddleware\nimport numpy as np\nimport tensorflow as tf\nfrom io import BytesIO\nfrom PIL import Image\n\napp = FastAPI()\n\norigins = [\"http://localhost:5173/\"]\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=origins,\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n\nmodel = tf.keras.models.load_model(\"../models/1\")\nclass_names = [\"Normal\", \"Tuberculosis\"]\n\ndef convert_image_to_np_array(bytes):\n # Read bytes as PIL image and convert it to np array\n np_array = np.array(Image.open(BytesIO(bytes)))\n return np_array\n\n@app.post(\"/predict\")\nasync def predict_tuberculosis(file: UploadFile):\n bytes = await file.read()\n np_array = convert_image_to_np_array(bytes)\n batch_image = np.expand_dims(np_array, axis=0)\n resized_batch_image = np.resize(batch_image, (1,256,256,3))\n prediction = model.predict(resized_batch_image)\n label = class_names[np.argmax(prediction)]\n accuracy = np.max(prediction)\n print(accuracy)\n return label\n```\n\n```text\nimport React from \"react\"\nimport { useState } from \"react\"\nimport axios from \"axios\"\nimport \"./App.css\"\n\nfunction App() {\n function callPrediction(file) {\n const formData = new FormData()\n formData.append(\"file\", file)\n axios.post(\"http://localhost:8000/predict\", formData)\n .then(res => setResult(res.data))\n .catch(err => console.log(err))\n }\n\n ...\n```\n\n```text\nfile\n```\n\n```text\ncallPrediction\n```\n\n```text\ncallPrediction\n```\n\n```text\npredict_tuberculosis\n```\n\n```text\nhttp://localhost:5173/\n ^\n```\n\n```py\norigins = [\"http://localhost:5173\"]\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=origins,\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n```\n\n```text\nhttp://localhost:5173\n```\n\n========================================\n\nComments:\n- Does this answer your question? Access from origin 'https://example.com' has been blocked even though I've allowed https://example.com/\n- Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.","metadata":{"transformedAt":"2026-08-18T18:32:29.134Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":9,"totalLines":192,"estimatedTokens":1186}}452{"id":"stack-63884139","source":"stackoverflow","questionId":63884139,"title":"FastAPI: How to download bytes through the API","tags":["python","fastapi","starlette"],"text":"Title: FastAPI: How to download bytes through the API\nTags: python, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nIs there a way to download a file through FastAPI? The files we want are located in an Azure Datalake and retrieving them from the lake is not an issue, the problem occurs when we try to get the bytes we get from the datalake down to a local machine.\n\nWe have tried using different modules in FastAPI such as `starlette.responses.FileResponse` and `fastapi.Response` with no luck.\n\nIn Flask this is not an issue and can be done in the following manner:\n\n```\nfrom io import BytesIO\nfrom flask import Flask\nfrom werkzeug import FileWrapper\n\nflask_app = Flask(__name__)\n\n@flask_app.route('/downloadfile/', methods=['GET'])\ndef get_the_file(file_name: str):\n the_file = FileWrapper(BytesIO(download_file_from_directory(file_name)))\n if the_file:\n return Response(the_file, mimetype=file_name, direct_passthrough=True)\n```\n\nWhen running this with a valid file name the file automatically downloads. Is there equivalent way to this in FastAPI?\n\n### Solved\n\nAfter some more troubleshooting I found a way to do this.\n\n```\nfrom fastapi import APIRouter, Response\n\nrouter = APIRouter()\n\n@router.get('/downloadfile/{file_name}', tags=['getSkynetDL'])\nasync def get_the_file(file_name: str):\n # the_file object is raw bytes\n the_file = download_file_from_directory(file_name)\n if the_file:\n return Response(the_file)\n```\n\nSo after a lot of troubleshooting and hours of looking through documentation, this was all it took, simply returning the bytes as `Response(the_file)`.\n\n========================================\n\nTop Answer:\nAs far as I know, you need to set `media_type` to the adequate type. I did that with some code a year ago and it worked fine.\n\n```\n@app.get(\"/img/{name}\")\ndef read(name: str, access_token_cookie: str=Cookie(None)):\n r = internal.get_data(name)\n if r is None:\n return RedirectResponse(url=\"/static/default.png\")\n else:\n return Response(content=r[\"data\"], media_type=r[\"mime\"])\n```\n\n`r` is a dictionary with the `data` as raw bytes and `mime` the type of the data as given by PythonMagick.\n\n========================================\n\nCode:\n```py\nfrom io import BytesIO\nfrom flask import Flask\nfrom werkzeug import FileWrapper\n\nflask_app = Flask(__name__)\n\n@flask_app.route('/downloadfile/<file_name>', methods=['GET'])\ndef get_the_file(file_name: str):\n the_file = FileWrapper(BytesIO(download_file_from_directory(file_name)))\n if the_file:\n return Response(the_file, mimetype=file_name, direct_passthrough=True)\n```\n\n```py\nfrom fastapi import APIRouter, Response\n\nrouter = APIRouter()\n\n@router.get('/downloadfile/{file_name}', tags=['getSkynetDL'])\nasync def get_the_file(file_name: str):\n # the_file object is raw bytes\n the_file = download_file_from_directory(file_name)\n if the_file:\n return Response(the_file)\n```\n\n```text\nstarlette.responses.FileResponse\n```\n\n```text\nfastapi.Response\n```\n\n```text\nResponse(the_file)\n```\n\n```py\nfrom fastapi import APIRouter, Response\n\nrouter = APIRouter()\n\n@router.get('/downloadfile/{file_name}', tags=['getSkynetDL'])\nasync def get_the_file(file_name: str):\n # the_file object is raw bytes\n the_file = download_file_from_directory(file_name)\n if the_file:\n return Response(the_file)\n```\n\n```text\nResponse(the_file)\n```\n\n```text\n@app.get(\"/img/{name}\")\ndef read(name: str, access_token_cookie: str=Cookie(None)):\n r = internal.get_data(name)\n if r is None:\n return RedirectResponse(url=\"/static/default.png\")\n else:\n return Response(content=r[\"data\"], media_type=r[\"mime\"])\n```\n\n```text\nmedia_type\n```\n\n```text\nr\n```\n\n```text\ndata\n```\n\n```text\nmime\n```\n\n```text\nfrom fastapi import APIRouter, Response\n\nrouter = APIRouter()\n\n@router.get('/downloadfile/{file_name}', tags=['getSkynetDL'])\nasync def get_the_file(file_name: str):\n # the_file object is raw bytes\n the_file = download_file_from_directory(file_name)\n filename1 = make_filename(file_name) # a custom filename\n headers1 = {'Content-Disposition': f'attachment; filename=\"{filename1}\"'}\n if the_file:\n return Response(the_file, headers=headers1)\n```\n\n========================================\n\nComments:\n- You should put it as answer below and mark it as the correct answer to close this question.\n- Solution here doesn't seem to cover setting a custom filename, though I suppose one can hack the path to make it look like a filename to the client side\n- Related answers can be found here, here, here, as well as here, here and here.\n- what the heck is \"download_file_from_directory\"?\n- “download_from_directory” is simply a function that retrieves the binaries of a file in an Azure storage container. The important part of it is that it returns the file as bytes.","metadata":{"transformedAt":"2026-08-18T18:32:29.134Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":13,"totalLines":171,"estimatedTokens":1194}}453{"id":"stack-62895883","source":"stackoverflow","questionId":62895883,"title":"Can't access path parameters from middleware","tags":["python","fastapi"],"text":"Title: Can't access path parameters from middleware\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nMy typical path is something like\n\n```\n/user/{user_id}/resource/{resource_id}\n```\n\nI have a validation method, already written in async Python, like this:\n\n```\nasync def is_allowed(user_id: int, resource_id: int) -> bool\n```\n\nThat returns a boolean: `True` if the user can access the resource, `False` otherwise.\n\nI want to write a middleware that calls `is_allowed` extracting the variables from the path.\n\nI fiddled around but I can't find how to get them: I was expecting to get this information from `request.path_params`.\n\nA more complete example:\n\n```\nimport logging\n\nfrom fastapi import FastAPI\nfrom starlette.requests import Request\nfrom starlette.responses import Response\n\napp = FastAPI()\n\n_logger = logging.getLogger()\n_logger.setLevel(logging.DEBUG)\n\nasync def is_allowed(user_id, resource_id):\n _logger.error(user_id)\n _logger.error(resource_id)\n return True\n\n@app.middleware('http')\nasync def acl(request: Request, call_next):\n user_id = request.path_params.get(\"user_id\", None)\n resource_id = request.path_params.get(\"resource_id\", None)\n allowed = await is_allowed(user_id, resource_id)\n if not allowed:\n return Response(status_code=403)\n else:\n return await call_next(request)\n\n@app.get('/user/{user_id}/resource/{resource_id}')\nasync def my_handler(user_id: int, resource_id: int):\n return {\"what\": f\"Doing stuff with {user_id} on {resource_id}\"}\n```\n\nThe logged values are `None`.\n\n========================================\n\nTop Answer:\nIn pure ASGI middleware you can get access to the path parameters as follows, but it's a bit awkward; you end up re-implementing things that will then happen again as the request is actually handled:\n\n```\nfrom typing import Optional\n\nfrom starlette.datastructures import URL\nfrom starlette.routing import Match, Route\nfrom starlette.types import ASGIApp, Receive, Scope, Send\n\nclass DemoMiddleware:\n\n _app: ASGIApp\n\n def __init__(self, app: ASGIApp):\n self._app = app\n\n async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:\n if scope[\"type\"] == \"http\":\n path_params = self._get_path_params(scope)\n await self._app(scope, receive, send)\n\n @staticmethod\n def _get_path_params(scope: Scope) -> Optional[dict[str, str]]:\n \"\"\"Get path parameters based on matching route.\"\"\"\n matched_params: Optional[dict[str, str]] = None\n routes: list[Route] = scope[\"app\"].routes\n for route in routes:\n match, match_scope = route.matches(scope)\n if match != Match.NONE:\n matched_params = match_scope.get(\"path_params\")\n if match == Match.FULL:\n break\n return matched_params\n```\n\n========================================\n\nCode:\n```text\n/user/{user_id}/resource/{resource_id}\n```\n\n```text\nasync def is_allowed(user_id: int, resource_id: int) -> bool\n```\n\n```text\nimport logging\n\nfrom fastapi import FastAPI\nfrom starlette.requests import Request\nfrom starlette.responses import Response\n\napp = FastAPI()\n\n_logger = logging.getLogger()\n_logger.setLevel(logging.DEBUG)\n\n\nasync def is_allowed(user_id, resource_id):\n _logger.error(user_id)\n _logger.error(resource_id)\n return True\n\n\n@app.middleware('http')\nasync def acl(request: Request, call_next):\n user_id = request.path_params.get(\"user_id\", None)\n resource_id = request.path_params.get(\"resource_id\", None)\n allowed = await is_allowed(user_id, resource_id)\n if not allowed:\n return Response(status_code=403)\n else:\n return await call_next(request)\n\n\n@app.get('/user/{user_id}/resource/{resource_id}')\nasync def my_handler(user_id: int, resource_id: int):\n return {\"what\": f\"Doing stuff with {user_id} on {resource_id}\"}\n```\n\n```text\nTrue\n```\n\n```text\nFalse\n```\n\n```text\nis_allowed\n```\n\n```text\nrequest.path_params\n```\n\n```text\nNone\n```\n\n```text\npath_params\n```\n\n```text\nfrom typing import Optional\n\nfrom starlette.datastructures import URL\nfrom starlette.routing import Match, Route\nfrom starlette.types import ASGIApp, Receive, Scope, Send\n\n\nclass DemoMiddleware:\n\n _app: ASGIApp\n\n def __init__(self, app: ASGIApp):\n self._app = app\n\n async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:\n if scope[\"type\"] == \"http\":\n path_params = self._get_path_params(scope)\n await self._app(scope, receive, send)\n\n @staticmethod\n def _get_path_params(scope: Scope) -> Optional[dict[str, str]]:\n \"\"\"Get path parameters based on matching route.\"\"\"\n matched_params: Optional[dict[str, str]] = None\n routes: list[Route] = scope[\"app\"].routes\n for route in routes:\n match, match_scope = route.matches(scope)\n if match != Match.NONE:\n matched_params = match_scope.get(\"path_params\")\n if match == Match.FULL:\n break\n return matched_params\n```\n\n========================================\n\nComments:\n- For what I can see, the `path_params` are avilable only after the `call_next()` method returned.\n- Using a `dependency` function, as shown in this answer, and raising an exception inside, if the requirements are not met, might be the most suited approach to solve this. Further possible solutions, involving Pydantic models, might be found here and here.\n- Another possible way would be to get the URL path, using `request.url.path` inside the middleware (before `call_next()` is called), as demonstrated here or here, and based on that, try to determine which endpoint was called and its associated path parameters.","metadata":{"transformedAt":"2026-08-18T18:32:29.135Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":10,"totalLines":207,"estimatedTokens":1384}}454{"id":"stack-66109609","source":"stackoverflow","questionId":66109609,"title":"How do I capture X-Forwarded-For with FastAPI logging?","tags":["python-3.x","haproxy","fastapi","uvicorn"],"text":"Title: How do I capture X-Forwarded-For with FastAPI logging?\nTags: python-3.x, haproxy, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI am running FastApi with guvicorn in a function like this:\n\n```\nif __name__ == \"__main__\":\n\n uvicorn.run(\n app=\"app.main:app\",\n host=\"HOSTIP\",\n port=8000,\n reload=True,\n # log_config=None,\n log_config=log_config,\n log_level=\"info\"\n )\n```\n\nThis is what my log_config looks like:\n\n```\nlog_config = {\n \"version\": 1,\n \"disable_existing_loggers\": True,\n \"formatters\": {\n \"default\": {\n \"()\": \"uvicorn.logging.DefaultFormatter\",\n \"fmt\": \"%(asctime)s::%(levelname)s::%(name)s::%(filename)s::%(funcName)s - %(message)s\",\n \"use_colors\": None,\n },\n \"access\": {\n \"()\": \"uvicorn.logging.AccessFormatter\",\n \"fmt\": '%(asctime)s::%(levelprefix)s %(client_addr)s - \"%(request_line)s\" %(status_code)s',\n },\n },\n \"handlers\":\n {\n \"default\":\n {\n \"formatter\": \"default\",\n # \"class\": 'logging.NullHandler',\n \"class\": 'logging.FileHandler',\n \"filename\": CONFIG[SECTION][\"default\"]\n },\n \"error\":\n {\n \"formatter\": \"default\",\n # \"class\": 'logging.NullHandler',\n \"class\": 'logging.FileHandler',\n \"filename\": CONFIG[SECTION][\"error\"]\n },\n \"access\":\n {\n \"formatter\": \"access\",\n # \"class\": 'logging.NullHandler',\n \"class\": 'logging.FileHandler',\n \"filename\": CONFIG[SECTION][\"access\"]\n },\n },\n \"loggers\":\n {\n \"uvicorn\": {\"handlers\": [\"default\"], \"level\": \"INFO\", \"propagate\": False},\n \"uvicorn.error\": {\"handlers\": [\"error\"], \"level\": \"ERROR\", \"propagate\": False},\n \"uvicorn.access\": {\"handlers\": [\"access\"], \"level\": \"INFO\", \"propagate\": False},\n }\n}\n```\n\nI have 2 instances of fastapi on 2 servers, running behind haproxy. I was able to put in this option in haproxy to fwd client IP to my API:\n\n```\noption forwardfor\n```\n\nI am able to confirm with TCPDUMP on one of the API servers that I am infact getting some x-fwd headers coming in:\n\n```\n[user@server ~]# tcpdump -i INTERFACE host SERVERIP -AAA | grep -i IP OF MY LAPTOP\ntcpdump: verbose output suppressed, use -v or -vv for full protocol decode\nlistening on INTERFACE, link-type EN10MB (Ethernet), capture size 262144 bytes\n*X-Forwarded-For: IP OF MY LAPTOP*\n```\n\nBut in my logs, I only see the IP of the vip that the requests hit, even though HAproxy is fwding the IP of client, I am not able to log it.\n\nIs there is a custom variable I can use for the log_config access section?\n\nThanks.\n\n========================================\n\nTop Answer:\nAlright, I figured it out.\n\nI had to include 2 things in the start.py:\n\n```\nif __name__ == \"__main__\":\n\n uvicorn.run(\n app=\"app.main:app\",\n host=\"HOSTIP\",\n port=8000,\n reload=True,\n proxy_headers=True, # THIS LINE\n forwarded_allow_ips='*', # THIS LINE\n log_config=log_config,\n log_level=\"info\"\n )\n```\n\n========================================\n\nCode:\n```text\nif __name__ == \"__main__\":\n\n uvicorn.run(\n app=\"app.main:app\",\n host=\"HOSTIP\",\n port=8000,\n reload=True,\n # log_config=None,\n log_config=log_config,\n log_level=\"info\"\n )\n```\n\n```text\nlog_config = {\n \"version\": 1,\n \"disable_existing_loggers\": True,\n \"formatters\": {\n \"default\": {\n \"()\": \"uvicorn.logging.DefaultFormatter\",\n \"fmt\": \"%(asctime)s::%(levelname)s::%(name)s::%(filename)s::%(funcName)s - %(message)s\",\n \"use_colors\": None,\n },\n \"access\": {\n \"()\": \"uvicorn.logging.AccessFormatter\",\n \"fmt\": '%(asctime)s::%(levelprefix)s %(client_addr)s - \"%(request_line)s\" %(status_code)s',\n },\n },\n \"handlers\":\n {\n \"default\":\n {\n \"formatter\": \"default\",\n # \"class\": 'logging.NullHandler',\n \"class\": 'logging.FileHandler',\n \"filename\": CONFIG[SECTION][\"default\"]\n },\n \"error\":\n {\n \"formatter\": \"default\",\n # \"class\": 'logging.NullHandler',\n \"class\": 'logging.FileHandler',\n \"filename\": CONFIG[SECTION][\"error\"]\n },\n \"access\":\n {\n \"formatter\": \"access\",\n # \"class\": 'logging.NullHandler',\n \"class\": 'logging.FileHandler',\n \"filename\": CONFIG[SECTION][\"access\"]\n },\n },\n \"loggers\":\n {\n \"uvicorn\": {\"handlers\": [\"default\"], \"level\": \"INFO\", \"propagate\": False},\n \"uvicorn.error\": {\"handlers\": [\"error\"], \"level\": \"ERROR\", \"propagate\": False},\n \"uvicorn.access\": {\"handlers\": [\"access\"], \"level\": \"INFO\", \"propagate\": False},\n }\n}\n```\n\n```text\noption forwardfor\n```\n\n```text\n[user@server ~]# tcpdump -i INTERFACE host SERVERIP -AAA | grep -i IP OF MY LAPTOP\ntcpdump: verbose output suppressed, use -v or -vv for full protocol decode\nlistening on INTERFACE, link-type EN10MB (Ethernet), capture size 262144 bytes\n*X-Forwarded-For: IP OF MY LAPTOP*\n```\n\n```text\n--proxy-headers / --no-proxy-headers\n Enable/Disable X-Forwarded-Proto,\n X-Forwarded-For, X-Forwarded-Port to\n populate remote address info.\n```\n\n```text\nproxy_headers=True\n```\n\n```text\nif __name__ == \"__main__\":\n\n uvicorn.run(\n app=\"app.main:app\",\n host=\"HOSTIP\",\n port=8000,\n reload=True,\n proxy_headers=True, # THIS LINE\n forwarded_allow_ips='*', # THIS LINE\n log_config=log_config,\n log_level=\"info\"\n )\n```\n\n========================================\n\nComments:\n- I added that in. Access log still seems to show ip of VIP. Is there a different variable I can use for the formatter? This is what I currently have: 31 \"()\": \"uvicorn.logging.AccessFormatter\", 33 \"fmt\": '%(asctime)s::%(levelprefix)s %(client_addr)s - \"%(request_line)s\" %(status_code)s',\n- Yeah, on the docs that I sent you it's explaining that you also need to use --forwarded-allow-ips if your traffic is not coming from 127.0.0.1\n- Thanks for the direction I got it working.\n- This is exactly what is needed to log real ips. THANK YOU!","metadata":{"transformedAt":"2026-08-18T18:32:29.135Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":7,"totalLines":223,"estimatedTokens":1493}}455{"id":"stack-61753056","source":"stackoverflow","questionId":61753056,"title":"Partial update in FastAPI","tags":["python","python-3.x","sqlalchemy","fastapi","pydantic"],"text":"Title: Partial update in FastAPI\nTags: python, python-3.x, sqlalchemy, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI want to implement a put or patch request in FastAPI that supports partial update. The official documentation is really confusing and I can't figure out how to do the request. (I don't know that `items` is in the documentation since my data will be passed with request's body, not a hard-coded dict).\n\n```\nclass QuestionSchema(BaseModel):\n title: str = Field(..., min_length=3, max_length=50)\n answer_true: str = Field(..., min_length=3, max_length=50)\n answer_false: List[str] = Field(..., min_length=3, max_length=50)\n category_id: int\n\nclass QuestionDB(QuestionSchema):\n id: int\n\nasync def put(id: int, payload: QuestionSchema):\n query = (\n questions\n .update()\n .where(id == questions.c.id)\n .values(**payload)\n .returning(questions.c.id)\n )\n return await database.execute(query=query)\n\n@router.put(\"/{id}/\", response_model=QuestionDB)\nasync def update_question(payload: QuestionSchema, id: int = Path(..., gt=0),):\n question = await crud.get(id)\n if not question:\n raise HTTPException(status_code=404, detail=\"question not found\")\n\n ## what should be the stored_item_data, as documentation?\n stored_item_model = QuestionSchema(**stored_item_data)\n update_data = payload.dict(exclude_unset=True)\n updated_item = stored_item_model.copy(update=update_data)\n\n response_object = {\n \"id\": question_id,\n \"title\": payload.title,\n \"answer_true\": payload.answer_true,\n \"answer_false\": payload.answer_false,\n \"category_id\": payload.category_id,\n }\n return response_object\n```\n\nHow can I complete my code to get a successful partial update here?\n\n========================================\n\nTop Answer:\nPosting this here for googlers who are looking for an intuitive solution for creating Optional Versions of their pydantic Models without code duplication.\n\nLet's say we have a `User` model, and we would like to allow for PATCH requests to update the User. But we need to create a schema that tells FastApi what to expect in the content body, and specifically that all the fields are Optional (Since that's the nature of PATCH requests). We can do so without redefining all the fields\n\n```\nfrom pydantic import BaseModel\nfrom typing import Optional\n\n# Creating our Base User Model\nclass UserBase(BaseModel):\n username: str\n email: str\n \n\n# And a Model that will be used to create an User\nclass UserCreate(UserBase):\n password: str\n```\n\n### Code Duplication ❌\n\n```\nclass UserOptional(UserCreate):\n username: Optional[str]\n email: Optional[str]\n password: Optional[str]\n```\n\n### One Liner ✅\n\n```\n# Now we can make a UserOptional class that will tell FastApi that all the fields are optional. \n# Doing it this way cuts down on the duplication of fields\nclass UserOptional(UserCreate):\n __annotations__ = {k: Optional[v] for k, v in UserCreate.__annotations__.items()}\n```\n\n*NOTE: Even if one of the fields on the Model is already Optional, it won't make a difference due to the nature of Optional being `typing.Union[type passed to Optional, None]` in the background.*\n\ni.e `typing.Union[str, None] == typing.Optional[str]`\n\nYou can even make it into a function if your going to be using it more than once:\n\n```\ndef convert_to_optional(schema):\n return {k: Optional[v] for k, v in schema.__annotations__.items()}\n\nclass UserOptional(UserCreate):\n __annotations__ = convert_to_optional(UserCreate)\n```\n\n========================================\n\nCode:\n```text\nclass QuestionSchema(BaseModel):\n title: str = Field(..., min_length=3, max_length=50)\n answer_true: str = Field(..., min_length=3, max_length=50)\n answer_false: List[str] = Field(..., min_length=3, max_length=50)\n category_id: int\n\n\nclass QuestionDB(QuestionSchema):\n id: int\n\n\nasync def put(id: int, payload: QuestionSchema):\n query = (\n questions\n .update()\n .where(id == questions.c.id)\n .values(**payload)\n .returning(questions.c.id)\n )\n return await database.execute(query=query)\n\n@router.put(\"/{id}/\", response_model=QuestionDB)\nasync def update_question(payload: QuestionSchema, id: int = Path(..., gt=0),):\n question = await crud.get(id)\n if not question:\n raise HTTPException(status_code=404, detail=\"question not found\")\n\n ## what should be the stored_item_data, as documentation?\n stored_item_model = QuestionSchema(**stored_item_data)\n update_data = payload.dict(exclude_unset=True)\n updated_item = stored_item_model.copy(update=update_data)\n\n response_object = {\n \"id\": question_id,\n \"title\": payload.title,\n \"answer_true\": payload.answer_true,\n \"answer_false\": payload.answer_false,\n \"category_id\": payload.category_id,\n }\n return response_object\n```\n\n```text\nitems\n```\n\n```text\nfrom typing import Optional\n\nclass Question(BaseModel):\n title: Optional[str] = None # title is optional on the base schema\n ...\n\nclass QuestionCreate(Question):\n title: str # Now title is required\n```\n\n```text\nOptional\n```\n\n```text\nQuestionCreate\n```\n\n```text\nQuestionSchema\n```\n\n```text\nfrom pydantic import BaseModel\nfrom typing import Optional\n\n# Creating our Base User Model\nclass UserBase(BaseModel):\n username: str\n email: str\n \n\n# And a Model that will be used to create an User\nclass UserCreate(UserBase):\n password: str\n```\n\n```text\nclass UserOptional(UserCreate):\n username: Optional[str]\n email: Optional[str]\n password: Optional[str]\n```\n\n```text\n# Now we can make a UserOptional class that will tell FastApi that all the fields are optional. \n# Doing it this way cuts down on the duplication of fields\nclass UserOptional(UserCreate):\n __annotations__ = {k: Optional[v] for k, v in UserCreate.__annotations__.items()}\n```\n\n```text\ndef convert_to_optional(schema):\n return {k: Optional[v] for k, v in schema.__annotations__.items()}\n\nclass UserOptional(UserCreate):\n __annotations__ = convert_to_optional(UserCreate)\n```\n\n```text\nUser\n```\n\n```text\ntyping.Union[type passed to Optional, None]\n```\n\n```text\ntyping.Union[str, None] == typing.Optional[str]\n```\n\n```py\nfrom typing import Mapping, Any, List, Type\nfrom pydantic import BaseModel\n\ndef model_annotations_with_parents(model: BaseModel) -> Mapping[str, Any]:\n parent_models: List[Type] = [\n parent_model for parent_model in model.__bases__\n if (\n issubclass(parent_model, BaseModel)\n and hasattr(parent_model, '__annotations__')\n )\n ]\n\n annotations: Mapping[str, Any] = {}\n\n for parent_model in reversed(parent_models):\n annotations.update(model_annotations_with_parents(parent_model))\n\n annotations.update(model.__annotations__)\n return annotations\n\n\ndef partial_model_factory(model: BaseModel, prefix: str = \"Partial\", name: str = None) -> BaseModel:\n if not name:\n name = f\"{prefix}{model.__name__}\"\n\n return type(\n name, (model,),\n dict(\n __module__=model.__module__,\n __annotations__={\n k: Optional[v]\n for k, v in model_annotations_with_parents(model).items()\n }\n )\n )\n\n\ndef partial_model(cls: BaseModel) -> BaseModel:\n return partial_model_factory(cls, name=cls.__name__)\n```\n\n```text\nPartialQuestionSchema = partial_model_factory(QuestionSchema)\n```\n\n```text\n@partial_model\nclass PartialQuestionSchema(QuestionSchema):\n pass\n```\n\n```text\npartial_model_factory\n```\n\n```text\npartial_model\n```\n\n========================================\n\nComments:\n- stored_item_data is the data that you get into your question variable. Basically, if your question is a dict with the old values, substitute the old values with the new ones (payload variable) and replace the entire row with the combined values (old and new) in the database. The docs shows a general case, you should implement the update on the database yourself, not fastapi\n- The code is not DRY. An idea solution should be something like the TypeScript's utitlity type `Partial`.\n- The disadvantage is that this approach is not friendly to linters (e.g. mypy) or IDEs. Also for mypy the base class should have optional values.\n- That's a great idea. I was wondering is it possbile to make use mixin to make it look pretty.\n- While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review","metadata":{"transformedAt":"2026-08-18T18:32:29.135Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":18,"totalLines":294,"estimatedTokens":2119}}456{"id":"stack-68811220","source":"stackoverflow","questionId":68811220,"title":"Handling the token expiration in fastapi","tags":["python","security","scope","token","fastapi"],"text":"Title: Handling the token expiration in fastapi\nTags: python, security, scope, token, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm new with fastapi security and I'm trying to implement the authentication thing and then use scopes.\n\nThe problem is that I'm setting an expiration time for the token but after the expiration time the user still authenticated and can access services\n\n```\nimport json\nfrom jose import jwt,JWTError\nfrom typing import Optional\nfrom datetime import datetime,timedelta\nfrom fastapi.security import OAuth2PasswordBearer,OAuth2PasswordRequestForm,SecurityScopes\nfrom fastapi import APIRouter, UploadFile, File, Depends, HTTPException,status\nfrom tinydb import TinyDB,where\nfrom tinydb import Query\nfrom passlib.hash import bcrypt\nfrom pydantic import BaseModel\nfrom passlib.context import CryptContext\n##\n\nclass TokenData(BaseModel):\n username: Optional[str] = None\nclass Token(BaseModel):\n access_token: str\n token_type: str\n\nrouter = APIRouter()\nSECRET_KEY=\"e79b2a1eaa2b801bc81c49127ca4607749cc2629f73518194f528fc5c8491713\"\nALGORITHM=\"HS256\"\nACCESS_TOKEN_EXPIRE_MINUTES=1\noauth2_scheme = OAuth2PasswordBearer(tokenUrl=\"/dev-service/api/v1/openvpn/token\")\ndb=TinyDB('app/Users.json')\nUsers = db.table('User')\nUser = Query\n\npwd_context = CryptContext(schemes=[\"bcrypt\"], deprecated=\"auto\")\nclass User(BaseModel):\n username: str\n password:str\n\ndef get_user(username: str):#still\n user= Users.search((where('name') ==name))\n if user:\n return user[0]\n\n@router.post('/verif')\nasync def verify_user(name,password):\n user = Users.search((where('name') ==name))\n print(user)\n if not user:\n return False\n print(user)\n passw=user[0]['password']\n if not bcrypt.verify(password,passw):\n return False\n return user\n\ndef create_access_token(data: dict, expires_delta: Optional[timedelta] = None):\n to_encode = data.copy()\n if expires_delta:\n expire = datetime.utcnow() + expires_delta\n else:\n expire = datetime.utcnow() + timedelta(minutes=1)\n to_encode.update({\"exp\": expire})\n encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)\n return encoded_jwt\n\n@router.post(\"/token\", response_model=Token)\nasync def token_generate(form_data:OAuth2PasswordRequestForm=Depends()):\n user=await verify_user(form_data.username,form_data.password)\n if not user:\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Incorrect username or password\",\n headers={\"WWW-Authenticate\": \"Bearer\"},\n )\n access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)\n access_token = create_access_token(data={\"sub\": form_data.username}, expires_delta=access_token_expires)\n return {\"access_token\": access_token, \"token_type\": \"bearer\"}\n\n@router.get('/user/me')\nasync def get_current_user(token: str = Depends(oauth2_scheme)):\n credentials_exception = HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Could not validate credentials\",\n headers={\"WWW-Authenticate\": \"Bearer\"},\n )\n try:\n payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])\n username: str = payload.get(\"sub\")\n if username is None:\n raise credentials_exception\n token_data = TokenData(username=username)\n except JWTError:\n raise credentials_exception\n user =Users.search(where('name') ==token_data.username)\n if user is None:\n raise credentials_exception\n return user\n\n@router.post('/user')\nasync def create_user(name,password):\n Users.insert({'name':name,'password':bcrypt.hash(password)})\n return True\n```\n\nHow can I really see the expiration of the token and how can I add the scopes?\n\n========================================\n\nTop Answer:\nI 'd wanted to comment on Unyime Etim's advice\nbut have no rating yet so this would be a separate answer\n\nI just wanted to add that jwt.decode has a built-in method to check \"exp\"\nand it does check it by default (https://github.com/mpdavis/python-jose/blob/96474ecfb6ad3ce16f41b0814ab5126d58725e2a/jose/jwt.py#L82)\n\nso to make sure your token has been expired you can just handle the corresponding exception **ExpiredSignatureError**\n\n```\ntry:\n # decode token and extract username and expires data\n payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])\n username: str = payload.get(\"sub\")\nexcept ExpiredSignatureError: # <---- this one\n raise HTTPException(status_code=403, detail=\"token has been expired\")\nexcept JWTError:\n raise credentials_exception\n```\n\n========================================\n\nCode:\n```text\nimport json\nfrom jose import jwt,JWTError\nfrom typing import Optional\nfrom datetime import datetime,timedelta\nfrom fastapi.security import OAuth2PasswordBearer,OAuth2PasswordRequestForm,SecurityScopes\nfrom fastapi import APIRouter, UploadFile, File, Depends, HTTPException,status\nfrom tinydb import TinyDB,where\nfrom tinydb import Query\nfrom passlib.hash import bcrypt\nfrom pydantic import BaseModel\nfrom passlib.context import CryptContext\n##\n\nclass TokenData(BaseModel):\n username: Optional[str] = None\nclass Token(BaseModel):\n access_token: str\n token_type: str\n\nrouter = APIRouter()\nSECRET_KEY=\"e79b2a1eaa2b801bc81c49127ca4607749cc2629f73518194f528fc5c8491713\"\nALGORITHM=\"HS256\"\nACCESS_TOKEN_EXPIRE_MINUTES=1\noauth2_scheme = OAuth2PasswordBearer(tokenUrl=\"/dev-service/api/v1/openvpn/token\")\ndb=TinyDB('app/Users.json')\nUsers = db.table('User')\nUser = Query\n\npwd_context = CryptContext(schemes=[\"bcrypt\"], deprecated=\"auto\")\nclass User(BaseModel):\n username: str\n password:str\n\ndef get_user(username: str):#still\n user= Users.search((where('name') ==name))\n if user:\n return user[0]\n\n\n\n@router.post('/verif')\nasync def verify_user(name,password):\n user = Users.search((where('name') ==name))\n print(user)\n if not user:\n return False\n print(user)\n passw=user[0]['password']\n if not bcrypt.verify(password,passw):\n return False\n return user\n\n\ndef create_access_token(data: dict, expires_delta: Optional[timedelta] = None):\n to_encode = data.copy()\n if expires_delta:\n expire = datetime.utcnow() + expires_delta\n else:\n expire = datetime.utcnow() + timedelta(minutes=1)\n to_encode.update({\"exp\": expire})\n encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)\n return encoded_jwt\n\n@router.post(\"/token\", response_model=Token)\nasync def token_generate(form_data:OAuth2PasswordRequestForm=Depends()):\n user=await verify_user(form_data.username,form_data.password)\n if not user:\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Incorrect username or password\",\n headers={\"WWW-Authenticate\": \"Bearer\"},\n )\n access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)\n access_token = create_access_token(data={\"sub\": form_data.username}, expires_delta=access_token_expires)\n return {\"access_token\": access_token, \"token_type\": \"bearer\"}\n\n@router.get('/user/me')\nasync def get_current_user(token: str = Depends(oauth2_scheme)):\n credentials_exception = HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Could not validate credentials\",\n headers={\"WWW-Authenticate\": \"Bearer\"},\n )\n try:\n payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])\n username: str = payload.get(\"sub\")\n if username is None:\n raise credentials_exception\n token_data = TokenData(username=username)\n except JWTError:\n raise credentials_exception\n user =Users.search(where('name') ==token_data.username)\n if user is None:\n raise credentials_exception\n return user\n\n@router.post('/user')\nasync def create_user(name,password):\n Users.insert({'name':name,'password':bcrypt.hash(password)})\n return True\n```\n\n```text\nclass TokenData(BaseModel):\n username: Optional[str] = None\n expires: Optional[datetime]\n```\n\n```text\n@router.get('/user/me')\nasync def get_current_user(token: str = Depends(oauth2_scheme)):\n # get the current user from auth token\n\n # define credential exception\n credentials_exception = HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Could not validate credentials\",\n headers={\"WWW-Authenticate\": \"Bearer\"},\n )\n\n try:\n # decode token and extract username and expires data\n payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])\n username: str = payload.get(\"sub\")\n expires = payload.get(\"exp\")\n except JWTError:\n raise credentials_exception\n\n # validate username\n if username is None:\n raise credentials_exception\n token_data = TokenData(username=username, expires=expires)\n user = Users.search(where('name') == token_data.username)\n if user is None:\n raise credentials_exception\n\n # check token expiration\n if expires is None:\n raise credentials_exception\n if datetime.utcnow() > token_data.expires:\n raise credentials_exception\n return user\n```\n\n```text\nget_current_user\n```\n\n```text\nTokenData\n```\n\n```text\nget_current_user\n```\n\n```text\n# check token expiration\nif expires is None:\n raise credentials_exception\nif datetime.utcnow() > datetime.utcfromtimestamp(token_data.expires):\n raise credentials_exception\nreturn user\n```\n\n```py\ntry:\n # decode token and extract username and expires data\n payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])\n username: str = payload.get(\"sub\")\nexcept ExpiredSignatureError: # <---- this one\n raise HTTPException(status_code=403, detail=\"token has been expired\")\nexcept JWTError:\n raise credentials_exception\n```\n\n```text\ndef get_current_user_from_token(\n token: str = Depends(oauth2_scheme), db: Session = Depends(get_db)\n ):\n credentials_exception = lambda x : HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=x,\n )\n try:\n payload = jwt.decode(\n token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM]\n )\n username: str = payload.get(\"sub\")\n print(\"username/email extracted is \", username)\n if username is None:\n raise credentials_exception('Could not validate login or error in username/pass')\n except JWTError as e:\n raise credentials_exception(str(e))\n user = get_user(username=username, db=db)\n if user is None:\n raise credentials_exception('Could not validate login')\n return user\n```\n\n========================================\n\nComments:\n- You're not validating the expiry time of the token in `get_current_user` (which should be a function you use in `Depends`, not a view by itself); you'll have to actually check the expiry time for it to be useful. Where do you expect the expiry time to be checked otherwise? It also doesn't seem like you're checking if the user has a valid token in most of your view endpoints?\n- I still don't get how to validate the token and test its expiration date,maybe I'm still not understanding the concept very well\n- It is good to know that. You can mark the answer as accepted for the benefit of others who will have a similar problem.\n- This doesn't work, `jwt.decode` raises an `ExpiredSignatureError` if the token is expired, which is a `JWTError`. This means that the \"check expiration code\" you wrote will never be reached.\n- I think this should be the accepted answer since it is the right way to deal with the case.","metadata":{"transformedAt":"2026-08-18T18:32:29.135Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":9,"totalLines":345,"estimatedTokens":2854}}457{"id":"stack-69843204","source":"stackoverflow","questionId":69843204,"title":"how to type a variable in FastApi-SwaggerUI with hyphen in its name?","tags":["python","swagger","fastapi","pydantic","uvicorn"],"text":"Title: how to type a variable in FastApi-SwaggerUI with hyphen in its name?\nTags: python, swagger, fastapi, pydantic, uvicorn\nSource: Stack Overflow\n\nQuestion:\nIf I send a request to this API:\n\n```\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\n\napp = FastAPI()\n\nclass Response(BaseModel):\n var_name: str\n\n@app.put(\"/\", response_model=Response)\ndef simple_server(a: str):\n response = Response(var_name=a)\n return response\n```\n\nI get a response which this json file `{\"var_name1\": \"a\"}`. In addition, I get a very beautiful Swagger UI that illustrate the fields of response.\n\nMy question is, how can I get this json file `{\"var-name1\": \"a\"}` (this is with a hyphen instead of an underscore) with the same nice typing in Swagger docs?\n\nObviously, I cannot name the `var_name` attribute `var-name` in Response dataclass.\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\n\napp = FastAPI()\n\n\nclass Response(BaseModel):\n var_name: str\n\n@app.put(\"/\", response_model=Response)\ndef simple_server(a: str):\n response = Response(var_name=a)\n return response\n```\n\n```text\n{\"var_name1\": \"a\"}\n```\n\n```text\n{\"var-name1\": \"a\"}\n```\n\n```text\nvar_name\n```\n\n```text\nvar-name\n```\n\n```text\nfrom pydantic import BaseModel, Field\n\nclass Response(BaseModel):\n var_name: str = Field(alias=\"var-name\")\n\n class Config:\n allow_population_by_field_name = True\n```\n\n```text\nallow_population_by_field_name\n```\n\n========================================\n\nComments:\n- You can alias field names: pydantic-docs.helpmanual.io/usage/model_config/… so maybe `var_name: str = Field(..., alias='var-name')` does what you need?","metadata":{"transformedAt":"2026-08-18T18:32:29.135Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":7,"totalLines":81,"estimatedTokens":423}}458{"id":"stack-65599686","source":"stackoverflow","questionId":65599686,"title":"FastAPI with uvicorn getting 404 Not Found error","tags":["python","fastapi","uvicorn"],"text":"Title: FastAPI with uvicorn getting 404 Not Found error\nTags: python, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI'm trying (failing) to set up a simple FastAPI project and run it with uvicorn.\nThis is my code:\n\n```\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\napp.get('/')\n\ndef hello_world():\n return{'hello':'world'}\n\napp.get('/abc')\n\ndef abc_test():\n return{'hello':'abc'}\n```\n\nThis is what I run from the terminal:\n\n```\nPS C:\\Users\\admin\\Desktop\\Self pace study\\Python\\Dev\\day 14> uvicorn server2:app \nINFO: Started server process [3808]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\nINFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\nINFO: 127.0.0.1:60391 - \"GET / HTTP/1.1\" 404 Not Found\nINFO: 127.0.0.1:60391 - \"GET /favicon.ico HTTP/1.1\" 404 Not Found\n```\n\nAs you see, I get a 404 Not found. What could be the reason? Some network-related stuff, possibly firewall/vpn blocking this connection or something else? I'm new to this.\nThanks in advance!\n\n========================================\n\nTop Answer:\nBy now you'd probably have figured it out. In order to get MWE running, you'd use the microservice's endpoint decorators before each function definition. The following snippet should get your issue solved.\nIt assumes that you have the following structure:\n\n```\n.\n+-- main.py\n+-- static\n| +-- favicon.ico\n+-- templates\n| +-- index.html\n```\n\n```\nfrom fastapi import FastAPI\nfrom fastapi.responses import HTMLResponse, FileResponse\nfrom fastapi.staticfiles import StaticFiles\nfrom fastapi.templating import Jinja2Templates\nimport os\n\napp = FastAPI()\n\napp.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")\n\ntemplates = Jinja2Templates(directory=\"templates\")\n\n@app.get('/')\ndef hello_world():\n return{'hello':'world'}\n\n@app.get('/favicon.ico')\nasync def favicon():\n file_name = \"favicon.ico\"\n file_path = os.path.join(app.root_path, \"static\", file_name)\n return FileResponse(path=file_path, headers={\"Content-Disposition\": \"attachment; filename=\" + file_name})\n\n@app.get('/abc')\ndef abc_test():\n return{'hello':'abc'}\n```\n\nSo you'd be all set to run your first app using the FastAPI default ASGI server.\n\n`(env)$: uvicorn main:app --reload --host 0.0.0.0 --port ${PORT}`\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\napp.get('/')\n\ndef hello_world():\n return{'hello':'world'}\n\napp.get('/abc')\n\ndef abc_test():\n return{'hello':'abc'}\n```\n\n```text\nPS C:\\Users\\admin\\Desktop\\Self pace study\\Python\\Dev\\day 14> uvicorn server2:app \nINFO: Started server process [3808]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\nINFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\nINFO: 127.0.0.1:60391 - \"GET / HTTP/1.1\" 404 Not Found\nINFO: 127.0.0.1:60391 - \"GET /favicon.ico HTTP/1.1\" 404 Not Found\n```\n\n```text\n@app.get('/')\n```\n\n```bash\n.\n+-- main.py\n+-- static\n| +-- favicon.ico\n+-- templates\n| +-- index.html\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.responses import HTMLResponse, FileResponse\nfrom fastapi.staticfiles import StaticFiles\nfrom fastapi.templating import Jinja2Templates\nimport os\n\napp = FastAPI()\n\napp.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")\n\ntemplates = Jinja2Templates(directory=\"templates\")\n\n@app.get('/')\ndef hello_world():\n return{'hello':'world'}\n\n@app.get('/favicon.ico')\nasync def favicon():\n file_name = \"favicon.ico\"\n file_path = os.path.join(app.root_path, \"static\", file_name)\n return FileResponse(path=file_path, headers={\"Content-Disposition\": \"attachment; filename=\" + file_name})\n\n@app.get('/abc')\ndef abc_test():\n return{'hello':'abc'}\n```\n\n```text\n(env)$: uvicorn main:app --reload --host 0.0.0.0 --port ${PORT}\n```\n\n========================================\n\nComments:\n- You need *decorate* the router using ***`@app.get(...)`***, not just `app.get()`\n- Thanks. That was the issue.\n- Something else, so that I don't open another question - if you happen to know - I am asked every time after I restart the terminal to install fastAPI, uvicorn and pipenv again, otherwise it behaves like they don't exist....? Why would that be? Visual Studio Code, Python 3.8\n- That kind of sounds like a virtual environment issue to me, where VSCode or your terminal are not picking it up correctly. Are you using the VSCode integrated terminal? Maybe look into setting up VSCode for a python environment here. I think that should at least get you in a decent spot to do some more research, after which I think another question would be appropriate if you aren't able to find anything. Since you're using pipenv, VSCode should integrate with that nicely and see everything that you've installed via `pipenv install`.\n- Yep this is exactly how VSCode is set up to use Python (because I set it up a few weeks ago using the same guide as the link you pasted) and I use the VSCode terminal. Anyway thanks for your help mate I'll keep digging and post if I find out what the issue was. Cheers.","metadata":{"transformedAt":"2026-08-18T18:32:29.135Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":6,"totalLines":168,"estimatedTokens":1266}}459{"id":"stack-73550398","source":"stackoverflow","questionId":73550398,"title":"How to download a large file using FastAPI?","tags":["python","download","fastapi","pydantic","starlette"],"text":"Title: How to download a large file using FastAPI?\nTags: python, download, fastapi, pydantic, starlette\nSource: Stack Overflow\n\nQuestion:\nI am trying to download a large file (`.tar.gz`) from FastAPI backend. On server side, I simply validate the filepath, and I then use `Starlette.FileResponse` to return the whole file—just like what I've seen in many related questions on StackOverflow.\n\nServer side:\n\n```\nreturn FileResponse(path=file_name, media_type='application/octet-stream', filename=file_name)\n```\n\nAfter that, I get the following error:\n\n```\nFile \"/usr/local/lib/python3.10/dist-packages/fastapi/routing.py\", line 149, in serialize_response\n return jsonable_encoder(response_content)\n File \"/usr/local/lib/python3.10/dist-packages/fastapi/encoders.py\", line 130, in jsonable_encoder\n return ENCODERS_BY_TYPE[type(obj)](obj)\n File \"pydantic/json.py\", line 52, in pydantic.json.lambda\nUnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte\n```\n\nI also tried using `StreamingResponse`, but got the same error. Any other ways to do it?\n\nThe `StreamingResponse` in my code:\n\n```\n@x.post(\"/download\")\nasync def download(file_name=Body(), token: str | None = Header(default=None)):\n file_name = file_name[\"file_name\"]\n # should be something like xx.tar\n def iterfile():\n with open(file_name,\"rb\") as f:\n yield from f\n return StreamingResponse(iterfile(),media_type='application/octet-stream')\n```\n\nOk, here is an update to this problem.\nI found the error did not occur on this api, but the api doing forward request of this.\n\n```\n@(\"/\")\ndef f():\n req = requests.post(url =\"/download\")\n return req.content\n```\n\nAnd here if I returned a `StreamingResponse` with `.tar` file, it led to (maybe) encoding problems.\n\nWhen using requests, remember to set the same media-type. Here is `media_type='application/octet-stream'`. And it works!\n\n========================================\n\nTop Answer:\nI would use `app.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")` to mount a static folder, and put this big file into this folder, so user can have the link to this big file to download directly.\n\nIn this way, you don't need code to read the file and feed the file to the user.\n\n========================================\n\nCode:\n```py\nreturn FileResponse(path=file_name, media_type='application/octet-stream', filename=file_name)\n```\n\n```text\nFile \"/usr/local/lib/python3.10/dist-packages/fastapi/routing.py\", line 149, in serialize_response\n return jsonable_encoder(response_content)\n File \"/usr/local/lib/python3.10/dist-packages/fastapi/encoders.py\", line 130, in jsonable_encoder\n return ENCODERS_BY_TYPE[type(obj)](obj)\n File \"pydantic/json.py\", line 52, in pydantic.json.lambda\nUnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte\n```\n\n```py\n@x.post(\"/download\")\nasync def download(file_name=Body(), token: str | None = Header(default=None)):\n file_name = file_name[\"file_name\"]\n # should be something like xx.tar\n def iterfile():\n with open(file_name,\"rb\") as f:\n yield from f\n return StreamingResponse(iterfile(),media_type='application/octet-stream')\n```\n\n```py\n@(\"/\")\ndef f():\n req = requests.post(url =\"/download\")\n return req.content\n```\n\n```text\n.tar.gz\n```\n\n```text\nStarlette.FileResponse\n```\n\n```text\nStreamingResponse\n```\n\n```text\nStreamingResponse\n```\n\n```text\nStreamingResponse\n```\n\n```text\n.tar\n```\n\n```text\nmedia_type='application/octet-stream'\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.responses import StreamingResponse\n\nsome_file_path = 'large-video-file.mp4'\napp = FastAPI()\n\n@app.get('/')\ndef main():\n def iterfile():\n with open(some_file_path, mode='rb') as f:\n yield from f\n\n return StreamingResponse(iterfile(), media_type='video/mp4')\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.responses import StreamingResponse\n\nCHUNK_SIZE = 1024 * 1024 # = 1MB - adjust the chunk size as desired\nsome_file_path = 'large_file.tar'\napp = FastAPI()\n\n@app.get('/')\ndef main():\n def iterfile():\n with open(some_file_path, 'rb') as f:\n while chunk := f.read(CHUNK_SIZE):\n yield chunk\n\n headers = {'Content-Disposition': 'attachment; filename=\"large_file.tar\"'}\n return StreamingResponse(iterfile(), headers=headers, media_type='application/x-tar')\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.responses import StreamingResponse\nimport aiofiles\n\nCHUNK_SIZE = 1024 * 1024 # = 1MB - adjust the chunk size as desired\nsome_file_path = 'large_file.tar'\napp = FastAPI()\n\n@app.get('/')\nasync def main():\n async def iterfile():\n async with aiofiles.open(some_file_path, 'rb') as f:\n while chunk := await f.read(CHUNK_SIZE):\n yield chunk\n\n headers = {'Content-Disposition': 'attachment; filename=\"large_file.tar\"'}\n return StreamingResponse(iterfile(), headers=headers, media_type='application/x-tar')\n```\n\n```text\nyield from f\n```\n\n```text\nStreamingResponse\n```\n\n```text\nStreamingResponse\n```\n\n```text\nasync\n```\n\n```text\nopen()\n```\n\n```text\nasync\n```\n\n```text\nawait\n```\n\n```text\ndef\n```\n\n```text\niterate_in_threadpool\n```\n\n```text\nContent-Disposition\n```\n\n```text\ninline\n```\n\n```text\n.mp4\n```\n\n```text\n.mp3\n```\n\n```text\nattachment\n```\n\n```text\nfilename\n```\n\n```text\nmedia_type\n```\n\n```text\ntext/plain\n```\n\n```text\napplication/octet-stream\n```\n\n```text\n.tar\n```\n\n```text\noctet-stream\n```\n\n```text\nx-tar\n```\n\n```text\napplication/octet-stream\n```\n\n```text\nasync\n```\n\n```text\naiofiles\n```\n\n```text\napp.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")\n```\n\n========================================\n\nComments:\n- Does this answer your question? How to make a large file accessible to external APIs?\n- I checked this answer and used StreamingResponse. Since the file type varies, I did not set a specific media_type. The code is just like `return StreamingResponse(iterfile())` And I still got error: `No json object could be decoded` when downloading tar file\n- Did you try setting `media_type='application/octet-stream'` for the StreamingResponse to indicate that it's binary data? Do you have the example code that fails?\n- That is just something I put in the data body. The actual name is the abosolute file path ,like /opt/123.tar. I tried with some other files like syslog or json files and they worked.\n- In `yield from f` I found this could use a large amount of CPU. How can I solve it? Maybe the reason is that chunk size is small and lead to massive file operation? Can I increase the chunk size here?","metadata":{"transformedAt":"2026-08-18T18:32:29.135Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":39,"totalLines":285,"estimatedTokens":1647}}460{"id":"stack-72214347","source":"stackoverflow","questionId":72214347,"title":"How to document default None/null in OpenAPI/Swagger using FastAPI?","tags":["python","swagger","fastapi","openapi","pydantic"],"text":"Title: How to document default None/null in OpenAPI/Swagger using FastAPI?\nTags: python, swagger, fastapi, openapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nUsing a ORM, I want to do a POST request letting some fields with a `null` value, which will be translated in the database for the default value specified there.\n\nThe problem is that OpenAPI (Swagger) **docs**, ignores the default `None` and still prompts a `UUID` by default.\n\n```\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\nfrom typing import Optional\nfrom uuid import UUID\nimport uvicorn\n\nclass Table(BaseModel):\n # ID: Optional[UUID] # the docs show a example UUID, ok\n ID: Optional[UUID] = None # the docs still shows a uuid, when it should show a null or valid None value.\n\napp = FastAPI() \n \n@app.post(\"/table/\", response_model=Table)\ndef create_table(table: Table):\n # here we call to sqlalchey orm etc.\n return 'nothing important, the important thing is in the docs'\n \nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n```\n\nIn the OpenAPI schema example (request body) which is at the **docs** we find:\n\n```\n{\n \"ID\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\"\n}\n```\n\nThis is not ok, because I specified that the default value is `None`,so I expected this instead:\n\n```\n{\n \"ID\": null, # null is the equivalent of None here\n}\n```\n\nWhich will pass a `null` to the `ID` and finally will be parsed in the db to the default value (that is a new generated `UUID`).\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\nfrom typing import Optional\nfrom uuid import UUID\nimport uvicorn\n\n\nclass Table(BaseModel):\n # ID: Optional[UUID] # the docs show a example UUID, ok\n ID: Optional[UUID] = None # the docs still shows a uuid, when it should show a null or valid None value.\n\napp = FastAPI() \n \n@app.post(\"/table/\", response_model=Table)\ndef create_table(table: Table):\n # here we call to sqlalchey orm etc.\n return 'nothing important, the important thing is in the docs'\n \nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n```\n\n```text\n{\n \"ID\": \"3fa85f64-5717-4562-b3fc-2c963f66afa6\"\n}\n```\n\n```text\n{\n \"ID\": null, # null is the equivalent of None here\n}\n```\n\n```text\nnull\n```\n\n```text\nNone\n```\n\n```text\nUUID\n```\n\n```text\nNone\n```\n\n```text\nnull\n```\n\n```text\nID\n```\n\n```text\nUUID\n```\n\n```py\nclass Table(BaseModel):\n ID: Optional[UUID] = None\n \n class Config:\n schema_extra = {\n \"example\": {\n }\n }\n\n@app.post(\"/table/\", response_model=Table)\ndef create_table(table: Table):\n return table\n```\n\n```py\nclass Table(BaseModel):\n ID: Optional[UUID] = None\n some_attr: str\n \n class Config:\n schema_extra = {\n \"example\": {\n \"some_attr\": \"Foo\"\n }\n }\n```\n\n```py\nclass Table(BaseModel):\n ID: Optional[UUID] = None\n some_attr: str\n some_attr2: float\n some_attr3: bool\n \n class Config:\n @staticmethod\n def schema_extra(schema: Dict[str, Any], model: Type['Table']) -> None:\n del schema.get('properties')['ID']\n```\n\n```text\n= None\n```\n\n```text\n= Query(default=None)\n```\n\n```text\nOptional\n```\n\n```text\nnull\n```\n\n```text\nNone\n```\n\n```text\nNone\n```\n\n```text\nNone\n```\n\n```text\nexample\n```\n\n```text\nConfig\n```\n\n```text\nschema_extra\n```\n\n```text\n{}\n```\n\n```text\nID\n```\n\n```text\nTable\n```\n\n```text\nexample\n```\n\n```text\nID\n```\n\n```text\nID\n```\n\n```text\nexample\n```\n\n```text\nField()\n```\n\n```text\nsome_attr: str = Field(example=\"Foo\")\n```\n\n```text\nID: Optional[UUID] = None\n```\n\n```text\nID: UUID = None\n```\n\n```text\nOptional[str]\n```\n\n```text\nUnion[str, None]\n```\n\n```text\nID: Union[UUID, None] = None\n```\n\n```text\nID: Optional[UUID] = None\n```\n\n```text\nID: UUID = None\n```\n\n```text\nID: UUID| None = None\n```\n\n```text\nInfo\n```\n\n```text\nNone\n```\n\n```text\nUnion[str, None]\n```\n\n========================================\n\nComments:\n- Why do you have `ID: UUID` defaulted to the string `'null'`? Shouldn't it be `None`?\n- @npk, yes you are right, and UUID should be Optional[UUID] but that will produce in the docs a UUID not a null, basically is exactly that what I need to change to get a null in the docs.\n- You want your users to explicitly post null for ID in the request body? Or you just want the example in the generated docs to be different?\n- @JarroVGIT The second, with Optional[UUID] they can already specify the uuid if they want or putting null, but I want null to be the default value and the one documented as in most of cases you won't generate the uuid by yourself.\n- Basically for the documentation ID: Optional[UUID] = None is the same as ID: Optional[UUID]. I think in one case it should write null and in the other a example UUID\n- I thought I had a pretty good handle on FastAPI, but this got me stumped. I tried everything I could think of, but none of them resulted in an example with a value of 'null' without quotations. I am sorry I wasn't able to help, but wanted to let you know either way because chances are; it can't be done. Might be a good idea to open an issue on Github? Please tag me there, I am very curious if this can be done. :)\n- @JarroVGIT, I just posted it there and tag you: github.com/tiangolo/fastapi/issues/…\n- I just want to add to this answer, that it is possible to make the `null` type required via Pydantic, in which case it would be a willingness to put `null` or `UID` in a concrete way. Of course, this does not affect the display of the example value, since swagger does not handle the `null` type. To make the `null` required : `Optional[UUID] = Field(...)` or `Optional[UUID] = ...`\n- This is indeed useful to know, thanks! but it doesn't quite solve the problem. If i use this solution I would need to write all the additional fields by hand in all the classes excluding the ID field.\n- My question explicitly asked how to document using the non quoted \"null\" because it still shows that you can use that field, even if it is an optional one. But if you can just skip documenting the ID would be OK for me, as long as I don't need to hardcode all other fields in the schema_extra.\n- @Chris, thanks! that works, it is pity that is not possible to document the null thought, but your answer is an OK alternative solution.\n- Adding to this in 2024 - in Pydantic V2 setting a default for Optional values is mandatory or you have to replace Optional with a Union with \"NoneType\".... (During the migration to V2 all my Optional code broke....)","metadata":{"transformedAt":"2026-08-18T18:32:29.135Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":43,"totalLines":291,"estimatedTokens":1633}}461{"id":"stack-75333446","source":"stackoverflow","questionId":75333446,"title":"FastAPI create a generic response model that would suit requirements","tags":["python","rest","fastapi"],"text":"Title: FastAPI create a generic response model that would suit requirements\nTags: python, rest, fastapi\nSource: Stack Overflow\n\nQuestion:\nI've been working with FastAPI for some time, it's a great framework.\nHowever real life scenarios can be surprising, sometimes a non-standard approach is necessary. There's a one case I'd like to ask your help with.\n\nThere's a strange external requirement that a model response should be formatted as stated in example:\n\n**Desired behavior:**\n\n`GET /object/1`\n\n```\n{status: ‘success’, data: {object: {id:‘1’, category: ‘test’ …}}}\n```\n\n`GET /objects`\n\n```\n{status: ‘success’, data: {objects: [...]}}}\n```\n\n**Current behavior:**\n\nGET `/object/1` would respond:\n\n```\n{id: 1,field1:\"content\",... }\n```\n\nGET `/objects/` would send a List of Object e.g.,:\n\n```\n{\n [\n {id: 1,field1:\"content\",... },\n {id: 1,field1:\"content\",... },\n ...\n ]\n}\n```\n\n*You can substitute 'object' by any class, it's just for description purposes.*\n\n**How to write a generic response model that will suit those reqs?**\n\nI know I can produce response model that would contain `status:str` and (depending on class) data structure e.g `ticket:Ticket` or `tickets:List[Ticket]`.\n\n**The point is there's a number of classes so I hope there's a more pythonic way to do it.**\n\n**Thanks for help.**\n\n========================================\n\nCode:\n```text\n{status: ‘success’, data: {object: {id:‘1’, category: ‘test’ …}}}\n```\n\n```text\n{status: ‘success’, data: {objects: [...]}}}\n```\n\n```text\n{id: 1,field1:\"content\",... }\n```\n\n```text\n{\n [\n {id: 1,field1:\"content\",... },\n {id: 1,field1:\"content\",... },\n ...\n ]\n}\n```\n\n```text\nGET /object/1\n```\n\n```text\nGET /objects\n```\n\n```text\n/object/1\n```\n\n```text\n/objects/\n```\n\n```text\nstatus:str\n```\n\n```text\nticket:Ticket\n```\n\n```text\ntickets:List[Ticket]\n```\n\n```json\n{\n \"status\": \"...\",\n \"data\": {\n \"object\": {...} # type variable\n }\n}\n```\n\n```py\nfrom typing import Generic, TypeVar\nfrom pydantic import BaseModel\nfrom pydantic.generics import GenericModel\n\nM = TypeVar(\"M\", bound=BaseModel)\n\n\nclass GenericSingleObject(GenericModel, Generic[M]):\n object: M\n\n\nclass GenericMultipleObjects(GenericModel, Generic[M]):\n objects: list[M]\n\n\nclass BaseGenericResponse(GenericModel):\n status: str\n\n\nclass GenericSingleResponse(BaseGenericResponse, Generic[M]):\n data: GenericSingleObject[M]\n\n\nclass GenericMultipleResponse(BaseGenericResponse, Generic[M]):\n data: GenericMultipleObjects[M]\n\n\nclass Foo(BaseModel):\n a: str\n b: int\n\n\nclass Bar(BaseModel):\n x: float\n```\n\n```json\n{\n \"title\": \"GenericSingleResponse[Foo]\",\n \"type\": \"object\",\n \"properties\": {\n \"status\": {\n \"title\": \"Status\",\n \"type\": \"string\"\n },\n \"data\": {\n \"$ref\": \"#/definitions/GenericSingleObject_Foo_\"\n }\n },\n \"required\": [\n \"status\",\n \"data\"\n ],\n \"definitions\": {\n \"Foo\": {\n \"title\": \"Foo\",\n \"type\": \"object\",\n \"properties\": {\n \"a\": {\n \"title\": \"A\",\n \"type\": \"string\"\n },\n \"b\": {\n \"title\": \"B\",\n \"type\": \"integer\"\n }\n },\n \"required\": [\n \"a\",\n \"b\"\n ]\n },\n \"GenericSingleObject_Foo_\": {\n \"title\": \"GenericSingleObject[Foo]\",\n \"type\": \"object\",\n \"properties\": {\n \"object\": {\n \"$ref\": \"#/definitions/Foo\"\n }\n },\n \"required\": [\n \"object\"\n ]\n }\n }\n}\n```\n\n```py\nfrom fastapi import FastAPI\n\n\napp = FastAPI()\n\n\n@app.get(\"/foo/\", response_model=GenericSingleResponse[Foo])\nasync def get_one_foo() -> dict[str, object]:\n return {\"status\": \"foo\", \"data\": {\"object\": {\"a\": \"spam\", \"b\": 123}}}\n```\n\n```json\n{\n \"status\": \"foo\",\n \"data\": {\n \"object\": {\n \"a\": \"spam\",\n \"b\": 123\n }\n }\n}\n```\n\n```py\nfrom typing import Any, Generic, Optional, TypeVar\nfrom pydantic import BaseModel, create_model\nfrom pydantic.generics import GenericModel\n\nM = TypeVar(\"M\", bound=BaseModel)\n\n\ndef create_data_model(\n model: type[BaseModel],\n plural: bool = False,\n custom_plural_name: Optional[str] = None,\n **kwargs: Any,\n) -> type[BaseModel]:\n data_field_name = model.__name__.lower()\n if plural:\n model_name = f\"Multiple{model.__name__}\"\n if custom_plural_name:\n data_field_name = custom_plural_name\n else:\n data_field_name += \"s\"\n kwargs[data_field_name] = (list[model], ...) # type: ignore[valid-type]\n else:\n model_name = f\"Single{model.__name__}\"\n kwargs[data_field_name] = (model, ...)\n return create_model(model_name, **kwargs)\n\n\nclass GenericResponse(GenericModel, Generic[M]):\n status: str\n data: M\n```\n\n```py\nclass Foo(BaseModel):\n a: str\n b: int\n\n\nclass Bar(BaseModel):\n x: float\n\n\nSingleFoo = create_data_model(Foo)\nMultipleBar = create_data_model(Bar, plural=True)\n```\n\n```py\nfrom fastapi import FastAPI\n\n\napp = FastAPI()\n\n\n@app.get(\"/foo/\", response_model=GenericResponse[SingleFoo]) # type: ignore[valid-type]\nasync def get_one_foo() -> dict[str, object]:\n return {\"status\": \"foo\", \"data\": {\"foo\": {\"a\": \"spam\", \"b\": 123}}}\n\n\n@app.get(\"/bars/\", response_model=GenericResponse[MultipleBar]) # type: ignore[valid-type]\nasync def get_multiple_bars() -> dict[str, object]:\n return {\"status\": \"bars\", \"data\": {\"bars\": [{\"x\": 3.14}, {\"x\": 0}]}}\n```\n\n```text\nobject\n```\n\n```text\nGenericModel\n```\n\n```text\nGenericSingleObject\n```\n\n```text\ndata\n```\n\n```text\nGenericSingleResponse\n```\n\n```text\nM\n```\n\n```text\nGenericSingleObject\n```\n\n```text\ndata\n```\n\n```text\nGenericSingleResponse[Foo]\n```\n\n```text\nGenericSingleResponse[Foo]\n```\n\n```text\npydantic.create_model\n```\n\n```text\ndata\n```\n\n```text\nGenericResponse\n```\n\n```text\nFoo\n```\n\n```text\nBar\n```\n\n========================================\n\nComments:\n- How much of the structure of the response do you want to avoid leaking into the implementation? i.e. are you happy with returning something like `{'data': {'objects': ...}}` from your endpoint as long as the response model is properly document, or do you want to automagically wrap returning a list inside the `objects` property? (i.e. do you want to do the wrapping automagically from what the API returns today by changing the response model?)\n- Well the thing is to make it generic in the way it would \"automagically\" detect what is the class, its type and produce the required response. Actually I'm thinking maybe adding a middleware to modify original api response would be a good idea.\n- I'm guessing you also want that change reflected in the OpenAPI documentation? (i.e. FastAPI actually has to know about the expected change, and not just transform it in a middleware)\n- To be clear, the `object` key is actually supposed to be something different for every endpoint? Meaning the `data` key in the response for `/object/1` should map to `{\"object\": ...}`, but for `/foo/1` it should map to `{\"foo\": ...}`? That would be a strange requirement because (for one thing) the plural is impossible to encode in some generic way. But I just want to clarify. Or will it always be `{\"object\": {...}}` and `{\"objects\": [...]}`?\n- Because making the response model generic to \"detect\" the class used is not the issue. That can be done. The problem is, if you want to somehow automatically set the attribute/field name (instead of `object`).\n- Thanks for the exhausting answer and time you spent for typing samples. I've used the `create_model` approach, despite is less self-explanatory :)","metadata":{"transformedAt":"2026-08-18T18:32:29.135Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":34,"totalLines":362,"estimatedTokens":1937}}462{"id":"stack-78132353","source":"stackoverflow","questionId":78132353,"title":"Pytest- How to remove created data after each test function","tags":["python","sqlalchemy","pytest","fastapi"],"text":"Title: Pytest- How to remove created data after each test function\nTags: python, sqlalchemy, pytest, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have a FastAPI + SQLAlchemy project and I'm using Pytest for writing unit tests for the APIs.\n\nIn each test function, I create some data in some tables (user table, post table, comment table, etc) using SQLAlchemy. These created data in each test function will remain in the tables after test function finished and will affect on other test functions.\n\nFor example, in the first test function I create 3 posts, and 2 users, then in the second test functions, these 3 posts and 2 users remained on the tables and makes my test expectations wrong.\n\nFollowing is my fixture for pytest:\n\n```\n@pytest.fixture\ndef session(engine):\n Session = sessionmaker(bind=engine)\n session = Session()\n yield session\n session.rollback() # Removes data created in each test method\n session.close() # Close the session after each test\n```\n\nI used `session.rollback()` to remove all created data during session, but it doesn't remove data.\n\nAnd the following is my test functions:\n\n```\nclass TestAllPosts(PostBaseTestCase):\n\n def create_logged_in_user(self, db):\n user = self.create_user(db)\n return user.generate_tokens()[\"access\"]\n\n def test_can_api_return_all_posts_without_query_parameters(self, client, session):\n posts_count = 5\n user_token = self.create_logged_in_user(session)\n for i in range(posts_count):\n self.create_post(session)\n\n response = client.get(url, headers={\"Authorization\": f\"Bearer {user_token}\"})\n assert response.status_code == 200\n json_response = response.json()\n assert len(json_response) == posts_count\n\n def test_can_api_detect_there_is_no_post(self, client, session):\n user_token = self.create_logged_in_user(session)\n response = client.get(url, headers={\"Authorization\": f\"Bearer {user_token}\"})\n assert response.status_code == 404\n```\n\nIn the latest test function, instead of getting 404, I get 200 with 5 posts (from the last test function)\n\nHow can I remove the created data in each test function after test function finished?\n\n========================================\n\nTop Answer:\nAfter you commit a transaction you can't rollback to the state before the commit.\nAccording to Durability in ACID principles once you commit a transaction the rollback won't affect the committed data:\nhttps://dba.stackexchange.com/questions/188653/rollback-after-commit\n\nSo you should delete those records manually.\n\nEdit:\n\nYou can use truncate statement which removes all the records in a table:\nhttps://dev.mysql.com/doc/refman/8.3/en/truncate-table.html\n\nNote: Consider truncating tables which there is no reference to their Primary key to avoid inconsistency errors.\n\nHere's an example of truncating using SqlAlchemy:\nhttps://stackoverflow.com/a/42097818/12961420\n\n========================================\n\nCode:\n```text\n@pytest.fixture\ndef session(engine):\n Session = sessionmaker(bind=engine)\n session = Session()\n yield session\n session.rollback() # Removes data created in each test method\n session.close() # Close the session after each test\n```\n\n```text\nclass TestAllPosts(PostBaseTestCase):\n\n def create_logged_in_user(self, db):\n user = self.create_user(db)\n return user.generate_tokens()[\"access\"]\n\n def test_can_api_return_all_posts_without_query_parameters(self, client, session):\n posts_count = 5\n user_token = self.create_logged_in_user(session)\n for i in range(posts_count):\n self.create_post(session)\n\n response = client.get(url, headers={\"Authorization\": f\"Bearer {user_token}\"})\n assert response.status_code == 200\n json_response = response.json()\n assert len(json_response) == posts_count\n\n def test_can_api_detect_there_is_no_post(self, client, session):\n user_token = self.create_logged_in_user(session)\n response = client.get(url, headers={\"Authorization\": f\"Bearer {user_token}\"})\n assert response.status_code == 404\n```\n\n```text\nsession.rollback()\n```\n\n```py\n@pytest.fixture\ndef session(engine):\n Session = sessionmaker(bind=engine)\n session = Session()\n yield session\n\n # Remove any data from database (even data not created by this session)\n with contextlib.closing(engine.connect()) as connection:\n transaction = connection.begin()\n connection.execute(f'TRUNCATE TABLE {\",\".join(table.name for table in reversed(Base.metadata.sorted_tables)} RESTART IDENTITY CASCADE;'))\n transaction.commit()\n\n session.rollback() # Removes data created in each test method\n session.close() # Close the session after each test\n```\n\n```py\ndef override_get_db():\n try:\n db = TestingSessionLocal()\n yield db\n finally:\n db.close()\n\n\napp.dependency_overrides[get_db] = override_get_db\n```\n\n```text\nclient.get\n```\n\n```text\n\"function\"\n```\n\n```text\nwith sesison.begin()\n```\n\n```text\nwith\n```\n\n```text\nsession.begin()\n```\n\n```text\nimport pytest\nfrom sqlalchemy import text\nfrom sqlalchemy.orm import Session\n\nfrom models import user, post\n\n\n@pytest.fixture()\ndef clean_db(session: Session):\n tables = [user.__tablename__, post.__tablename__]\n for table in tables:\n session.execute(text(f'TRUNCATE TABLE {table}'))\n session.commit()\n```\n\n```text\nimport pytest\n\n@pytest.mark.usefixtures(\"clean_db\", autouse=True)\nclass TestAllPosts(PostBaseTestCase):\n\n...\n```\n\n========================================\n\nComments:\n- doc said the rollback method only rolls back in-progress transactions. You need to re-think your test roll back strategy.\n- @HaiVu Is there a better solution? I need to remove all created rows (in all tables) during the test function. (The same as Django does in its test framework)\n- I am sorry, I don't have a solution for this.\n- It's not a scalable approach to remove them manually. I need an automated approach to remove all created rows In all tables after test function finished\n- This might help: gist.github.com/absent1706/3ccc1722ea3ca23a5cf54821dbc813fb\n- Here's another example: dev.to/whchi/…\n- Thanks for your answer. Without commit, can data be inserted (or updated) in the database? I commented all `session.commit()` calls in my tests, but all of them now return 404.\n- @msln Without commit, the changes (insert/update) are not persisted in the database. Which means other connections(or transactions - depending on the isolation level) won't be able to see them, but the current session which have opened the transaction can see the changes. So if you need to query and get the newly inserted data, you need to pass the session object that started the transaction.\n- I don't think there is a way to pass session from the test function to the API function. So, I think I have reached a dead end!\n- @msln Yes in that situation you're out of luck with the first solution.\n- You're right. The problem was my session in API and in tests is not the same. Thanks\n- With #1, you can still have race conditions, e.g. a second session starts before fixture from the first session has cleaned the data. The only real solution is isolation. This can be at the DB level (like a temp, per session, local DB), table level (e.g. a fixture to create a table with unique name), or even at the record level (e.g. the session fixture tracks it's own data, asserts only on own data, and cleans up only own data). I personally prefer DB level, as it forces me to create some code to create and bootstrap the test DB, which helps in the long run.\n- @ThomasD Can you give me some useful links? I don't know anything about database-level isolation and how can I use them. thanks\n- @ThomasD thanks for pointing out the race condition! I am aware that `COMMIT` can be asynchronous and return response even before all changes were fully applied. However, `TRUNCATE` should have an `ACCESS EXCLUSIVE` lock, so it shouldn't happen that data will leak between tests (and I've never seen it happen when using pattern either). Although, you do have to look out for tests that spawn threads, or any other form of background workers, which are not automatically cleaned up and can still write data to the database after the `TRUNCATE` was committed (and therefore leak data between tests).","metadata":{"transformedAt":"2026-08-18T18:32:29.135Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":12,"totalLines":206,"estimatedTokens":2062}}463{"id":"stack-67023417","source":"stackoverflow","questionId":67023417,"title":"AttributeError: 'Blog' object has no attribute 'items' - FastAPI","tags":["python","python-3.x","sqlalchemy","fastapi"],"text":"Title: AttributeError: 'Blog' object has no attribute 'items' - FastAPI\nTags: python, python-3.x, sqlalchemy, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to update a single record in the database by using the PUT operation in FastAPI. But for some reason, I keep getting this error. All other operations work fine except this one. The error is only raised for the update query.\n\n```\nAttributeError: 'Blog' object has no attribute 'items'\n```\n\nHere is the relevant code.\n\n```\ndef get_db():\n db = SessionLocal()\n try:\n yield db\n finally:\n db.close()\n\nclass Blog(BaseModel):\n title: str\n body: str\n\n@app.put('/blog/{id}', status_code=status.HTTP_204_NO_CONTENT, response_class=Response)\ndef update(id: int, request: schemas.Blog, db: Session = Depends(get_db)):\n blog = db.query(models.Blog).filter(models.Blog.id == id)\n if not blog.first():\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,\n detail=f'Blog with id {id} not found')\n blog.update(request)\n db.commit()\n```\n\nThis is the StackTrace:\n\n```\nTraceback (most recent call last):\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\uvicorn\\protocols\\http\\h11_impl.py\", line 396, in run_asgi \n result = await app(self.scope, self.receive, self.send)\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\uvicorn\\middleware\\proxy_headers.py\", line 45, in __call__ \n return await self.app(scope, receive, send)\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\fastapi\\applications.py\", line 199, in __call__\n await super().__call__(scope, receive, send)\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\starlette\\applications.py\", line 111, in __call__\n await self.middleware_stack(scope, receive, send)\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\starlette\\middleware\\errors.py\", line 181, in __call__\n raise exc from None\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\starlette\\middleware\\errors.py\", line 159, in __call__\n await self.app(scope, receive, _send)\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\starlette\\exceptions.py\", line 82, in __call__\n raise exc from None\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\starlette\\exceptions.py\", line 71, in __call__\n await self.app(scope, receive, sender)\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\starlette\\routing.py\", line 566, in __call__\n await route.handle(scope, receive, send)\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\starlette\\routing.py\", line 227, in handle\n await self.app(scope, receive, send)\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\starlette\\routing.py\", line 41, in app\n response = await func(request)\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\fastapi\\routing.py\", line 201, in app\n raw_response = await run_endpoint_function(\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\fastapi\\routing.py\", line 150, in run_endpoint_function\n return await run_in_threadpool(dependant.call, **values)\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\starlette\\concurrency.py\", line 34, in run_in_threadpool\n return await loop.run_in_executor(None, func, *args)\n File \"C:\\Python39\\lib\\concurrent\\futures\\thread.py\", line 52, in run\n result = self.fn(*self.args, **self.kwargs)\n File \".\\blog\\main.py\", line 66, in update\n blog.update(request)\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\sqlalchemy\\orm\\query.py\", line 3190, in update\n upd = upd.values(values)\n File \"\", line 2, in values\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\sqlalchemy\\sql\\base.py\", line 96, in _generative\n x = fn(self, *args, **kw)\n File \"\", line 2, in values\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\sqlalchemy\\sql\\base.py\", line 125, in check\n return fn(self, *args, **kw)\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\sqlalchemy\\sql\\dml.py\", line 701, in values\n for k, v in arg.items()\nAttributeError: 'Blog' object has no attribute 'items'\n```\n\n========================================\n\nTop Answer:\nI was also challenged with the same problem. However, I realized after printing the request, that exhibits:\n\n\"`title='strinaaaaaag' body='asasa'`\"\n\nTherefore to solve this issue, just convert your 'request' to the dictionary type:\n\n`dict(request)`\n\n========================================\n\nCode:\n```text\nAttributeError: 'Blog' object has no attribute 'items'\n```\n\n```text\ndef get_db():\n db = SessionLocal()\n try:\n yield db\n finally:\n db.close()\n\nclass Blog(BaseModel):\n title: str\n body: str\n\n@app.put('/blog/{id}', status_code=status.HTTP_204_NO_CONTENT, response_class=Response)\ndef update(id: int, request: schemas.Blog, db: Session = Depends(get_db)):\n blog = db.query(models.Blog).filter(models.Blog.id == id)\n if not blog.first():\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,\n detail=f'Blog with id {id} not found')\n blog.update(request)\n db.commit()\n```\n\n```text\nTraceback (most recent call last):\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\uvicorn\\protocols\\http\\h11_impl.py\", line 396, in run_asgi \n result = await app(self.scope, self.receive, self.send)\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\uvicorn\\middleware\\proxy_headers.py\", line 45, in __call__ \n return await self.app(scope, receive, send)\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\fastapi\\applications.py\", line 199, in __call__\n await super().__call__(scope, receive, send)\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\starlette\\applications.py\", line 111, in __call__\n await self.middleware_stack(scope, receive, send)\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\starlette\\middleware\\errors.py\", line 181, in __call__\n raise exc from None\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\starlette\\middleware\\errors.py\", line 159, in __call__\n await self.app(scope, receive, _send)\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\starlette\\exceptions.py\", line 82, in __call__\n raise exc from None\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\starlette\\exceptions.py\", line 71, in __call__\n await self.app(scope, receive, sender)\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\starlette\\routing.py\", line 566, in __call__\n await route.handle(scope, receive, send)\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\starlette\\routing.py\", line 227, in handle\n await self.app(scope, receive, send)\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\starlette\\routing.py\", line 41, in app\n response = await func(request)\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\fastapi\\routing.py\", line 201, in app\n raw_response = await run_endpoint_function(\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\fastapi\\routing.py\", line 150, in run_endpoint_function\n return await run_in_threadpool(dependant.call, **values)\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\starlette\\concurrency.py\", line 34, in run_in_threadpool\n return await loop.run_in_executor(None, func, *args)\n File \"C:\\Python39\\lib\\concurrent\\futures\\thread.py\", line 52, in run\n result = self.fn(*self.args, **self.kwargs)\n File \".\\blog\\main.py\", line 66, in update\n blog.update(request)\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\sqlalchemy\\orm\\query.py\", line 3190, in update\n upd = upd.values(values)\n File \"<string>\", line 2, in values\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\sqlalchemy\\sql\\base.py\", line 96, in _generative\n x = fn(self, *args, **kw)\n File \"<string>\", line 2, in values\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\sqlalchemy\\sql\\base.py\", line 125, in check\n return fn(self, *args, **kw)\n File \"c:\\dev\\fast-tuts\\env\\lib\\site-packages\\sqlalchemy\\sql\\dml.py\", line 701, in values\n for k, v in arg.items()\nAttributeError: 'Blog' object has no attribute 'items'\n```\n\n```text\nblog.update({'title': request.title, 'body': request.body})\n```\n\n```text\nblog.update(request.dict())\n```\n\n```text\n@app.put(\"/blog/update/{id}\")\ndef updateBlog(id, request:schemas.Blog, db:Session=Depends(get_db)):\n blog= db.query(model.Blog).filter(model.Blog.id == id).first()\n \n if not blog:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,detail=f'blog with id {id} not found')\n else:\n db.query(model.Blog).filter(model.Blog.id == id).update(request.dict())\n\ndb.commit()\ndb.refresh(blog)\nreturn blog\n```\n\n```text\n<class 'blog.schemas.Blog'>\n```\n\n```text\ntitle='strinaaaaaag' body='asasa'\n```\n\n```text\ndict(request)\n```\n\n```text\nfrom pydantic import BaseModel\nfrom typing import Optional\n\nclass Blog(BaseModel):\n title: str\n body: str\n\nclass UpdateBlog(BaseModel):\n title: Optional[str]\n body: Optional[str]\n```\n\n```text\n# Update Blog\n@app.put('/blog/{id}', status_code=status.HTTP_202_ACCEPTED)\ndef update(id, request_body: UpdateBlog, db: Session = Depends(get_db)):\n blog = db.query(models.Blog).filter(models.Blog.id == id).first()\n\n if not blog:\n content={'success': False, 'message': f\"Blog with id {id} don't exists\"}\n return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, content=content)\n \n # exclude_none=True will only update the field which you want to update\n # If you don't want to update \"body\" then only pass the \"title\" and \"body\" field will stay as it is\n db.query(models.Blog).filter(models.Blog.id == id).update(request_body.dict(exclude_none=True))\n db.commit()\n\n content={'success': True, 'message': f\"Blog with id {id} Updated\"}\n return JSONResponse(status_code=status.HTTP_200_OK, content=content)\n```\n\n```text\nschemas.py\n```\n\n```text\nschemas.py\n```\n\n```text\nmain.py\n```\n\n```text\ndef updateblog (id:int, title:Optional[str]=None, body:Optional[str]=None, db:Session = Depends(get_db)):\n\n if title!=None:\n db.query(models.Blog).filter(models.Blog.id==id).update({'title':title})\n \n if body!=None:\n db.query(models.Blog).filter(models.Blog.id==id).update({'body':body})\n\n db.commit()\n \n return f'Blog #{id} has been updated.'\n```\n\n```text\nThe method \"dict\" in class \"BaseModel\" is deprecated The `dict` method is deprecated; use `model_dump` instead.Pylance\n```\n\n```text\nqueried_blog.update(blog.model_dump())\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.136Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":17,"totalLines":271,"estimatedTokens":2501}}464{"id":"stack-74508774","source":"stackoverflow","questionId":74508774,"title":"What's the difference between FastAPI background tasks and Celery tasks?","tags":["python","celery","scheduled-tasks","fastapi","background-task"],"text":"Title: What's the difference between FastAPI background tasks and Celery tasks?\nTags: python, celery, scheduled-tasks, fastapi, background-task\nSource: Stack Overflow\n\nQuestion:\nRecently I read something about this and the point was that celery is more productive.\n\nNow, I can't find detailed information about the difference between these two and what should be the best way to use them.\n\n========================================\n\nCode:\n```text\nBackgroundTasks\n```\n\n========================================\n\nComments:\n- An article on this here: medium.com/@hitorunajp/celery-and-background-tasks-aebb234ca‌​e5d","metadata":{"transformedAt":"2026-08-18T18:32:29.136Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":1,"totalLines":20,"estimatedTokens":156}}465{"id":"stack-68532627","source":"stackoverflow","questionId":68532627,"title":"Fastapi returns 404 when accessing URL in the browser","tags":["python","fastapi","uvicorn"],"text":"Title: Fastapi returns 404 when accessing URL in the browser\nTags: python, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI am learning `fastapi` and created the sample following application:\n\n```\nfrom fastapi import FastAPI\nimport uvicorn\napp = FastAPI()\n\n@app.get(\"/hello\")\nasync def hello_world():\n return {\"message\": \"hello_world\"}\n\nif __name__== \"__main__\":\n uvicorn.run(app, host=\"127.0.0.1\", port=8080)\n```\n\nThe server starts fine but when I test the `url` in browser I am getting the following error:\n\n{\"detail\": \"Not Found\"}\n\nand this error in the log:\n\n\"GET / HTTP /\" 404 Not Found\n\nI noticed another weird problem, when I make some error its not detecting the error and still starting the server. For example if I change the function like the following:\n\n```\n@app.get(\"/hello\")\nasync def hello_world():\n print (sample)\n return {\"message\": \"hello_world\"}\n```\n\nIt should have thrown the error:\n\nNameError: \"sample\" not defined\n\nbut it still is starting the server. Any suggestions will be helpful.\n\n========================================\n\nTop Answer:\nQuestion 1: It doesn't work. You code a handler for path `/hello`. But you are testing path `/` which is not configured.\n\nQuestion 2: You didn't define the variable `sample`.\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nimport uvicorn\napp = FastAPI()\n\n@app.get(\"/hello\")\nasync def hello_world():\n return {\"message\": \"hello_world\"}\n\nif __name__== \"__main__\":\n uvicorn.run(app, host=\"127.0.0.1\", port=8080)\n```\n\n```text\n@app.get(\"/hello\")\nasync def hello_world():\n print (sample)\n return {\"message\": \"hello_world\"}\n```\n\n```text\nfastapi\n```\n\n```text\nurl\n```\n\n```text\n/hello\n```\n\n```text\n/\n```\n\n```text\nsample\n```\n\n```text\n{\"detail\": \"Not Found\"}\n```\n\n```text\n8000/docs\n```\n\n```text\n/segmentation\n```\n\n```text\n/docs\n```\n\n```text\n/\n```\n\n========================================\n\nComments:\n- The response `{\"detail\": \"Not Found\"}` is valid since you have accessed the URL ***`/`*** (the root URL), but in your app, you don't have any route to serve the same. In that case, you must've to access the `/hello` path. The second error is obvious in Python since you didn't define any variable named `sample` in the program context.\n- Since the code in your second example never runs (you never called `/hello` as described in your question), it will never be detected as non-existant. The variable isn't resolved before it's actually needed.\n- Just as feedback, I don't think answering with 'of course..' is very supportive. Everyone makes simple mistakes, especially when learning.","metadata":{"transformedAt":"2026-08-18T18:32:29.136Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":12,"totalLines":119,"estimatedTokens":650}}466{"id":"stack-72727897","source":"stackoverflow","questionId":72727897,"title":"StreamingResponse FASTAPI returns strange file name","tags":["python-3.x","swagger","fastapi"],"text":"Title: StreamingResponse FASTAPI returns strange file name\nTags: python-3.x, swagger, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have an API that outputs `StreamingReponse` (https://fastapi.tiangolo.com/advanced/custom-response/?h=fileresponse#streamingresponse) as zip/gz.\nWhen I download the file VIA Swagger, I get a very strange name, for example:\n`application_gz export something=1&something=1&something=Example&archive_type=gz blob https ___aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaaa`\nso basically - with an ip address of the server, a uuid, some names. Is there anyway to change this to be something I decide, or atleast more elegant?\nthanks!\n\n========================================\n\nCode:\n```text\nStreamingReponse\n```\n\n```text\napplication_gz export something=1&something=1&something=Example&archive_type=gz blob https __<ip_address>_aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaaa\n```\n\n```text\nreturn StreamingResponse(fp, headers={'Content-Disposition': 'attachment; filename=\"yourfilename.zip\"'}\n```\n\n```text\nContent-Disposition\n```\n\n```text\nStreamingResponse\n```\n\n```text\nResponse\n```\n\n```text\nheaders\n```\n\n```text\ninline\n```\n\n```text\nattachment\n```\n\n========================================\n\nComments:\n- `StreamingResponse(..., headers={'Content-Disposition': 'attachment; filename=\"yourfilename.zip\"'}` should work, since `StreamingResponse` inherits from the general `Response` class.\n- @MatsLindh it doesn't work unfortunately: `content-disposition: attachment;filename = config.zip content-type: application/zip date: Thu,23 Jun 2022 10:41:27 GMT server:xx` these are the headers and i still get the weird file names.\n- whoops - fixed it- my problem was there was space between the `filename` and the `=`","metadata":{"transformedAt":"2026-08-18T18:32:29.136Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":56,"estimatedTokens":428}}467{"id":"stack-74318682","source":"stackoverflow","questionId":74318682,"title":"How to submit HTML form value using FastAPI and Jinja2 Templates?","tags":["python","html","jinja2","fastapi"],"text":"Title: How to submit HTML form value using FastAPI and Jinja2 Templates?\nTags: python, html, jinja2, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am facing the following issue while trying to pass a value from an HTML form `` element to the form's `action` attribute and send it to the FastAPI server.\n\nThis is how the Jinja2 (HTML) template is loaded:\n\n```\n# Test TEMPLATES\n@app.get(\"/test\",response_class=HTMLResponse)\nasync def read_item(request: Request):\n return templates.TemplateResponse(\"index.html\", {\"request\": request})\n```\n\nMy HTML form:\n\n```\n\n SubCategory:\n\n \n\n \n\n```\n\nMy FastAPI endpoint to be called in the form action:\n\n```\n# Disable SubCategory\n@app.get(\"/disableSubCategory/{subCatName}\")\nasync def deactivateSubCategory(subCatName: str):\n disableSubCategory(subCatName)\n return {\"message\": \"SubCategory [\" + subCatName + \"] Disabled\"}\n```\n\nThe error I get:\n\n```\n\"GET /disableSubCategory/?subCatName=Barber HTTP/1.1\" 404 Not Found\n```\n\nWhat I am trying to achieve is the following FastAPI call:\n\n```\n/disableSubCategory/{subCatName} ==> \"/disableSubCategory/Barber\"\n```\n\nAnyone who could help me understand what I am doing wrong?\n\nThanks.\nLeo\n\n========================================\n\nTop Answer:\nJust to provide you a feedback and keep track about the solution I've put in place.\n\nAs mentioned by @Chris, I went to the proposed solution 3.\n\nPlease find below my new code:\n\n== FastAPI ==\n\n```\n# Test TEMPLATES\n@app.get(\"/test\",response_class=HTMLResponse)\nasync def read_item(request: Request):\n return templates.TemplateResponse(\"index.html\", {\"request\": request})\n\n# Disable SubCategory\n@app.post(\"/disableSubCategory/{subCatName}\")\nasync def deactivateSubCategory(subCatName: str):\n disableSubCategory(subCatName)\n return {\"message\": \"Sub-Category [\" + subCatName + \"] Disabled\"}\n\n# Enable SubCategory\n@app.post(\"/enableSubCategory/{subCatName}\")\nasync def activateSubCategory(subCatName: str):\n enableSubCategory(subCatName)\n return {\"message\": \"Sub-Category [\" + subCatName + \"] Enabled\"}\n```\n\n== HTML ==\n\n```\n\n Item Details\n \n\n \n document.addEventListener('DOMContentLoaded', (event) => {\n document.getElementById(\"disableSubCategory\").addEventListener(\"submit\", function (e) {\n var myForm = document.getElementById('disableSubCategory');\n var disableSubCatName = document.getElementById('id_disableSubCategory').value;\n myForm.action = '/disableSubCategory/' + disableSubCatName;\n });\n });\n \n\n \n document.addEventListener('DOMContentLoaded', (event) => {\n document.getElementById(\"enableSubCategory\").addEventListener(\"submit\", function (e) {\n var myForm2 = document.getElementById('enableSubCategory');\n var enableSubCatName = document.getElementById('id_enableSubCategory').value;\n myForm2.action = '/enableSubCategory/' + enableSubCatName;\n });\n });\n \n\n \n SubCategory:\n\n \n\n \n \n\n \n SubCategory:\n\n \n\n \n \n\n```\n\n========================================\n\nCode:\n```py\n# Test TEMPLATES\n@app.get(\"/test\",response_class=HTMLResponse)\nasync def read_item(request: Request):\n return templates.TemplateResponse(\"index.html\", {\"request\": request})\n```\n\n```text\n<form action=\"/disableSubCategory/{{subCatName}}\">\n <label for=\"subCatName\">SubCategory:</label><br>\n <input type=\"text\" id=\"subCatName\" name=\"subCatName\" value=\"\"><br>\n <input type=\"submit\" value=\"Disable\">\n</form>\n```\n\n```py\n# Disable SubCategory\n@app.get(\"/disableSubCategory/{subCatName}\")\nasync def deactivateSubCategory(subCatName: str):\n disableSubCategory(subCatName)\n return {\"message\": \"SubCategory [\" + subCatName + \"] Disabled\"}\n```\n\n```text\n\"GET /disableSubCategory/?subCatName=Barber HTTP/1.1\" 404 Not Found\n```\n\n```text\n/disableSubCategory/{subCatName} ==> \"/disableSubCategory/Barber\"\n```\n\n```text\n<input>\n```\n\n```text\naction\n```\n\n```py\nfrom fastapi import FastAPI, Form, Request\nfrom fastapi.responses import HTMLResponse\nfrom fastapi.templating import Jinja2Templates\n\napp = FastAPI()\ntemplates = Jinja2Templates(directory='templates')\n\n@app.post('/disable')\nasync def disable_cat(cat_name: str = Form(...)):\n return f'{cat_name} category has been disabled.'\n\n@app.get('/', response_class=HTMLResponse)\nasync def main(request: Request):\n return templates.TemplateResponse('index.html', {'request': request})\n```\n\n```html\n<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n </head>\n <body>\n <h1>Disable a category</h1>\n <form method=\"post\" action=\"/disable\">\n <label for=\"cat_name\">Enter a category name to disable:</label><br>\n <input type=\"text\" id=\"cat_name\" name=\"cat_name\">\n <input class=\"submit\" type=\"submit\" value=\"Submit\">\n </form>\n </body>\n</html>\n```\n\n```html\n<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n </head>\n <body>\n <h1>Disable a category</h1>\n <label for=\"cat_name\">Enter a category name to disable:</label><br>\n <input type=\"text\" id=\"cat_name\" name=\"cat_name\">\n <input type=\"button\" value=\"Submit\" onclick=\"send()\">\n <p id=\"resp\"></p>\n <script>\n function send() {\n var resp = document.getElementById(\"resp\");\n const cat_name = document.getElementById(\"cat_name\").value;\n var formData = new FormData();\n formData.append(\"cat_name\", cat_name);\n \n fetch('/disable', {\n method: 'POST',\n body: formData,\n })\n .then(response => response.json())\n .then(data => {\n resp.innerHTML = JSON.stringify(data); // data is a JSON object\n })\n .catch(error => {\n console.error(error);\n });\n }\n </script>\n </body>\n</html>\n```\n\n```py\nfrom fastapi import FastAPI, Request\nfrom fastapi.responses import HTMLResponse\nfrom fastapi.templating import Jinja2Templates\n\napp = FastAPI()\ntemplates = Jinja2Templates(directory='templates')\n\n@app.get('/disable')\nasync def disable_cat(cat_name: str):\n return f'{cat_name} category has been disabled.'\n\n@app.get('/', response_class=HTMLResponse)\nasync def main(request: Request):\n return templates.TemplateResponse('index.html', {'request': request})\n```\n\n```html\n<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n </head>\n <body>\n <h1>Disable a category</h1>\n <form method=\"get\" id=\"myForm\" action='/disable{{ cat_name }}'>\n <label for=\"cat_name\">Enter a category name to disable:</label><br>\n <input type=\"text\" id=\"cat_name\" name=\"cat_name\">\n <input class=\"submit\" type=\"submit\" value=\"Submit\">\n </form>\n </body>\n</html>\n```\n\n```html\n<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <script>\n document.addEventListener('DOMContentLoaded', (event) => {\n document.getElementById(\"myForm\").addEventListener(\"submit\", function (e) {\n var myForm = document.getElementById('myForm');\n var qs = new URLSearchParams(new FormData(myForm)).toString();\n myForm.action = '/disable?' + qs;\n });\n });\n </script>\n </head>\n <body>\n <h1>Disable a category</h1>\n <form method=\"post\" id=\"myForm\">\n <label for=\"cat_name\">Enter a category name to disable:</label><br>\n <input type=\"text\" id=\"cat_name\" name=\"cat_name\">\n <input class=\"submit\" type=\"submit\" value=\"Submit\">\n </form>\n </body>\n</html>\n```\n\n```py\nfrom fastapi import FastAPI, Request\nfrom fastapi.responses import HTMLResponse\nfrom fastapi.templating import Jinja2Templates\n\napp = FastAPI()\ntemplates = Jinja2Templates(directory='templates')\n\n@app.post('/disable/{name}')\nasync def disable_cat(name: str):\n return f'{name} category has been disabled.'\n\n@app.get('/', response_class=HTMLResponse)\nasync def main(request: Request):\n return templates.TemplateResponse('index.html', {'request': request})\n```\n\n```html\n<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <script>\n document.addEventListener('DOMContentLoaded', (event) => {\n document.getElementById(\"myForm\").addEventListener(\"submit\", function (e) {\n var myForm = document.getElementById('myForm');\n var catName = document.getElementById('catName').value;\n myForm.action = '/disable/' + catName;\n });\n });\n </script>\n </head>\n <body>\n <h1>Disable a category</h1>\n <form method=\"post\" id=\"myForm\">\n <label for=\"catName\">Enter a category name to disable:</label><br>\n <input type=\"text\" id=\"catName\" name=\"catName\">\n <input class=\"submit\" type=\"submit\" value=\"Submit\">\n </form>\n </body>\n</html>\n```\n\n```py\nfrom fastapi import FastAPI, Request\nfrom fastapi.responses import HTMLResponse\nfrom fastapi.templating import Jinja2Templates\n\napp = FastAPI()\ntemplates = Jinja2Templates(directory='templates')\n\n@app.post('/disable/{name}')\nasync def disable_cat(name: str):\n return f'{name} category has been disabled.'\n\n@app.get('/', response_class=HTMLResponse)\nasync def main(request: Request):\n return templates.TemplateResponse('index.html', {'request': request})\n```\n\n```html\n<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <script>\n document.addEventListener('DOMContentLoaded', (event) => {\n document.getElementById(\"myForm\").addEventListener(\"submit\", function (e) {\n e.preventDefault() // Cancel the default action\n var catName = document.getElementById('catName').value;\n fetch('/disable/' + catName, {\n method: 'POST',\n })\n .then(resp => resp.text()) // or, resp.json(), etc.\n .then(data => {\n document.getElementById(\"response\").innerHTML = data;\n })\n .catch(error => {\n console.error(error);\n });\n });\n });\n </script>\n </head>\n <body>\n <h1>Disable a category</h1>\n <form id=\"myForm\">\n <label for=\"catName\">Enter a category name to disable:</label><br>\n <input type=\"text\" id=\"catName\" name=\"catName\">\n <input class=\"submit\" type=\"submit\" value=\"Submit\">\n </form>\n <div id=\"response\"></div>\n </body>\n</html>\n```\n\n```text\nForm\n```\n\n```text\n<form>\n```\n\n```text\nForm\n```\n\n```text\nPOST\n```\n\n```text\nForm\n```\n\n```text\nForm\n```\n\n```text\n<form>\n```\n\n```text\n<input>\n```\n\n```text\naction\n```\n\n```text\n@app.get()\n```\n\n```text\n<form method=\"get\" ...\n```\n\n```text\n@app.post()\n```\n\n```text\n<form>\n```\n\n```text\n<form>\n```\n\n```text\naction\n```\n\n```text\n<form>\n```\n\n```text\n<form>\n```\n\n```text\n<input>\n```\n\n```text\nsubmit\n```\n\n```text\n<form>\n```\n\n```text\nEvent.preventDefault()\n```\n\n```text\n<form>\n```\n\n```text\n<form>\n```\n\n```text\n<input>\n```\n\n```text\nForm\n```\n\n```text\n# Test TEMPLATES\n@app.get(\"/test\",response_class=HTMLResponse)\nasync def read_item(request: Request):\n return templates.TemplateResponse(\"index.html\", {\"request\": request})\n\n# Disable SubCategory\n@app.post(\"/disableSubCategory/{subCatName}\")\nasync def deactivateSubCategory(subCatName: str):\n disableSubCategory(subCatName)\n return {\"message\": \"Sub-Category [\" + subCatName + \"] Disabled\"}\n\n# Enable SubCategory\n@app.post(\"/enableSubCategory/{subCatName}\")\nasync def activateSubCategory(subCatName: str):\n enableSubCategory(subCatName)\n return {\"message\": \"Sub-Category [\" + subCatName + \"] Enabled\"}\n```\n\n```text\n<html>\n<head>\n <title>Item Details</title>\n <link href=\"{{ url_for('static', path='/styles.css') }}\" rel=\"stylesheet\">\n\n <script>\n document.addEventListener('DOMContentLoaded', (event) => {\n document.getElementById(\"disableSubCategory\").addEventListener(\"submit\", function (e) {\n var myForm = document.getElementById('disableSubCategory');\n var disableSubCatName = document.getElementById('id_disableSubCategory').value;\n myForm.action = '/disableSubCategory/' + disableSubCatName;\n });\n });\n </script>\n\n <script>\n document.addEventListener('DOMContentLoaded', (event) => {\n document.getElementById(\"enableSubCategory\").addEventListener(\"submit\", function (e) {\n var myForm2 = document.getElementById('enableSubCategory');\n var enableSubCatName = document.getElementById('id_enableSubCategory').value;\n myForm2.action = '/enableSubCategory/' + enableSubCatName;\n });\n });\n </script>\n\n</head>\n<body>\n\n <form id=\"disableSubCategory\" enctype=\"multipart/form-data\" method=\"post\">\n <label for=\"subCatName\">SubCategory:</label><br>\n <input type=\"text\" id=\"id_disableSubCategory\" value=\"\"><br>\n <input type=\"submit\" value=\"Disable\" id=\"disable\">\n </form>\n\n <form id=\"enableSubCategory\" enctype=\"multipart/form-data\" method=\"post\">\n <label for=\"subCatName\">SubCategory:</label><br>\n <input type=\"text\" id=\"id_enableSubCategory\" value=\"\"><br>\n <input type=\"submit\" value=\"Enable\" id=\"enable\">\n </form>\n\n</body>\n</html>\n```\n\n========================================\n\nComments:\n- You're calling `/disableSubCategory/` with the parameter `?subCatName=Barber`; did you mean to actually access `/disableSubCategory/Barber`? (a side note: doing modifications when doing a GET request is absolutely not recommended - use a POST request (or PUT/PATCH) if you're modifying content; GET requests should not modify content).\n- I've changed the method to POST as you said, thanks. I am now struggling to retrieve the form field value and use it into the action tag. I did some tests with Flask and the \"request.form.get\" for me, it was a lot easier to get what I want. :)\n- If you want to have it as a Form variable, define it as such: `deactivateSubCategory(subCatName: str = Form(...)):` - right now you have it defined as a path argument.\n- Wow ... you sent different samples and ways to achieve what I want. I got what you said and will put in place. I really appreciate that, thanks.","metadata":{"transformedAt":"2026-08-18T18:32:29.136Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":44,"totalLines":575,"estimatedTokens":3633}}468{"id":"stack-67774905","source":"stackoverflow","questionId":67774905,"title":"How to make Depends optional in FastAPI?","tags":["python","dependency-injection","oauth-2.0","fastapi"],"text":"Title: How to make Depends optional in FastAPI?\nTags: python, dependency-injection, oauth-2.0, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have an API which gives images to the user and non-users. Images can be *public* or *private*.\n\n### My code:\n\n```\n@router.get(\"/{id}\")\ndef get_resource(id: str, current_user: User = Depends(get_current_user)):\n return return_resource(id, current_user)\n```\n\nThis code enforces `authorization` strictly. What I want is if the user is not logged in, it should then set the `current_user` parameter to `None`, so that I can allow access to public images and restrict private.\n\n### Other codes:\n\n### get_current_user\n\n```\noauth2_scheme = OAuth2PasswordBearer(tokenUrl=\"auth/login\")\n\nasync def get_current_user(required: bool = True, token: str = Depends(oauth2_scheme)):\n credentials_exception = HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Could not validate credentials\",\n headers={\"WWW-Authenticate\": \"Bearer\"},\n )\n\n if not required and not token:\n return None\n\n return verify_token(token, credentials_exception)\n```\n\nI want to send parameter like `required` to `get_current_user`\n\n### verify_token\n\n```\ndef verify_token(token: str, credentials_exception):\n try:\n payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])\n email: str = payload.get(\"email\")\n pk: str = payload.get(\"pk\")\n if email is None:\n raise credentials_exception\n token_data = TokenData(\n email=email,\n pk = pk\n )\n except JWTError:\n raise credentials_exception\n return token_data\n```\n\n========================================\n\nCode:\n```py\n@router.get(\"/{id}\")\ndef get_resource(id: str, current_user: User = Depends(get_current_user)):\n return return_resource(id, current_user)\n```\n\n```py\noauth2_scheme = OAuth2PasswordBearer(tokenUrl=\"auth/login\")\n\nasync def get_current_user(required: bool = True, token: str = Depends(oauth2_scheme)):\n credentials_exception = HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Could not validate credentials\",\n headers={\"WWW-Authenticate\": \"Bearer\"},\n )\n\n if not required and not token:\n return None\n\n return verify_token(token, credentials_exception)\n```\n\n```py\ndef verify_token(token: str, credentials_exception):\n try:\n payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])\n email: str = payload.get(\"email\")\n pk: str = payload.get(\"pk\")\n if email is None:\n raise credentials_exception\n token_data = TokenData(\n email=email,\n pk = pk\n )\n except JWTError:\n raise credentials_exception\n return token_data\n```\n\n```text\nauthorization\n```\n\n```text\ncurrent_user\n```\n\n```text\nNone\n```\n\n```text\nrequired\n```\n\n```text\nget_current_user\n```\n\n```text\ndef get_current_user(required: bool = True):\n async def _get_user(token: str = Depends(oauth2_scheme)):\n credentials_exception = HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Could not validate credentials\",\n headers={\"WWW-Authenticate\": \"Bearer\"},\n )\n\n if not required and not token:\n return None\n\n return verify_token(token, credentials_exception)\n\n return _get_user\n\n\n\n@router.get(\"/{id}\")\ndef get_resource(id: str, current_user: User = Depends(get_current_user(False))):\n return return_resource(id, current_user)\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.136Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":142,"estimatedTokens":831}}469{"id":"stack-69507122","source":"stackoverflow","questionId":69507122,"title":"Fastapi custom response model","tags":["python","json","fastapi","pydantic"],"text":"Title: Fastapi custom response model\nTags: python, json, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI have a router that fetches all data from the database. Here is my code:\n\n```\n@router.get('/articles/', response_model=List[articles_schema.Articles])\nasync def main_endpoint():\n query = articles_model.articles.select().where(articles_model.articles.c.status == 2)\n return await db.database.fetch_all(query)\n```\n\nThe response is an array that contains JSON objects like this\n\n```\n[\n {\n \"title\": \"example1\",\n \"content\": \"example_content1\"\n },\n {\n \"title\": \"example2\",\n \"content\": \"example_content2\"\n },\n]\n```\n\nBut I want to make the response like this:\n\n```\n{\n \"items\": [\n {\n \"title\": \"example1\",\n \"content\": \"example_content1\"\n },\n {\n \"title\": \"example2\",\n \"content\": \"example_content2\"\n },\n ]\n}\n```\n\nHow can I achieve that? Please help. Thank you in advance\n\n========================================\n\nTop Answer:\nAlso, You can create a custom responses using generic types as if you plan to reuse a response template\n\n```\nfrom typing import Any, Generic, List, Optional, TypeVar\nfrom pydantic import BaseModel\nfrom pydantic.generics import GenericModel\n\nDataType = TypeVar(\"DataType\")\n\nclass IResponseBase(GenericModel, Generic[DataType]):\n message: str = \"\"\n meta: dict = {}\n items: Optional[DataType] = None\n```\n\n```\n@router.get('/articles/', response_model=IResponseBase[List[Articles]])\nasync def main_endpoint():\n query = articles_model.articles.select().where(articles_model.articles.c.status == 2)\n items=await db.database.fetch_all(query)\n return IResponseBase[List[Articles]](items=items)\n```\n\nYou can find a FastAPI template here\nhttps://github.com/jonra1993/fastapi-alembic-sqlmodel-async/blob/main/fastapi-alembic-sqlmodel-async/app/schemas/response_schema.py\n\n========================================\n\nCode:\n```py\n@router.get('/articles/', response_model=List[articles_schema.Articles])\nasync def main_endpoint():\n query = articles_model.articles.select().where(articles_model.articles.c.status == 2)\n return await db.database.fetch_all(query)\n```\n\n```json\n[\n {\n \"title\": \"example1\",\n \"content\": \"example_content1\"\n },\n {\n \"title\": \"example2\",\n \"content\": \"example_content2\"\n },\n]\n```\n\n```json\n{\n \"items\": [\n {\n \"title\": \"example1\",\n \"content\": \"example_content1\"\n },\n {\n \"title\": \"example2\",\n \"content\": \"example_content2\"\n },\n ]\n}\n```\n\n```py\nfrom pydantic import BaseModel\nfrom typing import List\n\nclass ResponseModel(BaseModel):\n items: List[articles_schema.Articles]\n```\n\n```py\n@router.get('/articles/', response_model=ResponseModel)\nasync def main_endpoint():\n query = articles_model.articles.select().where(\n articles_model.articles.c.status == 2\n )\n return ResponseModel(\n items=await db.database.fetch_all(query),\n )\n```\n\n```text\nitems\n```\n\n```text\nfrom typing import Any, Generic, List, Optional, TypeVar\nfrom pydantic import BaseModel\nfrom pydantic.generics import GenericModel\n\nDataType = TypeVar(\"DataType\")\n\nclass IResponseBase(GenericModel, Generic[DataType]):\n message: str = \"\"\n meta: dict = {}\n items: Optional[DataType] = None\n```\n\n```text\n@router.get('/articles/', response_model=IResponseBase[List[Articles]])\nasync def main_endpoint():\n query = articles_model.articles.select().where(articles_model.articles.c.status == 2)\n items=await db.database.fetch_all(query)\n return IResponseBase[List[Articles]](items=items)\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.136Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":8,"totalLines":158,"estimatedTokens":884}}470{"id":"stack-62823097","source":"stackoverflow","questionId":62823097,"title":"FastApi communication with other API","tags":["python","rest","fastapi"],"text":"Title: FastApi communication with other API\nTags: python, rest, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am using fastapi very recently and as an exercise I want to connect my fastapi API with a validation service on other server... but I do not know how to do this, I have not found something that will help me in the official documentation.. Will I have to do it with python code? Or is there a way?\n\nFastApi docs\n\n========================================\n\nTop Answer:\nThe accepted answer certainly works, but it is not an effective solution. With each request, the `ClientSession` is closed, so we lose the advantage [0] of `ClientSession`: connection pooling, keepalives, etc. etc.\n\nWe can use the `startup` and `shutdown` events [1] in FastAPI, which are triggered when the server starts and shuts down respectively. In these events it is possible to create a `ClientSession` instance and use it during the runtime of the whole application (and therefore utilize its full potential).\n\nThe `ClientSession` instance is stored in the application state. [2]\n\nHere I answered a very similar question in the context of the aiohttp server: https://stackoverflow.com/a/60850857/752142\n\n```\nfrom __future__ import annotations\n\nimport asyncio\nfrom typing import Final\n\nfrom aiohttp import ClientSession\nfrom fastapi import Depends, FastAPI\nfrom starlette.requests import Request\n\napp: Final = FastAPI()\n\n@app.on_event(\"startup\")\nasync def startup_event():\n setattr(app.state, \"client_session\", ClientSession(raise_for_status=True))\n\n@app.on_event(\"shutdown\")\nasync def shutdown_event():\n await asyncio.wait((app.state.client_session.close()), timeout=5.0)\n\ndef client_session_dep(request: Request) -> ClientSession:\n return request.app.state.client_session\n\n@app.get(\"/\")\nasync def root(\n client_session: ClientSession = Depends(client_session_dep),\n) -> str:\n async with client_session.get(\n \"https://example.com/\", raise_for_status=True\n ) as the_response:\n return await the_response.text()\n```\n\n- [0] https://docs.aiohttp.org/en/stable/client_reference.html\n\n- [1] https://fastapi.tiangolo.com/advanced/events/\n\n- [2] https://www.starlette.io/applications/#storing-state-on-the-app-instance\n\n========================================\n\nCode:\n```py\nimport aiohttp\n\n@app.get(\"/\")\nasync def slow_route():\n async with aiohttp.ClientSession() as session:\n async with session.get(\"http://validation_service.com\") as resp:\n data = await resp.text()\n # do something with data\n```\n\n```py\nfrom __future__ import annotations\n\nimport asyncio\nfrom typing import Final\n\nfrom aiohttp import ClientSession\nfrom fastapi import Depends, FastAPI\nfrom starlette.requests import Request\n\napp: Final = FastAPI()\n\n\n@app.on_event(\"startup\")\nasync def startup_event():\n setattr(app.state, \"client_session\", ClientSession(raise_for_status=True))\n\n\n@app.on_event(\"shutdown\")\nasync def shutdown_event():\n await asyncio.wait((app.state.client_session.close()), timeout=5.0)\n\n\ndef client_session_dep(request: Request) -> ClientSession:\n return request.app.state.client_session\n\n\n@app.get(\"/\")\nasync def root(\n client_session: ClientSession = Depends(client_session_dep),\n) -> str:\n async with client_session.get(\n \"https://example.com/\", raise_for_status=True\n ) as the_response:\n return await the_response.text()\n```\n\n```text\nClientSession\n```\n\n```text\nClientSession\n```\n\n```text\nstartup\n```\n\n```text\nshutdown\n```\n\n```text\nClientSession\n```\n\n```text\nClientSession\n```\n\n```text\nimport asyncio\nfrom contextlib import asynccontextmanager\n\nfrom fastapi import Request\nfrom httpx import AsyncClient\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI):\n setattr(app.state, \"client_session\", AsyncClient())\n yield\n await app.state.client_session.aclose()\n\n\ndef client_session_dep(request: Request) -> AsyncClient:\n return request.app.state.client_session\n\n\n@app.get(\"/\")\nasync def root(\n client_session: AsyncClient = Depends(client_session_dep),\n) -> str:\n response = await client_session.get('https://www.example.com/')\n return response.text()\n```\n\n```text\nstartup\n```\n\n```text\nshutdown\n```\n\n```text\nlifespan\n```\n\n========================================\n\nComments:\n- For connecting to other REST service, use `requests` library","metadata":{"transformedAt":"2026-08-18T18:32:29.136Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":12,"totalLines":176,"estimatedTokens":1071}}471{"id":"stack-76645926","source":"stackoverflow","questionId":76645926,"title":"peewee.ImproperlyConfigured: Postgres driver not installed","tags":["python","postgresql","fastapi","peewee"],"text":"Title: peewee.ImproperlyConfigured: Postgres driver not installed\nTags: python, postgresql, fastapi, peewee\nSource: Stack Overflow\n\nQuestion:\nI have installed peewee and postgres. I am using FastAPI as the backend. When I run the request to create tables, it throws the shown error:\n\n```\nINFO: 127.0.0.1:33284 - \"GET /setup_db HTTP/1.1\" 500 Internal Server Error\nERROR: Exception in ASGI application\nTraceback (most recent call last):\npeewee.ImproperlyConfigured: Postgres driver not installed!\n```\n\nThis is my main.py:\n\n```\nfrom fastapi import FastAPI\nfrom models.schema import db, User, Plan\nfrom datetime import datetime\nfrom peewee import *\n\ndb = PostgresqlDatabase('database_name', host='localhost', port=5432, user='user', password='password')\n\napp = FastAPI()\n\n@app.get('/')\nasync def Home():\n return \"Welcome Home\"\n\n@app.get('/setup_db')\nasync def SetupDB():\n db.connect()\n db.create_tables([User],[Plan])\n\n new_user = User.create(\n username = 'user1',\n email = 'user1@email.com',\n hashed_password = 'pwd####',\n create_on = datetime(2001, 3, 29, 5, 15, 30)\n )\n print(new_user)\n return new_user\n```\n\nI tried importing the Models from different folders but it did not work. Please let me know what drivers/config do I need to add to make this work. Thanks & Cheers!\n\n========================================\n\nCode:\n```text\nINFO: 127.0.0.1:33284 - \"GET /setup_db HTTP/1.1\" 500 Internal Server Error\nERROR: Exception in ASGI application\nTraceback (most recent call last):\npeewee.ImproperlyConfigured: Postgres driver not installed!\n```\n\n```text\nfrom fastapi import FastAPI\nfrom models.schema import db, User, Plan\nfrom datetime import datetime\nfrom peewee import *\n\ndb = PostgresqlDatabase('database_name', host='localhost', port=5432, user='user', password='password')\n\napp = FastAPI()\n\n@app.get('/')\nasync def Home():\n return \"Welcome Home\"\n\n@app.get('/setup_db')\nasync def SetupDB():\n db.connect()\n db.create_tables([User],[Plan])\n\n new_user = User.create(\n username = 'user1',\n email = 'user1@email.com',\n hashed_password = 'pwd####',\n create_on = datetime(2001, 3, 29, 5, 15, 30)\n )\n print(new_user)\n return new_user\n```\n\n```text\npip install psycopg2\n```\n\n```text\nsqlalchemy\n```\n\n```text\nasyncpg\n```\n\n```text\nalembic\n```\n\n========================================\n\nComments:\n- can you `models` package or `schema` file contents?","metadata":{"transformedAt":"2026-08-18T18:32:29.136Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":6,"totalLines":106,"estimatedTokens":598}}472{"id":"stack-69660608","source":"stackoverflow","questionId":69660608,"title":"Customise Status codes in place of 500: Internal Server Error in FastAPI using Postman","tags":["fastapi","postman-testcase"],"text":"Title: Customise Status codes in place of 500: Internal Server Error in FastAPI using Postman\nTags: fastapi, postman-testcase\nSource: Stack Overflow\n\nQuestion:\nI'm very new in using FastAPI and postman. When I am sending a POST request with a body (input data), I'm getting Success code 200 and also intended Response.\n\nNow, I want to tweak my input data to make my code fail intentionally. This is also happening. But the status code is coming to be **500** and *Internal Server Error* is being displayed in response.\n\nI want to manually give a status code in each case of failure and also some related output in Response. How to achieve this goal?\n\n========================================\n\nTop Answer:\nIf you want to JSON response format, this might be helpful\n\n```\nfrom fastapi.responses import JSONResponse\nfrom fastapi import status\n\ndef my_function():\n return JSONResponse(\n status_code=500,\n content={\n \"code\": status.HTTP_500_INTERNAL_SERVER_ERROR,\n \"message\": \"Internal Server Error\"}\n )\n```\n\n========================================\n\nCode:\n```text\ntry:\n output\nexcept Exception:\n raise HTTPException(status_code=406, detail=\"New Error Found\")\n```\n\n```text\nfrom fastapi.responses import JSONResponse\nfrom fastapi import status\n\ndef my_function():\n return JSONResponse(\n status_code=500,\n content={\n \"code\": status.HTTP_500_INTERNAL_SERVER_ERROR,\n \"message\": \"Internal Server Error\"}\n )\n```\n\n========================================\n\nComments:\n- Have you seen fastapi.tiangolo.com/tutorial/handling-errors?\n- I needed to give manual status codes. Is it possible here?\n- Yeah, possible. Change the status code as you want. See this list github.com/encode/starlette/blob/master/starlette/status.py . If not found any relevant, Just put manual code.\n- Okay.. Could you show an instance with status code 406 and detail as \"Solver TimeOut\"?\n- Just change the status code. JSONResponse( status_code=406, content={ \"code\": 406 \"message\": \"Solver TimeOut\"} )","metadata":{"transformedAt":"2026-08-18T18:32:29.136Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":2,"totalLines":60,"estimatedTokens":515}}473{"id":"stack-68766136","source":"stackoverflow","questionId":68766136,"title":"Including special character in Basemodel for Pydantic","tags":["python","fastapi","pydantic"],"text":"Title: Including special character in Basemodel for Pydantic\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI am trying to create a Pydantic basemodel with a key including a '$' sign. It looks like this:\n\n```\nclass someModel(BaseModel):\n $something:Optional[str] = None\n```\n\nThen I get `SyntaxError: invalid syntax`.\nBut I need to keep the key name `$something` to use in other parts. Is there a way to allow the dollar sign in this case?\n\n========================================\n\nCode:\n```text\nclass someModel(BaseModel):\n $something:Optional[str] = None\n```\n\n```text\nSyntaxError: invalid syntax\n```\n\n```text\n$something\n```\n\n```text\nfrom pydantic import BaseModel, Field\n\nclass SomeModel(BaseModel):\n something: Optional[str] = Field(alias=\"$something\", default=None)\n```\n\n```text\nimport logging\nfrom typing import Optional\nfrom fastapi import FastAPI, Request\nfrom pydantic import BaseModel, Field\n\nlogging.basicConfig(level=logging.INFO, format=\"%(levelname)-9s %(asctime)s - %(name)s - %(message)s\")\nLOGGER = logging.getLogger(__name__)\n\napp = FastAPI()\n\n\nclass SomeModel(BaseModel):\n something: Optional[str] = Field(alias=\"$something\", default=None)\n\n\n@app.post(\"/\")\nasync def root(request: Request, parsed_body: SomeModel):\n\n # A dict of all the model fields and their properties\n LOGGER.info(f\"SomeModel.__fields__: {SomeModel.__fields__}\")\n\n # To get the alias of the variable name\n something_alias = SomeModel.__fields__[\"something\"].alias\n LOGGER.info(f\"something_alias: {something_alias}\")\n\n # Edit: prefer to use \"parsed_body_by_alias\" than raw_body. Leaving here to show the difference.\n raw_body: bytes = await request.body()\n LOGGER.info(f\"raw_body: {raw_body}\")\n\n # Edit: This is better as you get validated / parsed values, including defaults if applicable.\n parsed_body_by_alias = parsed_body.dict(by_alias=True)\n LOGGER.info(f\"parsed_body_by_alias: {parsed_body_by_alias}\")\n\n # If you just want \"something\" instead of \"$something\"\n LOGGER.info(f\"parsed_body: {parsed_body}\")\n LOGGER.info(f\"parsed_body.something: {parsed_body.something}\")\n\n return 1\n\n\nif __name__ == \"__main__\":\n import uvicorn\n\n uvicorn.run(app, host=\"127.0.0.1\", port=8080)\n```\n\n```text\nINFO xxx - __main__ - SomeModel.__fields__: {'something': ModelField(name='something', type=Optional[str], required=False, default=None, alias='$something')}\nINFO xxx - __main__ - something_alias: $something\nINFO xxx - __main__ - raw_body: b'{\"$something\": \"bar\"}'\nINFO xxx - __main__ - parsed_body_by_alias: {'$something': 'bar'}\nINFO xxx - __main__ - parsed_body: something='bar'\nINFO xxx - __main__ - parsed_body.something: bar\nINFO: 127.0.0.1:xxxxx - \"POST / HTTP/1.1\" 200 OK\n```\n\n```text\nField(alias=...)\n```\n\n```text\nNone\n```\n\n```text\n{\"$something\": \"bar\"}\n```\n\n========================================\n\nComments:\n- Can you explain why you need the `$` symbol on the attribute name? it is not a valid python name.\n- Thanks, that's because I need to pass it to a request body. I could convert to string and put the $ sign to communicate with other services but I was wondering how this issue should be handled.\n- Thanks a lot! I learned the new way :) But would there be a way without the use of Request? Preferably, I'd just like to use parsed_body with the set `alias` for `something`.\n- No worries and yes, I just edited my answer to show alternatives. Depending on how you're using it you might want to get the alias name of `something` by looking it up in the model's fields, or alternatively you might just want a dict of the parsed payload with the alias names. The edited answer illustrates these different methods now.","metadata":{"transformedAt":"2026-08-18T18:32:29.136Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":114,"estimatedTokens":931}}474{"id":"stack-64099243","source":"stackoverflow","questionId":64099243,"title":"How to disallow empty parameters in FastAPI?","tags":["python","python-3.x","fastapi","pydantic"],"text":"Title: How to disallow empty parameters in FastAPI?\nTags: python, python-3.x, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI have FastAPI function like this:\n\n```\n@router.post(\"/test/\")\nasync def test(ids: List[str] = Body(..., )):\n # some logic\n```\n\nI want \"ids\" field as required and pass there values like [\"1\", \"2\"]. If I pass a valid list it working fine. But if I pass empty list - [], this is also will be valid param and I dont want that.\nI can write function that checks it myself pretty easy, but I feel from my expirience with this wonderful framework that FastAPI have it covered already and I just dont know how.\n\n========================================\n\nTop Answer:\n### Method 1: use field validator -- (Pydantic Doc)\n\n```\nfrom pydantic import BaseModel, validator\n\nclass MyModel(BaseModel):\n ids: List[str] = []\n\n @validator('ids', pre=True, always=True)\n def validate_ids_length(cls, value):\n if len(value) == 0:\n raise ValueError(\"empty list not allowed\")\n return value\n\n@demo_app.post(\"/test/\")\nasync def test(data: **MyModel** = Body(...)):\n return data\n```\n\n### Method 2: Use **`min_items`** argument of **`Field`**--(Pydantic Doc) class\n\n```\nfrom pydantic import BaseModel, Field\n\nclass MyModel(BaseModel):\n ids: List[str] = **Field(..., min_items=1)**\n\n@demo_app.post(\"/test/\")\nasync def test(data: MyModel = Body(...)):\n return data\n```\n\nexample cURL request:\n\n```\ncurl -X POST \"http://0.0.0.0:8000/test/\" -H \"accept: application/json\" -H \"Content-Type: application/json\" **-d \"{\\\"ids\\\":[\\\"string\\\"]}\"**\n```\n\n========================================\n\nCode:\n```text\n@router.post(\"/test/\")\nasync def test(ids: List[str] = Body(..., )):\n # some logic\n```\n\n```text\n@router.post(\"/test/\")\nasync def test(ids: List[str] = Body(..., min_items=1)):\n # some logic\n```\n\n```text\nmin_items\n```\n\n```text\nBaseModel\n```\n\n```text\nfrom pydantic import validator, BaseModel\nfrom fastapi import FastAPI, Body\nfrom typing import List\n\napp = FastAPI()\n\n\nclass User(BaseModel):\n ids: List[str]\n\n @validator(\"ids\", pre=True, always=True)\n def check_ids(cls, ids):\n assert len(ids) > 0, \"ID's cannot be empty.\"\n return ids\n\n\n@app.post(\"/test\")\nasync def get_ids(user: User = Body(...)):\n return user\n```\n\n```text\nfrom pydantic import BaseModel, validator\n\n\nclass MyModel(BaseModel):\n ids: List[str] = []\n\n @validator('ids', pre=True, always=True)\n def validate_ids_length(cls, value):\n if len(value) == 0:\n raise ValueError(\"empty list not allowed\")\n return value\n\n\n@demo_app.post(\"/test/\")\nasync def test(data: MyModel = Body(...)):\n return data\n```\n\n```text\nfrom pydantic import BaseModel, Field\n\n\nclass MyModel(BaseModel):\n ids: List[str] = Field(..., min_items=1)\n\n\n@demo_app.post(\"/test/\")\nasync def test(data: MyModel = Body(...)):\n return data\n```\n\n```text\ncurl -X POST \"http://0.0.0.0:8000/test/\" -H \"accept: application/json\" -H \"Content-Type: application/json\" -d \"{\\\"ids\\\":[\\\"string\\\"]}\"\n```\n\n```text\nmin_items\n```\n\n```text\nField\n```\n\n========================================\n\nComments:\n- what is `cls` in this scenario?","metadata":{"transformedAt":"2026-08-18T18:32:29.136Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":10,"totalLines":150,"estimatedTokens":779}}475{"id":"stack-73759718","source":"stackoverflow","questionId":73759718,"title":"How to post JSON data from JavaScript frontend to FastAPI backend?","tags":["python","reactjs","next.js","fastapi"],"text":"Title: How to post JSON data from JavaScript frontend to FastAPI backend?\nTags: python, reactjs, next.js, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to pass a value called 'ethAddress' from an input form on the client to FastAPI so that I can use it in a function to generate a matplotlib chart.\n\nI am using fetch to POST the inputted text in Charts.tsx file:\n\n```\nfetch(\"http://localhost:8000/ethAddress\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(ethAddress),\n }).then(fetchEthAddresses);\n```\n\nThen I have my api.py file set up as follows:\n\n```\n#imports\napp = FastAPI()\n\n@app.get(\"/ethAddress\")\nasync def get_images(background_tasks: BackgroundTasks, ethAddress: str):\n \n image = EthBalanceTracker.get_transactions(ethAddress)\n img_buf = image\n background_tasks.add_task(img_buf.close)\n headers = {'Content-Disposition': 'inline; filename=\"out.png\"'}\n return Response(img_buf.getvalue(), headers=headers, media_type='image/png')\n\n@app.post(\"/ethAddress\")\nasync def add_ethAddress(ethAddress: str):\n return ethAddress\n```\n\nTo my understanding, I am passing the 'ethAddress' in the Request Body from the client to the backend using `fetch` `POST` request, where I then have access to the value that has been posted using `@app.post` in FastAPI. I then return that value as a string. Then I am using it in the `GET` route to generate the chart.\n\nI'm getting this error:\n\n```\nINFO: 127.0.0.1:59821 - \"POST /ethAddress HTTP/1.1\" 422 Unprocessable Entity\nINFO: 127.0.0.1:59821 - \"GET /ethAddress HTTP/1.1\" 422 Unprocessable Entity\n```\n\nI have also tried switching the fetch method on the client to GET instead of POST. But get the following error:\n\n```\nTypeError: Failed to execute 'fetch' on 'Window': Request with GET/HEAD method cannot have body.\n```\n\n========================================\n\nCode:\n```text\nfetch(\"http://localhost:8000/ethAddress\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(ethAddress),\n }).then(fetchEthAddresses);\n```\n\n```text\n#imports\napp = FastAPI()\n\n@app.get(\"/ethAddress\")\nasync def get_images(background_tasks: BackgroundTasks, ethAddress: str):\n \n image = EthBalanceTracker.get_transactions(ethAddress)\n img_buf = image\n background_tasks.add_task(img_buf.close)\n headers = {'Content-Disposition': 'inline; filename=\"out.png\"'}\n return Response(img_buf.getvalue(), headers=headers, media_type='image/png')\n\n\n@app.post(\"/ethAddress\")\nasync def add_ethAddress(ethAddress: str):\n return ethAddress\n```\n\n```text\nINFO: 127.0.0.1:59821 - \"POST /ethAddress HTTP/1.1\" 422 Unprocessable Entity\nINFO: 127.0.0.1:59821 - \"GET /ethAddress HTTP/1.1\" 422 Unprocessable Entity\n```\n\n```text\nTypeError: Failed to execute 'fetch' on 'Window': Request with GET/HEAD method cannot have body.\n```\n\n```text\nfetch\n```\n\n```text\nPOST\n```\n\n```text\n@app.post\n```\n\n```text\nGET\n```\n\n```py\nfrom pydantic import BaseModel\n\n\nclass Item(BaseModel):\n eth_addr: str\n\n\n@app.post('/')\nasync def add_eth_addr(item: Item):\n return item\n```\n\n```json\n{\n \"eth_addr\": \"some addr\"\n}\n```\n\n```js\nfetch('/', {\n method: 'POST',\n headers: {\n 'Accept': 'application/json',\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n \"eth_addr\": \"some addr\"\n }),\n })\n .then(resp => resp.json()) // or, resp.text(), etc.\n .then(data => {\n console.log(data); // handle response data\n })\n .catch(error => {\n console.error(error);\n });\n```\n\n```py\nfrom fastapi import Body\n\n\n@app.post('/')\nasync def add_eth_addr(eth_addr: str = Body()):\n return {'eth_addr': eth_addr}\n```\n\n```json\n\"some addr\"\n```\n\n```js\nfetch('/', {\n method: 'POST',\n headers: {\n 'Accept': 'application/json',\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(\"some addr\"),\n })\n .then(resp => resp.json()) // or, resp.text(), etc.\n .then(data => {\n console.log(data); // handle response data\n })\n .catch(error => {\n console.error(error);\n });\n```\n\n```py\nfrom fastapi import Body\n\n\n@app.post('/')\nasync def add_eth_addr(eth_addr: str = Body(embed=True)):\n return {'eth_addr': eth_addr}\n```\n\n```json\n{\n \"eth_addr\": \"some addr\"\n}\n```\n\n```js\nfetch('/', {\n method: 'POST',\n headers: {\n 'Accept': 'application/json',\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n \"eth_addr\": \"some addr\"\n }),\n })\n .then(resp => resp.json()) // or, resp.text(), etc.\n .then(data => {\n console.log(data); // handle response data\n })\n .catch(error => {\n console.error(error);\n });\n```\n\n```text\nethAddress\n```\n\n```text\n422 Unprocessable Entity\n```\n\n```text\nBody\n```\n\n```text\nBody\n```\n\n```text\nembed\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.136Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":22,"totalLines":231,"estimatedTokens":1205}}476{"id":"stack-64221720","source":"stackoverflow","questionId":64221720,"title":"FastAPI and Python threads","tags":["python","multithreading","python-3.7","python-multithreading","fastapi"],"text":"Title: FastAPI and Python threads\nTags: python, multithreading, python-3.7, python-multithreading, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have a little issue with FastAPI and additional threads spawning. Let's say i have an application that serves two endpoints.\n\n- One of them to `/create_user` to create user in some database\n\n- Other is just `/ping`. Ping is made simply because my app is running in Kubernetes and it's continuously checking if my app is alive by sending GET request and receive response_code 200.\n\n- Additionally i have a separate process made with `threading.Thread`, that receive some key from external service. Key have TTL, so it needs to be renewed from time to time.\n\nThe problem is when i load data by first endpoint, the database i'm loading into, is pretty slow and can answer up to 10 seconds. In that moment all other endpoints(including `/ping`) is locked. So k8s is thinking that my app is dead and try to rollback it.\n\nI could simply try to increase the number of workers, that serve the application with command `uvicorn main:app --workers 4`\nBUT additional thread is also spawning with each worker and output in logs looks smth like that\n\n```\nINFO: Application startup complete.\nHello from additional thread\nINFO: Started server process [88030]\nHello from additional thread \nINFO: Waiting for application startup\nHello from additional thread Hello from additional thread\nINFO: Application startup complete. Hello from additional thread\n```\n\nMy question *is it possible to spawn only one additional thread with multiple gunicorn workers?*\n\nHere is code snippet from my main.py\n\n```\n@app.post(\"/api/v1/create_user\")\nasync def create_user() -> JSONResponse:\n \"\"\"Some creation magic here\"\"\"\n return JSONResponse(status_code=status.HTTP_201_CREATED, content={\"Success\": True, \"Username\":raw_credentials[\"user\"]})\n \n \n@app.get(\"/ping\", status_code=status.HTTP_200_OK)\nasync def dummy_response():\n return\n\n# Special treads lunching for some jobs that need to be repeated during app lifecycle.\nt1 = Thread(target=renew_api_token)\nt1.start()\n```\n\n========================================\n\nCode:\n```text\nINFO: Application startup complete.\nHello from additional thread\nINFO: Started server process [88030]\nHello from additional thread \nINFO: Waiting for application startup\nHello from additional thread Hello from additional thread\nINFO: Application startup complete. Hello from additional thread\n```\n\n```text\n@app.post(\"/api/v1/create_user\")\nasync def create_user() -> JSONResponse:\n \"\"\"Some creation magic here\"\"\"\n return JSONResponse(status_code=status.HTTP_201_CREATED, content={\"Success\": True, \"Username\":raw_credentials[\"user\"]})\n \n \n@app.get(\"/ping\", status_code=status.HTTP_200_OK)\nasync def dummy_response():\n return\n\n# Special treads lunching for some jobs that need to be repeated during app lifecycle.\nt1 = Thread(target=renew_api_token)\nt1.start()\n```\n\n```text\n/create_user\n```\n\n```text\n/ping\n```\n\n```text\nthreading.Thread\n```\n\n```text\n/ping\n```\n\n```text\nuvicorn main:app --workers 4\n```\n\n```text\ndef create_user()\n```\n\n```text\nasync def create_user()\n```\n\n========================================\n\nComments:\n- Thanks a lot! I forget that with normal def instead of async def FastAPI run function inside ThreadPool. Search for async db lib i think is overkill, cause service will be running with not so big load\n- I came across this question when implementing API for ML. It is not possible to implement PyTorch inference on CPU using async approach. Probably most of tools for ML in python don't support async inference. To summarize, this is not a viable solution for ML.","metadata":{"transformedAt":"2026-08-18T18:32:29.136Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":110,"estimatedTokens":930}}477{"id":"stack-78094087","source":"stackoverflow","questionId":78094087,"title":"How do I correctly route FastAPI on AWS Lambda using Mangum to avoid a 'not found' error?","tags":["aws-lambda","aws-api-gateway","fastapi","mangum"],"text":"Title: How do I correctly route FastAPI on AWS Lambda using Mangum to avoid a 'not found' error?\nTags: aws-lambda, aws-api-gateway, fastapi, mangum\nSource: Stack Overflow\n\nQuestion:\nI have an AWS Lambda function which I can't seem to hook up to a custom domain using AWS API Gateway. I consistently get a `{\"detail\":\"Not Found\"}` error when I curl:\n\n```\nhttps://api.domain.com/api/v1/users\nhttps://api.domain.com/api/v1/users/1\n```\n\nI added a catch all to return the method and the request with the code looking like this but I can't see how to match it to the returned url:\n\n```\nfrom fastapi import FastAPI, Request\nfrom mangum import Mangum\n\napp = FastAPI() # /api/v1/users/\n\n@app.get(\"/\")\ndef read_root():\n return {\"Hello\": \"World\"}\n\n@app.get(\"/users\")\ndef read_root():\n return {\"Hello\": \"Users\"}\n\n@app.get(\"/users/{user_id}\")\ndef user_item(user_id: int, q: str = None):\n return {\"user_id\": user_id, \"q\": q}\n\n# My catch all code\n#@app.api_route(\"/{path_name:path}\", methods=[\"GET\"])\n#async def catch_all(request: Request, path_name: str):\n# return {\"request_method\": request.method, \"path_name\": path_name}\n\nhandler = Mangum(app, lifespan=\"off\")\n```\n\nWhich, when uncommented returns the path_name correctly:\n\n```\n{\"request_method\":\"GET\",\"path_name\":\"api/v1/users\"}\n{\"request_method\":\"GET\",\"path_name\":\"api/v1/users/1\"}\n```\n\nI am totally stuck but I think it's something to do with either a prefix or a default root.\n\n========================================\n\nTop Answer:\nI have a solution which resolves the issue of '/docs' not rendering.\n\nMangum's `api_gateway_base_path` always drops the first `/`, so I don't use that feature. Instead, I modify the event before passing it to mangum:\n\n```\nfrom mangum import Mangum\nfrom src.app import app \n\n_handler = Mangum(app) \n\ndef handler(event, context):\n \n # Extract which API Gateway stage we're coming from\n stage = event.get('requestContext', {}).get('stage')\n\n # If we have a stage, remove '/' and '' prefixed routes\n prefixes = ['/' + stage, stage] if stage else []\n\n # Mine is routed from '/api/*' routes in cloudfront, so peel that off\n prefixes.append('/api')\n\n # remove the prefixes in order\n for prefix in prefixes:\n\n # Clean the rawPath\n if event.get('rawPath', '').startswith(prefix):\n event['rawPath'] = event['rawPath'][len(prefix):]\n\n # Clean the requestContext\n if event.get('requestContext', {}).get('http', {}).get('path', '').startswith(prefix):\n event['requestContext']['http']['path'] = event['requestContext']['http']['path'][len(prefix):]\n\n # Hand it off to mangum\n return _handler(event, context)\n```\n\n========================================\n\nCode:\n```text\nhttps://api.domain.com/api/v1/users\nhttps://api.domain.com/api/v1/users/1\n```\n\n```text\nfrom fastapi import FastAPI, Request\nfrom mangum import Mangum\n\napp = FastAPI() # /api/v1/users/\n\n\n@app.get(\"/\")\ndef read_root():\n return {\"Hello\": \"World\"}\n\n@app.get(\"/users\")\ndef read_root():\n return {\"Hello\": \"Users\"}\n\n@app.get(\"/users/{user_id}\")\ndef user_item(user_id: int, q: str = None):\n return {\"user_id\": user_id, \"q\": q}\n\n# My catch all code\n#@app.api_route(\"/{path_name:path}\", methods=[\"GET\"])\n#async def catch_all(request: Request, path_name: str):\n# return {\"request_method\": request.method, \"path_name\": path_name}\n\nhandler = Mangum(app, lifespan=\"off\")\n```\n\n```text\n{\"request_method\":\"GET\",\"path_name\":\"api/v1/users\"}\n{\"request_method\":\"GET\",\"path_name\":\"api/v1/users/1\"}\n```\n\n```text\n{\"detail\":\"Not Found\"}\n```\n\n```text\nfrom datetime import datetime\n\nfrom fastapi import FastAPI, Request\nfrom mangum import Mangum\nfrom pydantic import BaseModel\n\napp = FastAPI(\n root_path=\"/api/v1/users\"\n) \n\n@app.get('', include_in_schema=False)\n@app.get(\"/\")\ndef read_root(request: Request):\n return {\"Hello\": \"Users\"}\n\n\n\n# @app.api_route(\"/{path_name:path}\", methods=[\"GET\"])\n# async def catch_all(request: Request, path_name: str):\n# print(request.scope)\n# return {\n# \"request_method\": request.method,\n# \"root_path\": request.scope['root_path'],\n# \"raw_path\": request.scope['raw_path'],\n# \"path\": request.scope['path'],\n# \"path_name\": path_name\n \n# }\n\nhandler = Mangum(\n app, \n lifespan=\"off\", \n api_gateway_base_path='/api/v1/users'\n)\n```\n\n```text\napi_gateway_base_path='/api/v1/users'\n```\n\n```text\napi.domain.com/api/v1/users\n```\n\n```text\n/users/\n```\n\n```text\n/users/whatever\n```\n\n```text\nroot_path=\"/api/v1/users\"\n```\n\n```text\napi.domain.com/api/v1/users/docs\n```\n\n```text\napi.domain.com/api/v1/users\n```\n\n```text\n@app.get('', include_in_schema=False)\n```\n\n```text\nfrom mangum import Mangum\nfrom src.app import app \n\n_handler = Mangum(app) \n\ndef handler(event, context):\n \n # Extract which API Gateway stage we're coming from\n stage = event.get('requestContext', {}).get('stage')\n\n # If we have a stage, remove '/<stage>' and '<stage>' prefixed routes\n prefixes = ['/' + stage, stage] if stage else []\n\n # Mine is routed from '/api/*' routes in cloudfront, so peel that off\n prefixes.append('/api')\n\n # remove the prefixes in order\n for prefix in prefixes:\n\n # Clean the rawPath\n if event.get('rawPath', '').startswith(prefix):\n event['rawPath'] = event['rawPath'][len(prefix):]\n\n # Clean the requestContext\n if event.get('requestContext', {}).get('http', {}).get('path', '').startswith(prefix):\n event['requestContext']['http']['path'] = event['requestContext']['http']['path'][len(prefix):]\n\n # Hand it off to mangum\n return _handler(event, context)\n```\n\n```text\napi_gateway_base_path\n```\n\n```text\n/\n```\n\n========================================\n\nComments:\n- It's because of `api/v1`. Try setting `api_gateway_root_path` in the Mangum app. or set `API_GATEWAY_ROOT_PATH` the corresponding environment variable.","metadata":{"transformedAt":"2026-08-18T18:32:29.136Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":16,"totalLines":245,"estimatedTokens":1453}}478{"id":"stack-73630653","source":"stackoverflow","questionId":73630653,"title":"Redirect to login page if user not logged in using FastAPI-Login package","tags":["python","authentication","http-redirect","fastapi"],"text":"Title: Redirect to login page if user not logged in using FastAPI-Login package\nTags: python, authentication, http-redirect, fastapi\nSource: Stack Overflow\n\nQuestion:\nI would like to redirect users to the login page, when they are not logged in.\n\nHere is my code:\n\n```\nfrom fastapi import (\n Depends,\n FastAPI,\n HTTPException,\n status,\n Body,\n Request\n)\nfrom fastapi.encoders import jsonable_encoder\nfrom fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm\nfrom fastapi.responses import HTMLResponse, RedirectResponse\nimport app.models as models\nimport app.database as database\nfrom datetime import datetime, timedelta\nfrom jose import JWTError, jwt\nfrom starlette.responses import FileResponse\nfrom fastapi_login import LoginManager\nfrom fastapi_login.exceptions import InvalidCredentialsException\nfrom fastapi import Cookie\nimport re\n\napp = FastAPI()\n\noauth2_scheme = OAuth2PasswordBearer(tokenUrl=\"token\")\nmanager = LoginManager(SECRET_KEY, token_url=\"/auth/login\", use_cookie=True)\nmanager.cookie_name = \"token\"\n\n@app.get(\"/\")\n@app.get(\"/item\")\nasync def read_index(user=Depends(manager)):\n try:\n return FileResponse('item.html')\n except status.HTTP_401_UNAUTHORIZED:\n return RedirectResponse(url=\"/login\", status_code=status.HTTP_302_FOUND)\n```\n\nHowever, when I access this page: `localhost:8000/item`, I get the following:\n\n```\n{\"detail\":\"Not authenticated\"}\n```\n\n========================================\n\nCode:\n```py\nfrom fastapi import (\n Depends,\n FastAPI,\n HTTPException,\n status,\n Body,\n Request\n)\nfrom fastapi.encoders import jsonable_encoder\nfrom fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm\nfrom fastapi.responses import HTMLResponse, RedirectResponse\nimport app.models as models\nimport app.database as database\nfrom datetime import datetime, timedelta\nfrom jose import JWTError, jwt\nfrom starlette.responses import FileResponse\nfrom fastapi_login import LoginManager\nfrom fastapi_login.exceptions import InvalidCredentialsException\nfrom fastapi import Cookie\nimport re\n\napp = FastAPI()\n\noauth2_scheme = OAuth2PasswordBearer(tokenUrl=\"token\")\nmanager = LoginManager(SECRET_KEY, token_url=\"/auth/login\", use_cookie=True)\nmanager.cookie_name = \"token\"\n\n\n@app.get(\"/\")\n@app.get(\"/item\")\nasync def read_index(user=Depends(manager)):\n try:\n return FileResponse('item.html')\n except status.HTTP_401_UNAUTHORIZED:\n return RedirectResponse(url=\"/login\", status_code=status.HTTP_302_FOUND)\n```\n\n```text\n{\"detail\":\"Not authenticated\"}\n```\n\n```text\nlocalhost:8000/item\n```\n\n```py\nfrom fastapi import FastAPI, Depends, Request, Response, status\nfrom starlette.responses import RedirectResponse, HTMLResponse, JSONResponse\nfrom fastapi.security import OAuth2PasswordRequestForm\nfrom fastapi_login.exceptions import InvalidCredentialsException\nfrom fastapi_login import LoginManager\n\nclass NotAuthenticatedException(Exception):\n pass\n \napp = FastAPI()\nSECRET = \"super-secret-key\"\n# Note that in fastapi-login v1.10, the `custom_exception` param changed to `not_authenticated_exception`:\nmanager = LoginManager(SECRET, '/login', use_cookie=True, not_authenticated_exception=NotAuthenticatedException)\n\n\nDB = {\n 'users': {\n 'johndoe@mail.com': {\n 'name': 'John Doe',\n 'password': 'hunter2'\n }\n }\n}\n\ndef query_user(user_id: str):\n return DB['users'].get(user_id)\n\n\n@manager.user_loader()\ndef load_user(user_id: str):\n user = DB['users'].get(user_id)\n return user\n \n \n@app.exception_handler(NotAuthenticatedException)\ndef auth_exception_handler(request: Request, exc: NotAuthenticatedException):\n \"\"\"\n Redirect the user to the login page if not logged in\n \"\"\"\n return RedirectResponse(url='/login')\n \n\n@app.get(\"/login\", response_class=HTMLResponse)\ndef login_form():\n return \"\"\"\n <!DOCTYPE html>\n <html>\n <body>\n <form method=\"POST\" action=\"/login\">\n <label for=\"username\">Username:</label><br>\n <input type=\"text\" id=\"username\" name=\"username\" value=\"johndoe@mail.com\"><br>\n <label for=\"password\">Password:</label><br>\n <input type=\"password\" id=\"password\" name=\"password\" value=\"hunter2\"><br><br>\n <input type=\"submit\" value=\"Submit\">\n </form>\n </body>\n </html>\n \"\"\"\n\n \n@app.post('/login')\ndef login(data: OAuth2PasswordRequestForm = Depends()):\n email = data.username\n password = data.password\n user = query_user(email)\n if not user:\n # you can return any response or error of your choice\n raise InvalidCredentialsException\n elif password != user['password']:\n raise InvalidCredentialsException\n\n token = manager.create_access_token(data={'sub': email})\n response = RedirectResponse(url=\"/protected\",status_code=status.HTTP_302_FOUND)\n manager.set_cookie(response, token)\n return response\n\n\n@app.get('/protected')\ndef protected_route(user=Depends(manager)):\n return {'user': user}\n```\n\n```text\nFastAPI-Login\n```\n\n```text\nException\n```\n\n```text\nLoginManager\n```\n\n```text\nlogin\n```\n\n```text\nAuthorization\n```\n\n```text\n/protected\n```\n\n========================================\n\nComments:\n- Where did `status` come from? What does login manager? I’d login manager raises, the endpoint function is never called.\n- it is a good practice to redirect user to the next endpoint after login and get access token. But when you the url address bar does not change to the new one and stay the same as before. The second issue is about working with swagger. I would like to authenticate with swagger of fastapi. it needs to get a token directly.\n- to whomever reads this in the future. In fastapi-login 1.10 the line: `manager = LoginManager(SECRET, '/login', use_cookie=True, custom_exception=NotAuthenticatedException)` should be: `manager = LoginManager(SECRET, '/login', use_cookie=True, not_authenticated_exception=NotAuthenticatedException)` The name of the parameter has changed.","metadata":{"transformedAt":"2026-08-18T18:32:29.136Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":10,"totalLines":214,"estimatedTokens":1500}}479{"id":"stack-65243587","source":"stackoverflow","questionId":65243587,"title":"FastAPI async class dependencies","tags":["python","dependency-injection","async-await","python-asyncio","fastapi"],"text":"Title: FastAPI async class dependencies\nTags: python, dependency-injection, async-await, python-asyncio, fastapi\nSource: Stack Overflow\n\nQuestion:\nIn FastAPI when a standard function is used as a dependency it could be used declared as regular `def` function or an asynchronous `async def` function. FastAPI claims that it will do the right thing in either case.\n\nHowever dependencies created this way are not as friendly to autocomplete as class dependencies. Also class dependencies have a bit better declaration syntax one can just specify the type of dependency once and FastAPI will figure out which dependency you mean.\n\ndef read_item(common: CommonQueryParam = Depends()):\n\nBut of the class dependency needs to execute an async operation as a part of its initialization. Is it possible to use class dependencies and async together. Clearly one cannot declare class `__init__` function as async. Is there another way to make it work?\n\n========================================\n\nCode:\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\n__init__\n```\n\n```text\nasync def async_dep():\n await asyncio.sleep(0)\n return 1\n\n\nclass CommonQueryParams:\n def __init__(self, a: int = Depends(async_dep)):\n self.a = a\n```\n\n```text\n__init__\n```\n\n```text\nawait\n```\n\n```text\n__init__\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.136Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":7,"totalLines":50,"estimatedTokens":322}}480{"id":"stack-63868046","source":"stackoverflow","questionId":63868046,"title":"I can not read uploaded csv file in FastAPI","tags":["python","csv","fastapi"],"text":"Title: I can not read uploaded csv file in FastAPI\nTags: python, csv, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to iterate through a csv file. However, the received file is giving a hard time to read. I searched for this, I could not get a clear solution!\n\n```\n@app.get(\"/uploadsequence/\")\nasync def upload_sequence_form():\n return HTMLResponse(\"\"\"\n \n \n \n sequence upload\n \n \n \n\n### upload sequence .CSV file\n\n \n Upload a csv file: \n \n \n \n \n \"\"\")\n\n@app.post(\"/uploadsequence/\")\nasync def upload_sequence(csv_file: UploadFile = File(...), db = Depends(get_db)):\n csv_file_encoded = TextIOWrapper(csv_file.file, encoding='utf-8')\n csv_reader = csv.DictReader(csv_file_encoded)\n for row in csv_reader:\n if row[\"Well Type\"] in [\"RIG MAINTENANCE\",\"RIG MOVE\",\"RIG COMMISSIONING\",\"ABANDONMENT\",\"LEARNINGCURVE\"]:\n crud.insert_sequence_record(db=db, row=row,is_drilling=False)\n else:\n crud.insert_sequence_record(db=db, row=row,is_drilling=True)\n```\n\nIt gives me this error:\n`csv_file_encoded = TextIOWrapper(csv_file.file, encoding='utf-8') AttributeError: 'SpooledTemporaryFile' object has no attribute 'readable'`\n\nI changed `UploadFile` to `bytes`:\n\n```\n@app.post(\"/uploadsequence/\")\nasync def upload_sequence(csv_file: bytes = File(...), db = Depends(get_db)):\n csv_file_encoded = TextIOWrapper(csv_file, encoding='utf-8')\n csv_reader = csv.DictReader(csv_file_encoded)\n for row in csv_reader:\n if row[\"Well Type\"] in [\"RIG MAINTENANCE\",\"RIG MOVE\",\"RIG COMMISSIONING\",\"ABANDONMENT\",\"LEARNINGCURVE\"]:\n crud.insert_sequence_record(db=db, row=row,is_drilling=False)\n else:\n crud.insert_sequence_record(db=db, row=row,is_drilling=True)\n```\n\nIt gives this error: `csv_file_encoded = TextIOWrapper(csv_file, encoding='utf-8') AttributeError: 'bytes' object has no attribute 'readable'`\n\nI got rid of encoding:\n\n```\n@app.post(\"/uploadsequence/\")\nasync def upload_sequence(csv_file: bytes = File(...), db = Depends(get_db)):\n # csv_file_encoded = TextIOWrapper(csv_file, encoding='utf-8')\n csv_reader = csv.DictReader(csv_file)\n for row in csv_reader:\n if row[\"Well Type\"] in [\"RIG MAINTENANCE\",\"RIG MOVE\",\"RIG COMMISSIONING\",\"ABANDONMENT\",\"LEARNINGCURVE\"]:\n crud.insert_sequence_record(db=db, row=row,is_drilling=False)\n else:\n crud.insert_sequence_record(db=db, row=row,is_drilling=True)\n```\n\nIt gives this error:\n`self._fieldnames = next(self.reader) _csv.Error: iterator should return strings, not int (did you open the file in text mode?)`\n\n========================================\n\nTop Answer:\n```\n@app.post(\"/submitform\")\nasync def handle_form(assignment_file: UploadFile = File(...)):\n print(assignment_file.filename)\n csv_reader = pd.read_csv(assignment_file.file)\n \n print(csv_reader)\n //else return response\n // csv data will be stored in the csv_reader\n```\n\n========================================\n\nCode:\n```text\n@app.get(\"/uploadsequence/\")\nasync def upload_sequence_form():\n return HTMLResponse(\"\"\"\n <!DOCTYPE html>\n <html>\n <head>\n <title>sequence upload</title>\n </head>\n <body>\n <h1>upload sequence .CSV file</h1>\n <form method='post' action='/uploadsequence/' enctype='multipart/form-data'>\n Upload a csv file: <input type='file' name='csv_file'>\n <input type='submit' value='Upload'>\n </form>\n </body>\n </html>\n \"\"\")\n\n@app.post(\"/uploadsequence/\")\nasync def upload_sequence(csv_file: UploadFile = File(...), db = Depends(get_db)):\n csv_file_encoded = TextIOWrapper(csv_file.file, encoding='utf-8')\n csv_reader = csv.DictReader(csv_file_encoded)\n for row in csv_reader:\n if row[\"Well Type\"] in [\"RIG MAINTENANCE\",\"RIG MOVE\",\"RIG COMMISSIONING\",\"ABANDONMENT\",\"LEARNINGCURVE\"]:\n crud.insert_sequence_record(db=db, row=row,is_drilling=False)\n else:\n crud.insert_sequence_record(db=db, row=row,is_drilling=True)\n```\n\n```text\n@app.post(\"/uploadsequence/\")\nasync def upload_sequence(csv_file: bytes = File(...), db = Depends(get_db)):\n csv_file_encoded = TextIOWrapper(csv_file, encoding='utf-8')\n csv_reader = csv.DictReader(csv_file_encoded)\n for row in csv_reader:\n if row[\"Well Type\"] in [\"RIG MAINTENANCE\",\"RIG MOVE\",\"RIG COMMISSIONING\",\"ABANDONMENT\",\"LEARNINGCURVE\"]:\n crud.insert_sequence_record(db=db, row=row,is_drilling=False)\n else:\n crud.insert_sequence_record(db=db, row=row,is_drilling=True)\n```\n\n```text\n@app.post(\"/uploadsequence/\")\nasync def upload_sequence(csv_file: bytes = File(...), db = Depends(get_db)):\n # csv_file_encoded = TextIOWrapper(csv_file, encoding='utf-8')\n csv_reader = csv.DictReader(csv_file)\n for row in csv_reader:\n if row[\"Well Type\"] in [\"RIG MAINTENANCE\",\"RIG MOVE\",\"RIG COMMISSIONING\",\"ABANDONMENT\",\"LEARNINGCURVE\"]:\n crud.insert_sequence_record(db=db, row=row,is_drilling=False)\n else:\n crud.insert_sequence_record(db=db, row=row,is_drilling=True)\n```\n\n```text\ncsv_file_encoded = TextIOWrapper(csv_file.file, encoding='utf-8') AttributeError: 'SpooledTemporaryFile' object has no attribute 'readable'\n```\n\n```text\nUploadFile\n```\n\n```text\nbytes\n```\n\n```text\ncsv_file_encoded = TextIOWrapper(csv_file, encoding='utf-8') AttributeError: 'bytes' object has no attribute 'readable'\n```\n\n```text\nself._fieldnames = next(self.reader) _csv.Error: iterator should return strings, not int (did you open the file in text mode?)\n```\n\n```text\ncsv_reader = csv.reader(codecs.iterdecode(csv_file.file,'utf-8'))\n```\n\n```text\ncodecs.iterdecode\n```\n\n```text\n@app.post(\"/submitform\")\nasync def handle_form(assignment_file: UploadFile = File(...)):\n print(assignment_file.filename)\n csv_reader = pd.read_csv(assignment_file.file)\n \n print(csv_reader)\n //else return response\n // csv data will be stored in the csv_reader\n```\n\n========================================\n\nComments:\n- In the first case you simply have a `File` object that you can use as a classic file. In the second case, you have the raw bytes. Thus you can't open a file from the file you already have nor by passing the bytes. You could try using the `DictReader` on the spooled file, instead of the bytes\n- @Sören It is a standard python library\n- Future readers may want to have a look at this answer as well.\n- I think this is method using pandas will be slower than using the standard libraries\n- How do you do this without uploading CSV, but reading csv off a path directly from Python?","metadata":{"transformedAt":"2026-08-18T18:32:29.137Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":11,"totalLines":194,"estimatedTokens":1665}}481{"id":"stack-71244472","source":"stackoverflow","questionId":71244472,"title":"Keep getting CORS policy: No 'Access-Control-Allow-Origin' even with FastAPI CORSMiddleware","tags":["python","reactjs","fastapi","http-status-code-500"],"text":"Title: Keep getting CORS policy: No 'Access-Control-Allow-Origin' even with FastAPI CORSMiddleware\nTags: python, reactjs, fastapi, http-status-code-500\nSource: Stack Overflow\n\nQuestion:\nI am working on a project that has a FastAPI back end with a React Frontend. When calling the back end via `fetch` I sometimes get the following:\n\n```\nAccess to fetch at 'http://localhost:8000/get-main-query-data' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.\n```\n\nThis happens every so often, I can call one endpoint then the error gets thrown. Sometimes the error gets thrown for all endpoints\n\nI have set up `Middleware` in my `main.py` like so: (also at this line)\n\n```\n# allows cross-origin requests from React\norigins = [\n \"http://localhost\",\n \"http://localhost:3000\",\n]\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=origins,\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n```\n\nCould this be an issue with fetch it's self? I am worried at when I get to host this ill be getting CORS errors and my prototype won't be working :(\n\nThe whole `main.py` is like so:\n\n### Backend\n\n```\n\"\"\" API to allow for data retrieval and manipulation. \"\"\"\nfrom typing import Optional\n\nfrom fastapi import FastAPI, HTTPException, status\nfrom fastapi.middleware.cors import CORSMiddleware\nfrom pydantic import BaseModel\n\nimport models\nfrom db import Session\n\napp = FastAPI()\n\n\"\"\" Pydantic BaseModels for the API. \"\"\"\n\nclass SignalJourneyAudiences(BaseModel):\n \"\"\"SignalJourneyAudiences BaseModel.\"\"\"\n\n audienceId: Optional[int] # PK\n segment: str\n enabled: bool\n\nclass SignalJourneyAudienceConstraints(BaseModel):\n \"\"\"SignalJourneyAudienceConstraints BaseModel.\"\"\"\n\n uid: Optional[int] # PK\n constraintId: int\n audienceId: int # FK - SignalJourneyAudiences -> audienceId\n sourceId: int # FK - SignalJourneySources -> sourceId\n constraintTypeId: int # FK - SignalJourneyConstraintType -> constraintTypeId\n constraintValue: str\n targeting: bool\n frequency: int\n period: int\n\nclass SignalJourneyAudienceConstraintRelations(BaseModel):\n \"\"\"SignalJourneyAudienceConstraintRelations BaseModel.\"\"\"\n\n uid: Optional[int] # PK\n audienceId: int\n relation: str\n constraintIds: str\n\nclass SignalJourneyConstraintType(BaseModel):\n \"\"\"SignalJourneyConstraintType BaseModel.\"\"\"\n\n constraintTypeId: Optional[int] # PK\n constraintType: str\n\nclass SingalJourneySources(BaseModel):\n \"\"\"SignalJourneySources BaseModel.\"\"\"\n\n sourceId: Optional[int] # PK\n source: str\n\n# allows cross-origin requests from React\norigins = [\n \"http://localhost\",\n \"http://localhost:3000\",\n]\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=origins,\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n\n# database instance\ndb = Session()\n\n@app.get(\"/\")\ndef index():\n \"\"\"Root endpoint.\"\"\"\n return {\n \"messagee\": \"Welcome to Signal Journey API. Please use the API documentation to learn more.\"\n }\n\n@app.get(\"/audiences\", status_code=status.HTTP_200_OK)\ndef get_audiences():\n \"\"\"Get all audience data from the database.\"\"\"\n return db.query(models.SignalJourneyAudiences).all()\n\n@app.get(\"/audience-constraints\", status_code=status.HTTP_200_OK)\ndef get_audience_constraints():\n \"\"\"Get all audience constraint data from the database.\"\"\"\n return db.query(models.SignalJourneyAudienceConstraints).all()\n\n@app.get(\"/audience-constraints-relations\", status_code=status.HTTP_200_OK)\ndef get_audience_constraints_relations():\n \"\"\"Get all audience constraint data from the database.\"\"\"\n return db.query(models.SignalJourneyAudienceConstraintRelations).all()\n\n@app.get(\"/get-constraint-types\", status_code=status.HTTP_200_OK)\ndef get_constraints_type():\n \"\"\"Get all audience constraint data from the database.\"\"\"\n\n return db.query(models.SignalJourneyConstraintType).all()\n\n@app.post(\"/add-constraint-type\", status_code=status.HTTP_200_OK)\ndef add_constraint_type(sjct: SignalJourneyConstraintType):\n \"\"\"Add a constraint type to the database.\"\"\"\n\n constraint_type_query = (\n db.query(models.SignalJourneyConstraintType)\n .filter(\n models.SignalJourneyConstraintType.constraintType\n == sjct.constraintType.upper()\n and models.SignalJourneyConstraintType.constraintTypeId\n == sjct.constraintTypeId\n )\n .first()\n )\n\n if constraint_type_query is not None:\n raise HTTPException(\n status_code=status.HTTP_400_BAD_REQUEST,\n detail=\"Constaint type already exists.\",\n )\n\n constraint_type = models.SignalJourneyConstraintType(\n constraintType=sjct.constraintType.upper(),\n )\n\n db.add(constraint_type)\n db.commit()\n\n return {\n \"message\": f\"Constraint type {sjct.constraintType.upper()} added successfully.\"\n }\n\n@app.get(\"/get-sources\", status_code=status.HTTP_200_OK)\ndef get_sources():\n \"\"\"Get all sources data from the database.\"\"\"\n return db.query(models.SingalJourneySources).all()\n\n@app.post(\"/add-source\", status_code=status.HTTP_200_OK)\ndef add_source_type(sjs: SingalJourneySources):\n \"\"\"Add a new source type to the database.\"\"\"\n source_type_query = (\n db.query(models.SingalJourneySources)\n .filter(models.SingalJourneySources.source == sjs.source.upper())\n .first()\n )\n\n if source_type_query is not None:\n raise HTTPException(\n status_code=status.HTTP_400_BAD_REQUEST,\n detail=\"Source already exists.\",\n )\n\n source_type = models.SingalJourneySources(source=sjs.source.upper())\n\n db.add(source_type)\n db.commit()\n\n return {\"message\": f\"Source {sjs.source.upper()} added successfully.\"}\n\n\"\"\"\nEndpoints for populating the UI with data. These need to consist of some joins.\n\nQuery to be used in SQL \n\nSELECT\n constraintid,\n sja.segment,\n sjs.source,\n sjct.constrainttype,\n constraintvalue,\n targeting,\n frequency,\n period\nFROM signaljourneyaudienceconstraints\nJOIN signaljourneyaudiences sja ON sja.audienceid = signaljourneyaudienceconstraints.audienceid;\nJOIN signaljourneysources sjs ON sjs.sourceid = signaljourneyaudienceconstraints.sourceid\nJOIN signaljourneyconstrainttype sjct ON sjct.constrainttypeid = signaljourneyaudienceconstraints.constrainttypeid\n\"\"\"\n\n@app.get(\"/get-main-query-data\", status_code=status.HTTP_200_OK)\ndef get_main_query_data():\n \"\"\"Returns data for the main query.\"\"\"\n return (\n db.query(\n models.SignalJourneyAudienceConstraints.constraintId,\n models.SignalJourneyAudiences.segment,\n models.SingalJourneySources.source,\n models.SignalJourneyConstraintType.constraintType,\n models.SignalJourneyAudienceConstraints.constraintValue,\n models.SignalJourneyAudienceConstraints.targeting,\n models.SignalJourneyAudienceConstraints.frequency,\n models.SignalJourneyAudienceConstraints.period,\n )\n .join(\n models.SignalJourneyAudiences,\n models.SignalJourneyAudiences.audienceId\n == models.SignalJourneyAudienceConstraints.audienceId,\n )\n .join(\n models.SingalJourneySources,\n models.SingalJourneySources.sourceId\n == models.SignalJourneyAudienceConstraints.sourceId,\n )\n .join(\n models.SignalJourneyConstraintType,\n models.SignalJourneyConstraintType.constraintTypeId\n == models.SignalJourneyAudienceConstraints.constraintTypeId,\n )\n .all()\n )\n```\n\n### Frontend\n\nI am calling my API endpoints like so:\n\n```\n//form.jsx\n\n // pulls segments name from signaljourneyaudiences\n useEffect(() => {\n fetch('http://localhost:8000/audiences')\n .then((res) => res.json())\n .then((data) => setSegmentNames(data))\n .catch((err) => console.log(err));\n }, []);\n\n // pulls field names from signaljourneyaudiences\n useEffect(() => {\n fetch('http://localhost:8000/get-constraint-types')\n .then((res) => res.json())\n .then((data) => setConstraints(data))\n .catch((err) => console.log(err));\n }, []);\n\n// table.jsx\n\n useEffect(() => {\n fetch('http://localhost:8000/get-main-query-data')\n .then((res) => res.json())\n .then((data) => {\n setTableData(data);\n })\n .catch((err) => console.log(err));\n }, []);\n```\n\nAs you can see here the table has been populated by the endpoints but on the other hand, one of the dropdowns have not.\n\nhttps://i.sstatic.net/NhTdI.png\n\n### HTTP 500 error description\n\n```\nINFO: 127.0.0.1:62301 - \"GET /get-constraint-types HTTP/1.1\" 500 Internal Server Error\n2022-02-24 09:26:44,234 INFO sqlalchemy.engine.Engine [cached since 2972s ago] ()\nERROR: Exception in ASGI application\nTraceback (most recent call last):\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/engine/base.py\", line 1702, in _execute_context\n context = constructor(\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/engine/default.py\", line 1013, in _init_compiled\n self.cursor = self.create_cursor()\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/engine/default.py\", line 1361, in create_cursor\n return self.create_default_cursor()\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/engine/default.py\", line 1364, in create_default_cursor\n return self._dbapi_connection.cursor()\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/pool/base.py\", line 1083, in cursor\n return self.dbapi_connection.cursor(*args, **kwargs)\nsqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 6191820800 and this is thread id 6174994432.\n\nThe above exception was the direct cause of the following exception:\n\nTraceback (most recent call last):\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/uvicorn/protocols/http/httptools_impl.py\", line 372, in run_asgi\n result = await app(self.scope, self.receive, self.send)\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/uvicorn/middleware/proxy_headers.py\", line 75, in __call__\n return await self.app(scope, receive, send)\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/fastapi/applications.py\", line 259, in __call__\n await super().__call__(scope, receive, send)\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/starlette/applications.py\", line 112, in __call__\n await self.middleware_stack(scope, receive, send)\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/starlette/middleware/errors.py\", line 181, in __call__\n raise exc\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/starlette/middleware/errors.py\", line 159, in __call__\n await self.app(scope, receive, _send)\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/starlette/middleware/cors.py\", line 92, in __call__\n await self.simple_response(scope, receive, send, request_headers=headers)\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/starlette/middleware/cors.py\", line 147, in simple_response\n await self.app(scope, receive, send)\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/starlette/exceptions.py\", line 82, in __call__\n raise exc\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/starlette/exceptions.py\", line 71, in __call__\n await self.app(scope, receive, sender)\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/fastapi/middleware/asyncexitstack.py\", line 21, in __call__\n raise e\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/fastapi/middleware/asyncexitstack.py\", line 18, in __call__\n await self.app(scope, receive, send)\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/starlette/routing.py\", line 656, in __call__\n await route.handle(scope, receive, send)\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/starlette/routing.py\", line 259, in handle\n await self.app(scope, receive, send)\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/starlette/routing.py\", line 61, in app\n response = await func(request)\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/fastapi/routing.py\", line 227, in app\n raw_response = await run_endpoint_function(\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/fastapi/routing.py\", line 162, in run_endpoint_function\n return await run_in_threadpool(dependant.call, **values)\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/starlette/concurrency.py\", line 39, in run_in_threadpool\n return await anyio.to_thread.run_sync(func, *args)\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/anyio/to_thread.py\", line 28, in run_sync\n return await get_asynclib().run_sync_in_worker_thread(func, *args, cancellable=cancellable,\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/anyio/_backends/_asyncio.py\", line 818, in run_sync_in_worker_thread\n return await future\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/anyio/_backends/_asyncio.py\", line 754, in run\n result = context.run(func, *args)\n File \"/Users/paul/Developer/signal_journey/backend/./main.py\", line 109, in get_constraints_type\n return db.query(models.SignalJourneyConstraintType).all()\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/orm/query.py\", line 2759, in all\n return self._iter().all()\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/orm/query.py\", line 2894, in _iter\n result = self.session.execute(\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/orm/session.py\", line 1692, in execute\n result = conn._execute_20(statement, params or {}, execution_options)\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/engine/base.py\", line 1614, in _execute_20\n return meth(self, args_10style, kwargs_10style, execution_options)\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/sql/elements.py\", line 325, in _execute_on_connection\n return connection._execute_clauseelement(\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/engine/base.py\", line 1481, in _execute_clauseelement\n ret = self._execute_context(\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/engine/base.py\", line 1708, in _execute_context\n self._handle_dbapi_exception(\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/engine/base.py\", line 2026, in _handle_dbapi_exception\n util.raise_(\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/util/compat.py\", line 207, in raise_\n raise exception\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/engine/base.py\", line 1702, in _execute_context\n context = constructor(\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/engine/default.py\", line 1013, in _init_compiled\n self.cursor = self.create_cursor()\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/engine/default.py\", line 1361, in create_cursor\n return self.create_default_cursor()\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/engine/default.py\", line 1364, in create_default_cursor\n return self._dbapi_connection.cursor()\n File \"/Users/paul/.local//virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/pool/base.py\", line 1083, in cursor\n return self.dbapi_connection.cursor(*args, **kwargs)\nsqlalchemy.exc.ProgrammingError: (sqlite3.ProgrammingError) SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 6191820800 and this is thread id 6174994432.\n[SQL: SELECT \"SignalJourneyConstraintType\".\"constraintTypeId\" AS \"SignalJourneyConstraintType_constraintTypeId\", \"SignalJourneyConstraintType\".\"constraintType\" AS \"SignalJourneyConstraintType_constraintType\" \nFROM \"SignalJourneyConstraintType\"]\n[parameters: [{}]]\n(Background on this error at: https://sqlalche.me/e/14/f405)\n```\n\n========================================\n\nCode:\n```text\nAccess to fetch at 'http://localhost:8000/get-main-query-data' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.\n```\n\n```py\n# allows cross-origin requests from React\norigins = [\n \"http://localhost\",\n \"http://localhost:3000\",\n]\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=origins,\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n```\n\n```py\n\"\"\" API to allow for data retrieval and manipulation. \"\"\"\nfrom typing import Optional\n\nfrom fastapi import FastAPI, HTTPException, status\nfrom fastapi.middleware.cors import CORSMiddleware\nfrom pydantic import BaseModel\n\nimport models\nfrom db import Session\n\napp = FastAPI()\n\n\"\"\" Pydantic BaseModels for the API. \"\"\"\n\n\nclass SignalJourneyAudiences(BaseModel):\n \"\"\"SignalJourneyAudiences BaseModel.\"\"\"\n\n audienceId: Optional[int] # PK\n segment: str\n enabled: bool\n\n\nclass SignalJourneyAudienceConstraints(BaseModel):\n \"\"\"SignalJourneyAudienceConstraints BaseModel.\"\"\"\n\n uid: Optional[int] # PK\n constraintId: int\n audienceId: int # FK - SignalJourneyAudiences -> audienceId\n sourceId: int # FK - SignalJourneySources -> sourceId\n constraintTypeId: int # FK - SignalJourneyConstraintType -> constraintTypeId\n constraintValue: str\n targeting: bool\n frequency: int\n period: int\n\n\nclass SignalJourneyAudienceConstraintRelations(BaseModel):\n \"\"\"SignalJourneyAudienceConstraintRelations BaseModel.\"\"\"\n\n uid: Optional[int] # PK\n audienceId: int\n relation: str\n constraintIds: str\n\n\nclass SignalJourneyConstraintType(BaseModel):\n \"\"\"SignalJourneyConstraintType BaseModel.\"\"\"\n\n constraintTypeId: Optional[int] # PK\n constraintType: str\n\n\nclass SingalJourneySources(BaseModel):\n \"\"\"SignalJourneySources BaseModel.\"\"\"\n\n sourceId: Optional[int] # PK\n source: str\n\n\n# allows cross-origin requests from React\norigins = [\n \"http://localhost\",\n \"http://localhost:3000\",\n]\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=origins,\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n\n# database instance\ndb = Session()\n\n\n@app.get(\"/\")\ndef index():\n \"\"\"Root endpoint.\"\"\"\n return {\n \"messagee\": \"Welcome to Signal Journey API. Please use the API documentation to learn more.\"\n }\n\n\n@app.get(\"/audiences\", status_code=status.HTTP_200_OK)\ndef get_audiences():\n \"\"\"Get all audience data from the database.\"\"\"\n return db.query(models.SignalJourneyAudiences).all()\n\n\n@app.get(\"/audience-constraints\", status_code=status.HTTP_200_OK)\ndef get_audience_constraints():\n \"\"\"Get all audience constraint data from the database.\"\"\"\n return db.query(models.SignalJourneyAudienceConstraints).all()\n\n\n@app.get(\"/audience-constraints-relations\", status_code=status.HTTP_200_OK)\ndef get_audience_constraints_relations():\n \"\"\"Get all audience constraint data from the database.\"\"\"\n return db.query(models.SignalJourneyAudienceConstraintRelations).all()\n\n\n@app.get(\"/get-constraint-types\", status_code=status.HTTP_200_OK)\ndef get_constraints_type():\n \"\"\"Get all audience constraint data from the database.\"\"\"\n\n return db.query(models.SignalJourneyConstraintType).all()\n\n\n@app.post(\"/add-constraint-type\", status_code=status.HTTP_200_OK)\ndef add_constraint_type(sjct: SignalJourneyConstraintType):\n \"\"\"Add a constraint type to the database.\"\"\"\n\n constraint_type_query = (\n db.query(models.SignalJourneyConstraintType)\n .filter(\n models.SignalJourneyConstraintType.constraintType\n == sjct.constraintType.upper()\n and models.SignalJourneyConstraintType.constraintTypeId\n == sjct.constraintTypeId\n )\n .first()\n )\n\n if constraint_type_query is not None:\n raise HTTPException(\n status_code=status.HTTP_400_BAD_REQUEST,\n detail=\"Constaint type already exists.\",\n )\n\n constraint_type = models.SignalJourneyConstraintType(\n constraintType=sjct.constraintType.upper(),\n )\n\n db.add(constraint_type)\n db.commit()\n\n return {\n \"message\": f\"Constraint type {sjct.constraintType.upper()} added successfully.\"\n }\n\n\n@app.get(\"/get-sources\", status_code=status.HTTP_200_OK)\ndef get_sources():\n \"\"\"Get all sources data from the database.\"\"\"\n return db.query(models.SingalJourneySources).all()\n\n\n@app.post(\"/add-source\", status_code=status.HTTP_200_OK)\ndef add_source_type(sjs: SingalJourneySources):\n \"\"\"Add a new source type to the database.\"\"\"\n source_type_query = (\n db.query(models.SingalJourneySources)\n .filter(models.SingalJourneySources.source == sjs.source.upper())\n .first()\n )\n\n if source_type_query is not None:\n raise HTTPException(\n status_code=status.HTTP_400_BAD_REQUEST,\n detail=\"Source already exists.\",\n )\n\n source_type = models.SingalJourneySources(source=sjs.source.upper())\n\n db.add(source_type)\n db.commit()\n\n return {\"message\": f\"Source {sjs.source.upper()} added successfully.\"}\n\n\n\"\"\"\nEndpoints for populating the UI with data. These need to consist of some joins.\n\nQuery to be used in SQL \n\nSELECT\n constraintid,\n sja.segment,\n sjs.source,\n sjct.constrainttype,\n constraintvalue,\n targeting,\n frequency,\n period\nFROM signaljourneyaudienceconstraints\nJOIN signaljourneyaudiences sja ON sja.audienceid = signaljourneyaudienceconstraints.audienceid;\nJOIN signaljourneysources sjs ON sjs.sourceid = signaljourneyaudienceconstraints.sourceid\nJOIN signaljourneyconstrainttype sjct ON sjct.constrainttypeid = signaljourneyaudienceconstraints.constrainttypeid\n\"\"\"\n\n\n@app.get(\"/get-main-query-data\", status_code=status.HTTP_200_OK)\ndef get_main_query_data():\n \"\"\"Returns data for the main query.\"\"\"\n return (\n db.query(\n models.SignalJourneyAudienceConstraints.constraintId,\n models.SignalJourneyAudiences.segment,\n models.SingalJourneySources.source,\n models.SignalJourneyConstraintType.constraintType,\n models.SignalJourneyAudienceConstraints.constraintValue,\n models.SignalJourneyAudienceConstraints.targeting,\n models.SignalJourneyAudienceConstraints.frequency,\n models.SignalJourneyAudienceConstraints.period,\n )\n .join(\n models.SignalJourneyAudiences,\n models.SignalJourneyAudiences.audienceId\n == models.SignalJourneyAudienceConstraints.audienceId,\n )\n .join(\n models.SingalJourneySources,\n models.SingalJourneySources.sourceId\n == models.SignalJourneyAudienceConstraints.sourceId,\n )\n .join(\n models.SignalJourneyConstraintType,\n models.SignalJourneyConstraintType.constraintTypeId\n == models.SignalJourneyAudienceConstraints.constraintTypeId,\n )\n .all()\n )\n```\n\n```js\n//form.jsx\n\n // pulls segments name from signaljourneyaudiences\n useEffect(() => {\n fetch('http://localhost:8000/audiences')\n .then((res) => res.json())\n .then((data) => setSegmentNames(data))\n .catch((err) => console.log(err));\n }, []);\n\n // pulls field names from signaljourneyaudiences\n useEffect(() => {\n fetch('http://localhost:8000/get-constraint-types')\n .then((res) => res.json())\n .then((data) => setConstraints(data))\n .catch((err) => console.log(err));\n }, []);\n\n// table.jsx\n\n\n useEffect(() => {\n fetch('http://localhost:8000/get-main-query-data')\n .then((res) => res.json())\n .then((data) => {\n setTableData(data);\n })\n .catch((err) => console.log(err));\n }, []);\n```\n\n```text\nINFO: 127.0.0.1:62301 - \"GET /get-constraint-types HTTP/1.1\" 500 Internal Server Error\n2022-02-24 09:26:44,234 INFO sqlalchemy.engine.Engine [cached since 2972s ago] ()\nERROR: Exception in ASGI application\nTraceback (most recent call last):\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/engine/base.py\", line 1702, in _execute_context\n context = constructor(\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/engine/default.py\", line 1013, in _init_compiled\n self.cursor = self.create_cursor()\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/engine/default.py\", line 1361, in create_cursor\n return self.create_default_cursor()\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/engine/default.py\", line 1364, in create_default_cursor\n return self._dbapi_connection.cursor()\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/pool/base.py\", line 1083, in cursor\n return self.dbapi_connection.cursor(*args, **kwargs)\nsqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 6191820800 and this is thread id 6174994432.\n\nThe above exception was the direct cause of the following exception:\n\nTraceback (most recent call last):\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/uvicorn/protocols/http/httptools_impl.py\", line 372, in run_asgi\n result = await app(self.scope, self.receive, self.send)\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/uvicorn/middleware/proxy_headers.py\", line 75, in __call__\n return await self.app(scope, receive, send)\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/fastapi/applications.py\", line 259, in __call__\n await super().__call__(scope, receive, send)\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/starlette/applications.py\", line 112, in __call__\n await self.middleware_stack(scope, receive, send)\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/starlette/middleware/errors.py\", line 181, in __call__\n raise exc\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/starlette/middleware/errors.py\", line 159, in __call__\n await self.app(scope, receive, _send)\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/starlette/middleware/cors.py\", line 92, in __call__\n await self.simple_response(scope, receive, send, request_headers=headers)\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/starlette/middleware/cors.py\", line 147, in simple_response\n await self.app(scope, receive, send)\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/starlette/exceptions.py\", line 82, in __call__\n raise exc\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/starlette/exceptions.py\", line 71, in __call__\n await self.app(scope, receive, sender)\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/fastapi/middleware/asyncexitstack.py\", line 21, in __call__\n raise e\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/fastapi/middleware/asyncexitstack.py\", line 18, in __call__\n await self.app(scope, receive, send)\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/starlette/routing.py\", line 656, in __call__\n await route.handle(scope, receive, send)\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/starlette/routing.py\", line 259, in handle\n await self.app(scope, receive, send)\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/starlette/routing.py\", line 61, in app\n response = await func(request)\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/fastapi/routing.py\", line 227, in app\n raw_response = await run_endpoint_function(\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/fastapi/routing.py\", line 162, in run_endpoint_function\n return await run_in_threadpool(dependant.call, **values)\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/starlette/concurrency.py\", line 39, in run_in_threadpool\n return await anyio.to_thread.run_sync(func, *args)\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/anyio/to_thread.py\", line 28, in run_sync\n return await get_asynclib().run_sync_in_worker_thread(func, *args, cancellable=cancellable,\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/anyio/_backends/_asyncio.py\", line 818, in run_sync_in_worker_thread\n return await future\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/anyio/_backends/_asyncio.py\", line 754, in run\n result = context.run(func, *args)\n File \"/Users/paul/Developer/signal_journey/backend/./main.py\", line 109, in get_constraints_type\n return db.query(models.SignalJourneyConstraintType).all()\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/orm/query.py\", line 2759, in all\n return self._iter().all()\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/orm/query.py\", line 2894, in _iter\n result = self.session.execute(\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/orm/session.py\", line 1692, in execute\n result = conn._execute_20(statement, params or {}, execution_options)\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/engine/base.py\", line 1614, in _execute_20\n return meth(self, args_10style, kwargs_10style, execution_options)\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/sql/elements.py\", line 325, in _execute_on_connection\n return connection._execute_clauseelement(\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/engine/base.py\", line 1481, in _execute_clauseelement\n ret = self._execute_context(\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/engine/base.py\", line 1708, in _execute_context\n self._handle_dbapi_exception(\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/engine/base.py\", line 2026, in _handle_dbapi_exception\n util.raise_(\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/util/compat.py\", line 207, in raise_\n raise exception\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/engine/base.py\", line 1702, in _execute_context\n context = constructor(\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/engine/default.py\", line 1013, in _init_compiled\n self.cursor = self.create_cursor()\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/engine/default.py\", line 1361, in create_cursor\n return self.create_default_cursor()\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/engine/default.py\", line 1364, in create_default_cursor\n return self._dbapi_connection.cursor()\n File \"/Users/paul/.local/share/virtualenvs/backend-CF5omcRU/lib/python3.9/site-packages/sqlalchemy/pool/base.py\", line 1083, in cursor\n return self.dbapi_connection.cursor(*args, **kwargs)\nsqlalchemy.exc.ProgrammingError: (sqlite3.ProgrammingError) SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 6191820800 and this is thread id 6174994432.\n[SQL: SELECT \"SignalJourneyConstraintType\".\"constraintTypeId\" AS \"SignalJourneyConstraintType_constraintTypeId\", \"SignalJourneyConstraintType\".\"constraintType\" AS \"SignalJourneyConstraintType_constraintType\" \nFROM \"SignalJourneyConstraintType\"]\n[parameters: [{}]]\n(Background on this error at: https://sqlalche.me/e/14/f405)\n```\n\n```text\nfetch\n```\n\n```text\nMiddleware\n```\n\n```text\nmain.py\n```\n\n```text\nmain.py\n```\n\n```text\nSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)\n\n...\n\n# Dependency\ndef get_db():\n db = SessionLocal()\n try:\n yield db\n finally:\n db.close()\n\n...\n\n@app.post(\"/users/{user_id}/items/\", response_model=schemas.Item)\ndef create_item_for_user(..., db: Session = Depends(get_db)):\n return crud.create_user_item(db=db, item=item, user_id=user_id)\n```\n\n========================================\n\nComments:\n- Does the server side generate any errors? What is the actual response from the server? If a 5xx error code is returned, the middleware doesn't get to insert their headers so the request fails to materialize in the frontend.\n- @MatsLindh yup you're right it's a 500 error. I have added the whole error message into my question, I often get this I am not too sure... looks like it's related to `sqlalchemy.exc.ProgrammingError: (sqlite3.ProgrammingError) SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 6191820800 and this is thread id 6174994432.`\n- You want to create a separate Session for each request; you do this by using a `Depends` in your view together with a function to create a local Session. See fastapi.tiangolo.com/tutorial/sql-databases/… for an example of how to do this, instead of having a global Session object.\n- thank you thank you! It took some refactoring but we got there!! I'm going to properly go through the tutorial later as I haven't created my crud functions in their own file. Seems easier for better readability","metadata":{"transformedAt":"2026-08-18T18:32:29.137Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":10,"totalLines":814,"estimatedTokens":8692}}482{"id":"stack-68800405","source":"stackoverflow","questionId":68800405,"title":"FastAPI: combining BackgroundTasks and UploadFile gives SyntaxError: non-default argument follows default argument","tags":["fastapi"],"text":"Title: FastAPI: combining BackgroundTasks and UploadFile gives SyntaxError: non-default argument follows default argument\nTags: fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm defining and endpoint as follows:\n\n```\nfrom fastapi import FastAPI, Request, Response, File, UploadFile, BackgroundTasks\n\n@app.post(\"/api/upload_file\", response_class=JSONResponse)\nasync def upload_file(file: UploadFile = File(...), background_tasks: BackgroundTasks):\n background_tasks.add_task(compute_secondary_structure_data, file)\n ...\n```\n\nSo, basically, I receive a file uploaded by a user and I want to do something in the background with it, while I already send a response to the user (hence, the need for a `BackgroundTask`).\n\nBut I get the following: `SyntaxError: non-default argument follows default argument`\n\nWhat is the best way in FastAPI to achieve what I want and combine those two arguments? Is there a way to add a default value to the background task argument? Or to remove the one for the file upload?\n\nThanks\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI, Request, Response, File, UploadFile, BackgroundTasks\n\n@app.post(\"/api/upload_file\", response_class=JSONResponse)\nasync def upload_file(file: UploadFile = File(...), background_tasks: BackgroundTasks):\n background_tasks.add_task(compute_secondary_structure_data, file)\n ...\n```\n\n```text\nBackgroundTask\n```\n\n```text\nSyntaxError: non-default argument follows default argument\n```\n\n```text\n@app.post(\"/api/upload_file\", response_class=JSONResponse)\nasync def upload_file(\n file: UploadFile = File(...),\n background_tasks: BackgroundTasks = BackgroundTasks()\n):\n background_tasks.add_task(compute_secondary_structure_data, file)\n ...\n```\n\n```text\nbackground_tasks\n```\n\n========================================\n\nComments:\n- Simple fix: move `file: UploadFile = File(...)` to the back?\n- @MatsLindh unfortunately it doesn't work because apparently the order of the arguments matter, if I put the file as second argument it contains an empty file instead of the one I send.","metadata":{"transformedAt":"2026-08-18T18:32:29.137Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":63,"estimatedTokens":521}}483{"id":"stack-72582066","source":"stackoverflow","questionId":72582066,"title":"Will FastAPI application with only async endpoints encounter the GIL problem?","tags":["python","gunicorn","fastapi","gil","uvicorn"],"text":"Title: Will FastAPI application with only async endpoints encounter the GIL problem?\nTags: python, gunicorn, fastapi, gil, uvicorn\nSource: Stack Overflow\n\nQuestion:\nIf all the fastapi endpoints are defined as `async def`, then there will only be 1 thread that is running right? (assuming a single uvicorn worker).\n\nJust wanted to confirm in such a setup, we will never hit the python's Global Interpreter Lock. If the same was to be done in a flask framework with multiple threads for the single gunicorn worker, then we would be facing the GIL which hinders the true parallelism between threads.\n\nSo basically, in the above fastapi, the parallelism is limited to 1 since there is only one thread. And to make use of all the cores, we would need to increase the number of workers either using gunicorn or uvicorn.\n\nIs my understanding correct?\n\n========================================\n\nCode:\n```text\nasync def\n```\n\n========================================\n\nComments:\n- Please have a look at this answer for more details around this topic.\n- It should be noted that if one uses FastAPI/Starlette's `UploadFile` methods inside `async def` endpoints, e.g., `await file.read()` and `await file.close()`, FastAPI, behind the scenes, will actually call the corresponding *synchronous* (i.e., normal `def`) File methods in a **separate thread** from an external threadpool. Also, if one uses *synchronous* Background Tasks/`StreamingResponse` generators/Dependencies, FastAPI will also run such functions in a separate thread from the same external threadpool. It is all explained in this answer.","metadata":{"transformedAt":"2026-08-18T18:32:29.137Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":1,"totalLines":25,"estimatedTokens":398}}484{"id":"stack-71180148","source":"stackoverflow","questionId":71180148,"title":"FastAPI and SlowAPI limit request under all “path/*”","tags":["python","fastapi","slowapi"],"text":"Title: FastAPI and SlowAPI limit request under all “path/*”\nTags: python, fastapi, slowapi\nSource: Stack Overflow\n\nQuestion:\nI'm having a problem with SlowAPI. All requests are limited according to the middleware, but I cannot manage to jointly limit all requests under the path `/schools/`\n\nMy code:\n\n```\nfrom fastapi import FastAPI, Request, Response, status\nfrom fastapi.middleware.cors import CORSMiddleware\nfrom slowapi import Limiter, _rate_limit_exceeded_handler\nfrom slowapi.util import get_remote_address\nfrom slowapi.errors import RateLimitExceeded\nfrom slowapi.middleware import SlowAPIMiddleware\n\nlimiter = Limiter(key_func=get_remote_address, default_limits=[\"2/5seconds\"])\napp = FastAPI()\napp.state.limiter = limiter\napp.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)\n\norigins = [\"http://127.0.0.1/\", \"http://localhost\", \"http://192.168.1.75\"] ## CORS\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=origins,\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\napp.add_middleware(SlowAPIMiddleware) ## Rate-limit all request\n\n@app.get('/schools/{regione}/{provincia}/{comune}')\ndef search_school(request: Request, response: Response, regione: str, provincia: str, comune: str):\n return {\"message\": 'No schools found!', \"status\": 'error', \"code\": 200} ## Or if found return schools informations\n\n@app.get('/testpath/{regione}') ## Works with one path. If I add \"provincia\" and \"comune\" non work\ndef search_school(request: Request, response: Response, regione: str, provincia: str, comune: str):\n return {\"message\": 'No schools found!', \"status\": 'error', \"code\": 200} ## Or if found return schools informations\n```\n\nWhen i send a request to `/schools/{region}/{province}/{city}` with jQuery the whole url is limited and therefore if I change region or province the limits are reset. How can I make myself apply settings for `/schools/*`\n\nExample:\n\n*2 request every 5 seconds*\n\nIf i send to request to `apiURL+/schools/Lombardy/Milan/Milan` the limit increases by 1 and if i made anothe 2 request at the third I get blocked.\n\nBut if instead of making it to the same domain, I change the city (`apiURL+/schools/Sicily/Palermo/Palermo`), the limit resets and returns to 1\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI, Request, Response, status\nfrom fastapi.middleware.cors import CORSMiddleware\nfrom slowapi import Limiter, _rate_limit_exceeded_handler\nfrom slowapi.util import get_remote_address\nfrom slowapi.errors import RateLimitExceeded\nfrom slowapi.middleware import SlowAPIMiddleware\n\nlimiter = Limiter(key_func=get_remote_address, default_limits=[\"2/5seconds\"])\napp = FastAPI()\napp.state.limiter = limiter\napp.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)\n\norigins = [\"http://127.0.0.1/\", \"http://localhost\", \"http://192.168.1.75\"] ## CORS\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=origins,\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\napp.add_middleware(SlowAPIMiddleware) ## Rate-limit all request\n\n@app.get('/schools/{regione}/{provincia}/{comune}')\ndef search_school(request: Request, response: Response, regione: str, provincia: str, comune: str):\n return {\"message\": 'No schools found!', \"status\": 'error', \"code\": 200} ## Or if found return schools informations\n\n@app.get('/testpath/{regione}') ## Works with one path. If I add \"provincia\" and \"comune\" non work\ndef search_school(request: Request, response: Response, regione: str, provincia: str, comune: str):\n return {\"message\": 'No schools found!', \"status\": 'error', \"code\": 200} ## Or if found return schools informations\n```\n\n```text\n/schools/\n```\n\n```text\n/schools/{region}/{province}/{city}\n```\n\n```text\n/schools/*\n```\n\n```text\napiURL+/schools/Lombardy/Milan/Milan\n```\n\n```text\napiURL+/schools/Sicily/Palermo/Palermo\n```\n\n```text\nlimiter = Limiter(key_func=get_remote_address, application_limits=[\"2/5seconds\"])\n```\n\n```text\nlimiter = Limiter(key_func=get_remote_address, default_limits=[\"2/5seconds\"])\n\n@app.get('/schools/{regione}/{provincia}/{comune}')\n@limiter.shared_limit(limit_value=\"2/5seconds\", scope=\"schools\") \ndef search_school(request: Request, response: Response, regione: str, provincia: str, comune: str):\n return {\"message\": 'No schools found!', \"status\": 'error', \"code\": 200}\n```\n\n```text\napplication_limits\n```\n\n```text\nLimiter\n```\n\n```text\n/schools/*\n```\n\n```text\n/testpath/*\n```\n\n```text\n/some-other-route/\n```\n\n```text\nshared_limit\n```\n\n```text\n/schools/*\n```\n\n========================================\n\nComments:\n- What if I wanted to set more limits? Like 1 per second and 10 per minute?\n- If you are using the first option, you could use, for example, `application_limits=[\"2/5seconds\", \"10/minute\"]`. If the second option is used, you could define multiple rate limit rules separated by `;`, e.g., `limit_value=\"2/5seconds; 10/minute\"`, or using multiple decorators (one for each rule).","metadata":{"transformedAt":"2026-08-18T18:32:29.137Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":15,"totalLines":154,"estimatedTokens":1250}}485{"id":"stack-74498191","source":"stackoverflow","questionId":74498191,"title":"How to define multiple API endpoints in FastAPI with different paths but the same path parameter?","tags":["python","rest","fastapi","fastapi-crudrouter"],"text":"Title: How to define multiple API endpoints in FastAPI with different paths but the same path parameter?\nTags: python, rest, fastapi, fastapi-crudrouter\nSource: Stack Overflow\n\nQuestion:\nI'm working on a project which uses FastAPI. My router file looks like the following:\n\n```\n# GET API Endpoint 1\n@router.get(\"/project/{project_id}/{employee_id}\")\nasync def method_one(\n project_id: str, organization_id: str, session: AsyncSession = Depends(get_db)\n):\n\n try:\n return await CustomController.method_one(\n session, project_id, employee_id\n )\n except Exception as e:\n return custom_exception_handler(e)\n\n# GET API Endpoint 2\n@router.get(\"/project/details/{project_id}\")\nasync def method_two(\n project_id: str, session: AsyncSession = Depends(get_db)\n):\n\n try:\n return await CustomController.method_two(\n session=session, project_id=project_id\n )\n except Exception as e:\n return custom_exception_handler(e)\n\n# GET API Endpoint 3\n@router.get(\"/project/metadata/{project_id}\")\nasync def method_three(\n project_id: str, session: AsyncSession = Depends(get_db)\n):\n try:\n return await CustomController.method_three(\n session=session, project_id=project_id\n )\n except Exception as e:\n return custom_exception_handler(e)\n```\n\nThe obvious expectation of workflow here is: when each of these API endpoints are triggered with their required path parameters, the controller method is executed, as defined in their body.\n\nHowever, for some strange reason, when API endpoints 2 and 3 are triggered, they are executing the controller method in endpoint 1, i.e., `CustomController.method_one()`.\n\nUpon adding some `print()` statements in the method `method_one()` of the router, I've observed that `method_one()` is being called when API endpoint 2 is called, while it is actually supposed to call `method_two()` in the router. Same is the case with API endpoint 3.\n\nI'm unable to understand why the method body of `method_one()` is getting executed, when API endpoints 2 and 3 are triggered. Am I missing out something on configuration, or something - can someone please correct me? Thanks!\n\n========================================\n\nCode:\n```py\n# GET API Endpoint 1\n@router.get(\"/project/{project_id}/{employee_id}\")\nasync def method_one(\n project_id: str, organization_id: str, session: AsyncSession = Depends(get_db)\n):\n\n try:\n return await CustomController.method_one(\n session, project_id, employee_id\n )\n except Exception as e:\n return custom_exception_handler(e)\n\n# GET API Endpoint 2\n@router.get(\"/project/details/{project_id}\")\nasync def method_two(\n project_id: str, session: AsyncSession = Depends(get_db)\n):\n\n try:\n return await CustomController.method_two(\n session=session, project_id=project_id\n )\n except Exception as e:\n return custom_exception_handler(e)\n\n# GET API Endpoint 3\n@router.get(\"/project/metadata/{project_id}\")\nasync def method_three(\n project_id: str, session: AsyncSession = Depends(get_db)\n):\n try:\n return await CustomController.method_three(\n session=session, project_id=project_id\n )\n except Exception as e:\n return custom_exception_handler(e)\n```\n\n```text\nCustomController.method_one()\n```\n\n```text\nprint()\n```\n\n```text\nmethod_one()\n```\n\n```text\nmethod_one()\n```\n\n```text\nmethod_two()\n```\n\n```text\nmethod_one()\n```\n\n```py\n# GET API Endpoint 1\n@router.get(\"/project/details/{project_id}\")\n # ...\n\n# GET API Endpoint 2\n@router.get(\"/project/metadata/{project_id}\")\n # ...\n\n# GET API Endpoint 3\n@router.get(\"/project/{project_id}/{employee_id}\")\n # ...\n```\n\n```text\n/project/{project_id}/...\n```\n\n```text\n/project/details/...\n```\n\n```text\n/project/metadata/...\n```\n\n```text\ndetails\n```\n\n```text\nmetadata\n```\n\n```text\nproject_id\n```\n\n```text\n/project/{project_id}/...\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.137Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":15,"totalLines":163,"estimatedTokens":955}}486{"id":"stack-67553888","source":"stackoverflow","questionId":67553888,"title":"Why am I not getting results of SQL query back from using encode databases?","tags":["python","postgresql","sqlalchemy","python-asyncio","fastapi"],"text":"Title: Why am I not getting results of SQL query back from using encode databases?\nTags: python, postgresql, sqlalchemy, python-asyncio, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have the following but for some reason instead of getting results of my query, I am getting something else\n\nHere is the Python package am using\n\nhttps://pypi.org/project/databases/\n\nAnd here is the documentation\n\nhttps://www.encode.io/databases/database_queries/\n\n```\nfrom databases import Database\ndatabase=Database('postgres://redacted')\nawait database.connect()\n...\n...\n...\nquery = \"SELECT orders.id AS orders_id, orders.notification_method AS orders_notification_method WHERE shipped=True\"\nresult = await database.fetch_all(query=query))\n```\n\nHere is what am getting instead of getting results of my query\n\nprint(result)\n\n```\n[, , , , , , , ]\n```\n\nAnd type says it is a list\n\nprint(type(result))\n\n```\n\n```\n\nHow do I return the actual result of the SQL query which is to return all rows from the query?\n\n### What I really want to do\n\nhere is `sqlalchemy` version that works but using `databases` package not working as mentioned above\n\nWhat I pretty much want to achieve is to have similar result from sqlalchemy query like below and be able to iterate over the rows from the result of the query\n\n```\n...\n...\n...\nclass Orders:\n id: Optional[int]\n notification_method: str\n shipped: Optional[bool]\n\n...\n...\n...\nsession = create_session()\nresult=session.query(Orders).filter(Orders.shipped == True)\n```\n\nprint(result)\n\n```\nSELECT orders.id AS orders_id, orders.notification_method AS orders_notification_method FROM orders \nWHERE orders.shipped = true\n```\n\nprint(type(result))\n\n```\n\n```\n\nAnd then I want to be able to iterate over the rows\n\n```\nfor r in result:\n print(r)\n```\n\noutput\n\n```\nOrders(id=1, notification_method='call', shipped=True)\nOrders(id=2, notification_method='sms', shipped=True)\nOrders(id=3, notification_method='call', shipped=True)\n```\n\nJust want to get similar result as this sqlalchmey one but using `databases` as mentioned at beginning of this question\n\n========================================\n\nCode:\n```text\nfrom databases import Database\ndatabase=Database('postgres://redacted')\nawait database.connect()\n...\n...\n...\nquery = \"SELECT orders.id AS orders_id, orders.notification_method AS orders_notification_method WHERE shipped=True\"\nresult = await database.fetch_all(query=query))\n```\n\n```text\n[<databases.backends.postgres.Record object at 0x7fb3f415ac50>, <databases.backends.postgres.Record object at 0x7fb3f415ae30>, <databases.backends.postgres.Record object at 0x7fb3f415a470>, <databases.backends.postgres.Record object at 0x7fb3f415af50>, <databases.backends.postgres.Record object at 0x7fb3f415ad70>, <databases.backends.postgres.Record object at 0x7fb3f415ab30>, <databases.backends.postgres.Record object at 0x7fb3f415a7d0>, <databases.backends.postgres.Record object at 0x7fb3f415ae90>]\n```\n\n```text\n<class 'list'>\n```\n\n```text\n...\n...\n...\nclass Orders:\n id: Optional[int]\n notification_method: str\n shipped: Optional[bool]\n\n...\n...\n...\nsession = create_session()\nresult=session.query(Orders).filter(Orders.shipped == True)\n```\n\n```text\nSELECT orders.id AS orders_id, orders.notification_method AS orders_notification_method FROM orders \nWHERE orders.shipped = true\n```\n\n```text\n<class 'sqlalchemy.orm.query.Query'>\n```\n\n```text\nfor r in result:\n print(r)\n```\n\n```text\nOrders(id=1, notification_method='call', shipped=True)\nOrders(id=2, notification_method='sms', shipped=True)\nOrders(id=3, notification_method='call', shipped=True)\n```\n\n```text\nsqlalchemy\n```\n\n```text\ndatabases\n```\n\n```text\ndatabases\n```\n\n```text\nresult = await database.fetch_all(query=query))\nfor rec in result:\n print(tuple(rec.values()) # or you could use `dict(rec.items())` as well\n```\n\n```text\nrec = await database.fetch_one(query=query)\nprint(rec)\nprint(tuple(rec.values()))\nprint(dict(rec.items()))\n```\n\n```text\n<databases.backends.postgres.Record object at 0x??????>\n(1, 'sms')\n{'orders_id': 1, 'orders_notification_method': 'sms'}\n```\n\n```text\ndatabases.backends.postgres.Record\n```\n\n```text\ncollections.abc.Mapping\n```\n\n========================================\n\nComments:\n- what is \"actual result\" if not the `Record`? If I check the source code, `Record` encapsulates the values of each row in `.values` property. What is the problem you have with it? Also you probably want to do Query instead of Raw Query\n- i want it to return result of my query...i mean the code shows what i want..i want to print the result of the sql query\n- how do i return the rows from the sql query?\n- i updated question with more context...anything am missing?\n- stackoverflow.com/questions/7784148/…\n- what if there is a different query that returns a single row and is fetching a single row? like `result = await database.fetch_one(query=query))` how will i get the single dictionary of the single row result? i tried `dict(rec.items())` and got `AttributeError: 'str' object has no attribute 'items'` how do i return the dictionary of that single row for `fetch_one` query?\n- I have updated the answer, but check carefully your code, single query should work as well.\n- one other question since you the only one really helpful...celery does not work when i add `async` to the task function...so how do i use the encode databases package with celery? seems databases is only async to query the database with every query ran with `await` and celery does not with `async def function():`...has to be `def function():`...will appreciate your help again..thanks\n- I am sorry, but I do not use celery. But most likely this question/answer will help you.\n- for some reason `res.items` is None for me so I can't call it, if you have this too you can use `dict(res._mapping)`. I used to use `dict(res.items())` but now I got error. why so?\n- @larick For future references, maybe is because of this: encode.io/databases/database_queries. View last paragraph. (Query result). To keep in line with SQLAlchemy 1.4 changes query result object no longer implements a mapping interface. To access query result as a mapping you should use the _mapping property. That way you can process both SQLAlchemy Rows and databases Records from raw queries with the same function without any instance checks.","metadata":{"transformedAt":"2026-08-18T18:32:29.137Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":16,"totalLines":207,"estimatedTokens":1573}}487{"id":"stack-70710874","source":"stackoverflow","questionId":70710874,"title":"How to send base64 image using Python requests and FastAPI?","tags":["python","file-upload","python-requests","base64","fastapi"],"text":"Title: How to send base64 image using Python requests and FastAPI?\nTags: python, file-upload, python-requests, base64, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to implement a code for image style transfer based on FastAPI. I found it effective to convert the byte of the image into base64 and transmit it.\n\nSo, I designed my client codeto encode the image into a base64 string and send it to the server, which received it succesfully. However, I face some difficulties in restoring the image bytes to ndarray.\n\nI get the following this errors:\n\n```\nimage_array = np.frombuffer(base64.b64decode(image_byte)).reshape(image_shape)\n\nValueError: cannot reshape array of size 524288 into shape (512,512,4)\n```\n\nThis is my client code :\n\n```\nimport base64\nimport requests\nimport numpy as np\nimport json\nfrom matplotlib.pyplot import imread\nfrom skimage.transform import resize\n\nif __name__ == '__main__':\n path_to_img = \"my image path\"\n\n image = imread(path_to_img)\n image = resize(image, (512, 512))\n\n image_byte = base64.b64encode(image.tobytes())\n data = {\"shape\": image.shape, \"image\": image_byte.decode()}\n\n response = requests.get('http://127.0.0.1:8000/myapp/v1/filter/a', data=json.dumps(data))\n```\n\nand this is my server code:\n\n```\nimport json\nimport base64\nimport uvicorn\nimport model_loader\nimport numpy as np\n\nfrom fastapi import FastAPI\nfrom typing import Optional\n\napp = FastAPI()\n\n@app.get(\"/\")\ndef read_root():\n return {\"Hello\": \"World\"}\n\n@app.get(\"/myapp/v1/filter/a\")\nasync def style_transfer(data: dict):\n image_byte = data.get('image').encode()\n image_shape = tuple(data.get('shape'))\n image_array = np.frombuffer(base64.b64decode(image_byte)).reshape(image_shape)\n\nif __name__ == '__main__':\n uvicorn.run(app, port='8000', host=\"127.0.0.1\")\n```\n\n========================================\n\nCode:\n```text\nimage_array = np.frombuffer(base64.b64decode(image_byte)).reshape(image_shape)\n\nValueError: cannot reshape array of size 524288 into shape (512,512,4)\n```\n\n```text\nimport base64\nimport requests\nimport numpy as np\nimport json\nfrom matplotlib.pyplot import imread\nfrom skimage.transform import resize\n\n\nif __name__ == '__main__':\n path_to_img = \"my image path\"\n\n image = imread(path_to_img)\n image = resize(image, (512, 512))\n\n image_byte = base64.b64encode(image.tobytes())\n data = {\"shape\": image.shape, \"image\": image_byte.decode()}\n\n response = requests.get('http://127.0.0.1:8000/myapp/v1/filter/a', data=json.dumps(data))\n```\n\n```text\nimport json\nimport base64\nimport uvicorn\nimport model_loader\nimport numpy as np\n\nfrom fastapi import FastAPI\nfrom typing import Optional\n\n\napp = FastAPI()\n\n@app.get(\"/\")\ndef read_root():\n return {\"Hello\": \"World\"}\n\n\n@app.get(\"/myapp/v1/filter/a\")\nasync def style_transfer(data: dict):\n image_byte = data.get('image').encode()\n image_shape = tuple(data.get('shape'))\n image_array = np.frombuffer(base64.b64decode(image_byte)).reshape(image_shape)\n\nif __name__ == '__main__':\n uvicorn.run(app, port='8000', host=\"127.0.0.1\")\n```\n\n```py\n@app.post(\"/upload\")\ndef upload(file: UploadFile = File(...)):\n try:\n contents = file.file.read()\n with open(file.filename, 'wb') as f:\n f.write(contents)\n except Exception:\n return {\"message\": \"There was an error uploading the file\"}\n finally:\n file.file.close()\n \n return {\"message\": f\"Successfuly uploaded {file.filename}\"}\n```\n\n```py\nimport requests\n\nurl = 'http://127.0.0.1:8000/upload'\nfile = {'file': open('images/1.png', 'rb')}\nresp = requests.post(url=url, files=file) \nprint(resp.json())\n```\n\n```py\n@app.post(\"/upload\")\ndef upload(filename: str = Form(...), filedata: str = Form(...)):\n image_as_bytes = str.encode(filedata) # convert string to bytes\n img_recovered = base64.b64decode(image_as_bytes) # decode base64string\n try:\n with open(\"uploaded_\" + filename, \"wb\") as f:\n f.write(img_recovered)\n except Exception:\n return {\"message\": \"There was an error uploading the file\"}\n \n return {\"message\": f\"Successfuly uploaded {filename}\"}\n```\n\n```py\nimport base64\nimport requests\n\nurl = 'http://127.0.0.1:8000/upload'\nwith open(\"photo.png\", \"rb\") as image_file:\n encoded_string = base64.b64encode(image_file.read())\n \npayload ={\"filename\": \"photo.png\", \"filedata\": encoded_string}\nresp = requests.post(url=url, data=payload)\n```\n\n```text\nUploadFile\n```\n\n```text\nasync\n```\n\n```text\nbase64\n```\n\n```text\nForm\n```\n\n```text\nbase64\n```\n\n```text\nPOST\n```\n\n========================================\n\nComments:\n- please check if your image have 16 bit color range - it seems suspicious that image have exactly 512*512*2 bytes = 2 bytes or 16 bits per pixel","metadata":{"transformedAt":"2026-08-18T18:32:29.137Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":13,"totalLines":203,"estimatedTokens":1176}}488{"id":"stack-75184430","source":"stackoverflow","questionId":75184430,"title":"How to redirect the user to another page after login using JavaScript Fetch API?","tags":["javascript","python","http-redirect","fetch","fastapi"],"text":"Title: How to redirect the user to another page after login using JavaScript Fetch API?\nTags: javascript, python, http-redirect, fetch, fastapi\nSource: Stack Overflow\n\nQuestion:\nUsing the following JavaScript code, I make a request to obtain the firebase token, and then a `POST` request to my FastAPI backend, using the JavaScript `fetch()` method, in order to login the user. Then, in the backend, as can be seen below, I check whether or not the token is valid, and if so, return a redirect (i.e., `RedirectResponse`) to another webpage. The problem is that the redirect in the browser does not work, and the previous page remains.\n\n```\nfunction loginGoogle() {\n var provider = new firebase.auth.GoogleAuthProvider();\n firebase.auth()\n //.currentUser.getToken(provider)\n .signInWithPopup(provider)\n .then((result) => {\n /** @type {firebase.auth.OAuthCredential} */\n var credential = result.credential;\n\n // This gives you a Google Access Token. You can use it to access the Google API.\n var token = credential.idToken;\n \n // The signed-in user info.\n var user = result.user;\n \n // ...\n })\n .catch((error) => {\n // Handle Errors here.\n var errorCode = error.code;\n var errorMessage = error.message;\n // The email of the user's account used.\n var email = error.email;\n // The firebase.auth.AuthCredential type that was used.\n var credential = error.credential;\n // ...\n \n });\n\n firebase.auth().currentUser.getIdToken(true).then(function(idToken) {\n console.log(idToken)\n\n const token = idToken;\n const headers = new Headers({\n 'x-auth-token': token\n });\n const request = new Request('http://localhost:8000/login', {\n method: 'POST',\n headers: headers\n });\n fetch(request)\n .then(response => response.json())\n .then(data => console.log(data))\n .catch(error => console.error(error));\n\n \n })\n```\n\nThe endpoint in the backend that returns the login page that contains the HTML code with the button and the `loginGoogle` function:\n\n```\n@router.get(\"/entrar\")\ndef login(request: Request):\n return templates.TemplateResponse(\"login.html\", {\"request\": request})\n```\n\nI call this `POST` endpoint and then a redirect to `/1` which is a `GET` route, and with `status_code` being `303`, which is how @tiangolo specifies it in the doc to redirect from a `POST` to a `GET` route.\n\n```\n@router.post(\"/login\")\nasync def login(x_auth_token: str = Header(None)):\n valid_token = auth.verify_id_token(x_auth_token)\n \n if valid_token:\n print(\"token validado\")\n return RedirectResponse(url=\"/1\", status_code=status.HTTP_303_SEE_OTHER)\n else:\n return {\"msg\": \"Token no recibido\"}\n```\n\nThis is the `GET` endpoint to which the user should be redirected, but it doesn't:\n\n```\n@app.get(\"/1\")\ndef get_landing(request: Request):\n return templates.TemplateResponse(\"landing.html\", {\"request\": request})\n```\n\nSwagger screenshot of testing the `/login` endpoint:\nhttps://i.sstatic.net/V4za7.png\n\n========================================\n\nCode:\n```js\nfunction loginGoogle() {\n var provider = new firebase.auth.GoogleAuthProvider();\n firebase.auth()\n //.currentUser.getToken(provider)\n .signInWithPopup(provider)\n .then((result) => {\n /** @type {firebase.auth.OAuthCredential} */\n var credential = result.credential;\n\n // This gives you a Google Access Token. You can use it to access the Google API.\n var token = credential.idToken;\n \n // The signed-in user info.\n var user = result.user;\n \n // ...\n })\n .catch((error) => {\n // Handle Errors here.\n var errorCode = error.code;\n var errorMessage = error.message;\n // The email of the user's account used.\n var email = error.email;\n // The firebase.auth.AuthCredential type that was used.\n var credential = error.credential;\n // ...\n \n });\n\n firebase.auth().currentUser.getIdToken(true).then(function(idToken) {\n console.log(idToken)\n\n const token = idToken;\n const headers = new Headers({\n 'x-auth-token': token\n });\n const request = new Request('http://localhost:8000/login', {\n method: 'POST',\n headers: headers\n });\n fetch(request)\n .then(response => response.json())\n .then(data => console.log(data))\n .catch(error => console.error(error));\n\n \n })\n```\n\n```text\n@router.get(\"/entrar\")\ndef login(request: Request):\n return templates.TemplateResponse(\"login.html\", {\"request\": request})\n```\n\n```text\n@router.post(\"/login\")\nasync def login(x_auth_token: str = Header(None)):\n valid_token = auth.verify_id_token(x_auth_token)\n \n if valid_token:\n print(\"token validado\")\n return RedirectResponse(url=\"/1\", status_code=status.HTTP_303_SEE_OTHER)\n else:\n return {\"msg\": \"Token no recibido\"}\n```\n\n```text\n@app.get(\"/1\")\ndef get_landing(request: Request):\n return templates.TemplateResponse(\"landing.html\", {\"request\": request})\n```\n\n```text\nPOST\n```\n\n```text\nfetch()\n```\n\n```text\nRedirectResponse\n```\n\n```text\nloginGoogle\n```\n\n```text\nPOST\n```\n\n```text\n/1\n```\n\n```text\nGET\n```\n\n```text\nstatus_code\n```\n\n```text\n303\n```\n\n```text\nPOST\n```\n\n```text\nGET\n```\n\n```text\nGET\n```\n\n```text\n/login\n```\n\n```py\nfrom fastapi import FastAPI, Request, status, Depends\nfrom fastapi.templating import Jinja2Templates\nfrom fastapi.responses import RedirectResponse\nfrom fastapi.security import OAuth2PasswordRequestForm\n\napp = FastAPI()\ntemplates = Jinja2Templates(directory='templates')\n\n\n@app.get('/')\nasync def index(request: Request):\n return templates.TemplateResponse('index.html', {'request': request})\n\n \n@app.post('/login')\nasync def login(data: OAuth2PasswordRequestForm = Depends()):\n # perform some validation, using data.username and data.password\n credentials_valid = True\n \n if credentials_valid:\n return RedirectResponse(url='/welcome',status_code=status.HTTP_302_FOUND)\n else:\n return 'Validation failed'\n \n\n@app.get('/welcome')\nasync def welcome():\n return 'You have been successfully redirected'\n```\n\n```html\n<!DOCTYPE html>\n<html>\n <head>\n <script>\n document.addEventListener(\"DOMContentLoaded\", (event) => {\n document.getElementById(\"myForm\").addEventListener(\"submit\", function (e) {\n e.preventDefault(); // Cancel the default action\n var formElement = document.getElementById('myForm');\n var data = new FormData(formElement);\n fetch('/login', {\n method: 'POST',\n redirect: 'follow',\n body: data,\n })\n .then(res => {\n if (res.redirected) {\n window.location.href = res.url; // or, location.replace(res.url); \n return;\n } \n else\n return res.text();\n })\n .then(data => {\n document.getElementById(\"response\").innerHTML = data;\n })\n .catch(error => {\n console.error(error);\n });\n });\n });\n \n </script>\n </head>\n <body>\n <form id=\"myForm\">\n <label for=\"username\">Username:</label><br>\n <input type=\"text\" id=\"username\" name=\"username\" value=\"user@mail.com\"><br>\n <label for=\"password\">Password:</label><br>\n <input type=\"password\" id=\"password\" name=\"password\" value=\"pa55w0rd\"><br><br>\n <input type=\"submit\" value=\"Submit\" class=\"submit\">\n </form>\n <div id=\"response\"></div>\n </body>\n</html>\n```\n\n```py\nfrom fastapi import FastAPI, Request, status, Depends\nfrom fastapi.templating import Jinja2Templates\nfrom fastapi.security import OAuth2PasswordRequestForm\n\napp = FastAPI()\ntemplates = Jinja2Templates(directory='templates')\n\n\n@app.get('/')\nasync def index(request: Request):\n return templates.TemplateResponse('index.html', {'request': request})\n\n \n@app.post('/login')\nasync def login(data: OAuth2PasswordRequestForm = Depends()):\n # perform some validation, using data.username and data.password\n credentials_valid = True\n \n if credentials_valid:\n return {'url': '/welcome'}\n else:\n return 'Validation failed'\n \n\n@app.get('/welcome')\nasync def welcome():\n return 'You have been successfully redirected'\n```\n\n```html\n<!DOCTYPE html>\n<html>\n <head>\n <script>\n document.addEventListener(\"DOMContentLoaded\", (event) => {\n document.getElementById(\"myForm\").addEventListener(\"submit\", function (e) {\n e.preventDefault(); // Cancel the default action\n var formElement = document.getElementById('myForm');\n var data = new FormData(formElement);\n fetch('/login', {\n method: 'POST',\n body: data,\n })\n .then(res => res.json())\n .then(data => {\n if (data.url)\n window.location.href = data.url; // or, location.replace(data.url);\n else\n document.getElementById(\"response\").innerHTML = data;\n })\n .catch(error => {\n console.error(error);\n });\n });\n });\n </script>\n </head>\n <body>\n <form id=\"myForm\">\n <label for=\"username\">Username:</label><br>\n <input type=\"text\" id=\"username\" name=\"username\" value=\"user@mail.com\"><br>\n <label for=\"password\">Password:</label><br>\n <input type=\"password\" id=\"password\" name=\"password\" value=\"pa55w0rd\"><br><br>\n <input type=\"submit\" value=\"Submit\" class=\"submit\">\n </form>\n <div id=\"response\"></div>\n </body>\n</html>\n```\n\n```text\nRedirectResponse\n```\n\n```text\nfetch()\n```\n\n```text\nRedirectResponse\n```\n\n```text\nredirect\n```\n\n```text\nfollow\n```\n\n```text\nfetch()\n```\n\n```text\nfetch()\n```\n\n```text\nredirect\n```\n\n```text\nmanual\n```\n\n```text\nLocation\n```\n\n```text\nredirect\n```\n\n```text\nfetch()\n```\n\n```text\nfollow\n```\n\n```text\nResponse.redirected\n```\n\n```text\nResponse.url\n```\n\n```text\nwindow.location.href\n```\n\n```text\nwindow.location.href\n```\n\n```text\nwindow.location.replace()\n```\n\n```text\nlocation.replace()\n```\n\n```text\nRedirectResponse\n```\n\n```text\nfetch()\n```\n\n```text\nurl\n```\n\n```text\nwindow.location.href\n```\n\n```text\nwindow.location.replace()\n```\n\n```text\nfetch()\n```\n\n```text\nAccess-Control-Expose-Headers\n```\n\n```text\nCORSMiddleware\n```\n\n```text\nexpose_headers\n```\n\n```text\n<form>\n```\n\n```text\nfetch()\n```\n\n```text\n<form>\n```\n\n```text\nsubmit\n```\n\n```text\nPOST\n```\n\n```text\nRedirectResponse\n```\n\n========================================\n\nComments:\n- Please include the relevant code and details *as text*. Images have bad accessibility, requires the reader to switch back and forth, doesn't allow for copy and pasting the code or referencing details in an answer, and makes it impossible to search for any relevant details.\n- INFO: 127.0.0.1:53670 - \"POST /login HTTP/1.1\" 303 See Other INFO: 127.0.0.1:53670 - \"GET /1 HTTP/1.1\" 200 OK can the error be that I am sending a post to a get?\n- Does this answer your question? How to redirect the user back to the home page using FastAPI, after submitting an HTML form?\n- Please have a look at this answer, as well as this answer and this answer.\n- none of these answers solves my problem\n- actually the problem is that in the swagger if I do the redirect, but then in the browser does not, stays on the previous page.\n- @LidorEliyahuShelef I have updated the question, with an image of my swagger, passing the auth token if I do the redirect to the url I want, but when I do it through the browser does not do anything does not redirect me.\n- @Chris I have looked at the questions you passed me and none of them solve my error, and yes I am testing the api, using a basic html button that does onclick() on a function to get the google token from firebase and then does a fetch to my api, which after checking it should redirect. Maybe it has to do with the loading time, why does the google form have to load first to login and then do the redirect?\n- @Chris I don't know what code you mean by relevant, I actually have a post and I'm doing a redirect to a get, there's not much more code to look at, there's the part of the front end that sends the token but I don't think that code is relevant to this problem.\n- @Chris i updated the question. sorry for not knowing how to extend the problem, I am new.\n- Hi, Thank you for the answer. I was trying option 1. The statement window.location.href = data.url causes another call to the same API. It results two calls - one by the redirect and then the next by this href assignment. @Chris","metadata":{"transformedAt":"2026-08-18T18:32:29.137Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":55,"totalLines":518,"estimatedTokens":3271}}489{"id":"stack-70468354","source":"stackoverflow","questionId":70468354,"title":"FastApi sqlalchemy Connection was closed in the middle of operation","tags":["python","sqlalchemy","fastapi","uvicorn","asyncpg"],"text":"Title: FastApi sqlalchemy Connection was closed in the middle of operation\nTags: python, sqlalchemy, fastapi, uvicorn, asyncpg\nSource: Stack Overflow\n\nQuestion:\nI have an async FastApi application with async sqlalchemy, source code (will not provide schemas.py because it is not necessary):\n\n### database.py\n\n```\nfrom sqlalchemy import (\n Column,\n String,\n)\nfrom sqlalchemy.ext.asyncio import AsyncSession, create_async_engine\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import sessionmaker\nfrom sqlalchemy.orm.decl_api import DeclarativeMeta\n\nfrom app.config import settings\n\nengine = create_async_engine(settings.DATABASE_URL)\nBase: DeclarativeMeta = declarative_base()\nasync_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)\n\nclass Titles(Base):\n __tablename__ = \"titles\"\n id = Column(String(100), primary_key=True)\n title = Column(String(100), unique=True)\n\nasync def get_session() -> AsyncSession:\n async with async_session() as session:\n yield session\n```\n\n### routers.py\n\n```\nimport .database\nfrom fastapi_utils.cbv import cbv\nfrom fastapi_utils.inferring_router import InferringRouter\n\nrouter = InferringRouter()\n\nasync def get_titles(session: AsyncSession):\n results = await session.execute(select(database.Titles)))\n return results.scalars().all()\n\n@cbv(router)\nclass TitlesView:\n session: AsyncSession = Depends(database.get_session)\n\n @router.get(\"/titles\", status_code=HTTP_200_OK)\n async def get(self) -> List[TitlesSchema]:\n results = await get_titles(self.session)\n return [TitlesSchema.from_orm(result) for result in results]\n```\n\n### main.py\n\n```\nfrom fastapi import FastAPI\n\nfrom app.routers import router \n\ndef create_app() -> FastAPI:\n app = FastAPI()\n app .include_router(routers, prefix=\"/\", tags=[\"Titles\"])\n\n return printer_app\n\napp = create_app()\n```\n\nIt runs with docker:\n\n```\nCMD [\"uvicorn\", \"main:app\", \"--reload\", \"--host\", \"0.0.0.0\", \"--port\", \"8000\", \"--limit-max-requests\", \"10000\"]\n```\n\nAnd it has Postgres database with default settings in docker too. It all runs at docker-swarm. Works fine at first, accepts all requests. But if you leave it for 15-30 minutes (I did not count), and then make a request, it will not work:\n\n```\n: connection was closed in the middle of operation\n```\n\nAnd right after that I send the next request and it doesn't throw an error. What could it be? How do I get rid of the ConnectionDoesNotExistError?\n\n========================================\n\nTop Answer:\nI will quote the answer from here, I think it might be useful. All credit to q210.\n\nIn our case, the root cause was that ipvs, used by swarm to route packets, have default expiration time for idle connections set to 900 seconds. So if connection had no activity for more than 15 minutes, ipvs broke it.\n900 seconds is significantly less than default linux tcp keepalive setting (7200 seconds) used by most of the services that can send keepalive tcp packets to keep connections from going idle.\n\nThe same problem is described here moby/moby#31208\n\nTo fix this we had to set the following in postgresql.conf:\n\n```\ntcp_keepalives_idle = 600 # TCP_KEEPIDLE, in seconds;\n # 0 selects the system default\ntcp_keepalives_interval = 30 # TCP_KEEPINTVL, in seconds;\n # 0 selects the system default\ntcp_keepalives_count = 10 # TCP_KEEPCNT;\n # 0 selects the system default\n```\n\nThese settings are forcing PostgreSQL to keep connections from going idle by sending keepalive packets more often than ipvs default setting (that we can't change in docker-swarm, sadly).\n\nI guess the same could be achieved by changing corresponding linux settings (`net.ipv4.tcp_keepalive_time` and the like), 'cause PostgreSQL uses them by default, but in our case changing these was a bit more cumbersome.\n\n========================================\n\nCode:\n```text\nfrom sqlalchemy import (\n Column,\n String,\n)\nfrom sqlalchemy.ext.asyncio import AsyncSession, create_async_engine\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import sessionmaker\nfrom sqlalchemy.orm.decl_api import DeclarativeMeta\n\nfrom app.config import settings\n\n\nengine = create_async_engine(settings.DATABASE_URL)\nBase: DeclarativeMeta = declarative_base()\nasync_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)\n\n\nclass Titles(Base):\n __tablename__ = \"titles\"\n id = Column(String(100), primary_key=True)\n title = Column(String(100), unique=True)\n\n\nasync def get_session() -> AsyncSession:\n async with async_session() as session:\n yield session\n```\n\n```text\nimport .database\nfrom fastapi_utils.cbv import cbv\nfrom fastapi_utils.inferring_router import InferringRouter\n\n\nrouter = InferringRouter()\n\n\nasync def get_titles(session: AsyncSession):\n results = await session.execute(select(database.Titles)))\n return results.scalars().all()\n\n\n@cbv(router)\nclass TitlesView:\n session: AsyncSession = Depends(database.get_session)\n\n @router.get(\"/titles\", status_code=HTTP_200_OK)\n async def get(self) -> List[TitlesSchema]:\n results = await get_titles(self.session)\n return [TitlesSchema.from_orm(result) for result in results]\n```\n\n```text\nfrom fastapi import FastAPI\n\nfrom app.routers import router \n\n\ndef create_app() -> FastAPI:\n app = FastAPI()\n app .include_router(routers, prefix=\"/\", tags=[\"Titles\"])\n\n return printer_app\n\n\napp = create_app()\n```\n\n```text\nCMD [\"uvicorn\", \"main:app\", \"--reload\", \"--host\", \"0.0.0.0\", \"--port\", \"8000\", \"--limit-max-requests\", \"10000\"]\n```\n\n```text\n<class 'asyncpg.exceptions.ConnectionDoesNotExistError'>: connection was closed in the middle of operation\n```\n\n```text\nengine = create_async_engine(DB_URL, pool_pre_ping=True)\n```\n\n```text\npool_pre_ping\n```\n\n```text\ntcp_keepalives_idle = 600 # TCP_KEEPIDLE, in seconds;\n # 0 selects the system default\ntcp_keepalives_interval = 30 # TCP_KEEPINTVL, in seconds;\n # 0 selects the system default\ntcp_keepalives_count = 10 # TCP_KEEPCNT;\n # 0 selects the system default\n```\n\n```text\nnet.ipv4.tcp_keepalive_time\n```\n\n```text\nfrom sqlalchemy.ext.asyncio import create_async_engine\nfrom sqlalchemy.pool import NullPool\n\nengine = create_async_engine(\n \"postgresql+asyncpg://user:pass@host/dbname\",\n poolclass=NullPool,\n)\n```\n\n========================================\n\nComments:\n- At postgresql container i see: LOG: could not receive data from client: Connection reset by peer\n- Thanks, but I saw this thread and yes it might be helpful for someone. I have exactly the same application, but in Flask, with default DB setup and no error. So I don’t want to change the DB setting and want to solve this error programmatically.\n- In your question you are using create_async_engine and here just create_engine. Did you switch to not using async engine?\n- No, sorry, I did not change anything. Edited my answer\n- Can you elaborate a bit?\n- @TheTridentGuy I had mistake: : connection was closed in the middle of operation after ~5 minutes of inactivity in my app. Try diffirent settings of connections, still the same. Error stops only if i add poolclass=NullPool in connection settings.","metadata":{"transformedAt":"2026-08-18T18:32:29.137Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":10,"totalLines":233,"estimatedTokens":1813}}490{"id":"stack-75249150","source":"stackoverflow","questionId":75249150,"title":"How to use class based views in FastAPI?","tags":["python","fastapi"],"text":"Title: How to use class based views in FastAPI?\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to use class based views in my FastApi project to reduce redundancy of code. Basically I need CRUD functionality for all of my models and therefor would have to write the same routes over and over again. I created a small example project to display my progress so far, but I ran into some issues.\n\nI know there is this Fastapi-utils but as far as I understand only reduces the number of Dependencies to call and is no longer maintained properly (last commit was March 2020).\n\nI have some arbitrary pydantic Schema/Model. The SQLAlchemy models and DB connection are irrelevant for now.\n\n```\nfrom typing import Optional\nfrom pydantic import BaseModel\n\nclass ObjBase(BaseModel):\n name: Optional[str]\n\nclass ObjCreate(ObjBase):\n pass\n\nclass ObjUpdate(ObjBase):\n pass\n\nclass Obj(ObjBase):\n id: int\n```\n\nA BaseService class is used to implement DB access. To simplify this there is no DB access right now and only get (by id) and list (all) is implemented.\n\n```\nfrom typing import Any, Generic, List, Optional, Type, TypeVar\nfrom pydantic import BaseModel\n\nSchemaType = TypeVar(\"SchemaType\", bound=BaseModel)\nCreateSchemaType = TypeVar(\"CreateSchemaType\", bound=BaseModel)\nUpdateSchemaType = TypeVar(\"UpdateSchemaType\", bound=BaseModel)\n\nclass BaseService(Generic[SchemaType, CreateSchemaType, UpdateSchemaType]):\n def __init__(self, model: Type[SchemaType]):\n self.model = model\n\n def get(self, id: Any) -> Any:\n return {\"id\": id}\n\n def list(self, skip: int = 0, limit: int = 100) -> Any:\n return [\n {\"id\": 1},\n {\"id\": 2},\n ]\n```\n\nThis BaseService can then be inherited by a ObjService class providing these base functions for the previously defined pydantic Obj Model.\n\n```\nfrom schemas.obj import Obj, ObjCreate, ObjUpdate\nfrom .base import BaseService\n\nclass ObjService(BaseService[Obj, ObjCreate, ObjUpdate]):\n def __init__(self):\n super(ObjService, self).__init__(Obj)\n```\n\nIn the **init**.py file in this directory a function is provided to get an ObjService instance.\n\n```\nfrom fastapi import Depends\nfrom .obj import ObjService\n\ndef get_obj_service() -> ObjService:\n return ObjService()\n```\n\nSo far everything is working. I can inject the Service Class into the relevant FastApi routes. But all routes need to be written for each model and CRUD function. Making it tedious when providing the same API endpoints for multiple models/schemas. Therefor my thought was to use something similar to the logic behind the BaseService by providing a BaseRouter which defines these routes and inherit from that class for each model.\n\nThe BaseRouter class:\n\n```\nfrom typing import Generic, Type, TypeVar\nfrom fastapi import APIRouter, Depends\nfrom pydantic import BaseModel\nfrom services.base import BaseService\n\nSchemaType = TypeVar(\"SchemaType\", bound=BaseModel)\nCreateSchemaType = TypeVar(\"CreateSchemaType\", bound=BaseModel)\nUpdateSchemaType = TypeVar(\"UpdateSchemaType\", bound=BaseModel)\n\nclass BaseRouter(Generic[SchemaType, CreateSchemaType, UpdateSchemaType]):\n def __init__(self, schema: Type[SchemaType], prefix: str, service: BaseService):\n self.schema = schema\n self.service = service\n \n self.router = APIRouter(\n prefix=prefix\n )\n\n self.router.add_api_route(\"/\", self.list, methods=['GET'])\n self.router.add_api_route(\"/{id}\", self.get, methods=['GET'])\n\n def get(self, id):\n return self.service.get(id)\n\n def list(self):\n return self.service.list()\n```\n\nThe ObjRouter class:\n\n```\nfrom schemas.obj import Obj, ObjCreate, ObjUpdate\nfrom .base import BaseRouter\nfrom services.base import BaseService\n\nclass ObjRouter(BaseRouter[Obj, ObjCreate, ObjUpdate]):\n def __init__(self, prefix: str, service: BaseService):\n super(ObjRouter, self).__init__(Obj, prefix, service)\n```\n\nThe **init**.py file in that directory\n\n```\nfrom fastapi import Depends\nfrom services import get_obj_service\nfrom services.obj import ObjService\nfrom .obj import ObjRouter\n\ndef get_obj_router(service: ObjService = Depends(get_obj_service())) -> ObjRouter:\n return ObjRouter(\"/obj\", service).router\n```\n\nIn my main.py file this router is added to the FastApi App.\n\n```\nfrom fastapi import Depends, FastAPI\nfrom routes import get_obj_router\n\napp = FastAPI()\n\napp.include_router(get_obj_router())\n```\n\nWhen starting the app the routes Get \"/obj\" and Get \"/obj/id\" show up in my Swagger Docs for the project. But when testing one of the endpoints I am getting an AttributeError: 'Depends' object has no attribute 'list'\n\nAs far as I understand Depends can only be used in FastApi functions or functions that are dependecies themselves. Therefor I tried altering the app.include_router line in my main.py by this\n\n```\napp.include_router(Depends(get_obj_router()))\n```\n\nBut it again throws an AttributeError: 'Depends' object has no attribute 'routes'.\n\nLong story short question: What am I doing wrong? Is this even possible in FastApi or do I need to stick to defining the same CRUD Api Endpoints over and over again?\n\nThe reason I want to use the Dependenvy Injection capabilities of FastApi is that later I will use the following function call in my Service classes to inject the DB session and automatically close it after the request:\n\n```\ndef get_db():\n db = SessionLocal()\n try:\n yield db\n finally:\n db.close()\n```\n\nAs far as I understand this is only possible when the highest call in the dependency hierachy (Route depends on Service depends on get_db) is done by a FastApi Route.\n\nPS: This is my first question on StackOverflow, please be gentle.\n\n========================================\n\nCode:\n```text\nfrom typing import Optional\nfrom pydantic import BaseModel\n\nclass ObjBase(BaseModel):\n name: Optional[str]\n\nclass ObjCreate(ObjBase):\n pass\n\nclass ObjUpdate(ObjBase):\n pass\n\nclass Obj(ObjBase):\n id: int\n```\n\n```text\nfrom typing import Any, Generic, List, Optional, Type, TypeVar\nfrom pydantic import BaseModel\n\n\nSchemaType = TypeVar(\"SchemaType\", bound=BaseModel)\nCreateSchemaType = TypeVar(\"CreateSchemaType\", bound=BaseModel)\nUpdateSchemaType = TypeVar(\"UpdateSchemaType\", bound=BaseModel)\n\nclass BaseService(Generic[SchemaType, CreateSchemaType, UpdateSchemaType]):\n def __init__(self, model: Type[SchemaType]):\n self.model = model\n\n def get(self, id: Any) -> Any:\n return {\"id\": id}\n\n def list(self, skip: int = 0, limit: int = 100) -> Any:\n return [\n {\"id\": 1},\n {\"id\": 2},\n ]\n```\n\n```text\nfrom schemas.obj import Obj, ObjCreate, ObjUpdate\nfrom .base import BaseService\n\nclass ObjService(BaseService[Obj, ObjCreate, ObjUpdate]):\n def __init__(self):\n super(ObjService, self).__init__(Obj)\n```\n\n```text\nfrom fastapi import Depends\nfrom .obj import ObjService\n\ndef get_obj_service() -> ObjService:\n return ObjService()\n```\n\n```text\nfrom typing import Generic, Type, TypeVar\nfrom fastapi import APIRouter, Depends\nfrom pydantic import BaseModel\nfrom services.base import BaseService\n\nSchemaType = TypeVar(\"SchemaType\", bound=BaseModel)\nCreateSchemaType = TypeVar(\"CreateSchemaType\", bound=BaseModel)\nUpdateSchemaType = TypeVar(\"UpdateSchemaType\", bound=BaseModel)\n\nclass BaseRouter(Generic[SchemaType, CreateSchemaType, UpdateSchemaType]):\n def __init__(self, schema: Type[SchemaType], prefix: str, service: BaseService):\n self.schema = schema\n self.service = service\n \n self.router = APIRouter(\n prefix=prefix\n )\n\n self.router.add_api_route(\"/\", self.list, methods=['GET'])\n self.router.add_api_route(\"/{id}\", self.get, methods=['GET'])\n\n\n def get(self, id):\n return self.service.get(id)\n\n def list(self):\n return self.service.list()\n```\n\n```text\nfrom schemas.obj import Obj, ObjCreate, ObjUpdate\nfrom .base import BaseRouter\nfrom services.base import BaseService\n\nclass ObjRouter(BaseRouter[Obj, ObjCreate, ObjUpdate]):\n def __init__(self, prefix: str, service: BaseService):\n super(ObjRouter, self).__init__(Obj, prefix, service)\n```\n\n```text\nfrom fastapi import Depends\nfrom services import get_obj_service\nfrom services.obj import ObjService\nfrom .obj import ObjRouter\n\ndef get_obj_router(service: ObjService = Depends(get_obj_service())) -> ObjRouter:\n return ObjRouter(\"/obj\", service).router\n```\n\n```text\nfrom fastapi import Depends, FastAPI\nfrom routes import get_obj_router\n\napp = FastAPI()\n\napp.include_router(get_obj_router())\n```\n\n```text\napp.include_router(Depends(get_obj_router()))\n```\n\n```text\ndef get_db():\n db = SessionLocal()\n try:\n yield db\n finally:\n db.close()\n```\n\n```py\nfrom typing import Optional, TypeVar, Type, Generic, Any, Union, Sequence\nfrom fastapi import Depends, APIRouter, FastAPI\nfrom pydantic import BaseModel\n\n\nclass ObjBase(BaseModel):\n name: Optional[str]\n\n\nclass ObjCreate(ObjBase):\n pass\n\n\nclass ObjUpdate(ObjBase):\n pass\n\n\nclass Obj(ObjBase):\n id: int\n\n\nSchemaType = TypeVar(\"SchemaType\", bound=BaseModel)\nCreateSchemaType = TypeVar(\"CreateSchemaType\", bound=BaseModel)\nUpdateSchemaType = TypeVar(\"UpdateSchemaType\", bound=BaseModel)\n\n\nclass Session:\n def __str__(self):\n return \"I am a session!\"\n\n\nasync def injecting_session():\n print(\"Creating Session\")\n return Session()\n\n\nclass BaseService(Generic[SchemaType, CreateSchemaType, UpdateSchemaType]):\n def __init__(self, model: Type[SchemaType]):\n self.model = model\n\n def get(self, id: Any, session: Session) -> Any:\n print(session)\n return {\"id\": id}\n\n def list(self, session: Session) -> Any:\n print(session)\n return [\n {\"id\": 1},\n {\"id\": 2},\n ]\n\n\nclass ObjService(BaseService[Obj, ObjCreate, ObjUpdate]):\n def __init__(self):\n super(ObjService, self).__init__(Obj)\n\n\ndef get_obj_service() -> ObjService:\n return ObjService()\n\n\nSchemaType2 = TypeVar(\"SchemaType2\", bound=BaseModel)\nCreateSchemaType2 = TypeVar(\"CreateSchemaType2\", bound=BaseModel)\nUpdateSchemaType2 = TypeVar(\"UpdateSchemaType2\", bound=BaseModel)\n\n\nclass BaseRouter(Generic[SchemaType2, CreateSchemaType2, UpdateSchemaType2]):\n def __init__(self, schema: Type[SchemaType2], prefix: str, service: BaseService):\n self.schema = schema\n self.service = service\n\n self.router = APIRouter(\n prefix=prefix\n )\n\n self.router.add_api_route(\"/\", self.list, methods=['GET'])\n self.router.add_api_route(\"/{id}\", self.get, methods=['GET'])\n\n def get(self, id, session=Depends(injecting_session)):\n return self.service.get(id, session)\n\n def list(self, session=Depends(injecting_session)):\n return self.service.list(session)\n\n\nclass ObjRouter(BaseRouter[Obj, ObjCreate, ObjUpdate]):\n def __init__(self, path, service):\n super(ObjRouter, self).__init__(Obj, path, service)\n\n\ndef get_obj_router(service=get_obj_service()) -> APIRouter: # returns API router now\n return ObjRouter(\"/obj\", service).router\n\n\napp = FastAPI()\napp.include_router(get_obj_router())\n```\n\n```text\nSession\n```\n\n```text\ninjecting_session\n```\n\n```text\nBaseRouter\n```\n\n```text\nBaseObject\n```\n\n```text\nget\n```\n\n```text\nlist\n```\n\n```text\ninjecting_session()\n```\n\n========================================\n\nComments:\n- Hey I am just trying to recreate your problem, but I believe you miscopied the ObjectRouter. It seems to be the ObjectService instead. Could you update your question?\n- I updated the code, it should now be correct.\n- Thanks for your answer. I updated my question above. I would like to use the Dependency Injection functionality of FastApi because this then makes it easier using the DB session etc. Therfore dropping the Depends is not an option.\n- Hey, I just updated my answer based on your comment. You want to add a dependency when you add the api route. Check `BaseRouter` in my updated code. In this example I am just injecting some parameters like the example on the fastapi website, but you can do whatever you want from here.\n- How can these parameters be accessed in the get() function for example?\n- I honestly still don't exactly understand what you are trying to do, but I just updated my answer again. This time showing how you could use a dependency injection to get a session to the controller function. If you are only looking to get a session to the controllers it might be more useful to use a decorator that passes a session to your function instead.\n- Thanks, that solved the issue I think. I did not think about adding the dependency to the function that gets added to the router. I am also not sure if what I am doing is correct or follows any good coding strandard, but for now this makes it more maintainable I think. Thank you very much!\n- No worries! Trying to automate routes and controllers seems like a smart move. I have in the past broken standards to write better and more maintainable code. It just needs to be documented well. Good luck with your project!\n- CheelHorn Thanks for sharing your brilliant approach and explaining it to this level of details!!! @Juhuja Thanks for the inspiring Answer!! unfortunately i dont get to understand why you decided to use two different typevars : CreateSchemaType / CreateSchemaType2 one for the service and one for the routing part. is it just for the sake of separation of concerns or is there any other thoughts behind it?? this is puzzeling me a couple of days now :) would be more than happy to get your point of view! thanks\n- @CheelHorn I think what happened is that I tried to mimic the original code closely for OP to understand my answer. In the code he posted he repeated the typevars probably for better understanding and I just copied them and renamed them as they had the same name. Given that they represent the same thing there should probably be no issue in reusing the first definition.\n- @atlasloewenherz looking back at this after half a year I am not sure anymore. Normally I would use different Schemas for the Service and the Router classes for the separation of concerns e.g. to hide some internal columns from the API. But I think in this example it was just a copy and paste issue as Juhuja guessed.\n- @atlasloewenherz I mainly followed this tutorial: patrick-muehlbauer.com/articles/fastapi-with-sqlalchemy. Maybe you can take a look","metadata":{"transformedAt":"2026-08-18T18:32:29.138Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":18,"totalLines":442,"estimatedTokens":3570}}491{"id":"stack-76970173","source":"stackoverflow","questionId":76970173,"title":"How to get Files and Form data using the Request object in FastAPI?","tags":["python","file","fastapi","multipartform-data","starlette"],"text":"Title: How to get Files and Form data using the Request object in FastAPI?\nTags: python, file, fastapi, multipartform-data, starlette\nSource: Stack Overflow\n\nQuestion:\nI am developing a webhook in which a third-party service will hit my URL and will provide some files, now I can not use FastAPI's `UploadFile = File (...)` because it throws an error of the required field **File**\nI want to read the payload and files from the request object as we can do in Flask by simply doing this\n\n```\nfrom flask import request\nfiles = request.files\n```\n\nHow can I achieve the same in FastAPI?\n\n========================================\n\nTop Answer:\nA more FastAPI-like way to obtain it is, as advised in the documentation\n\n```\n@app.post(\"/string_n_file\")\nasync def elaborate_image( a_string: Annotated[str, Form()], a_file: Annotated[UploadFile, File()]):\n # note that 'a_string' and 'a_file' should be named the same as in the request from the client\n ...\n```\n\n========================================\n\nCode:\n```text\nfrom flask import request\nfiles = request.files\n```\n\n```text\nUploadFile = File (...)\n```\n\n```py\n@app.post(\"/submit\")\nasync def register(name: str = Form(...), files: List[UploadFile] = File(...)):\n pass\n```\n\n```py\nfrom fastapi import FastAPI, Request\n\napp = FastAPI()\n\n\n@app.post(\"/submit\")\nasync def submit(request: Request):\n return await request.form()\n```\n\n```py\nfrom fastapi import FastAPI, Request, Depends, HTTPException\nfrom fastapi.responses import HTMLResponse\nfrom fastapi.templating import Jinja2Templates\nfrom starlette.datastructures import FormData, UploadFile\n\napp = FastAPI()\ntemplates = Jinja2Templates(directory='templates')\n\n\nasync def get_body(request: Request):\n content_type = request.headers.get('Content-Type')\n if content_type is None:\n raise HTTPException(status_code=400, detail='No Content-Type provided!')\n elif (content_type == 'application/x-www-form-urlencoded' or\n content_type.startswith('multipart/form-data')):\n try:\n return await request.form()\n except Exception:\n raise HTTPException(status_code=400, detail='Invalid Form data')\n else:\n raise HTTPException(status_code=400, detail='Content-Type not supported!')\n\n\n# Use this approach, if keys (names) of Form/File data are unknown to the backend beforehand\n@app.post('/submit')\nasync def submit(body=Depends(get_body)):\n if isinstance(body, FormData): # if Form/File data received\n for k in body:\n entries = body.getlist(k)\n if isinstance(body.getlist(k)[0], UploadFile): # check if it is an UploadFile object\n for file in entries:\n print(f'Filename: {file.filename}. Content (first 15 bytes): {await file.read(15)}')\n else:\n data = entries if len(entries) > 1 else entries[0]\n print(f\"{k}={data}\")\n\n return 'OK'\n\n\n# Use this approach, if keys (names) of Form/File data are known to the backend beforehand\n@app.post('/other')\nasync def other(body=Depends(get_body)):\n if isinstance(body, FormData): # if Form/File data received\n items = body.getlist('items')\n print(f\"items={items}\")\n msg = body.get('msg')\n print(f\"msg={msg}\")\n files = body.getlist('files') # returns a list of UploadFile objects\n if files:\n for file in files:\n print(f'Filename: {file.filename}. Content (first 15 bytes): {await file.read(15)}')\n \n return 'OK'\n\n\n@app.get('/', response_class=HTMLResponse)\nasync def main(request: Request):\n return templates.TemplateResponse('index.html', {'request': request})\n```\n\n```html\n<!DOCTYPE html>\n<html>\n <body>\n <form method=\"post\" action=\"/submit\" enctype=\"multipart/form-data\">\n msg : <input type=\"text\" name=\"msg\" value=\"test\"><br>\n item 2 : <input type=\"text\" name=\"items\" value=\"1\"><br>\n item 2 : <input type=\"text\" name=\"items\" value=\"2\"><br> \n <label for=\"fileInput\">Choose file(s) to upload</label>\n <input type=\"file\" id=\"fileInput\" name=\"files\" multiple>\n <input type=\"submit\" value=\"submit\">\n </form>\n </body>\n</html>\n```\n\n```html\n<!DOCTYPE html>\n<html>\n <body>\n <form id=\"myForm\" >\n msg : <input type=\"text\" name=\"msg\" value=\"test\"><br>\n item 1 : <input type=\"text\" name=\"items\" value=\"1\"><br>\n item 2 : <input type=\"text\" name=\"items\" value=\"2\"><br>\n </form>\n <label for=\"fileInput\">Choose file(s) to upload</label>\n <input type=\"file\" id=\"fileInput\" name=\"files\" multiple><br>\n <input type=\"button\" value=\"Submit\" onclick=\"submitUsingFetch()\">\n <p id=\"resp\"></p>\n <script>\n function submitUsingFetch() {\n const resp = document.getElementById(\"resp\");\n const fileInput = document.getElementById('fileInput');\n const myForm = document.getElementById('myForm');\n var formData = new FormData(myForm);\n for (const file of fileInput.files)\n formData.append('files', file);\n \n fetch('/submit', {\n method: 'POST',\n body: formData,\n })\n .then(response => response.json())\n .then(data => {\n resp.innerHTML = JSON.stringify(data); // data is a JSON object\n })\n .catch(error => {\n console.error(error);\n });\n }\n </script>\n </body>\n</html>\n```\n\n```py\nimport requests\n\nurl = 'http://127.0.0.1:8000/submit'\ndata = {'items': ['foo', 'bar'], 'msg': 'Hello!'}\nfiles = [('files', open('a.txt', 'rb')), ('files', open('b.txt', 'rb'))]\n \n# Send Form data and files\nr = requests.post(url, data=data, files=files) \nprint(r.text)\n\n# Send Form data only\nr = requests.post(url, data=data) \nprint(r.text)\n```\n\n```text\nFile\n```\n\n```text\nUploadFile\n```\n\n```text\nForm\n```\n\n```text\nRequest\n```\n\n```text\nawait request.form()\n```\n\n```text\nFormData\n```\n\n```text\nFile\n```\n\n```text\nForm\n```\n\n```text\nFile\n```\n\n```text\nForm\n```\n\n```text\nFormData\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\ndef\n```\n\n```text\n<form>\n```\n\n```text\n<input>\n```\n\n```text\nname\n```\n\n```text\nFormData\n```\n\n```text\nrequests\n```\n\n```py\n@app.post(\"/string_n_file\")\nasync def elaborate_image( a_string: Annotated[str, Form()], a_file: Annotated[UploadFile, File()]):\n # note that 'a_string' and 'a_file' should be named the same as in the request from the client\n ...\n```\n\n========================================\n\nComments:\n- What is the error you're facing and why exactly can't you use `UploadFile`?\n- because I will have to assign a variable inside the function like file; UploadFIle = File(..) and the third party hitting my endpoint is not sending the data like this. they are sending the files in request. so I want to read the files from the request object\n- That's what `UploadFile` does; can you show the code and the request that doesn't work as you expect it to?\n- the code is working but I am getting an empty list of files.\n- Please make sure that you are using the **same** name for the `files` parameter as the one used by the third-party service that is calling the API endpoint. In the example above, that name is `files`. Have a look at related posts here, here and here. If that is unknown to you, you could use/print `await request.body()` to get the raw `multipart/form-data` body and extract the name from the `Content-Disposition` header of the file part.","metadata":{"transformedAt":"2026-08-18T18:32:29.138Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":28,"totalLines":279,"estimatedTokens":1887}}492{"id":"stack-65410635","source":"stackoverflow","questionId":65410635,"title":"Python FastAPI Async Variable Sharing","tags":["python","asynchronous","fastapi"],"text":"Title: Python FastAPI Async Variable Sharing\nTags: python, asynchronous, fastapi\nSource: Stack Overflow\n\nQuestion:\nIf I had the below code, how would the variable `service` affect the asynchronous nature of the endpoints? Will the variable be shared? Or will it be locked when in use, thus blocking other endpoints from accessing it until the current one is done?\n\nI ask the above assuming that Service instances are stateless, i.e. it would be equivalent if I created an instance of Service in each endpoint. I am reluctant to do that because I don't know which is more time consuming, instantiating and destroying a Service object or sharing one?\n\n```\nfrom typing import List, Union\nfrom fastapi import APIRouter, Body, Depends\n\n# Service definition\nrouter = APIRouter()\nservice = Service()\n\n@router.post(\"/a\", response_model=Union[A, None])\nasync def x():\n service.start()\n pass\n\n@router.post(\"/b\", response_model=Union[B, None])\nasync def y():\n service.stop()\n pass\n```\n\n========================================\n\nCode:\n```text\nfrom typing import List, Union\nfrom fastapi import APIRouter, Body, Depends\n\n# Service definition\nrouter = APIRouter()\nservice = Service()\n\n@router.post(\"/a\", response_model=Union[A, None])\nasync def x():\n service.start()\n pass\n\n@router.post(\"/b\", response_model=Union[B, None])\nasync def y():\n service.stop()\n pass\n```\n\n```text\nservice\n```\n\n```py\nasync def x():\n a = await service.start()\n return a\n```\n\n```py\nimport asyncio\n\n@asyncio.coroutine\ndef decorated(x):\n yield from x \n\nasync def native(x):\n await x\n```\n\n```text\nservice.stop()\n```\n\n```text\nawaitable\n```\n\n```text\nList\n```\n\n```text\nstart()\n```\n\n```text\nservice().start()\n```\n\n```text\nstart()\n```\n\n```text\nservice().start()\n```\n\n```text\na\n```\n\n```text\nreturn a\n```\n\n```text\nservice().start()\n```\n\n```text\nyielding\n```\n\n```text\nasync\n```\n\n```text\nawait\n```\n\n```text\nyield from\n```\n\n```text\nselect()\n```\n\n```text\npoll()\n```\n\n```text\nselect()\n```\n\n========================================\n\nComments:\n- What do the `start` and `stop` functions do? If they execute fast enough, then this code is valid.\n- So what you're saying is if I'm sharing the same variable across multiple async functions, they will not automatically lock the resource because they are concurrently running and not in parallel? So in this case, would it be slower if I did Service().start() in each of them? (because of the added memory allocation time)\n- Yup, no language that I have worked with such as locks some variable automatically, you need to lock it yourself. Even if it runs parallel you still need to lock it. This is not specific to any language there is a location on your physical memory and you are trying to change it. It's pretty physical, there are no abstractions at that point. Coroutines are just abstractions to call stack and the instruction pointer. Every code piece that executes in the stack has a specific instruction.\n- I thought the comment wouldn't be enough and I updated the answer.\n- Makes sense, hard to know what memory to lock automatically, thanks!","metadata":{"transformedAt":"2026-08-18T18:32:29.138Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":21,"totalLines":147,"estimatedTokens":767}}493{"id":"stack-63292900","source":"stackoverflow","questionId":63292900,"title":"Upload .csv with FastAPI and JS fetch","tags":["javascript","python","reactjs","csv","fastapi"],"text":"Title: Upload .csv with FastAPI and JS fetch\nTags: javascript, python, reactjs, csv, fastapi\nSource: Stack Overflow\n\nQuestion:\nMy app uses React on the frontend and FastAPI on the backend.\n\nI'm trying to upload a csv file to my server.\n\nOn submitting a form, this gets called:\n\n```\nconst onSubmit = async (e) => {\n e.preventDefault();\n const formData = new FormData();\n formData.append(\"file\", file);\n fetch(\"/api/textitems/upload\", {\n method: \"POST\",\n body: formData,\n });\n };\n```\n\nThe data is received by:\n\n```\n@app.post('/api/textitems/upload')\ndef upload_file(csv_file: UploadFile = File(...)):\n dataframe = pd.read_csv(csv_file.file)\n return dataframe.head()\n```\n\nI keep getting `INFO: 127.0.0.1:0 - \"POST /api/textitems/upload HTTP/1.1\" 422 Unprocessable Entity` errors.\n\nI am able to successfully perform the post request with curl like so:\n\n`curl -X POST \"http://localhost:8000/api/textitems/upload\" -H \"accept: application/json\" -H \"Content-Type: multipart/form-data\" -F \"csv_file=@exp_prod.csv;type=text/csv\"`\n\nAny advice about where I'm going wrong when using Javascript though?\n\n========================================\n\nTop Answer:\nBe sure that the name of the file in the form matches the name of the file in the parameter!\n\nSee my answer to the same question below.\n\nHow to send file to fastapi endpoint using postman\n\n========================================\n\nCode:\n```js\nconst onSubmit = async (e) => {\n e.preventDefault();\n const formData = new FormData();\n formData.append(\"file\", file);\n fetch(\"/api/textitems/upload\", {\n method: \"POST\",\n body: formData,\n });\n };\n```\n\n```py\n@app.post('/api/textitems/upload')\ndef upload_file(csv_file: UploadFile = File(...)):\n dataframe = pd.read_csv(csv_file.file)\n return dataframe.head()\n```\n\n```text\nINFO: 127.0.0.1:0 - \"POST /api/textitems/upload HTTP/1.1\" 422 Unprocessable Entity\n```\n\n```text\ncurl -X POST \"http://localhost:8000/api/textitems/upload\" -H \"accept: application/json\" -H \"Content-Type: multipart/form-data\" -F \"csv_file=@exp_prod.csv;type=text/csv\"\n```\n\n```js\nconst onSubmit = async (e) => {\n e.preventDefault();\n const formData = new FormData();\n formData.append(\"file\", file, file.name);\n await fetch(`/api/textitems/upload`, {\n method: \"POST\",\n body: formData,\n })\n```\n\n```py\n@app.post('/api/textitems/upload')\ndef upload_file(file: UploadFile = File(...), db: Session = Depends(get_db)):\n df = pd.read_csv(file.file).head()\n return df\n```\n\n```js\nconst onSubmit = async (e) => {\n e.preventDefault();\n const formData = new FormData();\n formData.append(\"file\", file);\n fetch(\"/api/textitems/upload\", {\n method: \"POST\",\n body: formData,\n headers: {\n 'Content-Type': 'multipart/form-data',\n }\n });\n };\n```\n\n```text\nmultipart/form-data\n```\n\n```ts\nimport { env } from '$env/dynamic/private';\n\n/** @type {import('./$types').Actions} */\nexport const actions: import('./$types').Actions = {\n uploadFile: async ({ request }) => {\n\n // Get the form data\n const formData = await request.formData();\n const file = formData.get('fileToUpload') as File; // taken from the `name` field on the form\n formData.append('file', file, file.name);\n\n await fetch(`${env.BACKEND_URL}/pdf-upload/`, {\n method: 'POST',\n body: formData\n })\n .then((res) => res.json())\n .then((data) => console.log(data))\n .catch((error) => console.error('Error:', error));\n\n return {\n success: true\n };\n\n\n }\n};\n```\n\n========================================\n\nComments:\n- Do you have `python-multipart` installed on your current environment?\n- Yes I do have `python-multipart`\n- I think your returning value causes this, by default fastapi expects key:value pairs, i'm not sure how `head()` sends data but can you try with dict? Also there was a function like `to_dict()` in pandas or something else and `FileResponse` from `fastapi.responses` could be helpful.\n- I've tried but unfortunately without success. I'm fairly sure it's that JS's fetch method is not sending something that FastAPI considers a correct type. I believe this because the endpoint does not even run when the input comes from my frontend yet it returns the desired output when invoked using curl.\n- Related answers can be found here, here, as well as here, here and here","metadata":{"transformedAt":"2026-08-18T18:32:29.138Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":9,"totalLines":153,"estimatedTokens":1104}}494{"id":"stack-74661044","source":"stackoverflow","questionId":74661044,"title":"Add a custom javascript to the FastAPI Swagger UI docs webpage in Python","tags":["python","fastapi","swagger-ui"],"text":"Title: Add a custom javascript to the FastAPI Swagger UI docs webpage in Python\nTags: python, fastapi, swagger-ui\nSource: Stack Overflow\n\nQuestion:\nI want to load my custom javascript file or code to the FastAPI Swagger UI webpage, to add some dynamic interaction when I create a FastAPI object.\n\nFor example, in Swagger UI on docs webpage I would like to\n\n```\n\n```\n\nor\n\n```\n alert('worked!') \n```\n\nI tried:\n\n```\napi = FastAPI(docs_url=None)\n\napi.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")\n\n@api.get(\"/docs\", include_in_schema=False)\nasync def custom_swagger_ui_html():\n return get_swagger_ui_html(\n openapi_url=api.openapi_url,\n title=api.title + \" - Swagger UI\",\n oauth2_redirect_url=api.swagger_ui_oauth2_redirect_url,\n swagger_js_url=\"/static/sample.js\",\n swagger_css_url=\"/static/sample.css\",\n )\n```\n\nbut it is not working. Is there a way just to insert my custom javascript code on docs webpage of FastAPI Swagger UI with Python ?\n\n========================================\n\nTop Answer:\nFinally I made it working. This is what I did:\n\n```\nfrom fastapi.openapi.docs import (\n get_redoc_html,\n get_swagger_ui_html,\n get_swagger_ui_oauth2_redirect_html,\n)\nfrom fastapi.staticfiles import StaticFiles\n\napi = FastAPI(docs_url=None) \n\npath_to_static = os.path.join(os.path.dirname(__file__), 'static')\nlogger.info(f\"path_to_static: {path_to_static}\")\napi.mount(\"/static\", StaticFiles(directory=path_to_static), name=\"static\")\n\n@api.get(\"/docs\", include_in_schema=False)\n async def custom_swagger_ui_html():\n return get_swagger_ui_html(\n openapi_url=api.openapi_url,\n title=\"My API\",\n oauth2_redirect_url=api.swagger_ui_oauth2_redirect_url,\n swagger_js_url=\"/static/custom_script.js\",\n # swagger_css_url=\"/static/swagger-ui.css\",\n # swagger_favicon_url=\"/static/favicon-32x32.png\",\n )\n```\n\n**Important notes:**\n\n- Make sure the static path is correct and all your files are in the static folder, by default the static folder should be in the same folder with the script that created the FastAPI object.\n\nFor example:\n\n```\n-parent_folder\n Build_FastAPI.py\n -static_folder\n custom_script.js\n custom_css.css\n```\n\n- Find the swagger-ui-bundle.js on internet and copy-paste all its content to custom_script.js, then add your custom javascript code at the beginning or at the end of custom_script.js.\n\nFor example:\n\n```\nsetTimeout(function(){alert('My custom script is working!')}, 5000);\n...\n.....\n/*! For license information please see swagger-ui-bundle.js.LICENSE.txt */\n !function(e,t){\"object\"==typeof exports&&\"object\"==typeof module?module.exports=t():\"function\"==typeof define&&define.amd?define([],t):\"object\"==typeof exports?exports.SwaggerUIBundle=t():e.SwaggerUIBundle=t()}\n...\n.....\n```\n\n- Save and refresh your browser, you are all way up!\n\n***IF SOMEBODY KNOWS A BETTER ANSWER YOUR ARE WELCOME, THE BEST ONE WILL BE ACCEPTED!***\n\n========================================\n\nCode:\n```text\n<script src=\"custom_script.js\"></script>\n```\n\n```text\n<script> alert('worked!') </script>\n```\n\n```text\napi = FastAPI(docs_url=None)\n\napi.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")\n\n@api.get(\"/docs\", include_in_schema=False)\nasync def custom_swagger_ui_html():\n return get_swagger_ui_html(\n openapi_url=api.openapi_url,\n title=api.title + \" - Swagger UI\",\n oauth2_redirect_url=api.swagger_ui_oauth2_redirect_url,\n swagger_js_url=\"/static/sample.js\",\n swagger_css_url=\"/static/sample.css\",\n )\n```\n\n```py\n# custom_swagger.py\n\nimport json\nfrom typing import Any, Dict, Optional\n\nfrom fastapi.encoders import jsonable_encoder\nfrom fastapi.openapi.docs import swagger_ui_default_parameters\nfrom starlette.responses import HTMLResponse\n\ndef get_swagger_ui_html(\n *,\n openapi_url: str,\n title: str,\n swagger_js_url: str = \"https://cdn.jsdelivr.net/npm/swagger-ui-dist@4/swagger-ui-bundle.js\",\n swagger_css_url: str = \"https://cdn.jsdelivr.net/npm/swagger-ui-dist@4/swagger-ui.css\",\n swagger_favicon_url: str = \"https://fastapi.tiangolo.com/img/favicon.png\",\n oauth2_redirect_url: Optional[str] = None,\n init_oauth: Optional[Dict[str, Any]] = None,\n swagger_ui_parameters: Optional[Dict[str, Any]] = None,\n custom_js_url: Optional[str] = None,\n) -> HTMLResponse:\n current_swagger_ui_parameters = swagger_ui_default_parameters.copy()\n if swagger_ui_parameters:\n current_swagger_ui_parameters.update(swagger_ui_parameters)\n\n html = f\"\"\"\n <!DOCTYPE html>\n <html>\n <head>\n <link type=\"text/css\" rel=\"stylesheet\" href=\"{swagger_css_url}\">\n <link rel=\"shortcut icon\" href=\"{swagger_favicon_url}\">\n <title>{title}</title>\n </head>\n <body>\n <div id=\"swagger-ui\">\n </div>\n \"\"\"\n \n if custom_js_url:\n html += f\"\"\"\n <script src=\"{custom_js_url}\"></script>\n \"\"\"\n\n html += f\"\"\"\n <script src=\"{swagger_js_url}\"></script>\n <!-- `SwaggerUIBundle` is now available on the page -->\n <script>\n const ui = SwaggerUIBundle({{\n url: '{openapi_url}',\n \"\"\"\n\n for key, value in current_swagger_ui_parameters.items():\n html += f\"{json.dumps(key)}: {json.dumps(jsonable_encoder(value))},\\n\"\n\n if oauth2_redirect_url:\n html += f\"oauth2RedirectUrl: window.location.origin + '{oauth2_redirect_url}',\"\n\n html += \"\"\"\n presets: [\n SwaggerUIBundle.presets.apis,\n SwaggerUIBundle.SwaggerUIStandalonePreset\n ],\n })\"\"\"\n\n if init_oauth:\n html += f\"\"\"\n ui.initOAuth({json.dumps(jsonable_encoder(init_oauth))})\n \"\"\"\n\n html += \"\"\"\n </script>\n </body>\n </html>\n \"\"\"\n return HTMLResponse(html)\n```\n\n```py\ncustom_js_url: Optional[str] = None,\n```\n\n```py\nif custom_js_url:\n html += f\"\"\"\n <script src=\"{custom_js_url}\"></script>\n \"\"\"\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.staticfiles import StaticFiles\nfrom fastapi.openapi.docs import (\n get_redoc_html,\n get_swagger_ui_oauth2_redirect_html,\n)\nfrom custom_swagger import get_swagger_ui_html\nimport os\n\napp = FastAPI(docs_url=None) \npath_to_static = os.path.join(os.path.dirname(__file__), 'static')\napp.mount(\"/static\", StaticFiles(directory=path_to_static), name=\"static\")\n\n@app.get(\"/docs\", include_in_schema=False)\nasync def custom_swagger_ui_html():\n return get_swagger_ui_html(\n openapi_url=app.openapi_url,\n title=\"My API\",\n oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url,\n swagger_js_url=\"/static/swagger-ui-bundle.js\",\n swagger_css_url=\"/static/swagger-ui.css\",\n # swagger_favicon_url=\"/static/favicon-32x32.png\",\n custom_js_url=\"/static/custom_script.js\",\n )\n```\n\n```text\nget_swagger_ui_html\n```\n\n```text\nfastapi.openapi.docs\n```\n\n```text\ncustom_js_url\n```\n\n```text\nswagger_js_url\n```\n\n```text\nget_swagger_ui_html\n```\n\n```text\n/docs\n```\n\n```text\nswagger-ui-bundle.js\n```\n\n```text\nfrom fastapi.openapi.docs import (\n get_redoc_html,\n get_swagger_ui_html,\n get_swagger_ui_oauth2_redirect_html,\n)\nfrom fastapi.staticfiles import StaticFiles\n\napi = FastAPI(docs_url=None) \n\npath_to_static = os.path.join(os.path.dirname(__file__), 'static')\nlogger.info(f\"path_to_static: {path_to_static}\")\napi.mount(\"/static\", StaticFiles(directory=path_to_static), name=\"static\")\n\n@api.get(\"/docs\", include_in_schema=False)\n async def custom_swagger_ui_html():\n return get_swagger_ui_html(\n openapi_url=api.openapi_url,\n title=\"My API\",\n oauth2_redirect_url=api.swagger_ui_oauth2_redirect_url,\n swagger_js_url=\"/static/custom_script.js\",\n # swagger_css_url=\"/static/swagger-ui.css\",\n # swagger_favicon_url=\"/static/favicon-32x32.png\",\n )\n```\n\n```text\n-parent_folder\n Build_FastAPI.py\n -static_folder\n custom_script.js\n custom_css.css\n```\n\n```text\nsetTimeout(function(){alert('My custom script is working!')}, 5000);\n...\n.....\n/*! For license information please see swagger-ui-bundle.js.LICENSE.txt */\n !function(e,t){\"object\"==typeof exports&&\"object\"==typeof module?module.exports=t():\"function\"==typeof define&&define.amd?define([],t):\"object\"==typeof exports?exports.SwaggerUIBundle=t():e.SwaggerUIBundle=t()}\n...\n.....\n```\n\n========================================\n\nComments:\n- Future readers might find this answer helpful as well.","metadata":{"transformedAt":"2026-08-18T18:32:29.138Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":17,"totalLines":321,"estimatedTokens":2098}}495{"id":"stack-61061580","source":"stackoverflow","questionId":61061580,"title":"Gunicorn is not respecting timeout when using UvicornWorker","tags":["python","gunicorn","fastapi","uvicorn"],"text":"Title: Gunicorn is not respecting timeout when using UvicornWorker\nTags: python, gunicorn, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI am setting up a timeout check so I made and endpoint:\n\n```\n@app.get(\"/tc\", status_code=200)\ndef timeout_check():\n time.sleep(500)\n return \"NOT OK\"\n```\n\nI am using the docker image `tiangolo/uvicorn-gunicorn-fastapi:python3.7`\nand my command to run the server:\n\n```\nCMD [\"gunicorn\",\"--log-level\",\"debug\",\"--keep-alive\",\"15\", \"--reload\", \"-b\", \"0.0.0.0:8080\", \"--timeout\", \"15\", \"--worker-class=uvicorn.workers.UvicornH11Worker\", \"--workers=10\", \"myapp.main:app\"]\n```\n\nI am expecting the endpoint to fail after 15 seconds, but it doesn't. Seems like the timeout is not respected. Any fix for that?\n\n========================================\n\nCode:\n```text\n@app.get(\"/tc\", status_code=200)\ndef timeout_check():\n time.sleep(500)\n return \"NOT OK\"\n```\n\n```text\nCMD [\"gunicorn\",\"--log-level\",\"debug\",\"--keep-alive\",\"15\", \"--reload\", \"-b\", \"0.0.0.0:8080\", \"--timeout\", \"15\", \"--worker-class=uvicorn.workers.UvicornH11Worker\", \"--workers=10\", \"myapp.main:app\"]\n```\n\n```text\ntiangolo/uvicorn-gunicorn-fastapi:python3.7\n```\n\n========================================\n\nComments:\n- It seems like they close the discussion here? github.com/benoitc/gunicorn/issues/1493","metadata":{"transformedAt":"2026-08-18T18:32:29.138Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":3,"totalLines":45,"estimatedTokens":326}}496{"id":"stack-68766563","source":"stackoverflow","questionId":68766563,"title":"fastapi response not formatted correctly for sqlite db with a json column","tags":["python","json","python-3.x","sqlite","fastapi"],"text":"Title: fastapi response not formatted correctly for sqlite db with a json column\nTags: python, json, python-3.x, sqlite, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have a fast api app with sqlite, I am trying to get an output as json which is valid.\nOne of the columns in sqlite database is a list stored in Text column and another column has json data in Text column.\n\n**code sample below**\n\n```\ndatabase = Database(\"sqlite:///db/database.sqlite\")\n\napp = FastAPI()\n\n@app.get(\"/flow_json\")\nasync def get_data(select: str='*'):\n query = query_formatter(table='api_flow_json',select=select)\n\n logger.info(query)\n results = await database.fetch_all(query=query)\n print(results)\n # this result is a list of tuples which i can confirm output stated below\n \n return results\n```\n\n**List of tuples printed**\n\n```\n[('182', 'ABC', 'response_name', '[[\"ABC\",\"DEF\",\"GHI\"]]', 'GHI', '{\"metadata\":{\"contentId\":\"ABC\"}}', '2', 'false', '39', '72', 'true')]\n```\n\n**sqlite db row example below**\n\n```\n\"id\",\"customer_name\",\"response_name\",\"entities\",\"abstract\",\"json_col\",\"revision\",\"disabled\",\"customer_id\",\"id2\",\"auth\"\n182,\"ABC\",\"response_name\",\"[[\"\"ABC\"\",\"\"DEF\"\",\"\"GHI\"\"]]\",\"GHI\",\"{\"\"metadata\"\":{\"\"contentId\"\":\"\"ABC\"\"}}\",2,false,39,72,true\n```\n\n**result using http call**\n\n```\n[{\"id\":\"182\",\"customer_name\":\"ABC\",\"response_name\":\"response_name\",\"entities\":\"[[\\\"ABC\\\",\\\"DEF\\\",\\\"GHI\\\"]]\",\"abstract\":\"GHI\",\"json_col\":\"{\\\"metadata\\\":{\\\"contentId\\\":\\\"ABC\\\"}}\",\"revision\":\"2\",\"disabled\":\"false\",\"customer_id\":\"39\",\"id2\":\"72\",\"auth\":\"true\"}]\n```\n\n**expected result**\n\n```\n[{\"id\":\"182\",\"customer_name\":\"ABC\",\"response_name\":\"response_name\",\"entities\":[[\"ABC\",\"DEF\",\"GHI\"]],\"abstract\":\"GHI\",\"json_col\":{metadata:{contentId:ABC}},\"revision\":\"2\",\"disabled\":\"false\",\"customer_id\":\"39\",\"id2\":\"72\",\"auth\":\"true\"}]\n```\n\nWhat did I try:\n\n- transforming list to be more json friendly after I get the list of tuples\n\n- tried the json1 extension for sqlite but doesn't work.\n\n- I know that this will involve a formatting after response from database but can't figure out the formatting to return to client.\n\n========================================\n\nTop Answer:\nYou should use pydantic BaseModel for your response:\n\n```\nfrom pydantic import BaseModel\n# Possible additional code\n\nclass Metadata(BaseModel):\n contentId: str\n\nclass JsonCol(BaseModel):\n metadata: Metadata\n\nclass ApiFlowJson(BaseModel):\n id: int\n customer_name: str\n response_name: str\n entities: List[str]\n abstract: str\n json_col: JsonCol\n revision: int\n disabled: bool\n customer_id: int\n id2: int\n auth: bool\n\n class Config:\n orm_mode = True\n\n@app.get(\"/flow_json\", response_model=List[ApiFlowJson])\nasync def get_data(select: str='*'):\n # your code\n```\n\nA more detailed explanation can be found here: https://fastapi.tiangolo.com/tutorial/response-model/\n\nOther way, if you don't want go into Pydantic, is to return response directly:\n\n```\nfrom fastapi.responses import JSONResponse\nfrom fastapi.encoders import jsonable_encoder\n\n@app.get(\"/flow_json\")\nasync def get_data(select: str='*'):\n # your code\n json_compatible_data = jsonable_encoder(results)\n return JSONResponse(content=json_compatible_data)\n```\n\nMore detailed on direct response can be found here: https://fastapi.tiangolo.com/advanced/response-directly/\n\n**NOTE: the code is not executed and tested, so you should not only copy-paste it, but also check it**\n\n========================================\n\nCode:\n```text\ndatabase = Database(\"sqlite:///db/database.sqlite\")\n\napp = FastAPI()\n\n@app.get(\"/flow_json\")\nasync def get_data(select: str='*'):\n query = query_formatter(table='api_flow_json',select=select)\n\n logger.info(query)\n results = await database.fetch_all(query=query)\n print(results)\n # this result is a list of tuples which i can confirm output stated below\n \n return results\n```\n\n```text\n[('182', 'ABC', 'response_name', '[[\"ABC\",\"DEF\",\"GHI\"]]', 'GHI', '{\"metadata\":{\"contentId\":\"ABC\"}}', '2', 'false', '39', '72', 'true')]\n```\n\n```text\n\"id\",\"customer_name\",\"response_name\",\"entities\",\"abstract\",\"json_col\",\"revision\",\"disabled\",\"customer_id\",\"id2\",\"auth\"\n182,\"ABC\",\"response_name\",\"[[\"\"ABC\"\",\"\"DEF\"\",\"\"GHI\"\"]]\",\"GHI\",\"{\"\"metadata\"\":{\"\"contentId\"\":\"\"ABC\"\"}}\",2,false,39,72,true\n```\n\n```text\n[{\"id\":\"182\",\"customer_name\":\"ABC\",\"response_name\":\"response_name\",\"entities\":\"[[\\\"ABC\\\",\\\"DEF\\\",\\\"GHI\\\"]]\",\"abstract\":\"GHI\",\"json_col\":\"{\\\"metadata\\\":{\\\"contentId\\\":\\\"ABC\\\"}}\",\"revision\":\"2\",\"disabled\":\"false\",\"customer_id\":\"39\",\"id2\":\"72\",\"auth\":\"true\"}]\n```\n\n```text\n[{\"id\":\"182\",\"customer_name\":\"ABC\",\"response_name\":\"response_name\",\"entities\":[[\"ABC\",\"DEF\",\"GHI\"]],\"abstract\":\"GHI\",\"json_col\":{metadata:{contentId:ABC}},\"revision\":\"2\",\"disabled\":\"false\",\"customer_id\":\"39\",\"id2\":\"72\",\"auth\":\"true\"}]\n```\n\n```text\nclass ApiFlowJson(BaseModel):\n id: int\n customer_name: str\n response_name: str\n entities: Json\n abstract: str\n json_col: Json\n revision: int\n disabled: bool\n customer_id: int\n id2: int\n auth: bool\n\n class Config:\n orm_mode = True\n```\n\n```text\nfrom typing import List\n\nimport sqlalchemy\nfrom databases import Database\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel, Json\n\n\nDATABASE_URL = \"sqlite:///test.db\"\n\n\napp = FastAPI()\n\n# database\ndatabase = Database(DATABASE_URL)\n\nmetadata = sqlalchemy.MetaData()\n\napi_flow_json = sqlalchemy.Table(\n \"api_flow_json\",\n metadata,\n sqlalchemy.Column(\"id\", sqlalchemy.Integer, primary_key=True),\n sqlalchemy.Column(\"customer_name\", sqlalchemy.String),\n sqlalchemy.Column(\"response_name\", sqlalchemy.String),\n sqlalchemy.Column(\"entities\", sqlalchemy.JSON),\n sqlalchemy.Column(\"abstract\", sqlalchemy.String),\n sqlalchemy.Column(\"json_col\", sqlalchemy.JSON),\n sqlalchemy.Column(\"revision\", sqlalchemy.Integer),\n sqlalchemy.Column(\"disabled\", sqlalchemy.Boolean),\n sqlalchemy.Column(\"customer_id\", sqlalchemy.Integer),\n sqlalchemy.Column(\"id2\", sqlalchemy.Integer),\n sqlalchemy.Column(\"auth\", sqlalchemy.Boolean),\n)\n\nengine = sqlalchemy.create_engine(\n DATABASE_URL, connect_args={\"check_same_thread\": False}\n)\n\nmetadata.create_all(engine)\n\n# pydantic\n\nclass ApiFlowJson(BaseModel):\n id: int\n customer_name: str\n response_name: str\n entities: Json\n abstract: str\n json_col: Json\n revision: int\n disabled: bool\n customer_id: int\n id2: int\n auth: bool\n\n class Config:\n orm_mode = True\n\n\n# events\n\n@app.on_event(\"startup\")\nasync def startup():\n await database.connect()\n\n\n@app.on_event(\"shutdown\")\nasync def shutdown():\n await database.disconnect()\n\n\n# route handlers\n\n@app.get(\"/\")\ndef home():\n return \"Hello, World!\"\n\n\n@app.get(\"/seed\")\nasync def seed():\n query = api_flow_json.insert().values(\n customer_name=\"ABC\",\n response_name=\"response_name\",\n entities='[\"ABC\",\"DEF\",\"GHI\"]',\n abstract=\"GHI\",\n json_col='{\"metadata\":{\"contentId\":\"ABC\"}}',\n revision=2,\n disabled=False,\n customer_id=39,\n id2=72,\n auth=True,\n )\n record_id = await database.execute(query)\n return {\"id\": record_id}\n\n\n@app.get(\"/get\", response_model=List[ApiFlowJson])\nasync def get_data():\n query = api_flow_json.select()\n return await database.fetch_all(query)\n```\n\n```text\nentities\n```\n\n```text\njson_col\n```\n\n```text\nfrom pydantic import BaseModel\n# Possible additional code\n\nclass Metadata(BaseModel):\n contentId: str\n\nclass JsonCol(BaseModel):\n metadata: Metadata\n\nclass ApiFlowJson(BaseModel):\n id: int\n customer_name: str\n response_name: str\n entities: List[str]\n abstract: str\n json_col: JsonCol\n revision: int\n disabled: bool\n customer_id: int\n id2: int\n auth: bool\n\n class Config:\n orm_mode = True\n\n\n@app.get(\"/flow_json\", response_model=List[ApiFlowJson])\nasync def get_data(select: str='*'):\n # your code\n```\n\n```text\nfrom fastapi.responses import JSONResponse\nfrom fastapi.encoders import jsonable_encoder\n\n@app.get(\"/flow_json\")\nasync def get_data(select: str='*'):\n # your code\n json_compatible_data = jsonable_encoder(results)\n return JSONResponse(content=json_compatible_data)\n```\n\n========================================\n\nComments:\n- I get an error pydantic.error_wrappers.ValidationError: 2 validation errors for ApiFlowCatalog response -> 0 -> entities value is not a valid list (type=type_error.list) response -> 0 -> json_col value is not a valid dict (type=type_error.dict)\n- I think its because entities is a list inside a string and same for json_col, its a json inside a string\n- Yes, you are propably right. Change it both (`entities` and `response`) to string.\n- But how would i convert the response to be a json, which is valid, like list is a list with string encapsulation?\n- I did not understand your last comment, please elaborate\n- So the issue is the single quotes in the \"result using http call\" example. If you look at it, you will see the difference b/w expected output and that http call, thanks in advance\n- This worked but can you explain what is happening here, i do understand all the parts individually, but how does sqlalchemy engine matter here? and json used. I would appreciate this\n- You can ignore the sqlalchemy bits. I assume you're just using vanilla SQL to set up the database and create the tables, right? For your code, use sqlite.org/json1.html to enable JSON fields for `entities` and `json_col`.\n- I used vanilla sql and imported data using CSVs. The main thing is pydantic Json worked for my database too, and everything is rendered perfectly now.","metadata":{"transformedAt":"2026-08-18T18:32:29.138Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":11,"totalLines":336,"estimatedTokens":2387}}497{"id":"stack-71532080","source":"stackoverflow","questionId":71532080,"title":"FastAPI swagger doesn't like list of strings passed via query parameter but endpoint works in browser","tags":["swagger-ui","fastapi"],"text":"Title: FastAPI swagger doesn't like list of strings passed via query parameter but endpoint works in browser\nTags: swagger-ui, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have a problem with a REST API endpoint in FastAPI that accepts a list of strings via a single query parameter. An example of this endpoint's usage is:\n\n```\nhttp://127.0.0.1:8000/items/2?short=false&response=this&response=that\n```\n\nHere, the parameter named 'response' accepts a list of strings as documented in FastAPI tutorial, section on Query Parameters and String Validation. The endpoint works as expected in the browser.\n\nhttps://i.sstatic.net/HAtSf.png\n\nHowever, it does not work in Swagger docs. The button labeled 'Add string item' shakes upon clicking 'Execute' to test the endpoint. Swagger UI seems unable to create the expected URL with the embedded query parameters (as shown in Fig 1.).\n\nhttps://i.sstatic.net/O4zAi.png\n\nThe code for the endpoint is as follows. I have tried with and without validation.\n\n```\n@app.get(\"/items/{item_ID}\")\nasync def getQuestion_byID(item_ID: int = Path(\n ...,\n title = \"Numeric ID of the question\",\n description = \"Specify a number between 1 and 999\",\n ge = 1,\n le = 999\n ), response: Optional[List[str]] = Query(\n [],\n title=\"Furnish an answer\",\n description=\"Answer can only have letters of the alphabet and is case-insensitive\",\n min_length=3,\n max_length=99,\n regex=\"^[a-zA-Z]+$\"\n ), short: bool = Query(\n False,\n title=\"Set flag for short result\",\n description=\"Acceptable values are 1, True, true, on, yes\"\n )):\n \"\"\"\n Returns the quiz question or the result.\n Accepts item ID as path parameter and\n optionally response as query parameter.\n Returns result when the response is passed with the item ID. \n Otherwise, returns the quiz question.\n \"\"\"\n item = question_bank.get(item_ID, None)\n if not item:\n return {\"question\": None}\n if response:\n return evaluate_response(item_ID, response, short)\n else:\n return {\"question\": item[\"question\"]}\n```\n\nGrateful for any help.\n\n========================================\n\nCode:\n```text\nhttp://127.0.0.1:8000/items/2?short=false&response=this&response=that\n```\n\n```text\n@app.get(\"/items/{item_ID}\")\nasync def getQuestion_byID(item_ID: int = Path(\n ...,\n title = \"Numeric ID of the question\",\n description = \"Specify a number between 1 and 999\",\n ge = 1,\n le = 999\n ), response: Optional[List[str]] = Query(\n [],\n title=\"Furnish an answer\",\n description=\"Answer can only have letters of the alphabet and is case-insensitive\",\n min_length=3,\n max_length=99,\n regex=\"^[a-zA-Z]+$\"\n ), short: bool = Query(\n False,\n title=\"Set flag for short result\",\n description=\"Acceptable values are 1, True, true, on, yes\"\n )):\n \"\"\"\n Returns the quiz question or the result.\n Accepts item ID as path parameter and\n optionally response as query parameter.\n Returns result when the response is passed with the item ID. \n Otherwise, returns the quiz question.\n \"\"\"\n item = question_bank.get(item_ID, None)\n if not item:\n return {\"question\": None}\n if response:\n return evaluate_response(item_ID, response, short)\n else:\n return {\"question\": item[\"question\"]}\n```\n\n```json\n{\n \"description\": \"Answer can only have letters of the alphabet and is case-insensitive\",\n \"required\": false,\n \"schema\": {\n \"title\": \"Furnish an answer\",\n \"maxLength\": 99,\n \"minLength\": 3,\n \"pattern\": \"^[a-zA-Z]+$\",\n \"type\": \"array\",\n \"items\": {\n \"maxLength\": 99,\n \"minLength\": 3,\n \"pattern\": \"^[a-zA-Z]+$\",\n \"type\": \"string\"\n },\n \"description\": \"Answer can only have letters of the alphabet and is case-insensitive\",\n \"default\": []\n },\n \"name\": \"response\",\n \"in\": \"query\"\n }\n```\n\n```python\nmy_constr = constr(regex=\"^[a-zA-Z]+$\", min_length=3, max_length=99)\nresponse: Optional[List[my_constr]] = Query([], title=\"Furnish an...\", description=\"Answer can...\")\n```\n\n```json\n...\n {\n \"description\": \"Answer can only have letters of the alphabet and is case-insensitive\",\n \"required\": false,\n \"schema\": {\n \"title\": \"Furnish an answer\",\n \"type\": \"array\",\n \"items\": {\n \"maxLength\": 99,\n \"minLength\": 3,\n \"pattern\": \"^[a-zA-Z]+$\",\n \"type\": \"string\"\n },\n \"description\": \"Answer can only have letters of the alphabet and is case-insensitive\",\n \"default\": []\n },\n \"name\": \"response\",\n \"in\": \"query\"\n },\n ...\n```\n\n```python\nimport json\napp.openapi_schema = json.load(open(\"my_openapi.json\"))\n```\n\n```python\nfrom fastapi.openapi.utils import get_openapi\n\ndef custom_openapi():\n if app.openapi_schema:\n return app.openapi_schema\n openapi_schema = get_openapi(\n title=\"FastAPI\",\n version=\"0.1.0\",\n description=\"This is a very custom OpenAPI schema\",\n routes=app.routes,\n )\n del openapi_schema[\"paths\"][\"/items/{item_ID}\"][\"get\"][\"parameters\"][1][\"schema\"][\"maxLength\"]\n del openapi_schema[\"paths\"][\"/items/{item_ID}\"][\"get\"][\"parameters\"][1][\"schema\"][\"minLength\"]\n del openapi_schema[\"paths\"][\"/items/{item_ID}\"][\"get\"][\"parameters\"][1][\"schema\"][\"pattern\"]\n \n app.openapi_schema = openapi_schema\n return app.openapi_schema\n \n \napp.openapi = custom_openapi\n```\n\n```text\npattern\n```\n\n```text\nminimum\n```\n\n```text\nmaximum\n```\n\n```text\narray\n```\n\n```text\nitems\n```\n\n```text\nresponse\n```\n\n```text\narray\n```\n\n```text\nconstr\n```\n\n```text\nitems\n```\n\n```text\nresponse\n```\n\n```text\npattern\n```\n\n```text\nminimum\n```\n\n```text\nmaximum\n```\n\n```text\nresponse\n```\n\n```text\narray\n```\n\n```text\nmy_openapi.json\n```\n\n```text\nresponse\n```\n\n```text\n(query) maxLength: 99 minLength: 3 pattern: ^[a-zA-Z]+$\n```\n\n```text\narray\n```\n\n```text\nitems\n```\n\n```text\n\"in\"\n```\n\n```text\nJSON\n```\n\n```text\nHTML\n```\n\n```text\nitems\n```\n\n```text\ndescription\n```\n\n```text\nQuery\n```\n\n========================================\n\nComments:\n- 1) If you hover over the \"Add string item\" button when it's red, what does the tooltip say? 2) Can you export the OpenAPI definition from Swagger UI and post the portion with the `response` parameter? I suspect that the FastAPI code annotations are slightly incorrect.\n- Possibly related: github.com/tiangolo/fastapi/issues/4345. See also github.com/tiangolo/fastapi/issues/1021#issuecomment-5903531‌​81\n- @Helen hello! When I hover over the button, the tooltip says \"Value must pattern..\". But the pattern-matching works as expected when I invoke the endpoint through browser.","metadata":{"transformedAt":"2026-08-18T18:32:29.138Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":33,"totalLines":292,"estimatedTokens":1720}}498{"id":"stack-64401878","source":"stackoverflow","questionId":64401878,"title":"How to extend FastAPI docs with another swagger docs?","tags":["python","swagger","openapi","fastapi","drf-yasg"],"text":"Title: How to extend FastAPI docs with another swagger docs?\nTags: python, swagger, openapi, fastapi, drf-yasg\nSource: Stack Overflow\n\nQuestion:\nI decided to make a micro-services gateway in Python's FastApi framework. My authorization service is written in Django and there are already generated by `drf-yasg` package swagger docs. I was thinking if there is a way to somehow import auth's schema to the gateway. I can serve the schema in `json` format via http and access it from the gateway. The question is how to integrate FastApi's docs with raw swagger schema file.\n\n========================================\n\nCode:\n```text\ndrf-yasg\n```\n\n```text\njson\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.openapi.utils import get_openapi\n\napp = FastAPI()\n\n\n@app.get(\"/items/\")\nasync def read_items():\n return [{\"name\": \"Foo\"}]\n\n\ndef custom_openapi():\n if app.openapi_schema:\n return app.openapi_schema\n openapi_schema = get_openapi(\n title=\"Custom title\",\n version=\"2.5.0\",\n description=\"This is a very custom OpenAPI schema\",\n routes=app.routes,\n )\n openapi_schema[\"paths\"][\"/api/auth\"] = {\n \"post\": {\n \"requestBody\": {\"content\": {\"application/json\": {}}, \"required\": True}, \"tags\": [\"Auth\"]\n }\n }\n app.openapi_schema = openapi_schema\n return app.openapi_schema\n\n\napp.openapi = custom_openapi\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.138Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":3,"totalLines":50,"estimatedTokens":347}}499{"id":"stack-78416773","source":"stackoverflow","questionId":78416773,"title":"How do I use python logging with uvicorn/FastAPI?","tags":["python","logging","fastapi","uvicorn"],"text":"Title: How do I use python logging with uvicorn/FastAPI?\nTags: python, logging, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nHere is a small application that reproduces my problem:\n\n```\nimport fastapi\nimport logging\nimport loguru\n\ninstance = fastapi.FastAPI()\n\n@instance.on_event(\"startup\")\nasync def startup_event():\n logger = logging.getLogger(\"mylogger\")\n logger.info(\"I expect this to log\")\n loguru.logger.info(\"but only this logs\")\n```\n\nWhen I launch this application with `uvicorn app.main:instance --log-level=debug` I see this in my terminal:\n\n```\nINFO: Waiting for application startup.\n2024-05-02 13:14:45.118 | INFO | app.main:startup_event:28 - but only this logs\nINFO: Application startup complete.\n```\n\nWhy does only the `loguru` logline work, and how can I make standard python logging work as expected?\n\n========================================\n\nTop Answer:\nTry this: `uvicorn app.main:instance --no-access-log`\n\nThe reasoning is that Uvicorn configures the built-in logging module by default. Passing this flag while starting your application will turn off Uvicorn's access log and allow you to configure custom logging. Source: Settings - Uvicorn\n\n========================================\n\nCode:\n```text\nimport fastapi\nimport logging\nimport loguru\n\ninstance = fastapi.FastAPI()\n\n@instance.on_event(\"startup\")\nasync def startup_event():\n logger = logging.getLogger(\"mylogger\")\n logger.info(\"I expect this to log\")\n loguru.logger.info(\"but only this logs\")\n```\n\n```text\nINFO: Waiting for application startup.\n2024-05-02 13:14:45.118 | INFO | app.main:startup_event:28 - but only this logs\nINFO: Application startup complete.\n```\n\n```text\nuvicorn app.main:instance --log-level=debug\n```\n\n```text\nloguru\n```\n\n```text\nlogging.basicConfig(level=logging.DEBUG,\n format=\"%(asctime)s | %(levelname)-8s | \"\n \"%(module)s:%(funcName)s:%(lineno)d - %(message)s\")\n```\n\n```text\n$ uvicorn main:instance --log-level=debug\nINFO: Started server process [1311]\nINFO: Waiting for application startup.\n2024-05-02 16:44:55,736 | INFO | main:startup_event:12 - I expect this to log\n2024-05-02 16:44:55.736 | INFO | main:startup_event:13 - but only this logs\nINFO: Application startup complete.\nINFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\n```\n\n```text\n--log-level=debug\n```\n\n```text\nmylogger\n```\n\n```text\nWARNING\n```\n\n```text\nmylogger\n```\n\n```text\nuvicorn app.main:instance --no-access-log\n```\n\n========================================\n\nComments:\n- Does this answer your question?","metadata":{"transformedAt":"2026-08-18T18:32:29.138Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":11,"totalLines":109,"estimatedTokens":649}}500{"id":"stack-77394812","source":"stackoverflow","questionId":77394812,"title":"Awaiting request.json() in FastAPI hangs forever","tags":["python","fastapi","freeze","starlette","exceptionhandler"],"text":"Title: Awaiting request.json() in FastAPI hangs forever\nTags: python, fastapi, freeze, starlette, exceptionhandler\nSource: Stack Overflow\n\nQuestion:\nI added the exception handling as given here (https://github.com/tiangolo/fastapi/discussions/6678) to my code but I want to print the complete request body to see the complete content. However, when I await the `request.json()` it never terminates. `request.json()` returns a coroutine, so I need to wait for the coroutine to complete before printing the result.\nHow can I print the content of the request in case an invalid request was sent to the endpoint?\n\nCode example from github with 2 changes by me in the error handler and a simple endpoint.\n\n```\nimport logging\nfrom fastapi import FastAPI, Request, status\nfrom fastapi.exceptions import RequestValidationError\nfrom fastapi.responses import JSONResponse\nfrom pydantic import BaseModel\n\napp = FastAPI()\n\n@app.exception_handler(RequestValidationError)\nasync def validation_exception_handler(\n request: Request, exc: RequestValidationError\n) -> JSONResponse:\n exc_str = f\"{exc}\".replace(\"\\n\", \" \").replace(\" \", \" \")\n logging.error(f\"{request}: {exc_str}\")\n body = await request.json() # This line was added by me and never completes\n logging.error(body) # This line was added by me\n content = {\"status_code\": 10422, \"message\": exc_str, \"data\": None}\n return JSONResponse(\n content=content, status_code=status.HTTP_422_UNPROCESSABLE_ENTITY\n )\n\nclass User(BaseModel):\n name: str\n\n@app.post(\"/\")\nasync def test(body: User) -> User:\n return body\n```\n\n========================================\n\nCode:\n```py\nimport logging\nfrom fastapi import FastAPI, Request, status\nfrom fastapi.exceptions import RequestValidationError\nfrom fastapi.responses import JSONResponse\nfrom pydantic import BaseModel\n\napp = FastAPI()\n\n\n@app.exception_handler(RequestValidationError)\nasync def validation_exception_handler(\n request: Request, exc: RequestValidationError\n) -> JSONResponse:\n exc_str = f\"{exc}\".replace(\"\\n\", \" \").replace(\" \", \" \")\n logging.error(f\"{request}: {exc_str}\")\n body = await request.json() # This line was added by me and never completes\n logging.error(body) # This line was added by me\n content = {\"status_code\": 10422, \"message\": exc_str, \"data\": None}\n return JSONResponse(\n content=content, status_code=status.HTTP_422_UNPROCESSABLE_ENTITY\n )\n\n\nclass User(BaseModel):\n name: str\n\n\n@app.post(\"/\")\nasync def test(body: User) -> User:\n return body\n```\n\n```text\nrequest.json()\n```\n\n```text\nrequest.json()\n```\n\n```py\nfrom fastapi.exceptions import RequestValidationError\n\n@app.exception_handler(RequestValidationError)\nasync def validation_exception_handler(request: Request, exc: RequestValidationError):\n return JSONResponse(\n status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,\n content=jsonable_encoder({\"detail\": exc.errors(), # optionally include the errors\n \"body\": exc.body,\n \"custom msg\": {\"Your error message\"}}),\n )\n```\n\n```text\nawait\n```\n\n```text\nrequest.json\n```\n\n```text\nrequest\n```\n\n```text\nresponse\n```\n\n```text\nawait request.json()\n```\n\n```text\nrequest\n```\n\n```text\nresponse\n```\n\n```text\nRequestValidationError\n```\n\n```text\nrequest\n```\n\n```text\nresponse\n```\n\n```text\nexc.body\n```\n\n```text\nrequest.json()\n```\n\n========================================\n\nComments:\n- You might find the following answers helpful: this, as well as this and this\n- Thanks, using `exc.body` instead of `request.json()` seems to work. However, I still don't understand why `await request.json()` never terminates.","metadata":{"transformedAt":"2026-08-18T18:32:29.138Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":16,"totalLines":150,"estimatedTokens":900}}501{"id":"stack-76268348","source":"stackoverflow","questionId":76268348,"title":"How to update/modify request headers and query parameters in a FastAPI middleware?","tags":["python","header","fastapi","query-string","starlette"],"text":"Title: How to update/modify request headers and query parameters in a FastAPI middleware?\nTags: python, header, fastapi, query-string, starlette\nSource: Stack Overflow\n\nQuestion:\nI'm trying to write a middleware for a FastAPI project that manipulates the request `headers` and / or `query` parameters in some special cases.\n\nI've managed to capture and modify the request object in the middleware, but it seems that even if I modify the request object that is passed to the middleware, the function that serves the endpoint receives the original, unmodified request.\n\nHere is a simplified version of my implementation:\n\n```\nfrom fastapi import FastAPI, Request\nfrom starlette.datastructures import MutableHeaders, QueryParams\nfrom starlette.middleware.base import BaseHTTPMiddleware\n\nclass TestMiddleware(BaseHTTPMiddleware):\n\n def __init__(self, app: FastAPI):\n super().__init__(app)\n\n \n def get_modified_query_params(request: Request) -> QueryParams:\n\n pass ## Create and return new query params\n\n async def dispatch(\n self, request: Request, call_next, *args, **kwargs\n ) -> None:\n \n # Check and manipulate the X-DEVICE-TOKEN if required\n header_key = \"X-DEVICE-INFo\"\n new_header_value = \"new device info\"\n\n new_header = MutableHeaders(request._headers)\n new_header[header_key] = new_header_value\n\n request._headers = new_header\n\n request._query_params = self.get_modified_query_params(request)\n\n print(\"modified headers =>\", request.headers)\n print(\"modified params =>\", request.query_params)\n\n return await call_next(request)\n```\n\nEven though I see the updated values in the print statements above, when I try to print request object in the function that serves the endpoint, I see original values of the request.\n\nWhat am I missing?\n\n========================================\n\nCode:\n```python\nfrom fastapi import FastAPI, Request\nfrom starlette.datastructures import MutableHeaders, QueryParams\nfrom starlette.middleware.base import BaseHTTPMiddleware\n\n\nclass TestMiddleware(BaseHTTPMiddleware):\n\n\n def __init__(self, app: FastAPI):\n super().__init__(app)\n\n \n def get_modified_query_params(request: Request) -> QueryParams:\n\n pass ## Create and return new query params\n\n\n async def dispatch(\n self, request: Request, call_next, *args, **kwargs\n ) -> None:\n \n # Check and manipulate the X-DEVICE-TOKEN if required\n header_key = \"X-DEVICE-INFo\"\n new_header_value = \"new device info\"\n\n new_header = MutableHeaders(request._headers)\n new_header[header_key] = new_header_value\n\n request._headers = new_header\n\n request._query_params = self.get_modified_query_params(request)\n\n print(\"modified headers =>\", request.headers)\n print(\"modified params =>\", request.query_params)\n\n return await call_next(request)\n```\n\n```text\nheaders\n```\n\n```text\nquery\n```\n\n```py\nfrom fastapi import FastAPI, Request\nfrom urllib.parse import urlencode\n\napp = FastAPI()\n\n@app.middleware('http')\nasync def some_middleware(request: Request, call_next):\n # update request headers\n headers = dict(request.scope['headers'])\n headers[b'custom-header'] = b'my custom header'\n request.scope['headers'] = [(k, v) for k, v in headers.items()]\n \n # update request query parameters\n q_params = dict(request.query_params)\n q_params['custom-q-param'] = 'my custom query param'\n request.scope['query_string'] = urlencode(q_params).encode('utf-8')\n \n return await call_next(request)\n\n\n@app.get('/')\nasync def main(request: Request):\n return {'headers': request.headers, 'q_params': request.query_params}\n```\n\n```text\nrequest.scope['headers']\n```\n\n```text\nrequest.scope['query_string']\n```\n\n========================================\n\nComments:\n- Is there any official documentation that addresses this by the way?\n- There is not, as far as I know. However, part of the solution has previously been described by a maintainer of Starlette (the relevant github link is given in the linked answer above).\n- Make sure to use lower-case names for your headers with this method. The starlette `Headers` class is case-insensitive and implements that by converting all keys to lower-case in the constructor. The example above bypasses the constructor, so care must be taken. For example, `headers[b'Custom-Header'] = b'my custom header'` will behave as though nothing was changed.","metadata":{"transformedAt":"2026-08-18T18:32:29.138Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":6,"totalLines":141,"estimatedTokens":1097}}502{"id":"stack-60307004","source":"stackoverflow","questionId":60307004,"title":"Unable to Access Local Host From Docker Container","tags":["python","docker","fastapi","uvicorn"],"text":"Title: Unable to Access Local Host From Docker Container\nTags: python, docker, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\n### Problem\n\nI have two Docker containers:\n\n- a server ran with `fastapi;uvicorn`\n\n- a client sending a `GET` request to `http://0.0.0.0`\n\nThe server seems to work just fine as bashing `curl -X GET http://0.0.0.0` works as expected. However, my docker client seems unable to get access.\n\nAfter building the client container (files below), when running `docker run -it --name app_client_container app_client:latest` I receive the following error:\n\n requests.exceptions.ConnectionError: HTTPConnectionPool(host='0.0.0.0', port=80): Max retries exceeded with url: / (Caused by NewConnectionError(': Failed to establish a new connection: Errno 111 Connection refused'))\n\n### Setup\n\nMy project looks like this\n\n```\n|- client.Dockerfile\n|- client.py\n|- client_req.txt\n|- server.Dockerfile\n|- server.py\n|- server_req.txt\n```\n\n**Client**\n\n```\n# client.Dockerfile\nFROM python:3.8\n\nWORKDIR /srv\nWORKDIR /srv\nADD client_req.txt /srv/client_req.txt\nRUN pip install -r client_req.txt\n\nADD . /srv\nCMD python /srv/client.py\n\n# client.py\nimport json\nimport requests\nimport traceback\n\ntry:\n response = requests.get('http://0.0.0.0', timeout=5)\n print(json.dumps(response.json(), indent=4))\nexcept Exception as e:\n print('Connection could not be established :(')\n print('Here is more information:')\n traceback.print_exc()\n\n# client_req.txt\nrequests\n```\n\n**Server**\n\n```\n# server.Dockerfile\nFROM python:3.8\n\nWORKDIR /srv\nADD server_req.txt /srv/server_req.txt\nRUN pip install -r server_req.txt\n\nEXPOSE 80\n\nADD . /srv\nCMD uvicorn server:app --host 0.0.0.0 --port 80 --reload\n\n# server.py\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/\")\ndef read_root():\n return {\"Hello\": \"World\"}\n\n# server_req.txt\nfastapi\nuvicorn\n```\n\n========================================\n\nTop Answer:\nYou can also use default docker bridge network.\n\nSet the IP address to: **172.17.0.1** (for mac it is docker.for.mac.host.internal)\n\nThis should work:\n\n```\nresponse = requests.get('http://172.17.0.1', timeout=5)\n```\n\n========================================\n\nCode:\n```none\n|- client.Dockerfile\n|- client.py\n|- client_req.txt\n|- server.Dockerfile\n|- server.py\n|- server_req.txt\n```\n\n```py\n# client.Dockerfile\nFROM python:3.8\n\nWORKDIR /srv\nWORKDIR /srv\nADD client_req.txt /srv/client_req.txt\nRUN pip install -r client_req.txt\n\nADD . /srv\nCMD python /srv/client.py\n\n# client.py\nimport json\nimport requests\nimport traceback\n\ntry:\n response = requests.get('http://0.0.0.0', timeout=5)\n print(json.dumps(response.json(), indent=4))\nexcept Exception as e:\n print('Connection could not be established :(')\n print('Here is more information:')\n traceback.print_exc()\n\n# client_req.txt\nrequests\n```\n\n```py\n# server.Dockerfile\nFROM python:3.8\n\nWORKDIR /srv\nADD server_req.txt /srv/server_req.txt\nRUN pip install -r server_req.txt\n\nEXPOSE 80\n\nADD . /srv\nCMD uvicorn server:app --host 0.0.0.0 --port 80 --reload\n\n# server.py\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n\n@app.get(\"/\")\ndef read_root():\n return {\"Hello\": \"World\"}\n\n# server_req.txt\nfastapi\nuvicorn\n```\n\n```text\nfastapi;uvicorn\n```\n\n```text\nGET\n```\n\n```text\nhttp://0.0.0.0\n```\n\n```text\ncurl -X GET http://0.0.0.0\n```\n\n```text\ndocker run -it --name app_client_container app_client:latest\n```\n\n```text\ndocker run ... --net=host ...\n```\n\n```text\n:80\n```\n\n```text\n:80\n```\n\n```text\nresponse = requests.get('http://172.17.0.1', timeout=5)\n```\n\n========================================\n\nComments:\n- Any time you have multiple containers that need to communicate I *strongly* recommend using Docker Compose, or a similar tool. It makes inter-container communication much simpler.\n- @Chris I'll look into it\n- 0.0.0.0 is a special IPv4 address that means “everywhere”; it usually only makes sense to tell servers what interfaces to listen on, not as a target for outbound HTTP requests. When your client makes that call, where do you expect it to go?\n- @DavidMaze I was just following this tutorial and my idea was to switch to `127.0.0.1` once I got it up and running.\n- Thanks, the `--net=host` flag solved it. I'll still look into the alternatives though.\n- I works but I don't understand why I cant use say `requests.get('http://localhost:4001/auth')`\n- Let's have two running containers c1 and c2. If you are inside c1 then calling GET HTTP://localhost:4001 is pointing to itself, i.e. container c1. The c1 can communicate with an external world (your system and c2) only using a bridge network.","metadata":{"transformedAt":"2026-08-18T18:32:29.139Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":12,"totalLines":220,"estimatedTokens":1142}}503{"id":"stack-76055891","source":"stackoverflow","questionId":76055891,"title":"fastAPI background task takes up to 100 times longer to execute than calling function directly","tags":["python","performance","google-cloud-platform","fastapi"],"text":"Title: fastAPI background task takes up to 100 times longer to execute than calling function directly\nTags: python, performance, google-cloud-platform, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have simple fastAPI endpoint deployed on Google Cloud Run. I wrote the `Workflow` class myself. When the `Workflow` instance is executed, some steps happen, e.g., the files are processed and the result are put in a vectorstore database.\n\nUsually, this takes a few seconds per file like this:\n\n```\nfrom .workflow import Workflow\n...\n\n@app.post('/execute_workflow_directly')\nasync def execute_workflow_directly(request: Request)\n ... # get files from request object\n workflow = Workflow.get_simple_workflow(files=files)\n workflow.execute()\n return JSONResponse(status_code=200, content={'message': 'Successfully processed files'})\n```\n\nNow, if many files are involved, this might take a while, and I don't want to let the caller of the endpoint wait, so I want to run the workflow execution in the background like this:\n\n```\nfrom .workflow import Workflow\nfrom fastapi import BackgroundTasks\n...\n\ndef run_workflow_in_background(workflow: Workflow):\n workflow.execute()\n\n@app.post('/execute_workflow_in_background')\nasync def execute_workflow_in_background(request: Request, background_tasks: BackgroundTasks):\n ... # get files from request object\n workflow = Workflow.get_simple_workflow(files=files)\n background_tasks.add_task(run_workflow_in_background, workflow)\n return JSONResponse(status_code=202, content={'message': 'File processing started'})\n```\n\nTesting this with still only one file, I already run into a problem: Locally, it works fine, but when I deploy it to my Google Cloud Run service, execution time goes through the roof: In one example, background execution it took almost ~500s until I saw the result in the database, compared to ~5s when executing the workflow directly.\n\nI already tried to increase the number of CPU cores to 4 and subsequently the number of gunicorn workers to 4 as well. Not sure if that makes much sense, but it did not decrease the execution times.\n\n**Can I solve this problem by allocating more resources to Google Cloud run somehow or is my approach flawed and I'm doing something wrong or should already switch to something more sophisticated like Celery?**\n\nEdit (not really relevant to the problem I had, see accepted answer):\n\nI read the accepted answer to this question and it helped clarify some things, but doesn't really answer my question why there is such a big difference in execution time between running directly vs. as a background task. Both versions call the CPU-intensive `workflow.execute()` asynchronously if I'm not mistaken.\n\nI can't really change the endpoint's definition to `def`, because I am awaiting other code inside.\n\nI tried changing the background function to\n\n```\nasync def run_workflow_in_background(workflow: Workflow):\n await run_in_threadpool(workflow.execute)\n```\n\nand\n\n```\nasync def run_workflow_in_background(workflow: Workflow):\n loop = asyncio.get_running_loop()\n with concurrent.futures.ThreadPoolExecutor() as pool:\n res = await loop.run_in_executor(pool, workflow.execute)\n```\n\nand\n\n```\nasync def run_workflow_in_background(workflow: Workflow):\n res = await asyncio.to_thread(workflow.execute)\n```\n\nand\n\n```\nasync def run_workflow_in_background(workflow: Workflow):\n loop = asyncio.get_running_loop()\n with concurrent.futures.ProcessPoolExecutor() as pool:\n res = await loop.run_in_executor(pool, workflow.execute)\n```\n\nas suggested and it didn't help.\n\nI tried increasing the number of workers as suggested and it didn't help.\n\nI guess I will look into switching to Celery, but still eager to understand why it works so slowly with fastAPI background tasks.\n\n========================================\n\nCode:\n```text\nfrom .workflow import Workflow\n...\n\n@app.post('/execute_workflow_directly')\nasync def execute_workflow_directly(request: Request)\n ... # get files from request object\n workflow = Workflow.get_simple_workflow(files=files)\n workflow.execute()\n return JSONResponse(status_code=200, content={'message': 'Successfully processed files'})\n```\n\n```text\nfrom .workflow import Workflow\nfrom fastapi import BackgroundTasks\n...\n\ndef run_workflow_in_background(workflow: Workflow):\n workflow.execute()\n\n@app.post('/execute_workflow_in_background')\nasync def execute_workflow_in_background(request: Request, background_tasks: BackgroundTasks):\n ... # get files from request object\n workflow = Workflow.get_simple_workflow(files=files)\n background_tasks.add_task(run_workflow_in_background, workflow)\n return JSONResponse(status_code=202, content={'message': 'File processing started'})\n```\n\n```text\nasync def run_workflow_in_background(workflow: Workflow):\n await run_in_threadpool(workflow.execute)\n```\n\n```text\nasync def run_workflow_in_background(workflow: Workflow):\n loop = asyncio.get_running_loop()\n with concurrent.futures.ThreadPoolExecutor() as pool:\n res = await loop.run_in_executor(pool, workflow.execute)\n```\n\n```text\nasync def run_workflow_in_background(workflow: Workflow):\n res = await asyncio.to_thread(workflow.execute)\n```\n\n```text\nasync def run_workflow_in_background(workflow: Workflow):\n loop = asyncio.get_running_loop()\n with concurrent.futures.ProcessPoolExecutor() as pool:\n res = await loop.run_in_executor(pool, workflow.execute)\n```\n\n```text\nWorkflow\n```\n\n```text\nWorkflow\n```\n\n```text\nworkflow.execute()\n```\n\n```text\ndef\n```\n\n========================================\n\nComments:\n- Does this answer your question? FastAPI runs api-calls in serial instead of parallel fashion\n- @Chris: Not really, see my edits. Might still be my lack of full understanding.\n- What do your Cloud Run settings look like? As described in this answer, unless you set the min instance to at least 1 and the CPU always on to true, Cloud Run will throttle your CPU access as soon as the HTTP request is over, which sounds exactly like what you're describing.\n- Thank you, this was the exactly the problem. Good explanation, makes a lot of sense. Of course less than ideal from a cost perspective when these background tasks are run only a few times a day. Is there any way to make sure background tasks have enough resources, without always allocating them?","metadata":{"transformedAt":"2026-08-18T18:32:29.139Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":10,"totalLines":167,"estimatedTokens":1578}}504{"id":"stack-77938134","source":"stackoverflow","questionId":77938134,"title":"Pydantic: How to validate json string that has an inner json string?","tags":["python-3.x","fastapi","pydantic","starlette","pydantic-v2"],"text":"Title: Pydantic: How to validate json string that has an inner json string?\nTags: python-3.x, fastapi, pydantic, starlette, pydantic-v2\nSource: Stack Overflow\n\nQuestion:\nI have the following string that my API is receiving:\n\n```\n'{\"data\": 123, \"inner_data\": \"{\\\\\"color\\\\\": \\\\\"RED\\\\\"}\"}'\n```\n\nMy goal is to build a `pydantic` model that can validate the outer and inner data fields.\nSo I built the following models:\n\n```\nfrom pydantic import BaseModel\n\nclass InnerData(BaseModel):\n color: str\n\nclass Expected(BaseModel):\n data: int\n inner_data: InnerData\n```\n\nBut when I run the following:\n\n```\nincoming_json_string = '{\"data\": 123, \"inner_data\": \"{\\\\\"color\\\\\": \\\\\"RED\\\\\"}\"}'\nexpected = Expected.model_validate_json(incoming_json_string)\n```\n\nI get:\n\n```\nTraceback (most recent call last):\n File \".../site-packages/pydantic/main.py\", line 532, in model_validate_json\n return cls.__pydantic_validator__.validate_json(json_data, strict=strict, context=context)\npydantic_core._pydantic_core.ValidationError: 1 validation error for Expected\ninner_data\n Input should be an object [type=model_type, input_value='{\"color\": \"RED\"}', input_type=str]\n For further information visit https://errors.pydantic.dev/2.5/v/model_type\n```\n\nThe link in the traceback doesn't help because it tells me the data is a string but should be a model. But that's what I'm trying to conjure up when I do `inner_data: InnerData`. What should I try?\n\n========================================\n\nCode:\n```text\n'{\"data\": 123, \"inner_data\": \"{\\\\\"color\\\\\": \\\\\"RED\\\\\"}\"}'\n```\n\n```text\nfrom pydantic import BaseModel\n\nclass InnerData(BaseModel):\n color: str\n\nclass Expected(BaseModel):\n data: int\n inner_data: InnerData\n```\n\n```text\nincoming_json_string = '{\"data\": 123, \"inner_data\": \"{\\\\\"color\\\\\": \\\\\"RED\\\\\"}\"}'\nexpected = Expected.model_validate_json(incoming_json_string)\n```\n\n```text\nTraceback (most recent call last):\n File \".../site-packages/pydantic/main.py\", line 532, in model_validate_json\n return cls.__pydantic_validator__.validate_json(json_data, strict=strict, context=context)\npydantic_core._pydantic_core.ValidationError: 1 validation error for Expected\ninner_data\n Input should be an object [type=model_type, input_value='{\"color\": \"RED\"}', input_type=str]\n For further information visit https://errors.pydantic.dev/2.5/v/model_type\n```\n\n```text\npydantic\n```\n\n```text\ninner_data: InnerData\n```\n\n```text\n{\n \"data\": 123,\n \"inner_data\": {\n \"color\": \"RED\"\n }\n}\n```\n\n```text\n>>> incoming_json_string = '{\"data\": 123, \"inner_data\": {\"color\": \"RED\"}}'\n>>> expected = Expected.model_validate_json(incoming_json_string)\n>>> expected\nExpected(data=123, inner_data=InnerData(color='RED'))\n```\n\n```text\nfrom pydantic import BaseModel, BeforeValidator\nfrom typing import Annotated\n\nclass InnerData(BaseModel):\n color: str\n\nclass Expected(BaseModel):\n data: int\n inner_data: Annotated[InnerData, BeforeValidator(InnerData.model_validate_json)]\n\nincoming_json_string = '{\"data\": 123, \"inner_data\": \"{\\\\\"color\\\\\": \\\\\"RED\\\\\"}\"}'\nexpected = Expected.model_validate_json(incoming_json_string)\n```\n\n```text\n{\n \"data\": 123,\n \"inner_data\": \"{\\\"color\\\": \\\"RED\\\"}\"\n}\n```\n\n```text\n>>> incoming_json_string = '{\"data\": 123, \"inner_data\": \"{\\\\\"color\\\\\": \\\\\"RED\\\\\"}\"}'\n>>> expected = Expected.model_validate_json(incoming_json_string)\n>>> expected\nExpected(data=123, inner_data=InnerData(color='RED'))\n```\n\n```text\nExpected\n```\n\n```text\nInnerData\n```\n\n```text\ninner_data\n```\n\n```text\nBeforeValidator\n```\n\n```text\nInnerData\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.139Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":16,"totalLines":151,"estimatedTokens":878}}505{"id":"stack-75610130","source":"stackoverflow","questionId":75610130,"title":"Relationship fields not showing up in FastAPI response","tags":["fastapi"],"text":"Title: Relationship fields not showing up in FastAPI response\nTags: fastapi\nSource: Stack Overflow\n\nQuestion:\nI have the following schema:\n\n```\nclass UserBase(SQLModel):\n username: str\n\nclass User(UserBase, table=True):\n id: int | None = Field(primary_key=True)\n channels: list['Channel'] = Relationship(back_populates='participants', sa_relationship_kwargs={'lazy': 'subquery'})\n\nclass UserOutput(UserBase):\n id: int\n channels: list['Channel']\n```\n\nI have an endpoint to read all users in the system.\n\n```\n@router.get('/user', response_model=??)\ndef read_users(...):\n return all_users(...)\n```\n\nNow, if `response_model = User`, there will be no `channels` field in the response, however, when `response_model = UserOutput`, `channels` will be set and contain the right data. Why is that?\n\n========================================\n\nTop Answer:\nTo solve this, I created a dto and typed the return of my route:\n\n```\nfrom pydantic import BaseModel\nfrom sqlmodel import Field, Relationship, SQLModel\n\nclass PillowBase(SQLModel):\n color: str\n\nclass Pillow(PillowBase, table=True):\n __tablename__ = \"pillow\"\n id: UUID = Field(default_factory=uuid4, primary_key=True)\n cats: list[\"Cat\"] = Relationship(back_populates=\"pillow\")\n\nclass CatBase(SQLModel):\n name: str\n pillow_id: Optional[UUID] = Field(foreign_key=\"pillow.id\")\n\nclass Cat(CatBase, table=True):\n __tablename__ = \"cat\"\n id: UUID = Field(default_factory=uuid4, primary_key=True)\n pillow: Pillow | None = Relationship(back_populates=\"cats\")\n\n# That one\nclass CatsWithPillowDto(BaseModel):\n id: UUID\n name: str\n pillow_id: UUID | None\n pillow: Pillow\n\n@router.get(\"/\")\ndef get_many(\n service: Annotated[CatService, Depends(get_cat_service)],\n) -> Sequence[CatsWithPillowDto]: # important\n catsWithPillow = service.get_many()\n return catsWithPillow # noqa\n```\n\n========================================\n\nCode:\n```text\nclass UserBase(SQLModel):\n username: str\n\nclass User(UserBase, table=True):\n id: int | None = Field(primary_key=True)\n channels: list['Channel'] = Relationship(back_populates='participants', sa_relationship_kwargs={'lazy': 'subquery'})\n\nclass UserOutput(UserBase):\n id: int\n channels: list['Channel']\n```\n\n```text\n@router.get('/user', response_model=??)\ndef read_users(...):\n return all_users(...)\n```\n\n```text\nresponse_model = User\n```\n\n```text\nchannels\n```\n\n```text\nresponse_model = UserOutput\n```\n\n```text\nchannels\n```\n\n```python\nclass A(BaseModel):\n a: list = Relationship()\n```\n\n```text\n>>> A()\nA(a=RelationshipInfo())\n>>> A.__fields__\n{'a': ModelField(name='a', type=list, required=False, default=RelationshipInfo())}\n```\n\n```python\nclass B(SQLModel):\n a: list = Relationship()\n```\n\n```text\n>>> B()\nB()\n>>> B.__fields__\n{}\n```\n\n```text\nRelationship\n```\n\n```py\nfrom pydantic import BaseModel\nfrom sqlmodel import Field, Relationship, SQLModel\n\nclass PillowBase(SQLModel):\n color: str\n\n\nclass Pillow(PillowBase, table=True):\n __tablename__ = \"pillow\"\n id: UUID = Field(default_factory=uuid4, primary_key=True)\n cats: list[\"Cat\"] = Relationship(back_populates=\"pillow\")\n\n\nclass CatBase(SQLModel):\n name: str\n pillow_id: Optional[UUID] = Field(foreign_key=\"pillow.id\")\n\n\nclass Cat(CatBase, table=True):\n __tablename__ = \"cat\"\n id: UUID = Field(default_factory=uuid4, primary_key=True)\n pillow: Pillow | None = Relationship(back_populates=\"cats\")\n\n\n# That one\nclass CatsWithPillowDto(BaseModel):\n id: UUID\n name: str\n pillow_id: UUID | None\n pillow: Pillow\n\n\n@router.get(\"/\")\ndef get_many(\n service: Annotated[CatService, Depends(get_cat_service)],\n) -> Sequence[CatsWithPillowDto]: # important\n catsWithPillow = service.get_many()\n return catsWithPillow # noqa\n```\n\n========================================\n\nComments:\n- As far as I can tell your schemas are those for ORM, while `response_model=` requires `pydantic` schemas. There are no such concepts as `Relationship` in `pydantic` schemes. You just need to draw up the correct `pydantic` scheme and specify it.\n- The value for the `channels` property will be `list[Channel]` for the instance that is returned from the router function. What does it matter what the value for that field is at the class level? - considering that it's functional with `UserOutput`.\n- The difference is that your classes are inherited from the `SQLModel`, and the `response_model` takes the `Base` class from the `pydantic`\n- What do you mean \"takes\" the `Base` class as pydantic? - \"accepts\"? It's already working with the `SQLModel` instances..\n- I don't know which ORM you use, but it's good practice to separate database models from data validation models\n- Enlightening answer!","metadata":{"transformedAt":"2026-08-18T18:32:29.139Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":12,"totalLines":187,"estimatedTokens":1161}}506{"id":"stack-58486316","source":"stackoverflow","questionId":58486316,"title":"Usage of pydantic with mypy","tags":["python","mypy","fastapi","pydantic"],"text":"Title: Usage of pydantic with mypy\nTags: python, mypy, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI'm trying to write an application using FastAPI which intensively uses pydantic. Also I would like to type-check my code using `mypy`. How can I use type annotations for pydantic and mypy without conflict?\n\nI know about `type: ignore` comments but in my opinion it's some kind of cheating :)\n\nExample:\n\n```\nfrom pydantic import BaseModel, Schema\n\nclass UsersQuery(BaseModel):\n limit: int = Schema(default=100, gt=0, le=100)\n offset: int = Schema(default=0, ge=0)\n```\n\nThis code works correctly but fails type checking.\n\nmypy output:\n\n```\nerror: Incompatible types in assignment (expression has type \"Schema\", variable has type \"int\")\nerror: Incompatible types in assignment (expression has type \"Schema\", variable has type \"int\")\n```\n\n========================================\n\nCode:\n```py\nfrom pydantic import BaseModel, Schema\n\n\nclass UsersQuery(BaseModel):\n limit: int = Schema(default=100, gt=0, le=100)\n offset: int = Schema(default=0, ge=0)\n```\n\n```text\nerror: Incompatible types in assignment (expression has type \"Schema\", variable has type \"int\")\nerror: Incompatible types in assignment (expression has type \"Schema\", variable has type \"int\")\n```\n\n```text\nmypy\n```\n\n```text\ntype: ignore\n```\n\n```text\ntype: ignore\n```\n\n```text\nField\n```\n\n```text\nSchema\n```\n\n```text\nAny\n```\n\n========================================\n\nComments:\n- Thank you @SColvin! Will wait for it to release!\n- SColvin thanks again! Marked the answer as accepted.","metadata":{"transformedAt":"2026-08-18T18:32:29.139Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":8,"totalLines":74,"estimatedTokens":389}}507{"id":"stack-75907394","source":"stackoverflow","questionId":75907394,"title":"What is the difference between Security and Depends in FastAPI?","tags":["python","fastapi"],"text":"Title: What is the difference between Security and Depends in FastAPI?\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nThis is my code:\n\n```\nfrom fastapi import FastAPI, Depends, Security\nfrom fastapi.security import HTTPBearer\n\nbearer = HTTPBearer()\n\n@app.get(\"/\")\nasync def root(q = Security(bearer)):\n return {'q': q}\n\n@app.get(\"/Depends\")\nasync def root(q = Depends(bearer)):\n return {'q': q,}\n```\n\nBoth routes give precisely the same result and act in the same manner. I checked the source code and found that the Security class inherits from the Depedends class. But I have no understanding in what way. Can you please show me the differences and why would I prefer to use Security over Depends.\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI, Depends, Security\nfrom fastapi.security import HTTPBearer\n\nbearer = HTTPBearer()\n\n@app.get(\"/\")\nasync def root(q = Security(bearer)):\n return {'q': q}\n\n@app.get(\"/Depends\")\nasync def root(q = Depends(bearer)):\n return {'q': q,}\n```\n\n```text\nSecurity\n```\n\n```text\nDepends\n```\n\n```text\nSecurity\n```\n\n```text\nDepends\n```\n\n```text\ndependencies\n```\n\n```text\nForm\n```\n\n```text\nBody\n```\n\n```text\nFile\n```\n\n```text\nSecurity\n```\n\n```text\nDepends\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.139Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":11,"totalLines":81,"estimatedTokens":311}}508{"id":"stack-69558683","source":"stackoverflow","questionId":69558683,"title":"Running FastAPI on Google Cloud Run (Docker Image)","tags":["docker","google-cloud-platform","fastapi","google-cloud-run"],"text":"Title: Running FastAPI on Google Cloud Run (Docker Image)\nTags: docker, google-cloud-platform, fastapi, google-cloud-run\nSource: Stack Overflow\n\nQuestion:\nI'm looking to build a Docker image to run FastAPI on Google Cloud Run. FastAPI uses Uvicorn as an ASGI server and Uvicorn recommend using Gunicorn with the Uvicorn worker class for production deployments. FastAPI themselves also have some excellent documentation on using Gunicorn with Uvicorn. I even see that FastAPI provide an official image combining the two (\nuvicorn-gunicorn-fastapi-docker) but this comes with a warning:\n\nYou are probably using Kubernetes or similar tools. In that case, you\nprobably don't need this image (or any other similar base image). You\nare probably better off building a Docker image from scratch\n\nThis warning basically explains that replication would be handled at *cluster-level* and doesn't need to be handled at *process-level*. This makes sense. I am however not quite sure if Cloud Run falls into this category? Essentially it is an abstracted and managed Knative service which therefore runs on Kubernetes.\n\nMy question is, should I be installing Gunicorn along with Uvicorn in my Dockerfile and handling replication at process-level? Along the lines of:\n\n```\nCMD [\"gunicorn\", \"app.main:app\", \"-w\", \"4\", \"-k\", \"uvicorn.workers.UvicornWorker\", \"--bind\", \"0.0.0.0:80\"]\n```\n\nOr should I stick with Uvicorn, a single process, and let Cloud Run (Kubernetes) handle replication at cluster-level? E.g.\n\n```\nCMD [\"uvicorn\", \"app.main:app\", \"--host\", \"0.0.0.0\", \"--port\", \"80\"]\n```\n\n========================================\n\nCode:\n```text\nCMD [\"gunicorn\", \"app.main:app\", \"-w\", \"4\", \"-k\", \"uvicorn.workers.UvicornWorker\", \"--bind\", \"0.0.0.0:80\"]\n```\n\n```text\nCMD [\"uvicorn\", \"app.main:app\", \"--host\", \"0.0.0.0\", \"--port\", \"80\"]\n```\n\n========================================\n\nComments:\n- Thanks for the scale breakdown. Just so I'm clear, on the small scale you recommend starting with my second code snippet: Uvicorn with a single process (no Uvicorn workers and no Gunicorn) in the Dockerfile?\n- Yes, sure, try that out.","metadata":{"transformedAt":"2026-08-18T18:32:29.139Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":2,"totalLines":42,"estimatedTokens":528}}509{"id":"stack-73689278","source":"stackoverflow","questionId":73689278,"title":"How to use SQLModel with more than 1 database?","tags":["python","fastapi","sqlmodel"],"text":"Title: How to use SQLModel with more than 1 database?\nTags: python, fastapi, sqlmodel\nSource: Stack Overflow\n\nQuestion:\nI have a FastAPI project using SQLModel as the orm. I would like to use multiple different databases in the same project. For example I would like one FastAPI endpoint to query 1 database and another FastAPI endpoint to query a completely different database. However I'm struggling to find any documentation on how to go about doing so. I'm assuming it involves a particular setup of the SQLModel classes/engines along with the metadata but I'm unsure. Any direction at all would be appreciated. Thanks.\n\n========================================\n\nCode:\n```py\nengine_a = create_engine(\"sqlite:///a.db\", echo=True)\nengine_b = create_engine(\"sqlite:///b.db\", echo=True)\n```\n\n```py\nSQLModel.metadata.create_all(engine_a)\nSQLModel.metadata.create_all(engine_b)\n```\n\n```py\nA.__table__.create(engine_a)\n```\n\n```py\nwith Session(engine_a) as session:\n ...\n```\n\n```py\nfrom typing import Optional\n\nfrom sqlmodel import Field, Session, SQLModel, create_engine\n\n\nclass A(SQLModel, table=True):\n id: Optional[int] = Field(primary_key=True)\n foo: str\n\n\nclass B(SQLModel, table=True):\n id: Optional[int] = Field(primary_key=True)\n bar: str\n\n\nif __name__ == '__main__':\n engine_a = create_engine(\"sqlite:///a.db\", echo=True)\n engine_b = create_engine(\"sqlite:///b.db\", echo=True)\n\n A.__table__.create(engine_a)\n B.__table__.create(engine_b)\n\n with Session(engine_a) as session:\n session.add(A(foo=\"abc\"))\n session.commit()\n\n with Session(engine_b) as session:\n session.add(B(bar=\"xyz\"))\n session.commit()\n```\n\n```text\nSession\n```\n\n```text\nEngine\n```\n\n```text\ncreate_engine\n```\n\n```text\ncreate_all\n```\n\n```text\nCREATE TABLE\n```\n\n```text\nA\n```\n\n```text\nengine_a\n```\n\n```text\na.db\n```\n\n```text\nb.db\n```\n\n```text\nsqlitebrowser\n```\n\n```text\nA\n```\n\n```text\na.db\n```\n\n```text\nB\n```\n\n```text\nb.db\n```\n\n========================================\n\nComments:\n- Thanks a lot. This really helps. I'm just getting started with this whole SQLModel/FastAPI ecosystem. I know alembic is for helping with migrations, but could you expand a bit on how that might help this particular case of wanting to have one fastapi project where I have different endpoints hitting different DBs depending on what they are doing? Thanks.","metadata":{"transformedAt":"2026-08-18T18:32:29.139Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":19,"totalLines":121,"estimatedTokens":592}}510{"id":"stack-73410132","source":"stackoverflow","questionId":73410132,"title":"How to download a file using ReactJS with Axios in the frontend and FastAPI in the backend?","tags":["javascript","reactjs","axios","fastapi"],"text":"Title: How to download a file using ReactJS with Axios in the frontend and FastAPI in the backend?\nTags: javascript, reactjs, axios, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to create a `docx` file and send it to the frontend client app, so that it can be downloaded to the user's local machine. I am using FastAPI for the backend. I am using `python-docx` library also to create the `Document`.\n\nThe code below is used to create a `docx` file and save it to the server.\n\n```\n@app.post(\"/create_file\")\nasync def create_file(data: Item):\n document = Document()\n document.add_heading(\"file generated\", level=1)\n document.add_paragraph(\"test\")\n document.save('generated_file.docx')\n return {\"status\":\"Done!\"}\n```\n\nThe below code is then used to send the created `docx` file as a `FileResponse` to the client.\n\n```\n@app.get(\"/generated_file\")\nasync def download_generated_file():\n file_path = \"generated_file.docx\"\n return FileResponse(file_path, media_type='application/vnd.openxmlformats-officedocument.wordprocessingml.document', filename=file_path)\n```\n\nOn Client side (I am using ReactJS):\n\n```\ncreateFile = async () => {\n const data = {\n start: this.state.start,\n end: this.state.end,\n text: this.state.text,\n };\n await axios.post(\"http://localhost:8000/create_file\", data).then(() => {\n console.log(\"processing completed!\");\n });\n};\n\ndownloadFile = async () => {\n await axios.get(\"http://localhost:8000/generated_file\").then((res) => {\n const url = URL.createObjectURL(new Blob([res.data]));\n const link = document.createElement(\"a\");\n link.href = url;\n link.setAttribute(\"download\", \"generated.txt\");\n link.click();\n });\n};\n```\n\nThe `generated.docx` file gets downloaded when `downloadFile` function is called. However, the `docx` file is always **corrupted** and doesn't open. I tried using txt file and it works fine. I need to use **docx** file, so what can I do?\n\n========================================\n\nCode:\n```text\n@app.post(\"/create_file\")\nasync def create_file(data: Item):\n document = Document()\n document.add_heading(\"file generated\", level=1)\n document.add_paragraph(\"test\")\n document.save('generated_file.docx')\n return {\"status\":\"Done!\"}\n```\n\n```text\n@app.get(\"/generated_file\")\nasync def download_generated_file():\n file_path = \"generated_file.docx\"\n return FileResponse(file_path, media_type='application/vnd.openxmlformats-officedocument.wordprocessingml.document', filename=file_path)\n```\n\n```js\ncreateFile = async () => {\n const data = {\n start: this.state.start,\n end: this.state.end,\n text: this.state.text,\n };\n await axios.post(\"http://localhost:8000/create_file\", data).then(() => {\n console.log(\"processing completed!\");\n });\n};\n\ndownloadFile = async () => {\n await axios.get(\"http://localhost:8000/generated_file\").then((res) => {\n const url = URL.createObjectURL(new Blob([res.data]));\n const link = document.createElement(\"a\");\n link.href = url;\n link.setAttribute(\"download\", \"generated.txt\");\n link.click();\n });\n};\n```\n\n```text\ndocx\n```\n\n```text\npython-docx\n```\n\n```text\nDocument\n```\n\n```text\ndocx\n```\n\n```text\ndocx\n```\n\n```text\nFileResponse\n```\n\n```text\ngenerated.docx\n```\n\n```text\ndownloadFile\n```\n\n```text\ndocx\n```\n\n```py\nfrom fastapi import FastAPI, Request\nfrom fastapi.templating import Jinja2Templates\nfrom fastapi.responses import FileResponse\nfrom docx import Document\n\napp = FastAPI()\ntemplates = Jinja2Templates(directory=\"templates\")\n\n\n@app.get('/')\ndef main(request: Request):\n return templates.TemplateResponse(\"index.html\", {\"request\": request})\n \n@app.post(\"/create\")\ndef create_file():\n document = Document()\n document.add_heading(\"file generated\", level=1)\n document.add_paragraph(\"test\")\n document.save('generated_file.docx')\n return {\"status\":\"Done!\"}\n \n@app.get(\"/download\")\ndef download_generated_file():\n file_path = \"generated_file.docx\"\n return FileResponse(file_path, media_type='application/vnd.openxmlformats-officedocument.wordprocessingml.document', filename=file_path)\n```\n\n```html\n<!DOCTYPE html>\n<html>\n <head>\n <title>Create and Download a Document</title>\n <script src=\"https://cdnjs.cloudflare.com/ajax/libs/axios/0.27.2/axios.min.js\"></script>\n </head>\n <body>\n <input type=\"button\" value=\"Create Document\" onclick=\"createFile()\">\n <div id=\"response\"></div><br>\n <input type=\"button\" value=\"Download Document \" onclick=\"downloadFile()\">\n <script>\n function createFile() {\n axios.post('/create', {\n headers: {\n 'Accept': 'application/json',\n 'Content-Type': 'application/json'\n }\n })\n .then(response => {\n document.getElementById(\"response\").innerHTML = JSON.stringify(response.data);\n })\n .catch(error => {\n console.error(error);\n });\n }\n \n function downloadFile() {\n axios.get('/download', {\n responseType: 'blob'\n })\n .then(response => {\n const disposition = response.headers['content-disposition'];\n filename = disposition.split(/;(.+)/)[1].split(/=(.+)/)[1];\n if (filename.toLowerCase().startsWith(\"utf-8''\"))\n filename = decodeURIComponent(filename.replace(\"utf-8''\", ''));\n else\n filename = filename.replace(/['\"]/g, '');\n return response.data;\n })\n .then(blob => {\n var url = window.URL.createObjectURL(blob);\n var a = document.createElement('a');\n a.href = url;\n a.download = filename;\n document.body.appendChild(a); // append the element to the dom\n a.click();\n a.remove(); // afterwards, remove the element \n })\n .catch(error => {\n console.error(error);\n });\n }\n </script>\n </body>\n</html>\n```\n\n```html\n<!DOCTYPE html>\n<html>\n <head>\n <title>Create and Download a Document</title>\n </head>\n <body>\n <input type=\"button\" value=\"Create Document\" onclick=\"createFile()\">\n <div id=\"response\"></div><br>\n <input type=\"button\" value=\"Download Document\" onclick=\"downloadFile()\">\n <script>\n function createFile() {\n fetch('/create', {\n method: 'POST',\n headers: {\n 'Accept': 'application/json',\n 'Content-Type': 'application/json'\n }\n })\n .then(response => response.text())\n .then(data => {\n document.getElementById(\"response\").innerHTML = data;\n })\n .catch(error => {\n console.error(error);\n });\n }\n \n function downloadFile() {\n fetch('/download')\n .then(response => {\n const disposition = response.headers.get('Content-Disposition');\n filename = disposition.split(/;(.+)/)[1].split(/=(.+)/)[1];\n if (filename.toLowerCase().startsWith(\"utf-8''\"))\n filename = decodeURIComponent(filename.replace(\"utf-8''\", ''));\n else\n filename = filename.replace(/['\"]/g, '');\n return response.blob();\n })\n .then(blob => {\n var url = window.URL.createObjectURL(blob);\n var a = document.createElement('a');\n a.href = url;\n a.download = filename;\n document.body.appendChild(a); // append the element to the dom\n a.click();\n a.remove(); // afterwards, remove the element\n })\n .catch(error => {\n console.error(error);\n });\n }\n </script>\n </body>\n</html>\n```\n\n```text\nGET\n```\n\n```text\nresponseType\n```\n\n```text\nblob\n```\n\n```text\nresponse\n```\n\n```text\nBlob\n```\n\n```text\nresponse.data\n```\n\n```text\nURL.createObjectURL()\n```\n\n```text\nDocument\n```\n\n```text\nJinja2Templates\n```\n\n========================================\n\nComments:\n- This implies that the full file is first loaded in memory and then save to disk, right ? Is there some way to avoid that ?\n- @leonbloy The example above is based on OP's needs, where the file has to be created and served by two different endpoints. Sure you can avoid that, by returning a `Response` directly. Please have a look here and here, as well as at this, this and this answer.","metadata":{"transformedAt":"2026-08-18T18:32:29.139Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":24,"totalLines":318,"estimatedTokens":2202}}511{"id":"stack-71103393","source":"stackoverflow","questionId":71103393,"title":"FastAPI: Swagger UI does not render because of custom Middleware","tags":["python","swagger","fastapi","swagger-ui","openapi"],"text":"Title: FastAPI: Swagger UI does not render because of custom Middleware\nTags: python, swagger, fastapi, swagger-ui, openapi\nSource: Stack Overflow\n\nQuestion:\nSo I have a custom middleware like this:\n\nIts objective is to add some meta_data fields to every response from all endpoints of my FastAPI app.\n\n```\n@app.middelware(\"http\")\nasync def add_metadata_to_response_payload(request: Request, call_next):\n\n response = await call_next(request)\n\n body = b\"\"\n async for chunk in response.body_iterator:\n body+=chunk\n\n data = {}\n data[\"data\"] = json.loads(body.decode())\n data[\"metadata\"] = {\n \"some_data_key_1\": \"some_data_value_1\",\n \"some_data_key_2\": \"some_data_value_2\",\n \"some_data_key_3\": \"some_data_value_3\"\n }\n\n body = json.dumps(data, indent=2, default=str).encode(\"utf-8\")\n\n return Response(\n content=body,\n status_code=response.status_code,\n media_type=response.media_type\n )\n```\n\nHowever, when I served my app using uvicorn, and launched the swagger URL, here is what I see:\n\n```\nUnable to render this definition\n\nThe provided definition does not specify a valid version field.\n\nPlease indicate a valid Swagger or OpenAPI version field. Supported version fields are\nSwagger: \"2.0\" and those that match openapi: 3.0.n (for example, openapi: 3.0.0)\n```\n\nWith a lot of debugging, I found that this error was due to the custom middleware and specifically this line:\n\n```\nbody = json.dumps(data, indent=2, default=str).encode(\"utf-8\")\n```\n\nIf I simply comment out this line, swagger renders just fine for me. However, I need this line for passing the content argument in Response from Middleware. How to sort this out?\n\n**UPDATE**:\n\nI tried the following:\n`body = json.dumps(data, indent=2).encode(\"utf-8\")`\nby removing default arg, the swagger did successfully load. But now when I hit any of the APIs, here is what swagger tells me along with response payload on screen:\n`Unrecognised response type; displaying content as text`\n\nMore Updates (6th April 2022):\n\nGot a solution to fix 1 part of the problem by Chris, but the swagger wasn't still loading. The code was hung up in the middleware level indefinitely and the page was not still loading.\n\nSo, I found in all these places:\n\n- https://github.com/encode/starlette/issues/919\n\n- Blocked code while using middleware and dependency injections to log requests in FastAPI(Python)\n\n- https://github.com/tiangolo/fastapi/issues/394\n\nthat this way of adding custom middleware works by inheriting from BaseHTTPMiddleware in Starlette and has its own issues (something to do with awaiting inside middleware, streamingresponse and normal response, and the way it is called). I don't understand it yet.\n\n========================================\n\nTop Answer:\nYou are substituting the body of the swagger html with json data taken from both middleware and response (html response in this case).\n\nYou'll end up with something like\n\n```\n{\n \"data\": \"....\",\n \"metadata\": {\n \"some_data_key_1\": \"some_data_value_1\",\n \"some_data_key_2\": \"some_data_value_2\",\n \"some_data_key_3\": \"some_data_value_3\"\n }\n}\n```\n\nOf course this won't work.\n\n### Possible Solution\n\nPerform a check on the content type of the response in the middleware. Extend the response if it `json`, otherwise leave it as it is.\n\nNote:\nThis can only be done if it can be safely assumed that every `json` response needs the `metadata` to be added, while `html` content type doesn't. (you can change the check according to your needs)\n\n### Another possible solution\n\nWait for the following issue to be merged into the current `starlette`s implementation and `fastapi` to start using this version.\n\nhttps://github.com/tiangolo/fastapi/issues/1174\nhttps://github.com/encode/starlette/pull/1286\n\n========================================\n\nCode:\n```py\n@app.middelware(\"http\")\nasync def add_metadata_to_response_payload(request: Request, call_next):\n\n response = await call_next(request)\n\n body = b\"\"\n async for chunk in response.body_iterator:\n body+=chunk\n\n\n data = {}\n data[\"data\"] = json.loads(body.decode())\n data[\"metadata\"] = {\n \"some_data_key_1\": \"some_data_value_1\",\n \"some_data_key_2\": \"some_data_value_2\",\n \"some_data_key_3\": \"some_data_value_3\"\n }\n\n body = json.dumps(data, indent=2, default=str).encode(\"utf-8\")\n\n return Response(\n content=body,\n status_code=response.status_code,\n media_type=response.media_type\n )\n```\n\n```text\nUnable to render this definition\n\nThe provided definition does not specify a valid version field.\n\nPlease indicate a valid Swagger or OpenAPI version field. Supported version fields are\nSwagger: \"2.0\" and those that match openapi: 3.0.n (for example, openapi: 3.0.0)\n```\n\n```py\nbody = json.dumps(data, indent=2, default=str).encode(\"utf-8\")\n```\n\n```text\nbody = json.dumps(data, indent=2).encode(\"utf-8\")\n```\n\n```text\nUnrecognised response type; displaying content as text\n```\n\n```py\nfrom fastapi import FastAPI, Request, Response\nimport json\n\napp = FastAPI()\n\n@app.middleware(\"http\")\nasync def add_metadata_to_response_payload(request: Request, call_next):\n response = await call_next(request)\n content_type = response.headers.get('Content-Type')\n if content_type == \"application/json\":\n response_body = [section async for section in response.body_iterator]\n resp_str = response_body[0].decode() # converts \"response_body\" bytes into string\n resp_dict = json.loads(resp_str) # converts resp_str into dict \n #print(resp_dict)\n if \"openapi\" not in resp_dict:\n data = {}\n data[\"data\"] = resp_dict # adds the \"resp_dict\" to the \"data\" dictionary\n data[\"metadata\"] = {\n \"some_data_key_1\": \"some_data_value_1\",\n \"some_data_key_2\": \"some_data_value_2\",\n \"some_data_key_3\": \"some_data_value_3\"}\n resp_str = json.dumps(data, indent=2) # converts dict into JSON string\n \n return Response(content=resp_str, status_code=response.status_code, media_type=response.media_type)\n \n return response\n\n\n@app.get(\"/\")\ndef foo(request: Request):\n return {\"hello\": \"world!\"}\n```\n\n```py\nfrom fastapi import FastAPI, Request, Response, Query\nfrom pydantic import constr\nfrom fastapi.responses import JSONResponse\nimport re\nimport uvicorn\nimport json\n\napp = FastAPI()\nroutes_with_middleware = [\"/\"]\nrx = re.compile(r'^(/items/\\d+|/courses/[a-zA-Z0-9]+)$') # support routes with path parameters\nmy_constr = constr(regex=\"^[a-zA-Z0-9]+$\")\n\n@app.middleware(\"http\")\nasync def add_metadata_to_response_payload(request: Request, call_next):\n response = await call_next(request)\n if request.url.path not in routes_with_middleware and not rx.match(request.url.path):\n return response\n else:\n content_type = response.headers.get('Content-Type')\n if content_type == \"application/json\":\n response_body = [section async for section in response.body_iterator]\n resp_str = response_body[0].decode() # converts \"response_body\" bytes into string\n resp_dict = json.loads(resp_str) # converts resp_str into dict \n data = {}\n data[\"data\"] = resp_dict # adds \"resp_dict\" to the \"data\" dictionary\n data[\"metadata\"] = {\n \"some_data_key_1\": \"some_data_value_1\",\n \"some_data_key_2\": \"some_data_value_2\",\n \"some_data_key_3\": \"some_data_value_3\"}\n resp_str = json.dumps(data, indent=2) # converts dict into JSON string\n return Response(content=resp_str, status_code=response.status_code, media_type=\"application/json\")\n\n\n@app.get(\"/\")\ndef root():\n return {\"hello\": \"world!\"}\n\n@app.get(\"/items/{id}\")\ndef get_item(id: int):\n return {\"Item\": id}\n\n@app.get(\"/courses/{code}\")\ndef get_course(code: my_constr):\n return {\"course_code\": code, \"course_title\": \"Deep Learning\"}\n```\n\n```text\nContent-Type\n```\n\n```text\nmetadata\n```\n\n```text\napplication/json\n```\n\n```text\n/docs\n```\n\n```text\n/redoc\n```\n\n```text\nopenapi\n```\n\n```text\ninfo\n```\n\n```text\nversion\n```\n\n```text\npaths\n```\n\n```text\nAPIRoute\n```\n\n```text\nresponse\n```\n\n```text\napp\n```\n\n```text\nresponse\n```\n\n```text\n{\n \"data\": \"<html>....</html>\",\n \"metadata\": {\n \"some_data_key_1\": \"some_data_value_1\",\n \"some_data_key_2\": \"some_data_value_2\",\n \"some_data_key_3\": \"some_data_value_3\"\n }\n}\n```\n\n```text\njson\n```\n\n```text\njson\n```\n\n```text\nmetadata\n```\n\n```text\nhtml\n```\n\n```text\nstarlette\n```\n\n```text\nfastapi\n```\n\n========================================\n\nComments:\n- Hey @Isabi, this error I am facing for cases where response type is JSON and not HTML, so my `data` key has value as byte string on JSON object.\n- @raghavsikaria have you tried with response.json() ?\n- Really good answer, thank you! Though I ended up with a simplified solution inspired by \"Update 1\": `if request.url.path in ['/docs', '/redoc', 'openapi.json']: return response`","metadata":{"transformedAt":"2026-08-18T18:32:29.139Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":27,"totalLines":336,"estimatedTokens":2234}}512{"id":"stack-69292855","source":"stackoverflow","questionId":69292855,"title":"Why do I get an \"Unprocessable Entity\" error while uploading an image with FastAPI?","tags":["python","python-3.x","fastapi"],"text":"Title: Why do I get an \"Unprocessable Entity\" error while uploading an image with FastAPI?\nTags: python, python-3.x, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to upload an image but FastAPI is coming back with an error I can't figure out.\n\nIf I leave out the \"`file: UploadFile = File(...)`\" from the function definition, it works correctly. But when I add the `file` to the function definition, then it throws the error.\n\nHere is the complete code.\n\n```\n@router.post('/', response_model=schemas.PostItem, status_code=status.HTTP_201_CREATED)\ndef create(request: schemas.Item, file: UploadFile = File(...), db: Session = Depends(get_db)):\n\n new_item = models.Item(\n name=request.name,\n price=request.price,\n user_id=1,\n )\n print(file.filename)\n db.add(new_item)\n db.commit()\n db.refresh(new_item)\n return new_item\n```\n\nThe `Item` Pydantic model is just\n\n```\nclass Item(BaseModel):\n name: str\n price: float\n```\n\nThe error is:\n\nCode 422 Error: Unprocessable Entity\n\n```\n{\n \"detail\": [\n {\n \"loc\": [\n \"body\",\n \"request\",\n \"name\"\n ],\n \"msg\": \"field required\",\n \"type\": \"value_error.missing\"\n },\n {\n \"loc\": [\n \"body\",\n \"request\",\n \"price\"\n ],\n \"msg\": \"field required\",\n \"type\": \"value_error.missing\"\n }\n ]\n}\n```\n\n========================================\n\nCode:\n```text\n@router.post('/', response_model=schemas.PostItem, status_code=status.HTTP_201_CREATED)\ndef create(request: schemas.Item, file: UploadFile = File(...), db: Session = Depends(get_db)):\n\n new_item = models.Item(\n name=request.name,\n price=request.price,\n user_id=1,\n )\n print(file.filename)\n db.add(new_item)\n db.commit()\n db.refresh(new_item)\n return new_item\n```\n\n```text\nclass Item(BaseModel):\n name: str\n price: float\n```\n\n```text\n{\n \"detail\": [\n {\n \"loc\": [\n \"body\",\n \"request\",\n \"name\"\n ],\n \"msg\": \"field required\",\n \"type\": \"value_error.missing\"\n },\n {\n \"loc\": [\n \"body\",\n \"request\",\n \"price\"\n ],\n \"msg\": \"field required\",\n \"type\": \"value_error.missing\"\n }\n ]\n}\n```\n\n```text\nfile: UploadFile = File(...)\n```\n\n```text\nfile\n```\n\n```text\nItem\n```\n\n```text\nclass Item(BaseModel):\n name: str\n price: float\n\nclass PostItem(BaseModel):\n name: str\n\n@router.post('/', response_model=PostItem, status_code=status.HTTP_201_CREATED)\ndef create(\n # Here we expect parameters for each field of the model\n name: str = Form(...),\n price: float = Form(...),\n # Here we expect an uploaded file\n file: UploadFile = File(...),\n):\n new_item = Item(name=name, price=price)\n print(new_item)\n print(file.filename)\n return new_item\n```\n\n```text\nclass ItemForm(BaseModel):\n name: str\n price: float\n\n @classmethod\n def as_form(cls, name: str = Form(...), price: float = Form(...)) -> 'ItemForm':\n return cls(name=name, price=price)\n\nclass PostItem(BaseModel):\n name: str\n\n@router.post('/', response_model=PostItem, status_code=status.HTTP_201_CREATED)\ndef create(\n item: ItemForm = Depends(ItemForm.as_form),\n file: UploadFile = File(...),\n):\n new_item = Item(name=item.name, price=item.price)\n print(new_item)\n print(file.filename)\n return new_item\n```\n\n```text\nrequest: schemas.Item\n```\n\n```text\napplication/json\n```\n\n```text\nfile: UploadFile = File(...)\n```\n\n```text\nmultipart/form-data\n```\n\n```text\nmultipart/form-data\n```\n\n```text\nFile\n```\n\n```text\nFile\n```\n\n```text\nForm\n```\n\n```text\nBody\n```\n\n```text\nmultipart/form-data\n```\n\n```text\napplication/json\n```\n\n```text\nmultipart/form-data\n```\n\n```text\nItem\n```\n\n```text\nmultipart/form-data\n```\n\n```text\nFile\n```\n\n```text\nForm\n```\n\n```text\ndb\n```\n\n```text\nItem\n```\n\n```text\nItem\n```\n\n```text\nItem\n```\n\n```text\nItemForm\n```\n\n```text\nForm\n```\n\n```text\nItem\n```\n\n```text\nfile: UploadFile = File(...)\n```\n\n```text\nFile\n```\n\n```text\napplication/json\n```\n\n```text\nrequest\n```\n\n```text\nrequest: Request\n```\n\n========================================\n\nComments:\n- Please edit to post the *exact* error message and response. Also, how are you sending the POST request? How are you uploading the file?\n- I am sending it using the SwaggerUI. So I click in the SwaggerUI file browser and select the image and upload. If I leave the request: ItemShow and the ItemShow from the route it works. SO I think I cannot have both the request: schemas.Item and file: UploadFile...\n- Well this is an incredibly instructive answer. By the way I read all the time about splitting the request into the body and the file into two different requests. This is strange as most of the web work I have done an image is typically part of a request along with other values like name price etc.\n- I have one more comment. FastAPI is good but the error messages needs to be more expressive. I had encounter errors where I have no clues on what's going on. If you can throw some lights into how you interpret this error to reach the conclusion that I was doing all this wrong. In other words, to teach me/others your mental process to figure this out, I will appreciate it.\n- Also, I noticed the price: str = Form(...), instead of float which is the right pydantic type. Is this an error?\n- @dianesis Yes, the price was a typo from copy-pasting without checking. It should be float in all the sample codes. Updated my answer.\n- @dianesis [1/2] For the 422 fastapi/pydantic error, I regularly get it when I'm either *passing* the request wrong or *receiving* the request wrong. I started with trying 1 route with just `item: Item` and 1 route with just `file: UploadFile...`, just to confirm they work normally as-is. Then, when it didn't work together, I accessed the `Request` object directly to see the actual content-type and body of the request.\n- @dianesis [2/2] I checked `request.headers['content-type']` and saw that it was `multipart/form-data`. That gave me a hint that it won't get parsed properly into the Pydantic model, which accepts a dict (so the body should be in JSON). Then I re-read the FastAPI docs on the uploading files, and saw that warning about mixing JSON and Form in 1 request. (In hindsight, re-reading the docs first would have solved the problem much more quickly.)","metadata":{"transformedAt":"2026-08-18T18:32:29.139Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":36,"totalLines":294,"estimatedTokens":1547}}513{"id":"stack-72229195","source":"stackoverflow","questionId":72229195,"title":"SQLAlchemy: JOIN between different databases AND using different files in a module","tags":["python","mysql","sqlalchemy","mariadb","fastapi"],"text":"Title: SQLAlchemy: JOIN between different databases AND using different files in a module\nTags: python, mysql, sqlalchemy, mariadb, fastapi\nSource: Stack Overflow\n\nQuestion:\n### Stack\n\nI am using:\n\n- Python 3.10.x\n\n- FastAPI 0.75.x\n\n- SQLAlchemy 1.4.3x\n\n### Summary\n\nI am building a unifying FastAPI project for several legacy databases (stored back-end on MariaDB 10.3 - structure has to be retained for some legacy software).\n\nMy SQLA setup uses a databases module to do the following:\n\n### /databases.py\n\n```\nimport dotenv\nimport os\n\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.orm import sessionmaker\n\nimport .models as models\n\ndotenv.load_dotenv()\n\nengines = {\n 'parts': create_engine(\"mysql+pymysql://\" + os.environ['DB_URL'] + \"/parts\", pool_pre_ping=True, pool_recycle=300),\n 'shop': create_engine(\"mysql+pymysql://\" + os.environ['DB_URL'] + \"/shop\", pool_pre_ping=True, pool_recycle=300),\n 'purchasing': create_engine(\"mysql+pymysql://\" + os.environ['DB_URL'] + \"/purchasing\", pool_pre_ping=True, pool_recycle=300),\n \"company\": create_engine(\"mysql+pymysql://\" + os.environ['DB_URL'] + \"/company\", pool_pre_ping=True, pool_recycle=300),\n \"auth\": create_engine(\"mysql+pymysql://\" + os.environ['DB_URL'] + \"/auth\", pool_pre_ping=True, pool_recycle=300),\n}\n\nDBSession = sessionmaker(autocommit=False, autoflush=False, binds={\n # Catalogue\n models.Shop.Catalogue: engines[\"shop\"],\n models.Shop.Sections: engines[\"shop\"],\n models.Shop.Orders: engines[\"shop\"],\n # ...\n # Parts\n models.Parts.Part: engines[\"parts\"],\n models.Parts.BinLocations: engines[\"parts\"],\n\n # ...\n #Purchasing\n models.Purchasing.SupplierOrder: engines[\"purchasing\"],\n models.Purchasing.SupplierOrder: engines[\"purchasing\"],\n # Company Data\n models.Company.Staffmember: engines[\"company\"],\n models.Company.Suppliers: engines[\"company\"],\n # API Auth\n models.Auth.User: engines[\"auth\"],\n models.Auth.Privileges: engines[\"auth\"],\n})\n\n# Dependency\ndef getDb():\n db = DBSession()\n try:\n yield db\n finally:\n db.close()\n```\n\nIt's a little laborious having to do this for every model but it does work.\n\nAs I have several dbs I thought it would be logical to create a `models` module with sub-files for each db e.g. `models.Parts`, `models.Shop`, `models.Purchase`, `models.Company`, `models.Auth` etc.\n\n/models/**init**.py\n\n```\nfrom importlib.metadata import metadata\nfrom sqlalchemy.orm import declarative_base\n\nbase = declarative_base()\n\nfrom . import Auth, Parts, Shop, Catalogue, Purchasing, Shop\n```\n\nI can create relationships successfully by importing the `Base` object in the `__init__.py` of `models` and importing that to each sub-file. For example:\n\n### /models/Auth.py\n\n```\nfrom . import base as Base\n\nfrom sqlalchemy.orm import relationship\nfrom sqlalchemy import Column, Integer, String, Numeric, Date, DateTime, ForeignKey, null, or_, and_\n\nclass User(Base):\n __tablename__ = 'users'\n\n id = Column(Integer, nullable=False, primary_key=True)\n username = Column(String(256), nullable=False)\n passhash = Column(String(512), nullable=False)\n email = Column(String, nullable=False)\n enabled = Column(Integer, nullable=True)\n staffmember_id = Column(Integer, nullable=False)\n\n staffmember = relationship(\"Company.Staffmember\", uselist=False)\n```\n\n### /models/Company.py\n\n```\nfrom . import base as Base\n\nfrom sqlalchemy.orm import relationship\nfrom sqlalchemy import Column, Integer, String, Numeric, Date, DateTime, ForeignKey, null, or_, and_\n\nclass Staffmebmer(Base):\n __tablename__ = 'staffmembers'\n\n id = Column(Integer, ForeignKey(\"users.staffmember_id\"), nullable=False, primary_key=True)\n order = Column(Integer, default=0, nullable=False)\n name = Column(String, nullable=True)\n initial = Column(String, nullable=True)\n email = Column(String, nullable=False)\n enabled = Column(Integer, default=0, nullable=False)\n\n relationship(\"Auth.User\", back_populates=\"staffmember\")\n```\n\nThe following route works just fine:\n\n### demo.py\n\n```\nfrom fastapi import Depends\n\nfrom sqlalchemy.orm import Session\n\nfrom .. import app, databases, models\n\n@app.get(\"/api/user/{id}\")\nasync def read_items(id: int, db: Session=Depends(databases.getDb)):\n user = db.query(models.Auth.User).filter(\n models.Auth.User.id == id\n ).first()\n\n user.staffmember\n\n return user\n```\n\nAccessing this URL returns:\n**(Yes, I'm aware this isn't secure, it is for illustrative purposes only to show that the relationship functions!)**\n\n```\n{\n \"username\": \"mark\",\n \"passhash\": \"\",\n \"enabled\": 1,\n \"email\": \"mark@demo.com\",\n \"id\": 1,\n \"staffmember_id\": 5,\n \"staffmember\": {\n \"order\": 20,\n \"name\": \"Mark\",\n \"email\": \"mark@demo.com\",\n \"kStaffmember\": 5,\n \"initial\": \"MB\",\n \"enabled\": 1\n }\n}\n```\n\nHowever, I want to use steffmember initials as a possible username, so when I qyuery for a user in my OAUTH Authorize scripts I tried to use:\n\n```\nfrom ..models import Auth, Company\n\n# 'username' is provided by the auth script from the standard username/password OAuth fields\n\ndef get_user(db: Session, username: str):\n db_user_data = db.query(Auth.User).join(Company.Staffmember).filter(\n or_(\n Auth.User.username == username,\n Auth.User.email == username,\n Company.Staffmember.initial == username\n )\n ).first()\n```\n\nand I get an Exception:\n\n```\n(pymysql.err.ProgrammingError) (1146, \"Table 'auth.staffmembers' doesn't exist\")\n```\n\nAm I going about this whole thing the right way and is there a possible way around this issue?\n\n========================================\n\nCode:\n```python\nimport dotenv\nimport os\n\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.orm import sessionmaker\n\nimport .models as models\n\ndotenv.load_dotenv()\n\nengines = {\n 'parts': create_engine(\"mysql+pymysql://\" + os.environ['DB_URL'] + \"/parts\", pool_pre_ping=True, pool_recycle=300),\n 'shop': create_engine(\"mysql+pymysql://\" + os.environ['DB_URL'] + \"/shop\", pool_pre_ping=True, pool_recycle=300),\n 'purchasing': create_engine(\"mysql+pymysql://\" + os.environ['DB_URL'] + \"/purchasing\", pool_pre_ping=True, pool_recycle=300),\n \"company\": create_engine(\"mysql+pymysql://\" + os.environ['DB_URL'] + \"/company\", pool_pre_ping=True, pool_recycle=300),\n \"auth\": create_engine(\"mysql+pymysql://\" + os.environ['DB_URL'] + \"/auth\", pool_pre_ping=True, pool_recycle=300),\n}\n\nDBSession = sessionmaker(autocommit=False, autoflush=False, binds={\n # Catalogue\n models.Shop.Catalogue: engines[\"shop\"],\n models.Shop.Sections: engines[\"shop\"],\n models.Shop.Orders: engines[\"shop\"],\n # ...\n # Parts\n models.Parts.Part: engines[\"parts\"],\n models.Parts.BinLocations: engines[\"parts\"],\n\n # ...\n #Purchasing\n models.Purchasing.SupplierOrder: engines[\"purchasing\"],\n models.Purchasing.SupplierOrder: engines[\"purchasing\"],\n # Company Data\n models.Company.Staffmember: engines[\"company\"],\n models.Company.Suppliers: engines[\"company\"],\n # API Auth\n models.Auth.User: engines[\"auth\"],\n models.Auth.Privileges: engines[\"auth\"],\n})\n\n# Dependency\ndef getDb():\n db = DBSession()\n try:\n yield db\n finally:\n db.close()\n```\n\n```python\nfrom importlib.metadata import metadata\nfrom sqlalchemy.orm import declarative_base\n\nbase = declarative_base()\n\nfrom . import Auth, Parts, Shop, Catalogue, Purchasing, Shop\n```\n\n```python\nfrom . import base as Base\n\nfrom sqlalchemy.orm import relationship\nfrom sqlalchemy import Column, Integer, String, Numeric, Date, DateTime, ForeignKey, null, or_, and_\n\nclass User(Base):\n __tablename__ = 'users'\n\n id = Column(Integer, nullable=False, primary_key=True)\n username = Column(String(256), nullable=False)\n passhash = Column(String(512), nullable=False)\n email = Column(String, nullable=False)\n enabled = Column(Integer, nullable=True)\n staffmember_id = Column(Integer, nullable=False)\n\n staffmember = relationship(\"Company.Staffmember\", uselist=False)\n```\n\n```python\nfrom . import base as Base\n\nfrom sqlalchemy.orm import relationship\nfrom sqlalchemy import Column, Integer, String, Numeric, Date, DateTime, ForeignKey, null, or_, and_\n\nclass Staffmebmer(Base):\n __tablename__ = 'staffmembers'\n\n id = Column(Integer, ForeignKey(\"users.staffmember_id\"), nullable=False, primary_key=True)\n order = Column(Integer, default=0, nullable=False)\n name = Column(String, nullable=True)\n initial = Column(String, nullable=True)\n email = Column(String, nullable=False)\n enabled = Column(Integer, default=0, nullable=False)\n\n relationship(\"Auth.User\", back_populates=\"staffmember\")\n```\n\n```python\nfrom fastapi import Depends\n\nfrom sqlalchemy.orm import Session\n\nfrom .. import app, databases, models\n\n@app.get(\"/api/user/{id}\")\nasync def read_items(id: int, db: Session=Depends(databases.getDb)):\n user = db.query(models.Auth.User).filter(\n models.Auth.User.id == id\n ).first()\n\n user.staffmember\n\n return user\n```\n\n```json\n{\n \"username\": \"mark\",\n \"passhash\": \"<my hash>\",\n \"enabled\": 1,\n \"email\": \"mark@demo.com\",\n \"id\": 1,\n \"staffmember_id\": 5,\n \"staffmember\": {\n \"order\": 20,\n \"name\": \"Mark\",\n \"email\": \"mark@demo.com\",\n \"kStaffmember\": 5,\n \"initial\": \"MB\",\n \"enabled\": 1\n }\n}\n```\n\n```python\nfrom ..models import Auth, Company\n\n# 'username' is provided by the auth script from the standard username/password OAuth fields\n\ndef get_user(db: Session, username: str):\n db_user_data = db.query(Auth.User).join(Company.Staffmember).filter(\n or_(\n Auth.User.username == username,\n Auth.User.email == username,\n Company.Staffmember.initial == username\n )\n ).first()\n```\n\n```text\n(pymysql.err.ProgrammingError) (1146, \"Table 'auth.staffmembers' doesn't exist\")\n```\n\n```text\nmodels\n```\n\n```text\nmodels.Parts\n```\n\n```text\nmodels.Shop\n```\n\n```text\nmodels.Purchase\n```\n\n```text\nmodels.Company\n```\n\n```text\nmodels.Auth\n```\n\n```text\nBase\n```\n\n```text\n__init__.py\n```\n\n```text\nmodels\n```\n\n```python\nimport dotenv\nimport os\n\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.orm import sessionmaker\n\nimport .models as models\n\ndotenv.load_dotenv()\n\nDBengine = create_engine(\"mysql+pymysql://\" + os.environ['DB_URL'] + \"/parts\", pool_pre_ping=True, pool_recycle=300)\n\nDBSession = sessionmaker(bind=DBengine autocommit=False, autoflush=False)\n\n# Dependency\ndef getDb():\n db = DBSession()\n try:\n yield db\n finally:\n db.close()\n```\n\n```python\nfrom . import base as Base\n\nfrom sqlalchemy.orm import relationship\nfrom sqlalchemy import Column, Integer, String, Numeric, Date, DateTime, ForeignKey, null, or_, and_\n\nclass User(Base):\n __tablename__ = 'users' #table is called 'users'\n __table_args__ = { \"schema\": \"auth\" } #database is called 'auth'\n\n id = Column(Integer, nullable=False, primary_key=True)\n username = Column(String(256), nullable=False)\n passhash = Column(String(512), nullable=False)\n email = Column(String, nullable=False)\n enabled = Column(Integer, nullable=True)\n staffmember_id = Column(Integer, nullable=False)\n\n staffmember = relationship(\"Company.Staffmember\", uselist=False)\n```\n\n```python\nfrom . import base as Base\n\nfrom sqlalchemy.orm import relationship\nfrom sqlalchemy import Column, Integer, String, Numeric, Date, DateTime, ForeignKey, null, or_, and_\n\nclass Staffmember(Base):\n __tablename__ = 'staffmembers' #table is called 'staffmembers'\n __table_args__ = { \"schema\": \"company\" } #database is called 'company'\n\n id = Column(Integer, ForeignKey(\"auth.users.staffmember_id\"), nullable=False, primary_key=True)\n # ForeignKey now needs to know the database AND table name for the field it refers to\n order = Column(Integer, default=0, nullable=False)\n name = Column(String, nullable=True)\n initial = Column(String, nullable=True)\n email = Column(String, nullable=False)\n enabled = Column(Integer, default=0, nullable=False)\n\n relationship(\"Auth.User\", back_populates=\"staffmember\")\n```\n\n```text\nForeignKey()\n```\n\n```text\nForeignKey(\"<db>.<table>.<field>\")\n```\n\n```text\n__table_args__ = { \"schema\": \"<database name>\" }\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.139Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":23,"totalLines":469,"estimatedTokens":2994}}514{"id":"stack-72205144","source":"stackoverflow","questionId":72205144,"title":"Fast API Python special log parameter for each request","tags":["python","logging","fastapi"],"text":"Title: Fast API Python special log parameter for each request\nTags: python, logging, fastapi\nSource: Stack Overflow\n\nQuestion:\nMaybe someone here have a good idea on how to solve my issue. I have a REST API project driven by FastAPI. Every incomming request comes with a hash in the header. I am looking for a simple solution to write this hash as an extra parameter to the logs. I want to avoid adding it every time per hand. I first come up with the solution to write a Middleware which writes the hash in a Logger Object and then later use the loggerObject.log() function which adds the hash automatically. But this only works for my own log messages. Log messages from for example exceptions or from libraries I use dont have the extra parameter.\n\n========================================\n\nCode:\n```text\nstructlog\n```\n\n```text\nFastAPI\n```\n\n```text\n/long\n```\n\n```text\nlogging.config.dictConfig(...)\n```\n\n========================================\n\nComments:\n- \"System logs\" -> which logs, *precisely*?\n- I edited my question. I mean the log messages from exception or from libraries.\n- Great, thanks a lot I think this is nearly exactly what I need!\n- This repo has a bug section in the readme, but I am unclear what it is showing? Is it showing the reult of an exception being thrown, or is it showing an issue in this current implementation? I am seeing this same anyio.WouldBlock and I'm not sure if its a logging error or just traiditional error handling\n- the GET /bug endpoint is a demo endpoint with an intentional bug in it, in order to show how logs will look like if an endpoint throws an unexpected bug. The endpoint tries to divide by 0, as you can see here: gitlab.com/sagbot/structlog-demo/-/blob/main/demo/route.py#L‌​36","metadata":{"transformedAt":"2026-08-18T18:32:29.139Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":34,"estimatedTokens":437}}515{"id":"stack-72029224","source":"stackoverflow","questionId":72029224,"title":"Why does running a python file inside a pod not have the same behavior as running it directly?","tags":["python","kubernetes","fastapi"],"text":"Title: Why does running a python file inside a pod not have the same behavior as running it directly?\nTags: python, kubernetes, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have a FastAPI app with the following code\n\n```\n@app.on_event(\"startup\")\n async def startup_event():\n \"\"\"Initialize application services\"\"\"\n print(\"Starting the service\")\n```\n\nwhen I run FastAPI directly from the terminal, I get the following output\n\n```\nINFO: Started server process [259936]\nINFO: Waiting for application startup.\nStarting the service\nINFO: Application startup complete.\nINFO: Uvicorn running on http://0.0.0.0:3000 (Press CTRL+C to quit)\n```\n\nYou can see that the print statement got executed.\n\nHowever, when the same app is automatically run inside a Kubernetes cluster, I get the following output\n\n```\nINFO: Waiting for application startup.\n INFO: Application startup complete.\n INFO: Uvicorn running on http://0.0.0.0:3000 (Press CTRL+C to quit)\n```\n\nThe print statement did not get executed, in fact, any additional code inside the function never gets executed.\n\nHowever, if I exit the process like this:\n\n```\n@app.on_event(\"startup\")\nasync def startup_event():\n \"\"\"Initialize application services\"\"\"\n print(\"Starting the service\")\n exit(99)\n```\n\nThe process exists then I can see the print statement.\n\n```\nSystemExit: 99\nERROR: Application startup failed. Exiting.\nStarting the service\n```\n\nWhat is the problem here?\n\nEdit: Actually no code whatsoever gets executed, I have put print statements literally everywhere and nothing gets printed, but somehow the webserver runs...\n\n========================================\n\nCode:\n```py\n@app.on_event(\"startup\")\n async def startup_event():\n \"\"\"Initialize application services\"\"\"\n print(\"Starting the service\")\n```\n\n```text\nINFO: Started server process [259936]\nINFO: Waiting for application startup.\nStarting the service\nINFO: Application startup complete.\nINFO: Uvicorn running on http://0.0.0.0:3000 (Press CTRL+C to quit)\n```\n\n```text\nINFO: Waiting for application startup.\n INFO: Application startup complete.\n INFO: Uvicorn running on http://0.0.0.0:3000 (Press CTRL+C to quit)\n```\n\n```py\n@app.on_event(\"startup\")\nasync def startup_event():\n \"\"\"Initialize application services\"\"\"\n print(\"Starting the service\")\n exit(99)\n```\n\n```text\nSystemExit: 99\nERROR: Application startup failed. Exiting.\nStarting the service\n```\n\n========================================\n\nComments:\n- perhaps you looking at an old image. You sure it got pulled?\n- @TheFool Yes, I changed the port to see if it changes in the logs and it does.\n- Looks like a difference of how asyncio is being handled in the kubernetes python client versus in your environment\n- It turns out the problem was the internal buffer not flushing the output. Forcing it to flush: print(\"\", flush=True) solved the issue.\n- I am one of the poor souls who stumbled upon this thread in the future, so thank you.","metadata":{"transformedAt":"2026-08-18T18:32:29.139Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":104,"estimatedTokens":739}}516{"id":"stack-72186688","source":"stackoverflow","questionId":72186688,"title":"FastAPI websockets not working when using Redis pubsub functionality","tags":["python","websocket","redis","fastapi"],"text":"Title: FastAPI websockets not working when using Redis pubsub functionality\nTags: python, websocket, redis, fastapi\nSource: Stack Overflow\n\nQuestion:\ncurrently I'm using websockets to pass through data that I receive from a Redis queue (pub/sub). But for some reason the websocket doesn't send messages when using this redis queue.\n\n### What my code looks like\n\nMy code works as folllow:\n\n- I accept the socket connection\n\n- I connect to the redis queue\n\n- For each message that I receive from the subscription, i sent a message through the socket. (at the moment only text for testing)\n\n```\n@check_route.websocket_route(\"/check\")\nasync def websocket_endpoint(websocket: WebSocket):\n\n await websocket.accept()\n\n redis = Redis(host='::1', port=6379, db=1)\n subscribe = redis.pubsub()\n subscribe.subscribe('websocket_queue')\n\n try:\n for result in subscribe.listen():\n await websocket.send_text('test')\n print('test send')\n except Exception as e:\n await websocket.close()\n raise e\n```\n\n### The issue with the code\n\nWhen I'm using this code it's just not sending the message through the socket. But when I accept the websocket within the `subscribe.listen()` loop it does work but it reconnects every time (see code below).\n\n```\n@check_route.websocket_route(\"/check\")\nasync def websocket_endpoint(websocket: WebSocket):\n\n redis = Redis(host='::1', port=6379, db=1)\n subscribe = redis.pubsub()\n subscribe.subscribe('websocket_queue')\n\n try:\n for result in subscribe.listen():\n await websocket.accept()\n await websocket.send_text('test')\n print('test send')\n except Exception as e:\n await websocket.close()\n raise e\n```\n\nI think that the `subscribe.listen()` causes some problems that make the websocket do nothing when `websocket.accept()` is outside the for loop.\n\nI hope someone knows whats wrong with this.\n\n========================================\n\nTop Answer:\nI'm not sure if this will work, but you could try this:\n\n```\nasync def websocket_endpoint(websocket: WebSocket):\n\n await websocket.accept()\n\n redis = Redis(host='::1', port=6379, db=1)\n subscribe = redis.pubsub()\n subscribe.subscribe('websocket_queue')\n\n try:\n results = await subscribe.listen()\n for result in results:\n await websocket.send_text('test')\n print('test send')\n except Exception as e:\n await websocket.close()\n raise e\n```\n\n========================================\n\nCode:\n```py\n@check_route.websocket_route(\"/check\")\nasync def websocket_endpoint(websocket: WebSocket):\n\n await websocket.accept()\n\n redis = Redis(host='::1', port=6379, db=1)\n subscribe = redis.pubsub()\n subscribe.subscribe('websocket_queue')\n\n try:\n for result in subscribe.listen():\n await websocket.send_text('test')\n print('test send')\n except Exception as e:\n await websocket.close()\n raise e\n```\n\n```py\n@check_route.websocket_route(\"/check\")\nasync def websocket_endpoint(websocket: WebSocket):\n\n redis = Redis(host='::1', port=6379, db=1)\n subscribe = redis.pubsub()\n subscribe.subscribe('websocket_queue')\n\n try:\n for result in subscribe.listen():\n await websocket.accept()\n await websocket.send_text('test')\n print('test send')\n except Exception as e:\n await websocket.close()\n raise e\n```\n\n```text\nsubscribe.listen()\n```\n\n```text\nsubscribe.listen()\n```\n\n```text\nwebsocket.accept()\n```\n\n```py\nimport json\nimport aioredis\n\nfrom fastapi import APIRouter, WebSocket\n\nfrom app.service.config_service import load_config\n\ncheck_route = APIRouter()\n\n\n@check_route.websocket(\"/check\")\nasync def websocket_endpoint(websocket: WebSocket):\n\n await websocket.accept()\n\n # ---------------------------- REDIS REQUIREMENTS ---------------------------- #\n config = load_config()\n redis_uri: str = f\"redis://{config.redis.host}:{config.redis.port}\"\n redis_channel = config.redis.redis_socket_queue.channel\n redis = await aioredis.create_redis_pool(redis_uri)\n\n # ------------------ SEND SUBSCRIBE RESULT THROUGH WEBSOCKET ----------------- #\n (channel,) = await redis.subscribe(redis_channel)\n assert isinstance(channel, aioredis.Channel)\n try:\n while True:\n response_raw = await channel.get()\n response_str = response_raw.decode(\"utf-8\")\n response = json.loads(response_str)\n\n if response:\n await websocket.send_json({\n \"event\": 'NEW_CHECK_RESULT',\n \"data\": response\n })\n except Exception as e:\n raise e\n```\n\n```py\nasync def websocket_endpoint(websocket: WebSocket):\n\n await websocket.accept()\n\n redis = Redis(host='::1', port=6379, db=1)\n subscribe = redis.pubsub()\n subscribe.subscribe('websocket_queue')\n\n try:\n results = await subscribe.listen()\n for result in results:\n await websocket.send_text('test')\n print('test send')\n except Exception as e:\n await websocket.close()\n raise e\n```\n\n========================================\n\nComments:\n- Have you tried the given solution?\n- @AbhinavMathur I tried your given solution, but unfortunately this didn't work for me. The `subscribe.listen()` is also not async. I found a solution for this issue and will post the answer down here. Nevertheless thanks for your suggestion anyway.","metadata":{"transformedAt":"2026-08-18T18:32:29.139Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":7,"totalLines":202,"estimatedTokens":1330}}517{"id":"stack-72026739","source":"stackoverflow","questionId":72026739,"title":"FastAPI - Uploading multiple files using Axios raises Bad Request error","tags":["javascript","python","file-upload","axios","fastapi"],"text":"Title: FastAPI - Uploading multiple files using Axios raises Bad Request error\nTags: javascript, python, file-upload, axios, fastapi\nSource: Stack Overflow\n\nQuestion:\nClient code:\n\n```\n!\n\n \n \n \n\n \n \n\nfunction uploadFile() {\n var formData = new FormData();\n var imagefile = document.querySelector('#file');\n formData.append(\"images\", imagefile.files);\n axios.post('http://127.0.0.1:8000/upload', formData, {\n headers: {\n 'Content-Type': 'multipart/form-data'\n }\n })\n}\n\n```\n\nServer code:\n\n```\nfrom fastapi import FastAPI, File, UploadFile, FastAPI\nfrom typing import Optional, List\nfrom fastapi.responses import FileResponse, HTMLResponse\nfrom fastapi.staticfiles import StaticFiles\nfrom fastapi.middleware.cors import CORSMiddleware\n\n...\n\ndef save_file(filename, data):\n with open(filename, 'wb') as f:\n f.write(data)\n print('file saved')\n\n@app.post(\"/upload\")\nasync def upload(files: List[UploadFile] = File(...)):\n print(files)\n for file in files:\n contents = await file.read()\n save_file(file.filename, contents)\n print('file received')\n\n return {\"Uploaded Filenames\": [file.filename for file in files]}\n```\n\nI get the following error:\n\n```\n←[32mINFO←[0m: 127.0.0.1:10406 - \"←[1mPOST /upload HTTP/1.1←[0m\" ←[31m400 Bad Request←[0m\n```\n\nI have tried to upload a single file via form action and all works fine, but I need to upload two files.\n\n========================================\n\nTop Answer:\nStarting from Axios v 0.27.2 you can do this easily:\n\n```\naxios\n .postForm(\"https://httpbin.org/post\", document.querySelector(\"#fileInput\").files)\n```\n\nAll the files will be submitted with `files[]` key.\n\nMore verbose example:\n\n```\naxios.postForm(\"https://httpbin.org/post\", {\n \"myField\": \"foo\"\n \"myJson{}\": {x:1, y: 'bar'}, \n \"files[]\": document.querySelector(\"#fileInput\").files\n })\n```\n\n========================================\n\nCode:\n```html\n!<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <title></title>\n <script src=\"https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js\"></script>\n</head>\n\n<form id=\"uploadForm\" role=\"form\" method=\"post\" enctype=multipart/form-data>\n <input type=\"file\" id=\"file\" name=\"file\" multiple>\n <input type=button value=Upload onclick=\"uploadFile()\">\n</form>\n\n<script type=\"text/javascript\">\nfunction uploadFile() {\n var formData = new FormData();\n var imagefile = document.querySelector('#file');\n formData.append(\"images\", imagefile.files);\n axios.post('http://127.0.0.1:8000/upload', formData, {\n headers: {\n 'Content-Type': 'multipart/form-data'\n }\n })\n}\n</script>\n</body>\n</html>\n```\n\n```text\nfrom fastapi import FastAPI, File, UploadFile, FastAPI\nfrom typing import Optional, List\nfrom fastapi.responses import FileResponse, HTMLResponse\nfrom fastapi.staticfiles import StaticFiles\nfrom fastapi.middleware.cors import CORSMiddleware\n\n...\n\ndef save_file(filename, data):\n with open(filename, 'wb') as f:\n f.write(data)\n print('file saved')\n\n@app.post(\"/upload\")\nasync def upload(files: List[UploadFile] = File(...)):\n print(files)\n for file in files:\n contents = await file.read()\n save_file(file.filename, contents)\n print('file received')\n\n return {\"Uploaded Filenames\": [file.filename for file in files]}\n```\n\n```text\n←[32mINFO←[0m: 127.0.0.1:10406 - \"←[1mPOST /upload HTTP/1.1←[0m\" ←[31m400 Bad Request←[0m\n```\n\n```html\n<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <title>Upload Files</title>\n <script src=\"https://cdnjs.cloudflare.com/ajax/libs/axios/0.27.2/axios.min.js\"></script> \n </head>\n <body>\n <input type=\"file\" id=\"fileInput\" multiple><br>\n <input type=\"button\" value=\"Upload\" onclick=\"uploadFile()\">\n <script type=\"text/javascript\">\n function uploadFile() {\n var fileInput = document.querySelector('#fileInput'); \n \n if (fileInput.files[0]) {\n var formData = new FormData();\n for (const file of fileInput.files)\n formData.append('files', file);\n\n axios({\n method: 'post',\n url: '/upload',\n data: formData,\n headers: {\n 'Accept': 'application/json',\n 'Content-Type': 'multipart/form-data'\n }\n })\n .then(response => {\n console.log(response);\n })\n .catch(error => {\n console.error(error);\n });\n }\n }\n </script>\n </body>\n</html>\n```\n\n```text\nfiles\n```\n\n```text\nimages\n```\n\n```text\nimagefile.files\n```\n\n```text\nFormData\n```\n\n```text\n0.27.1\n```\n\n```text\n0.27.2\n```\n\n```text\nContent-Type\n```\n\n```js\naxios\n .postForm(\"https://httpbin.org/post\", document.querySelector(\"#fileInput\").files)\n```\n\n```js\naxios.postForm(\"https://httpbin.org/post\", {\n \"myField\": \"foo\"\n \"myJson{}\": {x:1, y: 'bar'}, \n \"files[]\": document.querySelector(\"#fileInput\").files\n })\n```\n\n```text\nfiles[]\n```\n\n========================================\n\nComments:\n- You're using `images` as the form key in JS, but `files` in your FastAPI definition. Does the 400 error have a body with more details? Does it work properly with a regular form and ``?","metadata":{"transformedAt":"2026-08-18T18:32:29.140Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":14,"totalLines":241,"estimatedTokens":1367}}518{"id":"stack-79575632","source":"stackoverflow","questionId":79575632,"title":"Why do I get \"GET / HTTP/1.1 404 Not Found\" with FastAPI server?","tags":["python","fastapi","http-status-code-404"],"text":"Title: Why do I get \"GET / HTTP/1.1 404 Not Found\" with FastAPI server?\nTags: python, fastapi, http-status-code-404\nSource: Stack Overflow\n\nQuestion:\nI am trying to create a token with FastAPI:\n\n```\n> import json\n> import os\n> import aiohttp\n> import asyncio\n> from fastapi import FastAPI\n> from fastapi import APIRouter, Request\n> from fastapi.responses import JSONResponse\n> \n> token = APIRouter(prefix=\"/management/api\", tags=[\"API Apl token\"])\n> \n> app=FastAPI()\n> app.include_router(token)\n```\n\nand many methods after...\n\nI got this\n\n```\n> uvicorn peg:token --reload\n> INFO: Will watch for changes in these directories: ['C:\\\\Users\\\\Ejbc25\\\\fastapi']\n> INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\n> INFO: Started reloader process [2232] using StatReload\n> INFO: Started server process [20632]\n> INFO: Waiting for application startup.\n> INFO: Application startup complete.\n> INFO: 127.0.0.1:51183 - \"GET / HTTP/1.1\" 404 Not Found\n> INFO: 127.0.0.1:51183 - \"GET / HTTP/1.1\" 404 Not Found\n```\n\nHow to fix this problem?\n\nI expected that\nhttp://127.0.0.1:8000/token\nwould return token\nbut shows\n\nNot Found\n\n========================================\n\nCode:\n```text\n> import json\n> import os\n> import aiohttp\n> import asyncio\n> from fastapi import FastAPI\n> from fastapi import APIRouter, Request\n> from fastapi.responses import JSONResponse\n> \n> token = APIRouter(prefix=\"/management/api\", tags=[\"API Apl token\"])\n> \n> app=FastAPI()\n> app.include_router(token)\n```\n\n```text\n> uvicorn peg:token --reload\n> INFO: Will watch for changes in these directories: ['C:\\\\Users\\\\Ejbc25\\\\fastapi']\n> INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\n> INFO: Started reloader process [2232] using StatReload\n> INFO: Started server process [20632]\n> INFO: Waiting for application startup.\n> INFO: Application startup complete.\n> INFO: 127.0.0.1:51183 - \"GET / HTTP/1.1\" 404 Not Found\n> INFO: 127.0.0.1:51183 - \"GET / HTTP/1.1\" 404 Not Found\n```\n\n```bash\nuvicorn peg:token --reload\n```\n\n```bash\nuvicorn peg:app --reload\n```\n\n```text\nAPIRouter\n```\n\n```text\ntoken\n```\n\n```text\nuvicorn\n```\n\n```text\nFastAPI\n```\n\n```text\napp\n```\n\n```text\nuvicorn\n```\n\n```text\ntoken\n```\n\n```text\ntoken\n```\n\n```text\nuvicorn\n```\n\n```text\nFastAPI\n```\n\n```text\napp\n```\n\n```text\npeg.py\n```\n\n```text\nuvicorn main:app --reload\n```\n\n```text\nmain.py\n```\n\n========================================\n\nComments:\n- Where is that `token` route defined? Or are you relying on the app picking up the variable name `token`?\n- Also, you have added a `prefix` to your router, i.e., `/management/api`. So that should be `http://127.0.0.1:8000/management/api/whatever`\n- See this and this as well.","metadata":{"transformedAt":"2026-08-18T18:32:29.140Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":18,"totalLines":147,"estimatedTokens":686}}519{"id":"stack-78845218","source":"stackoverflow","questionId":78845218,"title":"FastAPI TestClient not starting lifetime in test","tags":["python","asynchronous","pytest","python-asyncio","fastapi"],"text":"Title: FastAPI TestClient not starting lifetime in test\nTags: python, asynchronous, pytest, python-asyncio, fastapi\nSource: Stack Overflow\n\nQuestion:\nExample code:\n\n```\nimport os\nimport asyncio\nfrom contextlib import asynccontextmanager\nfrom fastapi import FastAPI, Request\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI):\n print(f'Lifetime ON {os.getpid()=}')\n app.state.global_rw = 0\n\n _ = asyncio.create_task(infinite_1(app.state), name='my_task')\n yield \n\napp = FastAPI(lifespan=lifespan)\n\n@app.get(\"/state/\") \nasync def inc(request: Request):\n return {'rw': request.app.state.global_rw}\n\nasync def infinite_1(app_rw_state):\n print('infinite_1 ON')\n while True:\n app_rw_state.global_rw += 1\n print(f'infinite_1 {app_rw_state.global_rw=}')\n await asyncio.sleep(10)\n```\n\nThis is all working fine, every 10 seconds `app.state.global_rw` is increased by one.\n\nTest code:\n\n```\nfrom fastapi.testclient import TestClient\n\ndef test_all():\n from a_10_code import app \n client = TestClient(app)\n\n response = client.get(\"/state/\")\n assert response.status_code == 200\n assert response.json() == {'rw': 0}\n```\n\nProblem that I have found is that TestClient(app) will not start `async def lifespan(app: FastAPI):`.\n\nStarted with `pytest -s a_10_test.py`\n\nSo, how to start lifespan in FastAPI TestClient ?\n\nP.S. my real code is more complex, this is just simple example for demonstration purposes.\n\n========================================\n\nTop Answer:\nI think the problem might be related of an sync/async issue.\n\nSince you're writing an async lifespan, you probably will need to use and async client with the asyncio pytest plugins.\n\nHere I define an async_fixture `get_client`, that allows us to inject an async test client in your test.\n\n```\nimport pytest_asyncio\nimport httpx\nfrom typing import AsyncGenerator\n\n@pytest_asyncio.fixture()\nasync def get_client() -> AsyncGenerator[httpx.AsyncClient]:\n from a_10_code import app\n transport = httpx.ASGITransport(app=app)\n\n async with httpx.AsyncClient(\n transport=transport,\n base_url=\"http://testserver\"\n ) as client:\n yield client\n\nasync def test_all(get_client: httpx.AsyncClient):\n response = await get_client.get(\"/state\")\n assert response.status_code == 200\n assert response.json() == {'rw': 0}\n```\n\nRead more information:\n\n- Httpx\n\n- Pytest Asyncio\n\n========================================\n\nCode:\n```text\nimport os\nimport asyncio\nfrom contextlib import asynccontextmanager\nfrom fastapi import FastAPI, Request\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI):\n print(f'Lifetime ON {os.getpid()=}')\n app.state.global_rw = 0\n\n _ = asyncio.create_task(infinite_1(app.state), name='my_task')\n yield \n\napp = FastAPI(lifespan=lifespan)\n\n@app.get(\"/state/\") \nasync def inc(request: Request):\n return {'rw': request.app.state.global_rw}\n\nasync def infinite_1(app_rw_state):\n print('infinite_1 ON')\n while True:\n app_rw_state.global_rw += 1\n print(f'infinite_1 {app_rw_state.global_rw=}')\n await asyncio.sleep(10)\n```\n\n```text\nfrom fastapi.testclient import TestClient\n\ndef test_all():\n from a_10_code import app \n client = TestClient(app)\n\n response = client.get(\"/state/\")\n assert response.status_code == 200\n assert response.json() == {'rw': 0}\n```\n\n```text\napp.state.global_rw\n```\n\n```text\nasync def lifespan(app: FastAPI):\n```\n\n```text\npytest -s a_10_test.py\n```\n\n```py\nimport pytest_asyncio\nimport pytest\nimport asyncio\n\nfrom fastapi.testclient import TestClient\nfrom fastapi_lifespan import app\n\n@pytest_asyncio.fixture(scope=\"module\")\ndef client():\n with TestClient(app) as client:\n yield client\n\n@pytest.mark.asyncio\nasync def test_state(client):\n response = client.get(\"/state/\")\n assert response.status_code == 200\n assert response.json() == {\"rw\": 1}\n\n await asyncio.sleep(11)\n\n response = client.get(\"/state/\")\n assert response.status_code == 200\n assert response.json() == {'rw': 2}\n```\n\n```text\nglobal_rw\n```\n\n```text\nAsyncClient\n```\n\n```text\nhttpx\n```\n\n```text\npytest_asyncio\n```\n\n```text\nglobal_rw\n```\n\n```text\nconftest.py\n```\n\n```py\nimport pytest_asyncio\nimport httpx\nfrom typing import AsyncGenerator\n\n@pytest_asyncio.fixture()\nasync def get_client() -> AsyncGenerator[httpx.AsyncClient]:\n from a_10_code import app\n transport = httpx.ASGITransport(app=app)\n\n async with httpx.AsyncClient(\n transport=transport,\n base_url=\"http://testserver\"\n ) as client:\n yield client\n\nasync def test_all(get_client: httpx.AsyncClient):\n response = await get_client.get(\"/state\")\n assert response.status_code == 200\n assert response.json() == {'rw': 0}\n```\n\n```text\nget_client\n```\n\n========================================\n\nComments:\n- FYI I got \"ERROR a_10_test_stackOwerflow.py - TypeError: Too few arguments for typing.AsyncGenerator; actual 1, expected 2\"\n- @WebOrCode The given error stems from improper use of hinting type for `AsyncGenerator`, it should be `AsyncGenerator[httpx.AsyncClient, None]`\n- For my test example, you code is working. Did not try it on my real production code, because I started using github.com/testcontainers/testcontainers-python for test. Thanks.","metadata":{"transformedAt":"2026-08-18T18:32:29.140Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":14,"totalLines":233,"estimatedTokens":1292}}520{"id":"stack-66119608","source":"stackoverflow","questionId":66119608,"title":"How to solve asyncpg.exceptions.InvalidAuthorizationSpecificationError","tags":["postgresql","fastapi","asyncpg","tortoise-orm"],"text":"Title: How to solve asyncpg.exceptions.InvalidAuthorizationSpecificationError\nTags: postgresql, fastapi, asyncpg, tortoise-orm\nSource: Stack Overflow\n\nQuestion:\nI'm going through the course Test-Driven Development with FastAPI and Docker from **testdriven.io** and just stucked with releasing my app to heroku (Part 2: Deployment). Everything was fine before I released the image to heroku:\n\n```\nheroku container:release web --app APP_NAME\n```\n\nThen I checked the `https://APP_NAME.herokuapp.com/ping/` endpoint and got\n\n503 Service Unavailable.\n\nNeed help. I found such tracebacks in `heroku logs --tail`:\n\n```\n2021-02-09T12:37:53.995055+00:00 app[web.1]: [2021-02-09 12:37:53 +0000] [27] [ERROR] Application startup failed. Exiting.\n2021-02-09T12:37:53.995458+00:00 app[web.1]: [2021-02-09 12:37:53 +0000] [27] [INFO] Worker exiting (pid: 27)\n2021-02-09T12:37:54.123770+00:00 app[web.1]: [2021-02-09 12:37:54 +0000] [32] [INFO] Booting worker with pid: 32\n2021-02-09T12:37:54.773146+00:00 app[web.1]: [2021-02-09 12:37:54 +0000] [32] [INFO] Started server process [32]\n2021-02-09T12:37:54.773392+00:00 app[web.1]: [2021-02-09 12:37:54 +0000] [32] [INFO] Waiting for application startup.\n2021-02-09T12:37:54.885999+00:00 app[web.1]: [2021-02-09 12:37:54 +0000] [32] [ERROR] Traceback (most recent call last):\n2021-02-09T12:37:54.886001+00:00 app[web.1]: File \"/usr/local/lib/python3.8/site-packages/starlette/routing.py\", line 526, in lifespan\n2021-02-09T12:37:54.886002+00:00 app[web.1]: async for item in self.lifespan_context(app):\n2021-02-09T12:37:54.886003+00:00 app[web.1]: File \"/usr/local/lib/python3.8/site-packages/starlette/routing.py\", line 467, in default_lifespan\n2021-02-09T12:37:54.886004+00:00 app[web.1]: await self.startup()\n2021-02-09T12:37:54.886004+00:00 app[web.1]: File \"/usr/local/lib/python3.8/site-packages/starlette/routing.py\", line 502, in startup\n2021-02-09T12:37:54.886004+00:00 app[web.1]: await handler()\n2021-02-09T12:37:54.886005+00:00 app[web.1]: File \"/usr/local/lib/python3.8/site-packages/tortoise/contrib/fastapi/__init__.py\", line 92, in init_orm\n2021-02-09T12:37:54.886006+00:00 app[web.1]: await Tortoise.init(config=config, config_file=config_file, db_url=db_url, modules=modules)\n2021-02-09T12:37:54.886006+00:00 app[web.1]: File \"/usr/local/lib/python3.8/site-packages/tortoise/__init__.py\", line 567, in init\n2021-02-09T12:37:54.886007+00:00 app[web.1]: await cls._init_connections(connections_config, _create_db)\n2021-02-09T12:37:54.886007+00:00 app[web.1]: File \"/usr/local/lib/python3.8/site-packages/tortoise/__init__.py\", line 385, in _init_connections\n2021-02-09T12:37:54.886008+00:00 app[web.1]: await connection.create_connection(with_db=True)\n2021-02-09T12:37:54.886008+00:00 app[web.1]: File \"/usr/local/lib/python3.8/site-packages/tortoise/backends/asyncpg/client.py\", line 94, in create_connection\n2021-02-09T12:37:54.886009+00:00 app[web.1]: self._pool = await asyncpg.create_pool(None, password=self.password, **self._template)\n2021-02-09T12:37:54.886009+00:00 app[web.1]: File \"/usr/local/lib/python3.8/site-packages/asyncpg/pool.py\", line 398, in _async__init__\n2021-02-09T12:37:54.886010+00:00 app[web.1]: await self._initialize()\n2021-02-09T12:37:54.886010+00:00 app[web.1]: File \"/usr/local/lib/python3.8/site-packages/asyncpg/pool.py\", line 426, in _initialize\n2021-02-09T12:37:54.886010+00:00 app[web.1]: await first_ch.connect()\n2021-02-09T12:37:54.886011+00:00 app[web.1]: File \"/usr/local/lib/python3.8/site-packages/asyncpg/pool.py\", line 125, in connect\n2021-02-09T12:37:54.886011+00:00 app[web.1]: self._con = await self._pool._get_new_connection()\n2021-02-09T12:37:54.886012+00:00 app[web.1]: File \"/usr/local/lib/python3.8/site-packages/asyncpg/pool.py\", line 468, in _get_new_connection\n2021-02-09T12:37:54.886012+00:00 app[web.1]: con = await connection.connect(\n2021-02-09T12:37:54.886012+00:00 app[web.1]: File \"/usr/local/lib/python3.8/site-packages/asyncpg/connection.py\", line 1718, in connect\n2021-02-09T12:37:54.886013+00:00 app[web.1]: return await connect_utils._connect(\n2021-02-09T12:37:54.886013+00:00 app[web.1]: File \"/usr/local/lib/python3.8/site-packages/asyncpg/connect_utils.py\", line 663, in _connect\n2021-02-09T12:37:54.886014+00:00 app[web.1]: con = await _connect_addr(\n2021-02-09T12:37:54.886014+00:00 app[web.1]: File \"/usr/local/lib/python3.8/site-packages/asyncpg/connect_utils.py\", line 642, in _connect_addr\n2021-02-09T12:37:54.886014+00:00 app[web.1]: await asyncio.wait_for(connected, timeout=timeout)\n2021-02-09T12:37:54.886015+00:00 app[web.1]: File \"/usr/local/lib/python3.8/asyncio/tasks.py\", line 491, in wait_for\n2021-02-09T12:37:54.886015+00:00 app[web.1]: return fut.result()\n2021-02-09T12:37:54.886016+00:00 app[web.1]: asyncpg.exceptions.InvalidAuthorizationSpecificationError: no pg_hba.conf entry for host \"XXX.XXX.XXX.XXX\", user \"XXXXXXXXXX\", database \"XXXXXXXXXXXX\", SSL off\n```\n\n========================================\n\nTop Answer:\nSo I ran into the same issue, and after puttering around for a bit, this is how I got it to work. I 100% know there is a better way, but I just wanted to move on.\n\n```\n# project/app/db.py\n\nimport logging\nimport os\nimport ssl # New\n\nfrom fastapi import FastAPI\nfrom tortoise import Tortoise, run_async\nfrom tortoise.contrib.fastapi import register_tortoise\n\nlog = logging.getLogger(\"uvicorn\")\n\n# DB setup\ndb_full_url = os.environ.get(\"DATABASE_URL\") # New\nhost = db_full_url.split(\"//\")[1].split(\":\")[1].split(\"@\")[1] # New\nuser = db_full_url.split(\"//\")[1].split(\":\")[0] # New\npassword = db_full_url.split(\"//\")[1].split(\":\")[1].split(\"@\")[0] # New\ndb = db_full_url.split(\"/\")[3] # New\nctx = ssl.create_default_context() # New\nctx.check_hostname = False # New\nctx.verify_mode = ssl.CERT_NONE # New\n\ndef init_db(app: FastAPI) -> None:\n log.info(\"Initializing DB...\")\n register_tortoise(\n app,\n config={\n 'connections': {\n 'default': {\n 'engine': 'tortoise.backends.asyncpg',\n 'credentials': {\n 'host': host,\n 'port': '5432',\n 'user': user,\n 'password': password,\n 'database': db,\n 'ssl': ctx,\n },\n },\n },\n 'apps': {\n 'models': {\n 'models': [\"app.models.tortoise\"],\n 'default_connection': 'default',\n }\n }\n }\n )\n log.info(db_full_url)\n```\n\n========================================\n\nCode:\n```text\nheroku container:release web --app APP_NAME\n```\n\n```text\n2021-02-09T12:37:53.995055+00:00 app[web.1]: [2021-02-09 12:37:53 +0000] [27] [ERROR] Application startup failed. Exiting.\n2021-02-09T12:37:53.995458+00:00 app[web.1]: [2021-02-09 12:37:53 +0000] [27] [INFO] Worker exiting (pid: 27)\n2021-02-09T12:37:54.123770+00:00 app[web.1]: [2021-02-09 12:37:54 +0000] [32] [INFO] Booting worker with pid: 32\n2021-02-09T12:37:54.773146+00:00 app[web.1]: [2021-02-09 12:37:54 +0000] [32] [INFO] Started server process [32]\n2021-02-09T12:37:54.773392+00:00 app[web.1]: [2021-02-09 12:37:54 +0000] [32] [INFO] Waiting for application startup.\n2021-02-09T12:37:54.885999+00:00 app[web.1]: [2021-02-09 12:37:54 +0000] [32] [ERROR] Traceback (most recent call last):\n2021-02-09T12:37:54.886001+00:00 app[web.1]: File \"/usr/local/lib/python3.8/site-packages/starlette/routing.py\", line 526, in lifespan\n2021-02-09T12:37:54.886002+00:00 app[web.1]: async for item in self.lifespan_context(app):\n2021-02-09T12:37:54.886003+00:00 app[web.1]: File \"/usr/local/lib/python3.8/site-packages/starlette/routing.py\", line 467, in default_lifespan\n2021-02-09T12:37:54.886004+00:00 app[web.1]: await self.startup()\n2021-02-09T12:37:54.886004+00:00 app[web.1]: File \"/usr/local/lib/python3.8/site-packages/starlette/routing.py\", line 502, in startup\n2021-02-09T12:37:54.886004+00:00 app[web.1]: await handler()\n2021-02-09T12:37:54.886005+00:00 app[web.1]: File \"/usr/local/lib/python3.8/site-packages/tortoise/contrib/fastapi/__init__.py\", line 92, in init_orm\n2021-02-09T12:37:54.886006+00:00 app[web.1]: await Tortoise.init(config=config, config_file=config_file, db_url=db_url, modules=modules)\n2021-02-09T12:37:54.886006+00:00 app[web.1]: File \"/usr/local/lib/python3.8/site-packages/tortoise/__init__.py\", line 567, in init\n2021-02-09T12:37:54.886007+00:00 app[web.1]: await cls._init_connections(connections_config, _create_db)\n2021-02-09T12:37:54.886007+00:00 app[web.1]: File \"/usr/local/lib/python3.8/site-packages/tortoise/__init__.py\", line 385, in _init_connections\n2021-02-09T12:37:54.886008+00:00 app[web.1]: await connection.create_connection(with_db=True)\n2021-02-09T12:37:54.886008+00:00 app[web.1]: File \"/usr/local/lib/python3.8/site-packages/tortoise/backends/asyncpg/client.py\", line 94, in create_connection\n2021-02-09T12:37:54.886009+00:00 app[web.1]: self._pool = await asyncpg.create_pool(None, password=self.password, **self._template)\n2021-02-09T12:37:54.886009+00:00 app[web.1]: File \"/usr/local/lib/python3.8/site-packages/asyncpg/pool.py\", line 398, in _async__init__\n2021-02-09T12:37:54.886010+00:00 app[web.1]: await self._initialize()\n2021-02-09T12:37:54.886010+00:00 app[web.1]: File \"/usr/local/lib/python3.8/site-packages/asyncpg/pool.py\", line 426, in _initialize\n2021-02-09T12:37:54.886010+00:00 app[web.1]: await first_ch.connect()\n2021-02-09T12:37:54.886011+00:00 app[web.1]: File \"/usr/local/lib/python3.8/site-packages/asyncpg/pool.py\", line 125, in connect\n2021-02-09T12:37:54.886011+00:00 app[web.1]: self._con = await self._pool._get_new_connection()\n2021-02-09T12:37:54.886012+00:00 app[web.1]: File \"/usr/local/lib/python3.8/site-packages/asyncpg/pool.py\", line 468, in _get_new_connection\n2021-02-09T12:37:54.886012+00:00 app[web.1]: con = await connection.connect(\n2021-02-09T12:37:54.886012+00:00 app[web.1]: File \"/usr/local/lib/python3.8/site-packages/asyncpg/connection.py\", line 1718, in connect\n2021-02-09T12:37:54.886013+00:00 app[web.1]: return await connect_utils._connect(\n2021-02-09T12:37:54.886013+00:00 app[web.1]: File \"/usr/local/lib/python3.8/site-packages/asyncpg/connect_utils.py\", line 663, in _connect\n2021-02-09T12:37:54.886014+00:00 app[web.1]: con = await _connect_addr(\n2021-02-09T12:37:54.886014+00:00 app[web.1]: File \"/usr/local/lib/python3.8/site-packages/asyncpg/connect_utils.py\", line 642, in _connect_addr\n2021-02-09T12:37:54.886014+00:00 app[web.1]: await asyncio.wait_for(connected, timeout=timeout)\n2021-02-09T12:37:54.886015+00:00 app[web.1]: File \"/usr/local/lib/python3.8/asyncio/tasks.py\", line 491, in wait_for\n2021-02-09T12:37:54.886015+00:00 app[web.1]: return fut.result()\n2021-02-09T12:37:54.886016+00:00 app[web.1]: asyncpg.exceptions.InvalidAuthorizationSpecificationError: no pg_hba.conf entry for host \"XXX.XXX.XXX.XXX\", user \"XXXXXXXXXX\", database \"XXXXXXXXXXXX\", SSL off\n```\n\n```text\nhttps://APP_NAME.herokuapp.com/ping/\n```\n\n```text\nheroku logs --tail\n```\n\n```text\nasyncpg==0.22.0\nfastapi==0.63.0\nrequests==2.25.1\ntortoise-orm==0.16.21\n```\n\n```text\n# project/app/db.py\n\nimport logging\nimport os\nimport ssl # New\n\nfrom fastapi import FastAPI\nfrom tortoise import Tortoise, run_async\nfrom tortoise.contrib.fastapi import register_tortoise\n\nlog = logging.getLogger(\"uvicorn\")\n\n# DB setup\ndb_full_url = os.environ.get(\"DATABASE_URL\") # New\nhost = db_full_url.split(\"//\")[1].split(\":\")[1].split(\"@\")[1] # New\nuser = db_full_url.split(\"//\")[1].split(\":\")[0] # New\npassword = db_full_url.split(\"//\")[1].split(\":\")[1].split(\"@\")[0] # New\ndb = db_full_url.split(\"/\")[3] # New\nctx = ssl.create_default_context() # New\nctx.check_hostname = False # New\nctx.verify_mode = ssl.CERT_NONE # New\n\n\ndef init_db(app: FastAPI) -> None:\n log.info(\"Initializing DB...\")\n register_tortoise(\n app,\n config={\n 'connections': {\n 'default': {\n 'engine': 'tortoise.backends.asyncpg',\n 'credentials': {\n 'host': host,\n 'port': '5432',\n 'user': user,\n 'password': password,\n 'database': db,\n 'ssl': ctx,\n },\n },\n },\n 'apps': {\n 'models': {\n 'models': [\"app.models.tortoise\"],\n 'default_connection': 'default',\n }\n }\n }\n )\n log.info(db_full_url)\n```\n\n========================================\n\nComments:\n- Have a look at this and this\n- Thank you very much!! However, to move on I had to add such config into the `generate_schema()` too, replacing the `modules={\"models\": [\"app.models.tortoise\"]}` with `modules={\"models\": [\"models.tortoise\"]}`. Don't ask me why Idk, but it works now...","metadata":{"transformedAt":"2026-08-18T18:32:29.140Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":6,"totalLines":234,"estimatedTokens":3135}}521{"id":"stack-72681390","source":"stackoverflow","questionId":72681390,"title":"How to upload a file from React frontend to FastAPI?","tags":["reactjs","file-upload","axios","multipartform-data","fastapi"],"text":"Title: How to upload a file from React frontend to FastAPI?\nTags: reactjs, file-upload, axios, multipartform-data, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm trying to upload a file from React frontend to FastAPI backend. The code I used is as shown below.\n\nThis is the FastAPI backend:\n\n```\n@app.post(\"/uploadfile\")\nasync def create_upload_file(file: UploadFile = File(...)):\n return {\"filename\": file.filename}\n```\n\nThis is the frontend:\n\n```\nconst [file, uploadFile] = useState(null)\n\n//when upload button clicked\nfunction handleSubmit(){\n console.log(file[0].name)\n const formdata = new FormData();\n formdata.append(\n \"file\",\n file[0],\n )\n axios.post(\"/uploadfile\", {\n file:formdata}, {\n \"Content-Type\": \"multipart/form-data\",\n })\n .then(function (response) {\n console.log(response); //\"dear user, please check etc...\"\n });\n \n }\n\n// this is when file has been selected\n function handleChange(e){\n uploadFile(e.target.files); //store uploaded file in \"file\" variable with useState\n }\n```\n\nIt returns a `422 (Unprocessable Entity)`. Here's the message `detail` from axios:\n\nhttps://i.sstatic.net/ISGQX.png\n\nI am not quite familiar with the rules and format needed behind file uploading. Could someone clear my confusion?\n\n========================================\n\nTop Answer:\nThis was helpful for me finding a bug in my code. I suspect your problem was nesting the `formData` inside another object in your first attempt: `axios.post(\"/uploadfile\", {file:formdata} ...` should be `axios.post(\"/uploadfile\", formdata ...`.\n\nFor me, the trick was ensuring that the key to the `formData.append` exactly matches the name of the `UploadFile` parameter for my FastAPI endpoint.\n\nIn this example the name is `file123`.\n\nIn the React code you have:\n\n```\nformdata.append(\"file123\", file[0])\naxios.post(\"/uploadfile\", formdata ...etc...\n```\n\nAnd in the Python code you have:\n\n```\nasync def create_upload_file(file123: UploadFile = File(...)): ...etc...\n```\n\n========================================\n\nCode:\n```py\n@app.post(\"/uploadfile\")\nasync def create_upload_file(file: UploadFile = File(...)):\n return {\"filename\": file.filename}\n```\n\n```js\nconst [file, uploadFile] = useState(null)\n\n//when upload button clicked\nfunction handleSubmit(){\n console.log(file[0].name)\n const formdata = new FormData();\n formdata.append(\n \"file\",\n file[0],\n )\n axios.post(\"/uploadfile\", {\n file:formdata}, {\n \"Content-Type\": \"multipart/form-data\",\n })\n .then(function (response) {\n console.log(response); //\"dear user, please check etc...\"\n });\n \n }\n\n// this is when file has been selected\n function handleChange(e){\n uploadFile(e.target.files); //store uploaded file in \"file\" variable with useState\n }\n```\n\n```text\n422 (Unprocessable Entity)\n```\n\n```text\ndetail\n```\n\n```text\nconst headers={'Content-Type': file[0].type}\nawait axios.post(\"/uploadfile\",formdata,headers)\n .then()//etc\n```\n\n```text\nformdata.append(\"file123\", file[0])\naxios.post(\"/uploadfile\", formdata ...etc...\n```\n\n```text\nasync def create_upload_file(file123: UploadFile = File(...)): ...etc...\n```\n\n```text\nformData\n```\n\n```text\naxios.post(\"/uploadfile\", {file:formdata} ...\n```\n\n```text\naxios.post(\"/uploadfile\", formdata ...\n```\n\n```text\nformData.append\n```\n\n```text\nUploadFile\n```\n\n```text\nfile123\n```\n\n```py\nfrom fastapi import File, UploadFile, Request, FastAPI, HTTPException\nfrom fastapi.templating import Jinja2Templates\nimport aiofiles\n\napp = FastAPI()\ntemplates = Jinja2Templates(directory=\"templates\")\n\n\n@app.post(\"/upload\")\nasync def upload(file: UploadFile = File(...)):\n try:\n contents = await file.read()\n async with aiofiles.open(file.filename, 'wb') as f:\n await f.write(contents)\n except Exception:\n raise HTTPException(status_code=500, detail='Something went wrong')\n finally:\n await file.close()\n\n return {\"message\": f\"Successfuly uploaded {file.filename}\"}\n\n\n@app.get(\"/\")\ndef main(request: Request):\n return templates.TemplateResponse(\"index.html\", {\"request\": request})\n```\n\n```html\n<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <title>Upload File</title>\n </head>\n <body>\n <input type=\"file\" id=\"fileInput\"><br>\n <input type=\"button\" value=\"Upload\" onclick=\"uploadFile()\">\n <script type=\"text/javascript\">\n function uploadFile() {\n var file = document.getElementById('fileInput').files[0];\n \n if (file) {\n var formData = new FormData();\n formData.append('file', file);\n \n fetch('/upload', {\n method: 'POST',\n body: formData,\n })\n .then(response => {\n console.log(response);\n })\n .catch(error => {\n console.error(error);\n });\n }\n }\n </script>\n </body>\n</html>\n```\n\n```html\n<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <title>Upload File</title>\n <script src=\"https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js\"></script> \n </head>\n <body>\n <input type=\"file\" id=\"fileInput\"><br>\n <input type=\"button\" value=\"Upload\" onclick=\"uploadFile()\">\n <script type=\"text/javascript\">\n function uploadFile() {\n var file = document.getElementById('fileInput').files[0];\n \n if (file) {\n var formData = new FormData();\n formData.append('file', file);\n \n axios({\n method: 'post',\n url: '/upload',\n data: formData,\n headers: {\n 'Accept': 'application/json',\n 'Content-Type': 'multipart/form-data'\n }\n })\n .then(response => {\n console.log(response);\n })\n .catch(error => {\n console.error(error);\n });\n }\n }\n </script>\n </body>\n</html>\n```\n\n```js\naxios.post('/upload', formData, {\n headers: {\n 'Content-Type': 'multipart/form-data'\n }\n })\n .then((response) => {\n console.log(response);\n })\n .catch((error) => {\n console.log(error);\n });\n```\n\n```text\n<form>\n```\n\n```text\nfetch\n```\n\n```text\naxios\n```\n\n```text\nUploadFile\n```\n\n```text\nfetch\n```\n\n```text\naxios\n```\n\n```text\naxios\n```\n\n========================================\n\nComments:\n- Related answers can be found here, as well as here and here\n- This was helpful for me. I think the key is ensuring that the key to the form data matches the `UploadFIle` parameter for you FastAPI endpoint. In this case the key is `file`. In the react code you have: formdata.append( \"file\", file[0], ) And in the Python code you have: ``` async def create_upload_file(file: UploadFile = File(...)): ```\n- Axios will replace the `content-type` header with the appropriate values for the `FormData` instance. There is no need to manually construct it","metadata":{"transformedAt":"2026-08-18T18:32:29.140Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":24,"totalLines":309,"estimatedTokens":1830}}522{"id":"stack-78110125","source":"stackoverflow","questionId":78110125,"title":"How to dynamically create FastAPI routes/handlers for a list of Pydantic models?","tags":["python","fastapi","url-routing","pydantic","starlette"],"text":"Title: How to dynamically create FastAPI routes/handlers for a list of Pydantic models?\nTags: python, fastapi, url-routing, pydantic, starlette\nSource: Stack Overflow\n\nQuestion:\nI have a problem using FastAPI, trying to dynamically define routes. It seems that the final route/handler defined overrides all the previous ones (see image below)\n\nSituation: I have a lot of Pydantic models as a list (imported from `models.py`: simplified in example), and would like to create a GET endpoint for each model.\n\nSomething like this (my app is more complex — there is a reason it is structured as it is — but I've simplified it down to this, in order to find the problem, which still occurs):\n\n```\n# models.py\n\nclass Thing(BaseNode):\n value: str\n\nclass Other(BaseNode):\n value: str\n\nmodel_list = [Thing, Other]\n\n# app.py\nfrom models import model_list\n\napp = FastApi()\n\n# Iterate over the models list and define a get function\nfor model in models_list:\n\n @app.get(f\"/{model.__name__.lower()}\")\n def get() -> str:\n print(model.__name__)\n return f\"Getting {model.__name__)\n```\n\nhttps://i.sstatic.net/Gmh0U.png\n\nI'm obviously doing something wrong (or FastAPI references the handler function in some weird way... by module/function name(?) so the get() function is being re-defined for each iteration?) Any ideas, or better way to structure this? (I can't manually write out a new function for each model!)\n\nThanks!\n\nUPDATE:\nUpdate:\n\nIf I define the `get()` function inside another function, it works:\n\n```\nfor model in models_list:\n def get(model):\n def _get():\n print(\"Getting\", model)\n \n return f\"Getting {model.__name__}\"\n return _get\n\n app.get(.get(f\"/{model.__name__.lower()}\", name=f\"{model.__name__}.View\")(get(model))\n```\n\n========================================\n\nCode:\n```py\n# models.py\n\nclass Thing(BaseNode):\n value: str\n\nclass Other(BaseNode):\n value: str\n\nmodel_list = [Thing, Other]\n\n\n\n# app.py\nfrom models import model_list\n\napp = FastApi()\n\n\n# Iterate over the models list and define a get function\nfor model in models_list:\n\n @app.get(f\"/{model.__name__.lower()}\")\n def get() -> str:\n print(model.__name__)\n return f\"Getting {model.__name__)\n```\n\n```py\nfor model in models_list:\n def get(model):\n def _get():\n print(\"Getting\", model)\n \n return f\"Getting {model.__name__}\"\n return _get\n\n app.get(.get(f\"/{model.__name__.lower()}\", name=f\"{model.__name__}.View\")(get(model))\n```\n\n```text\nmodels.py\n```\n\n```text\nget()\n```\n\n```py\nfrom fastapi import FastAPI, APIRouter, Request\nfrom pydantic import BaseModel\n\n\nclass One(BaseModel):\n value: str\n\n\nclass Two(BaseModel):\n value: str\n\n\napp = FastAPI()\nmodels = [One, Two]\n\n\ndef create_endpoint(m_name: str):\n async def endpoint(request: Request):\n print(request.url)\n return f\"You called {m_name}\"\n return endpoint\n\n\nfor m in models: \n app.add_api_route(f\"/{m.__name__.lower()}\", create_endpoint(m.__name__), methods=[\"GET\"])\n```\n\n```text\nmodel\n```\n\n========================================\n\nComments:\n- please add the missing imports so that this code can run. Currently it does not run.\n- Also my guess would be that in the first example you're defining a function with the same name multiple times, which might result in some weird behavior. In the second example you do the same thing, but before it gets overwritten you are storing it. Can't test without runnable code though, just a theory.\n- How would you do for POST/PATCH methods that would take data corresponding to each model as input. (the equivalent to `def myroute_one(data: One, request: Request`) ? And also, how would you define the response model for such endpoints ?\n- @ibi0tux Please have a look at the implementation of `add_api_route()` - it should be straightforward. For instance, see `methods` and `response_class` parameters.","metadata":{"transformedAt":"2026-08-18T18:32:29.140Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":6,"totalLines":149,"estimatedTokens":969}}523{"id":"stack-78017822","source":"stackoverflow","questionId":78017822,"title":"No overloads for \"update\" match the provided arguments","tags":["python","fastapi","python-typing","pyright"],"text":"Title: No overloads for \"update\" match the provided arguments\nTags: python, fastapi, python-typing, pyright\nSource: Stack Overflow\n\nQuestion:\nI'm currently reading FastAPI's tutorial user guide and pylance is throwing the following warning:\n\nNo overloads for \"update\" match the provided argumentsPylancereportCallIssue\n\ntyping.pyi(690, 9): Overload 2 is the closest match\n\nHere is the code that is throwing the warning:\n\n```\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/items/\")\nasync def read_items(q: str | None = None):\n results = {\"items\": [{\"item_id\": \"Foo\"}, {\"item_id\": \"Bar\"}]}\n if q:\n results.update({\"q\": q}) # warning here\n return results\n```\n\nI tried changing `Python › Analysis: Type Checking Mode` to `basic` and using the Pre-Release version of Pylance but warning persists.\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/items/\")\nasync def read_items(q: str | None = None):\n results = {\"items\": [{\"item_id\": \"Foo\"}, {\"item_id\": \"Bar\"}]}\n if q:\n results.update({\"q\": q}) # warning here\n return results\n```\n\n```text\nPython › Analysis: Type Checking Mode\n```\n\n```text\nbasic\n```\n\n```py\nfoo = {\"foo\": [\"bar\"]}\nfoo[\"bar\"] = \"baz\"\n```\n\n```py\nfrom typing import Any, TypedDict, NotRequired\n\nclass Possible(TypedDict):\n foo: list[str]\n bar: NotRequired[str]\n\nfoo: dict[str, Any] = {\"foo\": [\"bar\"]}\nfoo: dict[str, object] = {\"foo\": [\"bar\"]}\nfoo: dict[str, list[str] | str] = {\"foo\": [\"bar\"]}\nfoo: Possible = {\"foo\": [\"bar\"]}\n```\n\n```py\n@app.get(\"/items/\")\nasync def read_items(q: str | None = None):\n results: dict[str, object] = {\"items\": [{\"item_id\": \"Foo\"}, {\"item_id\": \"Bar\"}]}\n if q:\n results.update({\"q\": q}) # warning here\n return results\n```\n\n```py\nclass MutableMapping(Mapping[_KT, _VT]):\n ... # More methods\n \n @overload\n def update(self, __m: SupportsKeysAndGetItem[_KT, _VT], **kwargs: _VT) -> None: ...\n @overload\n def update(self, __m: Iterable[tuple[_KT, _VT]], **kwargs: _VT) -> None: ...\n @overload\n def update(self, **kwargs: _VT) -> None: ...\n```\n\n```text\nmypy\n```\n\n```text\npylance\n```\n\n```text\nmypy\n```\n\n```text\nfoo\n```\n\n```text\ndict[str, list[str]]\n```\n\n```text\nreveal_type\n```\n\n```text\nstr\n```\n\n```text\nlist[str]\n```\n\n```text\nobject\n```\n\n```text\nPossible\n```\n\n```text\nTypedDict\n```\n\n```text\nAny\n```\n\n```text\nobject\n```\n\n```text\nAny\n```\n\n```text\ndict[str, int | str]\n```\n\n```text\nMutableMapping.update\n```\n\n```text\ndict\n```\n\n```text\nMutableMapping\n```\n\n========================================\n\nComments:\n- Since you copied the code straight from the documentation, I suspect this is an issue with the type hints in FastAPI.\n- @Barmar no, this has nothing to do with FastAPI typing - they obviously do not provide `dict.update` type hints.\n- For reference, here's how Pyright sees the same piece of code.\n- Oh, @InSync thanks! I know that Pylance uses Pyright under the hood, do errors pass through unchanged?\n- I just created a new project in VSCode to check, and it seems that Pylance added the \"Overload 2 is the closest match\" part. Either that, or Pyright could emit such a message, but only for a specific kind of LSP request not used in the online playground.\n- Regarding the \"Overload 2 is the closest match\" part, it's expected.","metadata":{"transformedAt":"2026-08-18T18:32:29.140Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":25,"totalLines":172,"estimatedTokens":826}}524{"id":"stack-73911250","source":"stackoverflow","questionId":73911250,"title":"How to render CSS/JS/Images along with HTML file in FastAPI?","tags":["python","html","fastapi","starlette"],"text":"Title: How to render CSS/JS/Images along with HTML file in FastAPI?\nTags: python, html, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nI am facing an issue while rendering the HTMl file in FastAPI.\n\n**main.py file**\n\n```\nstatic_dir = os.path.join(os.path.dirname(__file__), \"static\")\napp.mount(\"/\",StaticFiles(directory=static_dir, html=True),name=\"static\")\n\n@app.get(\"/\")\nasync def index():\n return FileResponse('index.html', media_type='text/html')\n```\n\nWhile running the above file using uvicorn I am able to render the HTML file at http://127.0.0.1:8765/, but the static files, such as css, js and images, are not getting rendered.\n\n**index.html**: some code of HTML File (which is build from Angular JS)\n\n```\n\n test\n \n\n```\n\n**File Structure:**\n\n```\nmodulename\n - static\n - index.html\n - styles.87afad25367d1df4.css\n - runtime.7f95ee6540776f88.js\n - polyfills.a246e584d5c017d7.js\n - main.4f51d0f81827a3db.js\n \n - main.py \n - __init__.py\n```\n\nWhen I open the browser console it show like below:\nhttps://i.sstatic.net/iNpvY.png\n\nThe CSS/js should be render without static included in it e.g. http://127.0.0.1:8765/styles.87afad25367d1df4.css but it run on browser it loads from http://127.0.0.1:8765/static/styles.87afad25367d1df4.css.\n\nI am not sure how to fix this any help will be appreciated.\n\n**Update: Adding below code to explain it better**\n\n**main.py**\n\n```\nimport uvicorn\nimport os\nimport webbrowser\nfrom fastapi import FastAPI\nfrom fastapi.responses import FileResponse\nfrom fastapi.staticfiles import StaticFiles\nfrom fastapi.middleware.cors import CORSMiddleware\nfrom fastapi.responses import HTMLResponse\n\napp = FastAPI(\n title=\"UI\",\n description=\"This is to test\",\n)\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=['*'],\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n\nstatic_dir = os.path.join(os.path.dirname(__file__), \"static\")\napp.mount(\"/\",StaticFiles(directory=static_dir, html=True),name=\"static\")\n\ndef start_server():\n # print('Starting Server...') \n\n uvicorn.run(\n \"ui.main:app\",\n host=\"0.0.0.0\",\n port=8765,\n log_level=\"debug\",\n reload=True,\n )\n # webbrowser.open(\"http://127.0.0.1:8765/\")\n\nif __name__ == \"__main__\":\n start_server()\n```\n\nRunning this file as package/module in test.py file:\n\n```\nfrom ui import main\n\nif __name__ == \"__main__\":\n main.start_server()\n```\n\n**index.html:**\n\n```\n\n \n \n WingmanUi\n \n \n \n\n This is to test \n\n```\n\n**File structure:**\n\n```\nui\n - static\n - index.html\n - styles.87afad25367d1df4.css\n - runtime.7f95ee6540776f88.js\n - polyfills.a246e584d5c017d7.js\n - main.4f51d0f81827a3db.js\n \n - main.py \n - __init__.py\n```\n\n========================================\n\nCode:\n```text\nstatic_dir = os.path.join(os.path.dirname(__file__), \"static\")\napp.mount(\"/\",StaticFiles(directory=static_dir, html=True),name=\"static\")\n\n@app.get(\"/\")\nasync def index():\n return FileResponse('index.html', media_type='text/html')\n```\n\n```text\n<link rel=\"stylesheet\" href=\"styles.87afad25367d1df4.css\" media=\"print\" onload=\"this.media='all'\"><noscript>\n<link rel=\"stylesheet\" href=\"styles.87afad25367d1df4.css\"></noscript></head>\n<body class=\"cui\">\n test\n <app-root></app-root>\n<script src=\"runtime.7f95ee6540776f88.js\" type=\"module\"></script>\n<script src=\"polyfills.a246e584d5c017d7.js\" type=\"module\"></script>\n<script src=\"main.4f51d0f81827a3db.js\" type=\"module\"></script>\n\n</body></html>\n```\n\n```text\nmodulename\n - static\n - index.html\n - styles.87afad25367d1df4.css\n - runtime.7f95ee6540776f88.js\n - polyfills.a246e584d5c017d7.js\n - main.4f51d0f81827a3db.js\n \n - main.py \n - __init__.py\n```\n\n```text\nimport uvicorn\nimport os\nimport webbrowser\nfrom fastapi import FastAPI\nfrom fastapi.responses import FileResponse\nfrom fastapi.staticfiles import StaticFiles\nfrom fastapi.middleware.cors import CORSMiddleware\nfrom fastapi.responses import HTMLResponse\n\napp = FastAPI(\n title=\"UI\",\n description=\"This is to test\",\n)\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=['*'],\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n\nstatic_dir = os.path.join(os.path.dirname(__file__), \"static\")\napp.mount(\"/\",StaticFiles(directory=static_dir, html=True),name=\"static\")\n\ndef start_server():\n # print('Starting Server...') \n\n uvicorn.run(\n \"ui.main:app\",\n host=\"0.0.0.0\",\n port=8765,\n log_level=\"debug\",\n reload=True,\n )\n # webbrowser.open(\"http://127.0.0.1:8765/\")\n\nif __name__ == \"__main__\":\n start_server()\n```\n\n```text\nfrom ui import main\n\nif __name__ == \"__main__\":\n main.start_server()\n```\n\n```text\n<!DOCTYPE html><html lang=\"en\">\n <head>\n <meta charset=\"utf-8\">\n <title>WingmanUi</title>\n <base href=\"static/\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n \n\n<link rel=\"icon\" type=\"image/x-icon\" href=\"favicon.ico\">\n<link rel=\"stylesheet\" href=\"styles.87afad25367d1df4.css\" media=\"print\" onload=\"this.media='all'\">\n</head>\n<body>\n This is to test \n<script src=\"runtime.7f95ee6540776f88.js\" type=\"module\"></script>\n<script src=\"polyfills.a246e584d5c017d7.js\" type=\"module\"></script>\n<script src=\"main.4f51d0f81827a3db.js\" type=\"module\"></script>\n\n</body>\n</html>\n```\n\n```text\nui\n - static\n - index.html\n - styles.87afad25367d1df4.css\n - runtime.7f95ee6540776f88.js\n - polyfills.a246e584d5c017d7.js\n - main.4f51d0f81827a3db.js\n \n - main.py \n - __init__.py\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.staticfiles import StaticFiles\n\napp = FastAPI()\n\napp.mount('/static', StaticFiles(directory='static', html=True), name='static')\n```\n\n```html\n<script src=\"someScript.js\"></script>\n```\n\n```html\n<script src=\"static/someScript.js\"></script>\n```\n\n```html\n<base href=\"static/\">\n```\n\n```text\nStaticFiles\n```\n\n```text\nhtml\n```\n\n```text\nTrue\n```\n\n```text\nhtml=True\n```\n\n```text\nindex.html\n```\n\n```text\nStaticFiles\n```\n\n```text\nStaticFiles\n```\n\n```text\ndirectory='static'\n```\n\n```text\nstatic\n```\n\n```text\nStaticFiles\n```\n\n```text\n/\n```\n\n```text\napp.mount('/', ...\n```\n\n```text\nStaticFiles\n```\n\n```text\n/static\n```\n\n```text\napp.mount('/static', ...)\n```\n\n```text\nStaticFiles\n```\n\n```text\n/\n```\n\n```text\nstatic\n```\n\n```text\nhttp://127.0.0.1:8000/static/someScript.js\n```\n\n```text\n<base>\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.140Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":31,"totalLines":358,"estimatedTokens":1568}}525{"id":"stack-73724304","source":"stackoverflow","questionId":73724304,"title":"How to display a bytes type image in HTML/Jinja2 template using FastAPI?","tags":["python","html","base64","jinja2","fastapi"],"text":"Title: How to display a bytes type image in HTML/Jinja2 template using FastAPI?\nTags: python, html, base64, jinja2, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have a FastAPI app that gets an image from an API. This image is stored in a variable with type: `bytes`.\n\nI want to display the image in HTML/Jinja2 template (without having to download it). I followed many tutorials but couldn't find the solution.\n\nHere is what I came up with so far:\n\n```\n@app.get(\"/{id}\")\nasync def root(request: Request, id: str):\n picture = await get_online_person()\n\n data = base64.b64encode(picture) # convert to base64 as bytes\n data = data.decode() # convert bytes to string\n\n # str_equivalent_image = base64.b64encode(img_buffer.getvalue()).decode()\n img_tag = ''.format(data)\n return templates.TemplateResponse(\n \"index.html\", {\"request\": request, \"img\": img_tag}\n )\n```\n\nAll I get in the HTML is this: (as text on the page, not from source code)\n\n```\nNote: For people who are marking my question to a duplicate talking about urllib, I cannot use `urllib` because the image I'm getting is from ana API, and using their direct url will result in a 403 Forbidden, so I should use their python API to get the image.\n\n========================================\n\nCode:\n```text\n@app.get(\"/{id}\")\nasync def root(request: Request, id: str):\n picture = await get_online_person()\n\n data = base64.b64encode(picture) # convert to base64 as bytes\n data = data.decode() # convert bytes to string\n\n # str_equivalent_image = base64.b64encode(img_buffer.getvalue()).decode()\n img_tag = '<img src=\"data:image/png;base64,{}\">'.format(data)\n return templates.TemplateResponse(\n \"index.html\", {\"request\": request, \"img\": img_tag}\n )\n```\n\n```text\n<img src=\"data:image/png;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQICAQECAQEBAgICAgICAgICAQICAgICAgICAgL/2wBDAQEBAQEBAQEBAQECAQEBAgICAgI\nCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgL/wgARCAQABAADASIAA\nhEBAxEB/8QAHgAAAQUBAQEBAQAAAAAAAAAABQIDBAYHAQgACQr/xAAcAQACAwEBAQEAAAAAAAAAAAACAwABBAUGBwj/2gAMAwEAAhADEAAAAfEpwSR+a+9IPR3c7347iwscmWyYchEIJjn+MbJj/c4FFbbb9J5....................\n```\n\n```text\nbytes\n```\n\n```text\nurllib\n```\n\n```py\n# ...\nbase64_encoded_image = base64.b64encode(image_bytes).decode(\"utf-8\")\nreturn templates.TemplateResponse(\"index.html\", {\"request\": request, \"myImage\": base64_encoded_image})\n```\n\n```html\n<img src=\"data:image/jpeg;base64,{{ myImage | safe }}\">\n```\n\n```text\nTemplateResponse\n```\n\n```text\n<img>\n```\n\n========================================\n\nComments:\n- I tried this tutorial: blog.furas.pl/… but I get the error `'bytes' object has no attribute 'getvalue'`\n- Does this answer your question? Why does parsing a webpage with beautiful soup leads to src attributes of images with values as base64 strings?\n- No it does not, because in my case I cannot use urllib (please check my explanation in the edit above). Thank you.","metadata":{"transformedAt":"2026-08-18T18:32:29.140Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":8,"totalLines":87,"estimatedTokens":741}}526{"id":"stack-77584118","source":"stackoverflow","questionId":77584118,"title":"Python FastAPI: How to return a Response with Unicode or non-ASCII characters encoded into JSON or CSV data?","tags":["python","json","csv","character-encoding","fastapi"],"text":"Title: Python FastAPI: How to return a Response with Unicode or non-ASCII characters encoded into JSON or CSV data?\nTags: python, json, csv, character-encoding, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am creating a FastAPI application that triggers file downloading through the `StreamingResponse` class (see FastAPI docs). This part is actually ok.\n\nMy problem is that when the file contains accent (e.g., é) or another special character, it seems to not encode it well.\n\nFor example, when there is a `é`, in a CSV it will be transformed to `é`, and in a JSON to `\\u00e9`.\n\nMy code looks something like this:\n\n- For JSON\n\n```\n# API CONTENT\n# ...\n\nreturn StreamingResponse(io.StringIO(json.dumps(data)), headers={\"Content-Disposition\": \"filename=filename.json\")\n```\n\n- For CSV\n\n```\n# API CONTENT\n# ...\n\nreturn StreamingResponse(io.StringIO(pandas.DataFrame(data).to_csv(index=False)), headers={\"Content-Disposition\": f\"filename=filename.csv\"})\n```\n\nIn order to fix the encoding, I also tried to:\n\nAdd `media_type=\"text/csv; charset=utf-8\"` in the CSV part but without success.\n\nAdd `\"Content-Type\": \"application/octet-stream; charset=utf-8\"` in the header part but without success too.\n\nTried to replace `StreamingResponse` by `Response` .\n\nHas somebody already faced this kind of problem? I would like to note that the content before adding it to `StreamingResponse` is well encoded.\n\nHere is a sample of code to test:\n\n```\nfrom fastapi import FastAPI\nfrom fastapi.responses import StreamingResponse\nimport pandas as pd\nimport io\nimport json\n\napp = FastAPI()\n\ndata = [\n {\"éète\": \"test\", \"age\": 10},\n {\"éète\": \"test2\", \"age\": 5},\n]\n\n@app.get(\"/download_json\")\nasync def download_json():\n return StreamingResponse(io.StringIO(json.dumps(data)), headers={\"Content-Disposition\": \"filename=data.json\"})\n\n@app.get(\"/download_csv\")\nasync def download_csv():\n return StreamingResponse(io.StringIO(pd.DataFrame(data).to_csv(index=False)), headers={\"Content-Disposition\": \"filename=data.csv\"})```\n```\n\n========================================\n\nCode:\n```text\n# API CONTENT\n# ...\n\nreturn StreamingResponse(io.StringIO(json.dumps(data)), headers={\"Content-Disposition\": \"filename=filename.json\")\n```\n\n```text\n# API CONTENT\n# ...\n\nreturn StreamingResponse(io.StringIO(pandas.DataFrame(data).to_csv(index=False)), headers={\"Content-Disposition\": f\"filename=filename.csv\"})\n```\n\n```text\nfrom fastapi import FastAPI\nfrom fastapi.responses import StreamingResponse\nimport pandas as pd\nimport io\nimport json\n\napp = FastAPI()\n\ndata = [\n {\"éète\": \"test\", \"age\": 10},\n {\"éète\": \"test2\", \"age\": 5},\n]\n\n@app.get(\"/download_json\")\nasync def download_json():\n return StreamingResponse(io.StringIO(json.dumps(data)), headers={\"Content-Disposition\": \"filename=data.json\"})\n\n@app.get(\"/download_csv\")\nasync def download_csv():\n return StreamingResponse(io.StringIO(pd.DataFrame(data).to_csv(index=False)), headers={\"Content-Disposition\": \"filename=data.csv\"})```\n```\n\n```text\nStreamingResponse\n```\n\n```text\né\n```\n\n```text\né\n```\n\n```text\n\\u00e9\n```\n\n```text\nmedia_type=\"text/csv; charset=utf-8\"\n```\n\n```text\n\"Content-Type\": \"application/octet-stream; charset=utf-8\"\n```\n\n```text\nStreamingResponse\n```\n\n```text\nResponse\n```\n\n```text\nStreamingResponse\n```\n\n```text\nheaders = {'Content-Disposition': 'inline; filename=\"out.json\"'}\n```\n\n```text\nheaders = {'Content-Disposition': 'attachment; filename=\"out.json\"'}\n```\n\n```py\nfrom fastapi import FastAPI, Response\nimport pandas as pd\nimport json\n\n\napp = FastAPI()\n\n\n# Exemple de données avec des caractères spéciaux\ndata = [\n {\"éète\": \"test\", \"age\": 10},\n {\"éète\": \"test2\", \"age\": 5},\n]\n\n \n@app.get(\"/1\")\ndef get_json():\n headers = {\"Content-Disposition\": 'inline; filename=\"out.json\"'}\n return Response(\n json.dumps(data, ensure_ascii=False),\n headers=headers,\n media_type=\"application/json\",\n )\n\n\n@app.get(\"/2\")\ndef get_json_from_df():\n headers = {\"Content-Disposition\": 'inline; filename=\"out.json\"'}\n return Response(\n pd.DataFrame(data).to_json(orient=\"records\", force_ascii=False),\n headers=headers,\n media_type=\"application/json\",\n )\n\n\n# Note: \"text/csv\" would force the browser to download the data, regardless\n# of specifying `inline` in the `Content-Disposition` header.\n# Use `media_type=\"text/plain\"` instead, in order to view the data in the browser.\n@app.get(\"/3\")\ndef get_csv_from_df():\n headers = {\"Content-Disposition\": 'inline; filename=\"out.csv\"'}\n return Response(\n pd.DataFrame(data).to_csv(index=False, encoding=\"utf-8\"),\n headers=headers,\n media_type=\"text/csv; charset=utf-8\",\n )\n```\n\n```py\n@app.get(\"/3\")\ndef get_csv_from_df():\n headers = {\"Content-Disposition\": 'attachment; filename=\"out.csv\"'}\n return Response(\n (u'\\uFEFF' + pd.DataFrame(data).to_csv(index=False, sep='\\t', encoding=\"utf-16\")).encode('utf-16'),\n headers=headers,\n media_type=\"text/csv; charset=utf-16\",\n )\n```\n\n```py\nfrom fastapi import BackgroundTasks, HTTPException\nfrom fastapi.responses import FileResponse\nfrom tempfile import NamedTemporaryFile\nimport csv\nimport os\n\n@app.get(\"/4\")\ndef get_csv(background_tasks: BackgroundTasks):\n headers = {\"Content-Disposition\": 'attachment; filename=\"out.csv\"'}\n temp = NamedTemporaryFile(delete=False, mode='w', encoding='utf-16', newline='')\n try:\n with temp as f:\n keys = data[0].keys()\n w = csv.DictWriter(f, fieldnames=keys, delimiter='\\t')\n w.writeheader()\n w.writerows(data)\n except Exception:\n os.remove(temp.name)\n raise HTTPException(detail='There was an error processing the data', status_code=400)\n\n background_tasks.add_task(os.remove, temp.name)\n return FileResponse(temp.name, headers=headers, media_type='text/csv; charset=utf-16')\n```\n\n```py\nfrom fastapi import HTTPException\nfrom tempfile import NamedTemporaryFile\nimport csv\nimport os\n\n@app.get(\"/5\")\ndef get_csv():\n headers = {\"Content-Disposition\": 'attachment; filename=\"out.csv\"'}\n temp = NamedTemporaryFile(delete=False, mode='w+', encoding='utf-16', newline='')\n try:\n keys = data[0].keys()\n w = csv.DictWriter(temp, fieldnames=keys, delimiter='\\t')\n w.writeheader()\n w.writerows(data)\n temp.seek(0)\n return Response(temp.read().encode('utf-16'), headers=headers, media_type='text/csv; charset=utf-16')\n except Exception:\n raise HTTPException(detail='There was an error processing the data', status_code=400)\n finally:\n temp.close()\n os.remove(temp.name)\n```\n\n```text\njson\n```\n\n```text\n\\u\n```\n\n```text\nensure_ascii\n```\n\n```text\njson.dumps()\n```\n\n```text\nFalse\n```\n\n```text\nto_json()\n```\n\n```text\nto_csv()\n```\n\n```text\nforce_ascii=False\n```\n\n```text\nencoding='utf-8'\n```\n\n```text\nencoding='utf-8'\n```\n\n```text\nto_csv()\n```\n\n```text\nStreamingResponse\n```\n\n```text\nResponse\n```\n\n```text\njson\n```\n\n```text\nContent-Disposition\n```\n\n```text\n/3\n```\n\n```text\nutf-8\n```\n\n```text\né\n```\n\n```text\nè\n```\n\n```text\n\\uFEFF\n```\n\n```text\nutf-16\n```\n\n```text\nutf-16-le\n```\n\n```text\nutf-8\n```\n\n```text\nutf-16\n```\n\n```text\nutf-8\n```\n\n```text\n\\t\n```\n\n```text\nsep='\\t'\n```\n\n```text\n,\n```\n\n```text\n;\n```\n\n```text\ncsv\n```\n\n```text\ncsv\n```\n\n```text\nNamedTemporaryFile\n```\n\n```text\n.seek(0)\n```\n\n```text\nUnicode\n```\n\n```text\nUTF-16 LE BOM\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\njson\n```\n\n```text\ncsv\n```\n\n```text\nNamedTemporaryFile\n```\n\n```text\nasync def\n```\n\n```text\nawait\n```\n\n```text\nasync\n```\n\n```text\ndef\n```\n\n```text\nThreadPool\n```\n\n```text\nawait\n```\n\n```text\nasync def\n```\n\n```text\nawait\n```\n\n```text\nasync\n```\n\n```text\nawait\n```\n\n```text\nasync\n```\n\n```text\nNamedTemporaryFile\n```\n\n```text\naiofiles\n```\n\n```text\nasync def\n```\n\n```text\njson.dumps()\n```\n\n```text\nPandas.DataFrame.to_csv()\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.140Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":74,"totalLines":482,"estimatedTokens":1956}}527{"id":"stack-75167317","source":"stackoverflow","questionId":75167317,"title":"Make Pydantic BaseModel fields optional including sub-models for PATCH","tags":["python","fastapi","crud","pydantic"],"text":"Title: Make Pydantic BaseModel fields optional including sub-models for PATCH\nTags: python, fastapi, crud, pydantic\nSource: Stack Overflow\n\nQuestion:\nAs already asked in ***similar*** questions, I want to support `PATCH` operations for a FastApi application where the caller can specify as many or as few fields as they like, of a Pydantic `BaseModel` ***with sub-models***, so that efficient `PATCH` operations can be performed, without the caller having to supply an entire valid model just in order to update two or three of the fields.\n\nI've discovered there are ***2 steps*** in Pydantic `PATCH` from the tutorial that ***don't support sub-models***. However, Pydantic is far too good for me to criticise it for something that it seems can be built using the tools that Pydantic provides. This question is to request implementation of those 2 things ***while also supporting sub-models***:\n\n- generate a new DRY `BaseModel` with all fields optional\n\n- implement deep copy with update of `BaseModel`\n\nThese problems are already recognised by Pydantic.\n\n- There is discussion of a class based solution to the optional model\n\n- And there two issues open on the deep copy with update\n\nA ***similar*** question has been asked one or two times here on SO and there are some great answers with different approaches to generating an all-fields optional version of the nested `BaseModel`. After considering them all this particular answer by Ziur Olpa seemed to me to be the best, providing a function that takes the existing model with optional and mandatory fields, and returning a new model with *all fields optional*: https://stackoverflow.com/a/72365032\n\nThe beauty of this approach is that you can hide the (actually quite compact) little function in a library and just use it as a dependency so that it appears in-line in the path operation function and there's no other code or boilerplate.\n\nBut the implementation provided in the previous answer did not take the step of dealing with sub-objects in the `BaseModel` being patched.\n\n**This question therefore requests an improved implementation of the all-fields-optional function that also deals with sub-objects, as well as a deep copy with update.**\n\nI have a simple example as a demonstration of this use-case, which although aiming to be simple for demonstration purposes, also includes a number of fields to more closely reflect the real world examples we see. Hopefully this example provides a test scenario for implementations, saving work:\n\n```\nimport logging\nfrom datetime import datetime, date\n\nfrom collections import defaultdict\nfrom pydantic import BaseModel\nfrom fastapi import FastAPI, HTTPException, status, Depends\nfrom fastapi.encoders import jsonable_encoder\n\napp = FastAPI(title=\"PATCH demo\")\nlogging.basicConfig(level=logging.DEBUG)\n\nclass Collection:\n collection = defaultdict(dict)\n\n def __init__(self, this, that):\n logging.debug(\"-\".join((this, that)))\n self.this = this\n self.that = that\n\n def get_document(self):\n document = self.collection[self.this].get(self.that)\n if not document:\n raise HTTPException(\n status_code=status.HTTP_404_NOT_FOUND,\n detail=\"Not Found\",\n )\n logging.debug(document)\n return document\n\n def save_document(self, document):\n logging.debug(document)\n self.collection[self.this][self.that] = document\n return document\n\nclass SubOne(BaseModel):\n original: date\n verified: str = \"\"\n source: str = \"\"\n incurred: str = \"\"\n reason: str = \"\"\n attachments: list[str] = []\n\nclass SubTwo(BaseModel):\n this: str\n that: str\n amount: float\n plan_code: str = \"\"\n plan_name: str = \"\"\n plan_type: str = \"\"\n meta_a: str = \"\"\n meta_b: str = \"\"\n meta_c: str = \"\"\n\nclass Document(BaseModel):\n this: str\n that: str\n created: datetime\n updated: datetime\n\n sub_one: SubOne\n sub_two: SubTwo\n\n the_code: str = \"\"\n the_status: str = \"\"\n the_type: str = \"\"\n phase: str = \"\"\n process: str = \"\"\n option: str = \"\"\n\n@app.get(\"/endpoint/{this}/{that}\", response_model=Document)\nasync def get_submission(this: str, that: str) -> Document:\n\n collection = Collection(this=this, that=that)\n return collection.get_document()\n\n@app.put(\"/endpoint/{this}/{that}\", response_model=Document)\nasync def put_submission(this: str, that: str, document: Document) -> Document:\n\n collection = Collection(this=this, that=that)\n return collection.save_document(jsonable_encoder(document))\n\n@app.patch(\"/endpoint/{this}/{that}\", response_model=Document)\nasync def patch_submission(\n document: Document,\n # document: optional(Document), # Document:\n\n collection = Collection(this=this, that=that)\n existing = collection.get_document()\n existing = Document(**existing)\n update = document.dict(exclude_unset=True)\n updated = existing.copy(update=update, deep=True) # This example is a working FastAPI application, following the tutorial, and can be run with `uvicorn example:app --reload`. Except it doesn't work, because there's no all-optional fields model, and Pydantic's deep copy with update actually ***overwrites*** sub-models rather than ***updating*** them.\n\nIn order to test it the following Bash script can be used to run `curl` requests. Again I'm supplying this just to hopefully make it easier to get started with this question.\nJust comment out the other commands each time you run it so that the command you want is used.\nTo demonstrate this initial state of the example app working you would run `GET` (expect 404), `PUT` (document stored), `GET` (expect 200 and same document returned), `PATCH` (expect 200), `GET` (expect 200 and updated document returned).\n\n```\nhost='http://127.0.0.1:8000'\npath=\"/endpoint/A123/B456\"\n\nmethod='PUT'\ndata='\n{\n\"this\":\"A123\",\n\"that\":\"B456\",\n\"created\":\"2022-12-01T01:02:03.456\",\n\"updated\":\"2023-01-01T01:02:03.456\",\n\"sub_one\":{\"original\":\"2022-12-12\",\"verified\":\"Y\"},\n\"sub_two\":{\"this\":\"A123\",\"that\":\"B456\",\"amount\":0.88,\"plan_code\":\"HELLO\"},\n\"the_code\":\"BYE\"}\n'\n\n# method='PATCH'\n# data='{\"this\":\"A123\",\"that\":\"B456\",\"created\":\"2022-12-01T01:02:03.456\",\"updated\":\"2023-01-02T03:04:05.678\",\"sub_one\":{\"original\":\"2022-12-12\",\"verified\":\"N\"},\"sub_two\":{\"this\":\"A123\",\"that\":\"B456\",\"amount\":123.456}}' \n\nmethod='GET'\ndata=''\n\nif [[ -n data ]]; then data=\" --data '$data'\"; fi\ncurl=\"curl -K curlrc -X $method '$host$path' $data\"\necho $curl >&2\neval $curl\n```\n\nThis `curlrc` will need to be co-located to ensure the content type headers are correct:\n\n```\n--cookie \"_cookies\"\n--cookie-jar \"_cookies\"\n--header \"Content-Type: application/json\"\n--header \"Accept: application/json\"\n--header \"Accept-Encoding: compress, gzip\"\n--header \"Cache-Control: no-cache\"\n```\n\nSo what I'm looking for is the implementation of `optional` that is commented out in the code, and a fix for `existing.copy` with the `update` parameter, that will enable this example to be used with `PATCH` calls that omit otherwise mandatory fields.\nThe implementation does not have to conform precisely to the commented out line, I just provided that based on Ziur Olpa's previous answer.\n\n========================================\n\nCode:\n```text\nimport logging\nfrom datetime import datetime, date\n\nfrom collections import defaultdict\nfrom pydantic import BaseModel\nfrom fastapi import FastAPI, HTTPException, status, Depends\nfrom fastapi.encoders import jsonable_encoder\n\napp = FastAPI(title=\"PATCH demo\")\nlogging.basicConfig(level=logging.DEBUG)\n\n\nclass Collection:\n collection = defaultdict(dict)\n\n def __init__(self, this, that):\n logging.debug(\"-\".join((this, that)))\n self.this = this\n self.that = that\n\n def get_document(self):\n document = self.collection[self.this].get(self.that)\n if not document:\n raise HTTPException(\n status_code=status.HTTP_404_NOT_FOUND,\n detail=\"Not Found\",\n )\n logging.debug(document)\n return document\n\n def save_document(self, document):\n logging.debug(document)\n self.collection[self.this][self.that] = document\n return document\n\n\nclass SubOne(BaseModel):\n original: date\n verified: str = \"\"\n source: str = \"\"\n incurred: str = \"\"\n reason: str = \"\"\n attachments: list[str] = []\n\n\nclass SubTwo(BaseModel):\n this: str\n that: str\n amount: float\n plan_code: str = \"\"\n plan_name: str = \"\"\n plan_type: str = \"\"\n meta_a: str = \"\"\n meta_b: str = \"\"\n meta_c: str = \"\"\n\n\nclass Document(BaseModel):\n this: str\n that: str\n created: datetime\n updated: datetime\n\n sub_one: SubOne\n sub_two: SubTwo\n\n the_code: str = \"\"\n the_status: str = \"\"\n the_type: str = \"\"\n phase: str = \"\"\n process: str = \"\"\n option: str = \"\"\n\n\n@app.get(\"/endpoint/{this}/{that}\", response_model=Document)\nasync def get_submission(this: str, that: str) -> Document:\n\n collection = Collection(this=this, that=that)\n return collection.get_document()\n\n\n@app.put(\"/endpoint/{this}/{that}\", response_model=Document)\nasync def put_submission(this: str, that: str, document: Document) -> Document:\n\n collection = Collection(this=this, that=that)\n return collection.save_document(jsonable_encoder(document))\n\n\n@app.patch(\"/endpoint/{this}/{that}\", response_model=Document)\nasync def patch_submission(\n document: Document,\n # document: optional(Document), # <<< IMPLEMENT optional <<<\n this: str,\n that: str,\n) -> Document:\n\n collection = Collection(this=this, that=that)\n existing = collection.get_document()\n existing = Document(**existing)\n update = document.dict(exclude_unset=True)\n updated = existing.copy(update=update, deep=True) # <<< FIX THIS <<<\n updated = jsonable_encoder(updated)\n collection.save_document(updated)\n return updated\n```\n\n```text\nhost='http://127.0.0.1:8000'\npath=\"/endpoint/A123/B456\"\n\nmethod='PUT'\ndata='\n{\n\"this\":\"A123\",\n\"that\":\"B456\",\n\"created\":\"2022-12-01T01:02:03.456\",\n\"updated\":\"2023-01-01T01:02:03.456\",\n\"sub_one\":{\"original\":\"2022-12-12\",\"verified\":\"Y\"},\n\"sub_two\":{\"this\":\"A123\",\"that\":\"B456\",\"amount\":0.88,\"plan_code\":\"HELLO\"},\n\"the_code\":\"BYE\"}\n'\n\n# method='PATCH'\n# data='{\"this\":\"A123\",\"that\":\"B456\",\"created\":\"2022-12-01T01:02:03.456\",\"updated\":\"2023-01-02T03:04:05.678\",\"sub_one\":{\"original\":\"2022-12-12\",\"verified\":\"N\"},\"sub_two\":{\"this\":\"A123\",\"that\":\"B456\",\"amount\":123.456}}' \n\nmethod='GET'\ndata=''\n\nif [[ -n data ]]; then data=\" --data '$data'\"; fi\ncurl=\"curl -K curlrc -X $method '$host$path' $data\"\necho $curl >&2\neval $curl\n```\n\n```text\n--cookie \"_cookies\"\n--cookie-jar \"_cookies\"\n--header \"Content-Type: application/json\"\n--header \"Accept: application/json\"\n--header \"Accept-Encoding: compress, gzip\"\n--header \"Cache-Control: no-cache\"\n```\n\n```text\nPATCH\n```\n\n```text\nBaseModel\n```\n\n```text\nPATCH\n```\n\n```text\nPATCH\n```\n\n```text\nBaseModel\n```\n\n```text\nBaseModel\n```\n\n```text\nBaseModel\n```\n\n```text\nBaseModel\n```\n\n```text\nuvicorn example:app --reload\n```\n\n```text\ncurl\n```\n\n```text\nGET\n```\n\n```text\nPUT\n```\n\n```text\nGET\n```\n\n```text\nPATCH\n```\n\n```text\nGET\n```\n\n```text\ncurlrc\n```\n\n```text\noptional\n```\n\n```text\nexisting.copy\n```\n\n```text\nupdate\n```\n\n```text\nPATCH\n```\n\n```text\nimport logging\nfrom typing import Optional, Type\nfrom datetime import datetime, date\nfrom functools import lru_cache\n\nfrom pydantic import BaseModel, create_model\n\nfrom collections import defaultdict\nfrom pydantic import BaseModel\nfrom fastapi import FastAPI, HTTPException, status, Depends, Body\nfrom fastapi.encoders import jsonable_encoder\n\napp = FastAPI(title=\"Nested model PATCH demo\")\nlogging.basicConfig(level=logging.DEBUG)\n\n\nclass Collection:\n collection = defaultdict(dict)\n\n def __init__(self, this, that):\n logging.debug(\"-\".join((this, that)))\n self.this = this\n self.that = that\n\n def get_document(self):\n document = self.collection[self.this].get(self.that)\n if not document:\n raise HTTPException(\n status_code=status.HTTP_404_NOT_FOUND,\n detail=\"Not Found\",\n )\n logging.debug(document)\n return document\n\n def save_document(self, document):\n logging.debug(document)\n self.collection[self.this][self.that] = document\n return document\n\n\nclass SubOne(BaseModel):\n original: date\n verified: str = \"\"\n source: str = \"\"\n incurred: str = \"\"\n reason: str = \"\"\n attachments: list[str] = []\n\n\nclass SubTwo(BaseModel):\n this: str\n that: str\n amount: float\n plan_code: str = \"\"\n plan_name: str = \"\"\n plan_type: str = \"\"\n meta_a: str = \"\"\n meta_b: str = \"\"\n meta_c: str = \"\"\n\nclass SubThree(BaseModel):\n one: str = \"\"\n two: str = \"\"\n\n\nclass Document(BaseModel):\n this: str\n that: str\n created: datetime\n updated: datetime\n\n sub_one: SubOne\n sub_two: SubTwo\n # sub_three: dict[str, SubThree] = {} # Hah hah not really\n\n the_code: str = \"\"\n the_status: str = \"\"\n the_type: str = \"\"\n phase: str = \"\"\n process: str = \"\"\n option: str = \"\"\n\n\n@lru_cache\ndef partial(baseclass: Type[BaseModel]) -> Type[BaseModel]:\n \"\"\"Make all fields in supplied Pydantic BaseModel Optional, for use in PATCH calls.\n\n Iterate over fields of baseclass, descend into sub-classes, convert fields to Optional and return new model.\n Cache newly created model with lru_cache to ensure it's only created once.\n Use with Body to generate the partial model on the fly, in the PATCH path operation function.\n\n - https://stackoverflow.com/questions/75167317/make-pydantic-basemodel-fields-optional-including-sub-models-for-patch\n - https://stackoverflow.com/questions/67699451/make-every-fields-as-optional-with-pydantic\n - https://github.com/pydantic/pydantic/discussions/3089\n - https://fastapi.tiangolo.com/tutorial/body-updates/#partial-updates-with-patch\n \"\"\"\n fields = {}\n for name, field in baseclass.__fields__.items():\n type_ = field.type_\n if type_.__base__ is BaseModel:\n fields[name] = (Optional[partial(type_)], {})\n else:\n fields[name] = (Optional[type_], None) if field.required else (type_, field.default)\n # https://docs.pydantic.dev/usage/models/#dynamic-model-creation\n validators = {\"__validators__\": baseclass.__validators__}\n return create_model(baseclass.__name__ + \"Partial\", **fields, __validators__=validators)\n\n\ndef merge(original, update):\n \"\"\"Update original nested dict with values from update retaining original values that are missing in update.\n\n - https://github.com/pydantic/pydantic/issues/3785\n - https://github.com/pydantic/pydantic/issues/4177\n - https://docs.pydantic.dev/usage/exporting_models/#modelcopy\n - https://github.com/pydantic/pydantic/blob/main/pydantic/main.py#L353\n \"\"\"\n for key in update:\n if key in original:\n if isinstance(original[key], dict) and isinstance(update[key], dict):\n merge(original[key], update[key])\n elif isinstance(original[key], list) and isinstance(update[key], list):\n original[key].extend(update[key])\n else:\n original[key] = update[key]\n else:\n original[key] = update[key]\n return original\n\n\n@app.get(\"/endpoint/{this}/{that}\", response_model=Document)\nasync def get_submission(this: str, that: str) -> Document:\n\n collection = Collection(this=this, that=that)\n return collection.get_document()\n\n\n@app.put(\"/endpoint/{this}/{that}\", response_model=Document)\nasync def put_submission(this: str, that: str, document: Document) -> Document:\n\n collection = Collection(this=this, that=that)\n return collection.save_document(jsonable_encoder(document))\n\n\n@app.patch(\"/endpoint/{this}/{that}\", response_model=Document)\nasync def patch_submission(\n this: str,\n that: str,\n document: partial(Document), # <<< IMPLEMENTED partial TO MAKE ALL FIELDS Optional <<<\n) -> Document:\n\n collection = Collection(this=this, that=that)\n existing_document = collection.get_document()\n incoming_document = document.dict(exclude_unset=True)\n # VVV IMPLEMENTED merge INSTEAD OF USING BROKEN PYDANTIC copy WITH update VVV\n updated_document = jsonable_encoder(merge(existing_document, incoming_document))\n collection.save_document(updated_document)\n return updated_document\n```\n\n```text\nOptional\n```\n\n```text\nBaseModel\n```\n\n```text\nPATCH\n```\n\n```text\nBaseModel.copy\n```\n\n```text\nupdate\n```\n\n```text\ndict\n```\n\n```text\nlist\n```\n\n```text\nset\n```\n\n```text\nBaseModel\n```\n\n```text\ndict\n```\n\n```text\n**\n```\n\n```text\nPATCH\n```\n\n```text\nBaseModel.copy\n```\n\n```text\nPATCH\n```\n\n```text\nPATCH\n```\n\n```text\npartial\n```\n\n```text\nmerge\n```\n\n```text\npartial\n```\n\n```text\noptional\n```\n\n```text\npartial\n```\n\n```text\nBaseModel\n```\n\n```text\nBaseModel\n```\n\n```text\nOptional\n```\n\n```text\nmerge\n```\n\n```text\nBaseModel\n```\n\n```text\nBaseModel\n```\n\n```text\ndict\n```\n\n```text\nmerge\n```\n\n```text\ndict\n```\n\n```text\ndict\n```\n\n========================================\n\nComments:\n- Consider making this a feature request on the pydantic project: github.com/pydantic/pydantic I agree, this problem is oft repeated, there should be some library code to help solve this for you.\n- Also, this Q contains a lot of information, hard to understand the essence of what you're asking with that info overload. Is it possible to simplify the Q? Are you looking simply for a recursive \"make fields optional\" function?\n- Thanks @YaakovBressler I appreciate the feedback. Actually I've been working with Zuir_Olpa from the original question and I formulated the question as I was working through it starting with his answer. It is too wordy for sure, and I actually have an implementation already based on Ziur_Olpa 's answer. It's simple enough to almost fit in a comment, but I've discovered along the way that there are further problems with other Pydantic components in order to implement the sub-model PATCH that I'm after. I will try to improve the question.\n- Question improved @YaakovBressler: removed additional confusing question from the end, clarified Pydantic problems to solve. Of course the code makes it longer but I hope the code clarifies the use-case and provides a way to get started on the solution.\n- it is not pickle-able. How could we make it pickle-able?\n- I don't normally use `pickle` @Gibbs but AFAI do K there's nothing special about the data transfer itself, it's just relying on the standard FastAPI JSON serialisation. But `pickle` can handle a lot more variety than JSON. I can't image what your problem is. Perhaps I'm not clear what you mean when you say \"it\", but it sounds like you may need to ask a separate question.","metadata":{"transformedAt":"2026-08-18T18:32:29.141Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":54,"totalLines":684,"estimatedTokens":4636}}528{"id":"stack-75448722","source":"stackoverflow","questionId":75448722,"title":"Is it possible to have a required query parameter with a default value on FastAPI?","tags":["python","swagger","fastapi","openapi"],"text":"Title: Is it possible to have a required query parameter with a default value on FastAPI?\nTags: python, swagger, fastapi, openapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to make a query parameter required but give it a default value on FastAPI, but i am not finding anything on their user guide.\n\nOn openapi, it would be something like this:\n\n```\nparameters:\n - name: \"some_name\"\n in: \"query\"\n description: \"a description\"\n required: true\n type: \"string\"\n default: \"First\"\n enum:\n - \"First\"\n - \"Second\"\n - \"Third\"\n```\n\nas you can see required is assigned to true and i have a default value (\"first\")\nWith fastapi i have this:\n\n```\nclass ModelNames(str, Enum):\n first = \"first\"\n second = \"second\"\n third = \"third\"\n\n@app.post(\"/path\")\nasync def this_function(\n modelInstance = Query(\n default=Required, # i would like to somehow assign \"first\" and Required to default \n description=\"a description\"\n )\n ):\n return None\n```\n\nI've tried directly assigning \"first\" but it makes it optional.\n\n========================================\n\nCode:\n```text\nparameters:\n - name: \"some_name\"\n in: \"query\"\n description: \"a description\"\n required: true\n type: \"string\"\n default: \"First\"\n enum:\n - \"First\"\n - \"Second\"\n - \"Third\"\n```\n\n```text\nclass ModelNames(str, Enum):\n first = \"first\"\n second = \"second\"\n third = \"third\"\n\n\n@app.post(\"/path\")\nasync def this_function(\n modelInstance = Query(\n default=Required, # i would like to somehow assign \"first\" and Required to default \n description=\"a description\"\n )\n ):\n return None\n```\n\n========================================\n\nComments:\n- Could you clarify, why do you need a default on required parameter? What behavior do you expect? Could example data be more appropriate for your usage case? fastapi.tiangolo.com/tutorial/schema-extra-example\n- @pavel-vergeev i have a web app that was created years ago with close to no documentation and it's not running, the app uses an api that was created using some old libraries and we couldn't find the versions that were used, so i am trying to create an api that behaves exactly the same because it will be time consuming to dig in the application's code and change the calls. So i am trying to have the default values that were on the old api but still have them required.\n- In OpenAPI, required parameters cannot have a default value. Default value is for optional parameters only. If you want to have a pre-selected value in Swagger UI, add an `example` value instead, as @PavelVergeev suggested.\n- @mazs What do you want to happen if someone doesnt pass in any value for that query parameter?\n- @TomMcLean if no value is assigned, the default value is sent\n- @mazs Whats wrong with having a default value?\n- If you can choose to not pass a query parameter (and thereby get the default value), that's kind of the definition of an optional parameter?\n- @M.O. but you can't assign \"None\" to it, so it's not really optional.\n- @TomMcLean that's the thing, i want a default value.\n- @mazs So what you really want is a field where you can either pass no value, or a value but it cant be None? Because you can do that...\n- I see, i thought that there may be a way. Thank you","metadata":{"transformedAt":"2026-08-18T18:32:29.141Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":2,"totalLines":92,"estimatedTokens":811}}529{"id":"stack-71650452","source":"stackoverflow","questionId":71650452,"title":"Use FastAPI to parse incoming POST request from Slack","tags":["python","slack","fastapi","slack-api","slack-commands"],"text":"Title: Use FastAPI to parse incoming POST request from Slack\nTags: python, slack, fastapi, slack-api, slack-commands\nSource: Stack Overflow\n\nQuestion:\nI'm building a FastAPI server to receive requests sent by slack slash command. Using the code below, I could see that the following:\n\n```\ntoken=BLAHBLAH&team_id=BLAHBLAH&team_domain=myteam&channel_id=BLAHBLAH&channel_name=testme&user_id=BLAH&user_name=myname&command=%2Fwhatever&text=test&api_app_id=BLAHBLAH&is_enterprise_install=false&response_url=https%3A%2F%2Fhooks.slack.com%2Fcommands%BLAHBLAH&trigger_id=BLAHBLAHBLAH\n```\n\nwas printed, which is exactly the payload I saw in the official docs. I'm trying to use the payload information to do something, and I'm curious whether there's a great way of parsing this payload info. I can definitely parse this payload using the `split()` function or any other beautiful functions, but I'm curious whether there is a \"de facto\" way of dealing with slack payload. Thanks in advance!\n\n```\nfrom fastapi import FastAPI, Request\n\napp = FastAPI()\n\n@app.post(\"/\")\nasync def root(request: Request):\n request_body = await request.body()\n print(request_body)\n```\n\n========================================\n\nCode:\n```text\ntoken=BLAHBLAH&team_id=BLAHBLAH&team_domain=myteam&channel_id=BLAHBLAH&channel_name=testme&user_id=BLAH&user_name=myname&command=%2Fwhatever&text=test&api_app_id=BLAHBLAH&is_enterprise_install=false&response_url=https%3A%2F%2Fhooks.slack.com%2Fcommands%BLAHBLAH&trigger_id=BLAHBLAHBLAH\n```\n\n```py\nfrom fastapi import FastAPI, Request\n\napp = FastAPI()\n\n@app.post(\"/\")\nasync def root(request: Request):\n request_body = await request.body()\n print(request_body)\n```\n\n```text\nsplit()\n```\n\n```py\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\n\n\nclass Item(BaseModel):\n token: str\n team_id: str\n team_domain: str\n # etc.\n\n\napp = FastAPI()\n\n\n@app.post(\"/\")\ndef root(item: Item):\n print(item.model_dump()) # convert into dict (if required)\n return item\n```\n\n```py\n{\n \"token\": \"gIkuvaNzQIHg97ATvDxqgjtO\"\n \"team_id\": \"Foo\",\n \"team_domain\": \"bar\",\n # etc.\n}\n```\n\n```py\nfrom fastapi import Form\n\n@app.post(\"/\")\ndef root(token: str = Form(...), team_id: str = Form(...), team_domain: str = Form(...)):\n return {\"token\": token, \"team_id\": team_id, \"team_domain\": team_domain}\n```\n\n```py\nfrom dataclasses import dataclass\nfrom fastapi import FastAPI, Form, Depends\n\n@dataclass\nclass Item:\n token: str = Form(...)\n team_id: str = Form(...)\n team_domain: str = Form(...)\n #...\n\n\napp = FastAPI()\n\n\n@app.post(\"/\")\ndef root(data: Item = Depends()):\n return data\n```\n\n```py\nfrom fastapi import FastAPI, Form, Depends\nfrom pydantic import BaseModel\n\n\nclass Item(BaseModel):\n token: str\n team_id: str\n team_domain: str\n #...\n\n\napp = FastAPI()\n\n\n@app.post(\"/\")\ndef root(data: Item = Form()):\n return data\n```\n\n```text\nJSON\n```\n\n```text\nJSON\n```\n\n```text\nJSON\n```\n\n```text\ndict()\n```\n\n```text\nmodel_dump()\n```\n\n```text\nForm\n```\n\n```text\nForm\n```\n\n```text\nForm\n```\n\n```text\nForm\n```\n\n```text\nForm\n```\n\n```text\n@dataclass\n```\n\n```text\nForm\n```\n\n```text\nForm\n```\n\n```text\n@dataclass\n```\n\n```text\nrequest.json()\n```\n\n```text\nrequest.form()\n```\n\n```text\nJSON\n```\n\n```text\nform-data\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.141Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":26,"totalLines":195,"estimatedTokens":812}}530{"id":"stack-73830400","source":"stackoverflow","questionId":73830400,"title":"Context Function error while using Jinja2 when trying to build templates","tags":["html","jinja2","fastapi"],"text":"Title: Context Function error while using Jinja2 when trying to build templates\nTags: html, jinja2, fastapi\nSource: Stack Overflow\n\nQuestion:\nIm following ChristopherGS's tutorial for FASTapi but i'm stuck on part 6 because I believe his syntax may be already deprecated.\n\nI get `AttributeError: module 'jinja2' has no attribute 'contextfunction` at the end when the program stops. How do I solve this, I've been stuck here for 3 days.\n\nThis is my code:\n\n```\nfrom fastapi.templating import Jinja2Templates\n\nfrom typing import Optional, Any\nfrom pathlib import Path\n\nfrom app.schemas import RecipeSearchResults, Recipe, RecipeCreate\nfrom app.recipe_data import RECIPES\n\nBASE_PATH = Path(__file__).resolve().parent\nTEMPLATES = Jinja2Templates(directory=str(BASE_PATH / \"templates\"))\n\napp = FastAPI(title=\"Recipe API\", openapi_url=\"/openapi.json\")\n\napi_router = APIRouter()\n\n# Updated to serve a Jinja2 template\n# https://www.starlette.io/templates/\n# https://jinja.palletsprojects.com/en/3.0.x/templates/#synopsis\n@api_router.get(\"/\", status_code=200)\ndef root(request: Request) -> dict:\n \"\"\"\n Root GET\n \"\"\"\n return TEMPLATES.TemplateResponse(\n \"index.html\",\n {\"request\": request, \"recipes\": RECIPES},\n )\n\n@api_router.get(\"/recipe/{recipe_id}\", status_code=200, response_model=Recipe)\ndef fetch_recipe(*, recipe_id: int) -> Any:\n \"\"\"\n Fetch a single recipe by ID\n \"\"\"\n\n result = [recipe for recipe in RECIPES if recipe[\"id\"] == recipe_id]\n if not result:\n # the exception is raised, not returned - you will get a validation\n # error otherwise.\n raise HTTPException(\n status_code=404, detail=f\"Recipe with ID {recipe_id} not found\"\n )\n\n return result[0]\n\nif __name__ == \"__main__\":\n # Use this for debugging purposes only\n import uvicorn\n\n uvicorn.run(app, host=\"0.0.0.0\", port=8001, log_level=\"debug\")\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi.templating import Jinja2Templates\n\nfrom typing import Optional, Any\nfrom pathlib import Path\n\nfrom app.schemas import RecipeSearchResults, Recipe, RecipeCreate\nfrom app.recipe_data import RECIPES\n\n\nBASE_PATH = Path(__file__).resolve().parent\nTEMPLATES = Jinja2Templates(directory=str(BASE_PATH / \"templates\"))\n\n\napp = FastAPI(title=\"Recipe API\", openapi_url=\"/openapi.json\")\n\napi_router = APIRouter()\n\n\n# Updated to serve a Jinja2 template\n# https://www.starlette.io/templates/\n# https://jinja.palletsprojects.com/en/3.0.x/templates/#synopsis\n@api_router.get(\"/\", status_code=200)\ndef root(request: Request) -> dict:\n \"\"\"\n Root GET\n \"\"\"\n return TEMPLATES.TemplateResponse(\n \"index.html\",\n {\"request\": request, \"recipes\": RECIPES},\n )\n\n\n@api_router.get(\"/recipe/{recipe_id}\", status_code=200, response_model=Recipe)\ndef fetch_recipe(*, recipe_id: int) -> Any:\n \"\"\"\n Fetch a single recipe by ID\n \"\"\"\n\n result = [recipe for recipe in RECIPES if recipe[\"id\"] == recipe_id]\n if not result:\n # the exception is raised, not returned - you will get a validation\n # error otherwise.\n raise HTTPException(\n status_code=404, detail=f\"Recipe with ID {recipe_id} not found\"\n )\n\n return result[0]\n\nif __name__ == \"__main__\":\n # Use this for debugging purposes only\n import uvicorn\n\n uvicorn.run(app, host=\"0.0.0.0\", port=8001, log_level=\"debug\")\n```\n\n```text\nAttributeError: module 'jinja2' has no attribute 'contextfunction\n```\n\n```text\npip install jinja2==3.0.3\n```\n\n========================================\n\nComments:\n- Please, add **your code** into the question post. See How to Ask.\n- This definitely worked for me (jinja2==3.0.3), thanks for the heads up :)","metadata":{"transformedAt":"2026-08-18T18:32:29.141Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":3,"totalLines":135,"estimatedTokens":905}}531{"id":"stack-77220728","source":"stackoverflow","questionId":77220728,"title":"Pydantic accept integer as string input","tags":["python","python-3.x","fastapi","pydantic"],"text":"Title: Pydantic accept integer as string input\nTags: python, python-3.x, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nFor a FastAPI Pydantic interface I want to be as tolerable as possible, such as receiving an integer for a string parameter and parse that integer to string:\n\n```\nfrom pydantic import BaseModel\n\nclass FooBar(BaseModel):\n whatever: str\n \nFooBar(whatever=12)\n```\n\nGives:\n\n```\nValidationError: 1 validation error for FooBar\nwhatever\n Input should be a valid string [type=string_type, input_value=12, input_type=int]\n For further information visit https://errors.pydantic.dev/2.4/v/string_type\n```\n\nI think in earlier versions this was possible.\n\n- Python 3.10\n\n- pydantic==2.4.2\n\n- pydantic_core==2.10.1\n\n========================================\n\nTop Answer:\nTo add on @M.O. with the newest release of `pydantic` 2.7.1 it is now possible to enable `coerce_numbers_to_str` on a `Field`'s level. Very handy. Given:\n\n```\nclass Foo(BaseModel):\n a: str = Field(coerce_numbers_to_str=True)\n b: str = Field()\n```\n\nThen `Foo(a=1, b=\"1\")` passes while `Foo(a=1, b=1)` will fail.\n\n========================================\n\nCode:\n```py\nfrom pydantic import BaseModel\n\nclass FooBar(BaseModel):\n whatever: str\n \nFooBar(whatever=12)\n```\n\n```text\nValidationError: 1 validation error for FooBar\nwhatever\n Input should be a valid string [type=string_type, input_value=12, input_type=int]\n For further information visit https://errors.pydantic.dev/2.4/v/string_type\n```\n\n```py\nfrom pydantic import BaseModel, ConfigDict\n\nclass FooBar(BaseModel):\n model_config = ConfigDict(coerce_numbers_to_str=True)\n\n whatever: str\n```\n\n```text\ncoerce_numbers_to_str\n```\n\n```py\nclass Foo(BaseModel):\n a: str = Field(coerce_numbers_to_str=True)\n b: str = Field()\n```\n\n```text\npydantic\n```\n\n```text\ncoerce_numbers_to_str\n```\n\n```text\nField\n```\n\n```text\nFoo(a=1, b=\"1\")\n```\n\n```text\nFoo(a=1, b=1)\n```\n\n========================================\n\nComments:\n- before it was possible to do that. but apparently, with the newer version of `pydantic` you need something extra which is mentioned in given answer to this question by M.O.\n- Although a new version is the opportunity to do better and different things, it seems a mistake to make compatibility so difficult. I don't understand why changing these things goes against everything we all expect it to do and makes the migration of existing services more difficult.","metadata":{"transformedAt":"2026-08-18T18:32:29.141Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":10,"totalLines":109,"estimatedTokens":606}}532{"id":"stack-66202833","source":"stackoverflow","questionId":66202833,"title":"How to set \"/*\" path to capture all routes in FastAPI?","tags":["python","fastapi"],"text":"Title: How to set \"/*\" path to capture all routes in FastAPI?\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nLike in `ExpressJS`, `app.get(\"/*\")` works for all routes.\n\nMy code -\n\n```\nfrom typing import Optional\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get('/*')\ndef user_lost():\n return \"Sorry You Are Lost !\"\n```\n\nI tried it but the webpage result shows `{\"detail\":\"Not Found\"}`\n\nHow can I do the **same** in **`FastApi`**?\n\n========================================\n\nTop Answer:\nI edited Yagiz's code to:\n\n```\n@app.get(\"/{full_path:path}\")\nasync def capture_routes(request: Request, full_path: str):\n ...\n```\n\n========================================\n\nCode:\n```py\nfrom typing import Optional\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n\n@app.get('/*')\ndef user_lost():\n return \"Sorry You Are Lost !\"\n```\n\n```text\nExpressJS\n```\n\n```text\napp.get(\"/*\")\n```\n\n```text\n{\"detail\":\"Not Found\"}\n```\n\n```text\nFastApi\n```\n\n```py\n@app.route(\"/{full_path:path}\")\nasync def capture_routes(request: Request, full_path: str):\n ...\n```\n\n```text\n/{full_path}\n```\n\n```text\n@app.get(\"/{full_path:path}\")\nasync def capture_routes(request: Request, full_path: str):\n ...\n```\n\n========================================\n\nComments:\n- What have you already tried? Please see How to Ask.\n- I tried, Still It Didn't Work.\n- this doesn't work for me with the newest FastAPI version\n- Weird, it worked for me when I replaced route with get\n- in the latest versions this has changed from `app.route` to `app.api_route` github.com/tiangolo/fastapi/issues/819#issuecomment-56922291‌​4\n- Please show the line of code where the problem is. Be mor eprecise.\n- Import `Request` class from fastapi. Use: `from fastapi import Request`","metadata":{"transformedAt":"2026-08-18T18:32:29.141Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":8,"totalLines":92,"estimatedTokens":434}}533{"id":"stack-75295132","source":"stackoverflow","questionId":75295132,"title":"How to place specific constraints on the parameters of a Pydantic model?","tags":["python","fastapi","pydantic"],"text":"Title: How to place specific constraints on the parameters of a Pydantic model?\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nHow can I place specific constraints on the parameters of a Pydantic model? In particular, I would like:\n\n- `start_date` must be at least `\"2019-01-01\"`\n\n- `end_date` must be greater than `start_date`\n\n- `code` must be one and only one of the values in the set\n\n- `cluster` must be one and only one of the values in the set\n\nThe code I'm using is as follows:\n\n```\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\nfrom typing import Set\nimport uvicorn\n\napp = FastAPI()\n\nclass Query(BaseModel):\n start_date: str\n end_date: str\n code: Set[str] = {\n \"A1\", \"A2\", \"A3\", \"A4\",\n \"X1\", \"X2\", \"X3\", \"X4\", \"X5\",\n \"Y1\", \"Y2\", \"Y3\"\n }\n cluster: Set[str] = {\"C1\", \"C2\", \"C3\"}\n\n@app.post(\"/\")\nasync def read_table(query: Query):\n return {\"msg\": query}\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n```\n\n========================================\n\nTop Answer:\nYou can use an `Enum` class or a `Literal` to validate the code and cluster and then use a `root_validator` for the date. Also type hint the date field with datetime instead of a string `str`. Like so:\n\n```\nfrom datetime import datetime\nfrom enum import Enum\nfrom typing import Literal\n\nfrom pydantic import BaseModel, root_validator\n\n\"\"\"using Literal to validater the code and cluster\"\"\"\n\nclass Query(BaseModel):\n start_date: datetime\n end_date: datetime\n code: Literal[\n \"A1\", \"A2\", \"A3\", \"A4\", \"X1\", \"X2\", \"X3\", \"X4\", \"X5\", \"Y1\", \"Y2\", \"Y3\"\n ]\n cluster: Literal[\"C1\", \"C2\", \"C3\"]\n\n @root_validator()\n def validate_dates(cls, values):\n if datetime(year=2019, month=1, day=1) if you wish to use `Enum` to validate the code and the cluster you will define the `Enum` class like so\n\n```\nclass Cluster(Enum):\n C1 = \"C1\"\n C2 = \"C3\"\n C3 = \"C3\"\n\nclass Code(Enum):\n A1 = \"A1\"\n A2 = \"A2\"\n A3 = \"A3\"\n A4 = \"A4\"\n X1 = \"X1\"\n X2 = \"X2\"\n X3 = \"X3\"\n X4 = \"X4\"\n X5 = \"X5\"\n Y1 = \"Y1\"\n Y2 = \"Y2\"\n Y3 = \"Y3\"\n```\n\nand then replace the literals in the Query class with this\n\n```\ncode: Code\ncluster: Cluster\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\nfrom typing import Set\nimport uvicorn\n\napp = FastAPI()\n\n\nclass Query(BaseModel):\n start_date: str\n end_date: str\n code: Set[str] = {\n \"A1\", \"A2\", \"A3\", \"A4\",\n \"X1\", \"X2\", \"X3\", \"X4\", \"X5\",\n \"Y1\", \"Y2\", \"Y3\"\n }\n cluster: Set[str] = {\"C1\", \"C2\", \"C3\"}\n\n@app.post(\"/\")\nasync def read_table(query: Query):\n return {\"msg\": query}\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n```\n\n```text\nstart_date\n```\n\n```text\n\"2019-01-01\"\n```\n\n```text\nend_date\n```\n\n```text\nstart_date\n```\n\n```text\ncode\n```\n\n```text\ncluster\n```\n\n```py\n>>> class Foo(BaseModel):\n... d: condate(ge=datetime.date.fromisoformat('2019-01-01')\n\n>>> Foo(d=datetime.date.fromisoformat('2018-01-12'))\nTraceback (most recent call last):\n File \"<stdin>\", line 1, in <module>\n File \"pydantic\\main.py\", line 342, in pydantic.main.BaseModel.__init__\npydantic.error_wrappers.ValidationError: 1 validation error for Foo\nd\n ensure this value is greater than or equal to 2019-01-01 (type=value_error.number.not_ge; limit_value=2019-01-01)\n\n>>> Foo(d=datetime.date.fromisoformat('2020-01-12'))\nFoo(d=datetime.date(2020, 1, 12))\n```\n\n```py\nfrom pydantic import BaseModel, root_validator\nfrom datetime import date\n\nclass StartEnd(BaseModel):\n start: date\n end: date\n \n @root_validator\n def validate_dates(cls, values):\n if values['start'] > values['end']:\n raise ValueError('start is after end')\n \n return values\n \n\nStartEnd(start=date.fromisoformat('2023-01-01'), end=date.fromisoformat('2022-01-01'))\n```\n\n```text\npydantic.error_wrappers.ValidationError: 1 validation error for StartEnd\n__root__\n start is after end (type=value_error)\n```\n\n```py\nfrom pydantic import BaseModel\nfrom enum import Enum # StrEnum in 3.11+\n\n\nclass ClusterEnum(str, Enum):\n C1 = \"C1\"\n C2 = \"C2\" \n C3 = \"C3\"\n \n\nclass ClusterVal(BaseModel):\n cluster: ClusterEnum\n \n\nprint(ClusterVal(cluster='C3').cluster.value)\n# outputs C3\n```\n\n```text\nfrom datetime import datetime\nfrom enum import Enum\nfrom typing import Literal\n\nfrom pydantic import BaseModel, root_validator\n\n\"\"\"using Literal to validater the code and cluster\"\"\"\n\nclass Query(BaseModel):\n start_date: datetime\n end_date: datetime\n code: Literal[\n \"A1\", \"A2\", \"A3\", \"A4\", \"X1\", \"X2\", \"X3\", \"X4\", \"X5\", \"Y1\", \"Y2\", \"Y3\"\n ]\n cluster: Literal[\"C1\", \"C2\", \"C3\"]\n\n @root_validator()\n def validate_dates(cls, values):\n if datetime(year=2019, month=1, day=1) < values.get(\"start_date\"):\n raise ValueError(\"Date cannot be earlier than 2019-01-01\")\n\n if values.get(\"end_date\") < values.get(\"start_date\"):\n raise ValueError(\"end date cannot be earlier than start date\")\n\n return values\n```\n\n```text\nclass Cluster(Enum):\n C1 = \"C1\"\n C2 = \"C3\"\n C3 = \"C3\"\n\n\nclass Code(Enum):\n A1 = \"A1\"\n A2 = \"A2\"\n A3 = \"A3\"\n A4 = \"A4\"\n X1 = \"X1\"\n X2 = \"X2\"\n X3 = \"X3\"\n X4 = \"X4\"\n X5 = \"X5\"\n Y1 = \"Y1\"\n Y2 = \"Y2\"\n Y3 = \"Y3\"\n```\n\n```text\ncode: Code\ncluster: Cluster\n```\n\n```text\nEnum\n```\n\n```text\nLiteral\n```\n\n```text\nroot_validator\n```\n\n```text\nstr\n```\n\n```text\nEnum\n```\n\n```text\nEnum\n```\n\n========================================\n\nComments:\n- Thank you for your answer, it is very clear. The only thing I didn't quite understand is how to write the Pydantic `Query` model following the constraints you put. Specifically, I'm guessing it's like: `class Query: start_date: ?; end_date: ?; code: CodeEnum; cluster: ClusterEnum` but I don't know how to handle the dates knowing that the user will make the POST call by passing them as strings.\n- You can just define them as `start_date: date, end_date: date`, Pydantic will automagically convert an iso-formatted string (`YYYY-mm-dd`) to a date object for you and validate it. `StartEnd(start='2023-01-01', end='2024-01-01')`.\n- So you put the date control in the `Query` class? `@root_validator \\n def validate_dates(cls, values): if values[\"start_date\"] values[\"end_date\"]: raise ValueError(\"Error2\"); return values`\n- Correct, I'm guessing it's the query you want to validate - an end_date before a start_date doesn't seem like a valid query. I'd use the `condate` field type to validate the start date (if possible, it was added in a relatively recent version of pydantic) instead of doing it in the root validator. The root validator should generally implement more advanced validations that can't be performed by the field type itself (since definitions in the field type can be used for documentation, is clearer when being read, etc.).","metadata":{"transformedAt":"2026-08-18T18:32:29.141Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":20,"totalLines":297,"estimatedTokens":1712}}534{"id":"stack-73291228","source":"stackoverflow","questionId":73291228,"title":"Add route to FastAPI with custom path parameters","tags":["python","fastapi","starlette"],"text":"Title: Add route to FastAPI with custom path parameters\nTags: python, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nI am trying to add routes from a file and I don't know the actual arguments beforehand so I need to have a general function that handles arguments via `**kwargs`.\n\nTo add routes I am using `add_api_route` as below:\n\n```\nfrom fastapi import APIRouter\n\nmy_router = APIRouter()\n\ndef foo(xyz):\n return {\"Result\": xyz}\n\nmy_router.add_api_route('/foo/{xyz}', endpoint=foo)\n```\n\nAbove works fine.\n\nHowever enrty path parameters are not fixed and I need to read them from a file, to achieve this, I am trying something like this:\n\n```\nfrom fastapi import APIRouter\n\nmy_router = APIRouter()\n\ndef foo(**kwargs):\n return {\"Result\": kwargs['xyz']}\n\nread_from_file = '/foo/{xyz}' # Assume this is read from a file\n\nmy_router.add_api_route(read_from_file, endpoint=foo)\n```\n\nBut it throws this error:\n\n```\n{\"detail\":[{\"loc\":[\"query\",\"kwargs\"],\"msg\":\"field required\",\"type\":\"value_error.missing\"}]}\n```\n\nFastAPI tries to find actual argument `xyz` in `foo` signature which is not there.\n\nIs there any way in FastAPI to achieve this? Or even any solution to accept a path like `/foo/... whatever .../`?\n\n========================================\n\nTop Answer:\nAs described here, you can use the `path` convertor, provided by Starlette, to capture arbitrary paths. Related answers using the `add_route()`, or preferably `add_api_route()` (since it allows using FastAPI `dependencies`), method can be found here and here.\n\n### Example\n\n```\nfrom fastapi import APIRouter, FastAPI\n\napp = FastAPI()\nmy_router = APIRouter()\n\ndef foo(rest_of_path: str):\n return {\"rest_of_path\": rest_of_path}\n\n \nroute_path = '/foo/{rest_of_path:path}'\nmy_router.add_api_route(route_path, endpoint=foo)\napp.include_router(my_router)\n```\n\nInput test URL:\n\n```\nhttp://127.0.0.1:8000/foo/https://placebear.com/cache/395-205.jpg\n```\n\nOutput:\n\n```\n{\"rest_of_path\":\"https://placebear.com/cache/395-205.jpg\"}\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi import APIRouter\n\nmy_router = APIRouter()\n\ndef foo(xyz):\n return {\"Result\": xyz}\n\nmy_router.add_api_route('/foo/{xyz}', endpoint=foo)\n```\n\n```text\nfrom fastapi import APIRouter\n\nmy_router = APIRouter()\n\ndef foo(**kwargs):\n return {\"Result\": kwargs['xyz']}\n\nread_from_file = '/foo/{xyz}' # Assume this is read from a file\n\nmy_router.add_api_route(read_from_file, endpoint=foo)\n```\n\n```text\n{\"detail\":[{\"loc\":[\"query\",\"kwargs\"],\"msg\":\"field required\",\"type\":\"value_error.missing\"}]}\n```\n\n```text\n**kwargs\n```\n\n```text\nadd_api_route\n```\n\n```text\nxyz\n```\n\n```text\nfoo\n```\n\n```text\n/foo/... whatever .../\n```\n\n```text\nfrom fastapi import APIRouter\nimport re\nimport inspect\n\nmy_router = APIRouter()\n\n\ndef generate_function_signature(route_path: str):\n args = {arg: str for arg in re.findall(r'\\{(.*?)\\}', route_path)}\n \n def new_fn(**kwargs):\n return {\"Result\": kwargs['xyz']}\n\n params = [\n inspect.Parameter(\n param,\n inspect.Parameter.POSITIONAL_OR_KEYWORD,\n annotation=type_\n ) for param, type_ in args.items()\n ]\n\n new_fn.__signature__ = inspect.Signature(params)\n new_fn.__annotations__ = args\n return new_fn\n\n\nread_from_file = '/foo/{xyz}' # Assume this is read from a file\n\nmy_router.add_api_route(\n read_from_file,\n endpoint=generate_function_signature(read_from_file)\n)\n```\n\n```py\nfrom fastapi import APIRouter, FastAPI\n\n\napp = FastAPI()\nmy_router = APIRouter()\n\n\ndef foo(rest_of_path: str):\n return {\"rest_of_path\": rest_of_path}\n\n \nroute_path = '/foo/{rest_of_path:path}'\nmy_router.add_api_route(route_path, endpoint=foo)\napp.include_router(my_router)\n```\n\n```text\nhttp://127.0.0.1:8000/foo/https://placebear.com/cache/395-205.jpg\n```\n\n```json\n{\"rest_of_path\":\"https://placebear.com/cache/395-205.jpg\"}\n```\n\n```text\npath\n```\n\n```text\nadd_route()\n```\n\n```text\nadd_api_route()\n```\n\n```text\ndependencies\n```\n\n========================================\n\nComments:\n- Have you seen stackoverflow.com/questions/63069190/… and fastapi.tiangolo.com/advanced/custom-request-and-route ? The first shows how you can use a `path` type to capture the path, while the other one shows how you can use a custom apiroute class if you want to customize the lower level functionality.\n- Please have a look at this answer.\n- I am using this right now, thanks. However I think FastAPI should support these kind of functions while it is supporting dynamic routing via add_api_route. I edited my question to describe the problem.\n- Thanks for the answer, your point about `path` inside route is very useful, however I am trying to extract parameter within url, but your code is extracting query parameters.","metadata":{"transformedAt":"2026-08-18T18:32:29.141Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":16,"totalLines":215,"estimatedTokens":1186}}535{"id":"stack-72942519","source":"stackoverflow","questionId":72942519,"title":"Alembic migration with FastAPI + Docker: Connection to port 5432 in localhost fails when I try to run migrations","tags":["python","docker","migration","fastapi","alembic"],"text":"Title: Alembic migration with FastAPI + Docker: Connection to port 5432 in localhost fails when I try to run migrations\nTags: python, docker, migration, fastapi, alembic\nSource: Stack Overflow\n\nQuestion:\nCurrently I am trying to learn about Api development with FastAPI and I am trying to dockerize my project. However, when I try to run the database migrations with alembic in Docker by using `docker run sm-api_api alembic upgrade head` I get the following error:\n\n```\nFile \"/usr/local/lib/python3.10/site-packages/sqlalchemy/engine/base.py\", line 3280, in _wrap_pool_connect\n return fn()\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/pool/base.py\", line 310, in connect\n return _ConnectionFairy._checkout(self)\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/pool/base.py\", line 868, in _checkout\n fairy = _ConnectionRecord.checkout(pool)\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/pool/base.py\", line 476, in checkout\n rec = pool._do_get()\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/pool/impl.py\", line 256, in _do_get\n return self._create_connection()\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/pool/base.py\", line 256, in _create_connection\n return _ConnectionRecord(self)\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/pool/base.py\", line 371, in __init__\n self.__connect()\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/pool/base.py\", line 665, in __connect\n with util.safe_reraise():\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/util/langhelpers.py\", line 70, in __exit__\n compat.raise_(\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/util/compat.py\", line 208, in raise_\n raise exception\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/pool/base.py\", line 661, in __connect\n self.dbapi_connection = connection = pool._invoke_creator(self)\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/engine/create.py\", line 590, in connect\n return dialect.connect(*cargs, **cparams)\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/engine/default.py\", line 597, in connect\n return self.dbapi.connect(*cargs, **cparams)\n File \"/usr/local/lib/python3.10/site-packages/psycopg2/__init__.py\", line 122, in connect\n conn = _connect(dsn, connection_factory=connection_factory, **kwasync)\npsycopg2.OperationalError: connection to server at \"localhost\" (127.0.0.1), port 5432 failed: Connection refused\n Is the server running on that host and accepting TCP/IP connections?\nconnection to server at \"localhost\" (::1), port 5432 failed: Cannot assign requested address\n Is the server running on that host and accepting TCP/IP connections?\n\nThe above exception was the direct cause of the following exception:\n\nTraceback (most recent call last):\n File \"/usr/local/bin/alembic\", line 8, in \n sys.exit(main())\n File \"/usr/local/lib/python3.10/site-packages/alembic/config.py\", line 590, in main\n CommandLine(prog=prog).main(argv=argv)\n File \"/usr/local/lib/python3.10/site-packages/alembic/config.py\", line 584, in main\n self.run_cmd(cfg, options)\n File \"/usr/local/lib/python3.10/site-packages/alembic/config.py\", line 561, in run_cmd\n fn(\n File \"/usr/local/lib/python3.10/site-packages/alembic/command.py\", line 322, in upgrade\n script.run_env()\n File \"/usr/local/lib/python3.10/site-packages/alembic/script/base.py\", line 569, in run_env\n util.load_python_file(self.dir, \"env.py\")\n File \"/usr/local/lib/python3.10/site-packages/alembic/util/pyfiles.py\", line 94, in load_python_file\n module = load_module_py(module_id, path)\n File \"/usr/local/lib/python3.10/site-packages/alembic/util/pyfiles.py\", line 110, in load_module_py\n spec.loader.exec_module(module) # type: ignore\n File \"\", line 883, in exec_module\n File \"\", line 241, in _call_with_frames_removed\n File \"/usr/src/app/alembic/env.py\", line 81, in \n run_migrations_online()\n File \"/usr/src/app/alembic/env.py\", line 69, in run_migrations_online\n with connectable.connect() as connection:\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/engine/base.py\", line 3234, in connect\n return self._connection_cls(self, close_with_result=close_with_result)\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/engine/base.py\", line 96, in __init__\n else engine.raw_connection()\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/engine/base.py\", line 3313, in raw_connection\n return self._wrap_pool_connect(self.pool.connect, _connection)\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/engine/base.py\", line 3283, in _wrap_pool_connect\n Connection._handle_dbapi_exception_noconnection(\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/engine/base.py\", line 2117, in _handle_dbapi_exception_noconnection\n util.raise_(\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/util/compat.py\", line 208, in raise_\n raise exception\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/engine/base.py\", line 3280, in _wrap_pool_connect\n return fn()\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/pool/base.py\", line 310, in connect\n return _ConnectionFairy._checkout(self)\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/pool/base.py\", line 868, in _checkout\n fairy = _ConnectionRecord.checkout(pool)\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/pool/base.py\", line 476, in checkout\n rec = pool._do_get()\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/pool/impl.py\", line 256, in _do_get\n return self._create_connection()\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/pool/base.py\", line 256, in _create_connection\n return _ConnectionRecord(self)\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/pool/base.py\", line 371, in __init__\n self.__connect()\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/pool/base.py\", line 665, in __connect\n with util.safe_reraise():\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/util/langhelpers.py\", line 70, in __exit__\n compat.raise_(\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/util/compat.py\", line 208, in raise_\n raise exception\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/pool/base.py\", line 661, in __connect\n self.dbapi_connection = connection = pool._invoke_creator(self)\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/engine/create.py\", line 590, in connect\n return dialect.connect(*cargs, **cparams)\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/engine/default.py\", line 597, in connect\n return self.dbapi.connect(*cargs, **cparams)\n File \"/usr/local/lib/python3.10/site-packages/psycopg2/__init__.py\", line 122, in connect\n conn = _connect(dsn, connection_factory=connection_factory, **kwasync)\nsqlalchemy.exc.OperationalError: (psycopg2.OperationalError) connection to server at \"localhost\" (127.0.0.1), port 5432 failed: Connection refused\n Is the server running on that host and accepting TCP/IP connections?\nconnection to server at \"localhost\" (::1), port 5432 failed: Cannot assign requested address\n Is the server running on that host and accepting TCP/IP connections?\n\n(Background on this error at: https://sqlalche.me/e/14/e3q8)\n```\n\nMy docker compose file is like this:\n\n```\nversion: '3'\nservices:\n api:\n build: .\n depends_on:\n - postgres\n ports:\n - 8000:8000\n environment:\n - DATABASE_HOSTNAME=${DATABASE_HOST}\n - DATABASE_PORT=${DATABASE_PORT}\n - DATABASE_PASSWORD=${DATABASE_PASSWORD}\n - DATABASE_NAME=${DATABASE_NAME}\n - DATABASE_USERNAME=${DATABASE_USERNAME}\n - SECRET_KEY=${SECRET_KEY}\n - ALGORITHM=${ALGORITHM}\n - ACCESS_TOKEN_EXPIRE_MINUTES=${ACCESS_TOKEN_EXPIRE_TIME}\n\n postgres:\n image: postgres\n environment:\n - POSTGRES_PASSWORD=${DATABASE_PASSWORD}\n - POSTGRES_DB=${DATABASE_NAME}\n ports:\n - 5432:5432\n volumes:\n - postgres-db:/var/lib/postgresql/data\n\nvolumes:\n postgres-db:\n```\n\nI already tried to kill the port and run it again, but it did not solve my problem. Does anyone know what the problem is?\n\nEdit:\nMy Docker file:\n\n```\nFROM python:3.10.5\n\nWORKDIR /usr/src/app\n\nCOPY requirements.txt ./\n\nRUN pip install --no-cache-dir -r requirements.txt\n\nCOPY . .\n\nCMD [\"uvicorn\", \"app.main:app\", \"--host\", \"0.0.0.0\", \"--port\", \"8000\"]\n```\n\nAnd my .env file:\n\n```\nDATABASE_HOST=localhost\nDATABASE_PORT=5432\nDATABASE_PASSWORD={password}\nDATABASE_NAME=SM_API\nDATABASE_USERNAME=postgres\nSECRET_KEY={secret key}\nALGORITHM=HS256\nACCESS_TOKEN_EXPIRE_TIME = 30\n```\n\n========================================\n\nTop Answer:\nIf anyone still has this issue, check to see if any of your database files (.env, env.py, main.py or app.py, docker-compose.yml, etc) have a reference to localhost (on VScode you can use `ctrl + shift + f` to search all files) and change it to the service name of your postgres service i.e.\n\n**.env**\n\n```\ndatabase_hostname = db\n```\n\n**docker-compose.yml**\n\n```\nversion: \"3\"\nservices:\n fastapi:\n build: .\n environment:\n - DATABASE_HOSTNAME=db\n - DATABASE_PORT=5432\n - DATABASE_PASSWORD=password123\n - DATABASE_NAME=fastapi\n - DATABASE_USERNAME=postgres\n ports:\n - 8000:8000\n command: bash -c \"alembic upgrade head && uvicorn main:app --host 0.0.0.0 --port 8000 --reload\"\n depends_on:\n - db\n \n db:\n image: postgres\n environment:\n - PGDATA:/var/lib/postgresql/data\n - POSTGRES_PASSWORD=password123\n - POSTGRES_DB=fastapi\n volumes:\n - postgres-db:/var/lib/postgresql/data\n \nvolumes:\n postgres-db:\n```\n\nIf the issue still persist after changing those files you need to rebuild the image with:\n\n`docker compose up --build`\n\nThe reason is changing your app or env files is a significant enough change that doesn't automatically get captured by your current image. Therefore, to keep your image up to date with your new code changes you have to rebuild it.\n\n========================================\n\nCode:\n```text\nFile \"/usr/local/lib/python3.10/site-packages/sqlalchemy/engine/base.py\", line 3280, in _wrap_pool_connect\n return fn()\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/pool/base.py\", line 310, in connect\n return _ConnectionFairy._checkout(self)\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/pool/base.py\", line 868, in _checkout\n fairy = _ConnectionRecord.checkout(pool)\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/pool/base.py\", line 476, in checkout\n rec = pool._do_get()\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/pool/impl.py\", line 256, in _do_get\n return self._create_connection()\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/pool/base.py\", line 256, in _create_connection\n return _ConnectionRecord(self)\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/pool/base.py\", line 371, in __init__\n self.__connect()\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/pool/base.py\", line 665, in __connect\n with util.safe_reraise():\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/util/langhelpers.py\", line 70, in __exit__\n compat.raise_(\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/util/compat.py\", line 208, in raise_\n raise exception\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/pool/base.py\", line 661, in __connect\n self.dbapi_connection = connection = pool._invoke_creator(self)\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/engine/create.py\", line 590, in connect\n return dialect.connect(*cargs, **cparams)\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/engine/default.py\", line 597, in connect\n return self.dbapi.connect(*cargs, **cparams)\n File \"/usr/local/lib/python3.10/site-packages/psycopg2/__init__.py\", line 122, in connect\n conn = _connect(dsn, connection_factory=connection_factory, **kwasync)\npsycopg2.OperationalError: connection to server at \"localhost\" (127.0.0.1), port 5432 failed: Connection refused\n Is the server running on that host and accepting TCP/IP connections?\nconnection to server at \"localhost\" (::1), port 5432 failed: Cannot assign requested address\n Is the server running on that host and accepting TCP/IP connections?\n\n\nThe above exception was the direct cause of the following exception:\n\nTraceback (most recent call last):\n File \"/usr/local/bin/alembic\", line 8, in <module>\n sys.exit(main())\n File \"/usr/local/lib/python3.10/site-packages/alembic/config.py\", line 590, in main\n CommandLine(prog=prog).main(argv=argv)\n File \"/usr/local/lib/python3.10/site-packages/alembic/config.py\", line 584, in main\n self.run_cmd(cfg, options)\n File \"/usr/local/lib/python3.10/site-packages/alembic/config.py\", line 561, in run_cmd\n fn(\n File \"/usr/local/lib/python3.10/site-packages/alembic/command.py\", line 322, in upgrade\n script.run_env()\n File \"/usr/local/lib/python3.10/site-packages/alembic/script/base.py\", line 569, in run_env\n util.load_python_file(self.dir, \"env.py\")\n File \"/usr/local/lib/python3.10/site-packages/alembic/util/pyfiles.py\", line 94, in load_python_file\n module = load_module_py(module_id, path)\n File \"/usr/local/lib/python3.10/site-packages/alembic/util/pyfiles.py\", line 110, in load_module_py\n spec.loader.exec_module(module) # type: ignore\n File \"<frozen importlib._bootstrap_external>\", line 883, in exec_module\n File \"<frozen importlib._bootstrap>\", line 241, in _call_with_frames_removed\n File \"/usr/src/app/alembic/env.py\", line 81, in <module>\n run_migrations_online()\n File \"/usr/src/app/alembic/env.py\", line 69, in run_migrations_online\n with connectable.connect() as connection:\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/engine/base.py\", line 3234, in connect\n return self._connection_cls(self, close_with_result=close_with_result)\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/engine/base.py\", line 96, in __init__\n else engine.raw_connection()\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/engine/base.py\", line 3313, in raw_connection\n return self._wrap_pool_connect(self.pool.connect, _connection)\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/engine/base.py\", line 3283, in _wrap_pool_connect\n Connection._handle_dbapi_exception_noconnection(\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/engine/base.py\", line 2117, in _handle_dbapi_exception_noconnection\n util.raise_(\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/util/compat.py\", line 208, in raise_\n raise exception\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/engine/base.py\", line 3280, in _wrap_pool_connect\n return fn()\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/pool/base.py\", line 310, in connect\n return _ConnectionFairy._checkout(self)\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/pool/base.py\", line 868, in _checkout\n fairy = _ConnectionRecord.checkout(pool)\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/pool/base.py\", line 476, in checkout\n rec = pool._do_get()\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/pool/impl.py\", line 256, in _do_get\n return self._create_connection()\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/pool/base.py\", line 256, in _create_connection\n return _ConnectionRecord(self)\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/pool/base.py\", line 371, in __init__\n self.__connect()\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/pool/base.py\", line 665, in __connect\n with util.safe_reraise():\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/util/langhelpers.py\", line 70, in __exit__\n compat.raise_(\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/util/compat.py\", line 208, in raise_\n raise exception\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/pool/base.py\", line 661, in __connect\n self.dbapi_connection = connection = pool._invoke_creator(self)\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/engine/create.py\", line 590, in connect\n return dialect.connect(*cargs, **cparams)\n File \"/usr/local/lib/python3.10/site-packages/sqlalchemy/engine/default.py\", line 597, in connect\n return self.dbapi.connect(*cargs, **cparams)\n File \"/usr/local/lib/python3.10/site-packages/psycopg2/__init__.py\", line 122, in connect\n conn = _connect(dsn, connection_factory=connection_factory, **kwasync)\nsqlalchemy.exc.OperationalError: (psycopg2.OperationalError) connection to server at \"localhost\" (127.0.0.1), port 5432 failed: Connection refused\n Is the server running on that host and accepting TCP/IP connections?\nconnection to server at \"localhost\" (::1), port 5432 failed: Cannot assign requested address\n Is the server running on that host and accepting TCP/IP connections?\n\n(Background on this error at: https://sqlalche.me/e/14/e3q8)\n```\n\n```text\nversion: '3'\nservices:\n api:\n build: .\n depends_on:\n - postgres\n ports:\n - 8000:8000\n environment:\n - DATABASE_HOSTNAME=${DATABASE_HOST}\n - DATABASE_PORT=${DATABASE_PORT}\n - DATABASE_PASSWORD=${DATABASE_PASSWORD}\n - DATABASE_NAME=${DATABASE_NAME}\n - DATABASE_USERNAME=${DATABASE_USERNAME}\n - SECRET_KEY=${SECRET_KEY}\n - ALGORITHM=${ALGORITHM}\n - ACCESS_TOKEN_EXPIRE_MINUTES=${ACCESS_TOKEN_EXPIRE_TIME}\n\n postgres:\n image: postgres\n environment:\n - POSTGRES_PASSWORD=${DATABASE_PASSWORD}\n - POSTGRES_DB=${DATABASE_NAME}\n ports:\n - 5432:5432\n volumes:\n - postgres-db:/var/lib/postgresql/data\n\nvolumes:\n postgres-db:\n```\n\n```text\nFROM python:3.10.5\n\nWORKDIR /usr/src/app\n\nCOPY requirements.txt ./\n\nRUN pip install --no-cache-dir -r requirements.txt\n\nCOPY . .\n\nCMD [\"uvicorn\", \"app.main:app\", \"--host\", \"0.0.0.0\", \"--port\", \"8000\"]\n```\n\n```text\nDATABASE_HOST=localhost\nDATABASE_PORT=5432\nDATABASE_PASSWORD={password}\nDATABASE_NAME=SM_API\nDATABASE_USERNAME=postgres\nSECRET_KEY={secret key}\nALGORITHM=HS256\nACCESS_TOKEN_EXPIRE_TIME = 30\n```\n\n```text\ndocker run sm-api_api alembic upgrade head\n```\n\n```text\nDATABASE_HOSTNAME=postgres\n```\n\n```text\nDATABASE_HOST=postgres\n...\n```\n\n```text\nconnection to server at \"localhost\" (127.0.0.1)\n```\n\n```text\nDATABASE_HOSTNAME\n```\n\n```text\n127.0.0.1\n```\n\n```text\ndatabase_hostname = db\n```\n\n```text\nversion: \"3\"\nservices:\n fastapi:\n build: .\n environment:\n - DATABASE_HOSTNAME=db\n - DATABASE_PORT=5432\n - DATABASE_PASSWORD=password123\n - DATABASE_NAME=fastapi\n - DATABASE_USERNAME=postgres\n ports:\n - 8000:8000\n command: bash -c \"alembic upgrade head && uvicorn main:app --host 0.0.0.0 --port 8000 --reload\"\n depends_on:\n - db\n \n db:\n image: postgres\n environment:\n - PGDATA:/var/lib/postgresql/data\n - POSTGRES_PASSWORD=password123\n - POSTGRES_DB=fastapi\n volumes:\n - postgres-db:/var/lib/postgresql/data\n \nvolumes:\n postgres-db:\n```\n\n```text\nctrl + shift + f\n```\n\n```text\ndocker compose up --build\n```\n\n```text\nSQLALCHEMY_DATABASE_URL = \"postgresql://localhost/dbname\"\n```\n\n```text\nSQLALCHEMY_DATABASE_URL = \"postgresql://host.docker.internal/dbname\"\n```\n\n========================================\n\nComments:\n- you have to pass postgres service name instead of localhost or 127.0.0.1 in your engine like \"postgres://:@:/...‌​....\n- Thank you for your suggestion, but it did not solve my problem and I still get the same error. I edited my post and added my Dockerfile and my .env files because I think there might be a problem with one of my environment variables.\n- After trying your suggestion I still get the same error. I edited my post to add my .env and Dockerfile because I think there might be a problem with my environment variables in my docker compose file\n- @FreAn, I think that is the right way to go. Have you created a new revision which has the new hostname as `postgres`?\n- Thank you for this! I have spent the whole day looking for a solution, thanks god I landed here. My problem was, I have my POSTGRES_SERVER=localhost and it didn't work. I changed it to POSTGRES_SERVER=db (since my service is \"db\" for the docker postgres, defined in the docker-compose.yml ) and it worked.","metadata":{"transformedAt":"2026-08-18T18:32:29.141Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":16,"totalLines":482,"estimatedTokens":5010}}536{"id":"stack-71457448","source":"stackoverflow","questionId":71457448,"title":"How can I skip authentication in a single test with a fixture in Fast API together with pytest?","tags":["python","pytest","fastapi","fixtures"],"text":"Title: How can I skip authentication in a single test with a fixture in Fast API together with pytest?\nTags: python, pytest, fastapi, fixtures\nSource: Stack Overflow\n\nQuestion:\nI have built authentication similar to what is described in the documentation. So I have this dependency copied from there:\n\n```\nasync def get_current_user(token: str = Depends(oauth2_scheme)):\n credentials_exception = HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Could not validate credentials\",\n headers={\"WWW-Authenticate\": \"Bearer\"},\n )\n try:\n payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])\n username: str = payload.get(\"sub\")\n if username is None:\n raise credentials_exception\n token_data = TokenData(username=username)\n except JWTError:\n raise credentials_exception\n user = get_user(fake_users_db, username=token_data.username)\n if user is None:\n raise credentials_exception\n return user\n```\n\nWhich I use in a set of endpoints, for example, in the other example of the documentation, for `User` I have `GET`, `POST`, `PUT`, `DELETE` and `GET ALL`.\n\nThe only method which does not require authentication is the POST method to create a new user.\n\nI want to be able to define unit tests that verify the method can not be accessed without authentication and also I want to skip the authentication completely when I'm focusing on the content of the method.\n\nTherefore I used the override functionality in a fixture. For example for this test:\n\n`test_user.py`\n\n```\ndef test_create_user(test_db, create_user, user, skip_authentication):\n \"\"\"\n Verify a user can be created and retrieved\n \"\"\"\n response = client.post(\n \"/api/v1/users/\",\n json=create_user,\n )\n\n # Assert creation\n assert response.status_code == 200, response.text\n data = response.json()\n assert \"id\" in data\n user_id = data[\"id\"]\n del data[\"id\"]\n assert data == user\n\n # Assert get user\n response = client.get(f\"/api/v1/users/{user_id}\")\n assert response.status_code == 200, response.text\n data = response.json()\n assert user_id == data[\"id\"]\n del data[\"id\"]\n assert data == user\n```\n\n`conftest.py`\n\n```\n@pytest.fixture\ndef skip_authentication() -> None:\n\n def get_current_user():\n pass\n app.dependency_overrides[get_current_active_user] = get_current_user\n```\n\nAnd this seems to work to remove the authentication, but it removes it in all tests, not just in the ones with the fixture `skip_authentication`.\n\nHow can I limit it to only the tests I want?\n\n========================================\n\nTop Answer:\nI've created the pytest-fastapi-deps library, which allows easy definition and cleanup of FastAPI dependencies.\n\nUse it like so and it would only affect a single test:\n\n```\ndef test_create_user(test_db, create_user, user, fastapi_dep):\n \"\"\"\n Verify a user can be created and retrieved\n \"\"\"\n def skip_auth():\n pass\n with fastapi_dep(app).override({get_current_active_user: skip_auth}):\n response = client.post(\n \"/api/v1/users/\",\n json=create_user,\n )\n\n # Assert creation\n assert response.status_code == 200, response.text\n data = response.json()\n assert \"id\" in data\n user_id = data[\"id\"]\n del data[\"id\"]\n assert data == user\n\n # Assert get user\n response = client.get(f\"/api/v1/users/{user_id}\")\n assert response.status_code == 200, response.text\n data = response.json()\n assert user_id == data[\"id\"]\n del data[\"id\"]\n assert data == user\n```\n\n========================================\n\nCode:\n```py\nasync def get_current_user(token: str = Depends(oauth2_scheme)):\n credentials_exception = HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Could not validate credentials\",\n headers={\"WWW-Authenticate\": \"Bearer\"},\n )\n try:\n payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])\n username: str = payload.get(\"sub\")\n if username is None:\n raise credentials_exception\n token_data = TokenData(username=username)\n except JWTError:\n raise credentials_exception\n user = get_user(fake_users_db, username=token_data.username)\n if user is None:\n raise credentials_exception\n return user\n```\n\n```py\ndef test_create_user(test_db, create_user, user, skip_authentication):\n \"\"\"\n Verify a user can be created and retrieved\n \"\"\"\n response = client.post(\n \"/api/v1/users/\",\n json=create_user,\n )\n\n # Assert creation\n assert response.status_code == 200, response.text\n data = response.json()\n assert \"id\" in data\n user_id = data[\"id\"]\n del data[\"id\"]\n assert data == user\n\n # Assert get user\n response = client.get(f\"/api/v1/users/{user_id}\")\n assert response.status_code == 200, response.text\n data = response.json()\n assert user_id == data[\"id\"]\n del data[\"id\"]\n assert data == user\n```\n\n```text\n@pytest.fixture\ndef skip_authentication() -> None:\n\n def get_current_user():\n pass\n app.dependency_overrides[get_current_active_user] = get_current_user\n```\n\n```text\nUser\n```\n\n```text\nGET\n```\n\n```text\nPOST\n```\n\n```text\nPUT\n```\n\n```text\nDELETE\n```\n\n```text\nGET ALL\n```\n\n```text\ntest_user.py\n```\n\n```text\nconftest.py\n```\n\n```text\nskip_authentication\n```\n\n```text\n@pytest.fixture\ndef client():\n \"\"\"\n Return an API Client\n \"\"\"\n app.dependency_overrides = {}\n return TestClient(app)\n\n@pytest.fixture\ndef client_authenticated():\n \"\"\"\n Returns an API client which skips the authentication\n \"\"\"\n def skip_auth():\n pass\n app.dependency_overrides[get_current_active_user] = skip_auth\n return TestClient(app)\n```\n\n```py\ndef test_premissions_user(client, test_db, create_user):\n \"\"\"\n Verify that not logged in users can not access the user functions excluding create\n \"\"\"\n # Create user\n response = client.post(\n \"/api/v1/users/\",\n json=create_user\n )\n assert response.status_code == 200, response.text\n\n # Get all users\n response = client.get(\n \"/api/v1/users/\",\n )\n assert response.status_code == 401, response.text\n \n # Get user 1\n response = client.get(\n \"/api/v1/users/1\",\n )\n assert response.status_code == 401, response.text \n \n # Delete user 1\n response = client.get(\n \"/api/v1/users/1\",\n )\n assert response.status_code == 401, response.text \n \n # Modify user 1\n response = client.delete(\n \"/api/v1/users/1\",\n )\n assert response.status_code == 401, response.text\n\ndef test_premissions_user_authenticated(client_authenticated, test_db, create_user):\n \"\"\"\n Verify that not logged in users can not access the user functions excluding create\n \"\"\"\n # Create user\n response = client_authenticated.post(\n \"/api/v1/users/\",\n json=create_user\n )\n assert response.status_code == 200, response.text\n\n # Get all users\n response = client_authenticated.get(\n \"/api/v1/users/\",\n )\n assert response.status_code == 200, response.text\n \n # Get user 1\n response = client_authenticated.get(\n \"/api/v1/users/1\",\n )\n assert response.status_code == 200, response.text \n \n # Delete user 1\n response = client_authenticated.get(\n \"/api/v1/users/1\",\n )\n assert response.status_code == 200, response.text \n \n # Modify user 1\n response = client_authenticated.delete(\n \"/api/v1/users/1\",\n )\n assert response.status_code == 204, response.text\n```\n\n```text\nconftest.py\n```\n\n```py\ndef test_create_user(test_db, create_user, user, fastapi_dep):\n \"\"\"\n Verify a user can be created and retrieved\n \"\"\"\n def skip_auth():\n pass\n with fastapi_dep(app).override({get_current_active_user: skip_auth}):\n response = client.post(\n \"/api/v1/users/\",\n json=create_user,\n )\n\n # Assert creation\n assert response.status_code == 200, response.text\n data = response.json()\n assert \"id\" in data\n user_id = data[\"id\"]\n del data[\"id\"]\n assert data == user\n\n # Assert get user\n response = client.get(f\"/api/v1/users/{user_id}\")\n assert response.status_code == 200, response.text\n data = response.json()\n assert user_id == data[\"id\"]\n del data[\"id\"]\n assert data == user\n```\n\n```text\nfrom contextlib import contextmanager\n\nfrom fastapi.testclient import TestClient\n\nfrom .app import app, validate_token\n\n\ndef auto_authenticate():\n pass\n\n\n@contextmanager\ndef manual_auth():\n try:\n # Remove the override\n del app.dependency_overrides[validate_token]\n yield\n finally:\n # Reapply the override\n app.dependency_overrides[validate_token] = auto_authenticate\n\n\n# Override the auth dependency globally to do nothing\napp.dependency_overrides[validate_token] = auto_authenticate\n\n\nclient = TestClient(app)\n\n\ndef test_hello():\n response = client.get(\"/\")\n assert response.status_code == 200\n\n\ndef test_hello_not_authenticated():\n with manual_auth():\n response = client.get(\"/\")\n assert response.status_code == 403\n```\n\n```text\nconftest.py\n```\n\n```text\ntry\n```\n\n```text\nfinally\n```\n\n```text\nmanual_auth\n```\n\n========================================\n\nComments:\n- Have you tried with `mock`?\n- Split your `client` fixture into two - one with `client` and `app.dependency_overrides[get_current_user] = None`, one named `skip_authentication_client` which depend on the `client` fixture and then configure the dependency override. I.e. you reset it to no override when not needed, and set it when needed. But if the endpoint *does not require authentication*, why does it check `get_current_user`? If the test fails with authentication required, wouldn't a regular client also fail?","metadata":{"transformedAt":"2026-08-18T18:32:29.141Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":21,"totalLines":401,"estimatedTokens":2425}}537{"id":"stack-64944900","source":"stackoverflow","questionId":64944900,"title":"Obtain JSON from FastAPI using Pydantic Nested Models","tags":["python","json","python-3.8","fastapi","pydantic"],"text":"Title: Obtain JSON from FastAPI using Pydantic Nested Models\nTags: python, json, python-3.8, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nThe following code receives some JSON that was POSTed to a FastAPI server. FastAPI makes it available within a function as a Pydantic model. My example code processes it by writing a file. What I don't like (and it seems to be side-effect of using Pydantic List) is that I have to loop back around to get some usable JSON.\n\nHow can I do this without looping?\n\nI feel it must be possible because `return images` just works.\n\n```\nfrom typing import List\n\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\nimport json\n\napp = FastAPI()\n\nclass Image(BaseModel):\n url: str\n name: str\n\n@app.post(\"/images/multiple/\")\nasync def create_multiple_images(images: List[Image]):\n #return images # returns json string\n #print(images) # prints an Image object\n #print(images.json()) # AttributeError: 'list' object has no attribute 'json'\n #print(json.dumps(images)) # TypeError: Object of type Image is not JSON serializable\n img_data = list() # does it really have to be this way?\n for i in images:\n img_data.append(i.dict())\n with open('./images.json', 'w') as f: \n json.dump(img_data, f, indent=2)\n\n'''\ncurl -v -d '[{\"name\":\"wilma\",\"url\":\"http://this.com\"},{\"name\":\"barney\",\"url\":\"http://that.com\"}]' http://localhost:8000/images/multiple/\n'''\n```\n\nThe example is expanded from the FastAPI docs\n\n========================================\n\nCode:\n```text\nfrom typing import List\n\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\nimport json\n\napp = FastAPI()\n\nclass Image(BaseModel):\n url: str\n name: str\n\n@app.post(\"/images/multiple/\")\nasync def create_multiple_images(images: List[Image]):\n #return images # returns json string\n #print(images) # prints an Image object\n #print(images.json()) # AttributeError: 'list' object has no attribute 'json'\n #print(json.dumps(images)) # TypeError: Object of type Image is not JSON serializable\n img_data = list() # does it really have to be this way?\n for i in images:\n img_data.append(i.dict())\n with open('./images.json', 'w') as f: \n json.dump(img_data, f, indent=2)\n\n'''\ncurl -v -d '[{\"name\":\"wilma\",\"url\":\"http://this.com\"},{\"name\":\"barney\",\"url\":\"http://that.com\"}]' http://localhost:8000/images/multiple/\n'''\n```\n\n```text\nreturn images\n```\n\n```text\nclass Image(BaseModel):\n url: str\n name: str\n\n\nclass Images(BaseModel):\n __root__: List[Image]\n\n\nimages_raw = '[{\"url\":\"url1\", \"name\":\"name1\"}, {\"url\":\"url2\", \"name\":\"name2\"}]'\nimages = parse_raw_as(Images, images_raw)\n\nwith open('./images.json', 'w') as f:\n f.write(images.json(indent=2))\n```\n\n```text\n@app.post(\"/images/multiple/\")\nasync def create_multiple_images(images: Images):\n with open('./images.json', 'w') as f:\n f.write(images.json(indent=2))\n```\n\n========================================\n\nComments:\n- You are not returning anything here ?\n- You are dealing with a list of items, how someone could possibly retrieve any data from a `list` without looping (assuming he doesn't know the `index`)\n- Perfect. I had tried defining a parent 'class Images' exactly as you have shown. But I didn't know about the custom root type. This was the missing piece of syntax I was looking for. Thanks Alex!","metadata":{"transformedAt":"2026-08-18T18:32:29.141Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":110,"estimatedTokens":833}}538{"id":"stack-63731584","source":"stackoverflow","questionId":63731584,"title":"How to dump http \"Content-type: application/json;\" in FastAPI","tags":["python-3.x","http-headers","netcat","fastapi"],"text":"Title: How to dump http \"Content-type: application/json;\" in FastAPI\nTags: python-3.x, http-headers, netcat, fastapi\nSource: Stack Overflow\n\nQuestion:\nI will write a python script that listen to a webhook for a custom tool that will send json(They might support other format also) on a port I can specify.\n\nHow to write something similar to linux command: \"nc -l 9000\" to dump the out put I get on that port (header and body)?\n\n```\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/\")\nasync def root():\n print() I want to print the content in the terminal, then I can easy see what I will get and take action on it. Not sure what I should replay to them if that is even needed (need to check this, they are not done with their part yet).\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/\")\nasync def root():\n print() <- how to get the data here?\n return {\"message\": \"ok\"}\n```\n\n```text\nfrom fastapi import FastAPI, Request\n\napp = FastAPI()\n\n\n@app.get(\"/\")\ndef read_root(request: Request):\n print(request.headers)\n return {}\n```\n\n```text\n{\n \"host\":\"127.0.0.1:8000\",\n \"connection\":\"keep-alive\",\n \"accept\":\"application/json\",\n \"sec-fetch-site\":\"same-origin\",\n \"sec-fetch-mode\":\"cors\",\n \"sec-fetch-dest\":\"empty\",\n \"referer\":\"http://127.0.0.1:8000/docs\",\n \"accept-encoding\":\"gzip, deflate, br\",\n \"accept-language\":\"en-US,en;q=0.9,tr;q=0.8\",\n \"cookie\":\"csrftoken=sdf6ty78uewfıfehq7y8fuq; _ga=GA.1.11242141,1234423\"\n}\n```\n\n```text\n@app.get(\"/\")\ndef read_root(request: Request):\n print(request.headers['accept'])\n return {}\n```\n\n```text\nOut: application/json\n```\n\n========================================\n\nComments:\n- If you mean how to request an HTTP(S) page, then you may be looking for could be requests.readthedocs.io/en/master or github.com/encode/httpx\n- No the other way around I want to dump what comes into the port. The web browser is just one example. How I should like to be able dump other request for other protocol.\n- Other than HTTP(S)? I don't think it's possible since uvicorn is an HTTP server. Probably some proxy in front of it can do this kind of job. Otherwise I don't know how to help\n- Ok, but it´s possible to dump the raw http(s) request?\n- You can handle the request object with a middleware, see fastapi.tiangolo.com/tutorial/middleware fastapi.tiangolo.com/advanced/middleware and starlette.io/middleware . Though, the raw request is quite difficult to get with python. Maybe there is a library that can take the request object and transform it, but I've never heard of it\n- Hey @olle.holm can you update your question with actually what you are trying to do, i 'd be happy to help.\n- @YagizcanDegirmenci I have updated it now, hope its more clear. They are not yet done with there part, so just want to start to prepare so Im ready when I get it.\n- @olle.holm yup, it's clear enough now, check my answer.","metadata":{"transformedAt":"2026-08-18T18:32:29.141Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":81,"estimatedTokens":739}}539{"id":"stack-58579158","source":"stackoverflow","questionId":58579158,"title":"Upload Image to Google Drive using PyDrive","tags":["python","pydrive","fastapi"],"text":"Title: Upload Image to Google Drive using PyDrive\nTags: python, pydrive, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have a silly question about PyDrive.\nI try to make a REST API using FastAPI that will upload an Image to Google Drive using PyDrive. Here is my code:\n\n```\nfrom fastapi import FastAPI, File\nfrom starlette.requests import Request\nfrom starlette.responses import JSONResponse\nfrom pydrive.auth import GoogleAuth\nfrom pydrive.drive import GoogleDrive\n\napp = FastAPI()\n\n@app.post('/upload')\ndef upload_drive(img_file: bytes=File(...)):\n g_login = GoogleAuth()\n g_login.LoadCredentialsFile(\"google-drive-credentials.txt\")\n\n if g_login.credentials is None:\n g_login.LocalWebserverAuth()\n elif g_login.access_token_expired:\n g_login.Refresh()\n else:\n g_login.Authorize()\n g_login.SaveCredentialsFile(\"google-drive-credentials.txt\")\n drive = GoogleDrive(g_login)\n \n file_drive = drive.CreateFile({'title':'test.jpg'})\n file_drive.SetContentString(img_file) \n file_drive.Upload()\n```\n\nAfter try to access my endpoint, i get this error:\n\n```\nfile_drive.SetContentString(img_file)\n File \"c:\\users\\aldho\\anaconda3\\envs\\fastai\\lib\\site-packages\\pydrive\\files.py\", line 155, in SetContentString\n self.content = io.BytesIO(content.encode(encoding))\nAttributeError: 'bytes' object has no attribute 'encode'\n```\n\nWhat should i do to complete this very simple task?\n\nthanks for your help!\n\n**\n\n### UPDATED - SOLVED\n\n**\n\nThanks for answer and comment from Stanislas Morbieu and the pydrive documentation example, here is my updated and working code:\n\n```\nfrom fastapi import FastAPI, File\nfrom starlette.requests import Request\nfrom starlette.responses import JSONResponse\nfrom pydrive.auth import GoogleAuth\nfrom pydrive.drive import GoogleDrive\nfrom PIL import Image\nimport os\n\napp = FastAPI()\n\n@app.post('/upload')\ndef upload_drive(filename, img_file: bytes=File(...)):\n try:\n g_login = GoogleAuth()\n g_login.LocalWebserverAuth()\n drive = GoogleDrive(g_login)\n \n file_drive = drive.CreateFile({'title':filename, 'mimeType':'image/jpeg'})\n \n if not os.path.exists('temp/' + filename):\n image = Image.open(io.BytesIO(img_file))\n image.save('temp/' + filename)\n image.close()\n\n file_drive.SetContentFile('temp/' + filename)\n file_drive.Upload()\n\n return {\"success\": True}\n except Exception as e:\n print('ERROR:', str(e))\n return {\"success\": False}\n```\n\nThanks guys\n\n========================================\n\nTop Answer:\nUse `file_drive.SetContentFile(img_path)`\n\nThis solved my problem\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI, File\nfrom starlette.requests import Request\nfrom starlette.responses import JSONResponse\nfrom pydrive.auth import GoogleAuth\nfrom pydrive.drive import GoogleDrive\n\napp = FastAPI()\n\n\n@app.post('/upload')\ndef upload_drive(img_file: bytes=File(...)):\n g_login = GoogleAuth()\n g_login.LoadCredentialsFile(\"google-drive-credentials.txt\")\n\n if g_login.credentials is None:\n g_login.LocalWebserverAuth()\n elif g_login.access_token_expired:\n g_login.Refresh()\n else:\n g_login.Authorize()\n g_login.SaveCredentialsFile(\"google-drive-credentials.txt\")\n drive = GoogleDrive(g_login)\n \n file_drive = drive.CreateFile({'title':'test.jpg'})\n file_drive.SetContentString(img_file) \n file_drive.Upload()\n```\n\n```text\nfile_drive.SetContentString(img_file)\n File \"c:\\users\\aldho\\anaconda3\\envs\\fastai\\lib\\site-packages\\pydrive\\files.py\", line 155, in SetContentString\n self.content = io.BytesIO(content.encode(encoding))\nAttributeError: 'bytes' object has no attribute 'encode'\n```\n\n```text\nfrom fastapi import FastAPI, File\nfrom starlette.requests import Request\nfrom starlette.responses import JSONResponse\nfrom pydrive.auth import GoogleAuth\nfrom pydrive.drive import GoogleDrive\nfrom PIL import Image\nimport os\n\napp = FastAPI()\n\n\n@app.post('/upload')\ndef upload_drive(filename, img_file: bytes=File(...)):\n try:\n g_login = GoogleAuth()\n g_login.LocalWebserverAuth()\n drive = GoogleDrive(g_login)\n \n file_drive = drive.CreateFile({'title':filename, 'mimeType':'image/jpeg'})\n \n if not os.path.exists('temp/' + filename):\n image = Image.open(io.BytesIO(img_file))\n image.save('temp/' + filename)\n image.close()\n\n file_drive.SetContentFile('temp/' + filename)\n file_drive.Upload()\n\n return {\"success\": True}\n except Exception as e:\n print('ERROR:', str(e))\n return {\"success\": False}\n```\n\n```text\nfile_drive.SetContentString(img_file.decode('utf-8'))\n```\n\n```text\nSetContentString\n```\n\n```text\nstr\n```\n\n```text\nbytes\n```\n\n```text\nimg_file\n```\n\n```text\nbytes\n```\n\n```text\nfile_drive.SetContentFile(img_path)\n```\n\n========================================\n\nComments:\n- Hello @stanislas-morbieu, thanks for your answer, however after try your code, i get this error: `UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte`\n- I forgot to consider this. I think you cannot use `SetContentString` then. `SetContentFile` might be the only option: you might have to save it to a temporary file though, in order to pass the filename as argument to `SetContentFile`.\n- Thanks, i also not know about this, i will post my updated and working code. Thank you very much for your answer","metadata":{"transformedAt":"2026-08-18T18:32:29.142Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":10,"totalLines":208,"estimatedTokens":1334}}540{"id":"stack-62915625","source":"stackoverflow","questionId":62915625,"title":"How to add docs to post body model on fast api view?","tags":["python","fastapi","pydantic"],"text":"Title: How to add docs to post body model on fast api view?\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nFor example imagine that we have two endpoints:\n\n```\nclass FooRequest(BaseModel):\n data: str\n\n@router.post(\"/foo/\", response_model=FooRequest)\nasync def foo_view(data: FooRequest) -> FooRequest:\n ...\n\n@router.get(\"/bar/\", response_model=FooRequest)\nasync def bar_view(data: str = Query(..., description=\"Data param\")) -> FooRequest:\n ...\n```\n\nIn swagger UI `/bar/` endpoint will have properly documented query param and `/foo/` will have some abstract example of post body without any description.\n\nSo how can I document post body model?\n\n========================================\n\nCode:\n```py\nclass FooRequest(BaseModel):\n data: str\n\n\n@router.post(\"/foo/\", response_model=FooRequest)\nasync def foo_view(data: FooRequest) -> FooRequest:\n ...\n\n\n@router.get(\"/bar/\", response_model=FooRequest)\nasync def bar_view(data: str = Query(..., description=\"Data param\")) -> FooRequest:\n ...\n```\n\n```text\n/bar/\n```\n\n```text\n/foo/\n```\n\n```text\nclass FooRequest(BaseModel):\n data: str\n\n class Config:\n schema_extra = {\n \"FooRequest\": {\n \"name\": \"Foo Request\",\n \"description\": \"Data param\",\n }\n }\n```\n\n```text\nfrom pydantic import Field\n\n...\n\nclass FooRequest(BaseModel):\n data: str = Field(..., example=\"Data param for Foo Request\")\n description: Optional[str] = Field(None, example=\"Description for Foo\")\n```\n\n```text\nfrom fastapi import Body\n\n...\n\nclass FooRequest(BaseModel):\n data: str\n\n\n@router.post(\"/foo/\", response_model=FooRequest)\nasync def foo_view(data: FooRequest = Body(\n ...,\n example={\n \"name\": \"Foo Request\",\n \"description\": \"data param\",\n },\n ),\n ) -> FooRequest:\n```\n\n```text\nConfig\n```\n\n```text\nschema_extra\n```\n\n```text\nField\n```\n\n```text\nField\n```\n\n```text\nPath\n```\n\n```text\nQuery\n```\n\n```text\nBody\n```\n\n```text\nBody\n```\n\n========================================\n\nComments:\n- Have you looked into the swagger documentation already? swagger.io/docs/specification/describing-request-body And in the FastAPI docs: fastapi.tiangolo.com/tutorial/body\n- `Field(..., description=\"foo\", example=\"bar\")` is exactly what I needed, tnx","metadata":{"transformedAt":"2026-08-18T18:32:29.142Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":14,"totalLines":130,"estimatedTokens":581}}541{"id":"stack-78315455","source":"stackoverflow","questionId":78315455,"title":"FastAPI error when using Annotated in Class dependencies","tags":["python","fastapi"],"text":"Title: FastAPI error when using Annotated in Class dependencies\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nFastAPI added support for Annotated (and started recommending it) in version 0.95.0.\n\nAdditionally, FastAPI has a very powerful but intuitive Dependency Injection system (documentation). Moreover, FastAPI support Classes as Dependencies.\n\nHowever, it seams like `Annotated` cannot be used in class dependencies, but on function dependencies.\n\nI use FastAPI version `0.110.1`.\n\n```\nfrom __future__ import annotations\n\nfrom typing import Annotated\n\nfrom fastapi import FastAPI, Depends, Query\n\napp = FastAPI()\n\nclass ClassDependency:\n def __init__(self, name: Annotated[str, Query(description=\"foo\")]):\n self.name = name\n\nasync def function_dependency(name: Annotated[str, Query(description=\"foo\")]) -> dict:\n return {\"name\": name}\n\n@app.get(\"/\")\nasync def search(c: Annotated[ClassDependency, Depends(function_dependency)]) -> dict:\n return {\"c\": c.name}\n```\n\nThe example above works without errors, but if I replace `Depends(function_dependency)` with `Depends(ClassDependency)` an exception is raised with the following message:\n\n```\npydantic.errors.PydanticUndefinedAnnotation: name 'Query' is not defined\n```\n\nThen, if I remove `Annotated` from the ClassDependency, by replacing the `name: Annotated[str, Query(description=\"foo\")]` with the `name: str`, the example works.\n\n**My question**: Can I use Class dependencies and put `Annotated` to the parameters set in the constructor? Because it seams this is not working.\n\n**My need**: I want to have a class hierarchy for the query params of my api endpoints and provide validation and documentation extras for each of the param.\n\n========================================\n\nCode:\n```text\nfrom __future__ import annotations\n\nfrom typing import Annotated\n\nfrom fastapi import FastAPI, Depends, Query\n\napp = FastAPI()\n\n\nclass ClassDependency:\n def __init__(self, name: Annotated[str, Query(description=\"foo\")]):\n self.name = name\n\nasync def function_dependency(name: Annotated[str, Query(description=\"foo\")]) -> dict:\n return {\"name\": name}\n\n\n@app.get(\"/\")\nasync def search(c: Annotated[ClassDependency, Depends(function_dependency)]) -> dict:\n return {\"c\": c.name}\n```\n\n```text\npydantic.errors.PydanticUndefinedAnnotation: name 'Query' is not defined\n```\n\n```text\nAnnotated\n```\n\n```text\n0.110.1\n```\n\n```text\nDepends(function_dependency)\n```\n\n```text\nDepends(ClassDependency)\n```\n\n```text\nAnnotated\n```\n\n```text\nname: Annotated[str, Query(description=\"foo\")]\n```\n\n```text\nname: str\n```\n\n```text\nAnnotated\n```\n\n```text\nfrom __future__ import annotations\n```\n\n========================================\n\nComments:\n- What version of fastapi are you using? It works in `0.110.0` for me. Btw if you are using class dependencies it is enough to say `c: Annotated[ClassDependency, Depends()]`\n- I use `0.110.1`, I don't think they have break it on their latest patch. Are you sure it works? Did you the exact example? Maybe I am missing something.\n- Remove `from __future__ import annotations` and it will work\n- Thanks a lot! Fixed! You may provide it as a solution for anybody else having the same issue.","metadata":{"transformedAt":"2026-08-18T18:32:29.142Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":11,"totalLines":119,"estimatedTokens":796}}542{"id":"stack-63004799","source":"stackoverflow","questionId":63004799,"title":"FastApi get request shows validation error","tags":["python","sqlalchemy","fastapi","pydantic"],"text":"Title: FastApi get request shows validation error\nTags: python, sqlalchemy, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI'm getting this error when I try to get some data from my postgre db and using fastapi.\n\nhttps://i.sstatic.net/g6owt.png\n\nI don't know why it happens...but here is my code, thank you for your help.\n\n**Route**\n\n```\n@router.get(\"/fuentes\", response_model=FuenteSerializer.MFuente) # **sqlalchemy model**\n\n```\nclass MFuente(Base):\n __tablename__ = 'M_fuentes'\n\n idfuentes = Column(Integer, primary_key=True)\n idproductos = Column(ForeignKey('M_productos.idproductos', ondelete='RESTRICT', onupdate='RESTRICT'), index=True)\n autoapp = Column(CHAR(2))\n rutFabricante = Column(String(12))\n elemento = Column(String(100))\n estado = Column(Integer)\n stype = Column(Integer)\n aql = Column(String(5))\n equiv = Column(String(5))\n division = Column(String(100))\n nu = Column(Integer)\n filexcel = Column(String(100))\n\n M_producto = relationship('MProducto')\n```\n\n**Serializer / schema**\n\n```\nclass MFuente(BaseModel):\n\n idfuentes: int\n autoapp: str\n fecregistro: datetime.date\n rutFabricante: str\n elemento: str\n estado: int\n stype: int\n aql: str\n equiv: str\n division: str\n fileexel: str\n productos: List[MProducto]\n\n class Config:\n orm_mode = True\n\ndef get_fuente(db: Session, skip: int = 0, limit: int = 100):\n return db.query(Fuente).offset(skip).limit(limit).all()\n```\n\n========================================\n\nCode:\n```text\n@router.get(\"/fuentes\", response_model=FuenteSerializer.MFuente) # <--- WHEN I REMOVE RESPONSE_MODEL WORKS AND RETURNS A JSON DATA DIRECTLY FROM MODEL I GUESS\n async def read_fuentes(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):\n fuentes = FuenteSerializer.get_fuente(db, skip=skip, limit=limit)\n return fuentes\n```\n\n```text\nclass MFuente(Base):\n __tablename__ = 'M_fuentes'\n\n idfuentes = Column(Integer, primary_key=True)\n idproductos = Column(ForeignKey('M_productos.idproductos', ondelete='RESTRICT', onupdate='RESTRICT'), index=True)\n autoapp = Column(CHAR(2))\n rutFabricante = Column(String(12))\n elemento = Column(String(100))\n estado = Column(Integer)\n stype = Column(Integer)\n aql = Column(String(5))\n equiv = Column(String(5))\n division = Column(String(100))\n nu = Column(Integer)\n filexcel = Column(String(100))\n\n M_producto = relationship('MProducto')\n```\n\n```text\nclass MFuente(BaseModel):\n\n idfuentes: int\n autoapp: str\n fecregistro: datetime.date\n rutFabricante: str\n elemento: str\n estado: int\n stype: int\n aql: str\n equiv: str\n division: str\n fileexel: str\n productos: List[MProducto]\n\n class Config:\n orm_mode = True\n\n\ndef get_fuente(db: Session, skip: int = 0, limit: int = 100):\n return db.query(Fuente).offset(skip).limit(limit).all()\n```\n\n```text\nclass MFuente(BaseModel):\n name: str\n value: int\n\n@app.get(\"/items/{name}\", response_model=MFuente)\nasync def get_item(name: str):\n query = fuente_db.select().where(fuente_db.c.name == name)\n return await database.fetch_all(query)\n```\n\n```text\nresponse -> name\n field required (type=value_error.missing)\nresponse -> value\n field required (type=value_error.missing)\n```\n\n```text\nfrom typing import List\n...\n@app.get(\"/items/{name}\", response_model=List[MFuente])\n```\n\n```text\nINFO: 127.0.0.1:52872 - \"GET /items/masteryoda HTTP/1.1\" 200 OK\n```\n\n```text\n@router.get(\"/fuentes\", response_model=List[FuenteSerializer.MFuente]) \n ^^^^\n```\n\n========================================\n\nComments:\n- My guess is that you are describing the response model as a single Fuente, while returning an array of Fuentes (or whatever that thing is). Also be sure to check the type of FuenteSerializer.get_fuente(db, skip=skip, limit=limit). If it's not of type Fuente, it cause problems","metadata":{"transformedAt":"2026-08-18T18:32:29.142Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":8,"totalLines":152,"estimatedTokens":964}}543{"id":"stack-67399724","source":"stackoverflow","questionId":67399724,"title":"What is the best way to stop Uvicorn server programmatically?","tags":["fastapi","uvicorn"],"text":"Title: What is the best way to stop Uvicorn server programmatically?\nTags: fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nIn Docker, I run uvicorn with bootstrap.sh & command line. In code there is a condition about public key file, if exception occurs, server needs to shutdown.\n\nSo what I want to do in main.py is here (It is FastAPI).\n\n```\npublic_key = None\n\ntry:\n with open(PUBLIC_KEY_FILE) as public_key_file:\n public_key = public_key_file.read()\nexcept Exception as f_error:\n logger.exception(f_error)\n module = util.find_spec(\"uvicorn\")\n\n if module:\n uvicorn = import_module('uvicorn')\n uvicorn.stop() # what I want to do\n```\n\nHowever, I couldn't find a way to shutdown uvicorn server programmatically. What would be the best approach?\n\n========================================\n\nTop Answer:\nGracefully Shutting Down Uvicorn running FastAPI Application\n\nThe key libraries to achieve graceful shutting down to a Uvicorn server running a FastAPI application are the built in `os` and `signal` modules.\nGiven an endpoint with which a client can request the server to shutdown.\n\n```\nos.kill(os.getpid(), signal.SIGINT)\n```\n\n`os.getpid()` retrieves the running process' system ID and then `signal.SIGINT` is passed to the process to signal an interrupt.\nSIGTERM and SIGINT can be used to achieve the same result.\n\nLinks:\n\n- os.kill\n\n- SIGINT\n\n```\nimport os\nimport signal\nimport fastapi\nimport uvicorn\n\napp = fastapi.FastAPI()\n\ndef hello():\n return fastapi.Response(status_code=200, content='Hello, world!')\n\ndef shutdown():\n os.kill(os.getpid(), signal.SIGTERM)\n return fastapi.Response(status_code=200, content='Server shutting down...')\n\n@app.on_event('shutdown')\ndef on_shutdown():\n print('Server shutting down...')\n\napp.add_api_route('/hello', hello, methods=['GET'])\napp.add_api_route('/shutdown', shutdown, methods=['GET'])\n\nif __name__ == '__main__':\n uvicorn.run(app, host='localhost', port=8000)\n```\n\n```\nimport requests\n\nif __name__ == '__main__':\n print(requests.get('http://localhost:8000/hello').content)\n print(requests.get('http://localhost:8000/shutdown').content)\n```\n\nhttps://gist.github.com/BnJam/8123540b1716c81922169fa4f7c43cf0\n\n========================================\n\nCode:\n```py\npublic_key = None\n\ntry:\n with open(PUBLIC_KEY_FILE) as public_key_file:\n public_key = public_key_file.read()\nexcept Exception as f_error:\n logger.exception(f_error)\n module = util.find_spec(\"uvicorn\")\n\n if module:\n uvicorn = import_module('uvicorn')\n uvicorn.stop() # what I want to do\n```\n\n```text\nexcept\n```\n\n```text\ntry:\n DB_CONN = os.environ[\"DB_CONN\"]\n\nexcept Exception as e:\n print(f\"Missing env variable value for {e}. Terminating.\")\n sys.exit(4)\n```\n\n```py\nos.kill(os.getpid(), signal.SIGINT)\n```\n\n```py\nimport os\nimport signal\nimport fastapi\nimport uvicorn\n\napp = fastapi.FastAPI()\n\ndef hello():\n return fastapi.Response(status_code=200, content='Hello, world!')\n\ndef shutdown():\n os.kill(os.getpid(), signal.SIGTERM)\n return fastapi.Response(status_code=200, content='Server shutting down...')\n\n@app.on_event('shutdown')\ndef on_shutdown():\n print('Server shutting down...')\n\napp.add_api_route('/hello', hello, methods=['GET'])\napp.add_api_route('/shutdown', shutdown, methods=['GET'])\n\nif __name__ == '__main__':\n uvicorn.run(app, host='localhost', port=8000)\n```\n\n```py\nimport requests\n\nif __name__ == '__main__':\n print(requests.get('http://localhost:8000/hello').content)\n print(requests.get('http://localhost:8000/shutdown').content)\n```\n\n```text\nos\n```\n\n```text\nsignal\n```\n\n```text\nos.getpid()\n```\n\n```text\nsignal.SIGINT\n```\n\n```text\nimport asyncio\nimport uvicorn\n\nasync def main():\n server = uvicorn.Server(uvicorn.Config(app))\n asyncio.create_task(server.serve())\n try:\n await do_something()\n except:\n await server.shutdown()\n```\n\n```text\nServer\n```\n\n```text\nshutdown()\n```\n\n```text\ndo_something()\n```\n\n```text\nexcept\n```\n\n========================================\n\nComments:\n- Raising an exception (or re-raising `f_error`) inside your `except` clause would terminate the current application unless there's another level of exception handling outside of this code. Would that work?\n- @MatsLindh Yes it works and it actually a quite good work around, thank you!\n- Does this answer your question? How to start a Uvicorn + FastAPI in background when testing with PyTest\n- duplicate of stackoverflow.com/q/57412825/1032286","metadata":{"transformedAt":"2026-08-18T18:32:29.142Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":15,"totalLines":204,"estimatedTokens":1108}}544{"id":"stack-68546099","source":"stackoverflow","questionId":68546099,"title":"How to pass templates location to all views in FastAPI","tags":["jinja2","fastapi"],"text":"Title: How to pass templates location to all views in FastAPI\nTags: jinja2, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have a FastAPI web app, where I would like to use a templating language.\nRight now, in order to use jinja2 I have to indicate where the templates folder is located by setting a templates variable like this:\n\n```\ntemplates = Jinja2Templates(directory=\"templates\")\n```\n\nI also have several view files for various pages and purposes, like `home.py`, `about.py`, `db.py` etc.\n\nIf I set up a templates variable once in `main.py` and then import it into view files like this:\n\n```\nfrom main import templates\n```\n\nI get all kind of circular import errors. So I have to set up a templates variable in every view file separately which is not optimal.\n\nHow can I set templates location once in the `main.py` and then make all view files aware of this location?\n\n========================================\n\nCode:\n```text\ntemplates = Jinja2Templates(directory=\"templates\")\n```\n\n```text\nfrom main import templates\n```\n\n```text\nhome.py\n```\n\n```text\nabout.py\n```\n\n```text\ndb.py\n```\n\n```text\nmain.py\n```\n\n```text\nmain.py\n```\n\n```text\ndef get_templates():\n return Jinja2Templates(directory=...)\n```\n\n```text\nfrom dependencies import get_templates\n\n...\n\n@router.get('...')\nasync def display_xyz(templates: Jinja2Templates = Depends(get_templates))\n```\n\n```text\ntemplating.py\n```\n\n```text\n__init__.py\n```\n\n```text\nDepends\n```\n\n```text\ndependencies.py\n```\n\n```text\napp_services.py\n```\n\n```text\n__init__.py\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.142Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":15,"totalLines":92,"estimatedTokens":378}}545{"id":"stack-65103017","source":"stackoverflow","questionId":65103017,"title":"In aiohttp or httpx do I need to close session/client on application shutdown","tags":["python","httprequest","aiohttp","fastapi","httpx"],"text":"Title: In aiohttp or httpx do I need to close session/client on application shutdown\nTags: python, httprequest, aiohttp, fastapi, httpx\nSource: Stack Overflow\n\nQuestion:\nI am using httpx library but I think the principle for aiohttp is the same.\nIf I create and reuse AsyncClient for multiple requests throughout the lifetime of the application do I need to call `aclose()` (or `close` if use Client) at the application shutdown event? Or will those connections die themselves.\n\nWhat if I run application in Docker container? Will that be a factor as well?\n\nI don't understand what's going on underneath AsyncClient or Client (or ClientSession in aoihttp) objects.\n\nThanks for help.\n\n========================================\n\nCode:\n```text\naclose()\n```\n\n```text\nclose\n```\n\n```text\nfrom fastapi import FastAPI\nimport httpx\n\napp = FastAPI()\n\nitems = {}\nclient = None\n\n\n@app.on_event(\"startup\")\nasync def startup_event():\n items[\"foo\"] = {\"name\": \"Fighters\"}\n items[\"bar\"] = {\"name\": \"Tenders\"}\n client = httpx.AsyncClient()\n\n@app.on_event(\"shutdown\")\nasync def shutdown_event():\n items[\"foo\"] = {\"name\": \"Fighters\"}\n items[\"bar\"] = {\"name\": \"Tenders\"}\n await client.aclose()\n```\n\n```text\nstartup\n```\n\n```text\nshutdown\n```\n\n========================================\n\nComments:\n- Typically the OS will close all connections open by a process if the process has ended. The same is valid for Docker containers, they are just isolated processes.\n- I upvoted your answer but I don't think that is the answer I was looking for in this question, as I was trying to understand do I need to call aclose() on application shutdown specifically or connection will be closed automatically. The answer below answers it a bit better.\n- Thanks @Isabi , but that's not exactly what I am asking. I wonder what can happen if I don't close client on application shutdown.","metadata":{"transformedAt":"2026-08-18T18:32:29.142Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":62,"estimatedTokens":467}}546{"id":"stack-69388337","source":"stackoverflow","questionId":69388337,"title":"FastApi pydantic: Json object inside a json object validation error","tags":["python","json","fastapi","pydantic"],"text":"Title: FastApi pydantic: Json object inside a json object validation error\nTags: python, json, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nThere is a nested rule of class `DocumentSchema` in pydantic written in FastApi as follows:\n\n```\nclass DocumentSchema(BaseModel):\n clientName: str\n transactionId: str\n documentList: List[SingleDocumentSchema]\n```\n\nand\n\n```\nclass SingleDocumentSchema(BaseModel):\n documentInfo: DocumentInfoSchema\n articleList: List[DocumentArticleSchema]\n```\n\nand\n\n```\nclass DocumentInfoSchema(BaseModel):\n title: str\n type: str\n referenceId: int\n batchNoList: Optional[List]\n otherData: Optional[Json]\n```\n\nand\n\n```\nclass DocumentArticleSchema(BaseModel):\n type: str\n value: int\n accountType: Optional[AccountTypeEnums]\n accountId: Optional[int]\n otherData: Optional[Json]\n```\n\nand this is the snippets of python code which receives the message from Kafka and process it:\n\n```\ndef process(self) -> bool:\n try:\n DocumentSchema(\n **json.loads(self._message)\n )\n return self._process()\n\n except ValidationError as e:\n raise UnprocessableEntityException(e, self._topic)\n except ValueError as e:\n raise UnprocessableEntityException(e, self._topic)\n except Exception as e:\n raise UnprocessableEntityException(e, self._topic)\n```\n\nbut for input\n\n```\n{\n \"clientName\": \"amazon\",\n \"transactionId\": \"e3e60ca3-7eb1-4a55-ae35-c43f9b2ea3fd\",\n \"documentList\": [\n {\n \"documentInfo\": {\n \"title\": \"New Order\",\n \"type\": \"order\",\n \"referenceId\": 19488682\n },\n \"articleList\": [\n {\n \"type\": \"product_price\",\n \"value\": 1350,\n \"otherData\": {\n \"weight\": \"4 kg\"\n }\n }\n ]\n }\n ]\n}\n```\n\nIt reports the validation error\n\n{\"message\":\"1 validation error for DocumentSchema\\ndocumentList -> 0 -> articleList -> 0 -> otherData\\n JSON object must be str, bytes or bytearray (type=type_error.json)\"}\n\nI should mention that without `OtherData` everything is Ok.\n\nI don't know how to fix it.\n\nThanks in advance.\n\n========================================\n\nTop Answer:\nPydantic error object have json attribute,\n\n```\nerrors.json()\n```\n\n========================================\n\nCode:\n```text\nclass DocumentSchema(BaseModel):\n clientName: str\n transactionId: str\n documentList: List[SingleDocumentSchema]\n```\n\n```text\nclass SingleDocumentSchema(BaseModel):\n documentInfo: DocumentInfoSchema\n articleList: List[DocumentArticleSchema]\n```\n\n```text\nclass DocumentInfoSchema(BaseModel):\n title: str\n type: str\n referenceId: int\n batchNoList: Optional[List]\n otherData: Optional[Json]\n```\n\n```text\nclass DocumentArticleSchema(BaseModel):\n type: str\n value: int\n accountType: Optional[AccountTypeEnums]\n accountId: Optional[int]\n otherData: Optional[Json]\n```\n\n```text\ndef process(self) -> bool:\n try:\n DocumentSchema(\n **json.loads(self._message)\n )\n return self._process()\n\n except ValidationError as e:\n raise UnprocessableEntityException(e, self._topic)\n except ValueError as e:\n raise UnprocessableEntityException(e, self._topic)\n except Exception as e:\n raise UnprocessableEntityException(e, self._topic)\n```\n\n```text\n{\n \"clientName\": \"amazon\",\n \"transactionId\": \"e3e60ca3-7eb1-4a55-ae35-c43f9b2ea3fd\",\n \"documentList\": [\n {\n \"documentInfo\": {\n \"title\": \"New Order\",\n \"type\": \"order\",\n \"referenceId\": 19488682\n },\n \"articleList\": [\n {\n \"type\": \"product_price\",\n \"value\": 1350,\n \"otherData\": {\n \"weight\": \"4 kg\"\n }\n }\n ]\n }\n ]\n}\n```\n\n```text\nDocumentSchema\n```\n\n```text\nOtherData\n```\n\n```text\nJson\n```\n\n```text\nstr\n```\n\n```text\nbytes\n```\n\n```text\nbytearray\n```\n\n```text\nOptional[Dict]\n```\n\n```text\nkey: value\n```\n\n```text\nerrors.json()\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.142Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":15,"totalLines":218,"estimatedTokens":971}}547{"id":"stack-69223063","source":"stackoverflow","questionId":69223063,"title":"How to reconnect to ray cluster after the cluster restarted?","tags":["python","fastapi","ray"],"text":"Title: How to reconnect to ray cluster after the cluster restarted?\nTags: python, fastapi, ray\nSource: Stack Overflow\n\nQuestion:\nI have a question regarding the reconnection process between a ray cluster and a FastAPI server. On FastAPI I init/connect to the ray cluster in the startup event:\n\n```\n@app.on_event(\"startup\")\nasync def init_ray():\n ...\n ray.init(address=f'{ray_head_host}:{ray_head_port}', _redis_password=ray_redis_password, namespace=ray_serve_namespace)\n\n ...\n```\n\nIn the case of a restart of the ray cluster I ran into a problem when I want to use the ray API in some FastAPI routes:\n\n```\nException: Ray Client is not connected. Please connect by calling `ray.connect`.\n```\n\nSo it seems that the connection from FastAPI to ray is lost (this is also confirmed by `ray.is_initilized()` ==> `False`). But if I try to re-connect using `ray.init()` I got the following error:\n\n```\nException: ray.connect() called, but ray client is already connected\n```\n\nI also tried to call `ray.shutdown()` infornt of the re-init call without success.\n\nMaybe someone has an idea how to reconnect from FastAPI?\n\n========================================\n\nTop Answer:\nI end up using a context manager to manage the connection to ray.\n\n```\nclass RayConnection:\n def __init__(self, address, **kwargs):\n ray.init(address=address, **kwargs)\n\n def __enter__(self):\n return self\n\n def __exit__(self, typ, value, traceback):\n ray.shutdown()\n```\n\nThen you can wrap your ray calls in it and have it always properly closed and re-opened.\n\n```\nwith RayConnection():\n print(ray.available_resources())\n```\n\n========================================\n\nCode:\n```py\n@app.on_event(\"startup\")\nasync def init_ray():\n ...\n ray.init(address=f'{ray_head_host}:{ray_head_port}', _redis_password=ray_redis_password, namespace=ray_serve_namespace)\n\n ...\n```\n\n```text\nException: Ray Client is not connected. Please connect by calling `ray.connect`.\n```\n\n```text\nException: ray.connect() called, but ray client is already connected\n```\n\n```text\nray.is_initilized()\n```\n\n```text\nFalse\n```\n\n```text\nray.init()\n```\n\n```text\nray.shutdown()\n```\n\n```text\nimport threading\nfrom ray.util.client import ray as ray_stub\n\nclass RayConn(threading.Thread):\n def __init__(self):\n threading.Thread.__init__(self)\n self.daemon = True\n self.start()\n\n def run(self):\n while True:\n # sleep for 30 seconds\n time.sleep(30)\n if not ray_stub.is_connected():\n logger.error(\"Ray client is disconnected. Trying to reconnect\")\n try:\n try:\n ray.shutdown()\n logger.info(\"Shutdown complete.\")\n except BaseException as e:\n logger.error(f\"Failed to shutdown: {e}\")\n reestablish_conn() # your function that call ray.init() and task creation, if any\n logger.info(f\"Successfully reconnected, reconnect count: {reconnect_count}\")\n except BaseException as ee:\n logger.error(f\"Failed to to connect to ray head! {ee}\")\n\n\nRayConn()\n```\n\n```text\ninit_ray()\n```\n\n```py\nclass RayConnection:\n def __init__(self, address, **kwargs):\n ray.init(address=address, **kwargs)\n\n def __enter__(self):\n return self\n\n def __exit__(self, typ, value, traceback):\n ray.shutdown()\n```\n\n```py\nwith RayConnection():\n print(ray.available_resources())\n```\n\n========================================\n\nComments:\n- Sebastian, did you manage to solve it?","metadata":{"transformedAt":"2026-08-18T18:32:29.142Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":11,"totalLines":148,"estimatedTokens":893}}548{"id":"stack-66933306","source":"stackoverflow","questionId":66933306,"title":"Conditionally set FastAPI response model for route","tags":["python","sqlalchemy","orm","fastapi","pydantic"],"text":"Title: Conditionally set FastAPI response model for route\nTags: python, sqlalchemy, orm, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI'm trying to return a list of objects of type Company, including only \"approved\" ones, and with more or less attributes depending on whether the user requesting the list is a superuser or a regular user. This is my code so far:\n\n```\n@router.get(\"/\", response_model=List[schema.CompanyRegularUsers])\ndef get_companies(db: Session = Depends(get_db), is_superuser: bool = Depends(check_is_superuser)):\n \"\"\"\n If SU, also include sensitive data.\n \"\"\"\n if is_superuser:\n return crud.get_companies_admin(db=db)\n return crud.get_companies_user(db=db)\n#\n```\n\nThe function correctly returns the objects according to request (ie., only `is_approved=True` companies if a regular request, and both `is_approved=True` and `is_approved=False` if requested by a superuser. Problem is, both cases use `schema.CompanyRegularUsers`, and I'd like to use `schema.CompanySuperusers` when SU's make the request.\n\nHow can I achieve that feature? I.e, is there a way to conditionally set the `response_model` property of the decorator function?\n\nI've tried using `JSONResponse` and calling Pydantic's `schema.CompanySuperusers.from_orm()`, but it won't work with a list of Companies...\n\n========================================\n\nTop Answer:\nYou can try to use `Union` type operator.\n\nYour code would become\n\n```\nfrom typing import Union\n\n@router.get(\"/\", response_model=List[Union[schema.CompanyRegularUsers, schema.CompanySuperUser]])\n```\n\nthis way, you specify as response model a list of either `schema.CompanyRegularUsers` or `schema.CompanySuperUser`\n\nLet me know if it works, since I didn't test it\n\n========================================\n\nCode:\n```text\n@router.get(\"/\", response_model=List[schema.CompanyRegularUsers])\ndef get_companies(db: Session = Depends(get_db), is_superuser: bool = Depends(check_is_superuser)):\n \"\"\"\n If SU, also include sensitive data.\n \"\"\"\n if is_superuser:\n return crud.get_companies_admin(db=db)\n return crud.get_companies_user(db=db)\n#\n```\n\n```text\nis_approved=True\n```\n\n```text\nis_approved=True\n```\n\n```text\nis_approved=False\n```\n\n```text\nschema.CompanyRegularUsers\n```\n\n```text\nschema.CompanySuperusers\n```\n\n```text\nresponse_model\n```\n\n```text\nJSONResponse\n```\n\n```text\nschema.CompanySuperusers.from_orm()\n```\n\n```text\n...\nfrom pydantic import parse_obj_as\nfrom fastapi.responses import JSONResponse\nfrom fastapi.encoders import jsonable_encoder\n...\n\n@router.get(\"/\", response_model=List[schema.CompanyRegularUsers])\ndef get_companies(db: Session = Depends(get_db), is_superuser: bool = Depends(check_is_superuser)):\n \"\"\"\n If SU, also include sensitive data.\n \"\"\"\n if is_superuser:\n companies = parse_obj_as(List[schema.CompanyAdmin], crud.get_companies_admin(db=db))\n return JSONResponse(jsonable_encoder(companies))\n return crud.get_companies_user(db=db)\n```\n\n```text\nis_admin\n```\n\n```text\nparse_obj_as\n```\n\n```text\nCompanyAdmin\n```\n\n```text\njsonable_encoder\n```\n\n```text\nfrom typing import Union\n\n@router.get(\"/\", response_model=List[Union[schema.CompanyRegularUsers, schema.CompanySuperUser]])\n```\n\n```text\nUnion\n```\n\n```text\nschema.CompanyRegularUsers\n```\n\n```text\nschema.CompanySuperUser\n```\n\n========================================\n\nComments:\n- BTW it is better to return dict with list in key \"items\" for example, than just list. It is simpler to add some meta information, for example pagination\n- Thanks @Arthur Shiriev, that totally makes sense. Thing is, FastAPI's default response is a list. Do you know the \"correct way\" to return a dict, with the list (among other meta information)?\n- something like this gist.github.com/lesnik512/fbc802c431aea6428c0a85bc2f44fe7d\n- Thanks Isabi. But as far as I can tell, this will allow for either schema to be used, but still needs a way to actually controlling which of the two will be used for the response...\n- You have to control which one to return. Either you patch a function that does that for you, or you do that in the route function. Response models of the decorator are not dynamic, so you'll have to return the union of both models since you only know at runtime which one will be returned\n- @Isabi: But how would that function work? That's what I'm after, and my problem is both `get_companies_admin` and `get_companies_user` return a `Company` SQLAlchemy model (ie., with full attributes, including those I want to hide from regular users), which the `response_model=schema.CompanyRegularUsers` filters out for me. I think that filtering should occur on the `get_companies_user` function, but how could I accomplish that? Thanks for your time!\n- It works the same way you posted it `if is_superuser: return crud.get_companies_admin(db=db) return crud.get_companies_user(db=db)` Not sure about `sqlalchemy` how can work with pydantic, but this sketches the idea\n- @Isabi, that won't do because both functions return the same SQLAlchemy model. Filtering should occur during response. I ended up solving it as detailed in the accepted answer. Thank you for your time!","metadata":{"transformedAt":"2026-08-18T18:32:29.142Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":18,"totalLines":152,"estimatedTokens":1285}}549{"id":"stack-76012502","source":"stackoverflow","questionId":76012502,"title":"Can't reach RestAPI (FastAPI) from my Flutter web - Cross-Origin Request Blocked","tags":["python","flutter","docker","nginx","fastapi"],"text":"Title: Can't reach RestAPI (FastAPI) from my Flutter web - Cross-Origin Request Blocked\nTags: python, flutter, docker, nginx, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have a Linux Server. On that I have two Docker Containers.In the first one I am deploying my Flutter Web and in the other one I am running my RestAPI with FastAPI().\n\nI set both the Docker containers in the same Network, so the communication should work. I also set origins with `origins = ['*']` (Wildcard). I reverse proxy my Flutter web with `nginx` from the Linux server. I also include `*.crt` and `*.key` with nginx to my Flutter Web.\n\nNow, obviously, since my Flutter Web App has `https`, I cant make `http` calls. When I am trying to make a call with `https`, I get the Error (from catch): `\"XMLHttpRequest error\"`, and in the Browser Console I get:\n\nCross-Origin Request Blocked: The Same Origin Policy disallows reading\nthe remote resource at https://172.21.0.2:8070/. (Reason: CORS request\ndid not succeed). Status code: (null).\n\n(172.21.0.2 is the ip of the Docker and 8070 the port on RestApi running)\n\nI am new to the RestAPI world. I normaly develop only Frontend. But I wanted to give it a try. So I'm sorry if I expressed some things wrong. I am searching since days but cant find a solution to my problem. I would be grateful for any help! (If i missed some information or you need more, feel free to write in the comments, I will update the Question immediately!)\n\nThank You!\n\n========================================\n\nCode:\n```text\norigins = ['*']\n```\n\n```text\nnginx\n```\n\n```text\n*.crt\n```\n\n```text\n*.key\n```\n\n```text\nhttps\n```\n\n```text\nhttp\n```\n\n```text\nhttps\n```\n\n```text\n\"XMLHttpRequest error\"\n```\n\n```text\nfinal Uri tokenUri = Uri.https(urlList[index]['url']!, '');\n```\n\n```text\nfinal Uri tokenUri = Uri.parse('${urlList[index]['url']!}/');\n```\n\n```text\nhttp\n```\n\n```text\nhttps\n```\n\n========================================\n\nComments:\n- If an error happens in the API, the CORS headers will not be included - i.e. meaning that any attempt to make the request from the frontend will fail with a CORS error. Your browser will probably not trust self-signed crt/keys either - what happens if you go directly to `https://172.21.0.2:8070/` in your browser? What's the result then? (CORS is only checked when the request is made on behalf of another page). What about using `curl` to call the endpoint?\n- Same happened for me. For me it was during calling get method. So i changed to post method.It worked for me.\n- @MatsLindh ty for your response. I couldnt answer earlier. Since all of them running on the ubuntu server edition, I cant check in the Browser. I know that I can reach the Docker. I also checked the Network Monitor on Firefox and can see \"NS_ERROR_NET_TIMEOUT\". I deploy my API with with uvicorn through the Docker with : \"FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9\" .\n- You may find this and this, as well as this, this and this helpful","metadata":{"transformedAt":"2026-08-18T18:32:29.142Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":12,"totalLines":79,"estimatedTokens":740}}550{"id":"stack-76530308","source":"stackoverflow","questionId":76530308,"title":"Tests with FastAPI and PostgreSQL","tags":["postgresql","sqlalchemy","fastapi","pydantic","sqlmodel"],"text":"Title: Tests with FastAPI and PostgreSQL\nTags: postgresql, sqlalchemy, fastapi, pydantic, sqlmodel\nSource: Stack Overflow\n\nQuestion:\nI'm developing a backend app with FastAPI connected to a PostgreSQL database and I'm a bit stuck and lost with the tests good practices.\nI read a lot stackoverflow posts and blogs but I'm not really used to backend development and I still doesn't really understand what is the best practice.\n\nKnowing that I use SQLModel, it is suggested in the documentation to perform the tests with a DB SQLite in memory. The problem is that when I the explained approach, I am struck by the non-compatibility between PG and SQLite (about schemas). The point is that I am consuming an existing DB with several schemas and not just a public schema. So, when I run my tests, I encounter the error \"schema pouetpouet does not exist\".\n\nFinally, the question is: What should I do to test my app ?\n\n- Find a way to setup the compatibility between my prod Postgres DB and an in-memory SQLite DB ?\n\n- Apply my tests on a preprod Postgres DB and try to cleanup the added/removed items ? (what I did actually but I don't think it is a really good practice)\n\n- Setup a local Postgres server inside a Docker container ?\n\n- Mock a DB with kind of a Dict in the pytest test file ?\n\n- Use a third lib like testcontainers for exemple ?\n\n- Don't do tests ?\n\nAfter all, I'd like to do unit and integration tests so maybe there is not only one solution about my needs.\n\nHere is a really simplified version of my project:\n\nThe **architecture of my project**: (Consider that there is an __ init__.py file in each folder)\n\n```\napp/\n├── api/\n│ ├── core/\n│ │ ├── config.py #get the env settings and distribute it to the app\n│ │ ├── .env\n│ ├── crud/\n│ │ ├── items.py #the CRUD functions called by the router\n│ ├── db/\n│ │ ├── session.py #the get_session function handling the db engine\n│ ├── models/\n│ │ ├── items.py #the SQLModel object def as is in the db\n│ ├── routers/\n│ │ ├── items.py #the routing system\n│ ├── schemas/\n│ │ ├── items.py #the python object def as it is used in the app\n│ ├── main.py #the main app\n├── tests/\n│ ├── test_items.py #the pytest testing file\n```\n\nIn the **crud/items.py**:\n\n```\nfrom fastapi.encoders import jsonable_encoder\nfrom sqlmodel import Session, select\nfrom api.models import Item\nfrom api.schemas import ItemCreate\n\ndef get_item(db_session: Session, item_id: int) -> Item:\n query = select(Item).where(Item.id == item_id)\n return db_session.exec(query).first()\n\ndef create_new_item(db_session: Session, *, obj_input: ItemCreate) -> Item:\n obj_in_data = jsonable_encoder(obj_input)\n db_obj = Item(**obj_in_data)\n db_session.add(db_obj)\n db_session.commit()\n db_session.refresh(db_obj)\n return db_obj\n```\n\nIn the **db/session.py**:\n\n```\nfrom sqlalchemy.engine import Engine\nfrom sqlmodel import create_engine, Session\nfrom api.core.config import settings\n\nengine: Engine = create_engine(settings.SQLALCHEMY_DATABASE_URI, pool_pre_ping=True)\n\ndef get_session() -> Session:\n with Session(engine) as session:\n yield session\n```\n\nIn the **models/items.py**:\n\n```\nfrom sqlmodel import SQLModel, Field, MetaData\n\nmeta = MetaData(schema=\"pouetpouet\") # https://github.com/tiangolo/sqlmodel/issues/20\n\nclass Item(SQLModel, table=True):\n __tablename__ = \"cities\"\n # __table_args__ = {\"schema\": \"pouetpouet\"}\n metadata = meta\n\n id: int = Field(primary_key=True, default=None)\n city_name: str\n```\n\nIn the **routers/items.py**:\n\n```\nfrom fastapi import APIRouter, Depends, HTTPException\nfrom sqlmodel import Session\nfrom api.crud import get_item, create_new_item\nfrom api.db.session import get_session\nfrom api.models import Item\nfrom api.schemas import ItemRead, ItemCreate\n\nrouter = APIRouter(prefix=\"/api/items\", tags=[\"Items\"])\n\n@router.get(\"/{item_id}\", response_model=ItemRead)\ndef read_item(\n *,\n db_session: Session = Depends(get_session),\n item_id: int,\n) -> Item:\n item = get_item(db_session=db_session, item_id=item_id)\n if not item:\n raise HTTPException(status_code=404, detail=\"Item not found\")\n return item\n\n@router.post(\"/\", response_model=ItemRead)\ndef create_item(\n *,\n db_session: Session = Depends(get_session),\n item_input: ItemCreate,\n) -> Item:\n item = create_new_item(db_session=db_session, obj_input=item_input)\n return item\n```\n\nIn the **schemas/items.py**:\n\n```\nfrom typing import Optional\nfrom sqlmodel import SQLModel\n\nclass ItemBase(SQLModel):\n city_name: Optional[str] = None\n\nclass ItemCreate(ItemBase):\n pass\n\nclass ItemRead(ItemBase):\n id: int\n class Config:\n orm_mode: True\n```\n\nIn the **tests/test_items.py**:\n\n```\nfrom fastapi.testclient import TestClient\nfrom api.main import app\n\nclient = TestClient(app)\n\ndef test_create_item() -> None:\n data = {\"city_name\": \"Las Vegas\"}\n response = client.post(\"/api/items/\", json=data)\n assert response.status_code == 200\n content = response.json()\n assert content[\"city_name\"] == data[\"city_name\"]\n assert \"id\" in content\n```\n\nps: not being very experienced in backend development, do not hesitate to bring constructive remarks about my code if you notice something strange. It will be very well received.\n\n========================================\n\nCode:\n```text\napp/\n├── api/\n│ ├── core/\n│ │ ├── config.py #get the env settings and distribute it to the app\n│ │ ├── .env\n│ ├── crud/\n│ │ ├── items.py #the CRUD functions called by the router\n│ ├── db/\n│ │ ├── session.py #the get_session function handling the db engine\n│ ├── models/\n│ │ ├── items.py #the SQLModel object def as is in the db\n│ ├── routers/\n│ │ ├── items.py #the routing system\n│ ├── schemas/\n│ │ ├── items.py #the python object def as it is used in the app\n│ ├── main.py #the main app\n├── tests/\n│ ├── test_items.py #the pytest testing file\n```\n\n```text\nfrom fastapi.encoders import jsonable_encoder\nfrom sqlmodel import Session, select\nfrom api.models import Item\nfrom api.schemas import ItemCreate\n\n\ndef get_item(db_session: Session, item_id: int) -> Item:\n query = select(Item).where(Item.id == item_id)\n return db_session.exec(query).first()\n\n\ndef create_new_item(db_session: Session, *, obj_input: ItemCreate) -> Item:\n obj_in_data = jsonable_encoder(obj_input)\n db_obj = Item(**obj_in_data)\n db_session.add(db_obj)\n db_session.commit()\n db_session.refresh(db_obj)\n return db_obj\n```\n\n```text\nfrom sqlalchemy.engine import Engine\nfrom sqlmodel import create_engine, Session\nfrom api.core.config import settings\n\nengine: Engine = create_engine(settings.SQLALCHEMY_DATABASE_URI, pool_pre_ping=True)\n\n\ndef get_session() -> Session:\n with Session(engine) as session:\n yield session\n```\n\n```text\nfrom sqlmodel import SQLModel, Field, MetaData\n\nmeta = MetaData(schema=\"pouetpouet\") # https://github.com/tiangolo/sqlmodel/issues/20\n\n\nclass Item(SQLModel, table=True):\n __tablename__ = \"cities\"\n # __table_args__ = {\"schema\": \"pouetpouet\"}\n metadata = meta\n\n id: int = Field(primary_key=True, default=None)\n city_name: str\n```\n\n```text\nfrom fastapi import APIRouter, Depends, HTTPException\nfrom sqlmodel import Session\nfrom api.crud import get_item, create_new_item\nfrom api.db.session import get_session\nfrom api.models import Item\nfrom api.schemas import ItemRead, ItemCreate\n\nrouter = APIRouter(prefix=\"/api/items\", tags=[\"Items\"])\n\n\n@router.get(\"/{item_id}\", response_model=ItemRead)\ndef read_item(\n *,\n db_session: Session = Depends(get_session),\n item_id: int,\n) -> Item:\n item = get_item(db_session=db_session, item_id=item_id)\n if not item:\n raise HTTPException(status_code=404, detail=\"Item not found\")\n return item\n\n\n@router.post(\"/\", response_model=ItemRead)\ndef create_item(\n *,\n db_session: Session = Depends(get_session),\n item_input: ItemCreate,\n) -> Item:\n item = create_new_item(db_session=db_session, obj_input=item_input)\n return item\n```\n\n```text\nfrom typing import Optional\nfrom sqlmodel import SQLModel\n\n\nclass ItemBase(SQLModel):\n city_name: Optional[str] = None\n\n\nclass ItemCreate(ItemBase):\n pass\n\nclass ItemRead(ItemBase):\n id: int\n class Config:\n orm_mode: True\n```\n\n```text\nfrom fastapi.testclient import TestClient\nfrom api.main import app\n\nclient = TestClient(app)\n\ndef test_create_item() -> None:\n data = {\"city_name\": \"Las Vegas\"}\n response = client.post(\"/api/items/\", json=data)\n assert response.status_code == 200\n content = response.json()\n assert content[\"city_name\"] == data[\"city_name\"]\n assert \"id\" in content\n```\n\n```text\nmodels\n```\n\n```text\nschemas\n```\n\n========================================\n\nComments:\n- *\"I'd like to do unit and integration tests so maybe there is not only one solution\"* Absolutely. IMO no database (not even SQLite) should ever be touched *at all* in any **unit test** whatsoever (unless you are writing a database engine of course). Side effects are haram. Use proper mocks. Test your own logic, not the database engine library. With integration tests however, it is almost the complete opposite. Try to emulate the production environment as closely as possible. Still, I am afraid this question is too opinion-based for SO.\n- Alright @DaniilFajnberg but that's what I don't understand. If I want to unit test the create_new_item() in crud/items.py or the create_item() in the routers/items.py each time I have dependencies to the DB session ... Sorry if it's too opinion-based but I though I was just missing something with FastAPI !\n- Yes, you simply mock the `Session` object. E.g. using `unittest.mock.create_autospec`. Then ensure the expected calls were made via `assert_called_once_with` for example.\n- I'm really sorry but I don't get it... I tried for the routers/items.py the following but it doesn't makes any sense ... def test_create_item(): data = {\"city_name\": \"London\"} mocked_create_item = create_autospec(create_item, return_value=data) mocked_create_item(get_session(), data) mocked_create_item.assert_called_once_with(get_session(), data) --EDIT-- sorry for the non-indentation available in the comments\n- Since there are a lot of questions in one here (and this thread is closed anyway), I would suggest you ask a separate question focusing *only* on specifically how you should write a unit test for the `create_new_item` function in such a way that you mock out the database engine and properly isolate the unit being tested. I can prepare a suggestion/answer for you.\n- Yes, you're right, it will be easier. I just put my question here : stackoverflow.com/questions/76533018/unit-tests-in-fastapi Thank you for your answers so far!\n- I mostly agree with your answers to the six questions. I *strongly* disagree with the article you cite in 4); I think the author just misuses mocks and therefore argues against a straw man. My opinion is that *in general* mocks should be used *extensively* in unit tests and *sparingly* (or not at all) in integration/e2e tests. Loved point 6) though.\n- @DaniilFajnberg Mocks are an industry standard, I tend to use them mostly for testing non-DB related stuff (like an external API response or anything 3rd party related to the app). For data testing, I prefer test DBs and/or integration tests to see the whole picture! Thank you for the 6th :D\n- @JohnMoutafis Thanks a lot for your time all those explanations ! It was really clear ! Also thx for SQLModel tips ! I certainly misunderstood the way to implement the ItemCreate, ItemUpdate and so on so I'll check the documentations !\n- @FloCAD happy to help :) and don't get discouraged, all of us have been where you are at some point or another!","metadata":{"transformedAt":"2026-08-18T18:32:29.142Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":332,"estimatedTokens":2895}}551{"id":"stack-61144192","source":"stackoverflow","questionId":61144192,"title":"Insert a nested schema into a database with fastAPI?","tags":["python-3.x","fastapi","pydantic"],"text":"Title: Insert a nested schema into a database with fastAPI?\nTags: python-3.x, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI have recently come to know about fastAPI and worked my way through the tutorial and other docs. Although fastAPI is pretty well documented, I couldn't find information about how to process a nested input when working with a database. \n\nFor testing, I wrote a very small **family** API with two models:\n\n```\nclass Member(Base):\n __tablename__ = 'members'\n\n id = Column(Integer, primary_key=True, server_default=text(\"nextval('members_id_seq'::regclass)\"))\n name = Column(String(128), nullable=False)\n age = Column(Integer, nullable=True)\n family_id = Column(Integer, ForeignKey('families.id', deferrable=True, initially='DEFERRED'), nullable=False, index=True)\n\n family = relationship(\"Family\", back_populates=\"members\")\n\nclass Family(Base):\n __tablename__ = 'families'\n\n id = Column(Integer, primary_key=True, server_default=text(\"nextval('families_id_seq'::regclass)\"))\n family_name = Column(String(128), nullable=False)\n\n members = relationship(\"Member\", back_populates=\"family\")\n```\n\nand I created a Postgres database with two tables and the relations described here. With schema definitions and a crud file as in the fastAPI tutorial, I can create individual families and members and view them in a nested fashion with a get request. Here is the nested schema:\n\n```\nclass Family(FamilyBase):\n id: int\n members: List[Member]\n\n class Config:\n orm_mode = True\n```\n\nSo far, so good. Now, I would like to add a post view which accepts the nested structure as input and populates the database accordingly. The documentation at https://fastapi.tiangolo.com/tutorial/body-nested-models/ shows how to do this in principle, but it misses the database (i.e. crud) part.\n\nAs the input will not have `id` fields and obviously doesn't need to specify `family_id`, I have a `MemberStub` schema and the `NestedFamilyCreate` schema as follows:\n\n```\nclass MemberStub(BaseModel):\n name: str\n age: int\n\nclass NestedFamilyCreate(BaseModel):\n family_name: str\n members: List[MemberStub]\n```\n\nIn my routing routine `families.py` I have:\n\n```\n@app.post('/nested-families/', response_model=schemas.Family)\ndef create_family(family: schemas.NestedFamilyCreate, db: Session = Depends(get_db)):\n # no check for previous existence as names can be duplicates\n return crud.create_nested_family(db=db, family=family)\n```\n\n(the response_model points to the nested view of a family with all members including all ids; see above).\n\nWhat I cannot figure out is how to write the `crud.create_nested_family` routine. Based on the simple create as in the tutorial, this looks like:\n\n```\ndef create_nested_family(db: Session, family: schemas.NestedFamilyCreate):\n # split information in family and members\n members = family.members\n core_family = None # ??? This is where I get stuck\n db_family = models.Family(**family.dict()) # This fails\n db.add(db_family)\n db.commit()\n db.refresh(db_family)\n return db_family\n```\n\nSo, I can extract the members and can loop through them, but I would first need to create a new `db_family` record which must not contain the members. Then, with `db.refresh`, I would get the new family_id back, which I could add to each record of `members`. But how can I do this? If I understand what is required here, I would need to achieve some mapping of my nested schema onto a plain schema for FamilyCreate (which works by itself) and a plain schema for MemberCreate (which also works by itself). But how can I do this?\n\n========================================\n\nCode:\n```text\nclass Member(Base):\n __tablename__ = 'members'\n\n id = Column(Integer, primary_key=True, server_default=text(\"nextval('members_id_seq'::regclass)\"))\n name = Column(String(128), nullable=False)\n age = Column(Integer, nullable=True)\n family_id = Column(Integer, ForeignKey('families.id', deferrable=True, initially='DEFERRED'), nullable=False, index=True)\n\n family = relationship(\"Family\", back_populates=\"members\")\n\n\nclass Family(Base):\n __tablename__ = 'families'\n\n id = Column(Integer, primary_key=True, server_default=text(\"nextval('families_id_seq'::regclass)\"))\n family_name = Column(String(128), nullable=False)\n\n members = relationship(\"Member\", back_populates=\"family\")\n```\n\n```text\nclass Family(FamilyBase):\n id: int\n members: List[Member]\n\n class Config:\n orm_mode = True\n```\n\n```text\nclass MemberStub(BaseModel):\n name: str\n age: int\n\nclass NestedFamilyCreate(BaseModel):\n family_name: str\n members: List[MemberStub]\n```\n\n```text\n@app.post('/nested-families/', response_model=schemas.Family)\ndef create_family(family: schemas.NestedFamilyCreate, db: Session = Depends(get_db)):\n # no check for previous existence as names can be duplicates\n return crud.create_nested_family(db=db, family=family)\n```\n\n```text\ndef create_nested_family(db: Session, family: schemas.NestedFamilyCreate):\n # split information in family and members\n members = family.members\n core_family = None # ??? This is where I get stuck\n db_family = models.Family(**family.dict()) # This fails\n db.add(db_family)\n db.commit()\n db.refresh(db_family)\n return db_family\n```\n\n```text\nid\n```\n\n```text\nfamily_id\n```\n\n```text\nMemberStub\n```\n\n```text\nNestedFamilyCreate\n```\n\n```text\nfamilies.py\n```\n\n```text\ncrud.create_nested_family\n```\n\n```text\ndb_family\n```\n\n```text\ndb.refresh\n```\n\n```text\nmembers\n```\n\n```text\ndef create_nested_family(db: Session, family: schemas.NestedFamilyCreate):\n # split information in family and members\n family_data = family.dict()\n member_data = family_data.pop('members', None) # ToDo: handle error if no members\n db_family = models.Family(**family_data)\n db.add(db_family)\n db.commit()\n db.refresh(db_family)\n # get family_id\n family_id = db_family.id\n # add members\n for m in member_data:\n m['family_id'] = family_id\n db_member = models.Member(**m)\n db.add(db_member)\n db.commit()\n db.refresh(db_member)\n return db_family\n```\n\n========================================\n\nComments:\n- Interesting. I was having the same question myself. Coming from a Symfony and Doctrine background, where these tools handle nested schema themself, I was looking for a similar behavior with FastAPI. Thank you Maschu.","metadata":{"transformedAt":"2026-08-18T18:32:29.142Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":15,"totalLines":204,"estimatedTokens":1591}}552{"id":"stack-56244496","source":"stackoverflow","questionId":56244496,"title":"FastAPI/Pydantic in a project with MyPy","tags":["python","mypy","pydantic","fastapi"],"text":"Title: FastAPI/Pydantic in a project with MyPy\nTags: python, mypy, pydantic, fastapi\nSource: Stack Overflow\n\nQuestion:\nIm currently working through the fastAPI tutorial, and my environment is setup with black, flake8, bandit and mypy. Everything in the tutorial is working fine, but I keep having to # type: ignore things to make mypy cooperate.\n\n```\nclass Item(BaseModel):\n name: str\n description: str = None\n price: float\n tax: float = None\n\n@app.post(\"/items/\")\nasync def create_items(item: Item) -> Item:\n return item\n```\n\nMypy then errors:\n\n```\n❯ mypy main.py [14:34:08]\nmain.py:9: error: Incompatible types in assignment (expression has type \"None\", variable has type \"str\")\nmain.py:11: error: Incompatible types in assignment (expression has type \"None\", variable has type \"float\")\n```\n\nI could # type: ignore, but then I lose the type hints and validation in my editor. Am I missing something obvious, or should I just disable mypy for FastAPI projects?\n\n========================================\n\nTop Answer:\nIf you are using mypy it could complain with type declarations like:\n\n```\ntax: float = None\n```\n\nWith an error like:\nIncompatible types in assignment (expression has type \"None\", variable has type \"float\")\nIn those cases you can use Optional to tell mypy that the value could be None, like:\n\n```\ntax: Optional[float] = None\n```\n\nIn the above code, \nCheck out this video, its been explained in this one \nBase Model explained here\n\n========================================\n\nCode:\n```text\nclass Item(BaseModel):\n name: str\n description: str = None\n price: float\n tax: float = None\n\n\n@app.post(\"/items/\")\nasync def create_items(item: Item) -> Item:\n return item\n```\n\n```text\n❯ mypy main.py [14:34:08]\nmain.py:9: error: Incompatible types in assignment (expression has type \"None\", variable has type \"str\")\nmain.py:11: error: Incompatible types in assignment (expression has type \"None\", variable has type \"float\")\n```\n\n```text\nfrom typing import Optional\n\nclass Item(BaseModel):\n name: str\n description: Optional[str] = None\n price: float\n tax: Optional[float] = None\n```\n\n```text\nOptional\n```\n\n```text\nmypy\n```\n\n```text\nNone\n```\n\n```text\ntax: float = None\n```\n\n```text\ntax: Optional[float] = None\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.142Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":8,"totalLines":101,"estimatedTokens":609}}553{"id":"stack-77471991","source":"stackoverflow","questionId":77471991,"title":"how to decide if StreamingResponse was closed in FastAPI/Starlette?","tags":["python","fastapi","starlette","asgi"],"text":"Title: how to decide if StreamingResponse was closed in FastAPI/Starlette?\nTags: python, fastapi, starlette, asgi\nSource: Stack Overflow\n\nQuestion:\nWhen looping a generator in StreamingResponse() using FastAPI/starlette\n\nhttps://www.starlette.io/responses/#streamingresponse\n\nhow can we tell if the connection was somehow disconnected, so a event could be fired and handled somewhere else?\n\nScenario: writing an API with `text/event-stream`, need to know when client closed the connection.\n\n========================================\n\nCode:\n```text\ntext/event-stream\n```\n\n```text\nrequest.is_disconnected()\n```\n\n========================================\n\nComments:\n- May be you can override `listen_for_disconnect`?\n- does this handle the case where the client never sends a disconnect message (e.g. internet dies)?\n- The disconnect *message* you're referring to is an ASGI Receive Event, not a message the client sends. *\"Sent to the application if receive is called after a response has been sent or after the HTTP connection has been closed.\"* See ASGI docs for more information.\n- I see is - is the HTTP connection closed if it doesn't hear the TCP ack back from the client, in case where client internet dies?","metadata":{"transformedAt":"2026-08-18T18:32:29.143Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":2,"totalLines":31,"estimatedTokens":303}}554{"id":"stack-79126171","source":"stackoverflow","questionId":79126171,"title":"ContextVar set and reset in the same function fails - created in a different context","tags":["python","python-3.x","fastapi","python-contextvars"],"text":"Title: ContextVar set and reset in the same function fails - created in a different context\nTags: python, python-3.x, fastapi, python-contextvars\nSource: Stack Overflow\n\nQuestion:\nI have this function:\n\n```\nasync_session = contextvars.ContextVar(\"async_session\")\n\nasync def get_async_session() -> AsyncGenerator[AsyncSession, None]:\n async with async_session_maker() as session:\n try:\n _token = async_session.set(session)\n yield session\n finally:\n async_session.reset(_token)\n```\n\nThis fails with:\n\n```\nValueError: at 0x7e14706d4680> was created in a different Context\n```\n\nHow can this happen? AFAICT the only way for the `Context` to be changed is for a whole function call. So how can the context change during a `yield`?\n\nThis function is being used as a FastAPI `Depends` in case that makes a difference - but I can't see how it does. It's running under Python 3.8 and the version of FastAPI is equally ancient - 0.54.\n\n========================================\n\nTop Answer:\nIf the generator would be used as a regular generator, in a `for` loop we control, it is really hard to think on how a context for contextvars could change. But the framework can do its own thing: it can store the generator in a variable, and call its `__next__` methods from arbitrary contexts.\n\nActually, ContextVars are not even meant to *work* with async generators - check the full text of PEP 567 - it was rewritten, simplifying the original proposal at PEP 550, because the iteration with pausing frames and running outer frame code became too complex, and that capability was simply stripped-out.\n\nI have a package to make the use of contextvars more simple - \"extracontext\" - and I have support for contextvars in async-generators there.\n\nEither way, my proposal is to bring back the \"threading.local\" namespace, and I did add \"context manager\" capabilities to \"contextvars\".\n\nYou can just `pip install python-extracontext`. I didn't write much docs besides docstrings and what is on embedded in the README at https://github.com/jsbueno/extracontext\n\nWIth this package you should be able to use:\n\n```\nfrom extracontext import ContextLocal\n\n# async_session = contextvars.ContextVar(\"async_session\")\nasync_session_ns = ContextLocal()\n\nasync def get_async_session() -> AsyncGenerator[AsyncSession, None]:\n async with (async_session_maker() as session, async_session_ns):\n with async_session_ns:\n async_session_ns.session = session\n # any code wanting this, should be able to use just\n # \"async_session_ns.session\" in any expression\n\n yield session\n\n # no finally blocks needed, as ContextLocal\n # works as a context manager.\n```\n\nPlease tell me if it does not work for you for any reason.\n\n========================================\n\nCode:\n```text\nasync_session = contextvars.ContextVar(\"async_session\")\n\nasync def get_async_session() -> AsyncGenerator[AsyncSession, None]:\n async with async_session_maker() as session:\n try:\n _token = async_session.set(session)\n yield session\n finally:\n async_session.reset(_token)\n```\n\n```text\nValueError: <Token var=<ContextVar name='async_session' at 0x7e1470e00e00> at 0x7e14706d4680> was created in a different Context\n```\n\n```text\nContext\n```\n\n```text\nyield\n```\n\n```text\nDepends\n```\n\n```text\nasync\n```\n\n```text\nfrom extracontext import ContextLocal\n\n# async_session = contextvars.ContextVar(\"async_session\")\nasync_session_ns = ContextLocal()\n\nasync def get_async_session() -> AsyncGenerator[AsyncSession, None]:\n async with (async_session_maker() as session, async_session_ns):\n with async_session_ns:\n async_session_ns.session = session\n # any code wanting this, should be able to use just\n # \"async_session_ns.session\" in any expression\n\n yield session\n\n # no finally blocks needed, as ContextLocal\n # works as a context manager.\n```\n\n```text\nfor\n```\n\n```text\n__next__\n```\n\n```text\npip install python-extracontext\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.143Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":10,"totalLines":130,"estimatedTokens":993}}555{"id":"stack-63635664","source":"stackoverflow","questionId":63635664,"title":"Cannot run uvicorn command on windows despite installing it and adding in path variables","tags":["python","windows","fastapi","windows-terminal","uvicorn"],"text":"Title: Cannot run uvicorn command on windows despite installing it and adding in path variables\nTags: python, windows, fastapi, windows-terminal, uvicorn\nSource: Stack Overflow\n\nQuestion:\nAs the title, I have installed uvicorn using the powershell, and added the environment variable. But whenever I run the command, I get the same error. I know I must be doing something small and stupid, but following every answer on SO tells me the same thing, and I have no leads at all.\n\nhttps://i.sstatic.net/HW6Nw.png\nhttps://i.sstatic.net/QpmvE.png\n\n========================================\n\nTop Answer:\nTry do the following\n\n```\npython3 -m uvicorn main:app\n```\n\n========================================\n\nCode:\n```text\nusers/AppData/roaming/Python/Python37/site-packages\n```\n\n```text\n\"uvicorn\"\n```\n\n```text\n\"uvicorn-X.XX.Xdist-info\"\n```\n\n```text\nusers/AppData/roaming/Python/Python37/Scripts\n```\n\n```text\n\"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\Python37_64\\Scripts\"\n```\n\n```text\n\"uvicorn main:app --reload\"\n```\n\n```text\npython3 -m uvicorn main:app\n```\n\n========================================\n\nComments:\n- I did restart the powershell everytime I did the changes...\n- pip has a command to dump information about a package that could be used here instead of uninstall `pip show `","metadata":{"transformedAt":"2026-08-18T18:32:29.143Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":7,"totalLines":55,"estimatedTokens":322}}556{"id":"stack-74647143","source":"stackoverflow","questionId":74647143,"title":"FastAPI decorators on endpoint","tags":["python","fastapi"],"text":"Title: FastAPI decorators on endpoint\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm trying to create role-based access control on endpoint and since fastAPI has this build-in Depends method with possibility to cache result I'm trying to create something like this\n\n```\n@router.get('/')\n#decorator \n@roles_decorator(\"admin\")\nasync def get_items(user_id: str = Depends(get_current_user)):\n\nreturn await get_all_items()\n```\n\n**get_current_user method** will need to receive roles from decorator (in this case admin) and from authorization service receive user_id if role matches provided role. So my question is, can we pass the role from decorator to method in Depends, or is there any chance that we can do this role-based access control with predefined roles for every endpoint?\n\n```\ndef get_current_user(role):\n #connect to auth_serivce and do other logic\n return user_id\n```\n\n========================================\n\nTop Answer:\nI'm new to Python and FastAPI but passing params to a dependency wasn't working too well for me, and it started causing the params to appear in Swagger which wasn't what I wanted.\n\nMy endpoints require API keys for authentication, so I check who the API key belongs to and if they have the required permissions to access the endpoint.\n\nComing from other frameworks where I'd use a decorator for this kind of thing, I ended up implementing it this way in my FastAPI project:\n\nHere's the decorator:\n\n```\ndef has_permission(permission: str):\n def decorator(func):\n @wraps(func)\n async def wrapper(*args, **kwargs):\n api_key = kwargs.get(\"api_key_header\")\n user_service = kwargs.get(\"user_service\")\n\n user = user_service.get_by_api_key(api_key)\n\n if permission not in user.permissions\n raise HTTPException(status_code=403, detail=\"User doesn\\'t have required permissions\")\n\n return await func(*args, **kwargs)\n\n return wrapper\n\n return decorator\n```\n\nAnd this is how I use it on my route:\n\n```\n@router.get(\"/\", summary=\"Retrieve all users.\", response_model=List[UserResponse])\n@has_permission(\"users.get\")\nasync def get_all_users(\n api_key_header: str = Security(api_key_header), user_service: UserService = Depends(UserService)\n):\n \"\"\"\n Retrieve all users.\n \"\"\"\n return user_service.get_all_users()\n```\n\n========================================\n\nCode:\n```text\n@router.get('/')\n#decorator \n@roles_decorator(\"admin\")\nasync def get_items(user_id: str = Depends(get_current_user)):\n\nreturn await get_all_items()\n```\n\n```text\ndef get_current_user(role):\n #connect to auth_serivce and do other logic\n return user_id\n```\n\n```py\nasync def get_current_user_with_role(role):\n async def get_user_and_validate(user=Depends(get_current_user)):\n if not user.has_role(role):\n raise 403\n\n return user.id\n\n return get_user_and_validate\n```\n\n```text\n@router.get('/')\nasync def get_items(user_id: str = Depends(get_current_user_with_role(\"admin\"))):\n pass\n```\n\n```text\nrole\n```\n\n```py\ndef has_permission(permission: str):\n def decorator(func):\n @wraps(func)\n async def wrapper(*args, **kwargs):\n api_key = kwargs.get(\"api_key_header\")\n user_service = kwargs.get(\"user_service\")\n\n user = user_service.get_by_api_key(api_key)\n\n if permission not in user.permissions\n raise HTTPException(status_code=403, detail=\"User doesn\\'t have required permissions\")\n\n return await func(*args, **kwargs)\n\n return wrapper\n\n return decorator\n```\n\n```py\n@router.get(\"/\", summary=\"Retrieve all users.\", response_model=List[UserResponse])\n@has_permission(\"users.get\")\nasync def get_all_users(\n api_key_header: str = Security(api_key_header), user_service: UserService = Depends(UserService)\n):\n \"\"\"\n Retrieve all users.\n \"\"\"\n return user_service.get_all_users()\n```\n\n========================================\n\nComments:\n- i dont quite what your asking ... to get the roles available to a user you need to get_current_user first ... so how could you pass roles into it?\n- I asked a similar question. Hope to get some answers :) stackoverflow.com/questions/74652763/…\n- @JoranBeasley so i need to pass role to get_current_user which will send role to authorization service decode jwt token and see if roles are matching, is this maybe better explained\n- With this you cannot pass param \"admin\" also so I think this is not game changer, and also I don't receive user object with role, I'm getting id of user but to get that ID I need to send role from endpoint to see if role which I send from endpoint are same as role from JWT token decrypted on auth service\n- You pass `\"admin\"` when you add the dependency. What you receive back depends on what you return from the `get_user_and_validate` function - you defined this as being a `str` in your original post, together with only having a `user_id` and not a user object. If you want t user object, return the user object from `get_current_user_with_role` instead when the role matches.\n- Oh okay I think I got this thanks, there is only one thing to try to implement with decorator to pass to that method\n- *Generally* FastAPI doesn't really use decorators for things like that, but instead use the dependency resolution framework.\n- so this is bad idea to use decorator and depends?\n- I'm not sure why you need to use a decorator when it can be solved with a dependency alone.\n- just for readability reasons to be on top of the route\n- This works well and is what I used in my project, however it raises another issue. If params or a body is required by the endpoint, this will be checked before any auth checks. e.g. a Pydantic schema for a body to that endpoint will raise exceptions until the body is sent correctly, only then will it check the auth. Not really something you want to have on protected endpoints. Better to have auth first then validation. I couldn't figure a way around that.\n- @MarkBarrett Applying the auth check at the router level might be more appropriate if looking to check auth before params/body hits the endpoint.\n- yea. I managed to make it work by modifying the Depend @MatsLindh mentioned above. Validates the auth first.","metadata":{"transformedAt":"2026-08-18T18:32:29.143Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":7,"totalLines":156,"estimatedTokens":1542}}557{"id":"stack-74124896","source":"stackoverflow","questionId":74124896,"title":"FastAPI is returning AttributeError: 'dict' object has no attribute 'encode'","tags":["python","fastapi","python-3.9"],"text":"Title: FastAPI is returning AttributeError: 'dict' object has no attribute 'encode'\nTags: python, fastapi, python-3.9\nSource: Stack Overflow\n\nQuestion:\nI am having a very simple FastAPI service, when I try to hit the `/spell_checking` endpoint, I get this error `AttributeError: 'dict' object has no attribute 'encode'.\n\nI am hitting the endpoint using postman, with Post request, and this is the url: `http://127.0.0.1:8080/spell_checking`, the payload is JSON with value:\n\n```\n{\"word\": \"testign\"}\n```\n\nHere is my code:\n\n```\nfrom fastapi import FastAPI, Response, Request\nimport uvicorn\nfrom typing import Dict\n\napp = FastAPI() \n\n@app.post('/spell_checking')\ndef spell_check(word: Dict ) :\n data = {\n 'corrected': 'some value'\n }\n return Response(data)\n\n@app.get('/')\ndef welcome():\n return Response('Hello World')\n\nif __name__ == '__main__':\n uvicorn.run(app, port=8080, host='0.0.0.0')\n```\n\nI still dont know why a simple service like this would show this error!\n\n========================================\n\nCode:\n```text\n{\"word\": \"testign\"}\n```\n\n```text\nfrom fastapi import FastAPI, Response, Request\nimport uvicorn\nfrom typing import Dict\n\napp = FastAPI() \n\n\n@app.post('/spell_checking')\ndef spell_check(word: Dict ) :\n data = {\n 'corrected': 'some value'\n }\n return Response(data)\n\n@app.get('/')\ndef welcome():\n return Response('Hello World')\n\nif __name__ == '__main__':\n uvicorn.run(app, port=8080, host='0.0.0.0')\n```\n\n```text\n/spell_checking\n```\n\n```text\nhttp://127.0.0.1:8080/spell_checking\n```\n\n```py\nfrom typing import Dict\n\nimport uvicorn\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n\n@app.post(\"/spell_checking\")\ndef spell_check(word: Dict):\n data = {\"corrected\": \"some value\"}\n return data\n\n\n@app.get(\"/\")\ndef welcome():\n return \"Hello World\"\n\n\nif __name__ == \"__main__\":\n uvicorn.run(app, port=8080, host=\"0.0.0.0\")\n```\n\n```text\nResponse\n```\n\n```text\n.encode()\n```\n\n========================================\n\nComments:\n- @Chris technically, this is what I wanted to do, yet the error did not specify what's causing it, which I found it weird, that's why I was fed up with it.\n- Thanks for the explanation, had a similar issue","metadata":{"transformedAt":"2026-08-18T18:32:29.143Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":7,"totalLines":114,"estimatedTokens":544}}558{"id":"stack-73632237","source":"stackoverflow","questionId":73632237,"title":"Upload small file to FastAPI enpoint but UploadFile content is empty","tags":["file-upload","fastapi","starlette"],"text":"Title: Upload small file to FastAPI enpoint but UploadFile content is empty\nTags: file-upload, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nI am trying to upload file (csv) to FastAPI `POST` endpoint.\n\nThis is the server code:\n\n```\n@app.post(\"/csv/file/preview\")\nasync def post_csv_file_preview(file: UploadFile):\n \"\"\"\n\n :param file:\n :return:\n \"\"\"\n contents = file.file.read()\n print(contents)\n```\n\nBut contents is empty if the file is small. If I increase the file content (add new lines in the csv file), without any others changes, it is working.\n\nIf I directly get the request body, the file content is returned normally.\n\n```\nprint(await request.body())\n```\n\nThe problem is only with my production server, not localally:\n\n```\nPYTHONPATH=/var/www/api/current /var/www/api/current/venv/bin/python /var/www/api/current/venv/bin/uvicorn main:app --reload --port=8004\n```\n\nI dont understand\n\n========================================\n\nCode:\n```py\n@app.post(\"/csv/file/preview\")\nasync def post_csv_file_preview(file: UploadFile):\n \"\"\"\n\n :param file:\n :return:\n \"\"\"\n contents = file.file.read()\n print(contents)\n```\n\n```py\nprint(await request.body())\n```\n\n```bash\nPYTHONPATH=/var/www/api/current /var/www/api/current/venv/bin/python /var/www/api/current/venv/bin/uvicorn main:app --reload --port=8004\n```\n\n```text\nPOST\n```\n\n```py\n@app.post(\"/csv/file/preview\")\ndef post_csv_file_preview(file: UploadFile):\n \"\"\"\n\n :param file:\n :return:\n \"\"\"\n file.file.seek(0)\n contents = file.file.read()\n print(contents)\n```\n\n```text\n.seek()\n```\n\n========================================\n\nComments:\n- Does this answer your question? How to Upload File using FastAPI?\n- Also, please make sure that you haven't already read the file contents, before calling `file.file.read()`. If so, you need to use the `.seek()` method to set the current position of the cursor to `0` (i.e., rewind the cursor to the start of the file), as described in Option 1 of this answer.\n- No. I send my file with Insomnia for test in production\n- Also, I would not recommend using `async def` endpoint while reading the file contents in a `sync` way. Please have a look at this answer and this answer for more details.\n- Hoo yes it's ok with seek. Thanks. But is so curious. This file is read only once by request.\n- I've encountered the same exact problem: file is only read once, `seek(0)` helps, and it can only be reproduced on production. I've narrowed down \"small file\" size to 9828 bytes - everything above that reads OK on the first try. Still no idea what causes this, though.\n- It worked for me. Thanks","metadata":{"transformedAt":"2026-08-18T18:32:29.143Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":6,"totalLines":91,"estimatedTokens":655}}559{"id":"stack-64336060","source":"stackoverflow","questionId":64336060,"title":"Cloud Run requests triggers error 400 without reaching deployed service","tags":["python-3.x","google-cloud-platform","google-cloud-run","fastapi","pydantic"],"text":"Title: Cloud Run requests triggers error 400 without reaching deployed service\nTags: python-3.x, google-cloud-platform, google-cloud-run, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI am currently using Google Cloud Run to deploy an API and although everything was working fine I am now having quite a hard time understanding an error I get.\n\nI created the API on python3 using FastAPI, the Location model is based on Pydantic's BaseModel.\n\nTo illustrate it I have defined a test route as :\n\n```\nclass Location(BaseModel):\n lat: float\n lng: float\n\n@router.get('/test_404')\nasync def test_404(origin: Location = Body(...),\n destination: Location = Body(...)):\n print(origin)\n print(destination)\n return {'res': 'ok'}\n```\n\nThe route should take two arguments in the request's body : origin and destination, and it ***does*** but only when I deploy it locally.\nThis :\n\n```\nurl_local = \"http://0.0.0.0:8080/test_404\"\ndata = {\n 'origin': {'lat': 104, 'lng': 342},\n 'destination': {'lat': 104, 'lng': 342}\n}\nresp = requests.get(url_local, json = data)\nprint(resp.text)\n```\n\nOutputs :\n\n```\n'{\"res\":\"ok\"}'\n```\n\nThe issue arises when I deploy the same service on Cloud Run. All of my other routes work fine but here is the output I get when I use the code above with the container url :\n\n```\n\\n\n \n \n \\n\n \n \\n Error 400 (Bad Request)!!1\\n\n \\n \\n\n **400.**\n That’s an error.\n \\n\n Your client has issued a malformed or illegal request.\n That’s all we know.\n```\n\nThis is an error triggered by google and that does not let my request reach the service (no log entry)\n\nI've searched online but did not find what causes this error. What am I missing ?\n\nThank you very much\n\n========================================\n\nCode:\n```py\nclass Location(BaseModel):\n lat: float\n lng: float\n\n\n@router.get('/test_404')\nasync def test_404(origin: Location = Body(...),\n destination: Location = Body(...)):\n print(origin)\n print(destination)\n return {'res': 'ok'}\n```\n\n```py\nurl_local = \"http://0.0.0.0:8080/test_404\"\ndata = {\n 'origin': {'lat': 104, 'lng': 342},\n 'destination': {'lat': 104, 'lng': 342}\n}\nresp = requests.get(url_local, json = data)\nprint(resp.text)\n```\n\n```py\n'{\"res\":\"ok\"}'\n```\n\n```text\n<!DOCTYPE html>\\n\n <html lang=en>\n <meta charset=utf-8>\n \\n\n <meta name=viewport content=\"initial-scale=1, minimum-scale=1, width=device-width\">\n \\n <title>Error 400 (Bad Request)!!1</title>\\n\n \\n <a href=//www.google.com/><span id=logo aria-label=Google></span></a>\\n\n <p><b>400.</b>\n <ins>That’s an error.</ins>\n \\n\n <p>Your client has issued a malformed or illegal request.\n <ins>That’s all we know.</ins>\n```\n\n========================================\n\nComments:\n- I thought so hard that google did something weird that I did not even take a look at what I what I was doing and it made sense. Thank you very much !","metadata":{"transformedAt":"2026-08-18T18:32:29.143Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":116,"estimatedTokens":722}}560{"id":"stack-70455897","source":"stackoverflow","questionId":70455897,"title":"Microsoft Authentication - Python Flask msal Example App Ported to FastAPI","tags":["python","fastapi","azure-ad-msal"],"text":"Title: Microsoft Authentication - Python Flask msal Example App Ported to FastAPI\nTags: python, fastapi, azure-ad-msal\nSource: Stack Overflow\n\nQuestion:\nI don't do much web work but I recently began using FastAPI and am building an MVC app with jinja2 templating that uses PowerBI embedded capacity to serve multiple embedded analytics in app owns data arrangement. All of this works beautifully. However, I'm wanting to add further modules and I'd like to use the msal package to do user authentication by routing a user to the Microsoft login page, letting them sign in against a multi-tenant app service I set up in Azure, and then redirecting back to my page via redirect URI, grabbing the token, and progressing with authorization. Microsoft saved a great example our here for doing this in Flask. However, I am having fits porting the example to FastAPI.\n\nI can get the user to the login screen and log in but I am having no luck capturing the token at my call back URI - it's appropriately routing but I am unable to capture the token from the response.\n\nHas anyone (or can anyone) taken that super simple Flask example and ported it to FastAPI? Everything I find online for FAPI is back-end token-bearer headers for APIs - not meant for MVC apps.\n\nHere's my current code. Messy because I have \"tests\" built in.\n\n```\nimport msal\nimport requests\nfrom fastapi import APIRouter, Request, Response\nfrom fastapi.responses import RedirectResponse\nfrom starlette.templating import Jinja2Templates\n\nfrom config import get_settings\n\nsettings = get_settings()\nrouter = APIRouter()\ntemplates = Jinja2Templates('templates')\n\n# Works\n@router.get('/login', include_in_schema=False)\nasync def login(request: Request):\n request.session['flow'] = _build_auth_code_flow(scopes=settings.AUTH_SCOPE)\n login_url = request.session['flow']['auth_uri']\n return templates.TemplateResponse('error.html', {'request': request, 'message': login_url})\n\n# DOES NOT WORK - Pretty sure error is in here --------------------\n@router.get('/getAToken', response_class=Response, include_in_schema=False)\nasync def authorize(request: Request):\n try:\n cache = _load_cache(request)\n result = _build_msal_app(cache=cache).acquire_token_by_auth_code_flow(\n request.session.get('flow'), request.session\n )\n if 'error' in result:\n return templates.TemplateResponse('error.html', {'request': request, 'message': result})\n request.session['user'] = result.get('id_token_claims')\n _save_cache(cache)\n except Exception as error:\n return templates.TemplateResponse('error.html', {'request': request, 'message': f'{error}: {str(request.query_params)}'})\n return templates.TemplateResponse('error.html', {'request': request, 'message': result})\n# -----------------------------------------------------\n\n \ndef _load_cache(request: Request):\n cache = msal.SerializableTokenCache()\n if request.session.get(\"token_cache\"):\n cache.deserialize(request.session[\"token_cache\"])\n return cache\n\ndef _save_cache(request: Request, cache):\n if cache.has_state_changed:\n request.session[\"token_cache\"] = cache.serialize()\n\ndef _build_msal_app(cache=None, authority=None):\n return msal.ConfidentialClientApplication(\n settings.CLIENT_ID,\n authority=authority or settings.AUTH_AUTHORITY,\n client_credential=settings.CLIENT_SECRET,\n token_cache=cache\n )\n\ndef _build_auth_code_flow(authority=None, scopes=None):\n return _build_msal_app(authority=authority).initiate_auth_code_flow(\n scopes or [],\n redirect_uri=settings.AUTH_REDIRECT)\n\ndef _get_token_from_cache(scope=None):\n cache = _load_cache() # This web app maintains one cache per session\n cca = _build_msal_app(cache=cache)\n accounts = cca.get_accounts()\n if accounts: # So all account(s) belong to the current signed-in user\n result = cca.acquire_token_silent(scope, account=accounts[0])\n _save_cache(cache)\n return result\n```\n\nAny help is GREATLY appreciated. Happy to answer any questions. Thank you.\n\n========================================\n\nCode:\n```text\nimport msal\nimport requests\nfrom fastapi import APIRouter, Request, Response\nfrom fastapi.responses import RedirectResponse\nfrom starlette.templating import Jinja2Templates\n\nfrom config import get_settings\n\nsettings = get_settings()\nrouter = APIRouter()\ntemplates = Jinja2Templates('templates')\n\n\n# Works\n@router.get('/login', include_in_schema=False)\nasync def login(request: Request):\n request.session['flow'] = _build_auth_code_flow(scopes=settings.AUTH_SCOPE)\n login_url = request.session['flow']['auth_uri']\n return templates.TemplateResponse('error.html', {'request': request, 'message': login_url})\n\n\n# DOES NOT WORK - Pretty sure error is in here --------------------\n@router.get('/getAToken', response_class=Response, include_in_schema=False)\nasync def authorize(request: Request):\n try:\n cache = _load_cache(request)\n result = _build_msal_app(cache=cache).acquire_token_by_auth_code_flow(\n request.session.get('flow'), request.session\n )\n if 'error' in result:\n return templates.TemplateResponse('error.html', {'request': request, 'message': result})\n request.session['user'] = result.get('id_token_claims')\n _save_cache(cache)\n except Exception as error:\n return templates.TemplateResponse('error.html', {'request': request, 'message': f'{error}: {str(request.query_params)}'})\n return templates.TemplateResponse('error.html', {'request': request, 'message': result})\n# -----------------------------------------------------\n\n \ndef _load_cache(request: Request):\n cache = msal.SerializableTokenCache()\n if request.session.get(\"token_cache\"):\n cache.deserialize(request.session[\"token_cache\"])\n return cache\n\n\ndef _save_cache(request: Request, cache):\n if cache.has_state_changed:\n request.session[\"token_cache\"] = cache.serialize()\n\n\ndef _build_msal_app(cache=None, authority=None):\n return msal.ConfidentialClientApplication(\n settings.CLIENT_ID,\n authority=authority or settings.AUTH_AUTHORITY,\n client_credential=settings.CLIENT_SECRET,\n token_cache=cache\n )\n\n\ndef _build_auth_code_flow(authority=None, scopes=None):\n return _build_msal_app(authority=authority).initiate_auth_code_flow(\n scopes or [],\n redirect_uri=settings.AUTH_REDIRECT)\n\n\ndef _get_token_from_cache(scope=None):\n cache = _load_cache() # This web app maintains one cache per session\n cca = _build_msal_app(cache=cache)\n accounts = cca.get_accounts()\n if accounts: # So all account(s) belong to the current signed-in user\n result = cca.acquire_token_silent(scope, account=accounts[0])\n _save_cache(cache)\n return result\n```\n\n```text\nfrom fastapi import FastAPI\nfrom fastapi.templating import Jinja2Templates\n\nfrom starlette.requests import Request\nfrom starlette.responses import RedirectResponse\n\nfrom starlette_session import SessionMiddleware\nfrom starlette_session.backends import BackendType\n\nfrom redis import Redis\n\nimport uvicorn\nimport functools\nimport msal\n\n\napp_client_id = \"sample_msal_client_id\"\napp_client_secret = \"sample_msal_client_secret\"\ntenant_id = \"sample_msal_tenant_id\"\n\napp = FastAPI()\n\n\nredis_client = Redis(host=\"localhost\", port=6379)\napp.add_middleware(\n SessionMiddleware,\n secret_key=\"SECURE_SECRET_KEY\",\n cookie_name=\"auth_cookie\",\n backend_type=BackendType.redis,\n backend_client=redis_client,\n)\n\ntemplates = Jinja2Templates(directory=\"templates\")\n\ndefault_scope = [\"https://graph.microsoft.com/.default\"]\ntoken_cache_key = \"token_cache\"\n\n# Private Functions - Start\ndef _load_cache(session):\n cache = msal.SerializableTokenCache()\n if session.get(token_cache_key):\n cache.deserialize(session[token_cache_key])\n return cache\n\ndef _save_cache(cache,session):\n if cache.has_state_changed:\n session[token_cache_key] = cache.serialize()\n\ndef _build_msal_app(cache=None):\n return msal.ConfidentialClientApplication(\n app_client_id, \n client_credential=app_client_secret,\n authority=f\"https://login.microsoftonline.com/{tenant_id}\",\n token_cache=cache\n )\n\ndef _build_auth_code_flow(request):\n return _build_msal_app().initiate_auth_code_flow(\n default_scope, #Scopes\n redirect_uri=request.url_for(\"callback\") #Redirect URI\n )\n\ndef _get_token_from_cache(session):\n cache = _load_cache(session) # This web app maintains one cache per session\n cca = _build_msal_app(cache=cache)\n accounts = cca.get_accounts()\n if accounts: # So all account(s) belong to the current signed-in user\n result = cca.acquire_token_silent(default_scope, account=accounts[0])\n _save_cache(cache,session)\n return result\n# Private Functions - End\n\n\n# Custom Decorators - Start\ndef authenticated_endpoint(func):\n @functools.wraps(func)\n def is_authenticated(*args,**kwargs):\n try:\n request = kwargs[\"request\"]\n token = _get_token_from_cache(request.session)\n if not token:\n return RedirectResponse(request.url_for(\"login\"))\n return func(*args,**kwargs)\n except:\n return RedirectResponse(request.url_for(\"login\"))\n\n return is_authenticated\n# Custom Decorators - End\n\n\n# Endpoints - Start\n@app.get(\"/\")\n@authenticated_endpoint\ndef index(request:Request):\n return {\n \"result\": \"good\"\n }\n\n@app.get(\"/login\")\ndef login(request:Request):\n return templates.TemplateResponse(\"login.html\",{\n \"version\": msal.__version__,\n 'request': request,\n \"config\": {\n \"B2C_RESET_PASSWORD_AUTHORITY\": False\n }\n })\n\n@app.get(\"/oauth/redirect\")\ndef get_redirect_url(request:Request):\n request.session[\"flow\"] = _build_auth_code_flow(request)\n return RedirectResponse(request.session[\"flow\"][\"auth_uri\"])\n\n@app.get(\"/callback\")\nasync def callback(request:Request):\n cache = _load_cache(request.session)\n result = _build_msal_app(cache=cache).acquire_token_by_auth_code_flow(request.session.get(\"flow\", {}), dict(request.query_params))\n if \"error\" in result:\n return templates.TemplateResponse(\"auth_error.html\",{\n \"result\": result,\n 'request': request\n })\n request.session[\"user\"] = result.get(\"id_token_claims\")\n request.session[token_cache_key] = cache.serialize()\n return RedirectResponse(request.url_for(\"index\"))\n# Endpoints - End\n\nif __name__ == \"__main__\":\n uvicorn.run(\"main:app\",host='0.0.0.0', port=4557,reload=True)`\n```\n\n========================================\n\nComments:\n- For further clarity, I'm getting a \"state mismatch\" in the return response after seemingly successfully logging in. \"state mismatch: dWASFCmYrjQzXnZv vs None: code=0.AXYA4G2......(about 200 more random characters)...\"\n- This is great! Thank you! A friend had helped me get to a similar answer using fastapi-cache. There are definitely a couple points from this answer that I'll further work in. Thank you for taking the time to include the example - EXTREMELY helpful.\n- @Richard can you provide your `fastapi-cache` based solution?","metadata":{"transformedAt":"2026-08-18T18:32:29.143Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":2,"totalLines":304,"estimatedTokens":2769}}561{"id":"stack-73810377","source":"stackoverflow","questionId":73810377,"title":"How to save an uploaded image to FastAPI using Python Imaging Library (PIL)?","tags":["python","python-imaging-library","fastapi"],"text":"Title: How to save an uploaded image to FastAPI using Python Imaging Library (PIL)?\nTags: python, python-imaging-library, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am using image compression to reduce the image size. When submitting the post request, I am not getting any error, but can't figure out why the images do not get saved. Here is my code:\n\n```\n@app.post(\"/post_ads\")\nasync def create_upload_files(title: str = Form(),body: str = Form(), \n db: Session = Depends(get_db), files: list[UploadFile] = File(description=\"Multiple files as UploadFile\")):\n for file in files:\n im = Image.open(file.file)\n im = im.convert(\"RGB\")\n im_io = BytesIO()\n im = im.save(im_io, 'JPEG', quality=50)\n```\n\n========================================\n\nTop Answer:\nI assume you are writing to a `BytesIO` to get an *\"in memory\"* JPEG without slowing yourself down by writing to disk and cluttering your filesystem.\n\nIf so, you want:\n\n```\nfrom PIL import Image\nfrom io import BytesIO\n\nim = Image.open(file.file)\nim = im.convert(\"RGB\")\nim_io = BytesIO()\n# create in-memory JPEG in RAM (not disk)\nim.save(im_io, 'JPEG', quality=50)\n\n# get the JPEG image in a variable called JPEG\nJPEG = im_io.get_value()\n```\n\n========================================\n\nCode:\n```py\n@app.post(\"/post_ads\")\nasync def create_upload_files(title: str = Form(),body: str = Form(), \n db: Session = Depends(get_db), files: list[UploadFile] = File(description=\"Multiple files as UploadFile\")):\n for file in files:\n im = Image.open(file.file)\n im = im.convert(\"RGB\")\n im_io = BytesIO()\n im = im.save(im_io, 'JPEG', quality=50)\n```\n\n```text\nImage.open(io.BytesIO(file.file.read()))\n```\n\n```py\n# ...\nfrom fastapi import HTTPException\nfrom PIL import Image\n\n@app.post(\"/upload\")\ndef upload(file: UploadFile = File()):\n try: \n im = Image.open(file.file)\n if im.mode in (\"RGBA\", \"P\"): \n im = im.convert(\"RGB\")\n im.save('out.jpg', 'JPEG', quality=50) \n except Exception:\n raise HTTPException(status_code=500, detail='Something went wrong')\n finally:\n file.file.close()\n im.close()\n```\n\n```py\n# ...\nfrom fastapi import HTTPException\nfrom PIL import Image\n\n@app.post(\"/upload\")\ndef upload(file: UploadFile = File()):\n try: \n im = Image.open(file.file)\n if im.mode in (\"RGBA\", \"P\"): \n im = im.convert(\"RGB\")\n buf = io.BytesIO()\n im.save(buf, 'JPEG', quality=50)\n # to get the entire bytes of the buffer use:\n contents = buf.getvalue()\n # or, to read from `buf` (which is a file-like object), call this first:\n buf.seek(0) # to rewind the cursor to the start of the buffer\n except Exception:\n raise HTTPException(status_code=500, detail='Something went wrong')\n finally:\n file.file.close()\n buf.close()\n im.close()\n```\n\n```text\nPIL.Image.open()\n```\n\n```text\nfp\n```\n\n```text\nfp\n```\n\n```text\nfilename\n```\n\n```text\npathlib.Path\n```\n\n```text\nfile\n```\n\n```text\nfile.read()\n```\n\n```text\nfile.seek()\n```\n\n```text\nfile.tell()\n```\n\n```text\nBytesIO\n```\n\n```text\n.file\n```\n\n```text\nUploadFile\n```\n\n```text\nfile\n```\n\n```text\nSpooledTemporaryFile\n```\n\n```text\nfile-like\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\nfrom PIL import Image\nfrom io import BytesIO\n\nim = Image.open(file.file)\nim = im.convert(\"RGB\")\nim_io = BytesIO()\n# create in-memory JPEG in RAM (not disk)\nim.save(im_io, 'JPEG', quality=50)\n\n# get the JPEG image in a variable called JPEG\nJPEG = im_io.get_value()\n```\n\n```text\nBytesIO\n```\n\n========================================\n\nComments:\n- Your image is saved in RAM inside `im_io`. Change last line to `im.save(im_io, 'JPEG', quality=50)`\n- @Mark Setchell this is my last line `im.save(im_io, 'JPEG', quality=50)` what I need to be changed? I tried `im = im.save('JPEG', quality=50)` getting this error `ValueError: unknown file extension:`","metadata":{"transformedAt":"2026-08-18T18:32:29.143Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":23,"totalLines":192,"estimatedTokens":979}}562{"id":"stack-74041393","source":"stackoverflow","questionId":74041393,"title":"Browser Cookie never expires","tags":["python-3.x","cookies","fastapi","uvicorn","cookie-httponly"],"text":"Title: Browser Cookie never expires\nTags: python-3.x, cookies, fastapi, uvicorn, cookie-httponly\nSource: Stack Overflow\n\nQuestion:\nI'm implementing for the first time a **login Auth with HTTPOnly Cookie**. In my case, the cookie it is created when the user calls the `login` method in a **Python service** with FastAPI and Uvicorn.\n\nI've read the MDN documentation to implement the expires property and so, the browser delete this cookie when the time expires.\n\nI've implemented the Cookie in Python with http.cookies and Morsel to apply the **HttpOnly** property like this:\n\n```\nfrom http import cookies\nfrom fastapi import FastAPI, Response, Cookie, Request\nfrom fastapi.responses import HTMLResponse, FileResponse\nfrom fastapi.staticfiles import StaticFiles\nfrom fastapi.templating import Jinja2Templates\n\nmytoken = 'blablabla'\n\ndef getUtcDate():\n sessionDate = datetime.now()\n sessionDate += timedelta(minutes=2)\n return sessionDate.strftime('%a, %d %b %Y %H:%M:%S GMT')\n\n@app.get('cookietest')\ndef getCookie(response: Response):\n cookie = cookies.Morsel()\n cookie['httponly'] = True\n cookie['version'] = '1.0.0'\n cookie['domain'] = '127.0.0.1'\n cookie['path'] = '/'\n cookie['expires'] = getUtcDate()\n cookie['max-age'] = 120\n cookie['samesite'] = 'Strict'\n cookie.set(\"jwt\", \"jwt\", mytoken)\n\n response.headers.append(\"Set-Cookie\", cookie.output())\n\n return {'status':'ok'}\n```\n\nDoing this, the Cookies looks correctly in the browser when I call the `cookietest` endpoint, the evidence:\n\nhttps://i.sstatic.net/rxSum.png\n\nAs you can see in the picture, the cookie has an expiration datetime in Expires / Max-Age:\"Wed, 12 Oct 2022 11:24:58 GMT\", 2 minutes after logging in (if the user logging at 14:05:00, the cookies expires at 14:07:00)\n\nMy problem is that **any browser doesn't delete the cookie when the expire time has been exceeded**, so this it's confusing me. If I let several minutes pass and then make a request to another endpoint (like http://127.0.0.1:8000/info), the cookie still exists in the http headers.\n\nWhat is the problem? What am I doing wrong? I'm reading a lot of documentation about cookie storing and expiration and I can't see anything about this issue.\n\n### EDITED: PROBLEM SOLVED\n\nAs Chris says, using the `set_cookie` method from FastAPI, the problem was solved.\n\nI still wonder why the MSD documentation indicates that the date format must be a specific one which does not cause the browser to delete the Cookie, but indicating the time in seconds works correctly.\n\n```\n@app.get(\"/cookietest\")\nasync def cookietest(response: Response):\n response.set_cookie(\n key='jwt', \n value=getToken(), \n max_age=120, \n expires=120, \n path='/', \n secure=False, \n httponly=True, \n samesite=\"strict\", \n domain='127.0.0.1'\n )\n return {\"Result\": \"Ok\"}\n```\n\n========================================\n\nCode:\n```py\nfrom http import cookies\nfrom fastapi import FastAPI, Response, Cookie, Request\nfrom fastapi.responses import HTMLResponse, FileResponse\nfrom fastapi.staticfiles import StaticFiles\nfrom fastapi.templating import Jinja2Templates\n\nmytoken = 'blablabla'\n\ndef getUtcDate():\n sessionDate = datetime.now()\n sessionDate += timedelta(minutes=2)\n return sessionDate.strftime('%a, %d %b %Y %H:%M:%S GMT')\n\n@app.get('cookietest')\ndef getCookie(response: Response):\n cookie = cookies.Morsel()\n cookie['httponly'] = True\n cookie['version'] = '1.0.0'\n cookie['domain'] = '127.0.0.1'\n cookie['path'] = '/'\n cookie['expires'] = getUtcDate()\n cookie['max-age'] = 120\n cookie['samesite'] = 'Strict'\n cookie.set(\"jwt\", \"jwt\", mytoken)\n\n response.headers.append(\"Set-Cookie\", cookie.output())\n\n return {'status':'ok'}\n```\n\n```text\n@app.get(\"/cookietest\")\nasync def cookietest(response: Response):\n response.set_cookie(\n key='jwt', \n value=getToken(), \n max_age=120, \n expires=120, \n path='/', \n secure=False, \n httponly=True, \n samesite=\"strict\", \n domain='127.0.0.1'\n )\n return {\"Result\": \"Ok\"}\n```\n\n```text\nlogin\n```\n\n```text\ncookietest\n```\n\n```text\nset_cookie\n```\n\n```py\nfrom datetime import timedelta, datetime\n\ndef get_expiry():\n expiry = datetime.utcnow()\n expiry += timedelta(seconds=120)\n return expiry.strftime('%a, %d-%b-%Y %T GMT')\n```\n\n```py\nimport time\n\ndef get_expiry():\n lease = 120 # seconds\n end = time.gmtime(time.time() + lease)\n return time.strftime('%a, %d-%b-%Y %T GMT', end)\n```\n\n```text\ncookie['expires'] = get_expiry()\n```\n\n```text\ncookie['expires'] = 120\n```\n\n```text\ncookie['max-age'] = 120\n```\n\n```text\nNOTE: Some existing user agents do not support the Max-Age \nattribute. User agents that do not support the Max-Age attribute \nignore the attribute.\n```\n\n```py\nfrom fastapi import FastAPI, Response\n\napp = FastAPI()\n\n@app.post('/')\ndef create_cookie(response: Response):\n response.set_cookie(key='token', value='token-value', max_age=120, expires=120, httponly=True)\n return {'message': 'success'}\n```\n\n```text\nexpires\n```\n\n```text\nGMT\n```\n\n```text\nGMT+2\n```\n\n```text\n20:30:00\n```\n\n```text\nGMT\n```\n\n```text\n18:30:00\n```\n\n```text\n20:32:00 GMT\n```\n\n```text\nExpires / Max-Age\n```\n\n```text\nNetwork\n```\n\n```text\nCookies\n```\n\n```text\nZ\n```\n\n```text\nUTC\n```\n\n```text\nexpires\n```\n\n```text\n20:32:00 GMT\n```\n\n```text\nUTC\n```\n\n```text\nGMT\n```\n\n```text\n.now()\n```\n\n```text\n.utcnow()\n```\n\n```text\nsecs\n```\n\n```text\nexpires\n```\n\n```text\nmax-age\n```\n\n```text\nexpires\n```\n\n```text\nmax-age\n```\n\n```text\nmax-age\n```\n\n```text\nExpires\n```\n\n```text\nExpires\n```\n\n```text\nMax-Age\n```\n\n```text\nMax-Age\n```\n\n```text\nMax-Age\n```\n\n```text\nExpires\n```\n\n```text\nMax-Age\n```\n\n```text\nMax-Age\n```\n\n```text\nExpires\n```\n\n```text\nexpires\n```\n\n```text\nmax-age\n```\n\n```text\nExpires/Max-Age\n```\n\n```text\nset_cookie\n```\n\n```text\nResponse\n```\n\n```text\nset_cookie\n```\n\n```text\nkey\n```\n\n```text\nvalue\n```\n\n```text\nmax_age\n```\n\n```text\n0\n```\n\n```text\nOptional\n```\n\n```text\nexpires\n```\n\n```text\nOptional\n```\n\n========================================\n\nComments:\n- Just to let you know that you could create cookies using the `set_cookie` method of the `Response` object, as described in this answer. See the relevant FastAPI documentation and Starlette documentation as well.\n- You can set the `expires` flag in the `set_cookie` method, which takes an integer that defines the number of seconds until the cookie expires. For instance, if you want the cookie to expire in 2 minutes from the time it is created, use `expires=120`.\n- Ok, I change my code using set_cookie method from fastapi and now works but, why the MDN documentation says that Expires use a DateTime with format like this \"Expires: Wed, 21 Oct 2015 07:28:00 GMT\"??\n- A lot of information and so usefull. Thanks for your explanation and time.","metadata":{"transformedAt":"2026-08-18T18:32:29.143Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":58,"totalLines":376,"estimatedTokens":1683}}563{"id":"stack-75486472","source":"stackoverflow","questionId":75486472,"title":"Flask teardown request equivalent in Fastapi","tags":["python","python-3.x","fastapi"],"text":"Title: Flask teardown request equivalent in Fastapi\nTags: python, python-3.x, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am building a rest api with fastapi. I implemented the data layer separately from the fastapi application meaning I do not have direct access to the database session in my fastapi application.\n\nI have access to the storage object which have method like `close_session` which allow me to close the current session.\n\nIs there a equivalent of **flask** `teardown_request` in **fastapi**?\n\n**Flask Implementation**\n\n```\nfrom models import storage\n.....\n.....\n\n@app.teardown_request\ndef close_session(exception=None):\n storage.close_session()\n```\n\nI have looked at fastapi `on_event('shutdown')` and `on_event('startup')`. These two only runs when the application is shutting down or starting up.\n\n========================================\n\nTop Answer:\n### use fastapi middleware\n\nA \"middleware\" is a function that works with every request before it is processed by any specific path operation. And also with every response before returning it.\n\n- It takes each request that comes to your application.\n\n- It can then do something to that request or run any needed code.\n\n- Then it passes the request to be processed by the rest of the application (by some path operation).\n\n- It then takes the response generated by the application (by some path operation).\n\n- It can do something to that response or run any needed code.\n\n- Then it returns the response.\n\nExample:\n\n```\nimport time\n\nfrom fastapi import FastAPI, Request\n\napp = FastAPI()\n\n@app.middleware(\"http\")\nasync def add_process_time_header(request: Request, call_next):\n # do things before the request\n response = await call_next(request)\n # do things after the response\n return response\n```\n\n### references:\n\n- https://fastapi.tiangolo.com/tutorial/middleware/\n\n========================================\n\nCode:\n```py\nfrom models import storage\n.....\n.....\n\n@app.teardown_request\ndef close_session(exception=None):\n storage.close_session()\n```\n\n```text\nclose_session\n```\n\n```text\nteardown_request\n```\n\n```text\non_event('shutdown')\n```\n\n```text\non_event('startup')\n```\n\n```py\nfrom fastapi import FastAPI, Depends \nfrom models import storage\n \nasync def close_session() -> None: \n \"\"\"Close current after every request.\"\"\"\n print('Closing current session')\n yield \n storage.close() \n print('db session closed.')\n\napp = FastAPI(dependencies=[Depends(close_session)]) \n \n@app.get('/') \ndef home(): \n return \"Hello World\" \n \nif __name__ == '__main__': \n import uvicorn \n uvicorn.run(app)\n```\n\n```py\nimport time\n\nfrom fastapi import FastAPI, Request\n\napp = FastAPI()\n\n\n@app.middleware(\"http\")\nasync def add_process_time_header(request: Request, call_next):\n # do things before the request\n response = await call_next(request)\n # do things after the response\n return response\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.143Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":7,"totalLines":131,"estimatedTokens":865}}564{"id":"stack-72564515","source":"stackoverflow","questionId":72564515,"title":"FastAPI: Permanently running background task that listens to Postgres notifications and sends data to websocket","tags":["postgresql","websocket","python-asyncio","fastapi"],"text":"Title: FastAPI: Permanently running background task that listens to Postgres notifications and sends data to websocket\nTags: postgresql, websocket, python-asyncio, fastapi\nSource: Stack Overflow\n\nQuestion:\nMinimal reproducible example:\n\n```\nimport asyncio\nimport aiopg\nfrom fastapi import FastAPI, WebSocket\n\ndsn = \"dbname=aiopg user=aiopg password=passwd host=127.0.0.1\"\napp = FastAPI()\n\nclass ConnectionManager:\n self.count_connections = 0\n # other class functions and variables are taken from FastAPI docs\n ...\n\nmanager = ConnectionManager()\n\nasync def send_and_receive_data(websocket: WebSocket):\n data = await websocket.receive_json()\n await websocket.send_text('Thanks for the message')\n # then process received data\n\n# taken from official aiopg documentation\n# the function listens to PostgreSQL notifications\nasync def listen(conn):\n async with conn.cursor() as cur:\n await cur.execute(\"LISTEN channel\")\n while True:\n msg = await conn.notifies.get()\n\nasync def postgres_listen():\n async with aiopg.connect(dsn) as listenConn:\n listener = listen(listenConn)\n await listener\n\n@app.get(\"/\")\ndef read_root():\n return {\"Hello\": \"World\"}\n\n@app.websocket(\"/\")\nasync def websocket_endpoint(websocket: WebSocket):\n await manager.connect(websocket)\n manager.count_connections += 1\n\n if manager.count_connections == 1:\n await asyncio.gather(\n send_and_receive_data(websocket),\n postgres_listen()\n )\n else:\n await send_and_receive_data(websocket)\n```\n\nDescription of the problem:\n\nI am building an app with Vue.js, FastAPI and PostgreSQL. In this example I attempt to use listen/notify from Postgres and implement it in the websocket. I also use a lot of usual http endpoints along with the websocket endpoint.\n\nI want to run a permanent background asynchronous function at the start of the FastAPI app that will then send messages to all websocket clients/connections. So, when I use `uvicorn main:app` it should not only run the FastAPI app but also my background function `postgres_listen()`, which notifies all websocket users, when a new row is added to the table in the database.\n\nI know that I can use `asyncio.create_task()` and place it in the `on_*` event, or even place it after the `manager = ConnectionManager()` row, but it will not work in my case! Because after any http request (for instance, `read_root()` function), I will get the same error described below.\n\nYou see that I use a strange way to run my `postgres_listen()` function in my `websocket_endpoint()` function only when the first client connects to the websocket. Any subsequent client connection does not run/trigger this function again. And everything works fine... until the first client/user disconnects (for example, closes browser tab). When it happens, I immediately get the `GeneratorExit` error caused by `psycopg2.OperationalError`:\n\n```\nFuture exception was never retrieved\nfuture: \npsycopg2.OperationalError: Connection closed\nTask was destroyed but it is pending!\ntask: wait_for=>\n```\n\nThe error comes from the `listen()` function. After this error, I will not get any notification from the database as the asyncio's `Task` is cancelled. There is nothing wrong with the `psycopg2`, `aiopg` or `asyncio`. The problem is that I don't understand where to put the `postgres_listen()` function so it will not be cancelled after the first client disconnects. From my understanding, I can easily write a python script that will connect to the websocket (so I will be the first client of the websocket) and then run forever so I will not get the `psycopg2.OperationalError` exception again, but it does not seem right to do so.\n\nMy question is: where should I put `postgres_listen()` function, so the first connection to websocket may be disconnected with no consequences?\n\nP.S. `asyncio.shield()` also does not work\n\n========================================\n\nCode:\n```text\nimport asyncio\nimport aiopg\nfrom fastapi import FastAPI, WebSocket\n\n\ndsn = \"dbname=aiopg user=aiopg password=passwd host=127.0.0.1\"\napp = FastAPI()\n\n\nclass ConnectionManager:\n self.count_connections = 0\n # other class functions and variables are taken from FastAPI docs\n ...\n\n\nmanager = ConnectionManager()\n\n\nasync def send_and_receive_data(websocket: WebSocket):\n data = await websocket.receive_json()\n await websocket.send_text('Thanks for the message')\n # then process received data\n\n\n# taken from official aiopg documentation\n# the function listens to PostgreSQL notifications\nasync def listen(conn):\n async with conn.cursor() as cur:\n await cur.execute(\"LISTEN channel\")\n while True:\n msg = await conn.notifies.get()\n\n\nasync def postgres_listen():\n async with aiopg.connect(dsn) as listenConn:\n listener = listen(listenConn)\n await listener\n\n\n@app.get(\"/\")\ndef read_root():\n return {\"Hello\": \"World\"}\n\n\n@app.websocket(\"/\")\nasync def websocket_endpoint(websocket: WebSocket):\n await manager.connect(websocket)\n manager.count_connections += 1\n\n if manager.count_connections == 1:\n await asyncio.gather(\n send_and_receive_data(websocket),\n postgres_listen()\n )\n else:\n await send_and_receive_data(websocket)\n```\n\n```text\nFuture exception was never retrieved\nfuture: <Future finished exception=OperationalError('Connection closed')>\npsycopg2.OperationalError: Connection closed\nTask was destroyed but it is pending!\ntask: <Task pending name='Task-18' coro=<Queue.get() done, defined at \n/home/user/anaconda3/lib/python3.8/asyncio/queues.py:154> wait_for=<Future cancelled>>\n```\n\n```text\nuvicorn main:app\n```\n\n```text\npostgres_listen()\n```\n\n```text\nasyncio.create_task()\n```\n\n```text\non_*\n```\n\n```text\nmanager = ConnectionManager()\n```\n\n```text\nread_root()\n```\n\n```text\npostgres_listen()\n```\n\n```text\nwebsocket_endpoint()\n```\n\n```text\nGeneratorExit\n```\n\n```text\npsycopg2.OperationalError\n```\n\n```text\nlisten()\n```\n\n```text\nTask\n```\n\n```text\npsycopg2\n```\n\n```text\naiopg\n```\n\n```text\nasyncio\n```\n\n```text\npostgres_listen()\n```\n\n```text\npsycopg2.OperationalError\n```\n\n```text\npostgres_listen()\n```\n\n```text\nasyncio.shield()\n```\n\n```py\n# app.py\nimport queue\nfrom typing import Any\nfrom fastapi import FastAPI, WebSocket, WebSocketDisconnect\nfrom asyncio import Queue, Task\nimport asyncio\n\nimport uvicorn\nimport websockets\n\nclass Listener:\n def __init__(self):\n #Every incoming websocket conneciton adds it own Queue to this list called \n #subscribers.\n self.subscribers: list[Queue] = []\n #This will hold a asyncio task which will receives messages and broadcasts them \n #to all subscribers.\n self.listener_task: Task\n\n async def subscribe(self, q: Queue):\n #Every incoming websocket connection must create a Queue and subscribe itself to \n #this class instance \n self.subscribers.append(q)\n\n\n async def start_listening(self):\n #Method that must be called on startup of application to start the listening \n #process of external messages.\n self.listener_task = asyncio.create_task(self._listener())\n\n async def _listener(self) -> None:\n #The method with the infinite listener. In this example, it listens to a websocket\n #as it was the fastest way for me to mimic the 'infinite generator' in issue 5015\n #but this can be anything. It is started (via start_listening()) on startup of app.\n async with websockets.connect(\"ws://localhost:8001\") as websocket:\n async for message in websocket:\n for q in self.subscribers:\n #important here: every websocket connection has its own Queue added to\n #the list of subscribers. Here, we actually broadcast incoming messages\n #to all open websocket connections.\n await q.put(message)\n\n async def stop_listening(self):\n #closing off the asyncio task when stopping the app. This method is called on \n #app shutdown\n if self.listener_task.done():\n self.listener_task.result()\n else:\n self.listener_task.cancel()\n\n async def receive_and_publish_message(self, msg: Any):\n #this was a method that was called when someone would make a request \n #to /add_item endpoint as part of earlier solution to see if the msg would be \n #broadcasted to all open websocket connections (it does)\n for q in self.subscribers:\n try:\n q.put_nowait(str(msg))\n except Exception as e:\n raise e\n\n #Note: missing here is any disconnect logic (e.g. removing the queue from the list of subscribers\n # when a websocket connection is ended or closed.)\n\n \nglobal_listener = Listener()\n\napp = FastAPI()\n\n@app.on_event(\"startup\")\nasync def startup_event():\n await global_listener.start_listening()\n return\n\n@app.on_event(\"shutdown\")\nasync def shutdown_event():\n await global_listener.stop_listening()\n return\n\n\n@app.get('/add_item/{item}')\nasync def add_item(item: str):\n #this was a test endpoint, to see if new items where actually broadcasted to all \n #open websocket connections.\n await global_listener.receive_and_publish_message(item)\n return {\"published_message:\": item}\n\n@app.websocket(\"/ws\")\nasync def websocket_endpoint(websocket: WebSocket):\n await websocket.accept()\n q: asyncio.Queue = asyncio.Queue()\n await global_listener.subscribe(q=q)\n try:\n while True:\n data = await q.get()\n await websocket.send_text(data)\n except WebSocketDisconnect:\n return\n\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n```\n\n```py\n# generator.py\nfrom fastapi import FastAPI, WebSocket, WebSocketDisconnect\nimport asyncio\nimport uvicorn\n\n\napp = FastAPI()\n\n@app.websocket(\"/\")\nasync def ws(websocket: WebSocket):\n await websocket.accept()\n i = 0\n while True:\n try:\n await websocket.send_text(f\"Hello - {i}\")\n await asyncio.sleep(2)\n i+=1\n except WebSocketDisconnect:\n pass\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", port=8001)\n```\n\n========================================\n\nComments:\n- Is there a way i could send message to a connection instead of all connections?","metadata":{"transformedAt":"2026-08-18T18:32:29.143Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":23,"totalLines":362,"estimatedTokens":2575}}565{"id":"stack-66936511","source":"stackoverflow","questionId":66936511,"title":"Pydantic field JSON alias simply does not work","tags":["python","fastapi","pydantic"],"text":"Title: Pydantic field JSON alias simply does not work\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI need to specify a JSON alias for a Pydantic object. It simply does not work.\n\n```\nfrom pydantic import Field\nfrom pydantic.main import BaseModel\n\nclass ComplexObject(BaseModel):\n for0: str = Field(None, alias=\"for\")\n\ndef create(x: int, y: int):\n print(\"was here\")\n co = ComplexObject(for0=str(x * y))\n return co\n\nco = create(x=1, y=2)\nprint(co.json(by_alias=True))\n```\n\nThe output for this is `{\"for\" : null` instead of `{\"for\" : \"2\"`}\n\nIs this real? How can such a simple use case not work?\n\n========================================\n\nTop Answer:\nYou can add the `allow_population_by_field_name=True` value on the `Config` for the pydantic model.\n\n```\n>>> class ComplexObject(BaseModel):\n... class Config:\n... allow_population_by_field_name = True\n... for0: str = Field(None, alias=\"for\")\n...\n>>>\n>>> def create(x: int, y: int):\n... print(\"was here\")\n... co = ComplexObject(for0=str(x * y))\n... return co\n...\n>>>\n>>> co = create(x=1, y=2)\nwas here\n>>> print(co.json(by_alias=True))\n{\"for\": \"2\"}\n>>> co.json()\n'{\"for0\": \"2\"}'\n>>> co.json(by_alias=False)\n'{\"for0\": \"2\"}'\n>>> ComplexObject.parse_raw('{\"for\": \"xyz\"}')\nComplexObject(for0='xyz')\n>>> ComplexObject.parse_raw('{\"for\": \"xyz\"}').json(by_alias=True)\n'{\"for\": \"xyz\"}'\n>>> ComplexObject.parse_raw('{\"for0\": \"xyz\"}').json(by_alias=True)\n'{\"for\": \"xyz\"}'\n```\n\n========================================\n\nCode:\n```text\nfrom pydantic import Field\nfrom pydantic.main import BaseModel\n\n\nclass ComplexObject(BaseModel):\n for0: str = Field(None, alias=\"for\")\n\n\ndef create(x: int, y: int):\n print(\"was here\")\n co = ComplexObject(for0=str(x * y))\n return co\n\n\nco = create(x=1, y=2)\nprint(co.json(by_alias=True))\n```\n\n```text\n{\"for\" : null\n```\n\n```text\n{\"for\" : \"2\"\n```\n\n```text\nComplexObject(for=str(x * y))\n```\n\n```text\nfor\n```\n\n```text\nco = ComplexObject(**{\"for\": str(x * y)})\n```\n\n```py\n>>> class ComplexObject(BaseModel):\n... class Config:\n... allow_population_by_field_name = True\n... for0: str = Field(None, alias=\"for\")\n...\n>>>\n>>> def create(x: int, y: int):\n... print(\"was here\")\n... co = ComplexObject(for0=str(x * y))\n... return co\n...\n>>>\n>>> co = create(x=1, y=2)\nwas here\n>>> print(co.json(by_alias=True))\n{\"for\": \"2\"}\n>>> co.json()\n'{\"for0\": \"2\"}'\n>>> co.json(by_alias=False)\n'{\"for0\": \"2\"}'\n>>> ComplexObject.parse_raw('{\"for\": \"xyz\"}')\nComplexObject(for0='xyz')\n>>> ComplexObject.parse_raw('{\"for\": \"xyz\"}').json(by_alias=True)\n'{\"for\": \"xyz\"}'\n>>> ComplexObject.parse_raw('{\"for0\": \"xyz\"}').json(by_alias=True)\n'{\"for\": \"xyz\"}'\n```\n\n```text\nallow_population_by_field_name=True\n```\n\n```text\nConfig\n```\n\n========================================\n\nComments:\n- Also instead of using reserved words like \"for\" or \"map\" it is common practice to use for_ or map_ with underscore at the end","metadata":{"transformedAt":"2026-08-18T18:32:29.143Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":9,"totalLines":144,"estimatedTokens":727}}566{"id":"stack-63784723","source":"stackoverflow","questionId":63784723,"title":"FastAPI finds my JSON array of objects an invalid list","tags":["python","json","fastapi","starlette"],"text":"Title: FastAPI finds my JSON array of objects an invalid list\nTags: python, json, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nI'm using FastAPI and I'm trying to send a JSON array of JSON objects to my post endpoint, in the body.\nMy endpoint is defined as:\n\n```\n@router.post(\"/create_mails\")\ndef create_mails(notas: List[schemas.Nota], db: Session = Depends(get_db)):\n```\n\nMy body in Postman looks like:\n\n```\n{\n \"notas\": [{\"a\":\"1\",\"b\":\"2\",\"c\":\"3\",\"d\":\"4\"},\n {\"a\":\"1\",\"b\":\"2\",\"c\":\"3\",\"d\":\"4\"}]\n}\n```\n\nHowever, I keep getting the 422 unprocessable entity error from FastAPI, with the error detail:\n\n*value is not a valid list*\n\nI also tested it with a modified endpoint:\n\n```\n@router.post(\"/create_mails\")\ndef create_mails(notas: List[str] = Body([]), db: Session = Depends(get_db)):\n```\n\nand with a simple string array, but the same error is returned.\n\nAm I missing FastAPI's definition of a valid list?\n\n========================================\n\nCode:\n```py\n@router.post(\"/create_mails\")\ndef create_mails(notas: List[schemas.Nota], db: Session = Depends(get_db)):\n```\n\n```json\n{\n \"notas\": [{\"a\":\"1\",\"b\":\"2\",\"c\":\"3\",\"d\":\"4\"},\n {\"a\":\"1\",\"b\":\"2\",\"c\":\"3\",\"d\":\"4\"}]\n}\n```\n\n```py\n@router.post(\"/create_mails\")\ndef create_mails(notas: List[str] = Body([]), db: Session = Depends(get_db)):\n```\n\n```text\nclass NotaList(BaseModel):\n notas: List[Nota]\n```\n\n```text\ndef create_mails(body: schemas.NotaList)\n```\n\n```text\nfor nota in body.notas:\n # do stuff\n```\n\n```text\nbody\n```\n\n```text\nnotas\n```\n\n```text\nnotas\n```\n\n========================================\n\nComments:\n- I tried this with class: `class NotaList(BaseModel): list: List[schemas.Nota]` , and tested with data: `{ \"notas\": {\"list\": [{\"a\":\"1\",\"b\":\"2\",\"c\":\"3\",\"d\":\"4\"}, {\"a\":\"1\",\"b\":\"2\",\"c\":\"3\",\"d\":\"4\"}]} }` But I get the error: `{\"detail\":[{\"loc\":[\"body\",\"list\"],\"msg\":\"field required\",\"type\":\"value_error.missing\"}]}`\n- @Simon if your `NotaList` class attribute is named `list` then the post variable also has to be `\"list`\" -- why are you wrapping it in an extra `\"notas\"` ?\n- Ahh thanks this was my mistake! I thought it had to be in an extra \"notas\" because my method parameter was called like that. But using only list is the trick!\n- Your method parameter's name is only relevant to your own code, and it represents the \"nameless\" *top-level* dictionary in the POST.","metadata":{"transformedAt":"2026-08-18T18:32:29.144Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":90,"estimatedTokens":589}}567{"id":"stack-73263202","source":"stackoverflow","questionId":73263202,"title":"How to display uploaded image in HTML page using FastAPI & Jinja2?","tags":["python","html","python-3.x","fastapi"],"text":"Title: How to display uploaded image in HTML page using FastAPI & Jinja2?\nTags: python, html, python-3.x, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm using FastAPI & Jinja2 to serve an HTML page to upload an image file, and then open another HTML link with the uploaded image name to show that image. Even though I was able to get the uploading part and the uploaded image link working, I was unable to get the `src` tag to work to actually display the image. How could I solve that?\n\nThis is **main.py**:\n\n```\nfrom fastapi import FastAPI, File, UploadFile,Request\nfrom fastapi.responses import HTMLResponse\nfrom fastapi.staticfiles import StaticFiles \nfrom fastapi.templating import Jinja2Templates\n\napp = FastAPI()\napp.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")\n \"\"\" upload file and save it to local \"\"\" \n@app.post(\"/upload-file\")\nasync def upload_file(file: UploadFile = File(...)):\nwith open(file.filename, \"wb\") as f:\n f.write(file.file.read())\nreturn {\"filename\": file.filename}\n\n''' create html page to show uploaded file '''\n@app.get(\"/\")\nasync def root():\nhtml_content = \"\"\"\n\n \n Upload File\n \n \n \n\n### Upload File\n\n \n \n \n \n \n\n\"\"\"\nreturn HTMLResponse(content=html_content)\n\ntemplates = Jinja2Templates(directory=\"templates\")\n\n @app.get(\"/{filename}\", response_class=HTMLResponse)\n async def read_item(request: Request, filename: str):\n return templates.TemplateResponse(\"template.html\", {\"request\": request,\"filename\": filename})\n```\n\nand this is **template.html**:\n\n```\n\n HTML img Tag\n\n \n\n```\n\nI'm open to better/simpler ways to achieve the needed results. Thanks.\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI, File, UploadFile,Request\nfrom fastapi.responses import HTMLResponse\nfrom fastapi.staticfiles import StaticFiles \nfrom fastapi.templating import Jinja2Templates\n\napp = FastAPI()\napp.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")\n \"\"\" upload file and save it to local \"\"\" \n@app.post(\"/upload-file\")\nasync def upload_file(file: UploadFile = File(...)):\nwith open(file.filename, \"wb\") as f:\n f.write(file.file.read())\nreturn {\"filename\": file.filename}\n\n''' create html page to show uploaded file '''\n@app.get(\"/\")\nasync def root():\nhtml_content = \"\"\"\n<html>\n <head>\n <title>Upload File</title>\n </head>\n <body>\n <h1>Upload File</h1>\n <form action=\"/upload-file/\" method=\"post\" enctype=\"multipart/form-data\">\n <input type=\"file\" name=\"file\" />\n <input type=\"submit\" />\n </form>\n </body>\n</html>\n\"\"\"\nreturn HTMLResponse(content=html_content)\n\n\ntemplates = Jinja2Templates(directory=\"templates\")\n\n\n @app.get(\"/{filename}\", response_class=HTMLResponse)\n async def read_item(request: Request, filename: str):\n return templates.TemplateResponse(\"template.html\", {\"request\": request,\"filename\": filename})\n```\n\n```text\n<!DOCTYPE html>\n<html>\n<head>\n <title>HTML img Tag</title>\n</head>\n\n<body>\n <img src= \"{{./filename}} \" alt=\"uploaded image\" width=\"400\" height=\"400\">\n</body>\n</html>\n```\n\n```text\nsrc\n```\n\n```py\nfrom fastapi import File, UploadFile, Request, FastAPI, HTTPException\nfrom fastapi.templating import Jinja2Templates\n\napp = FastAPI()\ntemplates = Jinja2Templates(directory=\"templates\")\n\n@app.post(\"/upload\")\ndef upload(file: UploadFile = File(...)):\n try:\n contents = file.file.read()\n with open(\"uploaded_\" + file.filename, \"wb\") as f:\n f.write(contents)\n except Exception:\n raise HTTPException(status_code=500, detail='Something went wrong')\n finally:\n file.file.close()\n \n return {\"message\": f\"Successfuly uploaded {file.filename}\"}\n\n@app.get(\"/\")\ndef main(request: Request):\n return templates.TemplateResponse(\"index.html\", {\"request\": request})\n```\n\n```html\n<script type=\"text/javascript\">\n function previewFile() {\n const preview = document.querySelector('img');\n const file = document.querySelector('input[type=file]').files[0];\n const reader = new FileReader();\n reader.addEventListener(\"load\", function() {\n preview.src = reader.result; // show image in <img> tag\n uploadFile(file)\n }, false);\n if (file) {\n reader.readAsDataURL(file);\n }\n }\n\n function uploadFile(file) {\n var formData = new FormData();\n formData.append('file', file);\n fetch('/upload', {\n method: 'POST',\n body: formData,\n })\n .then(response => {\n console.log(response);\n })\n .catch(error => {\n console.error(error);\n });\n }\n</script>\n<input type=\"file\" onchange=\"previewFile()\"><br>\n<img src=\"\" height=\"200\" alt=\"Image preview...\">\n```\n\n```html\n<script type=\"text/javascript\">\n function previewFile() {\n const preview = document.querySelector('img');\n var file = document.getElementById('fileInput').files[0];\n const reader = new FileReader();\n reader.addEventListener(\"load\", function() {\n preview.src = reader.result; // show image in <img> tag\n }, false);\n if (file) {\n reader.readAsDataURL(file);\n }\n }\n\n function uploadFile(file) {\n var file = document.getElementById('fileInput').files[0];\n if (file) {\n var formData = new FormData();\n formData.append('file', file);\n fetch('/upload', {\n method: 'POST',\n body: formData,\n })\n .then(response => response.json())\n .then(data => {\n document.getElementById(\"serverMsg\").innerHTML = data.message;\n })\n .catch(error => {\n console.error(error);\n });\n }\n }\n</script>\n<input type=\"file\" id=\"fileInput\" onchange=\"previewFile()\"><br>\n<input type=\"button\" value=\"Upload Image\" onclick=\"uploadFile()\">\n<p id=\"serverMsg\"></p>\n<img height=\"200\">\n```\n\n```html\n<script type=\"text/javascript\">\n function previewFile() {\n const preview = document.querySelector('img');\n var file = document.getElementById('fileInput').files[0];\n const reader = new FileReader();\n reader.addEventListener(\"load\", function () {\n displayImgInNewTab(reader.result)\n }, false);\n if (file) {\n reader.readAsDataURL(file);\n }\n }\n\n function uploadFile() {\n var file = document.getElementById('fileInput').files[0];\n if (file) {\n var formData = new FormData();\n formData.append('file', file);\n fetch('/upload', {\n method: 'POST',\n body: formData,\n })\n .then(response => response.json())\n .then(data => {\n document.getElementById(\"serverMsg\").innerHTML = data.message;\n })\n .catch(error => {\n console.error(error);\n });\n previewFile()\n }\n }\n\n function displayImgInNewTab(data) {\n var image = new Image();\n image.src = data\n var w = window.open(\"\");\n w.document.write(image.outerHTML);\n }\n</script>\n<!--<input type=\"file\" id=\"fileInput\" onchange=\"previewFile()\"><br>-->\n<input type=\"file\" id=\"fileInput\"><br>\n<input type=\"button\" value=\"Upload Image\" onclick=\"uploadFile()\">\n<p id=\"serverMsg\"></p>\n<img height=\"200\">\n```\n\n```py\nfrom fastapi import File, UploadFile, Request, FastAPI, HTTPException\nfrom fastapi.templating import Jinja2Templates\nimport base64\n\napp = FastAPI()\ntemplates = Jinja2Templates(directory=\"templates\")\n\n@app.get(\"/\")\ndef main(request: Request):\n return templates.TemplateResponse(\"index.html\", {\"request\": request})\n \n@app.post(\"/upload\")\ndef upload(request: Request, file: UploadFile = File(...)):\n try:\n contents = file.file.read()\n with open(\"uploaded_\" + file.filename, \"wb\") as f:\n f.write(contents)\n except Exception:\n raise HTTPException(status_code=500, detail='Something went wrong')\n finally:\n file.file.close()\n \n base64_encoded_image = base64.b64encode(contents).decode(\"utf-8\")\n\n return templates.TemplateResponse(\"display.html\", {\"request\": request, \"myImage\": base64_encoded_image})\n```\n\n```html\n<html>\n <body>\n <form method=\"post\" action=\"/upload\" enctype=\"multipart/form-data\"> \n <label for=\"file\">Choose image to upload</label>\n <input type=\"file\" id=\"files\" name=\"file\"><br> \n <input type=\"submit\" value=\"Upload\">\n </form>\n </body>\n</html>\n```\n\n```html\n<html>\n <head>\n <title>Display Uploaded Image</title>\n </head>\n <body>\n <h1>My Image<h1>\n <img src=\"data:image/jpeg;base64,{{ myImage | safe }}\">\n </body>\n</html>\n```\n\n```text\nFileReader.readAsDataURL()\n```\n\n```text\nUpload Image\n```\n\n```text\n\"Upload Image\"\n```\n\n```text\npreviewFile()\n```\n\n```text\nuploadFile()\n```\n\n```text\n<input type=\"file\">\n```\n\n```text\nonchange=\"previewFile()\"\n```\n\n```text\nTemplateResponse\n```\n\n```text\nStaticFiles\n```\n\n```text\nurl_for()\n```\n\n```text\n{{ url_for('static', path='/uploaded_img.png') }}\n```\n\n```text\nfilename\n```\n\n```text\nStaticFiles\n```\n\n```text\nTemplateResponse\n```\n\n```text\n'imgPath': /static/uploaded_img.png'\n```\n\n```text\nJinja2Template\n```\n\n```text\n<img src=\"{{ imgPath }}\">\n```\n\n```text\n/static\n```\n\n========================================\n\nComments:\n- Does this answer your question? How to Download a File after POSTing data using FastAPI?\n- Also, please have a look at this, this, as well as this and this answer. Note: if what you want is to display the same image that the user has uploaded, you don't need to have FastAPI send it back to you, just use `FileReader.readAsDataURL()` (as shown in Option 2 of the last link above) that allows you to preview the img.\n- Thanks for the example provided Chris , while it actually does show the uploaded image , It is important to my use is to be able preview image in separate html page. I will try to create another template and include the preview part of the script .\n- I was able to make it work , and I used the revised code you provided \" much better code than mine \" , I accept your solution and marked it as answer . Thank you Chris.\n- If you had to define the `/upload` endpoint with `async def` - as you might need to `await` for some other coroutines - please have a look at this answer on how to use `async` writing with `aiofiles`. I would also suggest you have a look here for more details on `def` vs `async def`.","metadata":{"transformedAt":"2026-08-18T18:32:29.144Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":28,"totalLines":406,"estimatedTokens":2650}}568{"id":"stack-73253559","source":"stackoverflow","questionId":73253559,"title":"How to handle path operations getting mixed-up in FastAPI?","tags":["python","fastapi"],"text":"Title: How to handle path operations getting mixed-up in FastAPI?\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI've got two path operation functions that look similar, except that the first one returns all the data for a *specific* user and the second one only the data of the *current* (logged in) user (with the schema `UserOut`, which has fewer fields):\n\n```\n@router.get(\"/{id}\", response_model=User)\nasync def get_user(user_id: PydanticObjectId):\n user = await User.find_one(User.id == user_id)\n if user is None:\n raise HTTPException(status_code=404, detail=\"User not found\")\n return user\n\n@router.get(\"/me\")\nasync def get_current_user(current_user: User = Depends(get_current_active_user)):\n return current_user\n```\n\nThe problem is when I call from Postman the second method, it takes the endpoint `/me` as the `id` of the first endpoint, so I always get the pydantic validation error that `\"me\" is not a valid user ID`.\n\nHow could I solve this problem? Do I need to necessarily modify my endpoints or are there any other alternatives?\n\n========================================\n\nTop Answer:\nThe fact that both endpoints return the same resource (they both return a user) is an indicator that maybe they should just be 1 endpoint that returns a user specified by an ID, or the current logged-in one *by default*.\n\nWhile you *can* differentiate based on how the endpoints are defined (as given by the other answer), I find that solution to be \"brittle\", in the sense that you (and other developers maintaining and reading your code) would have to *always* remember that the order matters, which can easily cause bugs when you (or someone else) reorganize or refactor the code.\n\nSo, as an alternative, you can just combine those 2 endpoints into 1 `get_user` endpoint:\n\n```\nfrom typing import Optional\nfrom fastapi import Query\nfrom pydantic import BaseModel, NonNegativeInt\n\nclass User(BaseModel):\n user_id: NonNegativeInt\n other_field: str = \"\"\n\n @classmethod\n async def find_one(cls, user_id: NonNegativeInt) -> \"User\":\n \"\"\"This is a fake method that returns a User from somewhere\"\"\"\n return cls(user_id=user_id, other_field=str(user_id) * 5)\n\ndef get_current_active_user() -> User:\n \"\"\"This is a fake method that somehow gets the logged-in user\"\"\"\n return User(user_id=0, other_field=\"This is the logged-in user\")\n\n@router.get(\"/user\", response_model=User)\nasync def get_user(user_id: Optional[NonNegativeInt] = Query(default=None)):\n if user_id:\n user = await User.find_one(user_id)\n else:\n user = get_current_active_user()\n\n if not user:\n raise HTTPException(status_code=404, detail=\"User not found\")\n\n return user\n```\n\n```\n$ curl -XGET localhost:8000/user\n{\"user_id\":0,\"other_field\":\"This is the logged-in user\"}\n\n$ curl -XGET localhost:8000/user?user_id=444\n{\"user_id\":444,\"other_field\":\"This is a different user\"}\n```\n\nThe advantages of this are, for one, the order *doesn't anymore matter*, and two, the same set of validations and parameters on the request and the response can be done on the same endpoint function.\n\nNow for the case of having 2 different response models:\n\n... the first one returns all the data for a specific user and the second one only the data of the current (logged in) user (with the schema UserOut, which has less fields)\n\nI don't know the use-case why the response for the logged-in user needs to have less fields, but, check out the section on defining multiple models from the FastAPI tutorials. Basically, you would want a base user model that has the minimum fields (to represent your logged-in user) and a more specific user model with all the other fields to represent the \"found\" users) Then define your route to be a `Union` of these 2 different types.\n\n```\nclass BaseUser(BaseModel):\n user_id: NonNegativeInt\n\nclass LoggedInUser(BaseUser):\n pass\n\nclass SomeOtherUser(BaseUser):\n other_field: str\n\n @classmethod\n async def find_one(cls, user_id: NonNegativeInt) -> \"SomeOtherUser\":\n \"\"\"This is a fake method that returns a User from somewhere\"\"\"\n return cls(user_id=user_id, other_field=\"This is a different user\")\n\ndef get_current_active_user() -> LoggedInUser:\n \"\"\"This is a fake method that somehow gets the logged-in user\"\"\"\n return LoggedInUser(user_id=0)\n\n@router.get(\"/user\", response_model=Union[SomeOtherUser, LoggedInUser])\nasync def get_user(user_id: Optional[NonNegativeInt] = Query(default=None)):\n if user_id:\n user = await SomeOtherUser.find_one(user_id)\n else:\n user = get_current_active_user()\n\n if not user:\n raise HTTPException(status_code=404, detail=\"User not found\")\n\n return user\n```\n\n```\n$ curl -XGET localhost:8000/user\n{\"user_id\":0}\n\n$ curl -XGET localhost:8000/user?user_id=444\n{\"user_id\":444,\"other_field\":\"This is a different user\"}\n```\n\n========================================\n\nCode:\n```text\n@router.get(\"/{id}\", response_model=User)\nasync def get_user(user_id: PydanticObjectId):\n user = await User.find_one(User.id == user_id)\n if user is None:\n raise HTTPException(status_code=404, detail=\"User not found\")\n return user\n\n\n@router.get(\"/me\")\nasync def get_current_user(current_user: User = Depends(get_current_active_user)):\n return current_user\n```\n\n```text\nUserOut\n```\n\n```text\n/me\n```\n\n```text\nid\n```\n\n```text\n\"me\" is not a valid user ID\n```\n\n```py\n@router.get(\"/me\")\nasync def get_current_user():\n pass\n \n@router.get(\"/{id}\")\nasync def get_user():\n pass\n```\n\n```text\n/me\n```\n\n```text\n/{id}\n```\n\n```text\n/me\n```\n\n```text\n/{id}\n```\n\n```text\nfrom typing import Optional\nfrom fastapi import Query\nfrom pydantic import BaseModel, NonNegativeInt\n\nclass User(BaseModel):\n user_id: NonNegativeInt\n other_field: str = \"\"\n\n @classmethod\n async def find_one(cls, user_id: NonNegativeInt) -> \"User\":\n \"\"\"This is a fake method that returns a User from somewhere\"\"\"\n return cls(user_id=user_id, other_field=str(user_id) * 5)\n\ndef get_current_active_user() -> User:\n \"\"\"This is a fake method that somehow gets the logged-in user\"\"\"\n return User(user_id=0, other_field=\"This is the logged-in user\")\n\n@router.get(\"/user\", response_model=User)\nasync def get_user(user_id: Optional[NonNegativeInt] = Query(default=None)):\n if user_id:\n user = await User.find_one(user_id)\n else:\n user = get_current_active_user()\n\n if not user:\n raise HTTPException(status_code=404, detail=\"User not found\")\n\n return user\n```\n\n```none\n$ curl -XGET localhost:8000/user\n{\"user_id\":0,\"other_field\":\"This is the logged-in user\"}\n\n$ curl -XGET localhost:8000/user?user_id=444\n{\"user_id\":444,\"other_field\":\"This is a different user\"}\n```\n\n```text\nclass BaseUser(BaseModel):\n user_id: NonNegativeInt\n\nclass LoggedInUser(BaseUser):\n pass\n\nclass SomeOtherUser(BaseUser):\n other_field: str\n\n @classmethod\n async def find_one(cls, user_id: NonNegativeInt) -> \"SomeOtherUser\":\n \"\"\"This is a fake method that returns a User from somewhere\"\"\"\n return cls(user_id=user_id, other_field=\"This is a different user\")\n\ndef get_current_active_user() -> LoggedInUser:\n \"\"\"This is a fake method that somehow gets the logged-in user\"\"\"\n return LoggedInUser(user_id=0)\n\n@router.get(\"/user\", response_model=Union[SomeOtherUser, LoggedInUser])\nasync def get_user(user_id: Optional[NonNegativeInt] = Query(default=None)):\n if user_id:\n user = await SomeOtherUser.find_one(user_id)\n else:\n user = get_current_active_user()\n\n if not user:\n raise HTTPException(status_code=404, detail=\"User not found\")\n\n return user\n```\n\n```none\n$ curl -XGET localhost:8000/user\n{\"user_id\":0}\n\n$ curl -XGET localhost:8000/user?user_id=444\n{\"user_id\":444,\"other_field\":\"This is a different user\"}\n```\n\n```text\nget_user\n```\n\n```text\nUnion\n```\n\n========================================\n\nComments:\n- How about /user?id=XXX","metadata":{"transformedAt":"2026-08-18T18:32:29.144Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":16,"totalLines":270,"estimatedTokens":1948}}569{"id":"stack-72193090","source":"stackoverflow","questionId":72193090,"title":"FastAPI with APIRouter plugin system not working","tags":["python","plugins","fastapi","python-importlib"],"text":"Title: FastAPI with APIRouter plugin system not working\nTags: python, plugins, fastapi, python-importlib\nSource: Stack Overflow\n\nQuestion:\nI'm trying to create a simple pluggable FastAPI application where plugins can add, or not, API endpoints\n\nThis is my folder structure:\n\nhttps://i.sstatic.net/P2ZoM.png\n\nserver.py\n\n```\nimport importlib\nimport pkgutil\nfrom pathlib import Path\n\nimport uvicorn\nfrom fastapi import FastAPI\n\nPLUGINS_PATH = Path(__file__).parent.joinpath(\"plugins\")\napp = FastAPI()\n\ndef import_module(module_name):\n \"\"\"Imports a module by it's name from plugins folder.\"\"\"\n module = f\"plugins.{module_name}\"\n return importlib.import_module(module, \".\")\n\ndef load_plugins() -> list:\n \"\"\"Import plugins from plugins folder.\"\"\"\n loaded_apps = []\n for _, application, _ in pkgutil.iter_modules([str(PLUGINS_PATH)]):\n module = import_module(application)\n print(\n f\"Loaded app: {module.__meta__['plugin_name']} -- version: {module.__meta__['version']}\"\n )\n loaded_apps.append(module)\n return loaded_apps\n\n@app.get(\"/\")\ndef main():\n return \"Hello World!\"\n\nif __name__ == \"__main__\":\n plugins = load_plugins()\n\n for plugin in plugins:\n \"\"\"Register the plugins router.\"\"\"\n if \"router\" in plugin.__dir__():\n app_router = plugin.router\n app.include_router(app_router)\n\n uvicorn.run(\"server:app\", host=\"localhost\", port=8000, reload=True)\n```\n\nAnd in my plugins folder I have:\n\nThe `plugins/non_api_plugin/__init__.py`:\n\n```\n__meta__ = {\"plugin_name\": \"NON API plugin\", \"version\": \"0.0.1\"}\n```\n\nThe `plugins//__init__.py`\n\n```\nfrom .routes import routes as router\n\n__meta__ = {\"plugin_name\": \"API \", \"version\": \"0.0.1\"}\n```\n\nAnd routes.py files:\n\n```\nfrom fastapi import APIRouter\n\nroutes = APIRouter(prefix=\"/\")\n\n@routes.get(\"/\")\ndef novels():\n return \"Hello World from \"\n```\n\nWhen I run the server, the plugins are loaded and log their information, but the API endpoints are not loaded.\n\nWhat I'm missing here? My best guess is that my plugin load system is wrong at some point.\n\n========================================\n\nCode:\n```text\nimport importlib\nimport pkgutil\nfrom pathlib import Path\n\nimport uvicorn\nfrom fastapi import FastAPI\n\nPLUGINS_PATH = Path(__file__).parent.joinpath(\"plugins\")\napp = FastAPI()\n\n\ndef import_module(module_name):\n \"\"\"Imports a module by it's name from plugins folder.\"\"\"\n module = f\"plugins.{module_name}\"\n return importlib.import_module(module, \".\")\n\n\ndef load_plugins() -> list:\n \"\"\"Import plugins from plugins folder.\"\"\"\n loaded_apps = []\n for _, application, _ in pkgutil.iter_modules([str(PLUGINS_PATH)]):\n module = import_module(application)\n print(\n f\"Loaded app: {module.__meta__['plugin_name']} -- version: {module.__meta__['version']}\"\n )\n loaded_apps.append(module)\n return loaded_apps\n\n\n@app.get(\"/\")\ndef main():\n return \"Hello World!\"\n\n\nif __name__ == \"__main__\":\n plugins = load_plugins()\n\n for plugin in plugins:\n \"\"\"Register the plugins router.\"\"\"\n if \"router\" in plugin.__dir__():\n app_router = plugin.router\n app.include_router(app_router)\n\n uvicorn.run(\"server:app\", host=\"localhost\", port=8000, reload=True)\n```\n\n```text\n__meta__ = {\"plugin_name\": \"NON API plugin\", \"version\": \"0.0.1\"}\n```\n\n```text\nfrom .routes import routes as router\n\n__meta__ = {\"plugin_name\": \"API <v1|v2>\", \"version\": \"0.0.1\"}\n```\n\n```text\nfrom fastapi import APIRouter\n\nroutes = APIRouter(prefix=\"/<v1|v2>\")\n\n\n@routes.get(\"/\")\ndef novels():\n return \"Hello World from <v1|v2>\"\n```\n\n```text\nplugins/non_api_plugin/__init__.py\n```\n\n```text\nplugins/<v1|v2>/__init__.py\n```\n\n```py\nif __name__ == \"__main__\":\n # plugin registration\n```\n\n```py\nplugins = load_plugins()\n\nfor plugin in plugins:\n \"\"\"Register the plugins router.\"\"\"\n if \"router\" in plugin.__dir__():\n app_router = plugin.router\n app.include_router(app_router, prefix='/foo') # I'd let the plugin name be the prefix here to avoid plugins using the same prefix\n\nif __name__ == \"__main__\":\n uvicorn.run(\"server:app\", host=\"localhost\", port=8000, reload=True)\n```\n\n```text\nuvicorn\n```\n\n```text\n__name__ == \"__main__\"\n```\n\n========================================\n\nComments:\n- What does \"doesn't work as expected\" mean?\n- @MatsLindh, the API endpoints are not added to the system, I edit the question for better understanding\n- Have you checked what the docs say about registered endpoints (`/docs`)? It seems like you're using the prefix both in your `include_router` and where you're calling the api router constructor?\n- @MatsLindh, yes that's what I'm doing to check the endpoint, the `/docs` only shows the default endpoint added with `main` function, using the prefix in the constructor was just to try something, but I can remove it and have the same result\n- I update the server code to avoid redefinition of the prefix,\n- So, as I understand I nees to have all routes loaded for all context not only in the `__main__` ??\n- `uvicorn` loads and launches the module you give it - loading it being the central part. If you wrap the plugin loading functionality inside a check to determine whether the script is being loaded directly by `python`, the plugin functionality will *not* run when uvicorn launches your asgi application - effectively not registrering your plugins.","metadata":{"transformedAt":"2026-08-18T18:32:29.144Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":10,"totalLines":203,"estimatedTokens":1327}}570{"id":"stack-68371974","source":"stackoverflow","questionId":68371974,"title":"How to deal with 'await' outside async function?","tags":["python","async-await","fastapi"],"text":"Title: How to deal with 'await' outside async function?\nTags: python, async-await, fastapi\nSource: Stack Overflow\n\nQuestion:\nThe below function is calling the create_presigned_url but I am getting an error in await.\n\n```\ndef getPreSignedURL(request: Request, file: UploadFile = File(...) ):\n resp = await create_presigned_url(request,file)\n return resp\n```\n\nthis is an async function which I want to call\n\n```\nasync def create_presigned_url(bucket_name, object_name, expiration=3600):\n---\nreturn response\n```\n\n========================================\n\nCode:\n```text\ndef getPreSignedURL(request: Request, file: UploadFile = File(...) ):\n resp = await create_presigned_url(request,file)\n return resp\n```\n\n```text\nasync def create_presigned_url(bucket_name, object_name, expiration=3600):\n---\nreturn response\n```\n\n```text\nimport asyncio\n\nloop = asyncio.get_event_loop()\n\n\nasync def demo(name):\n return f\"hello {name}\"\n\n\ndef main():\n result = loop.run_until_complete(demo(\"world\"))\n print(result)\n\n\nif __name__ == '__main__':\n main()\n```\n\n========================================\n\nComments:\n- Please provide the error.\n- you can not call an async method from a sync method. for more info stackoverflow.com/questions/55647753/…","metadata":{"transformedAt":"2026-08-18T18:32:29.144Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":3,"totalLines":60,"estimatedTokens":314}}571{"id":"stack-79556268","source":"stackoverflow","questionId":79556268,"title":"MCP Python SDK. How to authorise a client with Bearer header with SSE?","tags":["python","fastapi","large-language-model"],"text":"Title: MCP Python SDK. How to authorise a client with Bearer header with SSE?\nTags: python, fastapi, large-language-model\nSource: Stack Overflow\n\nQuestion:\nI am building the MCP server application to connect some services to LLM . I use the MCP Python SDK https://github.com/modelcontextprotocol/python-sdk\nOne of things i want to implement is authorisation of a user with the token.\n\nhttps://i.sstatic.net/CU2VUUer.png\n\nI see it must be possible somehow.\n\nMost of tutorials about MCP are related to STDIO kind of a server run. My will be SSE.\n\nThere is my code:\n\n```\nfrom mcp.server.fastmcp import FastMCP\nfrom fastapi import FastAPI, Request, Depends, HTTPException\n\napp = FastAPI()\nmcp = FastMCP(\"SMB Server\")\n\n@mcp.tool()\ndef create_folder(parent_path: str, name: str) -> str:\n \"\"\"Create new subfolder in the specified path\"\"\"\n return f\"Folder {name} created in {parent_path}\"\n\napp.mount(\"/\", mcp.sse_app())\n```\n\nHow can i read Authorization header in case if it is sent by the client?\n\nI tried to use approaches of FastAPI - setting dependency, adding request:Request to arguments but this doesn't work.\n\nIs there a way?\n\n========================================\n\nCode:\n```text\nfrom mcp.server.fastmcp import FastMCP\nfrom fastapi import FastAPI, Request, Depends, HTTPException\n\napp = FastAPI()\nmcp = FastMCP(\"SMB Share Server\")\n\n@mcp.tool()\ndef create_folder(parent_path: str, name: str) -> str:\n \"\"\"Create new subfolder in the specified path\"\"\"\n return f\"Folder {name} created in {parent_path}\"\n\napp.mount(\"/\", mcp.sse_app())\n```\n\n```text\nfrom mcp.server.fastmcp import FastMCP\nfrom fastapi import FastAPI, Request\nimport subprocess\nimport shlex\n\n# Global variable to keep a token a for a request\nauth_token = \"\"\n\napp = FastAPI()\nmcp = FastMCP(\"Server to manage a Linux instance\")\n\n@app.middleware(\"http\")\nasync def auth_middleware(request: Request, call_next):\n auth_header = request.headers.get(\"Authorization\")\n if auth_header:\n # extract token from the header and keep it in the global variable\n global auth_token\n auth_token = auth_header.split(\" \")[1]\n \n response = await call_next(request)\n \n return response\n\ndef require_auth():\n \"\"\"\n Check access and raise an error if the token is not valid.\n \"\"\"\n\n if auth_token != \"expected-token\":\n raise ValueError(\"Invalid token\")\n return None\n\ndef run_cli(command: str, cwd: str = None) -> str:\n \"\"\"\n Execute a CLI command using subprocess.\"\"\"\n\n if cwd == \"\":\n cwd = None\n\n command_list = shlex.split(command)\n \n run_result = subprocess.run(\n command_list,\n cwd=cwd,\n capture_output=True,\n text=True,\n check=False,\n )\n success = run_result.returncode == 0\n return f\"STDOUT: {run_result.stdout}\\n\\nSTDERR: {run_result.stderr}\\nRETURNCODE: {run_result.returncode}\\nSUCCESS: {success}\"\n\n@mcp.tool()\ndef cli_command(command: str, work_dir: str | None = \"\") -> str:\n \"\"\"\n Execute command line cli command on the Linux server. \n \n Arguments:\n command - command to execute.\n work_dir - workdir will be changed to this path before executing the command.\n \"\"\"\n require_auth() # we have to add this inside each tool method\n return run_cli(command, work_dir)\n\napp.mount(\"/\", mcp.sse_app())\n```\n\n========================================\n\nComments:\n- This does not seem to be available at the moment. There are PRs open and it is asked for at multiple occasions not just for Python: github.com/modelcontextprotocol/python-sdk/pull/380\n- It is possible. I have found theb solution and described in my blog post here gelembjuk.hashnode.dev/…\n- @RomanGelembjuk The link you shared proposes an thread UNSAFE solution using globals\n- What happens when there are more than two users accessing the server at the same time?\n- Nothing special, it will just work. There can be as many users as Fastapi can handle.\n- Interesting. In my environment this does not work. Here is a simple example: ``` var = \"\" @app.get(\"/\") async def home(): global var var = str(uuid4()) before = var await asyncio.sleep(random.randint(1, 3)) after = var result = f\"check:{'ok' if before == after else 'not equal'}\" print(result) return {\"message\": result} ``` When you run it with ` ab -n 100 -c 100 127.0.0.1:8000` you should see eventually a `check:not equal` in the logs\n- TL;DR: Don’t store session tokens in globals — they’re not thread-safe. Instead, use a pool or thread-local storage to avoid locking and improve concurrency.\n- Or, better yet, let's stick with the MCP specs and use OAuth. FastMCP seems to be working on it. It did not appear working yet, however there is a VERY sparse document you can check out: gofastmcp.com/servers/fastmcp#authentication\n- Also, the fastapi_mcp project has a somewhat working authentication: github.com/tadata-org/fastapi_mcp However, it only supports converting FastAPI endpoints into MCP endpoints (which may be all you need)\n- You are right. THis solution is not thread safe. Some extra tricks are needed. However, i expect \"normal\" solution will be available soon. SDKs are progressing. I hope the will have a normal way to read input headers and most probably fastapi will not be needed at all\n- can we add a middleware which captures headers on mcp app, instead of fastapi app ? What exactly is the need of fastapi app ?\n- That's awesome. Does anybody know an equivalent for Java SDK ?\n- It is possible to build much better solution using FastMCP SDK. Details are in my blog post gelembjuk.com/blog/post/authentication-remote-mcp-server-pyt‌​hon","metadata":{"transformedAt":"2026-08-18T18:32:29.144Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":2,"totalLines":138,"estimatedTokens":1416}}572{"id":"stack-65408109","source":"stackoverflow","questionId":65408109,"title":"How do I receive image and json data in FastAPI?","tags":["python","fastapi"],"text":"Title: How do I receive image and json data in FastAPI?\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am sending and image and also json data to my API in the following way:\n\n```\nimport requests\nfilename = \"test_image.jpeg\"\nfiles = {'my_file': (filename, open(filename, 'rb'))}\njson={'first': \"Hello\", 'second': \"World\"}\n\nresponse = requests.post('http://127.0.0.1:8000/file', files=files, params=json)\n```\n\nHow do I receive both the image and json data on the server-side via FastAPI?\n\nMy code looks like this:\n\n```\n@app.post('/file')\ndef _file_upload(my_file: UploadFile = File(...), params: str = Form(...)):\n\n image_bytes = my_file.file.read()\n decoded = cv2.imdecode(np.frombuffer(image_bytes, np.uint8), -1)\n pg_image = cv2.resize(decoded, (220, 220))\n return {\"file_size\": params}\n```\n\nHowever, this gives me the following error:\n\n```\n\n{'detail': [{'loc': ['body', 'params'], 'msg': 'field required', 'type': 'value_error.missing'}]}\n```\n\nIs there something which I am doing wrong here?\n\n========================================\n\nTop Answer:\nI came across your question when I encountered this same issue. I was looking for a way I could make my endpoint accept a JSON body and a file (image). The answer is you can't.\n\nThis is because they both require different content-type and I don't think there is a way to set 2 content-type when making a request.\n\nI noticed this when I opened the documentation. The content-type set to allow images is the reason the JSON is not accepted. That is the reason your program throws the error saying those fields are missing.\n\nHowever, you can use a form to take in all the parameters you required in the JSON body as suggested by other comments. It should work fine as the values can still be accepted.\n\nBut for me, I opted to use an endpoint to accept the JSON without the image and give the object a default image. Then I created another endpoint to update the image.\n\n========================================\n\nCode:\n```text\nimport requests\nfilename = \"test_image.jpeg\"\nfiles = {'my_file': (filename, open(filename, 'rb'))}\njson={'first': \"Hello\", 'second': \"World\"}\n\nresponse = requests.post('http://127.0.0.1:8000/file', files=files, params=json)\n```\n\n```text\n@app.post('/file')\ndef _file_upload(my_file: UploadFile = File(...), params: str = Form(...)):\n\n image_bytes = my_file.file.read()\n decoded = cv2.imdecode(np.frombuffer(image_bytes, np.uint8), -1)\n pg_image = cv2.resize(decoded, (220, 220))\n return {\"file_size\": params}\n```\n\n```text\n<Response [422]>\n{'detail': [{'loc': ['body', 'params'], 'msg': 'field required', 'type': 'value_error.missing'}]}\n```\n\n```text\n# app.py\nfrom fastapi import FastAPI, File, UploadFile, Form\n\napp = FastAPI()\n\n\n@app.post('/file')\ndef _file_upload(\n my_file: UploadFile = File(...),\n first: str = Form(...),\n second: str = Form(\"default value for second\"),\n):\n return {\n \"name\": my_file.filename,\n \"first\": first,\n \"second\": second\n }\n```\n\n```text\n# client.py\nimport requests\n\nfilename = \"requirements.txt\"\nfiles = {'my_file': (filename, open(filename, 'rb'))}\njson = {'first': \"Hello\", 'second': \"World\"}\n\nresponse = requests.post(\n 'http://127.0.0.1:8000/file',\n files=files,\n data={'first': \"Hello\", 'second': \"World\"}\n)\nprint(response.json())\n```\n\n```py\n@app.post('/file')\ndef my_function(param1: str, param2: str):\n ...\n```\n\n```py\n{\"param1\": \"some string\", \"param2\": \"some_string\"}\n```\n\n```py\n{'first': \"Hello\", 'second': \"World\"}\n```\n\n```py\n@app.post(\"/dummy\")\ndef my_function(first: str = Body(...), second: str = Body(...)):\n ...\n```\n\n```py\n@app.post('/file')\ndef my_function(param1: str = Body(...), param2: str = Body(...)):\n ...\n```\n\n```text\n/file\n```\n\n```text\nmy_file\n```\n\n```text\nparams\n```\n\n```text\n{'first': \"Hello\", 'second': \"World\"}\n```\n\n```text\nparams\n```\n\n========================================\n\nComments:\n- i tried a similar thing with the base model, it works independently without a file and when i add a file, fastapi is not able to parse. class Data(BaseModel): first: str second: str async def temp_fn( data:Data,my_file: UploadFile = File(...))\n- I am not sure what is the issue in your case, ask a new question with a *minimal reproducible example*","metadata":{"transformedAt":"2026-08-18T18:32:29.144Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":15,"totalLines":166,"estimatedTokens":1065}}573{"id":"stack-66226692","source":"stackoverflow","questionId":66226692,"title":"mocking environment variables during testing","tags":["python","mocking","pytest","fastapi","pytest-mock"],"text":"Title: mocking environment variables during testing\nTags: python, mocking, pytest, fastapi, pytest-mock\nSource: Stack Overflow\n\nQuestion:\nI have a very simple fastapi application which i want to test , the code for `dummy_api.py` is as follows :\n\n```\nimport os\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(os.getenv(\"ENDPOINT\", \"/get\"))\ndef func():\n return {\n \"message\": \"Endpoint working !!!\"\n }\n```\n\nWhen i want to test this i am using the below file :\n\n```\nfrom fastapi.testclient import TestClient\nimport dummy_api\n\ndef test_dummy_api():\n client = TestClient(dummy_api.app)\n response = client.get(\"/get\")\n assert response.status_code == 200\n\ndef test_dummy_api_with_envar(monkeypatch):\n monkeypatch.setenv(\"ENDPOINT\", \"dummy\")\n client = TestClient(dummy_api.app)\n response = client.get(\"/dummy\")\n assert response.status_code == 200\n```\n\nHowever i am unable to mock the environment variable part as one of the tests fail with a `404`.\n\n```\npytest -s -v\n================================================================= test session starts ==================================================================\nplatform linux -- Python 3.8.5, pytest-6.2.2, py-1.9.0, pluggy-0.13.1 -- /home/subhayan/anaconda3/envs/fastapi/bin/python\ncachedir: .pytest_cache\nrootdir: /home/subhayan/Codes/ai4bd/roughdir\ncollected 2 items \n\ntest_dummy_api.py::test_dummy_api PASSED\ntest_dummy_api.py::test_dummy_api_with_envar FAILED\n\n======================================================================= FAILURES =======================================================================\n______________________________________________________________ test_dummy_api_with_envar _______________________________________________________________\n\nmonkeypatch = \n\n def test_dummy_api_with_envar(monkeypatch):\n monkeypatch.setenv(\"ENDPOINT\", \"dummy\")\n client = TestClient(dummy_api.app)\n response = client.get(\"/dummy\")\n> assert response.status_code == 200\nE assert 404 == 200\nE +404\nE -200\n\ntest_dummy_api.py:15: AssertionError\n=============================================================== short test summary info ================================================================\nFAILED test_dummy_api.py::test_dummy_api_with_envar - assert 404 == 200\n============================================================= 1 failed, 1 passed in 0.19s ==============================================================\n```\n\nCan anyone point out where am i going wrong please !!\n\n========================================\n\nTop Answer:\nThis is an approach I've taken - simply don't import app until after the env is set up.\n\n```\n@pytest.fixture\ndef client():\n os.environ['DB_URL'] = 'http://foobar:1111'\n\n from main import app # Import only after env created\n yield TestClient(app)\n\ndef test_health_endpoint(client):\n response = client.get(\"/health\")\n assert response.status_code == 200\n```\n\n========================================\n\nCode:\n```text\nimport os\nfrom fastapi import FastAPI\n\n\napp = FastAPI()\n\n\n@app.get(os.getenv(\"ENDPOINT\", \"/get\"))\ndef func():\n return {\n \"message\": \"Endpoint working !!!\"\n }\n```\n\n```text\nfrom fastapi.testclient import TestClient\nimport dummy_api\n\n\ndef test_dummy_api():\n client = TestClient(dummy_api.app)\n response = client.get(\"/get\")\n assert response.status_code == 200\n\n\ndef test_dummy_api_with_envar(monkeypatch):\n monkeypatch.setenv(\"ENDPOINT\", \"dummy\")\n client = TestClient(dummy_api.app)\n response = client.get(\"/dummy\")\n assert response.status_code == 200\n```\n\n```text\npytest -s -v\n================================================================= test session starts ==================================================================\nplatform linux -- Python 3.8.5, pytest-6.2.2, py-1.9.0, pluggy-0.13.1 -- /home/subhayan/anaconda3/envs/fastapi/bin/python\ncachedir: .pytest_cache\nrootdir: /home/subhayan/Codes/ai4bd/roughdir\ncollected 2 items \n\ntest_dummy_api.py::test_dummy_api PASSED\ntest_dummy_api.py::test_dummy_api_with_envar FAILED\n\n======================================================================= FAILURES =======================================================================\n______________________________________________________________ test_dummy_api_with_envar _______________________________________________________________\n\nmonkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7ff8c4cf1430>\n\n def test_dummy_api_with_envar(monkeypatch):\n monkeypatch.setenv(\"ENDPOINT\", \"dummy\")\n client = TestClient(dummy_api.app)\n response = client.get(\"/dummy\")\n> assert response.status_code == 200\nE assert 404 == 200\nE +404\nE -200\n\ntest_dummy_api.py:15: AssertionError\n=============================================================== short test summary info ================================================================\nFAILED test_dummy_api.py::test_dummy_api_with_envar - assert 404 == 200\n============================================================= 1 failed, 1 passed in 0.19s ==============================================================\n```\n\n```text\ndummy_api.py\n```\n\n```text\n404\n```\n\n```text\n.\n└── tests\n ├── conftest.py\n ├── dummy_api.py\n └── test_api.py\n```\n\n```py\nimport pytest\nfrom fastapi.testclient import TestClient\nfrom importlib import reload\nimport dummy_api\n\n\n@pytest.fixture(params=[\"/get\", \"/dummy\", \"/other\"])\ndef endpoint(request, monkeypatch):\n monkeypatch.setenv(\"ENDPOINT\", request.param)\n return request.param\n\n\n@pytest.fixture()\ndef client(endpoint):\n app = reload(dummy_api).app\n yield TestClient(app=app)\n```\n\n```py\nimport os\n\n\ndef test_dummy_api(client):\n endpoint = os.environ[\"ENDPOINT\"]\n response = client.get(endpoint)\n assert response.status_code == 200\n assert response.json() == {\"message\": f\"Endpoint {endpoint} working !\"}\n```\n\n```text\ncollected 3 items \n\ntests/test_api.py::test_dummy_api[/get] PASSED [ 33%]\ntests/test_api.py::test_dummy_api[/dummy] PASSED [ 66%]\ntests/test_api.py::test_dummy_api[/other] PASSED [100%]\n```\n\n```text\nimportlib.reload\n```\n\n```text\nconftest.py\n```\n\n```text\ntest_api.py\n```\n\n```text\npytest\n```\n\n```text\n@pytest.fixture\ndef client():\n os.environ['DB_URL'] = 'http://foobar:1111'\n\n from main import app # Import only after env created\n yield TestClient(app)\n\ndef test_health_endpoint(client):\n response = client.get(\"/health\")\n assert response.status_code == 200\n```\n\n========================================\n\nComments:\n- Any ideas how to change it ?","metadata":{"transformedAt":"2026-08-18T18:32:29.144Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":14,"totalLines":245,"estimatedTokens":1760}}574{"id":"stack-69801799","source":"stackoverflow","questionId":69801799,"title":"Why does a yielded SQLAlchemy Session in a FastAPI dependency close once it goes out of scope?","tags":["python","sqlalchemy","fastapi"],"text":"Title: Why does a yielded SQLAlchemy Session in a FastAPI dependency close once it goes out of scope?\nTags: python, sqlalchemy, fastapi\nSource: Stack Overflow\n\nQuestion:\nIn the FastAPI docs it is recommended to set up a SQLAlchemy database session dependency using a generator function like so:\n\n```\nasync def get_db():\n db = DBSession()\n try:\n yield db\n finally:\n db.close()\n```\n\nMy question is why does the finally block ever get executed? I was under the impression that generator functions pause execution at each yield. Once the session object goes out of scope, shouldn't the execution of `get_db` be discarded with `db.close()` never having run?\n\n========================================\n\nTop Answer:\ndevaerial posted a good answer about how `next()` is called during the enter and exit magic methods of the context manager that is implemented by FastAPI generator dependencies. However, there is another more general reason the `finally` block would execute that I wanted to post here.\n\nI found this answer about generators more broadly. Say we have a generator function...\n\n```\ndef gen():\n yield 1\n print(\"test\")\n```\n\nMy output will be like so:\n\n```\n>>> print(next(gen()))\n1\n```\n\nHowever, if I modify my function using `try...finally`\n\n```\ndef gen():\n try:\n yield 1\n finally:\n print(\"test\")\n```\n\nI will get this output:\n\n```\n>>> print(next(gen()))\ntest\n1\n```\n\nThe `finally` block is guaranteed to be executed before garbage collection once the generator is destroyed.\n\n========================================\n\nCode:\n```py\nasync def get_db():\n db = DBSession()\n try:\n yield db\n finally:\n db.close()\n```\n\n```text\nget_db\n```\n\n```text\ndb.close()\n```\n\n```text\n[0] c:\\users\\homeuser\\.pyenv\\pyenv-win\\versions\\3.7.9\\lib\\threading.py(890)_bootstrap()\n-> self._bootstrap_inner()\n[1] c:\\users\\homeuser\\.pyenv\\pyenv-win\\versions\\3.7.9\\lib\\threading.py(926)_bootstrap_inner()\n-> self.run()\n[2] c:\\users\\homeuser\\.pyenv\\pyenv-win\\versions\\3.7.9\\lib\\threading.py(870)run()\n-> self._target(*self._args, **self._kwargs)\n[3] c:\\users\\homeuser\\.pyenv\\pyenv-win\\versions\\3.7.9\\lib\\concurrent\\futures\\thread.py(80)_worker()\n-> work_item.run()\n[4] c:\\users\\homeuser\\.pyenv\\pyenv-win\\versions\\3.7.9\\lib\\concurrent\\futures\\thread.py(57)run()\n-> result = self.fn(*self.args, **self.kwargs)\n[5] c:\\users\\homeuser\\.pyenv\\pyenv-win\\versions\\3.7.9\\lib\\contextlib.py(112)__enter__()\n-> return next(self.gen)\n```\n\n```text\n[0] c:\\users\\homeuser\\.pyenv\\pyenv-win\\versions\\3.7.9\\lib\\threading.py(890)_bootstrap()\n-> self._bootstrap_inner()\n[1] c:\\users\\homeuser\\.pyenv\\pyenv-win\\versions\\3.7.9\\lib\\threading.py(926)_bootstrap_inner()\n-> self.run()\n[2] c:\\users\\homeuser\\.pyenv\\pyenv-win\\versions\\3.7.9\\lib\\threading.py(870)run()\n-> self._target(*self._args, **self._kwargs)\n[3] c:\\users\\homeuser\\.pyenv\\pyenv-win\\versions\\3.7.9\\lib\\concurrent\\futures\\thread.py(80)_worker()\n-> work_item.run()\n[4] c:\\users\\homeuser\\.pyenv\\pyenv-win\\versions\\3.7.9\\lib\\concurrent\\futures\\thread.py(57)run()\n-> result = self.fn(*self.args, **self.kwargs)\n[5] c:\\users\\homeuser\\.pyenv\\pyenv-win\\versions\\3.7.9\\lib\\contextlib.py(119)__exit__()\n-> next(self.gen)\n```\n\n```text\nbreakpoint()\n```\n\n```text\ntry\n```\n\n```text\nw\n```\n\n```text\nnext()\n```\n\n```text\ncontextlib\n```\n\n```text\nnext()\n```\n\n```text\n__enter__\n```\n\n```text\nwith\n```\n\n```text\nyield\n```\n\n```text\nfinally\n```\n\n```text\nw\n```\n\n```text\nnext()\n```\n\n```text\nnext()\n```\n\n```text\n__enter__\n```\n\n```text\nnext()\n```\n\n```text\nfinally\n```\n\n```text\n@contextmanager\n```\n\n```text\nDepends\n```\n\n```py\ndef gen():\n yield 1\n print(\"test\")\n```\n\n```py\n>>> print(next(gen()))\n1\n```\n\n```py\ndef gen():\n try:\n yield 1\n finally:\n print(\"test\")\n```\n\n```py\n>>> print(next(gen()))\ntest\n1\n```\n\n```text\nnext()\n```\n\n```text\nfinally\n```\n\n```text\ntry...finally\n```\n\n```text\nfinally\n```\n\n========================================\n\nComments:\n- I appreciate the answer. I figured there was something going on under the hood with FastAPI dependencies that isn't obvious. I assume they have some kind of custom context manager implementation that runs `next()` on enter and exit. I think there is also another reason why `finally` would get run, more general to generators. I'm going to post my own answer for that.","metadata":{"transformedAt":"2026-08-18T18:32:29.144Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":31,"totalLines":225,"estimatedTokens":1066}}575{"id":"stack-64601521","source":"stackoverflow","questionId":64601521,"title":"Change Pydantic's inherited BaseModel's attribute precedence in JSON schema","tags":["json","python-3.x","fastapi","pydantic"],"text":"Title: Change Pydantic's inherited BaseModel's attribute precedence in JSON schema\nTags: json, python-3.x, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI'm using `pydantic 1.6.1` and `fastapi 0.61.1` with Python 3.8.3. Here's how I've tried defining the models:\n\n```\nclass UserBase(BaseModel):\n name: str\n\nclass UserCreate(UserBase):\n password: str\n\nclass UserInfo(UserBase):\n id: str\n group: Optional[GroupInfo] = None\n```\n\nThe issue I'm having with this setup is that the schema is built such that the `name` attribute is on top of the remaining attributes like so - in this case, while using `UserInfo` as the endpoint's `response_model`:\n\n```\n[\n {\n \"name\": \"string\",\n \"id\": \"string\",\n \"group\": {\n \"name\": \"string\"\n }\n }\n]\n```\n\nYet I'd like to be able to set them up like this:\n\n```\n[\n {\n \"id\": \"string\",\n \"name\": \"string\",\n \"group\": {\n \"name\": \"string\"\n }\n }\n]\n```\n\nIs there a way I can manually set a custom order for the attributes in the JSON response's schema?\n\n========================================\n\nCode:\n```text\nclass UserBase(BaseModel):\n name: str\n\nclass UserCreate(UserBase):\n password: str\n\nclass UserInfo(UserBase):\n id: str\n group: Optional[GroupInfo] = None\n```\n\n```text\n[\n {\n \"name\": \"string\",\n \"id\": \"string\",\n \"group\": {\n \"name\": \"string\"\n }\n }\n]\n```\n\n```text\n[\n {\n \"id\": \"string\",\n \"name\": \"string\",\n \"group\": {\n \"name\": \"string\"\n }\n }\n]\n```\n\n```text\npydantic 1.6.1\n```\n\n```text\nfastapi 0.61.1\n```\n\n```text\nname\n```\n\n```text\nUserInfo\n```\n\n```text\nresponse_model\n```\n\n```text\nclass UserID(BaseModel):\n id: str\n\n\nclass UserInfo(UserBase, UserID): # `UserID` should be second\n group: Optional[GroupInfo] = None\n```\n\n```text\n{\n \"id\": \"string\",\n \"name\": \"string\",\n \"group\": {\n \"name\": \"string\"\n }\n}\n```\n\n```text\nclass UserBase(BaseModel):\n name: str\n\n\nclass UserCreate(UserBase):\n password: str\n\n\nclass UserInfo(UserBase):\n id: str\n group: Optional[GroupInfo] = None\n\n\nfields = UserInfo.__fields__.copy()\nUserInfo.__fields__ = {\"id\": fields.pop(\"id\"), **fields}\n```\n\n```text\nid\n```\n\n```text\nUserInfo\n```\n\n```text\n.__fields__\n```\n\n========================================\n\nComments:\n- Does the order really matter? 😳 *\"An object is an unordered set of name/value pairs.\"* (Source json.org)\n- @ArakkalAbu In the grand scheme of things, not really. Still, I'd rather have this option available for presentation purposes.","metadata":{"transformedAt":"2026-08-18T18:32:29.144Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":14,"totalLines":162,"estimatedTokens":605}}576{"id":"stack-62965442","source":"stackoverflow","questionId":62965442,"title":"FastAPI says missing folder name as module","tags":["python","pymongo","fastapi"],"text":"Title: FastAPI says missing folder name as module\nTags: python, pymongo, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have a question related to FastAPI with uvicorn in pycharm. My project is having following structure:\n\n```\nLearningPy \n | \n |-- apis \n -----|--modelservice \n ---------|--dataprovider.py \n ---------|--main.py \n ---------|--persondetails.py \n -----|--config.py\n```\n\nFirst I was using following path : **D:\\Learnings\\apis** and ran following code : uvicorn main:app --reload\nthen it was giving error :\n\n```\nUvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)\nStarted reloader process [23445]\nError loading ASGI app. Could not import module \"apis\".\n```\n\nHowever, after reading suggestion from here, I have changed the path to **D:\\Learnings\\apis\\modeservice** and above error gone but now it started throwing a different error :\n**ModuleNotFoundError: No module named 'apis'**\n\nHere are my main.py and config.py code files :\n\nmain.py --\n\n```\nimport uvicorn\nfrom fastapi import FastAPI\nfrom starlette.middleware.cors import CORSMiddleware\nfrom datetime import datetime\n\nfrom apis import config\nfrom apis.modelservice import dataprovider\n\napp = FastAPI(debug=True)\ndef get_application() -> FastAPI:\n application = FastAPI(title=\"PersonProfile\", description=\"Learning Python CRUD\",version=\"0.1.0\")\n origins = [\n config.API_CONFIG[\"origin_local_ip\"],\n config.API_CONFIG[\"origin_local_url\"]\n ]\n application.add_middleware(\n CORSMiddleware,\n allow_origins=origins,\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n )\n #application.include_router(processA.router)\n return application\n\napp = get_application()\n\n@app.get(\"/\")\ndef read_root():\n return {\"main\": \"API Server \" + datetime.now().strftime(\"%Y%m%d %H:%M:%S\")}\n\n@app.get(\"/dbcheck\")\ndef read_root():\n try:\n dataprovider.get_db().get_collection(\"Person\")\n except Exception as e:\n return {\"failed\":e}\n else:\n return { \"connected\":True}\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", port=8000, reload=True)\n```\n\nAnd here is config.py--\n\n```\nAPI_CONFIG = {\n \"origin_local_ip\": \"http://127.0.0.1:3000\",\n \"origin_local_url\": \"http://localhost:3000\"\n}\n```\n\nThis project is being built on React+Mongo+python (pymongo for connecting mongodb).\n\nThanks in advance.\n\n========================================\n\nTop Answer:\nAdded to what Yagizcan answered above, if anyone still getting module import error in pycharm then change the sources root to the code folder from File menu.\n\n```\nLearningPy \n | \n |-- apis \n -----|--modelservice \n ---------|--dataprovider.py \n ---------|--persondetails.py \n------|--main.py \n------|--config.py\n```\n\nHere I have moved the main.py outside of modelservice folder. since main.py will be running as api. Then, to run the code I have added following code\n`uvicorn path to apisfolder.main:app --reload`. And now it ran without any problem.\n\n========================================\n\nCode:\n```text\nLearningPy <folder name> \n | \n |-- apis <folder name> \n -----|--modelservice <folder name> \n ---------|--dataprovider.py \n ---------|--main.py \n ---------|--persondetails.py \n -----|--config.py\n```\n\n```text\nUvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)\nStarted reloader process [23445]\nError loading ASGI app. Could not import module \"apis\".\n```\n\n```text\nimport uvicorn\nfrom fastapi import FastAPI\nfrom starlette.middleware.cors import CORSMiddleware\nfrom datetime import datetime\n\nfrom apis import config\nfrom apis.modelservice import dataprovider\n\napp = FastAPI(debug=True)\ndef get_application() -> FastAPI:\n application = FastAPI(title=\"PersonProfile\", description=\"Learning Python CRUD\",version=\"0.1.0\")\n origins = [\n config.API_CONFIG[\"origin_local_ip\"],\n config.API_CONFIG[\"origin_local_url\"]\n ]\n application.add_middleware(\n CORSMiddleware,\n allow_origins=origins,\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n )\n #application.include_router(processA.router)\n return application\n\napp = get_application()\n\n@app.get(\"/\")\ndef read_root():\n return {\"main\": \"API Server \" + datetime.now().strftime(\"%Y%m%d %H:%M:%S\")}\n\n@app.get(\"/dbcheck\")\ndef read_root():\n try:\n dataprovider.get_db().get_collection(\"Person\")\n except Exception as e:\n return {\"failed\":e}\n else:\n return { \"connected\":True}\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", port=8000, reload=True)\n```\n\n```text\nAPI_CONFIG = {\n \"origin_local_ip\": \"http://127.0.0.1:3000\",\n \"origin_local_url\": \"http://localhost:3000\"\n}\n```\n\n```text\nprint('__file__={0:<35} | __name__={1:<20} | __package__={2<20}'.format(__file__,__name__,str(__package__)))\nimport apis.config\nimport apis.modelservice.main\n```\n\n```text\napis\n├── config.py\n└── modelservice\n └── main.py\n```\n\n```text\n__file__=main.py | __name__=__main__ | __package__=None \n__file__=/home/yagiz/Desktop/test/apis/config.py | __name__=apis.config | package__=apis \napis.config\n__file__=/home/yagiz/Desktop/test/apis/modelservice/main.py | __name__=apis.modelservice.main | __package__=apis.modelservice\n```\n\n```text\nfrom .. import config\n```\n\n```text\nFile \"./main.py\", line 8, in <module>\n from .. import config\nImportError: attempted relative import with no known parent package\n```\n\n```text\napis/\n├── modelservice\n ├── config.py\n ├── main.py\n\nINFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\nINFO: Started reloader process [14155] using statreload\n__file__=./main.py | __name__=main | __package__= \n__file__=./config.py | __name__=config | __package__= config\nINFO: Started server process [14157]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\n```\n\n```text\nconfig.py\n```\n\n```text\nmodelservice.main.py\n```\n\n```text\nimport config:\n```\n\n```text\nLearningPy <folder name> \n | \n |-- apis <folder name> \n -----|--modelservice <folder name> \n ---------|--dataprovider.py \n ---------|--persondetails.py \n------|--main.py \n------|--config.py\n```\n\n```text\nuvicorn path to apisfolder.main:app --reload\n```\n\n========================================\n\nComments:\n- Are you sure you are in the same directory with `main.py`? check this answer fastapi asgi app couldnt not import module\n- No, the config.py file is outside of main.py folder. and Thanks Yagizcan, I was exactly read your answer. but the error is now coming due to calling module outside outside of modeservice folder. Any suggestions?\n- Try changing directory to `modelservice` and run the `uvicorn main:app --reload` again, if you get an error add in to the question\n- Ya, I did that Yagizcan, as you see I have already added that part in question (find this : I have changed the path to D:\\Learnings\\apis\\modeservice ) and then the error is coming relateds to apis fodler\n- Now I just cut and pasted config file inside modelservice folder and also changed the import namespaces of main.py like this `from modelservice import config` but then it says `No module named modelservice` .\n- you just need `import config`","metadata":{"transformedAt":"2026-08-18T18:32:29.144Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":15,"totalLines":264,"estimatedTokens":1780}}577{"id":"stack-73754664","source":"stackoverflow","questionId":73754664,"title":"How to display a Matplotlib chart with FastAPI/ Nextjs without saving the chart locally?","tags":["python","matplotlib","next.js","charts","fastapi"],"text":"Title: How to display a Matplotlib chart with FastAPI/ Nextjs without saving the chart locally?\nTags: python, matplotlib, next.js, charts, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am using Nextjs frontend and FastAPI backend for a website. I have an input form for an 'ethereum address' on the frontend and using the inputted address, I am generating a matplotlib chart in the backend that displays 'ethereum balance over time'. Now, I am trying to return this chart using FastAPI so I can display it on the frontend. I do not want to save the chart locally.\n\nHere is my relevant code so far:\n\nFrontend/ nexjs file called 'Chart.tsx'. 'ethAddress' in the body is capturing data inputted in the input form.\n\n```\nfetch(\"http://localhost:8000/image\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(ethAddress),\n }).then(fetchEthAddresses);\n```\n\nBackend python file that generates matplotlib chart called ethBalanceTracker.py\n\n```\n#Imports\n#Logic for chart here\n\n plt.plot(times, balances)\n buf = BytesIO()\n plt.savefig(buf, format=\"png\")\n buf.seek(0)\n\n return StreamingResponse(buf, media_type=\"image/png\")\n```\n\nBackend python file using FastAPI called api.py\n\n```\n@app.get(\"/image\")\nasync def get_images() -> dict:\n return {\"data\": images}\n\n@app.post(\"/image\")\nasync def add_image(ethAddress: dict) -> dict:\n\n test = EthBalanceTracker.get_transactions(ethAddress[\"ethAddress\"])\n images.append(test)\n```\n\nI have tried the above code and a few other variants. I am using `StreamingResponse` because I do not want to save the chart locally. My issue is I cannot get the chart to display in `localhost:8000/images` and am getting an `'Internal Server Error'`.\n\n========================================\n\nTop Answer:\nThe answer by Chris works quite well (thank you!) but I found in my own work that adding an `async` can be important. Without an `async`, the buffers were being cut short when multiple requests were entering the FastAPI server. The solution was to allow asynchronous processing. Modifying Chris's answer:\n\n```\nimport io\nimport matplotlib\nmatplotlib.use('AGG')\nimport matplotlib.pyplot as plt\nfrom fastapi import FastAPI, Response, BackgroundTasks\n\napp = FastAPI()\n\ndef create_img():\n plt.rcParams['figure.figsize'] = [7.50, 3.50]\n plt.rcParams['figure.autolayout'] = True\n plt.plot([1, 2])\n img_buf = io.BytesIO()\n plt.savefig(img_buf, format='png')\n plt.close()\n return img_buf\n \n@app.get('/')\nasync def get_img(background_tasks: BackgroundTasks):\n img_buf = create_img()\n # get the entire buffer content\n # because of the async, this will await the loading of all content\n bufContents: bytes = img_buf.getvalue()\n background_tasks.add_task(img_buf.close)\n headers = {'Content-Disposition': 'inline; filename=\"out.png\"'}\n return Response(bufContents, headers=headers, media_type='image/png')\n```\n\n========================================\n\nCode:\n```text\nfetch(\"http://localhost:8000/image\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(ethAddress),\n }).then(fetchEthAddresses);\n```\n\n```text\n#Imports\n#Logic for chart here\n\n plt.plot(times, balances)\n buf = BytesIO()\n plt.savefig(buf, format=\"png\")\n buf.seek(0)\n\n return StreamingResponse(buf, media_type=\"image/png\")\n```\n\n```text\n@app.get(\"/image\")\nasync def get_images() -> dict:\n return {\"data\": images}\n\n@app.post(\"/image\")\nasync def add_image(ethAddress: dict) -> dict:\n\n test = EthBalanceTracker.get_transactions(ethAddress[\"ethAddress\"])\n images.append(test)\n```\n\n```text\nStreamingResponse\n```\n\n```text\nlocalhost:8000/images\n```\n\n```text\n'Internal Server Error'\n```\n\n```py\nimport io\nimport matplotlib\nmatplotlib.use('AGG')\nimport matplotlib.pyplot as plt\nfrom fastapi import FastAPI, Response, BackgroundTasks\n\napp = FastAPI()\n\ndef create_img():\n plt.rcParams['figure.figsize'] = [7.50, 3.50]\n plt.rcParams['figure.autolayout'] = True\n fig = plt.figure() # make sure to call this, in order to create a new figure\n plt.plot([1, 2])\n img_buf = io.BytesIO()\n plt.savefig(img_buf, format='png')\n plt.close(fig)\n return img_buf\n \n@app.get('/')\ndef get_img(background_tasks: BackgroundTasks):\n img_buf = create_img()\n background_tasks.add_task(img_buf.close)\n headers = {'Content-Disposition': 'inline; filename=\"out.png\"'}\n return Response(img_buf.getvalue(), headers=headers, media_type='image/png')\n```\n\n```text\nUserWarning: Starting a Matplotlib GUI outside of the main thread will likely fail.\nWARNING: QApplication was not created in the main() thread.\n```\n\n```text\nbuf.getvalue()\n```\n\n```text\ncontent\n```\n\n```text\nResponse\n```\n\n```text\nStreamingResponse\n```\n\n```text\nResponse\n```\n\n```text\nContent-Disposition\n```\n\n```text\nBackgroundTasks\n```\n\n```text\nget_img()\n```\n\n```text\nasync def\n```\n\n```text\ncreate_img()\n```\n\n```text\nmatplotlib\n```\n\n```text\nmatplotlib\n```\n\n```text\nmatplotlib.use()\n```\n\n```text\nmatplotlib.use()\n```\n\n```text\npyplot\n```\n\n```text\nAGG\n```\n\n```text\nimport io\nimport matplotlib\nmatplotlib.use('AGG')\nimport matplotlib.pyplot as plt\nfrom fastapi import FastAPI, Response, BackgroundTasks\n\napp = FastAPI()\n\ndef create_img():\n plt.rcParams['figure.figsize'] = [7.50, 3.50]\n plt.rcParams['figure.autolayout'] = True\n plt.plot([1, 2])\n img_buf = io.BytesIO()\n plt.savefig(img_buf, format='png')\n plt.close()\n return img_buf\n \n@app.get('/')\nasync def get_img(background_tasks: BackgroundTasks):\n img_buf = create_img()\n # get the entire buffer content\n # because of the async, this will await the loading of all content\n bufContents: bytes = img_buf.getvalue()\n background_tasks.add_task(img_buf.close)\n headers = {'Content-Disposition': 'inline; filename=\"out.png\"'}\n return Response(bufContents, headers=headers, media_type='image/png')\n```\n\n```text\nasync\n```\n\n```text\nasync\n```\n\n========================================\n\nComments:\n- Hey Chris, your answer was very helpful, thank you","metadata":{"transformedAt":"2026-08-18T18:32:29.144Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":27,"totalLines":267,"estimatedTokens":1502}}578{"id":"stack-72134530","source":"stackoverflow","questionId":72134530,"title":"Celery, uvicorn and FastAPI","tags":["python","celery","fastapi","uvicorn"],"text":"Title: Celery, uvicorn and FastAPI\nTags: python, celery, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI have a FastAPI api code that is executed using uvicorn. Now I want to add a queue system, and I think Celery and Flower can be great tools for me since my api has some endpoints that uses a lot CPU and take some seconds in answering. However, I have a couple of questions about the addition of Celery:\n\n- Does Celery substitute Uvicorn? Do I need it any more? I cannot see any example on the website where they consider uvicorn too, and when you execute the Celery seems to do not need it...\n\n- I have read a lot about using Celery for creating a queu for FastAPI. However, you can manage a queue in FastAPI without using Celery. What's better? and why?\n\n========================================\n\nComments:\n- 1. uvicorn is an ASGI compatible web server. Celery is a task queue. They do orthogonal different things. 2. Celery is out-of-process, letting FastAPI handle what's relevant for the web request itself and handing off the long running process to a proper queue system. Whether the complexity is necessary or \"better\" depends on your problem at hand.\n- That's what I thought. So it is still necessary an ASGI. I'm saying this because I see people starting Celery -A celery_tasks worker But I do not see that they then init the fastapi from uvicorn for instance...\n- That would depend on the project layout; you usually wouldn't start the celery workers themselves from FastAPI or uvicorn, only hand off the tasks that should be performed. If you have a resource that you've followed it'd be easier to comment on what you've read.\n- Hard agree on this. They would work hand-in-hand. Instead of using celery consider redis-queue or rq for short for lighter ETL type things that dont need the extra framing of celery.","metadata":{"transformedAt":"2026-08-18T18:32:29.144Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":0,"totalLines":18,"estimatedTokens":458}}579{"id":"stack-70250068","source":"stackoverflow","questionId":70250068,"title":"With FastAPI, How to add charset to content-type (media-type) on request header on OpenAPI (Swagger) doc?","tags":["python-3.x","swagger","openapi","fastapi"],"text":"Title: With FastAPI, How to add charset to content-type (media-type) on request header on OpenAPI (Swagger) doc?\nTags: python-3.x, swagger, openapi, fastapi\nSource: Stack Overflow\n\nQuestion:\nWith FastAPI, How to add charset to content-type (media-type) on request header on OpenAPI (Swagger) doc?\n\n```\n@app.post(\"/\")\ndef post_hello(username: str = Form(...)):\n return {\"Hello\": username}\n```\n\nOpenAPI (http:///docs) shows \"*application/x-www-form-urlencoded*\".\n\nhttps://i.sstatic.net/bJ7Ip.png\n\nI tried to change like:\n\n```\ndef post_hello(username: str = Form(..., media_type=\"application/x-www-form-urlencoded; charset=cp932\")):\n return {\"Hello\": \"World!\", \"userName\": username}\n```\n\nbut not be add *charset=cp932*\n\nI want to set \"*application/x-www-form-urlencoded; charset=cp932*\" to Content-Type on Request.\nAnd I want to get *username* decoded by the charset.\n\n========================================\n\nCode:\n```text\n@app.post(\"/\")\ndef post_hello(username: str = Form(...)):\n return {\"Hello\": username}\n```\n\n```text\ndef post_hello(username: str = Form(..., media_type=\"application/x-www-form-urlencoded; charset=cp932\")):\n return {\"Hello\": \"World!\", \"userName\": username}\n```\n\n```none\nMedia type name: application\nMedia subtype name: x-www-form-urlencoded\n\nRequired parameters: No parameters\n\nOptional parameters:\nNo parameters\n\nEncoding considerations: 7bit\n```\n\n```none\nMIME media type name : Text\n\nMIME subtype name : Standards Tree - html\n\nRequired parameters : No required parameters\n\nOptional parameters :\ncharset\nThe charset parameter may be provided to definitively specify the document's character encoding, overriding any character encoding declarations in the document. The parameter's value must be one of the labels of the character encoding used to serialize the file.\n\nEncoding considerations : 8bit\n```\n\n```python\nfrom fastapi import FastAPI, Form\nfrom fastapi.openapi.utils import get_openapi\n\napp = FastAPI()\n\n\n@app.post(\"/\")\ndef post_hello(username: str = Form(...)):\n return {\"Hello\": username}\n\n\ndef custom_openapi():\n if app.openapi_schema:\n return app.openapi_schema\n\n app.openapi_schema = get_openapi(\n title=app.title,\n version=app.version,\n openapi_version=app.openapi_version,\n description=app.description,\n terms_of_service=app.terms_of_service,\n contact=app.contact,\n license_info=app.license_info,\n routes=app.routes,\n tags=app.openapi_tags,\n servers=app.servers,\n )\n\n requestBody = app.openapi_schema[\"paths\"][\"/\"][\"post\"][\"requestBody\"]\n content = requestBody[\"content\"]\n new_content = {\n \"application/x-www-form-urlencoded;charset=cp932\": content[\n \"application/x-www-form-urlencoded\"\n ]\n }\n requestBody[\"content\"] = new_content\n\n return app.openapi_schema\n\n\napp.openapi = custom_openapi\n```\n\n```python\nimport typing\nfrom unittest.mock import patch\nfrom urllib.parse import unquote_plus\n\nimport multipart\nfrom fastapi import FastAPI, Form, Request, Response\nfrom fastapi.openapi.utils import get_openapi\nfrom multipart.multipart import parse_options_header\nfrom starlette.datastructures import FormData, UploadFile\nfrom starlette.formparsers import FormMessage, FormParser\n\napp = FastAPI()\n\nform_path = \"/\"\n\n\n@app.post(form_path)\nasync def post_hello(username: str = Form(...)):\n return {\"Hello\": username}\n\n\ndef custom_openapi():\n if app.openapi_schema:\n return app.openapi_schema\n\n app.openapi_schema = get_openapi(\n title=app.title,\n version=app.version,\n openapi_version=app.openapi_version,\n description=app.description,\n terms_of_service=app.terms_of_service,\n contact=app.contact,\n license_info=app.license_info,\n routes=app.routes,\n tags=app.openapi_tags,\n servers=app.servers,\n )\n\n requestBody = app.openapi_schema[\"paths\"][\"/\"][\"post\"][\"requestBody\"]\n content = requestBody[\"content\"]\n new_content = {\n \"application/x-www-form-urlencoded;charset=cp932\": content[\n \"application/x-www-form-urlencoded\"\n ]\n }\n requestBody[\"content\"] = new_content\n\n return app.openapi_schema\n\n\napp.openapi = custom_openapi\n\n\nclass CP932FormParser(FormParser):\n async def parse(self) -> FormData:\n \"\"\"\n copied from:\n https://github.com/encode/starlette/blob/0.17.1/starlette/formparsers.py#L72-L110\n \"\"\"\n # Callbacks dictionary.\n callbacks = {\n \"on_field_start\": self.on_field_start,\n \"on_field_name\": self.on_field_name,\n \"on_field_data\": self.on_field_data,\n \"on_field_end\": self.on_field_end,\n \"on_end\": self.on_end,\n }\n\n # Create the parser.\n parser = multipart.QuerystringParser(callbacks)\n field_name = b\"\"\n field_value = b\"\"\n\n items: typing.List[typing.Tuple[str, typing.Union[str, UploadFile]]] = []\n\n # Feed the parser with data from the request.\n async for chunk in self.stream:\n if chunk:\n parser.write(chunk)\n else:\n parser.finalize()\n messages = list(self.messages)\n self.messages.clear()\n for message_type, message_bytes in messages:\n if message_type == FormMessage.FIELD_START:\n field_name = b\"\"\n field_value = b\"\"\n elif message_type == FormMessage.FIELD_NAME:\n field_name += message_bytes\n elif message_type == FormMessage.FIELD_DATA:\n field_value += message_bytes\n elif message_type == FormMessage.FIELD_END:\n name = unquote_plus(field_name.decode(\"cp932\")) # changed line\n value = unquote_plus(field_value.decode(\"cp932\")) # changed line\n items.append((name, value))\n\n return FormData(items)\n\n\nclass CustomRequest(Request):\n async def form(self) -> FormData:\n \"\"\"\n copied from\n https://github.com/encode/starlette/blob/0.17.1/starlette/requests.py#L238-L253\n \"\"\"\n if not hasattr(self, \"_form\"):\n assert (\n parse_options_header is not None\n ), \"The `python-multipart` library must be installed to use form parsing.\"\n content_type_header = self.headers.get(\"Content-Type\")\n content_type, options = parse_options_header(content_type_header)\n if content_type == b\"multipart/form-data\":\n multipart_parser = MultiPartParser(self.headers, self.stream())\n self._form = await multipart_parser.parse()\n elif content_type == b\"application/x-www-form-urlencoded\":\n form_parser = CP932FormParser(\n self.headers, self.stream()\n ) # use the custom parser above\n self._form = await form_parser.parse()\n else:\n self._form = FormData()\n return self._form\n\n\n@app.middleware(\"http\")\nasync def custom_form_parser(request: Request, call_next) -> Response:\n if request.scope[\"path\"] == form_path:\n # starlette creates a new Request object for each middleware/app\n # invocation:\n # https://github.com/encode/starlette/blob/0.17.1/starlette/routing.py#L59\n # this temporarily patches the Request object starlette\n # uses with our modified version\n with patch(\"starlette.routing.Request\", new=CustomRequest):\n return await call_next(request)\n```\n\n```none\n>>> import sys\n>>> from urllib.parse import quote_plus\n>>> name = quote_plus(\"username\").encode(\"cp932\")\n>>> value = quote_plus(\"cp932文字コード\").encode(\"cp932\")\n>>> with open(\"temp.txt\", \"wb\") as file:\n... file.write(name + b\"=\" + value)\n...\n59\n```\n\n```shellsession\n$ curl -X 'POST' \\\n 'http://localhost:8000/' \\\n -H 'accept: application/json' \\\n -H 'Content-Type: application/x-www-form-urlencoded;charset=cp932' \\\n --data-binary \"@temp.txt\" \\\n --silent \\\n| jq -C .\n\n{\n \"Hello\": \"cp932文字コード\"\n}\n```\n\n```none\nusername=cp932%E6%96%87%E5%AD%97%E3%82%B3%E3%83%BC%E3%83%89\n```\n\n```shellsession\n$ curl -X 'POST' \\\n 'http://localhost:8000/' \\\n -H 'accept: application/json' \\\n -H 'Content-Type: application/x-www-form-urlencoded;charset=cp932' \\\n --data-urlencode \"username=cp932文字コード\" \\\n --silent \\\n| jq -C .\n\n{\n \"Hello\": \"cp932文字コード\"\n}\n```\n\n```shellsession\n$ curl -X 'POST' \\\n 'http://localhost:8000/' \\\n -H 'accept: application/json' \\\n -H 'Content-Type: application/x-www-form-urlencoded' \\\n --data \"username=cp932文字コード\" \\\n --silent \\\n| jq -C .\n{\n \"Hello\": \"cp932æ–‡å—コード\"\n}\n```\n\n```python\nimport typing\nfrom unittest.mock import patch\nfrom urllib.parse import unquote_plus\n\nimport multipart\nfrom fastapi import FastAPI, Form, Request, Response\nfrom fastapi.openapi.utils import get_openapi\nfrom multipart.multipart import parse_options_header\nfrom starlette.datastructures import FormData, UploadFile\nfrom starlette.formparsers import FormMessage, FormParser\n\napp = FastAPI()\n\nform_path = \"/\"\n\n\n@app.post(form_path)\nasync def post_hello(username: str = Form(...)):\n return {\"Hello\": username}\n\n\ndef custom_openapi():\n if app.openapi_schema:\n return app.openapi_schema\n\n app.openapi_schema = get_openapi(\n title=app.title,\n version=app.version,\n openapi_version=app.openapi_version,\n description=app.description,\n terms_of_service=app.terms_of_service,\n contact=app.contact,\n license_info=app.license_info,\n routes=app.routes,\n tags=app.openapi_tags,\n servers=app.servers,\n )\n\n requestBody = app.openapi_schema[\"paths\"][\"/\"][\"post\"][\"requestBody\"]\n content = requestBody[\"content\"]\n new_content = {\n \"application/x-www-form-urlencoded;charset=cp932\": content[\n \"application/x-www-form-urlencoded\"\n ]\n }\n requestBody[\"content\"] = new_content\n\n return app.openapi_schema\n\n\napp.openapi = custom_openapi\n\n\nclass CP932FormParser(FormParser):\n async def parse(self) -> FormData:\n \"\"\"\n copied from:\n https://github.com/encode/starlette/blob/0.17.1/starlette/formparsers.py#L72-L110\n \"\"\"\n # Callbacks dictionary.\n callbacks = {\n \"on_field_start\": self.on_field_start,\n \"on_field_name\": self.on_field_name,\n \"on_field_data\": self.on_field_data,\n \"on_field_end\": self.on_field_end,\n \"on_end\": self.on_end,\n }\n\n # Create the parser.\n parser = multipart.QuerystringParser(callbacks)\n field_name = b\"\"\n field_value = b\"\"\n\n items: typing.List[typing.Tuple[str, typing.Union[str, UploadFile]]] = []\n\n # Feed the parser with data from the request.\n async for chunk in self.stream:\n if chunk:\n parser.write(chunk)\n else:\n parser.finalize()\n messages = list(self.messages)\n self.messages.clear()\n for message_type, message_bytes in messages:\n if message_type == FormMessage.FIELD_START:\n field_name = b\"\"\n field_value = b\"\"\n elif message_type == FormMessage.FIELD_NAME:\n field_name += message_bytes\n elif message_type == FormMessage.FIELD_DATA:\n field_value += message_bytes\n elif message_type == FormMessage.FIELD_END:\n name = unquote_plus(field_name.decode(\"cp932\")) # changed line\n value = unquote_plus(field_value.decode(\"cp932\")) # changed line\n items.append((name, value))\n\n return FormData(items)\n\n\nclass CustomRequest(Request):\n async def form(self) -> FormData:\n \"\"\"\n copied from\n https://github.com/encode/starlette/blob/0.17.1/starlette/requests.py#L238-L253\n \"\"\"\n if not hasattr(self, \"_form\"):\n assert (\n parse_options_header is not None\n ), \"The `python-multipart` library must be installed to use form parsing.\"\n content_type_header = self.headers.get(\"Content-Type\")\n content_type, options = parse_options_header(content_type_header)\n if content_type == b\"multipart/form-data\":\n multipart_parser = MultiPartParser(self.headers, self.stream())\n self._form = await multipart_parser.parse()\n elif content_type == b\"application/x-www-form-urlencoded\":\n form_parser = CP932FormParser(\n self.headers, self.stream()\n ) # use the custom parser above\n self._form = await form_parser.parse()\n else:\n self._form = FormData()\n return self._form\n\n\n@app.middleware(\"http\")\nasync def custom_form_parser(request: Request, call_next) -> Response:\n if request.scope[\"path\"] != form_path:\n return await call_next(request)\n\n content_type_header = request.headers.get(\"content-type\", None)\n if not content_type_header:\n return await call_next(request)\n\n media_type, options = parse_options_header(content_type_header)\n if b\"charset\" not in options or options[b\"charset\"] != b\"cp932\":\n return await call_next(request)\n\n # starlette creates a new Request object for each middleware/app\n # invocation:\n # https://github.com/encode/starlette/blob/0.17.1/starlette/routing.py#L59\n # this temporarily patches the Request object starlette\n # uses with our modified version\n with patch(\"starlette.routing.Request\", new=CustomRequest):\n return await call_next(request)\n```\n\n```text\n;charset=UTF-8\n```\n\n```text\napplication/json\n```\n\n```text\nContent-Type\n```\n\n```text\napplication/x-www-form-urlencoded\n```\n\n```text\ntext/html\n```\n\n```text\napplication/x-www-form-urlencoded\n```\n\n```text\ncharset\n```\n\n```text\napplication/x-www-form-urlencoded\n```\n\n```text\napplication/x-www-form-urlencoded\n```\n\n```text\nRequest\n```\n\n```text\n/openapi.json\n```\n\n```text\nForm\n```\n\n```text\nForm\n```\n\n```text\nForm\n```\n\n```text\nmedia_type\n```\n\n```text\nForm.__init__\n```\n\n```text\napplication/x-www-form-urlencoded\n```\n\n```text\nForm()\n```\n\n```text\n__init__(\n```\n\n```text\nmedia_type\n```\n\n```text\n/openapi.json\n```\n\n```text\napplication/x-www-form-urlencoded\n```\n\n```text\ncharset\n```\n\n```text\npython-multipart\n```\n\n```text\nstarlette\n```\n\n```text\nLatin-1\n```\n\n```text\nstarlette\n```\n\n```text\npython-multipart\n```\n\n```text\n&\n```\n\n```text\n;\n```\n\n```text\n&\n```\n\n```text\n;\n```\n\n```text\n=\n```\n\n```text\n0x5C\n```\n\n```text\n¥\n```\n\n```text\nstarlette\n```\n\n```text\n0x7E\n```\n\n```text\n~\n```\n\n```text\n0x5C\n```\n\n```text\n\\\n```\n\n```text\n¥\n```\n\n```text\ncurl -d\n```\n\n```text\n--data\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.145Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":55,"totalLines":624,"estimatedTokens":3698}}580{"id":"stack-60832975","source":"stackoverflow","questionId":60832975,"title":"Is it possible to pass a path to a fastapi end point?","tags":["python","python-3.x","fastapi"],"text":"Title: Is it possible to pass a path to a fastapi end point?\nTags: python, python-3.x, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to create a folder traversing api with fastapi. \nSay I have an end point like this:\n\n```\n@root_router.get(\"/path/{path}\")\ndef take_path(path):\n logger.info(\"test %s\", path)\n return path\n```\n\nIf I do to the browser and call \"URL:PORT/path/path\"\n\nit returns \"path\", easy. But if I try \"URL:PORT/path/path/path\" the code doesnt even get to the logger. I guess that makes sense as the API doesnt have that end point in existence. But it DOES exist on my server. I have figured out other ways to do this, i.e. pass the path as an array of params and rebuld in code with / separator, but passing params in url feels a bit clunky, if I can move through the paths in the url the same as my server, that would be ideal. Is this doable?\n\nThanks.\n\n========================================\n\nCode:\n```text\n@root_router.get(\"/path/{path}\")\ndef take_path(path):\n logger.info(\"test %s\", path)\n return path\n```\n\n```py\n@root_router.get(\"/path/{path:path}\")\nasync def take_path(path: str):\n logger.info(\"test %s\", path)\n return path\n```\n\n```text\n:path\n```\n\n========================================\n\nComments:\n- wow, that worked. thanks. This is the correct way to do it, yes? Any recommendations? I am using angular to call in the api and serve files.\n- @ScipioAfricanus In general this API design is discouraged. OpenAPI, for example, doesn't even allow defining something like this. I'd recommend passing the path as a query parameter. However if you decide to continue with the current design, this is the standard way to go.","metadata":{"transformedAt":"2026-08-18T18:32:29.145Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":3,"totalLines":47,"estimatedTokens":416}}581{"id":"stack-69417502","source":"stackoverflow","questionId":69417502,"title":"How to validate request body in FastAPI?","tags":["python","sql","rest","request","fastapi"],"text":"Title: How to validate request body in FastAPI?\nTags: python, sql, rest, request, fastapi\nSource: Stack Overflow\n\nQuestion:\nI understand that if the incoming request body misses certain required keys, FastAPI will automatically raise `422 unserviceable entity` error. However, is there a way to check the incoming request body by myself in the code and raise a `400 bad request` if if misses required names?\n\nFor example, say I have this model and schema:\n\n```\nclass Student(Base):\n __tablename__ = \"student\"\n\n id = Column(Integer, primary_key=True)\n name = Column(String(50), unique=True, nullable=False)\n email = Column(String(100), unique=True, nullable=False)\n gpa = Column(Float, unique=False, nullable=False)\n```\n\n```\nclass StudentBase(BaseModel):\n name: str\n email: str\n gpa: float\n```\n\nThe POST endpoint to create a new row is:\n\n```\n@app.post(\"/student\", dependencies=[Depends(check_request_header)],\n response_model=schemas.Student, status_code=200)\ndef create_student(student: schemas.StudentCreate, db: Session = Depends(get_db)):\n db_student = crud.get_student(db, student=student)\n if db_student:\n raise HTTPException(status_code=400, detail=\"This student has already been created.\")\n return crud.create_student(db=db, student=student)\n```\n\nThe expected request body should be something like this:\n\n```\n{\n\"name\": \"johndoe\",\n\"email\": \"johndoe@gmail.com\",\n\"gpa\": 5.0\n}\n```\n\nis there a way to check the request body for the above endpoint?\n\n========================================\n\nCode:\n```py\nclass Student(Base):\n __tablename__ = \"student\"\n\n id = Column(Integer, primary_key=True)\n name = Column(String(50), unique=True, nullable=False)\n email = Column(String(100), unique=True, nullable=False)\n gpa = Column(Float, unique=False, nullable=False)\n```\n\n```py\nclass StudentBase(BaseModel):\n name: str\n email: str\n gpa: float\n```\n\n```py\n@app.post(\"/student\", dependencies=[Depends(check_request_header)],\n response_model=schemas.Student, status_code=200)\ndef create_student(student: schemas.StudentCreate, db: Session = Depends(get_db)):\n db_student = crud.get_student(db, student=student)\n if db_student:\n raise HTTPException(status_code=400, detail=\"This student has already been created.\")\n return crud.create_student(db=db, student=student)\n```\n\n```json\n{\n\"name\": \"johndoe\",\n\"email\": \"johndoe@gmail.com\",\n\"gpa\": 5.0\n}\n```\n\n```text\n422 unserviceable entity\n```\n\n```text\n400 bad request\n```\n\n```text\n.from_dict\n```\n\n========================================\n\nComments:\n- Could you add the definitions of the various functions you are using? Also, could you make clearer what your expectations are and how the code is not doing what you want?","metadata":{"transformedAt":"2026-08-18T18:32:29.145Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":7,"totalLines":104,"estimatedTokens":675}}582{"id":"stack-79441349","source":"stackoverflow","questionId":79441349,"title":"Why is my FastAPI endpoint not saving an HTTPonly Cookie using Fetch?","tags":["cookies","cors","fetch","fastapi"],"text":"Title: Why is my FastAPI endpoint not saving an HTTPonly Cookie using Fetch?\nTags: cookies, cors, fetch, fastapi\nSource: Stack Overflow\n\nQuestion:\nThe question says it all, I feel like I've read everything I can and I am still no further forwards. The current situation is:\n\n- Enter `api.mydomain.com` into a browser directly ***does*** save my cookie\n\n- Using Fetch from my `index.html` from my `portal.mydomain.com` ***does not***.\n\nI have no CORS errors and the OPTIONS, GET and POST requests all get a 200 response. The payload in FastAPI is being correctly received as I can see the JSON data payload, just no cookie, nor can I see the cookie set in my broswer dev tools.\n\nIn my HTML file I have the following:\n\n```\nfetch('https://api.mydomain.com/api/v1/forms/cookie?category=all&count=2', {\n method: 'GET',\n credentials: 'include',\n headers: {\n \"Access-Control-Allow-Origin\": \"https://portal.mydomain.com\"\n }\n})\n .then(response => response.json())\n .then(data => console.log(data))\n .catch(err => console.error(err));\n \n\nconst payload = {\n \"email\": \"test@test.com\",\n \"password\": \"password\",\n \"csrf\": \"csrf\"\n}\nconst jsonData = JSON.stringify(payload);\n\nfetch('https://api.mydomain.com/api/v1/forms/auth', {\n method: 'POST',\n credentials: 'include',\n headers: {\n \"Access-Control-Allow-Origin\": \"https://portal.mydomain.com\",\n \"Content-Type\": \"application/json\"\n },\n body: jsonData\n})\n .then(response => response.json())\n .then(data => console.log(data))\n .catch(err => console.error(err));\n```\n\nMy router looks like this for API:\n\n```\n@router.get(\"/cookie\")\ndef set_cookie(response: Response):\n # Set an HttpOnly cookie\n response.set_cookie(\n key=\"testCookie\",\n value=\"testCookieValue\",\n httponly=True, # This makes the cookie HttpOnly\n secure=True, # Use secure cookies in production\n samesite=\"none\" # Adjust based on your needs\n )\n return {\"message\": \"Cookie has been set2\"}\n```\n\nMy initial FastAPI config looks like this:\n\n```\norigins = [\n \"https://portal.mydomain.com\",\n \"https://api.mydomain.com\",\n]\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=origins,\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\n \"Content-Type\", \n \"Authorization\", \n \"X-Requested-With\", \n \"Access-Control-Request-Method\", \n \"Access-Control-Request-Headers\",\n \"Access-Control-Allow-Origin\"],\n \n)\n```\n\nI'm not sure what else to try.\n\n========================================\n\nCode:\n```text\nfetch('https://api.mydomain.com/api/v1/forms/cookie?category=all&count=2', {\n method: 'GET',\n credentials: 'include',\n headers: {\n \"Access-Control-Allow-Origin\": \"https://portal.mydomain.com\"\n }\n})\n .then(response => response.json())\n .then(data => console.log(data))\n .catch(err => console.error(err));\n \n\nconst payload = {\n \"email\": \"test@test.com\",\n \"password\": \"password\",\n \"csrf\": \"csrf\"\n}\nconst jsonData = JSON.stringify(payload);\n\nfetch('https://api.mydomain.com/api/v1/forms/auth', {\n method: 'POST',\n credentials: 'include',\n headers: {\n \"Access-Control-Allow-Origin\": \"https://portal.mydomain.com\",\n \"Content-Type\": \"application/json\"\n },\n body: jsonData\n})\n .then(response => response.json())\n .then(data => console.log(data))\n .catch(err => console.error(err));\n```\n\n```text\n@router.get(\"/cookie\")\ndef set_cookie(response: Response):\n # Set an HttpOnly cookie\n response.set_cookie(\n key=\"testCookie\",\n value=\"testCookieValue\",\n httponly=True, # This makes the cookie HttpOnly\n secure=True, # Use secure cookies in production\n samesite=\"none\" # Adjust based on your needs\n )\n return {\"message\": \"Cookie has been set2\"}\n```\n\n```text\norigins = [\n \"https://portal.mydomain.com\",\n \"https://api.mydomain.com\",\n]\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=origins,\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\n \"Content-Type\", \n \"Authorization\", \n \"X-Requested-With\", \n \"Access-Control-Request-Method\", \n \"Access-Control-Request-Headers\",\n \"Access-Control-Allow-Origin\"],\n \n)\n```\n\n```text\napi.mydomain.com\n```\n\n```text\nindex.html\n```\n\n```text\nportal.mydomain.com\n```\n\n```py\n@router.get(\"/cookie\")\ndef set_cookie(response: Response):\n # Set an HttpOnly cookie\n response.set_cookie(\n key=\"testCookie\",\n value=\"testCookieValue\",\n httponly=True,\n secure=True,\n samesite=\"none\",\n domain=\".mydomain.com\",\n )\n return {\"message\": \"Cookie has been set2\"}\n```\n\n```text\napi.mydomain.com\n```\n\n```text\nportal.mydomain.com\n```\n\n```text\n.mydomain.com\n```\n\n========================================\n\nComments:\n- Regardless of the issue, please take a look at this answer, as it could prove helpful to you.\n- what's the reason of setting `samesite` to `none` - it doesn't seem that you need it. Are you aware of the risks?\n- This (and the references included) might be helpful as well.\n- Thanks @Chris they were helpful links. I set it at none just to see if this was the cause, since I've the domain= to the response, I managed to set it more securely.\n- The leading period is superfluous. `domain=\"mydomain.com\"` would work just as well.","metadata":{"transformedAt":"2026-08-18T18:32:29.145Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":10,"totalLines":211,"estimatedTokens":1301}}583{"id":"stack-74551520","source":"stackoverflow","questionId":74551520,"title":"Not able to copy file in docker file which is downloaded in github actions","tags":["python","docker","github-actions","fastapi"],"text":"Title: Not able to copy file in docker file which is downloaded in github actions\nTags: python, docker, github-actions, fastapi\nSource: Stack Overflow\n\nQuestion:\nI can able to see the `.pkl` which is downloaded using `actions/download-artifact@v3` action in work directory along with `Dockerfile` as shown below,\n\nhttps://i.sstatic.net/GuS8X.png\n\nWhen I try to `COPY` file inside Dockefile, I get a file not found error.\n\nhttps://i.sstatic.net/SC7rO.png\n\nHow to copy the files inside docker image that are downloaded(through github actions) before building docker image?\n\nHere is doc from github on docker support, but I didn't get exactly how to solve my issue. Any help would be really appreciated!!\n\n**Dockerfile:**\n\n```\nname: Docker - GitHub workflow\n\nenv:\n CONTAINER_NAME: xxx-xxx\n\non:\n workflow_dispatch:\n push:\n branches: [\"main\"]\n pull_request:\n branches: [\"main\"]\n\npermissions:\n id-token: write\n contents: read\n\njobs:\n load-artifacts:\n runs-on: ubuntu-latest\n environment: dev\n env:\n output_path: ./xxx/xxx_model.pkl\n \n steps:\n - uses: actions/checkout@v3\n\n - name: Download PPE model file\n run: |\n az storage blob download --container-name ppe-container --name xxx_model.pkl -f \"${{ env.output_path }}\"\n \n - name: View output - after\n run: |\n ls -lhR\n \n - name: 'Upload Artifact'\n uses: actions/upload-artifact@v3\n with:\n name: ppe_model\n path: ${{ env.output_path }}\n\n \n build:\n needs: load-artifacts\n runs-on: ubuntu-latest\n env:\n ACR: xxxx\n \n steps:\n - uses: actions/checkout@v3\n\n - uses: actions/download-artifact@v3\n id: download\n with:\n name: ppe_model\n # path: ${{ env.model_path }}\n\n - name: Echo download path\n run: echo ${{steps.download.outputs.download-path}}\n \n - name: View directory files\n run: |\n ls -lhR -a\n\n - name: Build container image\n uses: docker/build-push-action@v2\n with:\n push: false\n tags: ${{ env.ACR }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.run_number }}\n file: ./Dockerfile\n```\n\n========================================\n\nCode:\n```text\nname: Docker - GitHub workflow\n\nenv:\n CONTAINER_NAME: xxx-xxx\n\non:\n workflow_dispatch:\n push:\n branches: [\"main\"]\n pull_request:\n branches: [\"main\"]\n\n\npermissions:\n id-token: write\n contents: read\n\njobs:\n load-artifacts:\n runs-on: ubuntu-latest\n environment: dev\n env:\n output_path: ./xxx/xxx_model.pkl\n \n steps:\n - uses: actions/checkout@v3\n\n - name: Download PPE model file\n run: |\n az storage blob download --container-name ppe-container --name xxx_model.pkl -f \"${{ env.output_path }}\"\n \n - name: View output - after\n run: |\n ls -lhR\n \n - name: 'Upload Artifact'\n uses: actions/upload-artifact@v3\n with:\n name: ppe_model\n path: ${{ env.output_path }}\n\n \n build:\n needs: load-artifacts\n runs-on: ubuntu-latest\n env:\n ACR: xxxx\n \n steps:\n - uses: actions/checkout@v3\n\n - uses: actions/download-artifact@v3\n id: download\n with:\n name: ppe_model\n # path: ${{ env.model_path }}\n\n - name: Echo download path\n run: echo ${{steps.download.outputs.download-path}}\n \n - name: View directory files\n run: |\n ls -lhR -a\n\n - name: Build container image\n uses: docker/build-push-action@v2\n with:\n push: false\n tags: ${{ env.ACR }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.run_number }}\n file: ./Dockerfile\n```\n\n```text\n.pkl\n```\n\n```text\nactions/download-artifact@v3\n```\n\n```text\nDockerfile\n```\n\n```text\nCOPY\n```\n\n```yaml\n- name: Build container image\n uses: docker/build-push-action@v2\n with:\n push: false\n tags: ${{ env.ACR }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.run_number }}\n file: ./Dockerfile\n```\n\n```yaml\n- name: Build container image\n uses: docker/build-push-action@v2\n with:\n context: .\n push: false\n tags: ${{ env.ACR }}.azurecr.io/${{ env.CONTAINER_NAME }}:${{ github.run_number }}\n file: ./Dockerfile\n```\n\n```text\ndocker/build-push-action\n```\n\n========================================\n\nComments:\n- what is the build context of docker image, relative paths are relative to build context\n- @SankethB.K Not sure. How to check that? or How to make sure it's pointing to the right location? Can please provide it as answer, if it's lengthy in comments?\n- You save my day.","metadata":{"transformedAt":"2026-08-18T18:32:29.145Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":8,"totalLines":212,"estimatedTokens":1112}}584{"id":"stack-68765398","source":"stackoverflow","questionId":68765398,"title":"Depends and a class instance in FastAPI","tags":["python","fastapi"],"text":"Title: Depends and a class instance in FastAPI\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm struggling to find a decent implementation to return a validated user with class implementation. Previously it worked with simple functions, but I want to refactor this piece. So I added a class and trying to make it work. The problem is it doesn't seem to create a new instance of a class. If I'm trying to do `Depends(UserAuthService().test)` I'm getting an error\n\n```\n{\n \"message\": \"Bad request.\",\n \"details\": \"'TokenService' object is not callable\"\n}\n```\n\nrouter.py\n\n```\nrouter = APIRouter()\n\n@router.get(\"/verify\")\ndef verify_user(user: User = Depends(UserAuthService().get_current_valid_user)):\n return user\n```\n\nuser_auth_service.py\n\n```\nclass UserAuthService:\n def __init__(self):\n self.user_repository = UserRepository()\n self.token_service = TokenService()\n\n def get_current_user(self, token: str = Depends(OAUTH2_SCHEME)):\n credentials_exception = HTTPException(\n status_code=HTTP_403_FORBIDDEN, detail=\"Could not validate the token\"\n )\n user_does_not_exist_exception = HTTPException(\n status_code=HTTP_403_FORBIDDEN, detail=\"User does not exist\"\n )\n try:\n payload = self.token_service.decode_access_token(token)\n sub: int = payload.get(\"sub\")\n if sub is None:\n raise credentials_exception\n except JWTError:\n raise credentials_exception\n\n user = self.user_repository.get_user(sub)\n if user is None:\n raise user_does_not_exist_exception\n return User(**user)\n\n def get_current_valid_user(self, user: User = Depends(get_current_user)):\n if user.disabled:\n raise HTTPException(status_code=400, detail=\"Inactive user\")\n return user\n\n def test(self):\n return self.token_service('123456')\n```\n\nP.S. as you can see there's Depends inside class methods, but that's from previous functional implementation.\n\n========================================\n\nTop Answer:\nAfter fixing classes the final code looks like this\n\nrouter.py\n\n```\n@router.get(\"/verify\")\ndef verify_user(user: User = Depends(UserValidator())):\n return user\n```\n\nuser_auth_service.py and user_validator.py\n\n```\nclass UserAuthService:\n def __init__(self):\n self.user_repository = UserRepository()\n self.token_service = TokenService()\n self.oauth2_scheme = OAuth2BearerCookie()\n\n async def get_current_user(self, request: Request):\n token = await self.oauth2_scheme(request)\n credentials_exception = HTTPException(\n status_code=HTTP_403_FORBIDDEN, detail=\"Could not validate the token\"\n )\n user_does_not_exist_exception = HTTPException(\n status_code=HTTP_403_FORBIDDEN, detail=\"User does not exist\"\n )\n try:\n payload = self.token_service.decode_access_token(token)\n sub: int = payload.get(\"sub\")\n if sub is None:\n raise credentials_exception\n except JWTError:\n raise credentials_exception\n\n user = self.user_repository.get_user(sub)\n if user is None:\n raise user_does_not_exist_exception\n return User(**user)\n\n async def get_current_valid_user(self, request: Request):\n user = await self.get_current_user(request)\n if user.disabled:\n raise HTTPException(status_code=400, detail=\"Inactive user\")\n return user\n\nclass UserValidator:\n async def __call__(self, request: Request):\n user_service = UserAuthService()\n return await user_service.get_current_valid_user(request)\n```\n\n========================================\n\nCode:\n```text\n{\n \"message\": \"Bad request.\",\n \"details\": \"'TokenService' object is not callable\"\n}\n```\n\n```text\nrouter = APIRouter()\n\n\n@router.get(\"/verify\")\ndef verify_user(user: User = Depends(UserAuthService().get_current_valid_user)):\n return user\n```\n\n```text\nclass UserAuthService:\n def __init__(self):\n self.user_repository = UserRepository()\n self.token_service = TokenService()\n\n def get_current_user(self, token: str = Depends(OAUTH2_SCHEME)):\n credentials_exception = HTTPException(\n status_code=HTTP_403_FORBIDDEN, detail=\"Could not validate the token\"\n )\n user_does_not_exist_exception = HTTPException(\n status_code=HTTP_403_FORBIDDEN, detail=\"User does not exist\"\n )\n try:\n payload = self.token_service.decode_access_token(token)\n sub: int = payload.get(\"sub\")\n if sub is None:\n raise credentials_exception\n except JWTError:\n raise credentials_exception\n\n user = self.user_repository.get_user(sub)\n if user is None:\n raise user_does_not_exist_exception\n return User(**user)\n\n def get_current_valid_user(self, user: User = Depends(get_current_user)):\n if user.disabled:\n raise HTTPException(status_code=400, detail=\"Inactive user\")\n return user\n\n def test(self):\n return self.token_service('123456')\n```\n\n```text\nDepends(UserAuthService().test)\n```\n\n```text\nclass UserAuthService:\n def __init__(self):\n ...\n self.token_service = TokenService()\n\n ...\n\n def test(self):\n return self.token_service('123456')\n```\n\n```text\nclass A():\n\n def __init__(self, param = None):\n self.param = param\n\n def print_something(self, something = None):\n print('Init param is', self.param)\n print('Something is', something)\n\n\nclass B():\n\n def __init__(self, param = None):\n self.a_instance = A(param)\n\n def test(self, something = None):\n self.a_instance.print_something(something) # run a_instance.print_something() instead of a_instance()\n\nb = B('A obj')\nb.test('test')\n```\n\n```text\nInit param is A obj\nSomething is test\n```\n\n```text\nclass ACallable():\n\n def __init__(self, param = None):\n self.param = param\n\n def __call__(self, something = None):\n print('Init param is', self.param)\n print('Something is', something)\n\n\nclass BCalling():\n\n def __init__(self, param = None):\n self.a_instance = ACallable(param)\n\n def test(self, something = None):\n self.a_instance(something) # __call__ method will be called\n\nb = BCalling('A obj')\nb.test('test')\n```\n\n```text\nInit param is A obj\nSomething is test\n```\n\n```text\nclass A():\n\n def __init__(self, param = None):\n print('Init param is', param)\n\nclass B():\n\n def __init__(self, param = None):\n self.a_instance = A # here is A without brackets\n\n def test(self, param = None):\n self.a_instance(param) # here is a_instance (== A) with brackets\n\nb = B()\nb.test('<- called from constructor')\n```\n\n```text\nInit param is <- called from constructor\n```\n\n```text\n@router.get(\"/verify\")\ndef verify_user(user: User = Depends(UserValidator())):\n return user\n```\n\n```text\nclass UserAuthService:\n def __init__(self):\n self.user_repository = UserRepository()\n self.token_service = TokenService()\n self.oauth2_scheme = OAuth2BearerCookie()\n\n async def get_current_user(self, request: Request):\n token = await self.oauth2_scheme(request)\n credentials_exception = HTTPException(\n status_code=HTTP_403_FORBIDDEN, detail=\"Could not validate the token\"\n )\n user_does_not_exist_exception = HTTPException(\n status_code=HTTP_403_FORBIDDEN, detail=\"User does not exist\"\n )\n try:\n payload = self.token_service.decode_access_token(token)\n sub: int = payload.get(\"sub\")\n if sub is None:\n raise credentials_exception\n except JWTError:\n raise credentials_exception\n\n user = self.user_repository.get_user(sub)\n if user is None:\n raise user_does_not_exist_exception\n return User(**user)\n\n async def get_current_valid_user(self, request: Request):\n user = await self.get_current_user(request)\n if user.disabled:\n raise HTTPException(status_code=400, detail=\"Inactive user\")\n return user\n\n\nclass UserValidator:\n async def __call__(self, request: Request):\n user_service = UserAuthService()\n return await user_service.get_current_valid_user(request)\n```\n\n========================================\n\nComments:\n- Thanks for pointing to an obvious mistake! I attached fixed code.\n- Many thanks for this answers. Making the instance callable (solution 2) worked for me","metadata":{"transformedAt":"2026-08-18T18:32:29.145Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":13,"totalLines":318,"estimatedTokens":2026}}585{"id":"stack-77969526","source":"stackoverflow","questionId":77969526,"title":"optional parameters FastAPI","tags":["python","fastapi","pydantic"],"text":"Title: optional parameters FastAPI\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nplease help me. In the function I set the optional parameter `param` as a boolean value, but the docs (swagger) do not display the data type for param. How to fix it? I'm using `python 3.12.1`\n\n```\nfrom fastapi import FastAPI\nfrom datetime import date\n\napp=FastAPI()\n\n@app.get (\"/sales\")\ndef sales(\n date_from: date, \n date_to: date,\n param: bool | None = None,\n):\n return date_from, date_to, param\n```\n\non version `python 3.9` everything is fine\n\n========================================\n\nTop Answer:\n@Leonidktoto's comment deserves to be an answer:\n\"Using SkipJsonSchema removes anyOf and null from openapi.json and swagger shows parameter correctly\"\n\nFor example:\n\n```\nfrom datetime import date\nfrom typing import Annotated\nfrom fastapi import FastAPI, Query\nfrom pydantic.json_schema import SkipJsonSchema\n\napp=FastAPI()\n\n@app.get (\"/sales\")\ndef sales(\n date_from: date, \n date_to: date,\n param: Annotated[bool | SkipJsonSchema[None], Query()] = None,\n):\n return date_from, date_to, param\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nfrom datetime import date\n\n\napp=FastAPI()\n\n\n\n@app.get (\"/sales\")\ndef sales(\n date_from: date, \n date_to: date,\n param: bool | None = None,\n):\n return date_from, date_to, param\n```\n\n```text\nparam\n```\n\n```text\npython 3.12.1\n```\n\n```text\npython 3.9\n```\n\n```text\nparam: bool = False,\n```\n\n```text\nbool\n```\n\n```text\nbool | None\n```\n\n```text\nOptional[bool]\n```\n\n```text\nfrom datetime import date\nfrom typing import Annotated\nfrom fastapi import FastAPI, Query\nfrom pydantic.json_schema import SkipJsonSchema\n\napp=FastAPI()\n\n@app.get (\"/sales\")\ndef sales(\n date_from: date, \n date_to: date,\n param: Annotated[bool | SkipJsonSchema[None], Query()] = None,\n):\n return date_from, date_to, param\n```\n\n========================================\n\nComments:\n- If it works with Python 3.9 but not 3.12, it's probably a bug in FastAPI. You should open a github issue.\n- I understood it. what to do with this parameter, it is also not displayed, example from the documentation `q: Annotated[str | None, Query(max_length=50)] = None`\n- It appears you're going to have to make some compromises. If you really want swagger docs (a lovely goal), and swagger offers a least-common-denominator type system that is less powerful than what `mypy` and beartype support, then maybe just cry \"Uncle!\" and do what swagger demands. Which in this case is probably sticking with a simple `str` type. // It's possible that you could have private \"strictly typed\" helper functions behind the scenes, which swagger doesn't care about. And then you call through to them and mostly get the best of both worlds.\n- this is a pydantic problem, I tried installing pydantic version 1.10 and it worked. json for Swagger is different. Now I don’t know what to do, should I use the old or new version of pydantc?\n- `q: Annotated[int | SkipJsonSchema[None], Query()] = None` Using SkipJsonSchema removes anyOf and null from openapi.json and swagger shows parameter correctly\n- SkipJsonSchema, FTW!\n- `from pydantic.json_schema import SkipJsonSchema`","metadata":{"transformedAt":"2026-08-18T18:32:29.145Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":9,"totalLines":125,"estimatedTokens":803}}586{"id":"stack-67469367","source":"stackoverflow","questionId":67469367,"title":"FastApi 422 Unprocessable Entity, on authentication, how to fix?","tags":["javascript","python","fastapi"],"text":"Title: FastApi 422 Unprocessable Entity, on authentication, how to fix?\nTags: javascript, python, fastapi\nSource: Stack Overflow\n\nQuestion:\nCannot understand even if i delete all inside function and just print something still got this error, but when i use fastapi docs, and try signing with that, it work.\n\n```\n@auth_router.post('/signin')\nasync def sign_in(username: str = Form(...), password: str = Form(...)) -> dict:\n user = await authenticate_user(username, password)\n\n if not user:\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED, \n detail='Invalid username or password',\n )\n\n user_obj = await User_Pydantic.from_tortoise_orm(user)\n user_token = await generate_token(user_obj)\n\n return {\n 'access_token': user_token,\n 'token_type': 'bearer',\n }\n```\n\nBefore i use OAuth2PasswordRequestForm, when got 422 error, try another way.\n\nmy model is tortoise orm, and when need i convert it to pydantic model,\nin docs all is work.\n\nJS\n\n```\nhandleEvent(signinform, 'submit', e => {\n e.preventDefault();\n if(!isEmpty(signinform)){\n\n signInUsername = getElement('input[name=\"username\"]', signinform).value;\n signInPassword = getElement('input[name=\"password\"]', signinform).value;\n recaptchaV3 = getElement('[name=\"g-recaptcha-response\"]').value;\n\n if(recaptchaV3){\n signInData = new FormData();\n signInData.append('username', signInUsername);\n signInData.append('password', signInPassword);\n\n isLogened = request('POST', '/signin', signInData);\n if(isLogened){\n log(isLogened);\n }\n \n } else{\n alert('Reload Page');\n }\n\n }\n\n})\n```\n\nauthenticate_user func\n\n```\nasync def authenticate_user(username: str, password: str):\n user = await User.get(username=username)\n\n if not user or not user.verify_password(password):\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED, \n detail='Invalid username or password',\n )\n return user\n```\n\nMy request function\n\n```\nconst request = (method, url, data = null) => {\n return new Promise((resolve, reject) => {\n let xhr = new XMLHttpRequest()\n xhr.open(method, url, true)\n xhr.setRequestHeader('Content-Type', 'application/json')\n xhr.onerror = function () {\n console.log(xhr.response);\n };\n xhr.onload = () => {\n if (xhr.status === 200) {\n return resolve(JSON.parse(xhr.responseText || '{}'))\n } else {\n return reject(new Error(`Request failed with status ${xhr.status}`))\n }\n } \n if (data) {\n xhr.send(JSON.stringify(data))\n } else {\n xhr.send()\n }\n\n })\n}\n```\n\n========================================\n\nTop Answer:\nEnsure that you have provided content type in your request,\n\n```\nxhr.setRequestHeader('Content-Type', 'application/json')\n```\n\nIf it's there then verify the format of your input. Here, you have declared two varibales - signInUsername and signInPassword.\n\n**Important: You might provided a default value for these files in FastAPI. In that case, if you provided an empty content or null as the attribute values then the fastapi will throw the above error.**\n\nEnsure that the data that you are sending to the server is correct.\n\n========================================\n\nCode:\n```text\n@auth_router.post('/signin')\nasync def sign_in(username: str = Form(...), password: str = Form(...)) -> dict:\n user = await authenticate_user(username, password)\n\n if not user:\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED, \n detail='Invalid username or password',\n )\n\n user_obj = await User_Pydantic.from_tortoise_orm(user)\n user_token = await generate_token(user_obj)\n\n return {\n 'access_token': user_token,\n 'token_type': 'bearer',\n }\n```\n\n```text\nhandleEvent(signinform, 'submit', e => {\n e.preventDefault();\n if(!isEmpty(signinform)){\n\n signInUsername = getElement('input[name=\"username\"]', signinform).value;\n signInPassword = getElement('input[name=\"password\"]', signinform).value;\n recaptchaV3 = getElement('[name=\"g-recaptcha-response\"]').value;\n\n if(recaptchaV3){\n signInData = new FormData();\n signInData.append('username', signInUsername);\n signInData.append('password', signInPassword);\n\n isLogened = request('POST', '/signin', signInData);\n if(isLogened){\n log(isLogened);\n }\n \n } else{\n alert('Reload Page');\n }\n\n }\n\n})\n```\n\n```text\nasync def authenticate_user(username: str, password: str):\n user = await User.get(username=username)\n\n if not user or not user.verify_password(password):\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED, \n detail='Invalid username or password',\n )\n return user\n```\n\n```text\nconst request = (method, url, data = null) => {\n return new Promise((resolve, reject) => {\n let xhr = new XMLHttpRequest()\n xhr.open(method, url, true)\n xhr.setRequestHeader('Content-Type', 'application/json')\n xhr.onerror = function () {\n console.log(xhr.response);\n };\n xhr.onload = () => {\n if (xhr.status === 200) {\n return resolve(JSON.parse(xhr.responseText || '{}'))\n } else {\n return reject(new Error(`Request failed with status ${xhr.status}`))\n }\n } \n if (data) {\n xhr.send(JSON.stringify(data))\n } else {\n xhr.send()\n }\n\n\n })\n}\n```\n\n```text\nxhr.setRequestHeader('Content-Type', 'application/json')\n```\n\n```text\nwww-form-urlencoded\n```\n\n```text\nFormData\n```\n\n```text\nxhr.setRequestHeader('Content-Type', 'application/json')\n```\n\n========================================\n\nComments:\n- The 422 error will have a body that explains which expected information is missing. 422 indicates that one of the required parameters to the FastAPI endpoint is missing (i.e. it doesn't match the expected input format). The message will tell you which field(s) is missing / in the wrong location. As possible explanation is that you're including a recaptcha value that your endpoint doesn't expect (and which wouldn't be expected if you used the docs). Not sure if that would result in a 422 error, though.\n- @MatsLindh No, i try recaptcha is not raise error, and my body is empty, i update my question, add func how i send request\n- You're sending your data as JSON, but you use `Form(...)` as the parameter - which implies regular urlencoded post params.\n- Please have a look at this answer\n- yeah problem was in it, sorry just blind copy js code, from one thing to another one, i remove that line and it work, i try set request header to what you suggest me, and also try use multipart/form-data and not work, but deleting that line is working idea! TNX A LOT SIR.","metadata":{"transformedAt":"2026-08-18T18:32:29.145Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":8,"totalLines":233,"estimatedTokens":1676}}587{"id":"stack-75500135","source":"stackoverflow","questionId":75500135,"title":"how can I add my own _id instead of the already given _id in MongoDB in Python?","tags":["python","mongodb","pymongo","fastapi","pydantic"],"text":"Title: how can I add my own _id instead of the already given _id in MongoDB in Python?\nTags: python, mongodb, pymongo, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI have a class model using *Pydantics*. I try to supply my own ID but it gives me two id fields in the MongoDB database. The one I gave it and the one it makes automatically.\n\nHere is the result of my post method:\n\nhttps://i.sstatic.net/c5dZm.png\n\nhere is my class in *models/articleModel.py*:\n\n```\nclass ArticleModel(BaseModel):\n _id: int\n title: str\n body: str\n tags: Optional[list] = None\n datetime: Optional[datetime] = None\n caption: Optional[str] = None\n link: Optional[str] = None\n \nclass Config:\n orm_mode = True\n allow_population_by_field_name = True\n arbitrary_types_allowed = True\n```\n\nhere is my code for the post method in *routers/article_router*:\n\n```\n@router.post(\"/article/\", status_code=status.HTTP_201_CREATED)\ndef add_article(article: articleModel.ArticleModel):\n article.datetime = datetime.utcnow()\n\n try:\n result = Articles.insert_one(article.dict())\n pipeline = [\n {'$match': {'_id': result.inserted_id}}\n ]\n new_article = articleListEntity(Articles.aggregate(pipeline))[0]\n return new_article\n except DuplicateKeyError:\n raise HTTPException(status_code=status.HTTP_409_CONFLICT,\n detail=f\"Article with title: '{article.id}' already exists\")\n```\n\n========================================\n\nCode:\n```py\nclass ArticleModel(BaseModel):\n _id: int\n title: str\n body: str\n tags: Optional[list] = None\n datetime: Optional[datetime] = None\n caption: Optional[str] = None\n link: Optional[str] = None\n \nclass Config:\n orm_mode = True\n allow_population_by_field_name = True\n arbitrary_types_allowed = True\n```\n\n```py\n@router.post(\"/article/\", status_code=status.HTTP_201_CREATED)\ndef add_article(article: articleModel.ArticleModel):\n article.datetime = datetime.utcnow()\n\n try:\n result = Articles.insert_one(article.dict())\n pipeline = [\n {'$match': {'_id': result.inserted_id}}\n ]\n new_article = articleListEntity(Articles.aggregate(pipeline))[0]\n return new_article\n except DuplicateKeyError:\n raise HTTPException(status_code=status.HTTP_409_CONFLICT,\n detail=f\"Article with title: '{article.id}' already exists\")\n```\n\n```py\n@router.post(\"/article/\", status_code=status.HTTP_201_CREATED)\ndef add_article(article: articleModel.ArticleModel):\n article.datetime = datetime.utcnow()\n \n article_new_id = article.dict()\n article_new_id['_id'] = article_new_id['id']\n del article_new_id['id']\n\n try:\n result = Articles.insert_one(article_new_id)\n pipeline = [\n {'$match': {'_id': result.inserted_id}}\n ]\n new_article = articleListEntity(Articles.aggregate(pipeline))[0]\n return new_article\n except DuplicateKeyError:\n raise HTTPException(status_code=status.HTTP_409_CONFLICT,\n detail=f\"Article with title: '{article.id}' already exists\")\n```\n\n========================================\n\nComments:\n- Could it be because of Pydantic's *Automatically excluded attributes*?\n- @rickhg12hs I don't think so. But I did solve it by converting it to a dictionary and adding a new key called _id.\n- You may find this answer helpful as well","metadata":{"transformedAt":"2026-08-18T18:32:29.145Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":3,"totalLines":111,"estimatedTokens":832}}588{"id":"stack-73671611","source":"stackoverflow","questionId":73671611,"title":"How to stream HTML content with static files using FastAPI?","tags":["python","streaming","fastapi","starlette"],"text":"Title: How to stream HTML content with static files using FastAPI?\nTags: python, streaming, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\n### Question\n\nHow to stream an HTML page with static files and hyperlinks from another service using FastAPI?\n\n### Additional Context\n\nA common architecture in micro-services is to have a gateway layer that implements a public API that passes requests to micro-services.\n\n```\n=============== Docker Network =============\n || ||\n || -------> Backend Service A ||\n || / ||\n || / ||\nExternal Request ===> Gateway Service * --------> Backend Service B ||\n || \\ ||\n || \\ ||\n || -------> Backend Service C ||\n || ||\n ============================================\n```\n\nIn case of FastAPI (which is not a `must` in my case), this solution worked great for APIs.\n\nI would go further and try use StreamingResponse to display HTML page with static files and hyperlinks generated dynamically.\n`RedirectResponse` will not work here, since services are not available outside of docker inner network.\nMentioned solution for API's isn't working neither, due to that static files and hyperlinks have links appropriate for inner service.\n\n========================================\n\nCode:\n```text\n=============== Docker Network =============\n || ||\n || -------> Backend Service A ||\n || / ||\n || / ||\nExternal Request ===> Gateway Service * --------> Backend Service B ||\n || \\ ||\n || \\ ||\n || -------> Backend Service C ||\n || ||\n ============================================\n```\n\n```text\nmust\n```\n\n```text\nRedirectResponse\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.responses import StreamingResponse\nfrom fastapi.staticfiles import StaticFiles\n\napp = FastAPI()\napp.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")\npath = \"index.html\"\n\n@app.get(\"/\")\ndef main():\n def iter_file():\n with open(path, 'rb') as f:\n yield from f\n\n return StreamingResponse(iter_file(), media_type=\"text/html\")\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.responses import StreamingResponse\nimport httpx\n\napp = FastAPI()\nurl = \"https://github.com/tiangolo/fastapi/issues/1788\"\n\n@app.get(\"/\")\ndef main():\n async def iter_url():\n async with httpx.AsyncClient() as client:\n async with client.stream(\"GET\", url) as r:\n async for chunk in r.aiter_bytes():\n yield chunk\n \n return StreamingResponse(iter_url(), media_type=\"text/html\")\n```\n\n```py\nfrom fastapi import FastAPI, Request\nfrom fastapi.responses import StreamingResponse\nimport httpx\nfrom urllib.parse import urljoin\n\napp = FastAPI()\nhost = \"http://127.0.0.1:9001\"\nstream_url = host + \"/stream\"\n\n@app.get(\"/stream\")\ndef main():\n async def iter_url():\n async with httpx.AsyncClient() as client:\n async with client.stream(\"GET\", stream_url) as r:\n async for chunk in r.aiter_bytes():\n yield chunk\n \n return StreamingResponse(iter_url(), media_type=\"text/html\")\n\n \n@app.get(\"/static-files/{_:path}\")\ndef get_resource(request: Request):\n async def iter_url(url):\n async with httpx.AsyncClient() as client:\n async with client.stream(\"GET\", url) as r:\n async for chunk in r.aiter_bytes():\n yield chunk\n \n url = urljoin(host, request.url.path)\n return StreamingResponse(iter_url(url))\n```\n\n```py\n@app.get(\"/subapi/{_:path}\")\n@app.get(\"/static-files/{_:path}\")\ndef get_resource(request: Request):\n ...\n```\n\n```py\n#...\n\n@app.get(\"/stream\")\n@app.get(\"/subapi/{_:path}\")\n@app.get(\"/static-files/{_:path}\")\ndef get_resource(request: Request):\n url = urljoin(host, request.url.path)\n return StreamingResponse(iter_url(url))\n```\n\n```py\nimport mimetypes\n...\nmt = mimetypes.guess_type(url) # url here includes a filename at the end\nif mt[0]:\n return StreamingResponse(iter_url(url), media_type=mt[0])\n```\n\n```py\nresult = magic.from_buffer(chunk, mime=True)\n```\n\n```text\nStreamingResponse\n```\n\n```text\nasync\n```\n\n```text\nopen()\n```\n\n```text\nStreamingResponse\n```\n\n```text\nmedia_type\n```\n\n```text\n\"text/html\"\n```\n\n```text\nStaticFiles\n```\n\n```text\ndirectory=\"static\"\n```\n\n```text\n\"/static\"\n```\n\n```text\nStaticFiles\n```\n\n```text\n\"/static\"\n```\n\n```text\n.html\n```\n\n```text\n<script src=\"/static/some_script.js\"></script>\n```\n\n```text\nyield from f\n```\n\n```text\nStreamingResponse\n```\n\n```text\nhttpx\n```\n\n```text\nasync\n```\n\n```text\nStaticFiles\n```\n\n```text\ndirectory\n```\n\n```text\n...StaticFiles(directory=\"path/to/service/static/folder\")\n```\n\n```text\nStaticFiles\n```\n\n```text\nStaticFiles\n```\n\n```text\n/static-files\n```\n\n```text\n<script src=\"/static-files/some_script.js\"></script>\n```\n\n```text\npath\n```\n\n```text\n\"/static-files/{_:path}\"\n```\n\n```text\n/test\n```\n\n```text\nAPIRouter\n```\n\n```text\n/subapi\n```\n\n```text\n<a href=\"/subapi/test\">Click here</a>\n```\n\n```text\niter_url()\n```\n\n```text\nmedia_type\n```\n\n```text\nStreamingResponse\n```\n\n```text\nmimetypes\n```\n\n```text\nStreamingResponse(iter_url(url))\n```\n\n```text\nmimetypes\n```\n\n```text\nmagic\n```\n\n```text\nmedia_type\n```\n\n========================================\n\nComments:\n- Thank you @Chris for answer:) Upper solution is working fine with online pages, but I can't make it work with HTML pages hosted on localhost. There are 2 problems. 1) HTML page is loaded without CSS files. I can see in web-browser console that static files are missing. 2) Generated hyperlinks aren't working as expected. Let's say that `http://0.0.0.0:9000/test/` doesn't exist and `http://0.0.0.0:9001/test/` does exist. Once i stream `http://0.0.0.0:9001/` over `http://0.0.0.0:9000/stream/`, the hyperlink redirects me to `http://0.0.0.0:9000/test/`, which is invalid.\n- Thank you @Chris, it's awesome that you spend time and solved the problem for me:)","metadata":{"transformedAt":"2026-08-18T18:32:29.145Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":48,"totalLines":315,"estimatedTokens":1593}}589{"id":"stack-68972093","source":"stackoverflow","questionId":68972093,"title":"How to get values from nested pydantic classes?","tags":["python","fastapi","pydantic"],"text":"Title: How to get values from nested pydantic classes?\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\n```\nclass mail(BaseModel):\n mailid: int\n email: str\n \nclass User(BaseModel):\n id: int\n name: str\n mails: List[mail]\n\ndata = {\n 'id': 123,\n 'name': 'Jane Doe',\n 'mails':[\n {'mailid':1,'email':'aeajhs@gmail.com'}, \n {'mailid':2,'email':'aeajhsds@gmail.com'}\n ]\n}\n \nuserobj = User(**data)\n```\n\nHow to get the value of `email` in `mail` class or `mailid` from `mail` class?\n\nWhen I try to use `print(mail.email)` it throws error as\n\n```\nAttributeError: type object 'mail' has no attribute 'email'\n```\n\nWhen I use this got error too\n\n```\nprint(userobj.mails.email)\n```\n\n```\nAttributeError: 'list' object has no attribute 'email'\n```\n\nWhen I use this I get data as follows\n\n```\nprint(userobj.mails)\n[mail(mailid=1, email='aeajhs@gmail.com'), mail(mailid=2, email='aeajhsds@gmail.com')]\n```\n\nMy desire output must be when I want to print email I must get `'aeajhs@gmail.com','aeajhsds@gmail.com'`\n\n========================================\n\nTop Answer:\nThe error\n\n```\nAttributeError: 'list' object has no attribute 'email'\n```\n\nmeans you are accessing an attribute of the `mails` list, not `mail` object.\n\nYou should pick the object from the list first using an index:\n\n```\nprint(userobj.mails[0].email)\n```\n\nAnd, if you want every email of every `mails` instance, do\n\n```\nprint([mail.email for mail in userobj.mails])\n```\n\n========================================\n\nCode:\n```py\nclass mail(BaseModel):\n mailid: int\n email: str\n \nclass User(BaseModel):\n id: int\n name: str\n mails: List[mail]\n\ndata = {\n 'id': 123,\n 'name': 'Jane Doe',\n 'mails':[\n {'mailid':1,'email':'aeajhs@gmail.com'}, \n {'mailid':2,'email':'aeajhsds@gmail.com'}\n ]\n}\n \nuserobj = User(**data)\n```\n\n```none\nAttributeError: type object 'mail' has no attribute 'email'\n```\n\n```py\nprint(userobj.mails.email)\n```\n\n```none\nAttributeError: 'list' object has no attribute 'email'\n```\n\n```py\nprint(userobj.mails)\n[mail(mailid=1, email='aeajhs@gmail.com'), mail(mailid=2, email='aeajhsds@gmail.com')]\n```\n\n```text\nemail\n```\n\n```text\nmail\n```\n\n```text\nmailid\n```\n\n```text\nmail\n```\n\n```text\nprint(mail.email)\n```\n\n```text\n'aeajhs@gmail.com','aeajhsds@gmail.com'\n```\n\n```py\nfrom pydantic import BaseModel\nfrom typing import List\n\nclass Mail(BaseModel):\n mailid: int\n email: str\n\none_mail = {\"mailid\": 1, \"email\": \"aeajhs@gmail.com\"}\n\nmail = Mail(**one_mail)\n\nprint(mail)\n# mailid=1 email='aeajhs@gmail.com'\n```\n\n```py\nclass User(BaseModel):\n id: int\n name: str\n mails: List[Mail]\n\ndata = {\n \"id\": 123, \n \"name\": \"Jane Doe\",\n \"mails\":[\n {\"mailid\": 1, \"email\": \"aeajhs@gmail.com\"}, \n {\"mailid\": 2, \"email\": \"aeajhsds@gmail.com\"}\n ]\n}\n\nuserobj = User(**data)\n\nprint(userobj.mails)\n# [Mail(mailid=1, email='aeajhs@gmail.com'), Mail(mailid=2, email='aeajhsds@gmail.com')]\n```\n\n```py\nprint(userobj.mails[0].email)\n# aeajhs@gmail.com\n```\n\n```py\nprint([mail.email for mail in userobj.mails])\n# ['aeajhs@gmail.com', 'aeajhsds@gmail.com']\n```\n\n```text\nUser\n```\n\n```text\nmails\n```\n\n```text\nAttributeError: 'list' object has no attribute 'email'\n```\n\n```text\nprint(userobj.mails[0].email)\n```\n\n```text\nprint([mail.email for mail in userobj.mails])\n```\n\n```text\nmails\n```\n\n```text\nmail\n```\n\n```text\nmails\n```\n\n========================================\n\nComments:\n- can i get mails as dictonary\n- Interesting! I tried it with only pure `dataclasses` and it does not work the same, the `userobj.mails[0]` is a simple dict. Only the Pydantic seems to do the casting to the `Mail` class.","metadata":{"transformedAt":"2026-08-18T18:32:29.145Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":23,"totalLines":227,"estimatedTokens":906}}590{"id":"stack-73460583","source":"stackoverflow","questionId":73460583,"title":"Docker Port Forwarding for FastAPI REST API","tags":["docker","port","fastapi"],"text":"Title: Docker Port Forwarding for FastAPI REST API\nTags: docker, port, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have a simple FastAPI project called `toyrest` that runs a trivial API. The code looks like this.\n\n```\nfrom fastapi import FastAPI\n\n__version__ = \"1.0.0\"\n\napp = FastAPI()\n\n@app.get(\"/\")\ndef root():\n return \"hello\"\n```\n\nI've built the usual Python package infrastructure around it. I can install the package. If I run `uvicorn toyrest:app` the server launches on port 8000 and everything works.\n\nNow I'm trying to get this to run in a Docker image. I have the following Dockerfile.\n\n```\n# syntax=docker/dockerfile:1\n\nFROM python:3\n\n# Create a user.\nRUN useradd --user-group --system --create-home --no-log-init user\nUSER user\nENV PATH=/home/user/.local/bin:$PATH\n\n# Install the API.\nWORKDIR /home/user\nCOPY --chown=user:user . ./toyrest\nRUN python -m pip install --upgrade pip && \\\n pip install -r toyrest/requirements.txt\nRUN pip install toyrest/ && \\\n rm -rf /home/user/toyrest\n\nCMD [\"uvicorn\", \"toyrest:app\"]\n```\n\nI build the Docker image and run it, forwarding port 8000 to the running container.\n\n```\ndocker run -p 8000:8000 toyrest:1.0.0\nINFO: Started server process [1]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\nINFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\n```\n\nWhen I try to connect to `http://127.0.0.1:8000/` I get no response.\n\nPresumably I am doing the port forwarding incorrectly. I've tried various permutations of the port forwarding argument (e.g. `-p 8000`, `-p 127.0.0.1:8000:8000`) to no avail.\n\nThis is such a basic Docker command that I can't see how I'm getting it wrong, but somehow I am. What am I doing wrong?\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\n\n__version__ = \"1.0.0\"\n\napp = FastAPI()\n\n\n@app.get(\"/\")\ndef root():\n return \"hello\"\n```\n\n```text\n# syntax=docker/dockerfile:1\n\nFROM python:3\n\n# Create a user.\nRUN useradd --user-group --system --create-home --no-log-init user\nUSER user\nENV PATH=/home/user/.local/bin:$PATH\n\n# Install the API.\nWORKDIR /home/user\nCOPY --chown=user:user . ./toyrest\nRUN python -m pip install --upgrade pip && \\\n pip install -r toyrest/requirements.txt\nRUN pip install toyrest/ && \\\n rm -rf /home/user/toyrest\n\n\nCMD [\"uvicorn\", \"toyrest:app\"]\n```\n\n```text\ndocker run -p 8000:8000 toyrest:1.0.0\nINFO: Started server process [1]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\nINFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\n```\n\n```text\ntoyrest\n```\n\n```text\nuvicorn toyrest:app\n```\n\n```text\nhttp://127.0.0.1:8000/\n```\n\n```text\n-p 8000\n```\n\n```text\n-p 127.0.0.1:8000:8000\n```\n\n```text\nCMD [\"uvicorn\", \"toyrest:app\",\"--host\", \"0.0.0.0\"]\n```\n\n```text\nCMD\n```\n\n========================================\n\nComments:\n- The app is listening on the loopback interface, inside the container. You cannot expose this by publishing a port. You need to bind to the private network interface, preferably using 0.0.0.0.\n- Please explain what you are doing and why.\n- Thanks. Adding \"--host 0.0.0.0\" to the CMD works. Why is it necessary though?\n- well I m not very good in docker but as i know the docker container have his own network so the `uvicorn` server inside the docker re listening to the docker nertwork `localhost` so when you try to communicate with the `uvicorn` from outside the container you re not using the same `localhost` runing `uvicorn`on `0.0.0.0` can solve the problem you can check this answer stackoverflow.com/a/20778887/18317391\n- This answer might prove helpful to future readers as well.","metadata":{"transformedAt":"2026-08-18T18:32:29.145Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":10,"totalLines":142,"estimatedTokens":911}}591{"id":"stack-76533018","source":"stackoverflow","questionId":76533018,"title":"Unit Tests in FastAPI","tags":["pytest","fastapi","sqlmodel"],"text":"Title: Unit Tests in FastAPI\nTags: pytest, fastapi, sqlmodel\nSource: Stack Overflow\n\nQuestion:\nI have a backend app developed with FastAPI, using SQLModel (SQLAlchemy & Pydantic) and connected to a Postgres database.\nI have integration tests to test if my endpoints are working fine with a stagging PG DB.\nBut right now I have to write units tests and I don't know how to proceed to test my endpoints and the functions called in a isolated way.\n\nHere is a really simplified version of my project:\n\nThe **architecture of my project**: (Consider that there is an __ init__.py file in each folder)\n\n```\napp/\n├── api/\n│ ├── core/\n│ │ ├── config.py #get the env settings and distribute it to the app\n│ │ ├── .env\n│ ├── crud/\n│ │ ├── items.py #the CRUD functions called by the router\n│ ├── db/\n│ │ ├── session.py #the get_session function handling the db engine\n│ ├── models/\n│ │ ├── items.py #the SQLModel object def as is in the db\n│ ├── routers/\n│ │ ├── items.py #the routing system\n│ ├── schemas/\n│ │ ├── items.py #the python object def as it is used in the app\n│ ├── main.py #the main app\n├── tests/ #the pytest tests\n│ ├── unit_tests/\n│ ├── integration_tests/\n│ │ ├── test_items.py\n```\n\nIn the **crud/items.py**:\n\n```\nfrom fastapi.encoders import jsonable_encoder\nfrom sqlmodel import Session, select\nfrom api.models import Item\nfrom api.schemas import ItemCreate\n\ndef get_item(db_session: Session, item_id: int) -> Item:\n query = select(Item).where(Item.id == item_id)\n return db_session.exec(query).first()\n\ndef create_new_item(db_session: Session, *, obj_input: ItemCreate) -> Item:\n obj_in_data = jsonable_encoder(obj_input)\n db_obj = Item(**obj_in_data)\n db_session.add(db_obj)\n db_session.commit()\n db_session.refresh(db_obj)\n return db_obj\n```\n\nIn the **db/session.py**:\n\n```\nfrom sqlalchemy.engine import Engine\nfrom sqlmodel import create_engine, Session\nfrom api.core.config import settings\n\nengine: Engine = create_engine(settings.SQLALCHEMY_DATABASE_URI, pool_pre_ping=True)\n\ndef get_session() -> Session:\n with Session(engine) as session:\n yield session\n```\n\nIn the **models/items.py**:\n\n```\nfrom sqlmodel import SQLModel, Field, MetaData\n\nmeta = MetaData(schema=\"pouetpouet\") # https://github.com/tiangolo/sqlmodel/issues/20\n\nclass Item(SQLModel, table=True):\n __tablename__ = \"cities\"\n # __table_args__ = {\"schema\": \"pouetpouet\"}\n metadata = meta\n\n id: int = Field(primary_key=True, default=None)\n city_name: str\n```\n\nIn the **routers/items.py**:\n\n```\nfrom fastapi import APIRouter, Depends, HTTPException\nfrom sqlmodel import Session\nfrom api.crud import get_item, create_new_item\nfrom api.db.session import get_session\nfrom api.models import Item\nfrom api.schemas import ItemRead, ItemCreate\n\nrouter = APIRouter(prefix=\"/api/items\", tags=[\"Items\"])\n\n@router.get(\"/{item_id}\", response_model=ItemRead)\ndef read_item(\n *,\n db_session: Session = Depends(get_session),\n item_id: int,\n) -> Item:\n item = get_item(db_session=db_session, item_id=item_id)\n if not item:\n raise HTTPException(status_code=404, detail=\"Item not found\")\n return item\n\n@router.post(\"/\", response_model=ItemRead)\ndef create_item(\n *,\n db_session: Session = Depends(get_session),\n item_input: ItemCreate,\n) -> Item:\n item = create_new_item(db_session=db_session, obj_input=item_input)\n return item\n```\n\nIn the **schemas/items.py**:\n\n```\nfrom typing import Optional\nfrom sqlmodel import SQLModel\n\nclass ItemBase(SQLModel):\n city_name: Optional[str] = None\n\nclass ItemCreate(ItemBase):\n pass\n\nclass ItemRead(ItemBase):\n id: int\n class Config:\n orm_mode: True\n```\n\nIn the **tests/integration_tests/test_items.py**:\n\n```\nfrom fastapi.testclient import TestClient\nfrom api.main import app\n\nclient = TestClient(app)\n\ndef test_create_item() -> None:\n data = {\"city_name\": \"Las Vegas\"}\n response = client.post(\"/api/items/\", json=data)\n assert response.status_code == 200\n content = response.json()\n assert content[\"city_name\"] == data[\"city_name\"]\n assert \"id\" in content\n```\n\nThe point here is that I feel stuck with the `db_session: Session` argument used in all the functions in the crud/items.py and the routers/items.py because I think it is mandatory to get a valid session of a valid postgres connexion for the tests.\n\nps: not being very experienced in backend development, do not hesitate to bring constructive remarks about my code if you notice something strange. It will be very well received.\n\n========================================\n\nCode:\n```text\napp/\n├── api/\n│ ├── core/\n│ │ ├── config.py #get the env settings and distribute it to the app\n│ │ ├── .env\n│ ├── crud/\n│ │ ├── items.py #the CRUD functions called by the router\n│ ├── db/\n│ │ ├── session.py #the get_session function handling the db engine\n│ ├── models/\n│ │ ├── items.py #the SQLModel object def as is in the db\n│ ├── routers/\n│ │ ├── items.py #the routing system\n│ ├── schemas/\n│ │ ├── items.py #the python object def as it is used in the app\n│ ├── main.py #the main app\n├── tests/ #the pytest tests\n│ ├── unit_tests/\n│ ├── integration_tests/\n│ │ ├── test_items.py\n```\n\n```text\nfrom fastapi.encoders import jsonable_encoder\nfrom sqlmodel import Session, select\nfrom api.models import Item\nfrom api.schemas import ItemCreate\n\n\ndef get_item(db_session: Session, item_id: int) -> Item:\n query = select(Item).where(Item.id == item_id)\n return db_session.exec(query).first()\n\n\ndef create_new_item(db_session: Session, *, obj_input: ItemCreate) -> Item:\n obj_in_data = jsonable_encoder(obj_input)\n db_obj = Item(**obj_in_data)\n db_session.add(db_obj)\n db_session.commit()\n db_session.refresh(db_obj)\n return db_obj\n```\n\n```text\nfrom sqlalchemy.engine import Engine\nfrom sqlmodel import create_engine, Session\nfrom api.core.config import settings\n\nengine: Engine = create_engine(settings.SQLALCHEMY_DATABASE_URI, pool_pre_ping=True)\n\n\ndef get_session() -> Session:\n with Session(engine) as session:\n yield session\n```\n\n```text\nfrom sqlmodel import SQLModel, Field, MetaData\n\nmeta = MetaData(schema=\"pouetpouet\") # https://github.com/tiangolo/sqlmodel/issues/20\n\n\nclass Item(SQLModel, table=True):\n __tablename__ = \"cities\"\n # __table_args__ = {\"schema\": \"pouetpouet\"}\n metadata = meta\n\n id: int = Field(primary_key=True, default=None)\n city_name: str\n```\n\n```text\nfrom fastapi import APIRouter, Depends, HTTPException\nfrom sqlmodel import Session\nfrom api.crud import get_item, create_new_item\nfrom api.db.session import get_session\nfrom api.models import Item\nfrom api.schemas import ItemRead, ItemCreate\n\nrouter = APIRouter(prefix=\"/api/items\", tags=[\"Items\"])\n\n\n@router.get(\"/{item_id}\", response_model=ItemRead)\ndef read_item(\n *,\n db_session: Session = Depends(get_session),\n item_id: int,\n) -> Item:\n item = get_item(db_session=db_session, item_id=item_id)\n if not item:\n raise HTTPException(status_code=404, detail=\"Item not found\")\n return item\n\n\n@router.post(\"/\", response_model=ItemRead)\ndef create_item(\n *,\n db_session: Session = Depends(get_session),\n item_input: ItemCreate,\n) -> Item:\n item = create_new_item(db_session=db_session, obj_input=item_input)\n return item\n```\n\n```text\nfrom typing import Optional\nfrom sqlmodel import SQLModel\n\n\nclass ItemBase(SQLModel):\n city_name: Optional[str] = None\n\n\nclass ItemCreate(ItemBase):\n pass\n\nclass ItemRead(ItemBase):\n id: int\n class Config:\n orm_mode: True\n```\n\n```text\nfrom fastapi.testclient import TestClient\nfrom api.main import app\n\nclient = TestClient(app)\n\ndef test_create_item() -> None:\n data = {\"city_name\": \"Las Vegas\"}\n response = client.post(\"/api/items/\", json=data)\n assert response.status_code == 200\n content = response.json()\n assert content[\"city_name\"] == data[\"city_name\"]\n assert \"id\" in content\n```\n\n```text\ndb_session: Session\n```\n\n```py\nfrom sqlmodel import Field, SQLModel, Session\n\n\nclass ItemCreate(SQLModel):\n x: str\n y: float\n\n\nclass Item(ItemCreate, table=True):\n id: int | None = Field(primary_key=True)\n\n\ndef create_new_item(db_session: Session, *, obj_input: ItemCreate) -> Item:\n db_obj = Item.from_orm(obj_input)\n db_session.add(db_obj)\n db_session.commit()\n db_session.refresh(db_obj)\n return db_obj\n```\n\n```py\nfrom unittest import TestCase\nfrom unittest.mock import call, create_autospec\n\nfrom sqlmodel import Session\n\n# ... import Item, ItemCreate\n\n\nclass MyTestCase(TestCase):\n def test_create_new_item(self) -> None:\n test_item = ItemCreate(x=\"foo\", y=3.14)\n mock_session = create_autospec(Session, instance=True)\n\n expected_output = Item.from_orm(test_item)\n expected_session_calls = [\n call.add(expected_output),\n call.commit(),\n call.refresh(expected_output),\n ]\n\n output = create_new_item(mock_session, obj_input=test_item)\n self.assertEqual(expected_output, output)\n self.assertListEqual(expected_session_calls, mock_session.mock_calls)\n```\n\n```py\nfrom unittest import TestCase\nfrom unittest.mock import MagicMock, call, create_autospec, patch\n\nfrom sqlmodel import Session\n\n# ... import Item\n\n\nclass MyTestCase(TestCase):\n @patch.object(Item, \"from_orm\")\n def test_create_new_item2(self, mock_from_orm: MagicMock) -> None:\n test_item = MagicMock()\n mock_session = create_autospec(Session, instance=True)\n\n expected_output = mock_from_orm.return_value = object()\n expected_session_calls = [\n call.add(expected_output),\n call.commit(),\n call.refresh(expected_output),\n ]\n\n output = create_new_item(mock_session, obj_input=test_item)\n self.assertEqual(expected_output, output)\n self.assertListEqual(expected_session_calls, mock_session.mock_calls)\n```\n\n```py\nfrom unittest import TestCase\n\nfrom sqlmodel import SQLModel, Session, create_engine, select\n\n# ... import Item, ItemCreate\n\n\nclass MyTestCase(TestCase):\n def test_create_new_item3(self) -> None:\n engine = create_engine(\"sqlite:///\")\n SQLModel.metadata.create_all(engine)\n\n test_item = ItemCreate(x=\"foo\", y=3.14)\n expected_output = Item(**test_item.dict(), id=1)\n\n with Session(engine) as session:\n output = create_new_item(session, obj_input=test_item)\n self.assertEqual(expected_output, output)\n result = session.exec(select(Item)).all()\n self.assertListEqual([expected_output], result)\n```\n\n```text\ncreate_new_item\n```\n\n```text\ncreate_new_item\n```\n\n```text\nItem\n```\n\n```text\nItemCreate\n```\n\n========================================\n\nComments:\n- This is typically done using FastAPI's depencency overrides, where you create a new dependency that connects to your test database, and override `get_session` with that.\n- @M.O. No, this is not the purpose here ! I'd like to test it in an isolated way ! Without using another DB connexion as explained in this FastAPI doc\n- I think that the suggested approach is the one that match with my needs ! Thanks a lot for your time all those explanations !","metadata":{"transformedAt":"2026-08-18T18:32:29.145Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":16,"totalLines":423,"estimatedTokens":2780}}592{"id":"stack-66931694","source":"stackoverflow","questionId":66931694,"title":"Alembic migrations in ormar not working (FastAPI)","tags":["postgresql","database-migration","fastapi","python-3.9","ormar"],"text":"Title: Alembic migrations in ormar not working (FastAPI)\nTags: postgresql, database-migration, fastapi, python-3.9, ormar\nSource: Stack Overflow\n\nQuestion:\nI want to migrate through Alembic, but something doesn't work. I don't understand what exactly I'm doing wrong.\n\nMy alembic .env\n\n```\nfrom logging.config import fileConfig\n\nfrom sqlalchemy import create_engine\nfrom sqlalchemy import engine_from_config\nfrom sqlalchemy import pool\nfrom db import ORMAR_DATABASE_URL\nfrom alembic import context\nimport sys, os\n\nsys.path.append(os.getcwd())\nconfig = context.config\n\nfileConfig(config.config_file_name)\n\nfrom db import Base\ntarget_metadata = Base.metadata\nURL = \"postgresql://admin:admin@localhost/fa_naesmi\"\n\ndef run_migrations_offline():\n\ncontext.configure(\n url=URL,\n target_metadata=target_metadata,\n literal_binds=True,\n dialect_opts={\"paramstyle\": \"named\"},\n user_module_prefix='sa.'\n)\n\nwith context.begin_transaction():\n context.run_migrations()\n\ndef run_migrations_online():\nconnectable = create_engine(URL)\n\nwith connectable.connect() as connection:\n context.configure(\n connection=connection,\n target_metadata=target_metadata,\n user_module_prefix='sa.'\n )\n\n with context.begin_transaction():\n context.run_migrations()\n\nif context.is_offline_mode():\n run_migrations_offline()\nelse:\n run_migrations_online()\n```\n\nmy db.py file:\n\n```\nimport sqlalchemy\nimport databases\nfrom sqlalchemy.ext.declarative import declarative_base\nORMAR_DATABASE_URL = \"postgresql://admin:admin@localhost/fa_naesmi\"\n\nBase = declarative_base()\nmetadata = sqlalchemy.MetaData()\ndatabase = databases.Database(ORMAR_DATABASE_URL)\nengine = sqlalchemy.create_engine(ORMAR_DATABASE_URL)\n```\n\nand my `models.py`:\n\n```\nimport datetime\nimport ormar\nfrom typing import Optional\nfrom db import database, metadata, Base\n\nclass MainMeta(Base, ormar.ModelMeta):\n metadata = metadata\n database = database\n\nclass Category(Base, ormar.Model):\n class Meta(MainMeta):\n pass\n\n id: int = ormar.Integer(primary_key=True)\n name: str = ormar.String(max_length=100)\n```\n\nafter using `alembic revision -m \"first\"`, it doesn't migrate my models.\n\n```\nrevision = '9176fb20d67a'\ndown_revision = '9159cff21eb5'\nbranch_labels = None\ndepends_on = None\n\ndef upgrade():\n pass\n\ndef downgrade():\n pass\n```\n\nI already wrote in console `alembic revision --autogenerate -m \"razraz\"` and it creates alembic database tables, but migrations still not working.\n\n========================================\n\nCode:\n```text\nfrom logging.config import fileConfig\n\nfrom sqlalchemy import create_engine\nfrom sqlalchemy import engine_from_config\nfrom sqlalchemy import pool\nfrom db import ORMAR_DATABASE_URL\nfrom alembic import context\nimport sys, os\n\nsys.path.append(os.getcwd())\nconfig = context.config\n\nfileConfig(config.config_file_name)\n\nfrom db import Base\ntarget_metadata = Base.metadata\nURL = \"postgresql://admin:admin@localhost/fa_naesmi\"\n\n\n\ndef run_migrations_offline():\n\n\ncontext.configure(\n url=URL,\n target_metadata=target_metadata,\n literal_binds=True,\n dialect_opts={\"paramstyle\": \"named\"},\n user_module_prefix='sa.'\n)\n\nwith context.begin_transaction():\n context.run_migrations()\n\n\ndef run_migrations_online():\nconnectable = create_engine(URL)\n\nwith connectable.connect() as connection:\n context.configure(\n connection=connection,\n target_metadata=target_metadata,\n user_module_prefix='sa.'\n )\n\n with context.begin_transaction():\n context.run_migrations()\n\n\nif context.is_offline_mode():\n run_migrations_offline()\nelse:\n run_migrations_online()\n```\n\n```text\nimport sqlalchemy\nimport databases\nfrom sqlalchemy.ext.declarative import declarative_base\nORMAR_DATABASE_URL = \"postgresql://admin:admin@localhost/fa_naesmi\"\n\nBase = declarative_base()\nmetadata = sqlalchemy.MetaData()\ndatabase = databases.Database(ORMAR_DATABASE_URL)\nengine = sqlalchemy.create_engine(ORMAR_DATABASE_URL)\n```\n\n```text\nimport datetime\nimport ormar\nfrom typing import Optional\nfrom db import database, metadata, Base\n\n\nclass MainMeta(Base, ormar.ModelMeta):\n metadata = metadata\n database = database\n\n\nclass Category(Base, ormar.Model):\n class Meta(MainMeta):\n pass\n\n id: int = ormar.Integer(primary_key=True)\n name: str = ormar.String(max_length=100)\n```\n\n```text\nrevision = '9176fb20d67a'\ndown_revision = '9159cff21eb5'\nbranch_labels = None\ndepends_on = None\n\ndef upgrade():\n pass\n\n\ndef downgrade():\n pass\n```\n\n```text\nmodels.py\n```\n\n```text\nalembic revision -m \"first\"\n```\n\n```text\nalembic revision --autogenerate -m \"razraz\"\n```\n\n```py\nfrom logging.config import fileConfig\nfrom sqlalchemy import create_engine\n\nfrom db import ORMAR_DATABASE_URL\nfrom models import metadata # adjust path if needed\nfrom alembic import context\nimport sys, os\n\nsys.path.append(os.getcwd())\nconfig = context.config\n\nfileConfig(config.config_file_name)\n\n# note how it's 'raw' metadata not the one attached to Base as there is no Base\ntarget_metadata = metadata\nURL = ORMAR_DATABASE_URL\n\n\ndef run_migrations_offline():\n\n\ncontext.configure(\n url=URL,\n target_metadata=target_metadata,\n literal_binds=True,\n dialect_opts={\"paramstyle\": \"named\"},\n user_module_prefix='sa.'\n)\n\nwith context.begin_transaction():\n context.run_migrations()\n\n\ndef run_migrations_online():\nconnectable = create_engine(URL)\n\nwith connectable.connect() as connection:\n context.configure(\n connection=connection,\n target_metadata=target_metadata,\n user_module_prefix='sa.'\n )\n\n with context.begin_transaction():\n context.run_migrations()\n\n\nif context.is_offline_mode():\n run_migrations_offline()\nelse:\n run_migrations_online()\n```\n\n```py\nimport sqlalchemy\nimport databases\nORMAR_DATABASE_URL = \"postgresql://admin:admin@localhost/fa_naesmi\"\n\n# note lack of declarative_base\nmetadata = sqlalchemy.MetaData()\ndatabase = databases.Database(ORMAR_DATABASE_URL)\nengine = sqlalchemy.create_engine(ORMAR_DATABASE_URL)\n```\n\n```py\nimport datetime\nimport ormar\nfrom typing import Optional\nfrom db import database, metadata\n\n\n# you cannot subclass Base class thats ORM part\nclass MainMeta(ormar.ModelMeta):\n metadata = metadata\n database = database\n\n\nclass Category(ormar.Model):\n class Meta(MainMeta):\n pass\n\n id: int = ormar.Integer(primary_key=True)\n name: str = ormar.String(max_length=100)\n```\n\n```text\ndeclarative_base()\n```\n\n```text\nsqlalchemy\n```\n\n```text\nSqlalchemy\n```\n\n```text\nORM\n```\n\n```text\ncore\n```\n\n```text\normar\n```\n\n```text\nORM\n```\n\n```text\normar\n```\n\n```text\nasync\n```\n\n```text\npydantic\n```\n\n```text\nORM\n```\n\n```text\nBase\n```\n\n```text\normar\n```\n\n========================================\n\nComments:\n- by the way about this, it migrates only the models of the main directory, does not look at the subfolders where other models are also located.\n- Yes! it worked! Thanks! My main mistake was that since ormar uses sqlalchemy under the hood, it will work on ormar itself. I want to thank you for creating this beautiful orm! it is very easy to use and not only! I have a big project ahead of me on this orm! and I would like to ask about the integration of graphql into ormar, are there any sources on this topic? I can't find it on the net. found on sqlalchemy but now I doubt that it will work. Or is it not related to orm but specifically to the framework?\n- No the ones for sqlalchemy won't work since you probably found graphene related info, and graphene won't work as it is a sync framework, you would have to use tartiflette or something else with async support. But there is no \"helper\" for any library/orm I think as of now\n- The key point for me was that we must import the models definitions themselves, because they actually \"populate\" the metadata. If you just import the metadata object without the models, it's empty, and the revisions are either empty or inverted (trying to drop tables instead of creating them).","metadata":{"transformedAt":"2026-08-18T18:32:29.146Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":23,"totalLines":373,"estimatedTokens":1970}}593{"id":"stack-63415152","source":"stackoverflow","questionId":63415152,"title":"FastAPI with aiocache and Redis Couldn't set databases.backends.postgres.Record object","tags":["python","docker","docker-compose","redis","fastapi"],"text":"Title: FastAPI with aiocache and Redis Couldn't set databases.backends.postgres.Record object\nTags: python, docker, docker-compose, redis, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm trying to implement Redis on my endpoint using the aiocache library.\nThe first test I did with aiocache I used @cache without indicating any other service and everything worked. But when I tried to use Redis I see this error (the endpoint still returns the request)\n\n```\nERROR: Couldn't set [, , ] in key app.api.authorget_authors()[], unexpected error\nTraceback (most recent call last):\n File \"/usr/local/lib/python3.8/site-packages/aiocache/decorators.py\", line 144, in set_in_cache\n await self.cache.set(key, value, ttl=self.ttl)\n File \"/usr/local/lib/python3.8/site-packages/aiocache/base.py\", line 61, in _enabled\n return await func(*args, **kwargs)\n File \"/usr/local/lib/python3.8/site-packages/aiocache/base.py\", line 45, in _timeout\n return await asyncio.wait_for(func(self, *args, **kwargs), timeout)\n File \"/usr/local/lib/python3.8/asyncio/tasks.py\", line 483, in wait_for\n return fut.result()\n File \"/usr/local/lib/python3.8/site-packages/aiocache/base.py\", line 75, in _plugins\n ret = await func(self, *args, **kwargs)\n File \"/usr/local/lib/python3.8/site-packages/aiocache/base.py\", line 265, in set\n ns_key, dumps(value), ttl=self._get_ttl(ttl), _cas_token=_cas_token, _conn=_conn\n File \"/usr/local/lib/python3.8/site-packages/aiocache/serializers/serializers.py\", line 140, in dumps\n return json.dumps(value)\nTypeError: is not JSON serializable\n```\n\nThe method is:\n\n```\n@authors.get(\"/\", response_model=List[AuthorOut]) \n@cached( \n ttl=100, \n cache=Cache.REDIS,\n endpoint=\"X.X.X.X\", #my local ip\n serializer=JsonSerializer(),\n port=6379,\n namespace=\"main\",\n #key=\"key\",\n )\nasync def get_authors():\n return await db_manager.get_all_authors()\n```\n\nThe whole environment is based on docker, 2 containers, 1 FastApi, 1 PostgreSQL and 1 Redis.\n\nIt seems evident that there is a problem with the object returned by the endpoint, so I ask you how can I pass such a complex object to Redis?\n\nFollowing the aiochace documentation I have tried all the serializers present but without success.\n\nMy docker-compose\n\n```\nversion: '3.7'\n\nservices:\n book_service:\n build: ./book-service\n command: uvicorn app.main:app --reload --host 0.0.0.0 --port 8000\n volumes:\n - ./book-service/:/app/\n ports:\n - 8001:8000\n environment:\n - DATABASE_URI=postgresql://book_db_username:book_db_password@book_db/book_db_dev\n - AUTHOR_SERVICE_HOST_URL=http://author_service:8000/api/v1/authors/\n depends_on:\n - book_db\n\n book_db:\n image: postgres:12.1-alpine\n volumes:\n - postgres_data_book:/var/lib/postgresql/data/\n environment:\n - POSTGRES_USER=book_db_username\n - POSTGRES_PASSWORD=book_db_password\n - POSTGRES_DB=book_db_dev\n \n author_service:\n build: ./author-service\n command: uvicorn app.main:app --reload --host 0.0.0.0 --port 8000\n volumes:\n - ./author-service/:/app/\n ports:\n - 8002:8000\n environment:\n - DATABASE_URI=postgresql://author_db_username:author_db_password@author_db/author_db_dev\n depends_on:\n - author_db\n\n author_db:\n image: postgres:12.1-alpine\n volumes:\n - postgres_data_author:/var/lib/postgres/data\n environment:\n - POSTGRES_USER=author_db_username\n - POSTGRES_PASSWORD=author_db_password\n - POSTGRES_DB=author_db_dev\n\n nginx:\n image: nginx:latest\n ports:\n - \"8080:8080\"\n volumes:\n - ./nginx_config.conf:/etc/nginx/conf.d/default.conf\n depends_on:\n - author_service\n - book_service\n\n redis:\n image: redis:3.2-alpine\n volumes:\n # - redis_data:/data\n - ./redis.conf:/usr/local/etc/redis/redis.conf\n command: redis-server /usr/local/etc/redis/redis.conf\n ports:\n - 6379:6379\n\n networks:\n node_net:\n ipv4_address: 172.28.1.4\n\nnetworks:\n node_net:\n ipam:\n driver: default\n config:\n - subnet: 172.28.0.0/16\n\nvolumes:\n postgres_data_book:\n postgres_data_author:\n redis_data:\n```\n\n========================================\n\nTop Answer:\n**You can use redis_cache to access with RedisDB**\n\nconnection.py\n\n```\nfrom typing import Optional\n\nfrom aioredis import Redis, create_redis_pool\n\n#Create a RedisCache instance\nclass RedisCache:\n \n def __init__(self):\n self.redis_cache: Optional[Redis] = None\n \n async def init_cache(self):\n self.redis_cache = await create_redis_pool(\"redis://localhost:6379/0?encoding=utf-8\") #Connecting to database\n\n async def keys(self, pattern):\n return await self.redis_cache.keys(pattern)\n\n async def set(self, key, value):\n return await self.redis_cache.set(key, value)\n \n async def get(self, key):\n return await self.redis_cache.get(key)\n\n \n async def close(self):\n self.redis_cache.close()\n await self.redis_cache.wait_closed()\n\nredis_cache = RedisCache()\n```\n\nmain.py\n\n```\nfrom fastapi import FastAPI, applications\nfrom uvicorn import run\nfrom fastapi import FastAPI, Request, Response\nfrom connection import redis_cache\n\napp = FastAPI(title=\"FastAPI with Redis\")\n\nasync def get_all():\n return await redis_cache.keys('*')\n\n@app.on_event('startup')\nasync def starup_event():\n await redis_cache.init_cache()\n\n@app.on_event('shutdown')\nasync def shutdown_event():\n redis_cache.close()\n await redis_cache.wait_closed()\n\n#root\n@app.get(\"/\")\ndef read_root():\n return {\"Redis\": \"FastAPI\"}\n\n#root > Get all keys from the redis DB\n@app.get('/RedisKeys')\nasync def redis_keys():\n return await get_all()\n\nif __name__ == '__main__':\n run(\"main:app\", port=3000, reload=True)\n```\n\nI am using uvicorn to access:\n\n```\nuvicorn main:app --reload\n```\n\n========================================\n\nCode:\n```text\nERROR: Couldn't set [<databases.backends.postgres.Record object at 0x7fb9f01d86a0>, <databases.backends.postgres.Record object at 0x7fb9f01d88b0>, <databases.backends.postgres.Record object at 0x7fb9f01d8a60>] in key app.api.authorget_authors()[], unexpected error\nTraceback (most recent call last):\n File \"/usr/local/lib/python3.8/site-packages/aiocache/decorators.py\", line 144, in set_in_cache\n await self.cache.set(key, value, ttl=self.ttl)\n File \"/usr/local/lib/python3.8/site-packages/aiocache/base.py\", line 61, in _enabled\n return await func(*args, **kwargs)\n File \"/usr/local/lib/python3.8/site-packages/aiocache/base.py\", line 45, in _timeout\n return await asyncio.wait_for(func(self, *args, **kwargs), timeout)\n File \"/usr/local/lib/python3.8/asyncio/tasks.py\", line 483, in wait_for\n return fut.result()\n File \"/usr/local/lib/python3.8/site-packages/aiocache/base.py\", line 75, in _plugins\n ret = await func(self, *args, **kwargs)\n File \"/usr/local/lib/python3.8/site-packages/aiocache/base.py\", line 265, in set\n ns_key, dumps(value), ttl=self._get_ttl(ttl), _cas_token=_cas_token, _conn=_conn\n File \"/usr/local/lib/python3.8/site-packages/aiocache/serializers/serializers.py\", line 140, in dumps\n return json.dumps(value)\nTypeError: <databases.backends.postgres.Record object at 0x7fb9f01d8a60> is not JSON serializable\n```\n\n```py\n@authors.get(\"/\", response_model=List[AuthorOut]) \n@cached( \n ttl=100, \n cache=Cache.REDIS,\n endpoint=\"X.X.X.X\", #my local ip\n serializer=JsonSerializer(),\n port=6379,\n namespace=\"main\",\n #key=\"key\",\n )\nasync def get_authors():\n return await db_manager.get_all_authors()\n```\n\n```text\nversion: '3.7'\n\nservices:\n book_service:\n build: ./book-service\n command: uvicorn app.main:app --reload --host 0.0.0.0 --port 8000\n volumes:\n - ./book-service/:/app/\n ports:\n - 8001:8000\n environment:\n - DATABASE_URI=postgresql://book_db_username:book_db_password@book_db/book_db_dev\n - AUTHOR_SERVICE_HOST_URL=http://author_service:8000/api/v1/authors/\n depends_on:\n - book_db\n\n book_db:\n image: postgres:12.1-alpine\n volumes:\n - postgres_data_book:/var/lib/postgresql/data/\n environment:\n - POSTGRES_USER=book_db_username\n - POSTGRES_PASSWORD=book_db_password\n - POSTGRES_DB=book_db_dev\n \n author_service:\n build: ./author-service\n command: uvicorn app.main:app --reload --host 0.0.0.0 --port 8000\n volumes:\n - ./author-service/:/app/\n ports:\n - 8002:8000\n environment:\n - DATABASE_URI=postgresql://author_db_username:author_db_password@author_db/author_db_dev\n depends_on:\n - author_db\n\n author_db:\n image: postgres:12.1-alpine\n volumes:\n - postgres_data_author:/var/lib/postgres/data\n environment:\n - POSTGRES_USER=author_db_username\n - POSTGRES_PASSWORD=author_db_password\n - POSTGRES_DB=author_db_dev\n\n nginx:\n image: nginx:latest\n ports:\n - \"8080:8080\"\n volumes:\n - ./nginx_config.conf:/etc/nginx/conf.d/default.conf\n depends_on:\n - author_service\n - book_service\n\n redis:\n image: redis:3.2-alpine\n volumes:\n # - redis_data:/data\n - ./redis.conf:/usr/local/etc/redis/redis.conf\n command: redis-server /usr/local/etc/redis/redis.conf\n ports:\n - 6379:6379\n\n networks:\n node_net:\n ipv4_address: 172.28.1.4\n\nnetworks:\n node_net:\n ipam:\n driver: default\n config:\n - subnet: 172.28.0.0/16\n\nvolumes:\n postgres_data_book:\n postgres_data_author:\n redis_data:\n```\n\n```text\nTypeError: <databases.backends.postgres.Record object at 0x7fb9f01d8a60> is not JSON serializable\n```\n\n```text\nfrom fastapi.encoders import jsonable_encoder\n\n@authors.get(\"/\", response_model=List[AuthorOut]) \n@cached( \n ttl=100, \n cache=Cache.REDIS,\n endpoint=\"X.X.X.X\", #my local ip\n serializer=JsonSerializer(),\n port=6379,\n namespace=\"main\",\n #key=\"key\",\n )\nasync def get_authors():\n return jsonable_encoder(await db_manager.get_all_authors())\n```\n\n```text\nRecord\n```\n\n```text\nfrom typing import Optional\n\nfrom aioredis import Redis, create_redis_pool\n\n#Create a RedisCache instance\nclass RedisCache:\n \n def __init__(self):\n self.redis_cache: Optional[Redis] = None\n \n async def init_cache(self):\n self.redis_cache = await create_redis_pool(\"redis://localhost:6379/0?encoding=utf-8\") #Connecting to database\n\n async def keys(self, pattern):\n return await self.redis_cache.keys(pattern)\n\n async def set(self, key, value):\n return await self.redis_cache.set(key, value)\n \n async def get(self, key):\n return await self.redis_cache.get(key)\n\n \n async def close(self):\n self.redis_cache.close()\n await self.redis_cache.wait_closed()\n\n\nredis_cache = RedisCache()\n```\n\n```text\nfrom fastapi import FastAPI, applications\nfrom uvicorn import run\nfrom fastapi import FastAPI, Request, Response\nfrom connection import redis_cache\n\n\n\napp = FastAPI(title=\"FastAPI with Redis\")\n\n\nasync def get_all():\n return await redis_cache.keys('*')\n\n\n@app.on_event('startup')\nasync def starup_event():\n await redis_cache.init_cache()\n\n\n@app.on_event('shutdown')\nasync def shutdown_event():\n redis_cache.close()\n await redis_cache.wait_closed()\n\n#root\n@app.get(\"/\")\ndef read_root():\n return {\"Redis\": \"FastAPI\"}\n\n#root > Get all keys from the redis DB\n@app.get('/RedisKeys')\nasync def redis_keys():\n return await get_all()\n\nif __name__ == '__main__':\n run(\"main:app\", port=3000, reload=True)\n```\n\n```text\nuvicorn main:app --reload\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.146Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":9,"totalLines":436,"estimatedTokens":2975}}594{"id":"stack-71063455","source":"stackoverflow","questionId":71063455,"title":"\"There was an error parsing the body\" error on requesting endpoint in FastAPI","tags":["python","json","postman","fastapi"],"text":"Title: \"There was an error parsing the body\" error on requesting endpoint in FastAPI\nTags: python, json, postman, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have implemented a endpoint in FastAPI and I am testing it from Postman. But whenever I send request I get this error:\n\n```\nThere was an error parsing the body\n```\n\nWhile searching for the error, I found a solution somewhere that I need to have `python-multipart` installed. However, this package is already installed and I am still facing the above error.\n\nFollowing is my code:\n\n```\n@router.put('/user')\ndef update_user(user_data: dict):\n from crain.uma import update_user\n user_id = user_data['id']\n update_user(user_id, user_data)\n return {\"message\": \"DONE\"}\n```\n\nThe endpoint excepts a `dict` like this:\n\n```\nuser_data = {\n \"username\":\"admin\",\n \"id\":\"2d06aa3b-c25a-4499-948a-86341ac4adc5\",\n \"email\":null,\n \"firstName\":\"admin\",\n \"lastName\":\"admin\",\n \"createdTimestamp\":1638268009973\n },\n```\n\nhttps://i.sstatic.net/fKaBx.png\nhttps://i.sstatic.net/56jJN.png\n\n========================================\n\nTop Answer:\nIn short, your endpoint expects `JSON` data, but your client sends `form-data` instead. Thus, **when sending the request through Postman**, you should navigate to `Body` from the top menu, then select `raw`, and finally, select `JSON` from the dropdown list, as described in this answer.\n\nAdditioanlly, I would highly sugget using Pydantic models for submitting JSON data, as described in the documentation (see this answer for more details and options as well). Using a Pydantic model would allow you to use the automatic data validation that Pydantic has to offer. You could even use `EmailStr` type for validating email inputs (requires email-validator to be installed, as described in the documentation). Example can be found below.\n\n### Example\n\n```\nfrom pydantic import BaseModel, EmailStr\nfrom datetime import datetime\n\nclass User(BaseModel):\n username: str\n id: str\n email: EmailStr = None\n firstName: str\n lastName: str\n createdTimestamp: datetime\n\n \n@app.put('/user')\nasync def update_user(user: User):\n pass\n```\n\nJSON payload should look like this:\n\n```\n{\n \"username\":\"admin\",\n \"id\":\"2d06aa3b-c25a-4499-948a-86341ac4adc5\",\n \"email\":null,\n \"firstName\":\"admin\",\n \"lastName\":\"admin\",\n \"createdTimestamp\":1638268009973\n}\n```\n\n========================================\n\nCode:\n```text\nThere was an error parsing the body\n```\n\n```py\n@router.put('/user')\ndef update_user(user_data: dict):\n from crain.uma import update_user\n user_id = user_data['id']\n update_user(user_id, user_data)\n return {\"message\": \"DONE\"}\n```\n\n```text\nuser_data = {\n \"username\":\"admin\",\n \"id\":\"2d06aa3b-c25a-4499-948a-86341ac4adc5\",\n \"email\":null,\n \"firstName\":\"admin\",\n \"lastName\":\"admin\",\n \"createdTimestamp\":1638268009973\n },\n```\n\n```text\npython-multipart\n```\n\n```text\ndict\n```\n\n```json\n{\n \"username\":\"admin\",\n \"id\":\"2d06aa3b-c25a-4499-948a-86341ac4adc5\",\n \"email\":null,\n \"firstName\":\"admin\",\n \"lastName\":\"admin\",\n \"createdTimestamp\":1638268009973\n}\n```\n\n```text\nuser_data = { \n \"username\":\"admin\", \n \"id\":\"2d06aa3b-c25a-4499-948a-86341ac4adc5\", \n \"email\":null, \n \"firstName\":\"admin\", \n \"lastName\":\"admin\", \n \"createdTimestamp\":1638268009973\n},\n```\n\n```text\nraw\n```\n\n```text\nform-data\n```\n\n```text\nuser_data\n```\n\n```text\nkey\n```\n\n```text\nform-data\n```\n\n```py\nfrom pydantic import BaseModel, EmailStr\nfrom datetime import datetime\n\n\nclass User(BaseModel):\n username: str\n id: str\n email: EmailStr = None\n firstName: str\n lastName: str\n createdTimestamp: datetime\n\n \n@app.put('/user')\nasync def update_user(user: User):\n pass\n```\n\n```json\n{\n \"username\":\"admin\",\n \"id\":\"2d06aa3b-c25a-4499-948a-86341ac4adc5\",\n \"email\":null,\n \"firstName\":\"admin\",\n \"lastName\":\"admin\",\n \"createdTimestamp\":1638268009973\n}\n```\n\n```text\nJSON\n```\n\n```text\nform-data\n```\n\n```text\nBody\n```\n\n```text\nraw\n```\n\n```text\nJSON\n```\n\n```text\nEmailStr\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.146Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":20,"totalLines":210,"estimatedTokens":1007}}595{"id":"stack-73221487","source":"stackoverflow","questionId":73221487,"title":"Struggling to get good performance for FastAPI on Kubernetes","tags":["kubernetes","fastapi"],"text":"Title: Struggling to get good performance for FastAPI on Kubernetes\nTags: kubernetes, fastapi\nSource: Stack Overflow\n\nQuestion:\nWith my team, we're currently building an API using FastAPI and we're really struggling to get good performances out of it once deployed to Kubernetes. We're using async calls as much as possible but overall sitting at ~8RPS / pod to stay under our SLA of P99 200ms.\n\nFor resources, we assign the following:\n\n```\nresources:\n limits:\n cpu: 1\n memory: 800Mi\n requests:\n cpu: 600m\n memory: 100Mi\n```\n\nSurprisingly, such performance drops don't occur when running load tests on the API running locally in a Docker container. There we easily get ~200RPS on a single container with 120ms latency at P99...\n\nWould anyone have an idea of what could go wrong in there and where I could start looking to find the bottleneck?\n\n========================================\n\nTop Answer:\nFirst, try to request at least 1 CPU for your API, because if there are no available CPUs on the node, the pod will only use the reserved amount of CPUs which is 600m, so if you have another application with requests cpu=400m for example, kubernetes will run both applications on the same cpu, with 60% of the time for the API and 40% for the second application. While docker uses 1 CPU (maybe more) in localhost.\n\nIf you are using Uvicorn with multiple workers, you can also increase CPU limits to or at least 2.\n\n```\nResources:\n limits:\n processor: 2\n memory: 800Mi\n requests:\n processor: 1\n memory: 100Mi\n```\n\nFinally, there is a difference between your local machine CPUs and kubernetes cluster CPUs, if you want to get good performance, you can test better CPUs and choose the most suitable one in terms of cost.\n\n========================================\n\nCode:\n```text\nresources:\n limits:\n cpu: 1\n memory: 800Mi\n requests:\n cpu: 600m\n memory: 100Mi\n```\n\n```text\ngunicorn\n```\n\n```text\nuvicorn\n```\n\n```text\ngunicorn\n```\n\n```yaml\nResources:\n limits:\n processor: 2\n memory: 800Mi\n requests:\n processor: 1\n memory: 100Mi\n```\n\n========================================\n\nComments:\n- Please have a look at **this answer** to understand the differece between using `def` and `async def`, and how your API's performance may get affected by CPU-bound operations, when using asynchronous code.\n- @Chris That doesn’t seem the issue here, as it works fantastic locally with a load test. dernat71 how is your k8s cluster sized? Don’t forget about the deamons that take up (sometimes a significant amount of) resources.\n- @JarroVGIT I am aware of; however, from their saying (i.e., *\"We're using async calls as much as possible, but...\"*), they don't seem to have a clear view of how `async /await` works (which might be another cause for the performance results they've obtained) - hence, the suggested answer.\n- @dernat17 Can you please say, how you implemented gunicorn or uvicorn on k8s! I am currently using - CMD [\"uvicorn\", \"app.main:app\", \"--host\", \"0.0.0.0\", \"--port\", \"8080\"] - this command on my Dockerfile! And deploy it to k8! Did you change anything here?\n- CMD [\"uvicorn\", \"app.main:app\", \"--host\", \"0.0.0.0\", \"--port\", \"8080\", \"--workers\", \"4\"] - Did you do this on your Dockerfile? Isn't it an antipattern?\n- @MdFazlulKarim we finally discovered that the performance issues were caused by our implementation of OpenTelemetry which was causing a lot of overhead and blocking calls over the async of FastAPI. Performances are now super stable using both gunicorn/uvicorn. We are still using gunicorn with multiple workers but we are also planning to move back to uvicorn single-process and scale more dynamically\n- @dernat17 Great to know. May I ask, what is your current alternative to OpenTelemetry?\n- @MdFazlulKarim: we're still using OpenTelemetry as it appears to be the direction the whole domain is taking. We made sure the usage of the opentelemetry-instrument CLI wrapper isn't blocking anymore :-)\n- @dernat71 What did you do to make sure that the usage of opentelemetry does not block anymore?","metadata":{"transformedAt":"2026-08-18T18:32:29.146Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":5,"totalLines":89,"estimatedTokens":1021}}596{"id":"stack-77652094","source":"stackoverflow","questionId":77652094,"title":"How to post JSON data that include unicode characters to FastAPI using Python requests?","tags":["python","json","python-requests","fastapi","pydantic"],"text":"Title: How to post JSON data that include unicode characters to FastAPI using Python requests?\nTags: python, json, python-requests, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nWhen a FastAPI endpoint expects a Pydantic model and one is passed with a string it works as expected unless that string contains unicode characters.\n\nFirst I create an example application for FastAPI with an example model.\n\n`serv.py`\n\n```\nfrom pydantic import BaseModel\n\nclass exClass(BaseModel):\n id: int = Field(example=1)\n text: str = Field(example=\"Text example\")\n\napp = FastAPI(debug=True)\n\n@app.post(\"/example\")\nasync def receive_pyd(ex: exClass):\n print(ex)\n return True\n\nif __name__ == \"__main__\":\n import uvicorn\n uvicorn.run(app, host=\"127.0.0.1\", port=8000)\n```\n\nThe client that shows the error in question `client.py`\n\n```\nfrom pydantic import BaseModel, Field\nimport requests\n\nclass exClass(BaseModel):\n id: int = Field(example=1)\n text: str = Field(example=\"Text example\")\n\nex1 = exClass(id=1, text=\"working example\")\nex2 = exClass(id=2, text=\"this’ will fail\")\nex3 = exClass(id=3, text=\"🤗 Output:\n\n```\ntrue\nInvalid HTTP request received.\nInvalid HTTP request received.\n```\n\nWhen `text` contains unicode characters the result is a 422 Unprocessable Entity. I have tried ex.dict(), model_dump(), and using json instead of data in the requests call. Enabling debugging in FastAPI/starlette bubbles up that the Invalid HTTP request is a JSON decode error.\n\n========================================\n\nTop Answer:\nWhen sending JSON data from Python `requests`, one should use the `json` argument to pass a valid dictionary. Using that argument would set the request's `Content-Type` header to `application/json`. The `data` argument, on the other hand, is used when sending form data, and these data are encoded with `application/x-www-form-urlencoded` (that is the default `Content-Type` in `requests`), or `multipart/form-data` (if `files` are included in the request as well).\n\nPlease have a look at this answer and this answer. You might find this answer, as well as this answer and this answer helpful as well. To return a FastAPI response with unicode or non-ascii characters, please take a look at this answer.\n\nAlong with setting the `Content-Type` header to `application/json`, you should use Pydantic's `model_dump()` method (see this answer for more details)—instead of `model_dump_json()`—which would convert the model to a dictionary.\n\n### Example\n\n```\nfrom pydantic import BaseModel, Field\nimport requests\n\nclass Example(BaseModel):\n id: int = Field(example=1)\n text: str = Field(example=\"test\")\n\nex1 = Example(id=1, text=\"Working\")\nex2 = Example(id=2, text=\"this’ will also work\")\nex3 = Example(id=3, text=\"🤗 <- will also work\")\n\nurl = 'http://127.0.0.1:8000/example'\nr = requests.post(url, json=ex1.model_dump())\nprint(r.text)\nr = requests.post(url, json=ex2.model_dump())\nprint(r.text)\nr = requests.post(url, json=ex3.model_dump())\nprint(r.text)\n```\n\n========================================\n\nCode:\n```text\nfrom pydantic import BaseModel\n\n\nclass exClass(BaseModel):\n id: int = Field(example=1)\n text: str = Field(example=\"Text example\")\n\napp = FastAPI(debug=True)\n\n@app.post(\"/example\")\nasync def receive_pyd(ex: exClass):\n print(ex)\n return True\n\nif __name__ == \"__main__\":\n import uvicorn\n uvicorn.run(app, host=\"127.0.0.1\", port=8000)\n```\n\n```text\nfrom pydantic import BaseModel, Field\nimport requests\n\nclass exClass(BaseModel):\n id: int = Field(example=1)\n text: str = Field(example=\"Text example\")\n\n\nex1 = exClass(id=1, text=\"working example\")\nex2 = exClass(id=2, text=\"this’ will fail\")\nex3 = exClass(id=3, text=\"🤗 <- also non-working\")\n\n\nr = requests.post(f\"http://127.0.0.1:8000/example\", data=ex1.model_dump_json())\nprint(r.text)\nr = requests.post(f\"http://127.0.0.1:8000/example\", data=ex2.model_dump_json())\nprint(r.text)\nr = requests.post(f\"http://127.0.0.1:8000/example\", data=ex3.model_dump_json())\nprint(r.text)\n```\n\n```text\ntrue\nInvalid HTTP request received.\nInvalid HTTP request received.\n```\n\n```text\nserv.py\n```\n\n```text\nclient.py\n```\n\n```text\ntext\n```\n\n```text\nr = requests.post(\n f\"http://127.0.0.1:8000/example\", data=ex1.model_dump_json().encode('utf-8')\n)\nprint(r.text)\nr = requests.post(\n f\"http://127.0.0.1:8000/example\", data=ex2.model_dump_json().encode('utf-8')\n)\nprint(r.text)\nr = requests.post(\n f\"http://127.0.0.1:8000/example\", data=ex3.model_dump_json().encode('utf-8')\n)\nprint(r.text)\n```\n\n```py\nfrom pydantic import BaseModel, Field\nimport requests\n\nclass Example(BaseModel):\n id: int = Field(example=1)\n text: str = Field(example=\"test\")\n\n\nex1 = Example(id=1, text=\"Working\")\nex2 = Example(id=2, text=\"this’ will also work\")\nex3 = Example(id=3, text=\"🤗 <- will also work\")\n\n\nurl = 'http://127.0.0.1:8000/example'\nr = requests.post(url, json=ex1.model_dump())\nprint(r.text)\nr = requests.post(url, json=ex2.model_dump())\nprint(r.text)\nr = requests.post(url, json=ex3.model_dump())\nprint(r.text)\n```\n\n```text\nrequests\n```\n\n```text\njson\n```\n\n```text\nContent-Type\n```\n\n```text\napplication/json\n```\n\n```text\ndata\n```\n\n```text\napplication/x-www-form-urlencoded\n```\n\n```text\nContent-Type\n```\n\n```text\nrequests\n```\n\n```text\nmultipart/form-data\n```\n\n```text\nfiles\n```\n\n```text\nContent-Type\n```\n\n```text\napplication/json\n```\n\n```text\nmodel_dump()\n```\n\n```text\nmodel_dump_json()\n```\n\n========================================\n\nComments:\n- I completely misunderstood the problem, thanks for setting me straight.\n- This works in the simplified Example class, but the reason I was using data=exN.model_dump_json() is the actual class contains datetimes and that breaks using json=exN.model_dump() without requiring me to make further updates to the class or function\n- In that case, you could use `model.model_dump()` with the `mode` parameter set to `json`, e.g., `ex1.model_dump(mode='json')` (see the relevant documentation). This would ensure that the returned dictionary will only contain JSON serializable types. Hence, a `datetime` object would be converted into a `str`, similar to what FastAPI's `jsonable_encoder` does, as described in this answer","metadata":{"transformedAt":"2026-08-18T18:32:29.148Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":22,"totalLines":247,"estimatedTokens":1533}}597{"id":"stack-77142174","source":"stackoverflow","questionId":77142174,"title":"use both PUT and POST methods from same API using FastAPI","tags":["python","post","fastapi","put"],"text":"Title: use both PUT and POST methods from same API using FastAPI\nTags: python, post, fastapi, put\nSource: Stack Overflow\n\nQuestion:\nI'm about to create an API using FastApi wherein I have to search for '*user_name*' in db. If '*user_name*' exists then I have to update the *user_details*. If the '*user_name*' doesn't exist, then I have to create entry for the user.\nIn this case, I think both **PUT** and **POST** methods need to be applied for the same API endpoint. Is this possible? can anyone brief me how to do it?\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n\n@app.put(\"/\")\nasync def put_root():\n return {\"message\": \"Hello World from put\"}\n\n@app.post(\"/\")\nasync def post_root():\n return {\"message\": \"Hello World from post\"}\n```\n\n========================================\n\nComments:\n- If you find it useful please accept the answer ;).","metadata":{"transformedAt":"2026-08-18T18:32:29.148Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":1,"totalLines":30,"estimatedTokens":226}}598{"id":"stack-70448668","source":"stackoverflow","questionId":70448668,"title":"Passing pandas dataframe to fastapi","tags":["python","python-3.x","pandas","dataframe","fastapi"],"text":"Title: Passing pandas dataframe to fastapi\nTags: python, python-3.x, pandas, dataframe, fastapi\nSource: Stack Overflow\n\nQuestion:\nI wish to create an API using which I can take Pandas dataframe as an input and store that in my DB.\n\nI am able to do so with the csv file. However, the problem with that is that, my datatype information is lost (column datatypes like: int, array, float and so on) which is important for what I am trying to do.\n\nI have already read this: Passing a pandas dataframe to FastAPI for NLP ML\n\nI cannot create a class like this:\n\n```\nclass Data(BaseModel):\n # id: str\n project: str\n messages: str\n```\n\nThe reason being I don't have any fixed schema. the dataframe could be of any shape with varying data types. I have created a dynamic query to create a table as per coming data frame and insert into that dataframe as well.\n\nHowever, being new to fastapi, I am not able to figure out if there is an efficient way of sending this changing (dynamic) dataframe requirement of mine and store it via the queries that I have created.\n\nIf the information is not sufficient, I can try to provide more examples.\n\nIs there a way I can send pandas dataframe from my jupyter notebook itself.\n\nAny guidance on this would be greatly appreciated.\n\n```\n@router.post(\"/send-df\")\nasync def push_df_funct(\n target_name: Optional[str] = Form(...),\n join_key: str = Form(...),\n local_csv_file: UploadFile = File(None),\n db: Session = Depends(pg.get_db)\n):\n \"\"\"\n API to upload dataframe to database\n \"\"\"\n return upload_dataframe(db, featureset_name, local_csv_file, join_key)\n```\n\n```\ndef registration_cassandra(self, feature_registation_dict):\n '''\n # Table creation in cassandra as per the given feature registration JSON\n Takes:\n 1. feature_registration_dict: Feature registration JSON\n Returns: \n - Response stating that the table has been created in cassandra\n '''\n logging.info(feature_registation_dict)\n target_table_name = feature_registation_dict.get('featureset_name')\n join_key = feature_registation_dict.get('join_key')\n metadata_list = feature_registation_dict.get('metadata_list')\n \n table_name_delimiter = \"__\"\n\n logging.info(metadata_list)\n\n column_names = [ sub['name'] for sub in metadata_list ]\n data_types = [ DataType.to_cass_datatype(eval(sub['data_type']).value) for sub in metadata_list ]\n \n logging.info(f\"Column names: {column_names}\")\n logging.info(f\"Data types: {data_types}\")\n \n ls = list(zip(column_names, data_types))\n\n target_table_name = target_table_name + table_name_delimiter + join_key\n\n base_query = f\"CREATE TABLE {self.keyspace}.{target_table_name} (\"\n \n # CREATE TABLE images_by_month5(tid object PRIMARY KEY , cc_num object,amount object,fraud_label object,activity_time object,month object);\n\n # create_query_new = \"CREATE TABLE vpinference_dev.images_by_month4 (month int,activity_time timestamp,amount double,cc_num varint,fraud_label varint,\n # tid text,PRIMARY KEY (month, activity_time, tid)) WITH CLUSTERING ORDER BY (activity_time DESC, tid ASC)\"\n\n #CREATE TABLE group_join_dates ( groupname text, joined timeuuid, username text, email text, age int, PRIMARY KEY (groupname, joined) )\n flag = True\n for name, data_type in ls:\n base_query += \" \" + name\n base_query += \" \" + data_type\n #if flag :\n # base_query += \" PRIMARY KEY \"\n # flag = False\n base_query += ','\n \n create_query = base_query.strip(',').rstrip(' ') + ', month varchar, activity_time timestamp,' + ' PRIMARY KEY (' + f'month, activity_time, {join_key}) )' + f' WITH CLUSTERING ORDER BY (activity_time DESC, {join_key} ASC' + ');'\n logging.info(f\"Query to create table in cassandra: {create_query}\")\n try: \n session = self.get_session()\n session.execute((create_query))\n except Exception as e:\n logging.exception(f\"Some error occurred while doing the registration in cassandra. Details :: {str(e)}\")\n raise AppException(f\"Some error occurred while doing the registration in cassandra. Details :: {str(e)}\")\n\n response = f\"Table created successfully in cassandra at: vpinference_dev.{target_table_name}__{join_key};\"\n return response\n```\n\nThis is the dictionary that I am passing:\n\n```\nfeature_registation_dict = {\n 'featureSetName': 'data_type_testing_29',\n 'teamName': 'Harsh',\n 'frequency': 'DAILY',\n 'joinKey': 'tid',\n 'model_version': 'v1',\n 'model_name': 'data type testing',\n 'metadata_list': [{'name': 'tid',\n 'data_type': 'text',\n 'definition': 'Credit Card Number (Unique)'},\n {'name': 'cc_num',\n 'data_type': 'bigint',\n 'definition': 'Aggregated Metric: Average number of transactions for the card aggregated by past 10 minutes'},\n {'name': 'amount',\n 'data_type': 'double',\n 'definition': 'Aggregated Metric: Average transaction amount for the card aggregated by past 10 minutes'},\n {'name': 'datetime',\n 'data_type': 'text',\n 'definition': 'Required feature for event timestamp'}]}\n```\n\n========================================\n\nCode:\n```text\nclass Data(BaseModel):\n # id: str\n project: str\n messages: str\n```\n\n```text\n@router.post(\"/send-df\")\nasync def push_df_funct(\n target_name: Optional[str] = Form(...),\n join_key: str = Form(...),\n local_csv_file: UploadFile = File(None),\n db: Session = Depends(pg.get_db)\n):\n \"\"\"\n API to upload dataframe to database\n \"\"\"\n return upload_dataframe(db, featureset_name, local_csv_file, join_key)\n```\n\n```text\ndef registration_cassandra(self, feature_registation_dict):\n '''\n # Table creation in cassandra as per the given feature registration JSON\n Takes:\n 1. feature_registration_dict: Feature registration JSON\n Returns: \n - Response stating that the table has been created in cassandra\n '''\n logging.info(feature_registation_dict)\n target_table_name = feature_registation_dict.get('featureset_name')\n join_key = feature_registation_dict.get('join_key')\n metadata_list = feature_registation_dict.get('metadata_list')\n \n table_name_delimiter = \"__\"\n\n logging.info(metadata_list)\n\n column_names = [ sub['name'] for sub in metadata_list ]\n data_types = [ DataType.to_cass_datatype(eval(sub['data_type']).value) for sub in metadata_list ]\n \n logging.info(f\"Column names: {column_names}\")\n logging.info(f\"Data types: {data_types}\")\n \n ls = list(zip(column_names, data_types))\n\n target_table_name = target_table_name + table_name_delimiter + join_key\n\n base_query = f\"CREATE TABLE {self.keyspace}.{target_table_name} (\"\n \n # CREATE TABLE images_by_month5(tid object PRIMARY KEY , cc_num object,amount object,fraud_label object,activity_time object,month object);\n\n # create_query_new = \"CREATE TABLE vpinference_dev.images_by_month4 (month int,activity_time timestamp,amount double,cc_num varint,fraud_label varint,\n # tid text,PRIMARY KEY (month, activity_time, tid)) WITH CLUSTERING ORDER BY (activity_time DESC, tid ASC)\"\n\n #CREATE TABLE group_join_dates ( groupname text, joined timeuuid, username text, email text, age int, PRIMARY KEY (groupname, joined) )\n flag = True\n for name, data_type in ls:\n base_query += \" \" + name\n base_query += \" \" + data_type\n #if flag :\n # base_query += \" PRIMARY KEY \"\n # flag = False\n base_query += ','\n \n create_query = base_query.strip(',').rstrip(' ') + ', month varchar, activity_time timestamp,' + ' PRIMARY KEY (' + f'month, activity_time, {join_key}) )' + f' WITH CLUSTERING ORDER BY (activity_time DESC, {join_key} ASC' + ');'\n logging.info(f\"Query to create table in cassandra: {create_query}\")\n try: \n session = self.get_session()\n session.execute((create_query))\n except Exception as e:\n logging.exception(f\"Some error occurred while doing the registration in cassandra. Details :: {str(e)}\")\n raise AppException(f\"Some error occurred while doing the registration in cassandra. Details :: {str(e)}\")\n\n response = f\"Table created successfully in cassandra at: vpinference_dev.{target_table_name}__{join_key};\"\n return response\n```\n\n```text\nfeature_registation_dict = {\n 'featureSetName': 'data_type_testing_29',\n 'teamName': 'Harsh',\n 'frequency': 'DAILY',\n 'joinKey': 'tid',\n 'model_version': 'v1',\n 'model_name': 'data type testing',\n 'metadata_list': [{'name': 'tid',\n 'data_type': 'text',\n 'definition': 'Credit Card Number (Unique)'},\n {'name': 'cc_num',\n 'data_type': 'bigint',\n 'definition': 'Aggregated Metric: Average number of transactions for the card aggregated by past 10 minutes'},\n {'name': 'amount',\n 'data_type': 'double',\n 'definition': 'Aggregated Metric: Average transaction amount for the card aggregated by past 10 minutes'},\n {'name': 'datetime',\n 'data_type': 'text',\n 'definition': 'Required feature for event timestamp'}]}\n```\n\n```py\n#fastapi\n@app.post(\"/receive_df\")\ndef receive_df(df_in: str):\n df = pd.DataFrame.read_json(df_in)\n\n#jupyter\npayload={\"df_in\":df.to_json()}\nrequests.post(\"localhost:8000/receive_df\", data=payload)\n```\n\n```text\npydantic.Json\n```\n\n```text\nBaseModel\n```\n\n========================================\n\nComments:\n- If you can't write a schema for your `DataFrame`, how can you have a schema for your database? Or what kind of database are you using?\n- I have edited my question to reflect how I am creating a schema. I am using Hive and Cassandra for a DB.\n- I tried the above example and I got this: \"POST /data/receive_df HTTP/1.1\" 422 Unprocessable Entity. fastAPI is not able to parse that as a string.\n- Think I might have screwed up the post request. Try the updated example.\n- Thank you so much. Yep, the updated one works. Any chance, you know how this can be scaled? It worked perfectly fine with small data frames but it is crashing with let's say few million records. Even if you don't, this was helpful. I will explore that by myself.\n- I don't have much experience with larger payloads, but you can pass a generator to the `data` param like this and `requests` will do a chunked transfer. Maybe that'll work.\n- for larger frames you will be lost with json. I would recommend to convert your frames into parquet bytestreams. You may also need bson if you have a dictionary of multiple parameters\n- Yea I have df with half a million rows, when I tried this method I got a `422 Unprocessable Entity` in FastApi..","metadata":{"transformedAt":"2026-08-18T18:32:29.148Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":7,"totalLines":260,"estimatedTokens":2611}}599{"id":"stack-71238037","source":"stackoverflow","questionId":71238037,"title":"Weak warning for a parameter not used but needed with Fast API","tags":["python","pycharm","fastapi"],"text":"Title: Weak warning for a parameter not used but needed with Fast API\nTags: python, pycharm, fastapi\nSource: Stack Overflow\n\nQuestion:\nI use a custom exception handler with Fast API:\n\n```\nclass CustomException(Exception):\n def __init__(self, err_message: str):\n self.err_message = err_message\n\n@app.exception_handler(CustomException)\nasync def custom_exception_handler(request: Request, exc: CustomException):\n return JSONResponse(content={\"error\": exc.err_message})\n```\n\nPycharm put the 'request: Request' as a weak warning:\n\n''Parameter 'request' value is not used'' since it's not used in the code.\n\nHowever, if I remove the parameter, I get a Fast API error when running the code.\nSo I wonder if this is a PyCharm 'bug', if we can call it that way ?\n\n========================================\n\nCode:\n```py\nclass CustomException(Exception):\n def __init__(self, err_message: str):\n self.err_message = err_message\n\n@app.exception_handler(CustomException)\nasync def custom_exception_handler(request: Request, exc: CustomException):\n return JSONResponse(content={\"error\": exc.err_message})\n```\n\n```text\ndef lambda_example(event, context):\n \"\"\"This raises a warning ⚠️\"\"\"\n print(event)\n\n\ndef second_example(event,_):\n \"\"\"This does not ✔️\"\"\"\n print(event)\n\n\ndef third_example(_event,_context):\n \"\"\"This does not either ✔️\"\"\"\n print(\"this does not care about it's parameters\")\n```\n\n```text\n_\n```\n\n```text\nevent\n```\n\n```text\ncontext\n```\n\n```text\n_\n```\n\n========================================\n\nComments:\n- Just disable the warning.\n- Very clear explanation! Fixed the issue for me :)\n- Except this `_` theory doesn't work when you actually NEED to put `request: Request` in the function arguments. Case and point? When using a rate-limit decorator such as with slowapi. It's the decorator eating up the `Request`. Enter in the point of having single line exemptions to ignore warnings. For example: `def func(request: Request): # pylint: disable=unused-argument`. It if was \"bad practice\" to ignore single lines (or entire blocks of code), then that functionality would be completely removed from any and all linters.\n- @BrandonStivers it is not a bat practice per se but is an inconsistency on your linting configuration ; you are basically saying I agree with this rule but i don't enforce it in my code. This warning is designed to help improve code quality by identifying and flagging code that includes parameters that are defined but not used within the function body. to prevent code bloat and to encourage developers to write cleaner, more efficient code. Unused arguments can indicate code smells and design issues, such as unused imports, copy-pasting from other functions, or bad function signatures.\n- @lcarvajal except you ignore the false positives given by linters, code in which you do not control. Again, go ahead try using your theory while using FastAPI and SlowAPI as a rate limeter. You're using valid function arguments that are used in the function itself, but MyPy gives a false positive. You run over to the SlowAPI code owners and tell them they don't know what they are doing. What projects you maintain again?\n- it is not a false positive , you have not prefixed the argument with a `_` and is not used internally in the method that exposes it therefore you have a linter you don't need to name it request , you need to type hint it as Request type `def func(_request: Request)...` please understand that linters are not intelligent they are barely pointing the obvious. it is you as the developer who has to figure ot the solution that shuts down all linter warnings","metadata":{"transformedAt":"2026-08-18T18:32:29.148Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":6,"totalLines":78,"estimatedTokens":906}}600{"id":"stack-71090906","source":"stackoverflow","questionId":71090906,"title":"FastAPI WebSocket replication","tags":["python","websocket","redis","replication","fastapi"],"text":"Title: FastAPI WebSocket replication\nTags: python, websocket, redis, replication, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have implemented a simple WebSocket proxy with FastAPI (using this example)\n\nThe application target is to just pass through all messages it gets to its active connections (proxy).\n\nIt works well only with a single instance because it keeps active WebSocket connections in memory. And memory is not shared when there is more than one instance.\n\nMy naive approach was to solve it by keeping active connections in some shared storage (Redis). But I was stuck with pickling it.\n\nHere is the complete app:\n\n```\nimport pickle\n\nfrom fastapi import FastAPI, WebSocket, WebSocketDisconnect\nfrom collections import defaultdict\nimport redis\n\napp = FastAPI()\nrds = redis.StrictRedis('localhost')\n\nclass ConnectionManager:\n def __init__(self):\n self.active_connections = defaultdict(dict)\n\n async def connect(self, websocket: WebSocket, application: str, client_id: str):\n await websocket.accept()\n if application not in self.active_connections:\n self.active_connections[application] = defaultdict(list)\n\n self.active_connections[application][client_id].append(websocket)\n\n #### this is my attempt to store connections ####\n rds.set('connections', pickle.dumps(self.active_connections)) \n\n def disconnect(self, websocket: WebSocket, application: str, client_id: str):\n self.active_connections[application][client_id].remove(websocket)\n\n async def broadcast(self, message: dict, application: str, client_id: str):\n for connection in self.active_connections[application][client_id]:\n try:\n await connection.send_json(message)\n print(f\"sent {message}\")\n except Exception as e:\n pass\n\nmanager = ConnectionManager()\n\n@app.websocket(\"/ws/channel/{application}/{client_id}/\")\nasync def websocket_endpoint(websocket: WebSocket, application: str, client_id: str):\n await manager.connect(websocket, application, client_id)\n while True:\n try:\n data = await websocket.receive_json()\n print(f\"received: {data}\")\n await manager.broadcast(data, application, client_id)\n except WebSocketDisconnect:\n manager.disconnect(websocket, application, client_id)\n except RuntimeError:\n break\n\nif __name__ == '__main__':\n import uvicorn\n\n uvicorn.run(app, host='0.0.0.0', port=8005)\n```\n\nHowever, pickling websocket connection was not successful:\n\n```\nAttributeError: Can't pickle local object 'FastAPI.setup..openapi'\n```\n\nWhat is the proper way to have WebSocket connections stored across the application instances?\n\n**UPD** The actual solution per @AKX answer.\n\nEach instance of the server is subscribed to Redis pubsub and tries to send the received message to all its connected clients.\n\nSince one client cannot be connected to several instances - each message should be delivered to each client only once\n\n```\nimport json\nimport asyncio\n\nfrom fastapi import FastAPI, WebSocket, WebSocketDisconnect\nfrom collections import defaultdict\nimport redis\n\napp = FastAPI()\nrds = redis.StrictRedis('localhost')\n\nclass ConnectionManager:\n def __init__(self):\n self.active_connections = defaultdict(dict)\n\n async def connect(self, websocket: WebSocket, application: str, client_id: str):\n await websocket.accept()\n if application not in self.active_connections:\n self.active_connections[application] = defaultdict(list)\n\n self.active_connections[application][client_id].append(websocket)\n\n def disconnect(self, websocket: WebSocket, application: str, client_id: str):\n self.active_connections[application][client_id].remove(websocket)\n\n async def broadcast(self, message: dict, application: str, client_id: str):\n for connection in self.active_connections[application][client_id]:\n try:\n await connection.send_json(message)\n print(f\"sent {message}\")\n except Exception as e:\n pass\n\n async def consume(self):\n print(\"started to consume\")\n sub = rds.pubsub()\n sub.subscribe('channel')\n while True:\n await asyncio.sleep(0.01)\n message = sub.get_message(ignore_subscribe_messages=True)\n if message is not None and isinstance(message, dict):\n msg = json.loads(message.get('data'))\n await self.broadcast(msg['message'], msg['application'], msg['client_id'])\n\nmanager = ConnectionManager()\n\n@app.on_event(\"startup\")\nasync def subscribe():\n asyncio.create_task(manager.consume())\n\n@app.websocket(\"/ws/channel/{application}/{client_id}/\")\nasync def websocket_endpoint(websocket: WebSocket, application: str, client_id: str):\n await manager.connect(websocket, application, client_id)\n while True:\n try:\n data = await websocket.receive_json()\n print(f\"received: {data}\")\n rds.publish(\n 'channel',\n json.dumps({\n 'application': application,\n 'client_id': client_id,\n 'message': data\n })\n )\n except WebSocketDisconnect:\n manager.disconnect(websocket, application, client_id)\n except RuntimeError:\n break\n\nif __name__ == '__main__': # pragma: no cover\n import uvicorn\n\n uvicorn.run(app, host='0.0.0.0', port=8005)\n```\n\n========================================\n\nCode:\n```text\nimport pickle\n\nfrom fastapi import FastAPI, WebSocket, WebSocketDisconnect\nfrom collections import defaultdict\nimport redis\n\napp = FastAPI()\nrds = redis.StrictRedis('localhost')\n\nclass ConnectionManager:\n def __init__(self):\n self.active_connections = defaultdict(dict)\n\n async def connect(self, websocket: WebSocket, application: str, client_id: str):\n await websocket.accept()\n if application not in self.active_connections:\n self.active_connections[application] = defaultdict(list)\n\n self.active_connections[application][client_id].append(websocket)\n\n #### this is my attempt to store connections ####\n rds.set('connections', pickle.dumps(self.active_connections)) \n\n def disconnect(self, websocket: WebSocket, application: str, client_id: str):\n self.active_connections[application][client_id].remove(websocket)\n\n async def broadcast(self, message: dict, application: str, client_id: str):\n for connection in self.active_connections[application][client_id]:\n try:\n await connection.send_json(message)\n print(f\"sent {message}\")\n except Exception as e:\n pass\n\n\nmanager = ConnectionManager()\n\n\n@app.websocket(\"/ws/channel/{application}/{client_id}/\")\nasync def websocket_endpoint(websocket: WebSocket, application: str, client_id: str):\n await manager.connect(websocket, application, client_id)\n while True:\n try:\n data = await websocket.receive_json()\n print(f\"received: {data}\")\n await manager.broadcast(data, application, client_id)\n except WebSocketDisconnect:\n manager.disconnect(websocket, application, client_id)\n except RuntimeError:\n break\n\n\nif __name__ == '__main__':\n import uvicorn\n\n uvicorn.run(app, host='0.0.0.0', port=8005)\n```\n\n```text\nAttributeError: Can't pickle local object 'FastAPI.setup.<locals>.openapi'\n```\n\n```text\nimport json\nimport asyncio\n\n\nfrom fastapi import FastAPI, WebSocket, WebSocketDisconnect\nfrom collections import defaultdict\nimport redis\n\napp = FastAPI()\nrds = redis.StrictRedis('localhost')\n\n\nclass ConnectionManager:\n def __init__(self):\n self.active_connections = defaultdict(dict)\n\n async def connect(self, websocket: WebSocket, application: str, client_id: str):\n await websocket.accept()\n if application not in self.active_connections:\n self.active_connections[application] = defaultdict(list)\n\n self.active_connections[application][client_id].append(websocket)\n\n def disconnect(self, websocket: WebSocket, application: str, client_id: str):\n self.active_connections[application][client_id].remove(websocket)\n\n async def broadcast(self, message: dict, application: str, client_id: str):\n for connection in self.active_connections[application][client_id]:\n try:\n await connection.send_json(message)\n print(f\"sent {message}\")\n except Exception as e:\n pass\n\n async def consume(self):\n print(\"started to consume\")\n sub = rds.pubsub()\n sub.subscribe('channel')\n while True:\n await asyncio.sleep(0.01)\n message = sub.get_message(ignore_subscribe_messages=True)\n if message is not None and isinstance(message, dict):\n msg = json.loads(message.get('data'))\n await self.broadcast(msg['message'], msg['application'], msg['client_id'])\n\n\nmanager = ConnectionManager()\n\n\n@app.on_event(\"startup\")\nasync def subscribe():\n asyncio.create_task(manager.consume())\n\n\n@app.websocket(\"/ws/channel/{application}/{client_id}/\")\nasync def websocket_endpoint(websocket: WebSocket, application: str, client_id: str):\n await manager.connect(websocket, application, client_id)\n while True:\n try:\n data = await websocket.receive_json()\n print(f\"received: {data}\")\n rds.publish(\n 'channel',\n json.dumps({\n 'application': application,\n 'client_id': client_id,\n 'message': data\n })\n )\n except WebSocketDisconnect:\n manager.disconnect(websocket, application, client_id)\n except RuntimeError:\n break\n\n\nif __name__ == '__main__': # pragma: no cover\n import uvicorn\n\n uvicorn.run(app, host='0.0.0.0', port=8005)\n```\n\n========================================\n\nComments:\n- No. To the connected client are relevant only the messages that are sent after the moment of connection.\n- @Chris, yes. And the potential for high load. I think pubsub suggested by AKX is a good way. Need only to figure out the implementation details\n- Thanks! pubsub approach seem to solve this. I've updated question with the actual solution for that","metadata":{"transformedAt":"2026-08-18T18:32:29.148Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":3,"totalLines":315,"estimatedTokens":2460}}601{"id":"stack-72208874","source":"stackoverflow","questionId":72208874,"title":"upload an image with a token to a fastAPI route using POST from reactJS","tags":["reactjs","axios","fastapi"],"text":"Title: upload an image with a token to a fastAPI route using POST from reactJS\nTags: reactjs, axios, fastapi\nSource: Stack Overflow\n\nQuestion:\ni'm trying to upload an image from client (reactJS) side to fastAPI using a post method\n\nthis is my client side\n\n```\nconst [img, setImg] = useState(null)\n\nconst onImageUpload = (e) => {\n console.log(e.target.files[0])\n setImg(e.target.files[0])\n }\n\nconst handleChange = () => {\n if (!img) setErr(\"please upload an image\")\n else {\n \n let formData = new FormData();\n let token = localStorage.getItem(\"TikToken\")\n\n formData.append(\n \"token\",\n token\n )\n \n formData.append(\n \"pic\",\n img,\n img.name\n )\n \n\n console.log(formData)\n axios({\n method: 'post',\n url: \"http://localhost:8000/profile/pic/\",\n data: formData\n \n })\n .then(function(response) {\n console.log(response);\n })\n\n \n }\n }\n```\n\nand this is my fastAPI function\n\n```\n@app.post(\"/profile/pic/\")\nasync def setpic(token: str, pic:bytes = File(...)):\n\n print(pic)\n image = Image.open(io.BytesIO(pic))\n image.show()\n # response = await store_profile_image(form, str(base64.b64encode(form)))\n return \"response\"\n```\n\ni'm gettin error 422 (Unprocessable Entity)\n\nthis is the error\n\n```\nEdit:1 Uncaught (in promise) \nAxiosError {message: 'Request failed with status code 422', name: 'AxiosError', code: 'ERR_BAD_REQUEST', config: {…}, request: XMLHttpRequest, …}\ncode: \"ERR_BAD_REQUEST\"\nconfig: {transitional: {…}, transformRequest: Array(1), transformResponse: Array(1), timeout: 0, adapter: ƒ, …}\nmessage: \"Request failed with status code 422\"\nname: \"AxiosError\"\nrequest: XMLHttpRequest {onreadystatechange: null, readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, …}\nresponse: {data: {…}, status: 422, statusText: 'Unprocessable Entity', headers: {…}, config: {…}, …}\n[[Prototype]]: Error\n```\n\nwhat am I doing wrong?\nand how to fix it?\n\nEDIT:\n\ni checked the error body ( response > data > detail )\n\ni found this\n\n```\ndetail: Array(1) 0: \n loc: (2) ['query', 'token'] \n msg: \"field required\" \n type: \"value_error.missing\"\n```\n\ni changed data in axios request to\n`data: { \"token\" : token, \"pic\": img}`\n\ni got this in the error body\n\n```\ndetail: Array(2)\n0:\n loc: (2) ['query', 'token']\n msg: \"field required\"\n type: \"value_error.missing\"\n [[Prototype]]: Object\n1:\n loc: (2) ['body', 'pic']\n msg: \"field required\"\n type: \"value_error.missing\"\n [[Prototype]]: Object\nlength: 2\n```\n\n========================================\n\nCode:\n```text\nconst [img, setImg] = useState(null)\n\nconst onImageUpload = (e) => {\n console.log(e.target.files[0])\n setImg(e.target.files[0])\n }\n\n\nconst handleChange = () => {\n if (!img) setErr(\"please upload an image\")\n else {\n \n let formData = new FormData();\n let token = localStorage.getItem(\"TikToken\")\n\n formData.append(\n \"token\",\n token\n )\n \n formData.append(\n \"pic\",\n img,\n img.name\n )\n \n\n console.log(formData)\n axios({\n method: 'post',\n url: \"http://localhost:8000/profile/pic/\",\n data: formData\n \n })\n .then(function(response) {\n console.log(response);\n })\n\n \n }\n }\n```\n\n```text\n@app.post(\"/profile/pic/\")\nasync def setpic(token: str, pic:bytes = File(...)):\n\n print(pic)\n image = Image.open(io.BytesIO(pic))\n image.show()\n # response = await store_profile_image(form, str(base64.b64encode(form)))\n return \"response\"\n```\n\n```text\nEdit:1 Uncaught (in promise) \nAxiosError {message: 'Request failed with status code 422', name: 'AxiosError', code: 'ERR_BAD_REQUEST', config: {…}, request: XMLHttpRequest, …}\ncode: \"ERR_BAD_REQUEST\"\nconfig: {transitional: {…}, transformRequest: Array(1), transformResponse: Array(1), timeout: 0, adapter: ƒ, …}\nmessage: \"Request failed with status code 422\"\nname: \"AxiosError\"\nrequest: XMLHttpRequest {onreadystatechange: null, readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, …}\nresponse: {data: {…}, status: 422, statusText: 'Unprocessable Entity', headers: {…}, config: {…}, …}\n[[Prototype]]: Error\n```\n\n```text\ndetail: Array(1) 0: \n loc: (2) ['query', 'token'] \n msg: \"field required\" \n type: \"value_error.missing\"\n```\n\n```text\ndetail: Array(2)\n0:\n loc: (2) ['query', 'token']\n msg: \"field required\"\n type: \"value_error.missing\"\n [[Prototype]]: Object\n1:\n loc: (2) ['body', 'pic']\n msg: \"field required\"\n type: \"value_error.missing\"\n [[Prototype]]: Object\nlength: 2\n```\n\n```text\ndata: { \"token\" : token, \"pic\": img}\n```\n\n```py\n@app.post(\"/profile/pic/\")\nasync def setpic(token: str = Form(...), pic:bytes = File(...)):\n\n print(pic)\n image = Image.open(io.BytesIO(pic))\n image.show()\n # response = await store_profile_image(form, str(base64.b64encode(form)))\n return \"response\"\n```\n\n```js\nheaders: {\n \"Content-Type\": \"multipart/form-data\",\n },\n```\n\n```text\ntoken:str = Form(...)\n```\n\n```text\nmultipart/form-data\n```\n\n```text\napplication/json\n```\n\n```text\nFile\n```\n\n```text\nForm\n```\n\n========================================\n\nComments:\n- The body of the 422 error will contain the actual error message - i.e. which field is missing or is failing validation.\n- i edited the question, i added this detail\n- this solved my problem Thank you could you recommend any good documentation that explains more about this ?\n- FastAPI documentation about that : fastapi.tiangolo.com/tutorial/request-forms-and-files","metadata":{"transformedAt":"2026-08-18T18:32:29.149Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":13,"totalLines":257,"estimatedTokens":1412}}602{"id":"stack-70520479","source":"stackoverflow","questionId":70520479,"title":"Flutter receives 422 response from Fastapi when posting a PNG file","tags":["flutter","dart","http-post","fastapi","flutter-image"],"text":"Title: Flutter receives 422 response from Fastapi when posting a PNG file\nTags: flutter, dart, http-post, fastapi, flutter-image\nSource: Stack Overflow\n\nQuestion:\nI have created a working localhost API with FastAPI. The POST takes a PNG, does some image processing and returns a PNG as expected when I click the 'try it out' button in the FastAPI generated docs:\nhttps://i.sstatic.net/l7ynP.png\nThe curl post command shows as follows:\n\n```\ncurl -X 'POST' \\\n 'http://localhost:8345/api/predict' \\\n -H 'accept: application/json' \\\n -H 'Content-Type: multipart/form-data' \\\n -F 'file=@test_img.png;type=image/png'\n```\n\nThe image File is successfully retrieved from the image picker library. (Where the image1 object has been initialized as `File image1;` in the app page's class.\n\n```\nFuture getImage() async {\n var imageTmp = await ImagePicker.pickImage(source: ImageSource.gallery);\n setState(() {\n image1 = imageTmp;\n print('Image Path $image1');\n });\n }\n```\n\nI tried to emulate the API call with the below function in Flutter.\n\n```\ndoUpload() {\n /*\n curl -X 'POST' \\\n 'http://192.168.178.26:8345/api/predict' \\\n -H 'accept: application/json' \\\n -H 'Content-Type: multipart/form-data' \\\n -F 'file=@test_img.png;type=image/png'\n\n */\n var request = http.MultipartRequest(\n 'POST',\n Uri.parse(\"http://:8345/api/predict\"),\n );\n Map headers = {\"Content-type\": \"multipart/form-data\"};\n request.files.add(\n http.MultipartFile(\n 'image',\n image1.readAsBytes().asStream(),\n image1.lengthSync(),\n filename: 'filename',\n contentType: MediaType('image', 'png'),\n ),\n );\n request.headers.addAll(headers);\n print(\"request: \" + request.toString());\n request.send().then((value) => print(value.statusCode));\n }\n```\n\nWhen I run the `doUpload()` function, a POST is successfully sent to the localhost API, but it returns a 422 error 'unprocessable entity'.\nWhat I tried:\n\n- I tried to set the image type in doUpload to jpg, jpeg, but I keep getting a 422 error.\nI tried looking up where the image_picker is supposed to store the temporary file to see if it's stored correctly, but when I look at the generated filepath, I don't see the actual file and tmp folder:\nfilepath: `File: '/data/user/0//cache/image_picker3300408791299772729jpg'`\n\nlooking at my local UI filepath, I see:\nhttps://i.sstatic.net/J2cxc.png\n\nIt shows no folder named cache, so I can't inspect it like this. However, the image picker saves it with a jpg at the end (not .jpg, is this normal?)\n\nI also tried adding this debugger function to my fastAPI server.py, but I'm not sure how I can inspect the resulting data in the current flutter code:\nhttps://fastapi.tiangolo.com/tutorial/handling-errors/#use-the-requestvalidationerror-body\nThe resulting `value` has properties like statusCode and reason, but I don't see a full json output option.\n\n========================================\n\nCode:\n```text\ncurl -X 'POST' \\\n 'http://localhost:8345/api/predict' \\\n -H 'accept: application/json' \\\n -H 'Content-Type: multipart/form-data' \\\n -F 'file=@test_img.png;type=image/png'\n```\n\n```text\nFuture getImage() async {\n var imageTmp = await ImagePicker.pickImage(source: ImageSource.gallery);\n setState(() {\n image1 = imageTmp;\n print('Image Path $image1');\n });\n }\n```\n\n```text\ndoUpload() {\n /*\n curl -X 'POST' \\\n 'http://192.168.178.26:8345/api/predict' \\\n -H 'accept: application/json' \\\n -H 'Content-Type: multipart/form-data' \\\n -F 'file=@test_img.png;type=image/png'\n\n */\n var request = http.MultipartRequest(\n 'POST',\n Uri.parse(\"http://<my locally hosted ip>:8345/api/predict\"),\n );\n Map<String, String> headers = {\"Content-type\": \"multipart/form-data\"};\n request.files.add(\n http.MultipartFile(\n 'image',\n image1.readAsBytes().asStream(),\n image1.lengthSync(),\n filename: 'filename',\n contentType: MediaType('image', 'png'),\n ),\n );\n request.headers.addAll(headers);\n print(\"request: \" + request.toString());\n request.send().then((value) => print(value.statusCode));\n }\n```\n\n```text\nFile image1;\n```\n\n```text\ndoUpload()\n```\n\n```text\nFile: '/data/user/0/<my package name>/cache/image_picker3300408791299772729jpg'\n```\n\n```text\nvalue\n```\n\n```text\nfinal request = http.MultipartRequest(\n 'POST',\n Uri.parse('http://<my locally hosted ip>:8345/api/predict'),\n );\n\n request.files.add(\n await http.MultipartFile.fromPath(\n 'file', // NOTE - this value must match the 'file=' at the start of -F\n image1.path,\n contentType: MediaType('image', 'png'),\n ),\n );\n\n final response = await http.Response.fromStream(await request.send());\n\n print(response.body);\n```\n\n```text\ncurl\n```\n\n========================================\n\nComments:\n- This worked perfectly, thanks a bunch! It returned `INFO: - \"POST /api/predict HTTP/1.1\" 200 OK` I only had additionally change the function to `doUpload() async {` due to your `await`. Which is probably for the better anyway :)\n- Also thanks for explaining what made it work, with the `file` comment","metadata":{"transformedAt":"2026-08-18T18:32:29.149Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":172,"estimatedTokens":1260}}603{"id":"stack-70243528","source":"stackoverflow","questionId":70243528,"title":"Propagate top-level span ID's in OpenTelemetry","tags":["python","fastapi","open-telemetry","distributed-tracing"],"text":"Title: Propagate top-level span ID's in OpenTelemetry\nTags: python, fastapi, open-telemetry, distributed-tracing\nSource: Stack Overflow\n\nQuestion:\nI'm trying to get OpenTelemetry tracing working with FastAPI and Requests. Currently, my setup looks like this:\n\n```\nimport requests\nfrom opentelemetry.baggage.propagation import W3CBaggagePropagator\nfrom opentelemetry.propagators.composite import CompositePropagator\nfrom fastapi import FastAPI\nfrom opentelemetry.instrumentation.fastapi import FastAPIInstrumentor\nfrom opentelemetry.instrumentation.requests import RequestsInstrumentor\nfrom opentelemetry.propagate import set_global_textmap\nfrom opentelemetry.propagators.b3 import B3MultiFormat\nfrom opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator\n\nset_global_textmap(CompositePropagator([B3MultiFormat(), TraceContextTextMapPropagator(), W3CBaggagePropagator()]))\n\napp = FastAPI()\n\nFastAPIInstrumentor.instrument_app(app)\nRequestsInstrumentor().instrument()\n\n@app.get(\"/\")\nasync def get_things():\n r = requests.get(\"http://localhost:8081\")\n\n return {\n \"Hello\": \"world\",\n \"result\": r.json()\n }\n```\n\nThe `/` endpoint just does a GET to another service that looks basically like this one, just with some middleware to log the incoming headers.\n\nIf I send a request like this (httpie format),\n\n```\nhttp :8000 'x-b3-traceid: f8c83f4b5806299983da51de66d9a242' 'x-b3-spanid: ba24f165998dfd8f' 'x-b3-sampled: 1'\n```\n\nI expect that the downstream service, i.e. the one being requested by `requests.get(\"http://localhost:8081\")`, to receive headers that look something like\n\n```\n{\n \"x-b3-traceid\": \"f8c83f4b5806299983da51de66d9a242\",\n \"x-b3-spanid\": \"xxxxxxx\", # some generated value from the upstream service\n \"x-b3-parentspanid\": \"ba24f165998dfd8f\", \n \"x-b3-sampled\": \"1\"\n}\n```\n\nBut what I'm getting is basically exactly what I sent to the upstream service:\n\n```\n{\n \"x-b3-traceid\": \"f8c83f4b5806299983da51de66d9a242\",\n \"x-b3-spanid\": \"ba24f165998dfd8f\",\n \"x-b3-sampled\": \"1\"\n}\n```\n\nI must be missing something obvious, but can't seem to figure out exactly what.\n\nSending a W3C `traceparent` header results in the same exact situation (just with `traceparent` in the headers that are received downstream). Any pointers would be appreciated.\n\nEDIT - I'm not using any exporters, as in our environment, Istio is configured to export the traces. So we just care about the HTTP traces for now.\n\n========================================\n\nCode:\n```text\nimport requests\nfrom opentelemetry.baggage.propagation import W3CBaggagePropagator\nfrom opentelemetry.propagators.composite import CompositePropagator\nfrom fastapi import FastAPI\nfrom opentelemetry.instrumentation.fastapi import FastAPIInstrumentor\nfrom opentelemetry.instrumentation.requests import RequestsInstrumentor\nfrom opentelemetry.propagate import set_global_textmap\nfrom opentelemetry.propagators.b3 import B3MultiFormat\nfrom opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator\n\nset_global_textmap(CompositePropagator([B3MultiFormat(), TraceContextTextMapPropagator(), W3CBaggagePropagator()]))\n\napp = FastAPI()\n\nFastAPIInstrumentor.instrument_app(app)\nRequestsInstrumentor().instrument()\n\n@app.get(\"/\")\nasync def get_things():\n r = requests.get(\"http://localhost:8081\")\n\n return {\n \"Hello\": \"world\",\n \"result\": r.json()\n }\n```\n\n```text\nhttp :8000 'x-b3-traceid: f8c83f4b5806299983da51de66d9a242' 'x-b3-spanid: ba24f165998dfd8f' 'x-b3-sampled: 1'\n```\n\n```text\n{\n \"x-b3-traceid\": \"f8c83f4b5806299983da51de66d9a242\",\n \"x-b3-spanid\": \"xxxxxxx\", # some generated value from the upstream service\n \"x-b3-parentspanid\": \"ba24f165998dfd8f\", \n \"x-b3-sampled\": \"1\"\n}\n```\n\n```text\n{\n \"x-b3-traceid\": \"f8c83f4b5806299983da51de66d9a242\",\n \"x-b3-spanid\": \"ba24f165998dfd8f\",\n \"x-b3-sampled\": \"1\"\n}\n```\n\n```text\n/\n```\n\n```text\nrequests.get(\"http://localhost:8081\")\n```\n\n```text\ntraceparent\n```\n\n```text\ntraceparent\n```\n\n```py\n...\nfrom opentelemetry.trace import set_tracer_provider\nfrom opentelemetry.sdk.trace import TracerProvider\nfrom opentelemetry.sdk.resources import Resource\n\nset_tracer_provider(TracerProvider(\n resource=Resource.create({\"serice.name\": \"my-service\"})\n))\n\n...\n```\n\n```text\nB3MultiFormat\n```\n\n```text\nX-B3-ParentSpanId\n```\n\n```text\nX-B3-TraceId\n```\n\n```text\nX-B3-SpanId\n```\n\n```text\nparentSpanId\n```\n\n========================================\n\nComments:\n- Off-topic, but you are calling a synchronous IO function from \"requests\" in an async function; it is better to keep call stack consistent.\n- Thanks for your answer. How do \"parent spans\" then get propagated between services? And why does my spanid stay the same between the incoming request and the call to the downstream service? That doesn't seem logical, or am I missing something?\n- Are you saying span_id received in downstream service \"localhost:8081\" is same as the span_id received by FastAPI service? That shouldn't be the case. Are you seeing any traces for the \"/\" route?\n- I updated the answer based on another round of detailed look. Please let me know if it doesn't solve the issue.\n- Well, at least now I have different span ID's in both services! But still no obvious way to tie them together, unless I export the traces directly from the app, which I don't actually want to do. There must be some way to have the parent span ID propagated to the downstream service?\n- What do you mean by tie them together without exporting the traces. If you are not going to export the traces from app/service how do you tie them? In opentelemetry data model parent id is the top level field of Span message and all backends use that for representation github.com/open-telemetry/opentelemetry-proto/blob/main/…\n- From my knowledge parent_span_id in trace context propagation is either deprecated or fully ignored (in your case). You don't even see it's mention in the W3C trace context propagation spec w3.org/TR/trace-context/#traceparent-header-field-values.\n- Added another edit to provide more info.\n- That's unfortunate. So basically the only way for me to get this information (as to which spans come from which upstream spans) is to export them from within the application itself? Thanks for your input and links to the specs, quite helpful indeed!\n- Yes, the id info you want is parent of parent span which is never propagated through header and only can be derived from the full spans exported.","metadata":{"transformedAt":"2026-08-18T18:32:29.149Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":14,"totalLines":184,"estimatedTokens":1606}}604{"id":"stack-73130722","source":"stackoverflow","questionId":73130722,"title":"API response of FastAPI delete call","tags":["python","python-3.x","fastapi"],"text":"Title: API response of FastAPI delete call\nTags: python, python-3.x, fastapi\nSource: Stack Overflow\n\nQuestion:\nIs it necessary to return anything when a delete is successful, or does merely specifying the status code in the decorator do everything? For example:\n\n```\n@app.delete(\"/posts/{id}\", status_code=status.HTTP_204_NO_CONTENT)\ndef delete_post(id: int):\n cursor.execute(\"DELETE FROM posts WHERE id=%s\", (id,))\n conn.commit()\n return Response(status_code=status.HTTP_204_NO_CONTENT)\n```\n\nOr, can I remote the `return` statement entirely?\n\n```\n@app.delete(\"/posts/{id}\", status_code=status.HTTP_204_NO_CONTENT)\ndef delete_post(id: int):\n cursor.execute(\"DELETE FROM posts WHERE id=%s\", (id,))\n conn.commit()\n```\n\n========================================\n\nCode:\n```text\n@app.delete(\"/posts/{id}\", status_code=status.HTTP_204_NO_CONTENT)\ndef delete_post(id: int):\n cursor.execute(\"DELETE FROM posts WHERE id=%s\", (id,))\n conn.commit()\n return Response(status_code=status.HTTP_204_NO_CONTENT)\n```\n\n```text\n@app.delete(\"/posts/{id}\", status_code=status.HTTP_204_NO_CONTENT)\ndef delete_post(id: int):\n cursor.execute(\"DELETE FROM posts WHERE id=%s\", (id,))\n conn.commit()\n```\n\n```text\nreturn\n```\n\n```text\nb””\n```\n\n========================================\n\nComments:\n- Is this specified anywhere in the docs or the repo?\n- This answer is more than 2 years old, there have been many releases of FastAPI since then. I can’t attest to the current accuracy of this answer anymore.","metadata":{"transformedAt":"2026-08-18T18:32:29.149Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":55,"estimatedTokens":373}}605{"id":"stack-72061637","source":"stackoverflow","questionId":72061637,"title":"FastAPI: How to upload a file without using multipart/form-data request?","tags":["python","file-upload","fastapi","starlette"],"text":"Title: FastAPI: How to upload a file without using multipart/form-data request?\nTags: python, file-upload, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nI have a FastAPI endpoint for handling file uploads that looks something like this:\n\n```\n@app.post('/upload')\nasync def accept_some_file(f: UploadFile):\n content = await f.read()\n # ... do stuff with content and generate a response\n```\n\nbut this appears to only work with `multipart/form-data` encoded payloads.\n\nI'd like to be able to send file bytes directly through a request that looks like this:\n\n```\nPOST /upload HTTP/1.1\nHost: localhost:8080\nUser-Agent: curl/7.79.1\nAccept: */*\nContent-Type: image/jpeg\nContent-Length: 11044\n\n... image bytes\n```\n\nIs there a FastAPI setting I can use to allow this? Or is there another request type that makes more sense for this use case?\n\n========================================\n\nCode:\n```py\n@app.post('/upload')\nasync def accept_some_file(f: UploadFile):\n content = await f.read()\n # ... do stuff with content and generate a response\n```\n\n```text\nPOST /upload HTTP/1.1\nHost: localhost:8080\nUser-Agent: curl/7.79.1\nAccept: */*\nContent-Type: image/jpeg\nContent-Length: 11044\n\n... image bytes\n```\n\n```text\nmultipart/form-data\n```\n\n```py\nfrom fastapi import Request\n\n@app.post('/upload')\nasync def upload_file(request: Request):\n body = await request.body()\n```\n\n```py\n@app.post('/upload')\nasync def upload_file(request: Request):\n chunks = []\n async for chunk in request.stream():\n chunks.append(chunk)\n body = b''.join(chunks)\n```\n\n```text\nbytes\n```\n\n```text\nawait request.body()\n```\n\n```text\ndef\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\nstream\n```\n\n```text\nrequest.stream()\n```\n\n```text\nrequest.body()\n```\n\n```text\nbody\n```\n\n```text\naiofiles\n```\n\n```text\nstreaming_form_data\n```\n\n========================================\n\nComments:\n- This question helps you? stackoverflow.com/questions/63048825/…\n- No, that question involves using `multipart/form-data` as the upload encoding. I would like to avoid that.","metadata":{"transformedAt":"2026-08-18T18:32:29.149Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":16,"totalLines":122,"estimatedTokens":515}}606{"id":"stack-70693671","source":"stackoverflow","questionId":70693671,"title":"Interaction Between Flutter and FastAPI","tags":["flutter","rest","fastapi","python-3.8"],"text":"Title: Interaction Between Flutter and FastAPI\nTags: flutter, rest, fastapi, python-3.8\nSource: Stack Overflow\n\nQuestion:\nUbuntu 20.04LTS, with Python 3.8 for FastAPI, and Flutter 2.8.1, with Android SDK version 32.0.0.\n\nI am trying to send a Map from Flutter to FastAPI.\nI have figured out how to POST, but how can I receive it from FastAPI side?\n\nIs database necessary?\n\nFlutter side:\n\n```\nimport 'src/models/keywords_model.dart';\nimport 'package:flutter/material.dart';\nimport 'package:http/http.dart' show get, post;\nimport 'dart:convert';\n\nclass SearchScreen extends StatefulWidget {\n const SearchScreen(List keywords, {Key? key}) : super(key: key);\n\n @override\n _SearchScreenState createState() => _SearchScreenState();\n}\n\nclass _SearchScreenState extends State {\n final _formKey = GlobalKey();\n final List keywords = [];\n final Map keywordsMap = {};\n\n \n Future postKeywords(parsedJson) async {\n await post(Uri.http(\"10.0.2.2:8000\", \"/search\"), body: parsedJson);\n }\n\n @override\n Widget build(BuildContext context) {\n return Scaffold(\n floatingActionButton: FloatingActionButton(\n child: Icon(Icons.search),\n onPressed: () {\n print('---------------' * 20);\n for (int i = 0 ; i FastAPI side:\n\n```\nfrom fastapi import FastAPI\nimport json\n\napp = FastAPI()\n\n@app.post(\"/search/\")\nasync def receive_keywords():\n \"\"\"What to Put Here?\"\"\"\n json.loads(?????)\n```\n\n========================================\n\nTop Answer:\nIf you wanna using flutter as the frontend, I really recommend you to use dio and retrofit to handle the API integration. And those two packages would help you easily manage and handle all your API endpoints.\n\nTake the below code as an example.\n\n```\n// Password - Controller\n@POST(\"merchant/change/password\")\nFuture merchantChangePassword(\n @Query('merchantId') String merchantId,\n @Query('oldPassword') String oldPassword,\n @Query('newPassword') String newPassword,\n @Query('confirmPassword') String confirmPassword,\n @Query('session') String session,\n);\n```\n\nYou need to write the python as like:\n\n```\n@app.post(\"/merchant/change/password\")\nasync def receive_keywords(\n merchantId: int = Query(None, alias='merchantId')\n oldPassword: str = Query(None, alias='oldPassword')\n newPassword: str = Query(None, alias='newPassword')\n confirmPassword: str = Query(None, alias='confirmPassword')\n session: str = Query(None, alias='session')\n):\n return True\n```\n\n========================================\n\nCode:\n```text\nimport 'src/models/keywords_model.dart';\nimport 'package:flutter/material.dart';\nimport 'package:http/http.dart' show get, post;\nimport 'dart:convert';\n\nclass SearchScreen extends StatefulWidget {\n const SearchScreen(List<KeywordsModel> keywords, {Key? key}) : super(key: key);\n\n\n @override\n _SearchScreenState createState() => _SearchScreenState();\n}\n\n\nclass _SearchScreenState extends State<SearchScreen> {\n final _formKey = GlobalKey<FormState>();\n final List<String> keywords = [];\n final Map<String, dynamic> keywordsMap = {};\n\n \n Future<void> postKeywords(parsedJson) async {\n await post(Uri.http(\"10.0.2.2:8000\", \"/search\"), body: parsedJson);\n }\n\n @override\n Widget build(BuildContext context) {\n return Scaffold(\n floatingActionButton: FloatingActionButton(\n child: Icon(Icons.search),\n onPressed: () {\n print('---------------' * 20);\n for (int i = 0 ; i < keywords.length ; i++) {\n keywordsMap[\"$i\"] = keywords[i];\n }\n var parsedJson = json.encode(keywordsMap);\n postKeywords(parsedJson);\n },\n ),\n\n/// Skipped many lines\n\n );\n }\n}\n```\n\n```text\nfrom fastapi import FastAPI\nimport json\n\n\napp = FastAPI()\n\n@app.post(\"/search/\")\nasync def receive_keywords():\n \"\"\"What to Put Here?\"\"\"\n json.loads(?????)\n```\n\n```dart\n// Password - Controller\n@POST(\"merchant/change/password\")\nFuture<bool> merchantChangePassword(\n @Query('merchantId') String merchantId,\n @Query('oldPassword') String oldPassword,\n @Query('newPassword') String newPassword,\n @Query('confirmPassword') String confirmPassword,\n @Query('session') String session,\n);\n```\n\n```py\n@app.post(\"/merchant/change/password\")\nasync def receive_keywords(\n merchantId: int = Query(None, alias='merchantId')\n oldPassword: str = Query(None, alias='oldPassword')\n newPassword: str = Query(None, alias='newPassword')\n confirmPassword: str = Query(None, alias='confirmPassword')\n session: str = Query(None, alias='session')\n):\n return True\n```\n\n```text\n@_app.get(\"/\")\ndef read_root():\n \"\"\"Root route\"\"\"\n return {\"Ping\": \"Pong\"}\n```\n\n```text\nresponse = {\"limit\": limit, \"offset\": offset, \"data\": users}\n```\n\n========================================\n\nComments:\n- chopper is also viable!","metadata":{"transformedAt":"2026-08-18T18:32:29.149Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":6,"totalLines":193,"estimatedTokens":1176}}607{"id":"stack-71665139","source":"stackoverflow","questionId":71665139,"title":"How to send a FastAPI response without redirecting the user to another page?","tags":["python","html","forms","fastapi"],"text":"Title: How to send a FastAPI response without redirecting the user to another page?\nTags: python, html, forms, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am creating an API using FastAPI, which receives `form-data` from an HTML page, process the data (requiring a few moments) and returns a message saying this task is complete.\n\nThis is my backend:\n\n```\nfrom cgi import test\nfrom fastapi import FastAPI, Form, Request\nfrom starlette.responses import FileResponse\n\napp = FastAPI()\n\n@app.post(\"/\")\nasync def swinir_dict_creation(request: Request,taskname: str = Form(...),tasknumber: int = Form(...)):\n\n args_to_test = {\"taskname\":taskname, \"tasknumber\":tasknumber} # dict creation\n print('\\n',args_to_test,'\\n')\n # my_function_does_some_data_treatment.main(args_to_test)\n # return 'Treating...'\n return 'Super resolution completed! task '+str(args_to_test[\"tasknumber\"])+' of '+args_to_test[\"taskname\"]+' done'\n\n@app.get(\"/\")\nasync def read_index():\n return FileResponse(\"index.html\")\n```\n\nThis is my frontend code:\n\n```\n\n \n \n\n### **Super resolution image treatment**\n\n \n \n \n\n Task name*:\n \n \n Task number*:\n \n\n * Cannot be null\n\n Start\n \n \n \n\n```\n\nSo the frontend page looks like this:\n\nhttps://i.sstatic.net/NDOvM.png\n\nWhen the processing is finished in the backend, after the user submitted some data, the return statement from FastAPI backend simply redirects the user to a new page showing only the return message. I was looking for a alternative that would keep the HTML form appearing and display the message returned from the server below this form. For example:\n\nhttps://i.sstatic.net/NvNIv.png\n\nI searched in FastAPI documentation about requests, but I haven't found anything that could avoid modifying my original HTML page.\n\n========================================\n\nCode:\n```text\nfrom cgi import test\nfrom fastapi import FastAPI, Form, Request\nfrom starlette.responses import FileResponse\n\napp = FastAPI()\n\n@app.post(\"/\")\nasync def swinir_dict_creation(request: Request,taskname: str = Form(...),tasknumber: int = Form(...)):\n\n args_to_test = {\"taskname\":taskname, \"tasknumber\":tasknumber} # dict creation\n print('\\n',args_to_test,'\\n')\n # my_function_does_some_data_treatment.main(args_to_test)\n # return 'Treating...'\n return 'Super resolution completed! task '+str(args_to_test[\"tasknumber\"])+' of '+args_to_test[\"taskname\"]+' done'\n\n@app.get(\"/\")\nasync def read_index():\n return FileResponse(\"index.html\")\n```\n\n```text\n<html>\n <head>\n <h1><b>Super resolution image treatment</b></h1> \n <body>\n <form action=\"http://127.0.0.1:8000/\" method=\"post\" enctype=\"multipart/form-data\">\n\n <label for=\"taskname\" style=\"font-size: 20px\">Task name*:</label>\n <input type=\"text\" name=\"taskname\" id=\"taskname\" />\n \n <label for=\"tasknumber\" style=\"font-size: 20px\">Task number*:</label>\n <input type=\"number\" name=\"tasknumber\" id=\"tasknumber\" />\n\n <b><p style=\"display:inline\"> * Cannot be null</p></b>\n <button type=\"submit\" value=\"Submit\">Start</button>\n </form>\n </body>\n </head>\n</html>\n```\n\n```text\nform-data\n```\n\n```py\nfrom fastapi import FastAPI, Form, Request\nfrom fastapi.templating import Jinja2Templates\n\napp = FastAPI()\ntemplates = Jinja2Templates(directory=\"templates\")\n\n@app.post(\"/submit\")\nasync def submit(request: Request, taskname: str = Form(...), tasknumber: int = Form(...)):\n return f'Super resolution completed! task {tasknumber} of {taskname} done'\n\n@app.get(\"/\")\nasync def index(request: Request):\n return templates.TemplateResponse(\"index.html\", {\"request\": request})\n```\n\n```html\n<!DOCTYPE html>\n<html>\n <body>\n <h1>Super resolution image treatment</h1>\n <form method=\"post\" id=\"myForm\">\n <label for=\"taskname\" style=\"font-size: 20px\">Task name*:</label><br>\n <input type=\"text\" name=\"taskname\" id=\"taskname\"><br>\n <label for=\"tasknumber\" style=\"font-size: 20px\">Task number*:</label><br>\n <input type=\"number\" name=\"tasknumber\" id=\"tasknumber\">\n <p style=\"display:inline\"><b>* Cannot be null</b></p><br><br>\n <input type=\"button\" value=\"Start\" onclick=\"submitForm()\">\n </form>\n <div id=\"responseArea\"></div>\n <script>\n function submitForm() {\n var formElement = document.getElementById('myForm');\n var data = new FormData(formElement);\n fetch('/submit', {\n method: 'POST',\n body: data,\n })\n .then(resp => resp.text()) // or, resp.json(), etc.\n .then(data => {\n document.getElementById(\"responseArea\").innerHTML = data;\n })\n .catch(error => {\n console.error(error);\n });\n }\n </script>\n </body>\n</html>\n```\n\n```text\nTemplateResponse\n```\n\n```text\nFileResponse\n```\n\n```text\n<form>\n```\n\n```text\nsubmit\n```\n\n```text\nJSON\n```\n\n```text\nFiles\n```\n\n```text\nForm\n```\n\n```text\nJSON\n```\n\n========================================\n\nComments:\n- You’ll need to make an AJAX call to the API using something like the Fetch API. Duplicate of How can I make an AJAX call without jQuery?\n- @esqew, it may be, but the answer I got here was way clearer to solve the problem and moreover it shows how to integrate it with a HTML code. So I'll check 'not duplicate' thinking about future people that might have the same doubt.","metadata":{"transformedAt":"2026-08-18T18:32:29.149Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":13,"totalLines":205,"estimatedTokens":1366}}608{"id":"stack-70749255","source":"stackoverflow","questionId":70749255,"title":"Proper way to cancel remaining trio nursery tasks inside fastAPI websocket?","tags":["python","websocket","async-await","fastapi","python-trio"],"text":"Title: Proper way to cancel remaining trio nursery tasks inside fastAPI websocket?\nTags: python, websocket, async-await, fastapi, python-trio\nSource: Stack Overflow\n\nQuestion:\nI'm still quite new to websockets and I've been given a problem I'm having a hard time solving.\n\nI need to build a websocket endpoint with FastAPI in which a group of tasks are run asynchronously (to do so I went with trio) with each task returning a json value through the websocket in realtime.\n\nI've managed to meet these requirements, with my code looking like this:\n\n```\n@router.websocket('/stream')\nasync def runTasks(\n websocket: WebSocket\n):\n # Initialise websocket\n await websocket.accept()\n while True:\n # Receive data\n tasks = await websocket.receive_json()\n # Run tasks asynchronously (limiting to 10 tasks at a time)\n async with trio.open_nursery() as nursery:\n limit = trio.CapacityLimiter(10)\n for task in tasks:\n nursery.start_soon(run_task, limit, task, websocket)\n```\n\nWith `run_task` looking something like this:\n\n```\nasync def run_task(limit, task, websocket):\n async with limit:\n # Complete task / transaction\n await websocket.send_json({\"placeholder\":\"data\"})\n```\n\nBut now, given two scenarios, I'm supposed to cancel/skip the current remaining nursery tasks, but I'm a bit loss as to how I could achieve that.\n\nThe two scenarios I'm given are as follows:\n\n**Scenario 1:** Imagining the endpoint is called when a user presses a button, if the user were to press the button again while some tasks were still running they should be cancelled or skipped and the process should begin anew\n\n**Scenario 2:** If the websocket were to be closed, the user were to refresh the page, or exit before the completion of the nursery tasks, the remaining tasks should be cancelled or skipped\n\nI'm trying to read more into Python - How to cancel a specific task spawned by a nursery in python-trio but I'm still puzzled as to how I can cancel the previous nursery with cancel scope before entering the new one. Should I create an additional task that watches a variable or something and cancels once it changes? But then I'd have to stop that task once all the other tasks have finished\n\n========================================\n\nCode:\n```py\n@router.websocket('/stream')\nasync def runTasks(\n websocket: WebSocket\n):\n # Initialise websocket\n await websocket.accept()\n while True:\n # Receive data\n tasks = await websocket.receive_json()\n # Run tasks asynchronously (limiting to 10 tasks at a time)\n async with trio.open_nursery() as nursery:\n limit = trio.CapacityLimiter(10)\n for task in tasks:\n nursery.start_soon(run_task, limit, task, websocket)\n```\n\n```py\nasync def run_task(limit, task, websocket):\n async with limit:\n # Complete task / transaction\n await websocket.send_json({\"placeholder\":\"data\"})\n```\n\n```text\nrun_task\n```\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Websocket test</title>\n</head>\n<body>\n <button id=\"start\">Start connection</button>\n <button id=\"close\" disabled>Close connection</button>\n <input type=\"text\" id=\"input_\" value=\"INPUT_YOUR_UUID\">\n\n <div id=\"state\">Status: Waiting for connection</div>\n\n <script>\n let state = document.getElementById(\"state\")\n let start_btn = document.getElementById(\"start\")\n let close_btn = document.getElementById(\"close\")\n let input_ = document.getElementById(\"input_\")\n\n function sleep(sec) {\n state.textContent = `Status: sleeping ${sec} seconds`\n return new Promise((func) => setTimeout(func, sec * 1000))\n }\n\n function websocket_test() {\n return new Promise((resolve, reject) => {\n let socket = new WebSocket(\"ws://127.0.0.1:8000/stream\")\n\n socket.onopen = function () {\n state.textContent = \"Status: Sending UUID - \" + input_.value\n socket.send(input_.value)\n close_btn.disabled = false\n close_btn.onclick = function () {socket.close()}\n }\n socket.onmessage = function (msg) {\n state.textContent = \"Status: Message Received - \" + msg.data\n socket.send(\"Received\")\n }\n socket.onerror = function (error) {\n reject(error)\n state.textContent = \"Status: Error encountered\"\n }\n socket.onclose = function () {\n state.textContent = \"Status: Connection Stopped\"\n close_btn.disabled = true\n }\n })\n }\n\n start_btn.onclick = websocket_test\n\n </script>\n</body>\n</html>\n```\n\n```py\n\"\"\"\nNursery cancellation demo\n\"\"\"\nimport itertools\nfrom typing import Dict, Tuple\n\nimport trio\nimport fastapi\nimport hypercorn\nfrom hypercorn.trio import serve\n\n\nGLOBAL_NURSERY_STORAGE: Dict[str, Tuple[trio.CancelScope, trio.Event]] = {}\nTIMEOUT = 5\n\nrouter = fastapi.APIRouter()\n\n\n@router.websocket('/stream')\nasync def run_task(websocket: fastapi.WebSocket):\n # accept and receive UUID\n # Replace UUID with anything client-specific\n await websocket.accept()\n uuid_ = await websocket.receive_text()\n\n print(f\"[{uuid_}] CONNECTED\")\n\n # check if nursery exist in session, if exists, cancel it and wait for it to end.\n if uuid_ in GLOBAL_NURSERY_STORAGE:\n print(f\"[{uuid_}] STOPPING NURSERY\")\n cancel_scope, event = GLOBAL_NURSERY_STORAGE[uuid_]\n cancel_scope.cancel()\n await event.wait()\n\n # create new event, and start new nursery.\n cancel_done_event = trio.Event()\n\n async with trio.open_nursery() as nursery:\n # save ref\n GLOBAL_NURSERY_STORAGE[uuid_] = nursery.cancel_scope, cancel_done_event\n\n try:\n for n in itertools.count(0, 1):\n nursery.start_soon(task, n, uuid_, websocket)\n await trio.sleep(1)\n\n # wait for client response\n with trio.fail_after(TIMEOUT):\n recv = await websocket.receive_text()\n print(f\"[{uuid_}] RECEIVED {recv}\")\n\n except trio.TooSlowError:\n # client possibly left without proper disconnection, due to network issue\n print(f\"[{uuid_}] CLIENT TIMEOUT\")\n\n except fastapi.websockets.WebSocketDisconnect:\n # client performed proper disconnection\n print(f\"[{uuid_}] CLIENT DISCONNECTED\")\n\n # fire event, and pop reference if any.\n cancel_done_event.set()\n GLOBAL_NURSERY_STORAGE.pop(uuid_, None)\n print(f\"[{uuid_}] NURSERY STOPPED & REFERENCE DROPPED\")\n\n\nasync def task(text, uuid_, websocket: fastapi.WebSocket):\n await websocket.send_text(str(text))\n print(f\"[{uuid_}] SENT {text}\")\n\n\nif __name__ == '__main__':\n cornfig = hypercorn.Config()\n # cornfig.bind = \"ws://127.0.0.1:8000\"\n trio.run(serve, router, cornfig)\n```\n\n```none\n[2022-01-31 21:23:12 +0900] [17204] [INFO] Running on http://127.0.0.1:8000 (CTRL + C to quit)\n[2] CONNECTED < start connection on tab 2\n[2] SENT 0\n[2] RECEIVED Received\n[2] SENT 1\n[2] RECEIVED Received\n[2] SENT 2\n[2] RECEIVED Received\n[2] SENT 3\n[2] RECEIVED Received\n[2] SENT 4\n[1] CONNECTED < start connection on tab 1\n[1] SENT 0\n[2] RECEIVED Received\n[2] SENT 5\n[1] RECEIVED Received\n[1] SENT 1\n...\n[2] SENT 18\n[1] RECEIVED Received\n[1] SENT 14\n[2] RECEIVED Received\n[2] SENT 19\n[1] CLIENT DISCONNECTED < closed connection on tab 1\n[1] NURSERY STOPPED & REFERENCE DROPPED < tab 1 nursery terminated\n[2] RECEIVED Received\n[2] SENT 20\n[2] RECEIVED Received\n[2] SENT 21\n[1] CONNECTED < start connection on tab 1\n[1] SENT 0\n[2] RECEIVED Received\n[2] SENT 22\n[1] RECEIVED Received\n...\n[2] SENT 26\n[1] RECEIVED Received\n[1] SENT 5\n[2] CLIENT DISCONNECTED < tab 2 closed\n[2] NURSERY STOPPED & REFERENCE DROPPED < tab 2 nursery terminated\n[1] RECEIVED Received\n[1] SENT 6\n[1] RECEIVED Received\n[1] SENT 7\n[1] RECEIVED Received\n[1] SENT 8\n[1] CONNECTED < start another connection on tab 1 without closing\n[1] STOPPING NURSERY < previous connection on tab 1 terminating\n[1] NURSERY STOPPED & REFERENCE DROPPED < previous connection on tab 1 terminated\n[1] SENT 0\n[1] RECEIVED Received\n[1] SENT 1\n...\n[1] RECEIVED Received\n[1] SENT 8\n[1] CLIENT DISCONNECTED < Refreshed tab 1\n[1] NURSERY STOPPED & REFERENCE DROPPED < tab 1 nursery terminated\n...\n```\n\n```text\nUUID\n```\n\n```text\nTuple[trio.CancelScope, trio.Event]\n```\n\n```text\ntrio.fail_after\n```\n\n```text\nexcept trio.TooSlowError\n```\n\n========================================\n\nComments:\n- To cancel the tasks, first you need to catch the correct exception in the `while` loop to know if something goes wrong or just disconnected. Once the exception is caught, use nursery's `cancel_scope` to cancel the running tasks. And btw, I think websocket is not reliable enough to know what happended to the client, since most websocket service make use of ping-pong to check connection.\n- @halfelf right, thank you. I'm using websockets because I needed a way to push data to a client in realtime from asynchronous trio nursery tasks.","metadata":{"transformedAt":"2026-08-18T18:32:29.149Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":10,"totalLines":294,"estimatedTokens":2315}}609{"id":"stack-73633371","source":"stackoverflow","questionId":73633371,"title":"How to configure FastAPI to publish logs to CloudWatch?","tags":["python","amazon-web-services","aws-lambda","fastapi"],"text":"Title: How to configure FastAPI to publish logs to CloudWatch?\nTags: python, amazon-web-services, aws-lambda, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have a FastAPI service that works as expected in every regard except the logging, only when it runs as a AWS Lambda function.\n\nWhen running it locally the logs are displayed on the console as expected:\n\n```\nINFO: 127.0.0.1:62160 - \"POST /api/v1/feature-requests/febbbc21-9650-44e6-8df5-80c8bb33b6ea/upvote HTTP/1.1\" 200 OK\nINFO: 127.0.0.1:62158 - \"OPTIONS /api/v1/feature-requests HTTP/1.1\" 200 OK\nINFO: 127.0.0.1:62160 - \"GET /api/v1/feature-requests HTTP/1.1\" 200 OK\nINFO: 127.0.0.1:62158 - \"OPTIONS /api/v1/feature-requests-meta HTTP/1.1\" 200 OK\nINFO: 127.0.0.1:62160 - \"GET /api/v1/feature-requests-meta HTTP/1.1\" 200 OK\nINFO: 127.0.0.1:62160 - \"GET /api/v1/feature-requests/febbbc21-9650-44e6-8df5-80c8bb33b6ea HTTP/1.1\" 200 OK\nINFO: 127.0.0.1:62160 - \"GET /api/v1/feature-requests-meta/febbbc21-9650-44e6-8df5-80c8bb33b6ea HTTP/1.1\" 200 OK\n```\n\nHowever, when deployed as a Lambda function the logs are not there:\n\n```\n2022-09-07T10:44:57.426+02:00 START RequestId: fd44ae47-5bfb-42e3-aeb4-d9f29857bb39 Version: $LATEST\n2022-09-07T10:44:57.604+02:00 END RequestId: fd44ae47-5bfb-42e3-aeb4-d9f29857bb39\n2022-09-07T10:44:57.604+02:00 REPORT RequestId: fd44ae47-5bfb-42e3-aeb4-d9f29857bb39 Duration: 177.85 ms Billed Duration: 178 ms Memory Size: 2048 MB Max Memory Used: 152 MB Init Duration: 1733.88 ms\n2022-09-07T10:45:00.299+02:00 START RequestId: 08a7a6da-c2c6-446c-baa3-1d08c9816f5b Version: $LATEST\n2022-09-07T10:45:00.318+02:00 END RequestId: 08a7a6da-c2c6-446c-baa3-1d08c9816f5b\n```\n\nEven for the logs that are produced by our code (as opposed to the framework) are not visible when running as a Lambda function.\n\nConfiguration:\n\nIn app.py\n\n```\nLOG = logging.getLogger()\nlog_format = \"%(asctime)s %(levelname)s %(message)s\"\nlog_date_fmt = \"%Y-%m-%d %H:%M:%S\"\nlogging.basicConfig(\n format=log_format,\n level=logging.INFO,\n datefmt=log_date_fmt,\n)\n```\n\nIn every other Python file:\n\n```\nLOG = logging.getLogger(__name__)\n```\n\nlogging.conf\n\n```\n[loggers]\nkeys=root,api,config\n\n[handlers]\nkeys=console_handler\n\n[formatters]\nkeys=normal_formatter\n\n[logger_root]\nlevel=INFO\nhandlers=console_handler\n\n[logger_api]\nlevel=INFO\nhandlers=console_handler\nqualname=api\npropagate=0\n\n[logger_config]\nlevel=INFO\nhandlers=console_handler\nqualname=config\npropagate=0\n\n[handler_console_handler]\nclass=StreamHandler\nlevel=INFO\nformatter=normal_formatter\nargs=(sys.stdout,)\n\n[formatter_normal_formatter]\nformat=%(asctime)s %(levelname)s %(name)s %(message)s\ndatefmt=%Y-%m-%d %H:%M:%S\n```\n\nI am not sure what else needs to happen to get the logs in CloudWatch.\n\n========================================\n\nTop Answer:\ntry `cloudwatch` library\n\nRun `pip install cloudwatch` in the console\n\nthen in your code:\n\n```\nimport logging\nfrom cloudwatch import cloudwatch\n\nlogger = logging.getLogger('cloudwatch_logger')\nformatter = logging.Formatter('%(asctime)s : %(levelname)s - %(message)s')\nhandler = cloudwatch.CloudwatchHandler(log_group = 'cloudwatch_log_group')\nhandler.setFormatter(formatter)\nlogger.setLevel(logging.DEBUG)\nlogger.addHandler(handler)\n```\n\nand then either use this logger to log to CloudWatch\n`logger.warning('I am here')` or add the handler to the root logger via logging configuration\n\n========================================\n\nCode:\n```text\nINFO: 127.0.0.1:62160 - \"POST /api/v1/feature-requests/febbbc21-9650-44e6-8df5-80c8bb33b6ea/upvote HTTP/1.1\" 200 OK\nINFO: 127.0.0.1:62158 - \"OPTIONS /api/v1/feature-requests HTTP/1.1\" 200 OK\nINFO: 127.0.0.1:62160 - \"GET /api/v1/feature-requests HTTP/1.1\" 200 OK\nINFO: 127.0.0.1:62158 - \"OPTIONS /api/v1/feature-requests-meta HTTP/1.1\" 200 OK\nINFO: 127.0.0.1:62160 - \"GET /api/v1/feature-requests-meta HTTP/1.1\" 200 OK\nINFO: 127.0.0.1:62160 - \"GET /api/v1/feature-requests/febbbc21-9650-44e6-8df5-80c8bb33b6ea HTTP/1.1\" 200 OK\nINFO: 127.0.0.1:62160 - \"GET /api/v1/feature-requests-meta/febbbc21-9650-44e6-8df5-80c8bb33b6ea HTTP/1.1\" 200 OK\n```\n\n```text\n2022-09-07T10:44:57.426+02:00 START RequestId: fd44ae47-5bfb-42e3-aeb4-d9f29857bb39 Version: $LATEST\n2022-09-07T10:44:57.604+02:00 END RequestId: fd44ae47-5bfb-42e3-aeb4-d9f29857bb39\n2022-09-07T10:44:57.604+02:00 REPORT RequestId: fd44ae47-5bfb-42e3-aeb4-d9f29857bb39 Duration: 177.85 ms Billed Duration: 178 ms Memory Size: 2048 MB Max Memory Used: 152 MB Init Duration: 1733.88 ms\n2022-09-07T10:45:00.299+02:00 START RequestId: 08a7a6da-c2c6-446c-baa3-1d08c9816f5b Version: $LATEST\n2022-09-07T10:45:00.318+02:00 END RequestId: 08a7a6da-c2c6-446c-baa3-1d08c9816f5b\n```\n\n```text\nLOG = logging.getLogger()\nlog_format = \"%(asctime)s %(levelname)s %(message)s\"\nlog_date_fmt = \"%Y-%m-%d %H:%M:%S\"\nlogging.basicConfig(\n format=log_format,\n level=logging.INFO,\n datefmt=log_date_fmt,\n)\n```\n\n```text\nLOG = logging.getLogger(__name__)\n```\n\n```text\n[loggers]\nkeys=root,api,config\n\n[handlers]\nkeys=console_handler\n\n[formatters]\nkeys=normal_formatter\n\n[logger_root]\nlevel=INFO\nhandlers=console_handler\n\n[logger_api]\nlevel=INFO\nhandlers=console_handler\nqualname=api\npropagate=0\n\n[logger_config]\nlevel=INFO\nhandlers=console_handler\nqualname=config\npropagate=0\n\n[handler_console_handler]\nclass=StreamHandler\nlevel=INFO\nformatter=normal_formatter\nargs=(sys.stdout,)\n\n[formatter_normal_formatter]\nformat=%(asctime)s %(levelname)s %(name)s %(message)s\ndatefmt=%Y-%m-%d %H:%M:%S\n```\n\n```py\nimport uvicorn\nlogging.config.fileConfig(\"logging.conf\", disable_existing_loggers=False)\nLOG = logging.getLogger(__name__)\n```\n\n```text\nimport logging\nfrom cloudwatch import cloudwatch\n\nlogger = logging.getLogger('cloudwatch_logger')\nformatter = logging.Formatter('%(asctime)s : %(levelname)s - %(message)s')\nhandler = cloudwatch.CloudwatchHandler(log_group = 'cloudwatch_log_group')\nhandler.setFormatter(formatter)\nlogger.setLevel(logging.DEBUG)\nlogger.addHandler(handler)\n```\n\n```text\ncloudwatch\n```\n\n```text\npip install cloudwatch\n```\n\n```text\nlogger.warning('I am here')\n```\n\n========================================\n\nComments:\n- Do you mean that I have the permission to write to CloudWatch?\n- Do you have these permissions in `serverless.yml`? `logs:CreateLogStream`, `logs:CreateLogGroup`, `logs:PutLogEvents`\n- Yes I do. The problem with FastAPI + logging. No idea how to configure the logging globally for all the FastAPI code.\n- Is it not possible to use the console just as is?\n- @Istvan There is, and it is even preferred (even from the `cloudwatch` library docs themselves): *\"You can still integrate it in your Serverless Infrastructure, but you might find it easier to just let AWS Handle the logs in this cases\"*. This library is indented to be used in code that does not run on AWS but still required to log to CloudWatch\n- I don't believe that Lambda (OP's infra) is compatible with uvicorn. In fact, there's a library `mangum` designed for this use case. No idea if similar declarations/syntax are required for Mangum.\n- Adding mangum logger settings worked for me: `python logger = logging.getLogger(\"mangum\") logger.setLevel(logging.DEBUG)`","metadata":{"transformedAt":"2026-08-18T18:32:29.149Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":10,"totalLines":230,"estimatedTokens":1783}}610{"id":"stack-73295786","source":"stackoverflow","questionId":73295786,"title":"How can I test for Exception cases in FastAPI with Pytest?","tags":["python","unit-testing","exception","pytest","fastapi"],"text":"Title: How can I test for Exception cases in FastAPI with Pytest?\nTags: python, unit-testing, exception, pytest, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am struggling to write test cases that will trigger an `Exception` within one of my FastAPI routes. I was thinking `pytest.Raises` would do what I intend, however that by itself doesn't seem to be doing what I thought it would.\n\nSince the TestClient runs the API client pretty much separately, it makes sense that I would have this issue - that being said, I am not sure what the best practice is to ensure a high code coverage in testing.\n\nHere is my test function:\n\n```\ndef test_function_exception():\n with pytest.raises(Exception):\n response = client.post(\"/\")\n assert response.status_code == 400\n```\n\nand here is the barebones route that I am hitting:\n\n```\n@router.post(\"/\")\ndef my_function():\n try:\n do_something()\n except Exception as e:\n raise HTTPException(400, \"failed to do something\")\n```\n\nIs there anyway that I can catch this Exception without making changes to the API route? If changes are needed, what are the changes required to ensure thorough testing?\n\n========================================\n\nCode:\n```py\ndef test_function_exception():\n with pytest.raises(Exception):\n response = client.post(\"/\")\n assert response.status_code == 400\n```\n\n```py\n@router.post(\"/\")\ndef my_function():\n try:\n do_something()\n except Exception as e:\n raise HTTPException(400, \"failed to do something\")\n```\n\n```text\nException\n```\n\n```text\npytest.Raises\n```\n\n```py\nfrom fastapi import FastAPI, HTTPException\nfrom fastapi.testclient import TestClient\nimport pytest\n\napp = FastAPI()\n\n\ndef do_something():\n return \"world\"\n\n\n@app.get(\"/myroute\")\nasync def myroute():\n try:\n text = do_something()\n return {\"hello\": text}\n except Exception:\n raise HTTPException(400, \"something went wrong\")\n```\n\n```py\nimport pytest\nfrom fastapi.testclient import TestClient\n\nfrom app import app\n\nclient = TestClient(app)\n\n\ndef replace_do_something():\n raise Exception()\n return\n\n\ndef test_read_main(monkeypatch: pytest.MonkeyPatch):\n response = client.get(\"/myroute\")\n assert response.status_code == 200\n assert response.json() == {\"hello\": \"world\"}\n\n\ndef test_read_main_with_error(monkeypatch: pytest.MonkeyPatch):\n monkeypatch.setattr(\"app.do_something\", replace_do_something)\n # Here we replace any reference to do_something \n # with replace_do_something. Note the 'app.' prefix!\n \n response = client.get(\"/myroute\")\n assert response.status_code == 400\n assert response.json() == {\"detail\": \"something went wrong\"}\n```\n\n```bash\n(venv) jarro@MacBook-Pro-van-Jarro fastapi-github-issues % pytest --cov=app SO/pytestwithmock/test_app.py\n===================================================== test session starts =====================================================\nplatform darwin -- Python 3.10.5, pytest-7.1.2, pluggy-1.0.0\nrootdir: /Users/jarro/Development/fastapi-github-issues\nplugins: anyio-3.6.1, cov-3.0.0\ncollected 2 items \n\nSO/pytestwithmock/test_app.py .. [100%]\n\n---------- coverage: platform darwin, python 3.10.5-final-0 ----------\nName Stmts Miss Cover\n----------------------------------------------\nSO/pytestwithmock/app.py 13 0 100%\n----------------------------------------------\nTOTAL 13 0 100%\n\n\n====================================================== 2 passed in 0.19s ======================================================\n```\n\n```text\nexcept\n```\n\n```text\ntry\n```\n\n```text\nException\n```\n\n```text\ndo_something()\n```\n\n```text\napp.py\n```\n\n```text\nreplace_do_something()\n```\n\n```text\nException\n```\n\n```text\npytest-cov\n```\n\n========================================\n\nComments:\n- What do you mean it's not working? What *does* happen? Your client isn't necessarily going to throw an error, just receive a 400 response.\n- Thank you for such a quick response! To clarify whats happening - I can see I am misusing `pytest.raises` as it expects an Exception to be raised from just invoking `my_function`. Whats happening now is I am running pytest WITHOUT hitting the exception case in `my_function` - causing my code coverage to drop. How can I test for that exception?\n- Again the client won't raise an error, just get a 400 response, so asserting it raises is indeed inappropriate. As to how to test the error handling case that depends on `do_something` throwing an error, and there's not enough information to determine how that might happen.\n- @jonrsharpe That makes sense. So if you happen to know, what is generally the best practice around reaching that full coverage if some code within an Exception block seems unreachable? Changing the function code to comply with testing (for ex. optional parameters to break the function) seems janky, however I don't see any other way to intentionally break a function that's expected to work *almost* all of the time\n- You're testing that the 400 error gets returned - i.e. submit data that isn't valid and triggers the exception. If you can't send data that triggers the exception, how would the user trigger that exception when using the application? If the exception can't happen, why test it? (if there's something in the code internally that can trigger the exception, use a dependency override in FastAPI to trigger it)\n- To add to Mats answers above, you could `monkeypatch` the function `do_something()` with something that would always raise an exception. Use monkeypatch.setattr to patch the function with your desired testing behavior.\n- Thank you so much! This makes perfect sense and should work for what I intend to do. That being said, do you know if `MonkeyPatch` is limited to functions I define within that file? It seemed like I couldn't `MonkeyPatch` an imported function but I am not sure...\n- In the example, I monkeypatched an imported function. You can use it to change variables, objects or even just methods of certain classes. You can read more about what it can do in the docs: docs.pytest.org/en/7.1.x/how-to/monkeypatch.html","metadata":{"transformedAt":"2026-08-18T18:32:29.149Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":15,"totalLines":173,"estimatedTokens":1572}}611{"id":"stack-70404952","source":"stackoverflow","questionId":70404952,"title":"\"422 Unprocessable Entity\" error when making POST request with both attributes and key using FastAPI","tags":["python","fastapi"],"text":"Title: \"422 Unprocessable Entity\" error when making POST request with both attributes and key using FastAPI\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have a file called `main.py` as follows:\n\n```\nfrom typing import Optional\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\n\napp = FastAPI()\n\nfake_db = {\n \"Foo\": {\"id\": \"foo\", \"title\": \"Foo\", \"description\": \"There goes my hero\"},\n \"Bar\": {\"id\": \"bar\", \"title\": \"Bar\", \"description\": \"The bartenders\"},\n}\n\nclass Item(BaseModel):\n id: str\n title: str\n description: Optional[str] = None\n\n@app.post(\"/items/\", response_model=Item)\nasync def create_item(item: Item, key: str):\n fake_db[key] = item\n return item\n```\n\nNow, if I run the code for the test, saved in the file `test_main.py`\n\n```\nfrom fastapi.testclient import TestClient\nfrom main import app\n\nclient = TestClient(app)\n\ndef test_create_item():\n response = client.post(\n \"/items/\",\n {\"id\": \"baz\", \"title\": \"A test title\", \"description\": \"A test description\"},\n \"Baz\"\n )\n return response.json()\n\nprint(test_create_item())\n```\n\nI don't get the desired result, that is\n\n```\n{\"id\": \"baz\", \"title\": \"A test title\", \"description\": \"A test description\"}\n```\n\nWhat is the mistake?\n\n========================================\n\nCode:\n```text\nfrom typing import Optional\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\n\napp = FastAPI()\n\nfake_db = {\n \"Foo\": {\"id\": \"foo\", \"title\": \"Foo\", \"description\": \"There goes my hero\"},\n \"Bar\": {\"id\": \"bar\", \"title\": \"Bar\", \"description\": \"The bartenders\"},\n}\n\nclass Item(BaseModel):\n id: str\n title: str\n description: Optional[str] = None\n\n@app.post(\"/items/\", response_model=Item)\nasync def create_item(item: Item, key: str):\n fake_db[key] = item\n return item\n```\n\n```text\nfrom fastapi.testclient import TestClient\nfrom main import app\n\nclient = TestClient(app)\n\ndef test_create_item():\n response = client.post(\n \"/items/\",\n {\"id\": \"baz\", \"title\": \"A test title\", \"description\": \"A test description\"},\n \"Baz\"\n )\n return response.json()\n\nprint(test_create_item())\n```\n\n```none\n{\"id\": \"baz\", \"title\": \"A test title\", \"description\": \"A test description\"}\n```\n\n```text\nmain.py\n```\n\n```text\ntest_main.py\n```\n\n```text\ndef post(self, url, data=None, json=None, **kwargs):\n r\"\"\"Sends a POST request. Returns :class:`Response` object.\n\n :param url: URL for the new :class:`Request` object.\n :param data: (optional) Dictionary, list of tuples, bytes, or file-like\n object to send in the body of the :class:`Request`.\n :param json: (optional) json to send in the body of the :class:`Request`.\n :param \\*\\*kwargs: Optional arguments that ``request`` takes.\n :rtype: requests.Response\n \"\"\"\n```\n\n```text\nresponse = client.post(\n \"/items/\",\n {\"id\": \"baz\", \"title\": \"A test title\", \"description\": \"A test description\"},\n \"Baz\",\n)\n```\n\n```text\ndef test_create_item():\n response = client.post(\n \"/items/\", {\"id\": \"baz\", \"title\": \"A test title\", \"description\": \"A test description\"}, \"Baz\"\n )\n print(response.status_code)\n print(response.reason)\n return response.json()\n\n# 422 Unprocessable Entity\n# {'detail': [{'loc': ['query', 'key'],\n# 'msg': 'field required',\n# 'type': 'value_error.missing'},\n# {'loc': ['body'],\n# 'msg': 'value is not a valid dict',\n# 'type': 'type_error.dict'}]}\n```\n\n```text\nclass Item(BaseModel):\n id: str\n title: str\n description: Optional[str] = None\n\nclass NewItem(Item):\n key: str\n\n@app.post(\"/items/\", response_model=Item)\nasync def create_item(new_item: NewItem):\n # See Pydantic https://pydantic-docs.helpmanual.io/usage/exporting_models/#modeldict\n # Also, Pydantic by default will ignore the extra attribute `key` when creating `Item`\n item = Item(**new_item.dict())\n print(item)\n fake_db[new_item.key] = item\n return item\n```\n\n```text\ndef test_create_item():\n response = client.post(\n \"/items/\",\n json={\n \"key\": \"Baz\",\n \"id\": \"baz\",\n \"title\": \"A test title\",\n \"description\": \"A test description\",\n },\n )\n print(response.status_code, response.reason)\n return response.json()\n```\n\n```none\nid='baz' title='A test title' description='A test description'\n200 OK\n{'description': 'A test description', 'id': 'baz', 'title': 'A test title'}\n```\n\n```json\n{\n \"item\": {\n \"id\": \"baz\",\n \"title\": \"A test title\",\n \"description\": \"A test description\",\n },\n \"key\": \"Baz\",\n},\n```\n\n```text\nfrom fastapi import Body, FastAPI\n\nclass Item(BaseModel):\n id: str\n title: str\n description: Optional[str] = None\n\n@app.post(\"/items/\", response_model=Item)\nasync def create_item(item: Item, key: str = Body(...)):\n print(item)\n fake_db[key] = item\n return item\n```\n\n```text\ndef test_create_item():\n response = client.post(\n \"/items/\",\n json={\n \"item\": {\n \"id\": \"baz\",\n \"title\": \"A test title\",\n \"description\": \"A test description\",\n },\n \"key\": \"Baz\",\n },\n )\n print(response.status_code, response.reason)\n return response.json()\n```\n\n```none\nid='baz' title='A test title' description='A test description'\n200 OK\n{'description': 'A test description', 'id': 'baz', 'title': 'A test title'}\n```\n\n```text\nTestClient\n```\n\n```text\nTestClient\n```\n\n```text\npost\n```\n\n```text\ndata\n```\n\n```text\njson\n```\n\n```text\ndata\n```\n\n```text\njson\n```\n\n```text\ndata\n```\n\n```text\njson\n```\n\n```text\njson\n```\n\n```text\njson\n```\n\n```text\ndata\n```\n\n```text\nfiles\n```\n\n```text\n\"Baz\"\n```\n\n```text\njson\n```\n\n```text\ndata\n```\n\n```text\nkey\n```\n\n```text\nkey\n```\n\n```text\n\"Baz\"\n```\n\n```text\ndata\n```\n\n```text\njson.dumps\n```\n\n```text\nItem\n```\n\n```text\njson=\n```\n\n```text\n.post\n```\n\n```text\nkey\n```\n\n```text\nNewItem\n```\n\n```text\nItem\n```\n\n```text\nnew_item\n```\n\n```text\nkey\n```\n\n```text\n.post\n```\n\n```text\njson=\n```\n\n```text\nItem\n```\n\n```text\nkey\n```\n\n```text\nitem\n```\n\n```text\nimportance\n```\n\n```text\nitem\n```\n\n```text\nuser\n```\n\n```text\nquery\n```\n\n```text\nkey\n```\n\n```text\nBody\n```\n\n```text\nkey\n```\n\n```text\nitem\n```\n\n```text\nkey\n```\n\n```text\n.post\n```\n\n```text\njson=\n```\n\n========================================\n\nComments:\n- I don't believe you can return a model object directly from a view. You have to wrap it in a JSONResponse.\n- But `response.json() == {\"id\": \"baz\", \"title\": \"A test title\", \"description\": \"A test description\"}` doesn't work either. I'm trying to do what is done in the function `test_create_item()` here: fastapi.tiangolo.com/tutorial/testing\n- That example explicitly returns a dict, which you aren't doing.\n- With a `GET` request I can return `response.json()` without problems. However, inserting the object in `fake_db` doesn't work either.\n- I mean the view function, not the test function. `async def create_item()` returns `item`, which may or may not be a dictionary (I don't know enough about typing to know for sure.) In the linked example, the view function returns an actual dict.\n- So what is the correct way to insert an element into `fake_db` from the test file `test_main.py`?\n- How do you know it isn't being inserted?\n- Because if after inserting I use a `GET` request I can't reach `Baz` (but I can reach `Foo`)\n- Why do you expect the `key` parameter to get any value from your request? You're not giving any key - did you mean to assign it from a `Form` value? You should probably extract the key from the `id` of the submitted item, or create a composite request model (i.e. a CreateItem request that has both item and the key on the root level).\n- So in any case should I create a single object (which contains all parameters) for each input? For example: `class Input(Basemodel): key: str, item: Item`\n- First of all thanks for the answer. Very clear and detailed, I really appreciated it. I have two questions. 1) In Solution #2 > `main.py` > `create_item()`, what would the form be if I had another parameter besides `item` and `key`? Is `create_item(item: Item, key: str = Body(...), another_parameter: int = Body(...))` correct? 2) In Solution #2 > `test_main.py` > `test_create_item()`, is it correct that I must necessarily pass the data through `json={...}`? Can't I pass an object of a class defined in `main.py` (for example `Item`, let's assume for simplicity that `key` doesn't exist)?\n- @LJG For 1), yes that is correct. See the FastAPI tutorial on multiple body parameters: fastapi.tiangolo.com/tutorial/body-multiple-params/…\n- @LJG For 2), an object of a class needs to be formatted into either form-encoded data (for `data=`) or as a JSON object (for `json=`). There is no such thing as passing \"*an object of a class*\" when making POST requests. I suggest reading through the requests docs on making POST requests: docs.python-requests.org/en/latest/user/quickstart/…. Pydantic offers a way to export `BaseModel`'s into a plain dict (pydantic-docs.helpmanual.io/usage/exporting_models) which you can directly pass into `json=`. Using `json=` would be the simplest approach.\n- For 1), it is not entirely clear to me how to use `Body(...)` in the general case. For example `create_item(item: Item, key: str = Body(...), another_parameter: int = Body(...))` works, but `create_item(key: str = Body(...), item : Item, another_parameter: int = Body(...))` no. For example, if I wanted to define a function `fun(item1: List[Item1], item2: Item2, id: int, key: str)`, which parameters should be marked as `Body(...)` (`Item1` and `Item2` are two generic classes)? The goal is to pass `json={\"item1\": [{...}, {...}], \"item2\": {...}, \"id\": 1, \"key\": \"abc\"}`.","metadata":{"transformedAt":"2026-08-18T18:32:29.149Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":60,"totalLines":437,"estimatedTokens":2423}}612{"id":"stack-76398117","source":"stackoverflow","questionId":76398117,"title":"how to override the default 200 response in fastapi docs","tags":["python","fastapi","openapi"],"text":"Title: how to override the default 200 response in fastapi docs\nTags: python, fastapi, openapi\nSource: Stack Overflow\n\nQuestion:\nI have this small fastapi application\n\n```\nimport uvicorn\nfrom fastapi import FastAPI, APIRouter\nfrom fastapi import Path\nfrom pydantic import BaseModel\nfrom starlette import status\n\napp = FastAPI()\n\ndef test():\n print(\"creating the resource\")\n return \"Hello world\"\n\nrouter = APIRouter()\n\nclass MessageResponse(BaseModel):\n detail: str\n\nrouter.add_api_route(\n path=\"/test\",\n endpoint=test,\n methods=[\"POST\"],\n responses={\n status.HTTP_201_CREATED: {\"model\": MessageResponse}\n }\n)\n\napp.include_router(router)\n\ndef main():\n uvicorn.run(\"run:app\", host=\"0.0.0.0\", reload=True, port=8001)\n\nif __name__ == \"__main__\":\n main()\n```\n\nwhen I check the docs on `http://127.0.0.1:8001/docs#/default/test_test_post`, in the list of responses in the docs, I see two responses: 200 and 201\n\nI don't have any 200 responses here.\nI don't want 200 to be shown for me in the docs.\n\nHere is the fast api auto-generated openapi.json file\n\n```\n{\n \"openapi\": \"3.0.2\",\n \"info\": {\"title\": \"FastAPI\", \"version\": \"0.1.0\"},\n \"paths\": {\"/test\": {\n \"post\": {\"summary\": \"Test\", \"operationId\": \"test_test_post\", \"responses\": {\n \"200\": {\n \"description\": \"Successful Response\", \"content\": {\"application/json\": {\"schema\": {}}}\n },\n \"201\": {\n \"description\": \"Created\",\n \"content\": {\"application/json\": {\"schema\": {\"$ref\": \"#/components/schemas/MessageResponse\"}}}}}}}\n },\n \"components\": {\"schemas\": {\n \"MessageResponse\": {\"title\": \"MessageResponse\", \"required\": [\"detail\"], \"type\": \"object\",\n \"properties\": {\"detail\": {\"title\": \"Detail\", \"type\": \"string\"}}}}}}\n```\n\nI should not be seeing\n\n```\n\"description\": \"Successful Response\", \"content\": {\"application/json\": {\"schema\": {}}}\n },\n```\n\nWhat should I do?\n\nUPDATE:\n\nthis one also did not work\n\n```\nimport uvicorn\nfrom fastapi import FastAPI, APIRouter\nfrom pydantic import BaseModel\nfrom starlette import status\nfrom starlette.responses import Response\n\napp = FastAPI()\n\ndef test(response: Response):\n print(\"creating the resource\")\n response.status_code = 201\n return \"Hello world\"\n\nrouter = APIRouter()\n\nclass MessageResponse(BaseModel):\n detail: str\n\nrouter.add_api_route(\n path=\"/test\",\n endpoint=test,\n methods=[\"POST\"],\n response_model=None,\n responses={\n 200: {},\n status.HTTP_201_CREATED: {\"model\": MessageResponse}\n }\n)\n\napp.include_router(router)\n\ndef main():\n uvicorn.run(\"run:app\", host=\"0.0.0.0\", reload=True, port=8001)\n\nif __name__ == \"__main__\":\n main()\n```\n\n========================================\n\nTop Answer:\nthis solution works but it is not ideal\n\n```\nimport uvicorn\nfrom fastapi import FastAPI, APIRouter\nfrom pydantic import BaseModel\nfrom starlette import status\nfrom starlette.responses import Response\n\napp = FastAPI()\n\ndef test(response: Response):\n print(\"creating the resource\")\n response.status_code = 201\n return \"Hello world\"\n\nrouter = APIRouter()\n\nclass MessageResponse(BaseModel):\n detail: str\n\nrouter.add_api_route(\n path=\"/test\",\n endpoint=test,\n methods=[\"POST\"],\n response_model=None,\n status_code=201,\n responses={\n status.HTTP_201_CREATED: {\"model\": MessageResponse}\n }\n)\n\napp.include_router(router)\n\ndef main():\n uvicorn.run(\"run:app\", host=\"0.0.0.0\", reload=True, port=8001)\n\nif __name__ == \"__main__\":\n main()\n```\n\nI have to repeat 201 twice. it is redundant.\n\nI thin this is a bug in fastapi.\n\nIdeally I should not need to do this\n\n========================================\n\nCode:\n```text\nimport uvicorn\nfrom fastapi import FastAPI, APIRouter\nfrom fastapi import Path\nfrom pydantic import BaseModel\nfrom starlette import status\n\napp = FastAPI()\n\n\ndef test():\n print(\"creating the resource\")\n return \"Hello world\"\n\n\nrouter = APIRouter()\n\n\nclass MessageResponse(BaseModel):\n detail: str\n\n\nrouter.add_api_route(\n path=\"/test\",\n endpoint=test,\n methods=[\"POST\"],\n responses={\n status.HTTP_201_CREATED: {\"model\": MessageResponse}\n }\n)\n\napp.include_router(router)\n\n\ndef main():\n uvicorn.run(\"run:app\", host=\"0.0.0.0\", reload=True, port=8001)\n\n\nif __name__ == \"__main__\":\n main()\n```\n\n```text\n{\n \"openapi\": \"3.0.2\",\n \"info\": {\"title\": \"FastAPI\", \"version\": \"0.1.0\"},\n \"paths\": {\"/test\": {\n \"post\": {\"summary\": \"Test\", \"operationId\": \"test_test_post\", \"responses\": {\n \"200\": {\n \"description\": \"Successful Response\", \"content\": {\"application/json\": {\"schema\": {}}}\n },\n \"201\": {\n \"description\": \"Created\",\n \"content\": {\"application/json\": {\"schema\": {\"$ref\": \"#/components/schemas/MessageResponse\"}}}}}}}\n },\n \"components\": {\"schemas\": {\n \"MessageResponse\": {\"title\": \"MessageResponse\", \"required\": [\"detail\"], \"type\": \"object\",\n \"properties\": {\"detail\": {\"title\": \"Detail\", \"type\": \"string\"}}}}}}\n```\n\n```text\n\"description\": \"Successful Response\", \"content\": {\"application/json\": {\"schema\": {}}}\n },\n```\n\n```text\nimport uvicorn\nfrom fastapi import FastAPI, APIRouter\nfrom pydantic import BaseModel\nfrom starlette import status\nfrom starlette.responses import Response\n\napp = FastAPI()\n\n\ndef test(response: Response):\n print(\"creating the resource\")\n response.status_code = 201\n return \"Hello world\"\n\n\nrouter = APIRouter()\n\n\nclass MessageResponse(BaseModel):\n detail: str\n\n\nrouter.add_api_route(\n path=\"/test\",\n endpoint=test,\n methods=[\"POST\"],\n response_model=None,\n responses={\n 200: {},\n status.HTTP_201_CREATED: {\"model\": MessageResponse}\n }\n)\n\napp.include_router(router)\n\n\ndef main():\n uvicorn.run(\"run:app\", host=\"0.0.0.0\", reload=True, port=8001)\n\n\nif __name__ == \"__main__\":\n main()\n```\n\n```text\nhttp://127.0.0.1:8001/docs#/default/test_test_post\n```\n\n```text\nclass MessageResponse(BaseModel):\n detail: str\n\n@router.post('/test', status_code=201)\ndef test() -> MessageResponse:\n print(\"creating the resource\")\n return \"Hello world\"\n```\n\n```text\nrouter.add_api_route(\n path=\"/test\",\n endpoint=test,\n methods=[\"POST\"],\n status_code=201,\n responses={\n status.HTTP_201_CREATED: {\"model\": MessageResponse}\n }\n)\n```\n\n```text\nstatus_code\n```\n\n```text\nstatus_code\n```\n\n```text\nadd_api_route\n```\n\n```text\nimport uvicorn\nfrom fastapi import FastAPI, APIRouter\nfrom pydantic import BaseModel\nfrom starlette import status\nfrom starlette.responses import Response\n\napp = FastAPI()\n\n\ndef test(response: Response):\n print(\"creating the resource\")\n response.status_code = 201\n return \"Hello world\"\n\n\nrouter = APIRouter()\n\n\nclass MessageResponse(BaseModel):\n detail: str\n\n\nrouter.add_api_route(\n path=\"/test\",\n endpoint=test,\n methods=[\"POST\"],\n response_model=None,\n status_code=201,\n responses={\n status.HTTP_201_CREATED: {\"model\": MessageResponse}\n }\n)\n\napp.include_router(router)\n\n\ndef main():\n uvicorn.run(\"run:app\", host=\"0.0.0.0\", reload=True, port=8001)\n\n\nif __name__ == \"__main__\":\n main()\n```\n\n========================================\n\nComments:\n- this is different from the structure of my application\n- I am using `router.add_api_route`\n- but your solution gave me a hint on how to solve my problem with the structure of mine\n- I know this is a different structure from your application. This is the structure recommended by FastAPI whereas your structure is non-standard which would make it difficult to find documentation. The `status_code=201` would still work if you put it inside `add_api_route`, but again, that is not what the documentation recommends.\n- fastapi is flexible and friendly and there is no recommended structure. you can restructure it the way you want. and it should give you the same features in any structure you use it\n- A chair is flexible and friendly and there is no correct way to sit on it, but if you sit on it sideways you can't lean back on the backrest, and your legs will hang over the armrest. If you are comfortable sitting in that position, sure, I'm not going to judge you, but for the sake of your health, I recommend you sit in the way most other people are sitting.\n- in no production-level big application, sitting straight (the simplest way of creating a fastapi application) will suffice.\n- In a case where a patient has severe spinal deformation, sitting straight alone will not fix it. Instead, you would combine sitting straight (simple, clear structure) with surgery or visiting a chiropractor (more advanced features). Continuing to sit sideways (using a suboptimal structure) will not help.\n- I dont believe such abstract examples are helpful in a technical discussion\n- Well if we are to discuss in technical terms, the structure I use is less code to write overall, saving valuable developer time. This structure is also standard, meaning 99% of FastAPI developers would be familiar with this structure increasing the productivity of collaborators should a team become necessary when the scale of this application becomes large enough. Almost all community support including YT tutorials, SO questions, GH issues, and even the Official FastAPI Documentation use this structure.\n- I agree that community support including YT tutorials, SO questions, GH issues, and even the Official FastAPI Documentation use this structure. I am not well-informed because I dont have access to a study but I dont believe big application the simple fastapi structure provided in the documentation. the same story about flask.\n- `do it with the decorator paradigm which is recommended over manually adding API routes` - Citation, please? Seems highly dependent on the use case, rather than simply \"recommended\" wholesale.\n- This is intended behavior in FastAPI and definitely not a bug. The default response model exists to reduce code in most circumstances. See my answer for an example of how.\n- @Squarish but when you list responses, the default should be removed. I should not need to define 201 twice\n- You don't have to list the default in `responses`. You can move the response model directly to the type hint of your endpoint function. Doing this here makes it unnecessary to have `responses=...` at all.\n- I have multiple responses and multiple models for each\n- in that case, you would define the default with `status_code` and endpoint return type hint, and then define other responses with `responses`. Still results in less code overall and makes it more intuitive what is the expected result versus error/edge case results.\n- I dont agree. I have and endpoint that returns 204, 401, 403, 404. I am defining their models in `respnses={204: {.....}, 401: {.....}, 403: {.....}, 404: {.....}` and then I have to again define `status_code=204` to get rid of 200 in the openapi.json file\n- In this case, you would remove `204: {'model': PyModel}` from `responses` completely and move it to `test() -> PyModel:` adding `status_code=204` to specify that the hinted response is a 204.\n- then response models for 401, 403, 404 are not in the same place as the response model for 204. they will be in two different part of the code. I want them all to be in the same place\n- I understand the desire to put all models in the same place, but here, they shouldn't be. If you'll notice, 204 is a 2xx Success response whereas the others are all 4xx Client Error responses. 204 is the expected successful response and should be distinct from the others.","metadata":{"transformedAt":"2026-08-18T18:32:29.150Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":11,"totalLines":390,"estimatedTokens":2846}}613{"id":"stack-68302044","source":"stackoverflow","questionId":68302044,"title":"FastAPI path parameter validation for a fixed string or any valid integer","tags":["python","fastapi","python-typing","pydantic"],"text":"Title: FastAPI path parameter validation for a fixed string or any valid integer\nTags: python, fastapi, python-typing, pydantic\nSource: Stack Overflow\n\nQuestion:\nI need to parse `version` parameter from URL path in FastAPI endpoint. The valid value for `version` parameter is either a fixed string e.g. `active` or any integer e.g. `1`.\n\nIs there an elegant way to make `FastAPI` or `pydantic` validate this path parameter with such rules so that I don't have to perform validation manually?\n\n```\n@app.get(\"/{version}\")\ndef endpoint(version):\n # version could be either 'active' or valid integer e.g. 1\n return {\"version\": version}\n```\n\n========================================\n\nCode:\n```text\n@app.get(\"/{version}\")\ndef endpoint(version):\n # version could be either 'active' or valid integer e.g. 1\n return {\"version\": version}\n```\n\n```text\nversion\n```\n\n```text\nversion\n```\n\n```text\nactive\n```\n\n```text\n1\n```\n\n```text\nFastAPI\n```\n\n```text\npydantic\n```\n\n```py\nfrom typing import Union\nfrom pydantic import BaseModel\n\nclass Version(BaseModel):\n version: Union[int, str]\n```\n\n```py\nfrom typing import Union, Literal\nfrom pydantic import BaseModel\n\nclass Version(BaseModel):\n version: Union[Literal['active'], int]\n```\n\n========================================\n\nComments:\n- I think you could write pydantic model with a validator\n- `from typing import Union, Literal`, `version: Union[Literal['active'], int]` could work?\n- It is not clear how to use that to solve the problem in the original post. What do you put in the `app.get decorator` and in the function signature? `def endpoint(version:Version)`? `def endpoint(version:Version.version)` ? Something else?\n- It is enough that the `def` becomes `def endpoint(version: Version):`\n- Thank you. So this is my understanding of how it works (I haven't seen this documented anywhere): FASTApi looks into the fields of the model (here `Version`) and if it finds a field name that matches the argument name of the decorated function, it uses the type of that field to validate the url parameter. Am I correct? Thanks again.","metadata":{"transformedAt":"2026-08-18T18:32:29.150Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":74,"estimatedTokens":520}}614{"id":"stack-66214960","source":"stackoverflow","questionId":66214960,"title":"Validation error while inputting a record into Postgres","tags":["python","sqlalchemy","fastapi","pydantic"],"text":"Title: Validation error while inputting a record into Postgres\nTags: python, sqlalchemy, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI have created a table using the following query,\n\n```\nCREATE TABLE user_account (\nuser_id serial PRIMARY KEY,\nuser_name VARCHAR ( 50 ) UNIQUE NOT NULL,\npassword VARCHAR ( 50 ) NOT NULL,\nemail VARCHAR ( 255 ) UNIQUE NOT NULL,\ncreated_on TIMESTAMP NOT NULL,\nallow BOOLEAN NOT NULL\n);\n```\n\nFollowing is my models.py\n\n```\nclass AccountsInfo(Base):\n __tablename__ = \"user_account\"\n\n user_id = Column(Integer, primary_key=True, index=True)\n user_name = Column(String)\n password = Column(String)\n email = Column(String)\n created_on = Column(DateTime)\n allow = Column(Boolean)\n```\n\nFollowing is my schema.py\n\n```\nclass AccountsInfoBase(BaseModel):\n user_name: str\n password: str\n email: str\n created_on: str\n allow: bool\n\n class Config:\n orm_mode = True\n\nclass AccountsCreate(AccountsInfoBase):\n password = str\n\nclass AccountsInfo(AccountsInfoBase):\n user_id: int\n\n class Config:\n orm_mode = True\n```\n\nI use the following code to create an user,\n\n```\ndef create_user(db: Session, user: schemas.AccountsCreate):\n db_user = models.AccountsInfo(user_name=user.user_name, password=user.password, email=user.email,created_on=time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())),allow=True)\n db.add(db_user)\n db.commit()\n db.refresh(db_user)\n return db_user\n```\n\nThe problem is that I'm getting the following error,\n\nraise ValidationError(errors, field.type_)\npydantic.error_wrappers.ValidationError: 1 validation error for\nAccountsInfo response -> created_on str type expected\n(type=type_error.str)\n\nwhat am I missing?\n\n========================================\n\nCode:\n```text\nCREATE TABLE user_account (\nuser_id serial PRIMARY KEY,\nuser_name VARCHAR ( 50 ) UNIQUE NOT NULL,\npassword VARCHAR ( 50 ) NOT NULL,\nemail VARCHAR ( 255 ) UNIQUE NOT NULL,\ncreated_on TIMESTAMP NOT NULL,\nallow BOOLEAN NOT NULL\n);\n```\n\n```text\nclass AccountsInfo(Base):\n __tablename__ = \"user_account\"\n\n user_id = Column(Integer, primary_key=True, index=True)\n user_name = Column(String)\n password = Column(String)\n email = Column(String)\n created_on = Column(DateTime)\n allow = Column(Boolean)\n```\n\n```text\nclass AccountsInfoBase(BaseModel):\n user_name: str\n password: str\n email: str\n created_on: str\n allow: bool\n\n class Config:\n orm_mode = True\n\n\nclass AccountsCreate(AccountsInfoBase):\n password = str\n\n\nclass AccountsInfo(AccountsInfoBase):\n user_id: int\n\n class Config:\n orm_mode = True\n```\n\n```text\ndef create_user(db: Session, user: schemas.AccountsCreate):\n db_user = models.AccountsInfo(user_name=user.user_name, password=user.password, email=user.email,created_on=time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())),allow=True)\n db.add(db_user)\n db.commit()\n db.refresh(db_user)\n return db_user\n```\n\n```py\nclass AccountsInfo(Base):\n __tablename__ = \"user_account\"\n\n created_on = Column(DateTime)\n```\n\n```py\nclass AccountsInfoBase(BaseModel):\n created_on: str\n```\n\n```py\nfrom sqlalchemy.sql import func\n\ntime_created = Column(DateTime(timezone=True), server_default=func.now())\n```\n\n```text\nstr\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.150Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":8,"totalLines":154,"estimatedTokens":805}}615{"id":"stack-70036507","source":"stackoverflow","questionId":70036507,"title":"Simply format SQLAlchemy models returned by FastApi endpoint","tags":["sqlalchemy","fastapi","camelcasing","post-processing"],"text":"Title: Simply format SQLAlchemy models returned by FastApi endpoint\nTags: sqlalchemy, fastapi, camelcasing, post-processing\nSource: Stack Overflow\n\nQuestion:\nSuppose I have a simple *SQLAlchemy* class and a simple *Flask* o *FastAPI* implementation like this:\n\n```\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom pydantic import BaseModel\nBase = declarative_base()\n \nclass A(Base):\n __tablename__ = 'as'\n my_id = Column(String)\n \nclass AModel(BaseModel):\n myId:str = None\n```\n\nAnd a simple endpoint like this:\n\n```\n@app_router.get('/a')\ndef get_all_a(session:Session = Depends(get_session)):\n return session.query(A).all()\n```\n\nHow could I ensure that the returned list of this endpoint yields in *camelCase* like this:\n\n```\n[{'myId': 'id1'},{'myId': 'id2'}, ...]\n```\n\nNote: My application is rather complex, as I also have pagination implemented and some post-processings require a little bit more that just snake_case to camelCase conversion, so the simplest solution would be the best.\n\nI've tried overriding *dict()* methods and similar stuff with no luck, simply cannot understand how *FastAPI* processes the results to obtain a JSON.\n\n========================================\n\nCode:\n```py\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom pydantic import BaseModel\nBase = declarative_base()\n \nclass A(Base):\n __tablename__ = 'as'\n my_id = Column(String)\n \nclass AModel(BaseModel):\n myId:str = None\n```\n\n```py\n@app_router.get('/a')\ndef get_all_a(session:Session = Depends(get_session)):\n return session.query(A).all()\n```\n\n```text\n[{'myId': 'id1'},{'myId': 'id2'}, ...]\n```\n\n```py\nfrom typing import List\n\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom pydantic import BaseModel, Field\nfrom pydantic import parse_obj_as\nBase = declarative_base()\n\nclass A(Base):\n __tablename__ = 'as'\n my_id = Column(String)\n\nclass AModel(BaseModel):\n myId: str = Field(alias=\"my_id\", default=None)\n\n@app_router.get('/a', response_model=List[AModel])\ndef get_all_a(session:Session = Depends(get_session)):\n return parse_obj_as(List[AModel], session.query(A).all())\n```\n\n========================================\n\nComments:\n- This Stack OV Question could help you Convert data keys between camelcase & snakecase, also a reference to marshmallow official docs could be useful as well marshmallow - docs\n- At this point I think that edge for the solution could be this pydantic Docs - Alias Generator\n- @Franco the problem with alias_generator is that you can't initialize fields with their snake syntax, and we need it here because de db output is snake. To use it we will need to convert from snake to camel and so having 2 time the inital problem to resolve.\n- At the end I solve this topic using a column \"synonym\" `sqlalchemy.orm import synonym`, but I am sill thinking that there is another door in this maze ja.","metadata":{"transformedAt":"2026-08-18T18:32:29.150Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":91,"estimatedTokens":718}}616{"id":"stack-65597315","source":"stackoverflow","questionId":65597315,"title":"How to return a list of PIL image files from fastapi response?","tags":["python","python-3.x","python-imaging-library","fastapi","uvicorn"],"text":"Title: How to return a list of PIL image files from fastapi response?\nTags: python, python-3.x, python-imaging-library, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI have created an rest-api using fastapi, which takes a document (pdf) as input and return a jpeg image of it, I am using a library called docx2pdf for conversion.\n\n```\nfrom docx2pdf import convert_to \nfrom fastapi import FastAPI, File, UploadFile\n\napp = FastAPI()\n\n@app.post(\"/file/convert\")\nasync def convert(doc: UploadFile = File(...)):\n if doc.filename.endswith(\".pdf\"):\n # convert pdf to image\n with tempfile.TemporaryDirectory() as path:\n doc_results = convert_from_bytes(\n doc.file.read(), output_folder=path, dpi=350, thread_count=4\n )\n\n print(doc_results)\n\n return doc_results if doc_results else None\n```\n\nThis is the output of `doc_results`, basically a list of PIL image files\n\n```\n[, ]\n```\n\nIf I run my current code, it is returning the doc_results as json output and I am not being able to load those images in another API.\n\nHow can I return image files without saving them to local storage? So, I can make a request to this api and get the response and work on the image directly.\n\nAlso, if you know any improvements I can make in the above code to speed up is also helpful.\n\nAny help is appreciated.\n\n========================================\n\nCode:\n```text\nfrom docx2pdf import convert_to \nfrom fastapi import FastAPI, File, UploadFile\n\napp = FastAPI()\n\n@app.post(\"/file/convert\")\nasync def convert(doc: UploadFile = File(...)):\n if doc.filename.endswith(\".pdf\"):\n # convert pdf to image\n with tempfile.TemporaryDirectory() as path:\n doc_results = convert_from_bytes(\n doc.file.read(), output_folder=path, dpi=350, thread_count=4\n )\n\n print(doc_results)\n\n return doc_results if doc_results else None\n```\n\n```text\n[<PIL.PpmImagePlugin.PpmImageFile image mode=RGB size=2975x3850 at 0x7F5AB4C9F9D0>, <PIL.PpmImagePlugin.PpmImageFile image mode=RGB size=2975x3850 at 0x7F5AB4C9FB80>]\n```\n\n```text\ndoc_results\n```\n\n```py\nimport io\n\ndef get_bytes_value(image):\n img_byte_arr = io.BytesIO()\n image.save(img_byte_arr, format='JPEG')\n return img_byte_arr.getvalue()\n```\n\n```py\nreturn [get_bytes_value(image) for image in doc_results] if doc_results else None\n```\n\n========================================\n\nComments:\n- Can you provide some example code to help me out a bit, I have been trying to achieve it from last few hours but so far not able to figure our how to return an array of bytes ?\n- I am getting a error `UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte`, I have tried this solution but didn't worked for me.\n- Have you tried the solutions for that error from this question?\n- I was able to figure out the issue, I had to base64 encoding.\n- Ah great, glad it helped.","metadata":{"transformedAt":"2026-08-18T18:32:29.150Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":93,"estimatedTokens":722}}617{"id":"stack-69757156","source":"stackoverflow","questionId":69757156,"title":"How can we run a FastAPI application on two ports one HTTP and one HTTPS without redirecting?","tags":["ssl","https","gunicorn","fastapi"],"text":"Title: How can we run a FastAPI application on two ports one HTTP and one HTTPS without redirecting?\nTags: ssl, https, gunicorn, fastapi\nSource: Stack Overflow\n\nQuestion:\nI want to host my FastAPI application using `gunicorn` and host it on a Kubernetes Service. My Kubernetes service runs a liveness probe (health check) using `HTTP` call on a specified endpoint.\n\nI also want the application to be served on `HTTPS` because my Kubernetes service exposes it to be used by external components.\n\nNow my HTTP endpoint can't rely on redirection as the liveness probe expects a `200 Response` and redirection will hamper that.\n\nI want to host my HTTPS endpoint on a pre-specified port as the organization has the best practices in place and the endpoint and port are specified.\n\nSome similar problems on StackOverflow:\n\n- Running Gunicorn on both http and https\n\n- uvicorn [fastapi] python run both HTTP and HTTPS\n\nBut both of these are okay with redirection, and we are not. And we cannot use the `NGINX` server too, because that support is deprecated in my organization.\n\n========================================\n\nTop Answer:\nFor people landing here looking for fastapi/uvicorn help:\n\n```\nuvicorn api:app\\\n --ssl-certfile=yourcert.pem\\\n --ssl-keyfile=yourkey.pem\\\n --host 0.0.0.0 --port 443 --workers 1\\\n &\\\n uvicorn api:app\\\n --host 0.0.0.0 --port 80 --workers 1\n```\n\nYou should know, the background daemon will fail to close on `CTRL+C`. It's best to use something like tmux, and run the `:80` and `:443` in different windows.\n\n========================================\n\nCode:\n```text\ngunicorn\n```\n\n```text\nHTTP\n```\n\n```text\nHTTPS\n```\n\n```text\n200 Response\n```\n\n```text\nNGINX\n```\n\n```text\nENTRYPOINT ./start.sh\n```\n\n```text\ngunicorn -k uvicorn.workers.UvicornWorker -w 3 -b 0.0.0.0:30000 -t 360 --reload app:app & gunicorn -k uvicorn.workers.UvicornWorker -w 3 --ssl-certfile certfile.txt --ssl-keyfile keyfile.txt --ca-certs ca_certs.txt -b 0.0.0.0:8443 -t 360 --reload app:app\n```\n\n```text\n&\n```\n\n```text\ngunicorn\n```\n\n```text\nfastAPI\n```\n\n```text\nuvicorn\n```\n\n```py\nuvicorn api:app\\\n --ssl-certfile=yourcert.pem\\\n --ssl-keyfile=yourkey.pem\\\n --host 0.0.0.0 --port 443 --workers 1\\\n &\\\n uvicorn api:app\\\n --host 0.0.0.0 --port 80 --workers 1\n```\n\n```text\nCTRL+C\n```\n\n```text\n:80\n```\n\n```text\n:443\n```\n\n========================================\n\nComments:\n- Is there a way to run it a python script?","metadata":{"transformedAt":"2026-08-18T18:32:29.150Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":15,"totalLines":111,"estimatedTokens":600}}618{"id":"stack-65903231","source":"stackoverflow","questionId":65903231,"title":"How to return a numpy array as an image using FastAPI?","tags":["python","numpy","fastapi","python-imageio"],"text":"Title: How to return a numpy array as an image using FastAPI?\nTags: python, numpy, fastapi, python-imageio\nSource: Stack Overflow\n\nQuestion:\nI load an image with `img = imageio.imread('hello.jpg')`.\nI want to return this numpy array as an image. I know I can do `return FileResponse('hello.jpg')`, however, in the future, I will have the pictures as numpy arrays.\n\nHow can I return the numpy array `img` from FastAPI server in a way that it is equivalent to `return FileResponse('hello.jpg')`?\n\n========================================\n\nTop Answer:\nYou can use StreamingResponse (https://fastapi.tiangolo.com/advanced/custom-response/#using-streamingresponse-with-file-like-objects) to do it e.g., but before you will need to convert your numpy array to the `io.BytesIO` or `io.StringIO`\n\n========================================\n\nCode:\n```text\nimg = imageio.imread('hello.jpg')\n```\n\n```text\nreturn FileResponse('hello.jpg')\n```\n\n```text\nimg\n```\n\n```text\nreturn FileResponse('hello.jpg')\n```\n\n```py\nimport io\nimport imageio\nfrom imageio import v3 as iio\nfrom fastapi import Response\n\n@app.get(\"/image\", response_class=Response)\ndef get_image():\n im = imageio.imread(\"test.jpeg\") # 'im' could be an in-memory image (numpy array) instead\n with io.BytesIO() as buf:\n iio.imwrite(buf, im, plugin=\"pillow\", format=\"JPEG\")\n im_bytes = buf.getvalue()\n \n headers = {'Content-Disposition': 'inline; filename=\"test.jpeg\"'}\n return Response(im_bytes, headers=headers, media_type='image/jpeg')\n```\n\n```text\nStreamingResponse\n```\n\n```text\nStreamingResponse\n```\n\n```text\nResponse\n```\n\n```text\nBytesIO\n```\n\n```text\nImageio\n```\n\n```text\nPIL\n```\n\n```text\nPillow\n```\n\n```text\nPIL\n```\n\n```text\nmedia_type\n```\n\n```text\nContent-Disposition\n```\n\n```text\nattachment\n```\n\n```text\ninline\n```\n\n```text\nio.BytesIO\n```\n\n```text\nio.StringIO\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.150Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":19,"totalLines":106,"estimatedTokens":462}}619{"id":"stack-76136469","source":"stackoverflow","questionId":76136469,"title":"How to allow hyphen (-) in query parameter name using FastAPI?","tags":["python","query-string","fastapi","pydantic"],"text":"Title: How to allow hyphen (-) in query parameter name using FastAPI?\nTags: python, query-string, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI have a simple application below:\n\n```\nfrom typing import Annotated\n\nimport uvicorn\nfrom fastapi import FastAPI, Query, Depends\nfrom pydantic import BaseModel\n\napp = FastAPI()\n\nclass Input(BaseModel):\n a: Annotated[str, Query(..., alias=\"your_name\")]\n\n@app.get(\"/\")\ndef test(inp: Annotated[Input, Depends()]):\n return f\"Hello {inp.a}\"\n\ndef main():\n uvicorn.run(\"run:app\", host=\"0.0.0.0\", reload=True, port=8001)\n\nif __name__ == \"__main__\":\n main()\n```\n\n`curl \"http://127.0.0.1:8001/?your_name=amin\"` returns \"Hello amin\"\n\nI now **change the alias from `your_name` to `your-name`**.\n\n```\nfrom typing import Annotated\n\nimport uvicorn\nfrom fastapi import FastAPI, Query, Depends\nfrom pydantic import BaseModel\n\napp = FastAPI()\n\nclass Input(BaseModel):\n a: Annotated[str, Query(..., alias=\"your-name\")]\n\n@app.get(\"/\")\ndef test(inp: Annotated[Input, Depends()]):\n return f\"Hello {inp.a}\"\n\ndef main():\n uvicorn.run(\"run:app\", host=\"0.0.0.0\", reload=True, port=8001)\n\nif __name__ == \"__main__\":\n main()\n```\n\nThen `curl \"http://127.0.0.1:8001/?your-name=amin\"` returns:\n\n```\n{\"detail\":[{\"loc\":[\"query\",\"extra_data\"],\"msg\":\"field required\",\"type\":\"value_error.missing\"}]}\n```\n\nHowever, hyphened alias in a simpler application is allowed.\n\n```\nfrom typing import Annotated\n\nimport uvicorn\nfrom fastapi import FastAPI, Query\n\napp = FastAPI()\n\n@app.get(\"/\")\ndef test(a: Annotated[str, Query(..., alias=\"your-name\")]):\n return f\"Hello {a}\"\n\ndef main():\n uvicorn.run(\"run:app\", host=\"0.0.0.0\", reload=True, port=8001)\n\nif __name__ == \"__main__\":\n main()\n```\n\n`curl \"http://127.0.0.1:8001/?your-name=amin\"` returns \"Hello Amin\"\n\nIs this a bug? what is the problem here?\n\n========================================\n\nCode:\n```py\nfrom typing import Annotated\n\nimport uvicorn\nfrom fastapi import FastAPI, Query, Depends\nfrom pydantic import BaseModel\n\napp = FastAPI()\n\n\nclass Input(BaseModel):\n a: Annotated[str, Query(..., alias=\"your_name\")]\n\n\n@app.get(\"/\")\ndef test(inp: Annotated[Input, Depends()]):\n return f\"Hello {inp.a}\"\n\n\ndef main():\n uvicorn.run(\"run:app\", host=\"0.0.0.0\", reload=True, port=8001)\n\n\nif __name__ == \"__main__\":\n main()\n```\n\n```py\nfrom typing import Annotated\n\nimport uvicorn\nfrom fastapi import FastAPI, Query, Depends\nfrom pydantic import BaseModel\n\napp = FastAPI()\n\n\nclass Input(BaseModel):\n a: Annotated[str, Query(..., alias=\"your-name\")]\n\n\n@app.get(\"/\")\ndef test(inp: Annotated[Input, Depends()]):\n return f\"Hello {inp.a}\"\n\n\ndef main():\n uvicorn.run(\"run:app\", host=\"0.0.0.0\", reload=True, port=8001)\n\n\nif __name__ == \"__main__\":\n main()\n```\n\n```text\n{\"detail\":[{\"loc\":[\"query\",\"extra_data\"],\"msg\":\"field required\",\"type\":\"value_error.missing\"}]}\n```\n\n```py\nfrom typing import Annotated\n\nimport uvicorn\nfrom fastapi import FastAPI, Query\n\napp = FastAPI()\n\n\n@app.get(\"/\")\ndef test(a: Annotated[str, Query(..., alias=\"your-name\")]):\n return f\"Hello {a}\"\n\n\ndef main():\n uvicorn.run(\"run:app\", host=\"0.0.0.0\", reload=True, port=8001)\n\n\nif __name__ == \"__main__\":\n main()\n```\n\n```text\ncurl \"http://127.0.0.1:8001/?your_name=amin\"\n```\n\n```text\nyour_name\n```\n\n```text\nyour-name\n```\n\n```text\ncurl \"http://127.0.0.1:8001/?your-name=amin\"\n```\n\n```text\ncurl \"http://127.0.0.1:8001/?your-name=amin\"\n```\n\n```json\n{\"detail\":[{\"loc\":[\"query\",\"extra_data\"],\"msg\":\"field required\",\"type\":\"value_error.missing\"}]}\n```\n\n```py\nfrom fastapi import Query, Depends\nfrom pydantic import BaseModel, Field\n\nclass Input(BaseModel):\n a: str = Field(Query(..., alias=\"your-name\"))\n\n\n@app.get(\"/\")\ndef main(i: Input = Depends()):\n pass\n```\n\n```py\nfrom fastapi import Query, Depends\nfrom dataclasses import dataclass\n\n@dataclass\nclass Input:\n a: str = Query(..., alias=\"your-name\")\n\n\n@app.get(\"/\")\ndef main(i: Input = Depends()):\n pass\n```\n\n```py\nfrom fastapi import Query\n\n@app.get(\"/\")\ndef main(a: str = Query(..., alias=\"your-name\")):\n pass\n```\n\n```text\nextra_data\n```\n\n```text\nBaseModel\n```\n\n```text\n/docs\n```\n\n```text\nextra_data\n```\n\n```text\ninspect.signature()\n```\n\n```text\nBaseModel\n```\n\n```text\nextra_data\n```\n\n```text\nextra_data\n```\n\n```text\nQuery()\n```\n\n```text\nField()\n```\n\n```text\nBaseModel\n```\n\n```text\nBaseModel\n```\n\n========================================\n\nComments:\n- Does `curl \"http://127.0.0.1:8001/?your%2Dname=amin\"` work?\n- no. the same error response\n- In your first solution, could you write it with `Annotated`?\n- the question is can I have Annotated and Field and Query in the same line?\n- `a: Annotated[str, Field(Query(..., alias=` in fastapi version 0.95.1\n- The question is about how to use hyphens in query parameters, when these are defined within a Pydantic model. *\"Python itself doesn't do anything with this `Annotated`\"*, and there is nothing preventing one from using `=` instead (regardless of the FastAPI version one might be using) - it serves the same purpose. In fact, there are cases, just like in Solution 1, where one needs to use `=` instead, as there stiil seem to be issues with `Annotated`.\n- Also, please *\"have in mind that when using `Query` inside of `Annotated` you cannot use the default parameter for `Query`\"*, as shown in your question.\n- I submitted an issue in the fastapi github issues github.com/tiangolo/fastapi/discussions/9472","metadata":{"transformedAt":"2026-08-18T18:32:29.150Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":25,"totalLines":289,"estimatedTokens":1346}}620{"id":"stack-75781488","source":"stackoverflow","questionId":75781488,"title":"How to use FastApi and SqlAlchemy for asynchronous operations","tags":["python-3.x","sqlalchemy","python-asyncio","fastapi"],"text":"Title: How to use FastApi and SqlAlchemy for asynchronous operations\nTags: python-3.x, sqlalchemy, python-asyncio, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm using translation software, there may be some mistakes in expression, please understand\nI have checked the tutorials on the internet and followed the corresponding ideas, but I have encountered a little problem, I can't use asynchronous SqlAlchemyc to operate Mysql.\n\n**Database connection**\n\n```\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.ext.asyncio import create_async_engine\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import sessionmaker, scoped_session\nfrom urllib import parse\nimport sys\n\nengine = create_async_engine(Sql_URL)\n\nSessionLocal = sessionmaker(bind=engine,autocommit=False,autoflush=False)\ndb_session = scoped_session(SessionLocal)\n\nBase = declarative_base()\nBase.query = db_session.query_property()\n```\n\n**Models**\n\n```\nimport asyncio\nimport datetime\n\nfrom sqlalchemy import Column, Integer, String, Boolean, DateTime, ForeignKey, MetaData\nfrom sqlalchemy.orm import registry\nfrom sqlalchemy_utils import EmailType,ChoiceType\n\nfrom app.Fast_blog.database import Base\n\nclass user(Base):\n choices = [\n ('0', 'woman'),\n ('1', 'man'),\n ('2', 'NULL')\n ]\n __tablename__ = \"usertable\"\n __table_args__ = {'extend_existing': True}\n UserId = Column(Integer,primary_key = True,index = True)\n username = Column(String(255))\n userpassword = Column(String(255))\n gender = Column(ChoiceType(choices))\n creation_time = Column(DateTime,default = datetime.datetime.now)\n Last_Login_Time = Column(DateTime,default= datetime.datetime.now)\n UserUuid = Column(String(255))\n UserEmail = Column(EmailType(255))\n\nclass Blog(Base):\n __tablename__ = \"blogtable\"\n __table_args__ = {'extend_existing': True}\n title = Column(String(255))\n content = Column(String(255))\n author = Column(String(255))\n BlogId = Column(String(255),primary_key=True,index=True)\n BlogUuid = Column(String(32))\n```\n\n**Views**\n\n```\nimport uuid\nfrom typing import Generator\n\nfrom sqlalchemy.ext.asyncio import async_session\nfrom sqlalchemy import select\n\nfrom app.Fast_blog import model\nfrom app.Fast_blog.model import models\nfrom app.Fast_blog.database.database import engine\nfrom sqlalchemy.orm import sessionmaker\nfrom fastapi.staticfiles import StaticFiles\nfrom fastapi.templating import Jinja2Templates\nfrom pydantic import EmailStr\nfrom fastapi import APIRouter\n\nfrom app.Fast_blog.model.models import user\n\nSessionLocal = sessionmaker(autocommit=False,autoflush=False,bind=engine)\nSession = SessionLocal()\n\nUserApp = APIRouter()\n\ntemplates = Jinja2Templates(directory=\"./Fast_blog/templates\")\n\nUserApp.mount(\"/static\", StaticFiles(directory=\"./Fast_blog/static\"), name=\"static\")\n\ndef UUID_crt(UuidApi):\n x = uuid.uuid5(uuid.NAMESPACE_DNS,UuidApi)\n return x\n\n@UserApp.get(\"/\")\nasync def query():\n async with Session as session:\n sql = select(model).where(model.id == 1)\n print(sql)\n result = await session.execute(sql)\n data = result.scalars().first()\n # data = result.scalars().all()\n```\n\nWhen I go to test this **def query function**\n\nThen I have a question, is this asynchronous SqlAlchemyc connection a success or a failure? Or is there something wrong with my coding?\n\nit reports an error\n\n```\nTraceback (most recent call last):\n File \"d:\\python3\\lib\\site-packages\\uvicorn\\protocols\\http\\h11_impl.py\", line 404, in run_asgi\n result = await app( # type: ignore[func-returns-value]\n File \"d:\\python3\\lib\\site-packages\\uvicorn\\middleware\\proxy_headers.py\", line 78, in __call__\n return await self.app(scope, receive, send)\n File \"d:\\python3\\lib\\site-packages\\uvicorn\\middleware\\debug.py\", line 106, in __call__\n raise exc from None\n File \"d:\\python3\\lib\\site-packages\\uvicorn\\middleware\\debug.py\", line 103, in __call__\n await self.app(scope, receive, inner_send)\n File \"d:\\python3\\lib\\site-packages\\fastapi\\applications.py\", line 270, in __call__\n await super().__call__(scope, receive, send)\n File \"d:\\python3\\lib\\site-packages\\starlette\\applications.py\", line 124, in __call__\n await self.middleware_stack(scope, receive, send)\n File \"d:\\python3\\lib\\site-packages\\starlette\\middleware\\errors.py\", line 184, in __call__\n raise exc\n File \"d:\\python3\\lib\\site-packages\\starlette\\middleware\\errors.py\", line 162, in __call__\n await self.app(scope, receive, _send)\n File \"d:\\python3\\lib\\site-packages\\starlette\\middleware\\exceptions.py\", line 79, in __call__\n raise exc\n File \"d:\\python3\\lib\\site-packages\\starlette\\middleware\\exceptions.py\", line 68, in __call__\n await self.app(scope, receive, sender)\n File \"d:\\python3\\lib\\site-packages\\fastapi\\middleware\\asyncexitstack.py\", line 21, in __call__\n raise e\n File \"d:\\python3\\lib\\site-packages\\fastapi\\middleware\\asyncexitstack.py\", line 18, in __call__\n await self.app(scope, receive, send)\n File \"d:\\python3\\lib\\site-packages\\starlette\\routing.py\", line 706, in __call__\n await route.handle(scope, receive, send)\n File \"d:\\python3\\lib\\site-packages\\starlette\\routing.py\", line 276, in handle\n await self.app(scope, receive, send)\n File \"d:\\python3\\lib\\site-packages\\starlette\\routing.py\", line 66, in app\n response = await func(request)\n File \"d:\\python3\\lib\\site-packages\\fastapi\\routing.py\", line 237, in app\n raw_response = await run_endpoint_function(\n File \"d:\\python3\\lib\\site-packages\\fastapi\\routing.py\", line 163, in run_endpoint_function\n return await dependant.call(**values)\n File \".\\Fast_blog\\apps\\User_app\\user.py\", line 37, in query\n async with Session as session:\nAttributeError: __aenter__\n```\n\nPlease help me, point out where my code is not correct,I also tried Google. but it doesn't seem to be the same as my problem\n\n========================================\n\nCode:\n```text\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.ext.asyncio import create_async_engine\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import sessionmaker, scoped_session\nfrom urllib import parse\nimport sys\n\nengine = create_async_engine(Sql_URL)\n\n\nSessionLocal = sessionmaker(bind=engine,autocommit=False,autoflush=False)\ndb_session = scoped_session(SessionLocal)\n\nBase = declarative_base()\nBase.query = db_session.query_property()\n```\n\n```text\nimport asyncio\nimport datetime\n\nfrom sqlalchemy import Column, Integer, String, Boolean, DateTime, ForeignKey, MetaData\nfrom sqlalchemy.orm import registry\nfrom sqlalchemy_utils import EmailType,ChoiceType\n\nfrom app.Fast_blog.database import Base\n\n\nclass user(Base):\n choices = [\n ('0', 'woman'),\n ('1', 'man'),\n ('2', 'NULL')\n ]\n __tablename__ = \"usertable\"\n __table_args__ = {'extend_existing': True}\n UserId = Column(Integer,primary_key = True,index = True)\n username = Column(String(255))\n userpassword = Column(String(255))\n gender = Column(ChoiceType(choices))\n creation_time = Column(DateTime,default = datetime.datetime.now)\n Last_Login_Time = Column(DateTime,default= datetime.datetime.now)\n UserUuid = Column(String(255))\n UserEmail = Column(EmailType(255))\n\nclass Blog(Base):\n __tablename__ = \"blogtable\"\n __table_args__ = {'extend_existing': True}\n title = Column(String(255))\n content = Column(String(255))\n author = Column(String(255))\n BlogId = Column(String(255),primary_key=True,index=True)\n BlogUuid = Column(String(32))\n```\n\n```text\nimport uuid\nfrom typing import Generator\n\nfrom sqlalchemy.ext.asyncio import async_session\nfrom sqlalchemy import select\n\nfrom app.Fast_blog import model\nfrom app.Fast_blog.model import models\nfrom app.Fast_blog.database.database import engine\nfrom sqlalchemy.orm import sessionmaker\nfrom fastapi.staticfiles import StaticFiles\nfrom fastapi.templating import Jinja2Templates\nfrom pydantic import EmailStr\nfrom fastapi import APIRouter\n\nfrom app.Fast_blog.model.models import user\n\nSessionLocal = sessionmaker(autocommit=False,autoflush=False,bind=engine)\nSession = SessionLocal()\n\n\nUserApp = APIRouter()\n\ntemplates = Jinja2Templates(directory=\"./Fast_blog/templates\")\n\nUserApp.mount(\"/static\", StaticFiles(directory=\"./Fast_blog/static\"), name=\"static\")\n\n\ndef UUID_crt(UuidApi):\n x = uuid.uuid5(uuid.NAMESPACE_DNS,UuidApi)\n return x\n\n@UserApp.get(\"/\")\nasync def query():\n async with Session as session:\n sql = select(model).where(model.id == 1)\n print(sql)\n result = await session.execute(sql)\n data = result.scalars().first()\n # data = result.scalars().all()\n```\n\n```text\nTraceback (most recent call last):\n File \"d:\\python3\\lib\\site-packages\\uvicorn\\protocols\\http\\h11_impl.py\", line 404, in run_asgi\n result = await app( # type: ignore[func-returns-value]\n File \"d:\\python3\\lib\\site-packages\\uvicorn\\middleware\\proxy_headers.py\", line 78, in __call__\n return await self.app(scope, receive, send)\n File \"d:\\python3\\lib\\site-packages\\uvicorn\\middleware\\debug.py\", line 106, in __call__\n raise exc from None\n File \"d:\\python3\\lib\\site-packages\\uvicorn\\middleware\\debug.py\", line 103, in __call__\n await self.app(scope, receive, inner_send)\n File \"d:\\python3\\lib\\site-packages\\fastapi\\applications.py\", line 270, in __call__\n await super().__call__(scope, receive, send)\n File \"d:\\python3\\lib\\site-packages\\starlette\\applications.py\", line 124, in __call__\n await self.middleware_stack(scope, receive, send)\n File \"d:\\python3\\lib\\site-packages\\starlette\\middleware\\errors.py\", line 184, in __call__\n raise exc\n File \"d:\\python3\\lib\\site-packages\\starlette\\middleware\\errors.py\", line 162, in __call__\n await self.app(scope, receive, _send)\n File \"d:\\python3\\lib\\site-packages\\starlette\\middleware\\exceptions.py\", line 79, in __call__\n raise exc\n File \"d:\\python3\\lib\\site-packages\\starlette\\middleware\\exceptions.py\", line 68, in __call__\n await self.app(scope, receive, sender)\n File \"d:\\python3\\lib\\site-packages\\fastapi\\middleware\\asyncexitstack.py\", line 21, in __call__\n raise e\n File \"d:\\python3\\lib\\site-packages\\fastapi\\middleware\\asyncexitstack.py\", line 18, in __call__\n await self.app(scope, receive, send)\n File \"d:\\python3\\lib\\site-packages\\starlette\\routing.py\", line 706, in __call__\n await route.handle(scope, receive, send)\n File \"d:\\python3\\lib\\site-packages\\starlette\\routing.py\", line 276, in handle\n await self.app(scope, receive, send)\n File \"d:\\python3\\lib\\site-packages\\starlette\\routing.py\", line 66, in app\n response = await func(request)\n File \"d:\\python3\\lib\\site-packages\\fastapi\\routing.py\", line 237, in app\n raw_response = await run_endpoint_function(\n File \"d:\\python3\\lib\\site-packages\\fastapi\\routing.py\", line 163, in run_endpoint_function\n return await dependant.call(**values)\n File \".\\Fast_blog\\apps\\User_app\\user.py\", line 37, in query\n async with Session as session:\nAttributeError: __aenter__\n```\n\n```text\nfrom asyncio import current_task\nfrom sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_scoped_session\nfrom sqlalchemy.orm import sessionmaker\n\nengine = create_async_engine(Sql_URL)\n\nSessionLocal = sessionmaker(bind=engine, autocommit=False, autoflush=False, class_=AsyncSession)\ndb_session = async_scoped_session(SessionLocal, scopefunc=current_task)\n```\n\n```text\nSessionLocal = sessionmaker(bind=engine,autocommit=False,autoflush=False)\n```\n\n```text\nclass_=AsyncSession\n```\n\n========================================\n\nComments:\n- thank you very much for your help, I used your proposal to make changes. Subsequently, I changed the query code to look like this ``` @UserApp.get(\"/\") async def query(): async with db_session() as session: sql = select(models.user).where(model.models.id == 1) ``` But he hinted at this error ``` Column expression, FROM clause, or other columns clause element expected, got . ```\n- if it works can you accept the answer @Exploit? and no prob regarding the misunderstanding\n- I have some more questions, please see the above questions, because my network problems, may be a little delayed response\n- you are asking an entirely different question now, I will try to help but you have to show your code @Exploit I am not able to figure out what is `model` and `models`\n- from app.Fast_blog.database.database import db_session from app.Fast_blog.model import models Main Code !MY2Fk.jpeg Database Models !MYrcy.jpeg\n- sql = select(models.user).where(models.user.UserEmail == 1) sqlalchemy.exc.ArgumentError: Column expression, FROM clause, or other columns clause element expected, got . It prompts an error like this\n- `class user(Base)` you just have `class user()` does changing that work?\n- Thanks again for your help, it works fine now. Your help was very helpful for my first time learning.😭😭","metadata":{"transformedAt":"2026-08-18T18:32:29.150Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":7,"totalLines":331,"estimatedTokens":3162}}621{"id":"stack-78680384","source":"stackoverflow","questionId":78680384,"title":"During uvicorn startup, child process dies in a Kubernetes cluster","tags":["python-3.x","kubernetes","fastapi","azure-aks","uvicorn"],"text":"Title: During uvicorn startup, child process dies in a Kubernetes cluster\nTags: python-3.x, kubernetes, fastapi, azure-aks, uvicorn\nSource: Stack Overflow\n\nQuestion:\nWe are using FastAPI version `0.111.0` for our application. The `uvicorn` server is started as shown below:\n\n```\nuvicorn.run(\n \"main:app\",\n host='0.0.0.0',\n port=8080,\n log_level=\"DEBUG\",\n workers=3\n )\n```\n\nThis works on a Windows machine during our development/test environment. When we deploy this code to the Azure Kubernets cluster, during startup the child process dies.\n\nError message:\n\n```\nINFO: Uvicorn running on http://0.0.0.0:8080 (Press CTRL+C to quit)\nINFO: Started parent process [1]\nINFO: Waiting for child process [12]\nINFO: Child process [12] died\nINFO: Waiting for child process [13]\nINFO: Child process [13] died\nINFO: Waiting for child process [14]\nINFO: Child process [14] died\nINFO: Waiting for child process [13]\nINFO: Child process [13] died\nINFO: Waiting for child process [15]\n```\n\nIf we remove the `workers` argument for the `uvicoen.run` call, the application starts in AKS. I would like to understand, why the child process dies with the `workers` argument.\n\n========================================\n\nTop Answer:\nI experimented with the request/limit CPU setting for our FastAPI app running with 5 child threads on a small AKS node.\n\nWhat I noticed is that when the CPU limit value of the pod is too low, the child processes are crashing during initial startup.\n\nIn our case (very simple API) I had to put the limit on 400mi (request I kept on 20mi). During 0.5 minute or so, the pod is using then 330mi and once started it drops to 10mi.\n\nOnly consistent thing I see happening is that the first spawned child process is still crashing. But that is directly replaced by another child process.\n\nMaybe when you don't specify any limits and the pod is deployed on a node that has insufficient CPU available, it won't get enough too startup correctly.\n\nI also wonder that precompiling the code to pyc may decrease the need for the higher limit.\n\n========================================\n\nCode:\n```text\nuvicorn.run(\n \"main:app\",\n host='0.0.0.0',\n port=8080,\n log_level=\"DEBUG\",\n workers=3\n )\n```\n\n```text\nINFO: Uvicorn running on http://0.0.0.0:8080 (Press CTRL+C to quit)\nINFO: Started parent process [1]\nINFO: Waiting for child process [12]\nINFO: Child process [12] died\nINFO: Waiting for child process [13]\nINFO: Child process [13] died\nINFO: Waiting for child process [14]\nINFO: Child process [14] died\nINFO: Waiting for child process [13]\nINFO: Child process [13] died\nINFO: Waiting for child process [15]\n```\n\n```text\n0.111.0\n```\n\n```text\nuvicorn\n```\n\n```text\nworkers\n```\n\n```text\nuvicoen.run\n```\n\n```text\nworkers\n```\n\n```text\npip install fastapi[all]==0.110.3\n```\n\n========================================\n\nComments:\n- This discussion may help.\n- This looks like workaround, like to see the fix in new version\n- I have upgraded uvicorn to 0.30.3, but the issues remains\n- Have you figured out how to solve this problem?\n- Setup with 5 threads and 2 replicas is running fine for months now for our use case. But we enforce that everything that is being deployed on the cluster has set limits for CPU and memory by using OPA Gatekeeper. This avoids that some pods are hijacking all resources and impacts other pods. I read after posting my previous post that it is better to stick to 1 worker process per pod and scaling it up by your replicas count of the deployment. That way the spread of pods over your available nodes is better, you can set cleaner limits and in case of pod crash it has less impact.\n- @Stebo And precompiling the code in pyc files has no impact on how the app is behaving during startup","metadata":{"transformedAt":"2026-08-18T18:32:29.150Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":8,"totalLines":112,"estimatedTokens":959}}622{"id":"stack-67776535","source":"stackoverflow","questionId":67776535,"title":"Sending files using python 'aiohttp' produce \"There was an error parsing the body\"","tags":["python","python-3.x","aiohttp","fastapi"],"text":"Title: Sending files using python 'aiohttp' produce \"There was an error parsing the body\"\nTags: python, python-3.x, aiohttp, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to make two services communicate. The first API is exposed to the user.\nThe second is hidden and can process files. So the first can redirect requests.\nI want to make of the post request asynchronus using aiohttp but i am facing this error : \"There was an error parsing the body\"\n\nTo recreate the error :\nLets say this is the server code\n\n```\nfrom fastapi import FastAPI\nfrom fastapi import UploadFile, File\n\napp = FastAPI()\n\n@app.post(\"/upload\")\nasync def transcript_file(file: UploadFile = File(...)):\n pass\n```\n\nAnd this is the client code :\n\n```\nfrom fastapi import FastAPI\nimport aiohttp\napp = FastAPI()\n\n@app.post(\"/upload_client\")\nasync def async_call():\n async with aiohttp.ClientSession() as session:\n headers = {'accept': '*/*',\n 'Content-Type': 'multipart/form-data'}\n file_dict = {\"file\": open(\"any_file\",\"rb\")}\n async with session.post(\"http://localhost:8000/upload\", headers=headers, data=file_dict) as response:\n return await response.json()\n```\n\n**Description** :\n\n- Run the server on port 8000 and the client on any port you like\n\n- Open the browser and open docs on the client.\n\n- Execute the post request and see the error\n\n**Environment** :\n\n- aiohttp = 3.7.4\n\n- fastapi = 0.63.0\n\n- uvicorn = 0.13.4\n\n- python-multipart = 0.0.2\n\nPython version: 3.8.8\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nfrom fastapi import UploadFile, File\n\napp = FastAPI()\n\n@app.post(\"/upload\")\nasync def transcript_file(file: UploadFile = File(...)):\n pass\n```\n\n```text\nfrom fastapi import FastAPI\nimport aiohttp\napp = FastAPI()\n\n@app.post(\"/upload_client\")\nasync def async_call():\n async with aiohttp.ClientSession() as session:\n headers = {'accept': '*/*',\n 'Content-Type': 'multipart/form-data'}\n file_dict = {\"file\": open(\"any_file\",\"rb\")}\n async with session.post(\"http://localhost:8000/upload\", headers=headers, data=file_dict) as response:\n return await response.json()\n```\n\n```text\nmultipart/*\n```\n\n```text\nContent-Type\n```\n\n```text\nContent-Type\n```\n\n```text\naiohttp\n```\n\n```text\nboundary\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.150Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":7,"totalLines":108,"estimatedTokens":569}}623{"id":"stack-79764955","source":"stackoverflow","questionId":79764955,"title":"Pytest in FastAPI + Postgres results in: :0: RuntimeWarning: coroutine 'Connection._cancel' was never awaited","tags":["python","pytest","python-asyncio","fastapi","asyncpg"],"text":"Title: Pytest in FastAPI + Postgres results in: :0: RuntimeWarning: coroutine 'Connection._cancel' was never awaited\nTags: python, pytest, python-asyncio, fastapi, asyncpg\nSource: Stack Overflow\n\nQuestion:\nI'm writing tests for my fastapi application that uses asynchronous posgtres connection:\n\n```\n# backend/database/session.py\nfrom sqlmodel import SQLModel\nfrom sqlmodel.ext.asyncio.session import AsyncSession\nfrom sqlalchemy.ext.asyncio import create_async_engine\nfrom sqlalchemy.orm import sessionmaker\nfrom config import config\n\nengine = create_async_engine(\n config.db_uri,\n echo=config.db_echo,\n # Connection pool configuration for scalability\n # Number of connections to maintain in pool\n pool_size=config.db_pool_size,\n # Additional connections when pool is full\n max_overflow=config.db_max_overflow,\n # Validate connections before use\n pool_pre_ping=True,\n # Recycle connections after specified time\n pool_recycle=config.db_pool_recycle,\n # Timeout waiting for available connection\n pool_timeout=config.db_pool_timeout,\n # Reset connection state on return\n pool_reset_on_return='commit',\n # Performance optimizations\n # Don't log pool operations (set to True for debugging)\n echo_pool=False,\n # Connection arguments\n connect_args={\n \"ssl\": config.db_ssl\n }\n)\n\nasync def init_db():\n async with engine.begin() as conn:\n await conn.run_sync(SQLModel.metadata.create_all)\n\nasync def get_session() -> AsyncSession: # type: ignore\n Session = sessionmaker(\n bind=engine,\n class_=AsyncSession,\n expire_on_commit=False,\n autocommit=False,\n autoflush=False\n )\n async with Session() as session:\n yield session\n```\n\nMy app, db connection and api routes work fine. My tests however are not. To be more precise all tests that require a `db_session` do not work correctly.\n\nI run my tests effectively in a python file via the `subprocess` module because I'm updating the env variables before each run to point to a different test database and run the migrations.\n\n```\n# backend/tests/run_tests.py\n\n# \n# Run the integration tests\ndef run_tests(env):\n print(\"Running unit tests...\\n\")\n try:\n # subprocess.run(\"ls\")\n subprocess.run(\"pytest -s --color=yes\",\n shell=True, check=True, text=True, env=env)\n except subprocess.CalledProcessError as e:\n print(f\"Error when running tests: {e}\")\n pass\n print(\"\\nTests completed.\")\n\n# \n```\n\nHere is one test that requires the db session and will fail:\n\n```\n# backend/tests/user/test_signup.py\n\nimport pytest\nfrom httpx import AsyncClient\nfrom httpx._transports.asgi import ASGITransport\nfrom main import app\n\n@pytest.mark.asyncio\nasync def test_signup_successful():\n \"\"\"Test user signup with valid data\"\"\"\n # Use ASGITransport explicitly\n transport = ASGITransport(app=app)\n async with AsyncClient(transport=transport, base_url=\"http://test\") as client:\n # Define the request payload\n payload = {\n \"first_name\": \"Test\",\n \"last_name\": \"User\",\n \"email\": \"integration_testuser@example.com\",\n \"password\": \"Strongpassword123-\"\n }\n # Perform POST request\n response = await client.post(\"/user/signup\", json=payload)\n\n # Assertions\n assert response.status_code == 201\n data = response.json()\n assert data[\"email\"] == payload[\"email\"]\n```\n\nThis is the traceback I get (cut down to the last 40% of the actual traceback due to stack character limit):\n\n```\nFile \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/core/user/helper.py\", line 52, in _get_users\n result = await session.exec(statement)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlmodel/ext/asyncio/session.py\", line 81, in exec\n result = await greenlet_spawn(\n ^^^^^^^^^^^^^^^^^^^^^\n ......\n )\n ^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/util/_concurrency_py3k.py\", line 201, in greenlet_spawn\n result = context.throw(*sys.exc_info())\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlmodel/orm/session.py\", line 66, in exec\n results = super().execute(\n statement,\n ......\n _add_event=_add_event,\n )\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/orm/session.py\", line 2365, in execute\n return self._execute_internal(\n ~~~~~~~~~~~~~~~~~~~~~~^\n statement,\n ^^^^^^^^^^\n ......\n _add_event=_add_event,\n ^^^^^^^^^^^^^^^^^^^^^^\n )\n ^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/orm/session.py\", line 2241, in _execute_internal\n conn = self._connection_for_bind(bind)\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/orm/session.py\", line 2110, in _connection_for_bind\n return trans._connection_for_bind(engine, execution_options)\n ~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"\", line 2, in _connection_for_bind\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/orm/state_changes.py\", line 137, in _go\n ret_value = fn(self, *arg, **kw)\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/orm/session.py\", line 1189, in _connection_for_bind\n conn = bind.connect()\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/engine/base.py\", line 3277, in connect\n return self._connection_cls(self)\n ~~~~~~~~~~~~~~~~~~~~^^^^^^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/engine/base.py\", line 143, in __init__\n self._dbapi_connection = engine.raw_connection()\n ~~~~~~~~~~~~~~~~~~~~~^^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/engine/base.py\", line 3301, in raw_connection\n return self.pool.connect()\n ~~~~~~~~~~~~~~~~~^^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/pool/base.py\", line 447, in connect\n return _ConnectionFairy._checkout(self)\n ~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/pool/base.py\", line 1363, in _checkout\n with util.safe_reraise():\n ~~~~~~~~~~~~~~~~~^^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/util/langhelpers.py\", line 224, in __exit__\n raise exc_value.with_traceback(exc_tb)\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/pool/base.py\", line 1301, in _checkout\n result = pool._dialect._do_ping_w_event(\n fairy.dbapi_connection\n )\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/engine/default.py\", line 728, in _do_ping_w_event\n return self.do_ping(dbapi_connection)\n ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py\", line 1169, in do_ping\n dbapi_connection.ping()\n ~~~~~~~~~~~~~~~~~~~~~^^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py\", line 813, in ping\n self._handle_exception(error)\n ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py\", line 794, in _handle_exception\n raise error\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py\", line 811, in ping\n _ = self.await_(self._async_ping())\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/util/_concurrency_py3k.py\", line 132, in await_only\n return current.parent.switch(awaitable) # type: ignore[no-any-return,attr-defined] # noqa: E501\n ~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/util/_concurrency_py3k.py\", line 196, in greenlet_spawn\n value = await result\n ^^^^^^^^^^^^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py\", line 820, in _async_ping\n await tr.start()\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/asyncpg/transaction.py\", line 146, in start\n await self._connection.execute(query)\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/asyncpg/connection.py\", line 349, in execute\n result = await self._protocol.query(query, timeout)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"asyncpg/protocol/protocol.pyx\", line 375, in query\nRuntimeError: Task .call_next..coro' coro=.call_next..coro() running at /Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/starlette/middleware/base.py:144> cb=[TaskGroup._spawn..task_done() at /Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/anyio/_backends/_asyncio.py:794]> got Future attached to a different loop\n\nDuring handling of the above exception, another exception occurred:\n\nsession = \n\n @pytest.mark.asyncio\n async def test_signup_successful(session):\n \"\"\"Test user signup with valid data\"\"\"\n # Use ASGITransport explicitly\n transport = ASGITransport(app=app)\n async with AsyncClient(transport=transport, base_url=\"http://test\") as client:\n # Define the request payload\n payload = {\n \"first_name\": \"Test\",\n \"last_name\": \"User\",\n \"email\": \"integration_testuser@example.com\",\n \"password\": \"Strongpassword123-\"\n }\n # Perform POST request\n> response = await client.post(\"/user/signup\", json=payload)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\ntests/user/test_user_signup.py:35: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n.venv/lib/python3.13/site-packages/httpx/_client.py:1859: in post\n return await self.request(\n.venv/lib/python3.13/site-packages/httpx/_client.py:1540: in request\n return await self.send(request, auth=auth, follow_redirects=follow_redirects)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/httpx/_client.py:1629: in send\n response = await self._send_handling_auth(\n.venv/lib/python3.13/site-packages/httpx/_client.py:1657: in _send_handling_auth\n response = await self._send_handling_redirects(\n.venv/lib/python3.13/site-packages/httpx/_client.py:1694: in _send_handling_redirects\n response = await self._send_single_request(request)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/httpx/_client.py:1730: in _send_single_request\n response = await transport.handle_async_request(request)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/httpx/_transports/asgi.py:170: in handle_async_request\n await self.app(scope, receive, send)\n.venv/lib/python3.13/site-packages/fastapi/applications.py:1054: in __call__\n await super().__call__(scope, receive, send)\n.venv/lib/python3.13/site-packages/starlette/applications.py:113: in __call__\n await self.middleware_stack(scope, receive, send)\n.venv/lib/python3.13/site-packages/starlette/middleware/errors.py:186: in __call__\n raise exc\n.venv/lib/python3.13/site-packages/starlette/middleware/errors.py:164: in __call__\n await self.app(scope, receive, _send)\n.venv/lib/python3.13/site-packages/starlette/middleware/base.py:182: in __call__\n with recv_stream, send_stream, collapse_excgroups():\n ^^^^^^^^^^^^^^^^^^^^\n/opt/homebrew/Cellar/python@3.13/3.13.2/Frameworks/Python.framework/Versions/3.13/lib/python3.13/contextlib.py:162: in __exit__\n self.gen.throw(value)\n.venv/lib/python3.13/site-packages/starlette/_utils.py:83: in collapse_excgroups\n raise exc\n.venv/lib/python3.13/site-packages/starlette/middleware/base.py:184: in __call__\n response = await self.dispatch_func(request, call_next)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nmiddleware.py:27: in execution_timer\n response = await call_next(request)\n ^^^^^^^^^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/starlette/middleware/base.py:159: in call_next\n raise app_exc\n.venv/lib/python3.13/site-packages/starlette/middleware/base.py:144: in coro\n await self.app(scope, receive_or_disconnect, send_no_error)\n.venv/lib/python3.13/site-packages/starlette/middleware/trustedhost.py:36: in __call__\n await self.app(scope, receive, send)\n.venv/lib/python3.13/site-packages/starlette/middleware/cors.py:85: in __call__\n await self.app(scope, receive, send)\n.venv/lib/python3.13/site-packages/starlette/middleware/exceptions.py:63: in __call__\n await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)\n.venv/lib/python3.13/site-packages/starlette/_exception_handler.py:53: in wrapped_app\n raise exc\n.venv/lib/python3.13/site-packages/starlette/_exception_handler.py:42: in wrapped_app\n await app(scope, receive, sender)\n.venv/lib/python3.13/site-packages/starlette/routing.py:716: in __call__\n await self.middleware_stack(scope, receive, send)\n.venv/lib/python3.13/site-packages/starlette/routing.py:736: in app\n await route.handle(scope, receive, send)\n.venv/lib/python3.13/site-packages/starlette/routing.py:290: in handle\n await self.app(scope, receive, send)\n.venv/lib/python3.13/site-packages/starlette/routing.py:78: in app\n await wrap_app_handling_exceptions(app, request)(scope, receive, send)\n.venv/lib/python3.13/site-packages/starlette/_exception_handler.py:53: in wrapped_app\n raise exc\n.venv/lib/python3.13/site-packages/starlette/_exception_handler.py:42: in wrapped_app\n await app(scope, receive, sender)\n.venv/lib/python3.13/site-packages/starlette/routing.py:75: in app\n response = await f(request)\n ^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/fastapi/routing.py:302: in app\n raw_response = await run_endpoint_function(\n.venv/lib/python3.13/site-packages/fastapi/routing.py:213: in run_endpoint_function\n return await dependant.call(**values)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/slowapi/extension.py:734: in async_wrapper\n response = await func(*args, **kwargs) # type: ignore\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^\napi/user/router.py:50: in signup\n user_exists = await service.user_exists(email=email, session=session)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\ncore/user/service.py:67: in user_exists\n user = await self.get_user_by_email(email, session)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\ncore/user/service.py:39: in get_user_by_email\n return await service_helper._get_users(session=session, where_clause=User.email == email, include_roles=include_roles, include_permissions=include_permissions)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\ncore/user/helper.py:52: in _get_users\n result = await session.exec(statement)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/sqlmodel/ext/asyncio/session.py:81: in exec\n result = await greenlet_spawn(\n.venv/lib/python3.13/site-packages/sqlalchemy/util/_concurrency_py3k.py:201: in greenlet_spawn\n result = context.throw(*sys.exc_info())\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/sqlmodel/orm/session.py:66: in exec\n results = super().execute(\n.venv/lib/python3.13/site-packages/sqlalchemy/orm/session.py:2365: in execute\n return self._execute_internal(\n.venv/lib/python3.13/site-packages/sqlalchemy/orm/session.py:2241: in _execute_internal\n conn = self._connection_for_bind(bind)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/sqlalchemy/orm/session.py:2110: in _connection_for_bind\n return trans._connection_for_bind(engine, execution_options)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n:2: in _connection_for_bind\n ???\n.venv/lib/python3.13/site-packages/sqlalchemy/orm/state_changes.py:137: in _go\n ret_value = fn(self, *arg, **kw)\n ^^^^^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/sqlalchemy/orm/session.py:1189: in _connection_for_bind\n conn = bind.connect()\n ^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/sqlalchemy/engine/base.py:3277: in connect\n return self._connection_cls(self)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/sqlalchemy/engine/base.py:143: in __init__\n self._dbapi_connection = engine.raw_connection()\n ^^^^^^^^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/sqlalchemy/engine/base.py:3301: in raw_connection\n return self.pool.connect()\n ^^^^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/sqlalchemy/pool/base.py:447: in connect\n return _ConnectionFairy._checkout(self)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/sqlalchemy/pool/base.py:1363: in _checkout\n with util.safe_reraise():\n ^^^^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/sqlalchemy/util/langhelpers.py:224: in __exit__\n raise exc_value.with_traceback(exc_tb)\n.venv/lib/python3.13/site-packages/sqlalchemy/pool/base.py:1301: in _checkout\n result = pool._dialect._do_ping_w_event(\n.venv/lib/python3.13/site-packages/sqlalchemy/engine/default.py:728: in _do_ping_w_event\n return self.do_ping(dbapi_connection)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py:1169: in do_ping\n dbapi_connection.ping()\n.venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py:813: in ping\n self._handle_exception(error)\n.venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py:794: in _handle_exception\n raise error\n.venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py:811: in ping\n _ = self.await_(self._async_ping())\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/sqlalchemy/util/_concurrency_py3k.py:132: in await_only\n return current.parent.switch(awaitable) # type: ignore[no-any-return,attr-defined] # noqa: E501\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/sqlalchemy/util/_concurrency_py3k.py:196: in greenlet_spawn\n value = await result\n ^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py:820: in _async_ping\n await tr.start()\n.venv/lib/python3.13/site-packages/asyncpg/transaction.py:146: in start\n await self._connection.execute(query)\n.venv/lib/python3.13/site-packages/asyncpg/connection.py:349: in execute\n result = await self._protocol.query(query, timeout)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\n> ???\nE RuntimeError: Task .call_next..coro' coro=.call_next..coro() running at /Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/starlette/middleware/base.py:144> cb=[TaskGroup._spawn..task_done() at /Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/anyio/_backends/_asyncio.py:794]> got Future attached to a different loop\n\nasyncpg/protocol/protocol.pyx:375: RuntimeError\n--------------------------------------------------------------------- Captured log call ----------------------------------------------------------------------\nERROR sqlalchemy.pool.impl.AsyncAdaptedQueuePool:base.py:376 Exception terminating connection >\nTraceback (most recent call last):\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/pool/base.py\", line 372, in _close_connection\n self._dialect.do_terminate(connection)\n ~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py\", line 1136, in do_terminate\n dbapi_connection.terminate()\n ~~~~~~~~~~~~~~~~~~~~~~~~~~^^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py\", line 907, in terminate\n self.await_(asyncio.shield(self._connection.close(timeout=2)))\n ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/util/_concurrency_py3k.py\", line 132, in await_only\n return current.parent.switch(awaitable) # type: ignore[no-any-return,attr-defined] # noqa: E501\n ~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/util/_concurrency_py3k.py\", line 196, in greenlet_spawn\n value = await result\n ^^^^^^^^^^^^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/asyncpg/connection.py\", line 1504, in close\n await self._protocol.close(timeout)\n File \"asyncpg/protocol/protocol.pyx\", line 627, in close\n File \"asyncpg/protocol/protocol.pyx\", line 660, in asyncpg.protocol.protocol.BaseProtocol._request_cancel\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/asyncpg/connection.py\", line 1673, in _cancel_current_command\n self._cancellations.add(self._loop.create_task(self._cancel(waiter)))\n ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^\n File \"/opt/homebrew/Cellar/python@3.13/3.13.2/Frameworks/Python.framework/Versions/3.13/lib/python3.13/asyncio/base_events.py\", line 466, in create_task\n self._check_closed()\n ~~~~~~~~~~~~~~~~~~^^\n File \"/opt/homebrew/Cellar/python@3.13/3.13.2/Frameworks/Python.framework/Versions/3.13/lib/python3.13/asyncio/base_events.py\", line 556, in _check_closed\n raise RuntimeError('Event loop is closed')\nRuntimeError: Event loop is closed\n================================================================== short test summary info ===================================================================\nFAILED tests/user/test_user_signup.py::test_signup_successful - RuntimeError: Task .call_next..coro' coro=:0: RuntimeWarning: coroutine 'Connection._cancel' was never awaited\nError when running tests: Command 'pytest -s --color=yes' returned non-zero exit status 1.\n```\n\nHere is also the GitHub repo if you need more reference.\n\nI also saw this GitHub issue but couldn't really make it work and I'm also not 100% sure if that is the exact same error but it seems likely.\n\n========================================\n\nTop Answer:\nYou shoud use async_session with async_ssesionmaker. the is the example\n\n```\nfrom sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine\n\nasync_engine = create_async_engine(\n settings.postgres_dsn, # Here put your own pg url\n connect_args={},\n)\n\nif __name__ == \"__main__\":\n\n async def main():\n async_session = async_sessionmaker(async_engine, expire_on_commit=False)\n async with async_session() as session:\n async with session.begin():\n result = await session.execute(text(\"select version()\"))\n\n print(result.scalar_one_or_none())\n pass\n await async_engine.dispose()\n```\n\n========================================\n\nCode:\n```text\n# backend/database/session.py\nfrom sqlmodel import SQLModel\nfrom sqlmodel.ext.asyncio.session import AsyncSession\nfrom sqlalchemy.ext.asyncio import create_async_engine\nfrom sqlalchemy.orm import sessionmaker\nfrom config import config\n\n\nengine = create_async_engine(\n config.db_uri,\n echo=config.db_echo,\n # Connection pool configuration for scalability\n # Number of connections to maintain in pool\n pool_size=config.db_pool_size,\n # Additional connections when pool is full\n max_overflow=config.db_max_overflow,\n # Validate connections before use\n pool_pre_ping=True,\n # Recycle connections after specified time\n pool_recycle=config.db_pool_recycle,\n # Timeout waiting for available connection\n pool_timeout=config.db_pool_timeout,\n # Reset connection state on return\n pool_reset_on_return='commit',\n # Performance optimizations\n # Don't log pool operations (set to True for debugging)\n echo_pool=False,\n # Connection arguments\n connect_args={\n \"ssl\": config.db_ssl\n }\n)\n\n\nasync def init_db():\n async with engine.begin() as conn:\n await conn.run_sync(SQLModel.metadata.create_all)\n\n\nasync def get_session() -> AsyncSession: # type: ignore\n Session = sessionmaker(\n bind=engine,\n class_=AsyncSession,\n expire_on_commit=False,\n autocommit=False,\n autoflush=False\n )\n async with Session() as session:\n yield session\n```\n\n```text\n# backend/tests/run_tests.py\n\n# <Update env and run alembic upgrade head>\n# Run the integration tests\ndef run_tests(env):\n print(\"Running unit tests...\\n\")\n try:\n # subprocess.run(\"ls\")\n subprocess.run(\"pytest -s --color=yes\",\n shell=True, check=True, text=True, env=env)\n except subprocess.CalledProcessError as e:\n print(f\"Error when running tests: {e}\")\n pass\n print(\"\\nTests completed.\")\n\n# <Run alembic downgrade base>\n```\n\n```text\n# backend/tests/user/test_signup.py\n\nimport pytest\nfrom httpx import AsyncClient\nfrom httpx._transports.asgi import ASGITransport\nfrom main import app\n\n\n@pytest.mark.asyncio\nasync def test_signup_successful():\n \"\"\"Test user signup with valid data\"\"\"\n # Use ASGITransport explicitly\n transport = ASGITransport(app=app)\n async with AsyncClient(transport=transport, base_url=\"http://test\") as client:\n # Define the request payload\n payload = {\n \"first_name\": \"Test\",\n \"last_name\": \"User\",\n \"email\": \"integration_testuser@example.com\",\n \"password\": \"Strongpassword123-\"\n }\n # Perform POST request\n response = await client.post(\"/user/signup\", json=payload)\n\n # Assertions\n assert response.status_code == 201\n data = response.json()\n assert data[\"email\"] == payload[\"email\"]\n```\n\n```text\nFile \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/core/user/helper.py\", line 52, in _get_users\n result = await session.exec(statement)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlmodel/ext/asyncio/session.py\", line 81, in exec\n result = await greenlet_spawn(\n ^^^^^^^^^^^^^^^^^^^^^\n ...<7 lines>...\n )\n ^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/util/_concurrency_py3k.py\", line 201, in greenlet_spawn\n result = context.throw(*sys.exc_info())\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlmodel/orm/session.py\", line 66, in exec\n results = super().execute(\n statement,\n ...<4 lines>...\n _add_event=_add_event,\n )\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/orm/session.py\", line 2365, in execute\n return self._execute_internal(\n ~~~~~~~~~~~~~~~~~~~~~~^\n statement,\n ^^^^^^^^^^\n ...<4 lines>...\n _add_event=_add_event,\n ^^^^^^^^^^^^^^^^^^^^^^\n )\n ^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/orm/session.py\", line 2241, in _execute_internal\n conn = self._connection_for_bind(bind)\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/orm/session.py\", line 2110, in _connection_for_bind\n return trans._connection_for_bind(engine, execution_options)\n ~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"<string>\", line 2, in _connection_for_bind\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/orm/state_changes.py\", line 137, in _go\n ret_value = fn(self, *arg, **kw)\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/orm/session.py\", line 1189, in _connection_for_bind\n conn = bind.connect()\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/engine/base.py\", line 3277, in connect\n return self._connection_cls(self)\n ~~~~~~~~~~~~~~~~~~~~^^^^^^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/engine/base.py\", line 143, in __init__\n self._dbapi_connection = engine.raw_connection()\n ~~~~~~~~~~~~~~~~~~~~~^^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/engine/base.py\", line 3301, in raw_connection\n return self.pool.connect()\n ~~~~~~~~~~~~~~~~~^^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/pool/base.py\", line 447, in connect\n return _ConnectionFairy._checkout(self)\n ~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/pool/base.py\", line 1363, in _checkout\n with util.safe_reraise():\n ~~~~~~~~~~~~~~~~~^^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/util/langhelpers.py\", line 224, in __exit__\n raise exc_value.with_traceback(exc_tb)\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/pool/base.py\", line 1301, in _checkout\n result = pool._dialect._do_ping_w_event(\n fairy.dbapi_connection\n )\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/engine/default.py\", line 728, in _do_ping_w_event\n return self.do_ping(dbapi_connection)\n ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py\", line 1169, in do_ping\n dbapi_connection.ping()\n ~~~~~~~~~~~~~~~~~~~~~^^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py\", line 813, in ping\n self._handle_exception(error)\n ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py\", line 794, in _handle_exception\n raise error\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py\", line 811, in ping\n _ = self.await_(self._async_ping())\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/util/_concurrency_py3k.py\", line 132, in await_only\n return current.parent.switch(awaitable) # type: ignore[no-any-return,attr-defined] # noqa: E501\n ~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/util/_concurrency_py3k.py\", line 196, in greenlet_spawn\n value = await result\n ^^^^^^^^^^^^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py\", line 820, in _async_ping\n await tr.start()\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/asyncpg/transaction.py\", line 146, in start\n await self._connection.execute(query)\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/asyncpg/connection.py\", line 349, in execute\n result = await self._protocol.query(query, timeout)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"asyncpg/protocol/protocol.pyx\", line 375, in query\nRuntimeError: Task <Task pending name='starlette.middleware.base.BaseHTTPMiddleware.__call__.<locals>.call_next.<locals>.coro' coro=<BaseHTTPMiddleware.__call__.<locals>.call_next.<locals>.coro() running at /Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/starlette/middleware/base.py:144> cb=[TaskGroup._spawn.<locals>.task_done() at /Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/anyio/_backends/_asyncio.py:794]> got Future <Future pending cb=[BaseProtocol._on_waiter_completed()]> attached to a different loop\n\nDuring handling of the above exception, another exception occurred:\n\nsession = <sqlalchemy.orm.session.AsyncSession object at 0x1100ebe00>\n\n @pytest.mark.asyncio\n async def test_signup_successful(session):\n \"\"\"Test user signup with valid data\"\"\"\n # Use ASGITransport explicitly\n transport = ASGITransport(app=app)\n async with AsyncClient(transport=transport, base_url=\"http://test\") as client:\n # Define the request payload\n payload = {\n \"first_name\": \"Test\",\n \"last_name\": \"User\",\n \"email\": \"integration_testuser@example.com\",\n \"password\": \"Strongpassword123-\"\n }\n # Perform POST request\n> response = await client.post(\"/user/signup\", json=payload)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\ntests/user/test_user_signup.py:35: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n.venv/lib/python3.13/site-packages/httpx/_client.py:1859: in post\n return await self.request(\n.venv/lib/python3.13/site-packages/httpx/_client.py:1540: in request\n return await self.send(request, auth=auth, follow_redirects=follow_redirects)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/httpx/_client.py:1629: in send\n response = await self._send_handling_auth(\n.venv/lib/python3.13/site-packages/httpx/_client.py:1657: in _send_handling_auth\n response = await self._send_handling_redirects(\n.venv/lib/python3.13/site-packages/httpx/_client.py:1694: in _send_handling_redirects\n response = await self._send_single_request(request)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/httpx/_client.py:1730: in _send_single_request\n response = await transport.handle_async_request(request)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/httpx/_transports/asgi.py:170: in handle_async_request\n await self.app(scope, receive, send)\n.venv/lib/python3.13/site-packages/fastapi/applications.py:1054: in __call__\n await super().__call__(scope, receive, send)\n.venv/lib/python3.13/site-packages/starlette/applications.py:113: in __call__\n await self.middleware_stack(scope, receive, send)\n.venv/lib/python3.13/site-packages/starlette/middleware/errors.py:186: in __call__\n raise exc\n.venv/lib/python3.13/site-packages/starlette/middleware/errors.py:164: in __call__\n await self.app(scope, receive, _send)\n.venv/lib/python3.13/site-packages/starlette/middleware/base.py:182: in __call__\n with recv_stream, send_stream, collapse_excgroups():\n ^^^^^^^^^^^^^^^^^^^^\n/opt/homebrew/Cellar/python@3.13/3.13.2/Frameworks/Python.framework/Versions/3.13/lib/python3.13/contextlib.py:162: in __exit__\n self.gen.throw(value)\n.venv/lib/python3.13/site-packages/starlette/_utils.py:83: in collapse_excgroups\n raise exc\n.venv/lib/python3.13/site-packages/starlette/middleware/base.py:184: in __call__\n response = await self.dispatch_func(request, call_next)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nmiddleware.py:27: in execution_timer\n response = await call_next(request)\n ^^^^^^^^^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/starlette/middleware/base.py:159: in call_next\n raise app_exc\n.venv/lib/python3.13/site-packages/starlette/middleware/base.py:144: in coro\n await self.app(scope, receive_or_disconnect, send_no_error)\n.venv/lib/python3.13/site-packages/starlette/middleware/trustedhost.py:36: in __call__\n await self.app(scope, receive, send)\n.venv/lib/python3.13/site-packages/starlette/middleware/cors.py:85: in __call__\n await self.app(scope, receive, send)\n.venv/lib/python3.13/site-packages/starlette/middleware/exceptions.py:63: in __call__\n await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)\n.venv/lib/python3.13/site-packages/starlette/_exception_handler.py:53: in wrapped_app\n raise exc\n.venv/lib/python3.13/site-packages/starlette/_exception_handler.py:42: in wrapped_app\n await app(scope, receive, sender)\n.venv/lib/python3.13/site-packages/starlette/routing.py:716: in __call__\n await self.middleware_stack(scope, receive, send)\n.venv/lib/python3.13/site-packages/starlette/routing.py:736: in app\n await route.handle(scope, receive, send)\n.venv/lib/python3.13/site-packages/starlette/routing.py:290: in handle\n await self.app(scope, receive, send)\n.venv/lib/python3.13/site-packages/starlette/routing.py:78: in app\n await wrap_app_handling_exceptions(app, request)(scope, receive, send)\n.venv/lib/python3.13/site-packages/starlette/_exception_handler.py:53: in wrapped_app\n raise exc\n.venv/lib/python3.13/site-packages/starlette/_exception_handler.py:42: in wrapped_app\n await app(scope, receive, sender)\n.venv/lib/python3.13/site-packages/starlette/routing.py:75: in app\n response = await f(request)\n ^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/fastapi/routing.py:302: in app\n raw_response = await run_endpoint_function(\n.venv/lib/python3.13/site-packages/fastapi/routing.py:213: in run_endpoint_function\n return await dependant.call(**values)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/slowapi/extension.py:734: in async_wrapper\n response = await func(*args, **kwargs) # type: ignore\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^\napi/user/router.py:50: in signup\n user_exists = await service.user_exists(email=email, session=session)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\ncore/user/service.py:67: in user_exists\n user = await self.get_user_by_email(email, session)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\ncore/user/service.py:39: in get_user_by_email\n return await service_helper._get_users(session=session, where_clause=User.email == email, include_roles=include_roles, include_permissions=include_permissions)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\ncore/user/helper.py:52: in _get_users\n result = await session.exec(statement)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/sqlmodel/ext/asyncio/session.py:81: in exec\n result = await greenlet_spawn(\n.venv/lib/python3.13/site-packages/sqlalchemy/util/_concurrency_py3k.py:201: in greenlet_spawn\n result = context.throw(*sys.exc_info())\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/sqlmodel/orm/session.py:66: in exec\n results = super().execute(\n.venv/lib/python3.13/site-packages/sqlalchemy/orm/session.py:2365: in execute\n return self._execute_internal(\n.venv/lib/python3.13/site-packages/sqlalchemy/orm/session.py:2241: in _execute_internal\n conn = self._connection_for_bind(bind)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/sqlalchemy/orm/session.py:2110: in _connection_for_bind\n return trans._connection_for_bind(engine, execution_options)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n<string>:2: in _connection_for_bind\n ???\n.venv/lib/python3.13/site-packages/sqlalchemy/orm/state_changes.py:137: in _go\n ret_value = fn(self, *arg, **kw)\n ^^^^^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/sqlalchemy/orm/session.py:1189: in _connection_for_bind\n conn = bind.connect()\n ^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/sqlalchemy/engine/base.py:3277: in connect\n return self._connection_cls(self)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/sqlalchemy/engine/base.py:143: in __init__\n self._dbapi_connection = engine.raw_connection()\n ^^^^^^^^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/sqlalchemy/engine/base.py:3301: in raw_connection\n return self.pool.connect()\n ^^^^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/sqlalchemy/pool/base.py:447: in connect\n return _ConnectionFairy._checkout(self)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/sqlalchemy/pool/base.py:1363: in _checkout\n with util.safe_reraise():\n ^^^^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/sqlalchemy/util/langhelpers.py:224: in __exit__\n raise exc_value.with_traceback(exc_tb)\n.venv/lib/python3.13/site-packages/sqlalchemy/pool/base.py:1301: in _checkout\n result = pool._dialect._do_ping_w_event(\n.venv/lib/python3.13/site-packages/sqlalchemy/engine/default.py:728: in _do_ping_w_event\n return self.do_ping(dbapi_connection)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py:1169: in do_ping\n dbapi_connection.ping()\n.venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py:813: in ping\n self._handle_exception(error)\n.venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py:794: in _handle_exception\n raise error\n.venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py:811: in ping\n _ = self.await_(self._async_ping())\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/sqlalchemy/util/_concurrency_py3k.py:132: in await_only\n return current.parent.switch(awaitable) # type: ignore[no-any-return,attr-defined] # noqa: E501\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/sqlalchemy/util/_concurrency_py3k.py:196: in greenlet_spawn\n value = await result\n ^^^^^^^^^^^^\n.venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py:820: in _async_ping\n await tr.start()\n.venv/lib/python3.13/site-packages/asyncpg/transaction.py:146: in start\n await self._connection.execute(query)\n.venv/lib/python3.13/site-packages/asyncpg/connection.py:349: in execute\n result = await self._protocol.query(query, timeout)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\n> ???\nE RuntimeError: Task <Task pending name='starlette.middleware.base.BaseHTTPMiddleware.__call__.<locals>.call_next.<locals>.coro' coro=<BaseHTTPMiddleware.__call__.<locals>.call_next.<locals>.coro() running at /Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/starlette/middleware/base.py:144> cb=[TaskGroup._spawn.<locals>.task_done() at /Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/anyio/_backends/_asyncio.py:794]> got Future <Future pending cb=[BaseProtocol._on_waiter_completed()]> attached to a different loop\n\nasyncpg/protocol/protocol.pyx:375: RuntimeError\n--------------------------------------------------------------------- Captured log call ----------------------------------------------------------------------\nERROR sqlalchemy.pool.impl.AsyncAdaptedQueuePool:base.py:376 Exception terminating connection <AdaptedConnection <asyncpg.connection.Connection object at 0x1101dc500>>\nTraceback (most recent call last):\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/pool/base.py\", line 372, in _close_connection\n self._dialect.do_terminate(connection)\n ~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py\", line 1136, in do_terminate\n dbapi_connection.terminate()\n ~~~~~~~~~~~~~~~~~~~~~~~~~~^^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/dialects/postgresql/asyncpg.py\", line 907, in terminate\n self.await_(asyncio.shield(self._connection.close(timeout=2)))\n ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/util/_concurrency_py3k.py\", line 132, in await_only\n return current.parent.switch(awaitable) # type: ignore[no-any-return,attr-defined] # noqa: E501\n ~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/sqlalchemy/util/_concurrency_py3k.py\", line 196, in greenlet_spawn\n value = await result\n ^^^^^^^^^^^^\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/asyncpg/connection.py\", line 1504, in close\n await self._protocol.close(timeout)\n File \"asyncpg/protocol/protocol.pyx\", line 627, in close\n File \"asyncpg/protocol/protocol.pyx\", line 660, in asyncpg.protocol.protocol.BaseProtocol._request_cancel\n File \"/Users/user/Documents/Programming/Python/Visual Studio Code/rag-sample/backend/.venv/lib/python3.13/site-packages/asyncpg/connection.py\", line 1673, in _cancel_current_command\n self._cancellations.add(self._loop.create_task(self._cancel(waiter)))\n ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^\n File \"/opt/homebrew/Cellar/python@3.13/3.13.2/Frameworks/Python.framework/Versions/3.13/lib/python3.13/asyncio/base_events.py\", line 466, in create_task\n self._check_closed()\n ~~~~~~~~~~~~~~~~~~^^\n File \"/opt/homebrew/Cellar/python@3.13/3.13.2/Frameworks/Python.framework/Versions/3.13/lib/python3.13/asyncio/base_events.py\", line 556, in _check_closed\n raise RuntimeError('Event loop is closed')\nRuntimeError: Event loop is closed\n================================================================== short test summary info ===================================================================\nFAILED tests/user/test_user_signup.py::test_signup_successful - RuntimeError: Task <Task pending name='starlette.middleware.base.BaseHTTPMiddleware.__call__.<locals>.call_next.<locals>.coro' coro=<BaseHTTPMiddleware._...\n================================================================ 1 failed, 11 passed in 1.28s ================================================================\n<sys>:0: RuntimeWarning: coroutine 'Connection._cancel' was never awaited\nError when running tests: Command 'pytest -s --color=yes' returned non-zero exit status 1.\n```\n\n```text\ndb_session\n```\n\n```text\nsubprocess\n```\n\n```text\n# backend/database/session.py\nfrom sqlmodel import SQLModel\nfrom sqlmodel.ext.asyncio.session import AsyncSession\nfrom sqlalchemy.ext.asyncio import create_async_engine\nfrom sqlalchemy.orm import sessionmaker\nfrom config import config\n\n\nengine = create_async_engine(\n config.db_uri,\n echo=config.db_echo,\n # Connection pool configuration for scalability\n # Number of connections to maintain in pool\n pool_size=config.db_pool_size,\n # Additional connections when pool is full\n max_overflow=config.db_max_overflow,\n # Validate connections before use\n pool_pre_ping=True,\n # Recycle connections after specified time\n pool_recycle=config.db_pool_recycle,\n # Timeout waiting for available connection\n pool_timeout=config.db_pool_timeout,\n # Reset connection state on return\n pool_reset_on_return='commit',\n # Performance optimizations\n # Don't log pool operations (set to True for debugging)\n echo_pool=False,\n # Connection arguments\n connect_args={\n \"ssl\": config.db_ssl\n }\n)\n\n\nasync def init_db():\n async with engine.begin() as conn:\n await conn.run_sync(SQLModel.metadata.create_all)\n\n\nasync def get_session() -> AsyncSession: # type: ignore\n Session = sessionmaker(\n bind=engine,\n class_=AsyncSession,\n expire_on_commit=False,\n autocommit=False,\n autoflush=False\n )\n async with Session() as session:\n yield session\n\n\nasync def get_test_session() -> AsyncSession: # type: ignore\n \"\"\"Get a database session specifically for tests.\n\n This version disposes the engine after each session to prevent\n asyncio loop conflicts in tests, but should NOT be used in production.\n \"\"\"\n Session = sessionmaker(\n bind=engine,\n class_=AsyncSession,\n expire_on_commit=False,\n autocommit=False,\n autoflush=False\n )\n async with Session() as session:\n yield session\n # Only dispose in test environment to prevent loop conflicts\n await engine.dispose()\n```\n\n```text\n# backend/tests/conftest.py\nimport pytest\nimport pytest_asyncio\nimport httpx\nfrom httpx._transports.asgi import ASGITransport\nfrom main import app\nfrom database.session import get_session, get_test_session\n\n\n@pytest.fixture(scope=\"session\", autouse=True)\ndef override_get_session():\n \"\"\"Override the get_session dependency for all tests.\"\"\"\n # Set the override before any tests run\n app.dependency_overrides[get_session] = get_test_session\n yield\n # Clean up after all tests\n app.dependency_overrides.clear()\n\n\n@pytest_asyncio.fixture\nasync def client():\n \"\"\"HTTP client fixture that uses test-specific database session.\"\"\"\n transport = ASGITransport(app=app)\n async with httpx.AsyncClient(transport=transport, base_url=\"http://test\") as client:\n yield client\n\n\n@pytest_asyncio.fixture\nasync def db_session():\n \"\"\"Direct database session fixture for tests that need direct DB access.\"\"\"\n async for session in get_test_session():\n yield session\n```\n\n```text\n# backend/tests/user/test_user_signup.py\nimport pytest\nimport uuid\nfrom sqlalchemy.sql import text\n\n\n@pytest.mark.asyncio\nasync def test_signup_successful(client, db_session):\n \"\"\"Test user signup with valid data\"\"\"\n # Generate unique email for each test run\n unique_email = f\"test_user_{uuid.uuid4().hex[:8]}@example.com\"\n\n # Define the request payload\n payload = {\n \"first_name\": \"Test\",\n \"last_name\": \"User\",\n \"email\": unique_email,\n \"password\": \"Strongpassword123-\"\n }\n\n # Perform POST request\n response = await client.post(\"/user/signup\", json=payload)\n\n # Assertions\n assert response.status_code == 201\n data = response.json()\n assert data[\"email\"] == payload[\"email\"]\n assert data[\"success\"]\n\n # Verify the user exists in the database\n statement = text(\n f\"SELECT email FROM users WHERE email = '{payload['email']}'\")\n result = await db_session.exec(statement)\n user = result.scalar()\n assert user is not None\n```\n\n```text\nget_session()\n```\n\n```text\ntest_db_session()\n```\n\n```text\ntest_db_session()\n```\n\n```text\nsession.py\n```\n\n```text\nconftest.py\n```\n\n```text\n@app.on_event(\"shutdown\")\nasync def on_shutdown():\n await engine.dispose()\n```\n\n```text\ntransport = ASGITransport(app=app, lifespan=\"on\")\n```\n\n```text\nfrom sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine\n\nasync_engine = create_async_engine(\n settings.postgres_dsn, # Here put your own pg url\n connect_args={},\n)\n\nif __name__ == \"__main__\":\n\n async def main():\n async_session = async_sessionmaker(async_engine, expire_on_commit=False)\n async with async_session() as session:\n async with session.begin():\n result = await session.execute(text(\"select version()\"))\n\n print(result.scalar_one_or_none())\n pass\n await async_engine.dispose()\n```\n\n========================================\n\nComments:\n- I tried adding the lifespan argument to the ASGITransport class in my tests but then I get `TypeError: ASGITransport.__init__() got an unexpected keyword argument 'lifespan'`. I only added the `engine.dispose()` method to my life_span object but this did not fix it. Also maybe you are using on older version of FastAPI but I think this is deprecated. fastapi.tiangolo.com/advanced/events/#use-case","metadata":{"transformedAt":"2026-08-18T18:32:29.151Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":17,"totalLines":1071,"estimatedTokens":13622}}624{"id":"stack-64232908","source":"stackoverflow","questionId":64232908,"title":"How to add multiple body params with fileupload in FastAPI?","tags":["python","python-3.x","postman","fastapi","uvicorn"],"text":"Title: How to add multiple body params with fileupload in FastAPI?\nTags: python, python-3.x, postman, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI have a machine learning model deployed using FastAPI, but the issue is I need the model to take two-body parameters\n\n```\napp = FastAPI()\n\nclass Inputs(BaseModel):\n industry: str = None\n file: UploadFile = File(...)\n\n@app.post(\"/predict\")\nasync def predict(inputs: Inputs):\n # params\n industry = inputs.industry\n file = inputs.file\n ### some code ###\n return predicted value\n```\n\nWhen I tried to send the input parameters I am getting an error in postman, please see the pic below,\n\nhttps://i.sstatic.net/tt8FJ.png\n\nhttps://i.sstatic.net/8IpJ5.png\n\n========================================\n\nTop Answer:\nIf you want to validate the data and get the documentation:\n\n```\nfrom fastapi import File, UploadFile, Form, Depends\n\nclass DocumentData(BaseModel):\n comment: str\n file: UploadFile = None\n\n @classmethod\n def form(\n cls,\n comment: str = Form(),\n file: UploadFile | None = File(...) if file is not None else None,\n ):\n return cls(\n comment=comment,\n file=file,\n )\n\n@router.post(\"/files/\")\nasync def get_representatives(\n data: DocumentData = Depends(DocumentData.form),\n):\n print(data.file.filename)\n```\n\n========================================\n\nCode:\n```text\napp = FastAPI()\n\nclass Inputs(BaseModel):\n industry: str = None\n file: UploadFile = File(...)\n\n@app.post(\"/predict\")\nasync def predict(inputs: Inputs):\n # params\n industry = inputs.industry\n file = inputs.file\n ### some code ###\n return predicted value\n```\n\n```text\nfrom fastapi import FastAPI, File, UploadFile, Form\n\napp = FastAPI()\n\n\n@app.post(\"/predict\")\nasync def predict(\n industry: str = Form(...),\n file: UploadFile = File(...)\n):\n # rest of your logic\n return {\"industry\": industry, \"filename\": file.filename}\n```\n\n```text\napplication/json\n```\n\n```text\nUploadFile\n```\n\n```text\nmultipart/form-data\n```\n\n```text\nUploadFile\n```\n\n```text\nfrom fastapi import File, UploadFile, Form, Depends\n\n\nclass DocumentData(BaseModel):\n comment: str\n file: UploadFile = None\n\n @classmethod\n def form(\n cls,\n comment: str = Form(),\n file: UploadFile | None = File(...) if file is not None else None,\n ):\n return cls(\n comment=comment,\n file=file,\n )\n\n@router.post(\"/files/\")\nasync def get_representatives(\n data: DocumentData = Depends(DocumentData.form),\n):\n print(data.file.filename)\n```\n\n========================================\n\nComments:\n- Does this answer your question? How to add both file and JSON body in a FastAPI POST request?\n- Now, when I pass inputs through postman, I am getting an error with industry, It is returning No, please check the screenshot, in the predict function I wrote a if condition where if industry is None return No\n- what does that `...` represent\n- It is the Ellipsis. In FastAPI, we can set a parameter/argument as ***required*** by using this `...` value @user_12","metadata":{"transformedAt":"2026-08-18T18:32:29.151Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":7,"totalLines":142,"estimatedTokens":758}}625{"id":"stack-79281001","source":"stackoverflow","questionId":79281001,"title":"FastAPI raises 422 Unprocessable Entity error when uploading File through Postman","tags":["python","file-upload","postman","fastapi","http-status-code-422"],"text":"Title: FastAPI raises 422 Unprocessable Entity error when uploading File through Postman\nTags: python, file-upload, postman, fastapi, http-status-code-422\nSource: Stack Overflow\n\nQuestion:\nI am using a `POST` request for uploading a file to a FastAPI application through Postman, and save it to my local directory. However, a `422 (Unprocessable entity)` error is raised, saying that the `file` is missing. I selected the `binary` option to upload the file, as can be seen in the image below:\n\nhttps://i.sstatic.net/f5KJoYq6.png\n\nBelow is how my FastAPI backend looks like:\n\n**main.py**\n\n```\nfrom fastapi import FastAPI\nfrom api.endpoints.vendor import router\n\napp = FastAPI(title='Vendor Acknolegment API')\napp.include_router(router, prefix='/vendor', tags=['vendor confirmation'])\n\nif __name__ == '__main__':\n import uvicorn\n uvicorn.run(\"main:app\", host=\"0.0.0.0\", port=8000, log_level='info', reload=True)\n```\n\n**vendor.py**\n\n```\nfrom fastapi import APIRouter, status, File, UploadFile\n#from lxml import etree\nimport os\n\n# file path\nUPLOAD_DIR = r\"c:\\ack\"\n\n# check if the directory exists.\nos.makedirs(UPLOAD_DIR, exist_ok=True)\n\n# creates the endpoint path\nrouter = APIRouter()\n\n# POST Ack\n@router.post(\"/ack/\", status_code=status.HTTP_201_CREATED)\nasync def upload_ack(file: UploadFile = File(...)):\n # define the complete path where the file will be saved.\n file_location = os.path.join(UPLOAD_DIR, file.filename)\n\n with open(file_location, \"wb\") as f:\n f.write(await file.read())\n\n return {\"message\": f\"The file '{file.filename}' has been successfully saved into the server.\"}\n```\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI\nfrom api.endpoints.vendor import router\n\napp = FastAPI(title='Vendor Acknolegment API')\napp.include_router(router, prefix='/vendor', tags=['vendor confirmation'])\n\nif __name__ == '__main__':\n import uvicorn\n uvicorn.run(\"main:app\", host=\"0.0.0.0\", port=8000, log_level='info', reload=True)\n```\n\n```py\nfrom fastapi import APIRouter, status, File, UploadFile\n#from lxml import etree\nimport os\n\n# file path\nUPLOAD_DIR = r\"c:\\ack\"\n\n# check if the directory exists.\nos.makedirs(UPLOAD_DIR, exist_ok=True)\n\n# creates the endpoint path\nrouter = APIRouter()\n\n# POST Ack\n@router.post(\"/ack/\", status_code=status.HTTP_201_CREATED)\nasync def upload_ack(file: UploadFile = File(...)):\n # define the complete path where the file will be saved.\n file_location = os.path.join(UPLOAD_DIR, file.filename)\n\n with open(file_location, \"wb\") as f:\n f.write(await file.read())\n\n return {\"message\": f\"The file '{file.filename}' has been successfully saved into the server.\"}\n```\n\n```text\nPOST\n```\n\n```text\n422 (Unprocessable entity)\n```\n\n```text\nfile\n```\n\n```text\nbinary\n```\n\n```py\nfrom fastapi import File, UploadFile\n\n@app.post(\"/upload\")\nasync def upload(file: UploadFile = File(...)):\n pass\n```\n\n```text\nUploadFile\n```\n\n```text\nUploadFile\n```\n\n```text\nmultipart/form-data\n```\n\n```text\nBody\n```\n\n```text\nform-data\n```\n\n```text\nUploadFile\n```\n\n```text\nfile\n```\n\n```text\nfile: UploadFile = File(...)\n```\n\n```text\nFile\n```\n\n```text\nValue\n```\n\n```text\nSelect files\n```\n\n```text\nfiles: List[UploadFile] = File(...)\n```\n\n```text\nfiles\n```\n\n```text\nbinary\n```\n\n```text\nBody\n```\n\n```text\nbinary\n```\n\n```text\nrequest.stream()\n```\n\n```text\nUploadFile\n```\n\n========================================\n\nComments:\n- Are you sure \"binary\" is the correct choice for the postman body? I think maybe it should be \"form-data\" or \"x-www-form-urlencoded\" instead.\n- Hi Chris, I appreciate your assistance, it was very helpfull to solve the problem. Thank you very much!","metadata":{"transformedAt":"2026-08-18T18:32:29.151Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":25,"totalLines":195,"estimatedTokens":907}}626{"id":"stack-59637254","source":"stackoverflow","questionId":59637254,"title":"How to do client certificate verification (mTLS) in Starlette/FastAPI","tags":["fastapi","asgi","starlette","mtls"],"text":"Title: How to do client certificate verification (mTLS) in Starlette/FastAPI\nTags: fastapi, asgi, starlette, mtls\nSource: Stack Overflow\n\nQuestion:\nI’m considering using FastAPI framework for implementing rather simple API, but it needs to support mTLS. AFAIK FastAPI is based on Starlette. Is it possible to check client certificate in Starlette?\n\n========================================\n\nComments:\n- Everything is possible, but wouldn't it be easier to handle SSL on a webserver (nginx, apache etc) and forward the meta headers to your upstream application?\n- @HeddevanderHeide Probably it would be, but in my case, client identification shall be done base on the certificate and the certificates to be registered through the same API, so nginx-base setup could be quite complex. Currently considering different options. Actually I came across with this ajg.id.au/2018/01/01/mutual-tls-with-python-flask-and-werkze‌​ug WSGI-based solution and thought similar could be done with ASGI/Starlette. Unfortunatelly my experience in the topic is not enough, so I was looking for some hints from people familiar with the topic.\n- I wish @tomchristie could help with this\n- Would you be so kind as so give an example of how this was accomplished or point me somewhere? I'm struggling to find useful documentation on this. Thanks.\n- Thanks for the answer. We ended up checking client certificates with Gunicorn (API itself is being implemented with FastAPI and running with uvicorn).","metadata":{"transformedAt":"2026-08-18T18:32:29.151Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":0,"totalLines":15,"estimatedTokens":372}}627{"id":"stack-62953477","source":"stackoverflow","questionId":62953477,"title":"fastapi could not find model defintion when run with uvicorn","tags":["python","pytorch","fastapi","uvicorn","asgi"],"text":"Title: fastapi could not find model defintion when run with uvicorn\nTags: python, pytorch, fastapi, uvicorn, asgi\nSource: Stack Overflow\n\nQuestion:\nI want to host a pytorch model in a fastapi backend. When I run the code with python it is working fine. the depickled model can use the defined class. When the same file is started with uvicorn it cannot find the class definition.\n\nSourcecode looks like this:\n\n```\nimport uvicorn\nimport json\nfrom typing import List\nfrom fastapi import Body, FastAPI\nfrom fastapi.encoders import jsonable_encoder\nimport requests\nfrom pydantic import BaseModel\n\n#from model_ii import Model_II_b\n\nimport dill as pickle\nimport torch as T\nimport sys\n\napp = FastAPI()\ncurrent_model = 'model_v2b_c2_small_ep15.pkl'\nverbose_model = False # for model v2\n\nclass Model_II_b(T.nn.Module):\n[...]\n@app.post('/function')\ndef API_call(req_json: dict = Body(...)):\n try:\n # load model...\n model = pickle.load(open('models/' + current_model, 'rb'))\n result = model.dosomething_with(req_json)\n\n return result\n\n except Exception as e:\n raise e\n return {\"error\" : str(e)}\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n```\n\nWhen I run this with `python main.py` it is working fine and I am gettings results. When I run it with `uvicorn main:app` and send a request I get the following error:\n\n```\nAttributeError: Can't get attribute 'Model_II_b' on \n```\n\nboth should be using the same python env as I use the uvicorn from within the env.\n\nI hope someone has an idea what is wrong with my setup or code.\n\nUpdate Stacktrace:\n\n```\n(model_2) root@machinelearning-01:/opt/apps# uvicorn main:app --env-file /opt/apps/env/pyvenv.cfg --reload\nINFO: Loading environment from '/opt/apps/env/pyvenv.cfg'\nINFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\nINFO: Started reloader process [164777] using statreload\nINFO: Started server process [164779]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\nINFO: 127.0.0.1:33872 - \"POST /ml/v2/predict HTTP/1.1\" 500 Internal Server Error\nERROR: Exception in ASGI application\nTraceback (most recent call last):\n File \"/opt/apps/env/lib/python3.6/site-packages/uvicorn/protocols/http/httptools_impl.py\", line 385, in run_asgi\n result = await app(self.scope, self.receive, self.send)\n File \"/opt/apps/env/lib/python3.6/site-packages/uvicorn/middleware/proxy_headers.py\", line 45, in __call__\n return await self.app(scope, receive, send)\n File \"/opt/apps/env/lib/python3.6/site-packages/fastapi/applications.py\", line 183, in __call__\n await super().__call__(scope, receive, send) # pragma: no cover\n File \"/opt/apps/env/lib/python3.6/site-packages/starlette/applications.py\", line 102, in __call__\n await self.middleware_stack(scope, receive, send)\n File \"/opt/apps/env/lib/python3.6/site-packages/starlette/middleware/errors.py\", line 181, in __call__\n raise exc from None\n File \"/opt/apps/env/lib/python3.6/site-packages/starlette/middleware/errors.py\", line 159, in __call__\n await self.app(scope, receive, _send)\n File \"/opt/apps/env/lib/python3.6/site-packages/starlette/exceptions.py\", line 82, in __call__\n raise exc from None\n File \"/opt/apps/env/lib/python3.6/site-packages/starlette/exceptions.py\", line 71, in __call__\n await self.app(scope, receive, sender)\n File \"/opt/apps/env/lib/python3.6/site-packages/starlette/routing.py\", line 550, in __call__\n await route.handle(scope, receive, send)\n File \"/opt/apps/env/lib/python3.6/site-packages/starlette/routing.py\", line 227, in handle\n await self.app(scope, receive, send)\n File \"/opt/apps/env/lib/python3.6/site-packages/starlette/routing.py\", line 41, in app\n response = await func(request)\n File \"/opt/apps/env/lib/python3.6/site-packages/fastapi/routing.py\", line 197, in app\n dependant=dependant, values=values, is_coroutine=is_coroutine\n File \"/opt/apps/env/lib/python3.6/site-packages/fastapi/routing.py\", line 149, in run_endpoint_function\n return await run_in_threadpool(dependant.call, **values)\n File \"/opt/apps/env/lib/python3.6/site-packages/starlette/concurrency.py\", line 34, in run_in_threadpool\n return await loop.run_in_executor(None, func, *args)\n File \"/usr/lib/python3.6/concurrent/futures/thread.py\", line 56, in run\n result = self.fn(*self.args, **self.kwargs)\n File \"./main.py\", line 155, in API_call\n raise e\n File \"./main.py\", line 129, in API_call\n model = pickle.load(open('models/' + current_model, 'rb'))\n File \"/opt/apps/env/lib/python3.6/site-packages/dill/_dill.py\", line 270, in load\n return Unpickler(file, ignore=ignore, **kwds).load()\n File \"/opt/apps/env/lib/python3.6/site-packages/dill/_dill.py\", line 473, in load\n obj = StockUnpickler.load(self)\n File \"/opt/apps/env/lib/python3.6/site-packages/dill/_dill.py\", line 463, in find_class\n return StockUnpickler.find_class(self, module, name)\nAttributeError: Can't get attribute 'Model_II_b' on \nenter code here\n```\n\n========================================\n\nCode:\n```text\nimport uvicorn\nimport json\nfrom typing import List\nfrom fastapi import Body, FastAPI\nfrom fastapi.encoders import jsonable_encoder\nimport requests\nfrom pydantic import BaseModel\n\n#from model_ii import Model_II_b\n\nimport dill as pickle\nimport torch as T\nimport sys\n\napp = FastAPI()\ncurrent_model = 'model_v2b_c2_small_ep15.pkl'\nverbose_model = False # for model v2\n\nclass Model_II_b(T.nn.Module):\n[...]\n@app.post('/function')\ndef API_call(req_json: dict = Body(...)):\n try:\n # load model...\n model = pickle.load(open('models/' + current_model, 'rb'))\n result = model.dosomething_with(req_json)\n\n return result\n\n except Exception as e:\n raise e\n return {\"error\" : str(e)}\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n```\n\n```text\nAttributeError: Can't get attribute 'Model_II_b' on <module '__mp_main__' from '/opt/webapp/env/bin/uvicorn'>\n```\n\n```text\n(model_2) root@machinelearning-01:/opt/apps# uvicorn main:app --env-file /opt/apps/env/pyvenv.cfg --reload\nINFO: Loading environment from '/opt/apps/env/pyvenv.cfg'\nINFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\nINFO: Started reloader process [164777] using statreload\nINFO: Started server process [164779]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\nINFO: 127.0.0.1:33872 - \"POST /ml/v2/predict HTTP/1.1\" 500 Internal Server Error\nERROR: Exception in ASGI application\nTraceback (most recent call last):\n File \"/opt/apps/env/lib/python3.6/site-packages/uvicorn/protocols/http/httptools_impl.py\", line 385, in run_asgi\n result = await app(self.scope, self.receive, self.send)\n File \"/opt/apps/env/lib/python3.6/site-packages/uvicorn/middleware/proxy_headers.py\", line 45, in __call__\n return await self.app(scope, receive, send)\n File \"/opt/apps/env/lib/python3.6/site-packages/fastapi/applications.py\", line 183, in __call__\n await super().__call__(scope, receive, send) # pragma: no cover\n File \"/opt/apps/env/lib/python3.6/site-packages/starlette/applications.py\", line 102, in __call__\n await self.middleware_stack(scope, receive, send)\n File \"/opt/apps/env/lib/python3.6/site-packages/starlette/middleware/errors.py\", line 181, in __call__\n raise exc from None\n File \"/opt/apps/env/lib/python3.6/site-packages/starlette/middleware/errors.py\", line 159, in __call__\n await self.app(scope, receive, _send)\n File \"/opt/apps/env/lib/python3.6/site-packages/starlette/exceptions.py\", line 82, in __call__\n raise exc from None\n File \"/opt/apps/env/lib/python3.6/site-packages/starlette/exceptions.py\", line 71, in __call__\n await self.app(scope, receive, sender)\n File \"/opt/apps/env/lib/python3.6/site-packages/starlette/routing.py\", line 550, in __call__\n await route.handle(scope, receive, send)\n File \"/opt/apps/env/lib/python3.6/site-packages/starlette/routing.py\", line 227, in handle\n await self.app(scope, receive, send)\n File \"/opt/apps/env/lib/python3.6/site-packages/starlette/routing.py\", line 41, in app\n response = await func(request)\n File \"/opt/apps/env/lib/python3.6/site-packages/fastapi/routing.py\", line 197, in app\n dependant=dependant, values=values, is_coroutine=is_coroutine\n File \"/opt/apps/env/lib/python3.6/site-packages/fastapi/routing.py\", line 149, in run_endpoint_function\n return await run_in_threadpool(dependant.call, **values)\n File \"/opt/apps/env/lib/python3.6/site-packages/starlette/concurrency.py\", line 34, in run_in_threadpool\n return await loop.run_in_executor(None, func, *args)\n File \"/usr/lib/python3.6/concurrent/futures/thread.py\", line 56, in run\n result = self.fn(*self.args, **self.kwargs)\n File \"./main.py\", line 155, in API_call\n raise e\n File \"./main.py\", line 129, in API_call\n model = pickle.load(open('models/' + current_model, 'rb'))\n File \"/opt/apps/env/lib/python3.6/site-packages/dill/_dill.py\", line 270, in load\n return Unpickler(file, ignore=ignore, **kwds).load()\n File \"/opt/apps/env/lib/python3.6/site-packages/dill/_dill.py\", line 473, in load\n obj = StockUnpickler.load(self)\n File \"/opt/apps/env/lib/python3.6/site-packages/dill/_dill.py\", line 463, in find_class\n return StockUnpickler.find_class(self, module, name)\nAttributeError: Can't get attribute 'Model_II_b' on <module '__mp_main__' from '/opt/apps/env/bin/uvicorn'>\nenter code here\n```\n\n```text\npython main.py\n```\n\n```text\nuvicorn main:app\n```\n\n```text\nclass CustomUnpickler(pickle.Unpickler):\n\n def find_class(self, module, name):\n if name == 'Model_II_b':\n from model_ii_b import Model_II_b\n return Model_II_b\n return super().find_class(module, name)\n\ncurrent_model = 'model_v2b_c2_small_ep24.pkl'\n\nmodel = CustomUnpickler(open('models/' + current_model, 'rb')).load()\n```\n\n========================================\n\nComments:\n- Are you using docker? Also, does the code come from two separate files? Do you mind sharing the folder and file structure?\n- @lsabi No docker involved and it is in the same file. the above code is exactly the code from the file. It runs with python directly and delivers a forecast from the model when called via the fastapi webserver. that is why i am really clueless at the moment. regarding the structure the model files are in a subfolder 'models/'.\n- I see. Then, do you mind posting a little bit more of the stack trace? It's difficult to say from just the module **mp_main**\n- @lsabi I added the stacktrace to my post. Hope you find a hint!\n- Could this be helpful? stackoverflow.com/questions/27732354/…\n- @lsabi thank you for the hint. The customer unpickler solved my problem!\n- I have the same issue but the custom unpickler route didn't solve my problem. I use `torch.load` to load my model and the model definition is right there, above that line. Is this an issue caused by uvicorn?","metadata":{"transformedAt":"2026-08-18T18:32:29.151Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":6,"totalLines":246,"estimatedTokens":2708}}628{"id":"stack-60732944","source":"stackoverflow","questionId":60732944,"title":"How to pass an array of strings to fastapi in python","tags":["python","python-3.x","fastapi"],"text":"Title: How to pass an array of strings to fastapi in python\nTags: python, python-3.x, fastapi\nSource: Stack Overflow\n\nQuestion:\nHere is the function I made:\n\n```\n@app.get(\"/shows/\")\ndef get_items(q: List[str] = Query(None)):\n '''\n Pass path to function.\n Returns folders and files.\n '''\n results = {}\n\n query_items = {\"q\": q}\n if query_items[\"q\"]:\n entry = PATH + \"/\".join(query_items[\"q\"])\n else:\n entry = PATH\n\n if os.path.isfile(entry):\n return download(entry)\n\n dirs = os.listdir(entry + \"/\")\n results[\"folders\"] = [\n val for val in dirs if os.path.isdir(entry + \"/\" + val)]\n results[\"files\"] = [val for val in dirs if\n os.path.isfile(entry + \"/\" + val)]\n results[\"path_vars\"] = query_items[\"q\"]\n\n return results\n```\n\nIdea is to pass an array of string which essentially form a path in the function to a file and I can have some array to it from an app to serve files and send this function an array of string as they traverse the folders. But.. I cant figure out how to send a list of params from something like python requests.\n\nHere is a sample function I wrote. \n\n```\ndef try_url():\n url = \"http://192.168.0.16:8000/shows/\"\n\n payload = {\n \"q\": [\"downloads\",\n \"showname\"]\n }\n headers = {}\n\n response = requests.request(\"GET\", url, headers=headers, data=payload)\n\n print(response.text.encode('utf8'))\n```\n\nApi doesnt even accept a q value. What am I missing? Is this the right way to traverse dirs? In url format, this is what a request looks like: \n\n```\nhttp://192.168.0.16:8000/shows/?q=downloads&q=foldername\n```\n\nDoesnt look right to me.\n\n========================================\n\nCode:\n```py\n@app.get(\"/shows/\")\ndef get_items(q: List[str] = Query(None)):\n '''\n Pass path to function.\n Returns folders and files.\n '''\n results = {}\n\n query_items = {\"q\": q}\n if query_items[\"q\"]:\n entry = PATH + \"/\".join(query_items[\"q\"])\n else:\n entry = PATH\n\n if os.path.isfile(entry):\n return download(entry)\n\n dirs = os.listdir(entry + \"/\")\n results[\"folders\"] = [\n val for val in dirs if os.path.isdir(entry + \"/\" + val)]\n results[\"files\"] = [val for val in dirs if\n os.path.isfile(entry + \"/\" + val)]\n results[\"path_vars\"] = query_items[\"q\"]\n\n return results\n```\n\n```py\ndef try_url():\n url = \"http://192.168.0.16:8000/shows/\"\n\n payload = {\n \"q\": [\"downloads\",\n \"showname\"]\n }\n headers = {}\n\n response = requests.request(\"GET\", url, headers=headers, data=payload)\n\n print(response.text.encode('utf8'))\n```\n\n```text\nhttp://192.168.0.16:8000/shows/?q=downloads&q=foldername\n```\n\n```text\npayload = {\n \"q\" : [\"downloads\",\n \"Brooklyn.Nine-Nine.S07E01.720p.HEVC.x265-MeGusta\"]\n}\nheaders = {\n}\n\nresponse = requests.request(\"GET\", url, headers=headers, params = payload)\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.151Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":122,"estimatedTokens":701}}629{"id":"stack-79065880","source":"stackoverflow","questionId":79065880,"title":"Pytest : Overriding production database with test database","tags":["python","pytest","fastapi"],"text":"Title: Pytest : Overriding production database with test database\nTags: python, pytest, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have started writing tests for my FastAPI/SQLAlchemy app and I would like to use a separate empty database for tests.\n\nI added an override in my conftest.py file but the function override_get_db() never gets called. As a result, tests are run on the production database and cannot get them to run on the testing database. Any idea of what is wrong in my code ?\n\nmain.py\n\n```\nfrom fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware\nfrom routes.address import router as address_router\n\napp = FastAPI()\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=[\"*\"],\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n\napp.include_router(address_router)\n```\n\ndatabase.py\n\n```\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.orm import sessionmaker\nfrom models.base import Base\nfrom config import Config\nfrom sqlalchemy.orm import Session\n\nengine = create_engine(\n Config.DATABASE_URI,\n echo=True,\n)\nSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)\n\ndef get_db():\n print(f\"Connecting to database: {Config.DATABASE_URI}\")\n Base.metadata.create_all(engine)\n db: Session = SessionLocal()\n try:\n yield db\n finally:\n db.close()\n```\n\nroutes/address.py\n\n```\nfrom fastapi import APIRouter, Depends\nfrom sqlalchemy.orm import Session\nfrom crud.address import get, get_all, create, update, delete\nfrom database.database import get_db\nfrom schemas.address import AddressCreate\n\nrouter = APIRouter()\n\n@router.get(\"/address/{address_id}\")\nasync def get_address(address_id: int, db: Session = Depends(get_db)):\n return get(db, address_id)\n\n@router.get(\"/address/\")\nasync def get_all_addresss(db: Session = Depends(get_db)):\n return get_all(db)\n\n@router.post(\"/address/\")\nasync def create_address(address: AddressCreate, db: Session = Depends(get_db)):\n return create(db, address)\n\n@router.put(\"/address/{address_id}\")\nasync def update_address(\n address_id: int, address: AddressCreate, db: Session = Depends(get_db)\n):\n return update(db, address_id, address)\n\n@router.delete(\"/address/{address_id}\")\nasync def delete_address(address_id: int, db: Session = Depends(get_db)):\n return delete(db, address_id)\n```\n\nconftest.py\n\n```\nimport pytest\nfrom fastapi.testclient import TestClient\nfrom sqlalchemy import Engine, StaticPool, create_engine\nfrom sqlalchemy.orm import sessionmaker\nfrom main import app\nfrom config import Config\nfrom src.database.database import get_db\nfrom src.models.base import Base\n\nprint(\"Loading conftest.py\")\n\nTEST_DATABASE_URI = \"sqlite:///:memory:\"\n\n@pytest.fixture(scope=\"session\")\ndef engine() -> Engine:\n print(f\"Using database URI: {Config.TEST_DATABASE_URI}\")\n return create_engine(\n Config.TEST_DATABASE_URI,\n connect_args={\"check_same_thread\": False},\n poolclass=StaticPool,\n echo=True,\n )\n\n@pytest.fixture(scope=\"function\")\ndef test_db(engine):\n Base.metadata.create_all(bind=engine)\n TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)\n db = TestingSessionLocal()\n try:\n yield db\n finally:\n db.close()\n Base.metadata.drop_all(bind=engine)\n\n@pytest.fixture(scope=\"function\")\ndef override_get_db():\n def _override_get_db():\n print(\"Using test database\")\n try:\n yield test_db\n finally:\n test_db.close()\n\n return _override_get_db\n\n@pytest.fixture(scope=\"function\")\ndef test_app(override_get_db):\n print(\"Applying dependency override\")\n app.dependency_overrides[get_db] = override_get_db\n yield app\n print(\"Clearing dependency override\")\n app.dependency_overrides.clear()\n\n@pytest.fixture(scope=\"function\")\ndef client(test_app):\n return TestClient(test_app)\n```\n\ntest_address.py\n\n```\ndef test_create_address(client):\n response = client.post(\n \"/address/\",\n json={\n \"city\": \"Springfield\",\n \"country\": \"USA\",\n },\n )\n assert response.status_code == 200\n response_data = response.json()\n assert response_data[\"city\"] == \"Springfield\"\n assert response_data[\"country\"] == \"USA\"\n assert \"id\" in response_data\n```\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware\nfrom routes.address import router as address_router\n\n\napp = FastAPI()\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=[\"*\"],\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n\napp.include_router(address_router)\n```\n\n```py\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.orm import sessionmaker\nfrom models.base import Base\nfrom config import Config\nfrom sqlalchemy.orm import Session\n\n\nengine = create_engine(\n Config.DATABASE_URI,\n echo=True,\n)\nSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)\n\n\ndef get_db():\n print(f\"Connecting to database: {Config.DATABASE_URI}\")\n Base.metadata.create_all(engine)\n db: Session = SessionLocal()\n try:\n yield db\n finally:\n db.close()\n```\n\n```py\nfrom fastapi import APIRouter, Depends\nfrom sqlalchemy.orm import Session\nfrom crud.address import get, get_all, create, update, delete\nfrom database.database import get_db\nfrom schemas.address import AddressCreate\n\nrouter = APIRouter()\n\n\n@router.get(\"/address/{address_id}\")\nasync def get_address(address_id: int, db: Session = Depends(get_db)):\n return get(db, address_id)\n\n\n@router.get(\"/address/\")\nasync def get_all_addresss(db: Session = Depends(get_db)):\n return get_all(db)\n\n\n@router.post(\"/address/\")\nasync def create_address(address: AddressCreate, db: Session = Depends(get_db)):\n return create(db, address)\n\n\n@router.put(\"/address/{address_id}\")\nasync def update_address(\n address_id: int, address: AddressCreate, db: Session = Depends(get_db)\n):\n return update(db, address_id, address)\n\n\n@router.delete(\"/address/{address_id}\")\nasync def delete_address(address_id: int, db: Session = Depends(get_db)):\n return delete(db, address_id)\n```\n\n```py\nimport pytest\nfrom fastapi.testclient import TestClient\nfrom sqlalchemy import Engine, StaticPool, create_engine\nfrom sqlalchemy.orm import sessionmaker\nfrom main import app\nfrom config import Config\nfrom src.database.database import get_db\nfrom src.models.base import Base\n\nprint(\"Loading conftest.py\")\n\nTEST_DATABASE_URI = \"sqlite:///:memory:\"\n\n\n@pytest.fixture(scope=\"session\")\ndef engine() -> Engine:\n print(f\"Using database URI: {Config.TEST_DATABASE_URI}\")\n return create_engine(\n Config.TEST_DATABASE_URI,\n connect_args={\"check_same_thread\": False},\n poolclass=StaticPool,\n echo=True,\n )\n\n\n@pytest.fixture(scope=\"function\")\ndef test_db(engine):\n Base.metadata.create_all(bind=engine)\n TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)\n db = TestingSessionLocal()\n try:\n yield db\n finally:\n db.close()\n Base.metadata.drop_all(bind=engine)\n\n\n@pytest.fixture(scope=\"function\")\ndef override_get_db():\n def _override_get_db():\n print(\"Using test database\")\n try:\n yield test_db\n finally:\n test_db.close()\n\n return _override_get_db\n\n\n@pytest.fixture(scope=\"function\")\ndef test_app(override_get_db):\n print(\"Applying dependency override\")\n app.dependency_overrides[get_db] = override_get_db\n yield app\n print(\"Clearing dependency override\")\n app.dependency_overrides.clear()\n\n\n@pytest.fixture(scope=\"function\")\ndef client(test_app):\n return TestClient(test_app)\n```\n\n```py\ndef test_create_address(client):\n response = client.post(\n \"/address/\",\n json={\n \"city\": \"Springfield\",\n \"country\": \"USA\",\n },\n )\n assert response.status_code == 200\n response_data = response.json()\n assert response_data[\"city\"] == \"Springfield\"\n assert response_data[\"country\"] == \"USA\"\n assert \"id\" in response_data\n```\n\n```py\napp.dependency_overrides[get_db] = override_get_db\n```\n\n```py\nimport pytest\nfrom fastapi.testclient import TestClient\nfrom sqlalchemy import create_engine,StaticPool\nfrom sqlalchemy.orm import sessionmaker\nfrom main import app\nfrom config import Config\nfrom models.base import Base\nfrom database.database import get_db\n\n@pytest.fixture(scope=\"function\")\ndef client(): \n engine = create_engine(\n Config.TEST_DATABASE_URI,\n connect_args={\"check_same_thread\": False},\n poolclass=StaticPool,\n echo=True\n ) \n Base.metadata.create_all(bind=engine)\n TestingSessionLocal= sessionmaker(autocommit=False,autoflush=False, bind=engine)\n \n def override_get_db():\n db =TestingSessionLocal()\n try:\n yield db\n finally:\n db.close()\n \n app.dependency_overrides[get_db]= override_get_db\n with TestClient(app) as client:\n yield client\n\n Base.metadata.drop_all(bind=engine )\n app.dependency_overrides.clear()\n```\n\n```text\nget_db\n```\n\n```text\noverride_get_db\n```\n\n```text\nclient\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.151Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":10,"totalLines":382,"estimatedTokens":2240}}630{"id":"stack-69840512","source":"stackoverflow","questionId":69840512,"title":"How is this access token stored on the client, in FastAPI's tutorial \"Simple OAuth2 with Password and Bearer\"","tags":["http","swagger","fastapi"],"text":"Title: How is this access token stored on the client, in FastAPI's tutorial \"Simple OAuth2 with Password and Bearer\"\nTags: http, swagger, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm pretty new to FastAPI and OAuth2 in general. I just worked through the tutorial \"Simple OAuth2 with Password and Bearer\" and it mostly made sense, but there was one step that felt like magic to me..\n\n**How does the access token get stored onto the client and subsequently get passed into the client's requests?**\n\nMy understanding of the flow is that it's basically\n\n- User authenticates with their username and password (these get POST'ed to the `/token` endpoint).\n\n- User's credentials are validated, and the `/token` endpoint returns the access token (`johndoe`) inside some JSON. (This is how the user receives his access token)\n\n- ???\n\n- User make a subsequent request to a private endpoint, like `GET /users/me`. The user's request includes the header `Authorization: Bearer johndoe`. (I don't think the docs mention this, but it's what I've gathered from inspecting the request in Chrome Developer Tools)\n\n- The authorization token is then used to lookup the user who made the request in (4)\n\nStep (3) is the part that I don't understand. How does the access token seemingly get stored on the client, and then passed as a header into the next request?\n\n### Demo\n\nWhen you run the code in the tutorial, you get the following swagger docs. (Note the *Authorize* button.)\n\nhttps://i.sstatic.net/PcMBe.png\n\nI click Authorize and enter my credentials. (username: `johndoe`, password: `secret`)\nhttps://i.sstatic.net/YVyxu.png\n\nAnd now I can access the `/users/me` endpoint.\n\nhttps://i.sstatic.net/OXPzb.png\n\nNotice how the header `Authorization: Bearer johndoe` was automagically included in my request.\n\nLast notes:\n\n- I've checked my cookies, session storage, and local storage and all are empty\n\n- The authorization header disappears if I refresh the page or open a new tab\n\nI suspect Swagger is doing something under the hood here, but I can't put my finger on it.\n\n========================================\n\nCode:\n```text\n/token\n```\n\n```text\n/token\n```\n\n```text\njohndoe\n```\n\n```text\nGET /users/me\n```\n\n```text\nAuthorization: Bearer johndoe\n```\n\n```text\njohndoe\n```\n\n```text\nsecret\n```\n\n```text\n/users/me\n```\n\n```text\nAuthorization: Bearer johndoe\n```\n\n```js\nexport const persistAuthorizationIfNeeded = () => ( { authSelectors, getConfigs } ) => {\n const configs = getConfigs()\n if (configs.persistAuthorization)\n {\n const authorized = authSelectors.authorized()\n localStorage.setItem(\"authorized\", JSON.stringify(authorized.toJS()))\n }\n}\n```\n\n========================================\n\nComments:\n- How you store the access token is up to you - but localstorage is probably what most people do. You could just store it in a variable inside your javascript application; there is no need to persist it if you don't want it to survive a reload (which apparently swagger doesn't)\n- @MatsLindh I think you're misunderstanding my question. I'm asking how the example above stores the access token, not *how should I* store the access token.\n- Sorry, that wasn't clear from your indexed list of how the flow worked at the start. SwaggerUI keeps the reference internally in the library, unless you enable persistence. In that case it gets persisted to localStorage. You can see the code for pesisting authentication information here: github.com/swagger-api/swagger-ui/blob/…\n- Ah, there it is. Thank you for helping me understand. If you feel like posting this as an answer, I'll accept it.","metadata":{"transformedAt":"2026-08-18T18:32:29.151Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":10,"totalLines":103,"estimatedTokens":897}}631{"id":"stack-76331894","source":"stackoverflow","questionId":76331894,"title":"Custom FastAPI middleware causes LocalProtocolError(\"Too much data for declared Content-Length\") exception","tags":["python","fastapi","middleware","starlette"],"text":"Title: Custom FastAPI middleware causes LocalProtocolError(\"Too much data for declared Content-Length\") exception\nTags: python, fastapi, middleware, starlette\nSource: Stack Overflow\n\nQuestion:\nI have a middleware implemented for FastAPI. For responses that includes some content, it works perfectly. But if a response has no body, it is causing `LocalProtocolError(\"Too much data for declared Content-Length\")` exception.\n\nTo isolate the problem, I've reduced the middleware class to this:\n\n```\nfrom starlette.middleware.base import BaseHTTPMiddleware\nfrom fastapi import FastAPI, Request\n\nclass LanguageManagerMiddleware(BaseHTTPMiddleware):\n\n def __init__(self, app: FastAPI):\n super().__init__(app)\n\n async def dispatch(self, request: Request, call_next) -> None:\n\n return await call_next(request)\n```\n\nIt basically does nothing.\n\nWhen I add the middleware, I have an exception:\n\n```\nraise LocalProtocolError(\"Too much data for declared Content-Length\")\nh11._util.LocalProtocolError: Too much data for declared Content-Length\n```\n\nWhen I disable the middleware, I have no problem.\n\nHere is the line that creates the response which triggers the exception:\n\n```\nreturn Response(status_code=HTTP_204_NO_CONTENT)\n```\n\nTo further debug the problem, I've activated a breakpoint in the `h11/_writers.py` `ContentLengthWriter` class, where the actual exception occurs.\n\nI've tried to decode the byte stream with utf-8 and cp437, but had no luch.\n\n```\nclass ContentLengthWriter(BodyWriter):\n def __init__(self, length: int) -> None:\n self._length = length\n \n def send_data(self, data: bytes, write: Writer) -> None:\n self._length -= len(data)\n if self._length I'm stopping the code at this line: `self._length -= len(data)`\n\nIf the middleware is **disabled**, `data` looks like this: `b''`\n\nIf the middleware is **enabled**, `data` looks like this: `b'\\x1f\\x8b\\x08\\x00\\xf6God\\x02\\xff'`\n\nWhat would be modifying the content of the response?\n\n========================================\n\nCode:\n```python\nfrom starlette.middleware.base import BaseHTTPMiddleware\nfrom fastapi import FastAPI, Request\n\nclass LanguageManagerMiddleware(BaseHTTPMiddleware):\n\n def __init__(self, app: FastAPI):\n super().__init__(app)\n\n\n async def dispatch(self, request: Request, call_next) -> None:\n\n return await call_next(request)\n```\n\n```text\nraise LocalProtocolError(\"Too much data for declared Content-Length\")\nh11._util.LocalProtocolError: Too much data for declared Content-Length\n```\n\n```text\nreturn Response(status_code=HTTP_204_NO_CONTENT)\n```\n\n```python\nclass ContentLengthWriter(BodyWriter):\n def __init__(self, length: int) -> None:\n self._length = length\n \n def send_data(self, data: bytes, write: Writer) -> None:\n self._length -= len(data)\n if self._length < 0:\n raise LocalProtocolError(\"Too much data for declared Content-Length\")\n write(data)\n```\n\n```text\nLocalProtocolError(\"Too much data for declared Content-Length\")\n```\n\n```text\nh11/_writers.py\n```\n\n```text\nContentLengthWriter\n```\n\n```text\nself._length -= len(data)\n```\n\n```text\ndata\n```\n\n```text\nb''\n```\n\n```text\ndata\n```\n\n```text\nb'\\x1f\\x8b\\x08\\x00\\xf6God\\x02\\xff'\n```\n\n========================================\n\nComments:\n- `\\x1f\\x8b\\x08` is a gzip header, so do you have gzip compression involved somewhere in the chain?\n- Yes actually I do, but what I can't figure out is how does the middleware effect this header.\n- Hi @MatsLindh. Thanks to you pointing out that it iz a gzip header, I've solved the problem. One question though, how did you figure out that it was a gzip header?\n- The bytes represented by `\\x1f\\x8b\\x08` is the binary header of a gzip stream, which identifies it as gzip with deflate used for compression: en.wikipedia.org/wiki/Gzip#File_format - \"a 10-byte header, containing a magic number (1f 8b), the compression method (08 for DEFLATE),\" (so `\\x1f\\x8b\\x08`)","metadata":{"transformedAt":"2026-08-18T18:32:29.151Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":12,"totalLines":137,"estimatedTokens":981}}632{"id":"stack-74797716","source":"stackoverflow","questionId":74797716,"title":"How do I get FastAPI to do SSR for Vue 3?","tags":["python","vue.js","jinja2","fastapi","server-side-rendering"],"text":"Title: How do I get FastAPI to do SSR for Vue 3?\nTags: python, vue.js, jinja2, fastapi, server-side-rendering\nSource: Stack Overflow\n\nQuestion:\nAccording to this documentation for Vue's SSR, it is possible to use node.js to render an app and return it using an express server. Is is possible to do the same with FastAPI?\n\nOr is using Jinja2 templates or SPA the only solution?\n\n### Problems:\n\n- No SPA: To help with SEO\n\n- No SSG: Too many pages will be generated. Some need to be generated dynamically.\n\n- No Jinja2/Python Templates: Node modules aren't built, bundled and served. All modules have to served from a remote package CDN.\n\nI have a feeling that maybe changing the Vue 3 delimiters and then building the project and serving the files as Jinja2 templates is the solution, but I'm not sure how it would work with Vue's routers. I know the `/dist` folder can be served on the default route and then use a catchall can be used to display files that do exist.\n\n### Possible Solution\n\n```\n@app.get(\"/\", response_class=FileResponse)\ndef read_index(request: Request):\n index = f\"{static_folder}/index.html\"\n return FileResponse(index)\n\n@app.get(\"/{catchall:path}\", response_class=FileResponse)\ndef read_index(request: Request):\n path = request.path_params[\"catchall\"]\n file = static_folder + path\n\n if os.path.exists(file):\n return FileResponse(file)\n\n index = f\"{static_folder}/index.html\"\n return FileResponse(index)\n```\n\n### Questions\n\n- If there is a way to do SSR with FastAPI and Vue 3, what is it?\n\n- If there is no direct way, how do I combine Vue's built `/dist` with Jinja2 templates to serve dynamic pages?\n\n========================================\n\nCode:\n```py\n@app.get(\"/\", response_class=FileResponse)\ndef read_index(request: Request):\n index = f\"{static_folder}/index.html\"\n return FileResponse(index)\n\n\n@app.get(\"/{catchall:path}\", response_class=FileResponse)\ndef read_index(request: Request):\n path = request.path_params[\"catchall\"]\n file = static_folder + path\n\n if os.path.exists(file):\n return FileResponse(file)\n\n index = f\"{static_folder}/index.html\"\n return FileResponse(index)\n```\n\n```text\n/dist\n```\n\n```text\n/dist\n```\n\n========================================\n\nComments:\n- I don't think you read my question. I have already looked into Nuxt and Gridsome. They use node.js and have to spin up a separate server to render pages. I'm asking if it's possible to render with FasAPI.\n- NVM, I didn't realize they had a dynamic routes section.","metadata":{"transformedAt":"2026-08-18T18:32:29.151Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":3,"totalLines":80,"estimatedTokens":624}}633{"id":"stack-64466813","source":"stackoverflow","questionId":64466813,"title":"Unable to override dependency in FastAPI/FastAPi-Utils","tags":["python","fastapi"],"text":"Title: Unable to override dependency in FastAPI/FastAPi-Utils\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nThis may be a newbie question. I am not able to override the greetings message in this simple 2 files FastAPI project. Could you please tell me what I might have done wrong? Thanks a lot for your help.\n\n**greetings_service.py**\n\n```\nfrom fastapi import Depends\nfrom fastapi_utils.cbv import cbv\nfrom fastapi_utils.inferring_router import InferringRouter\n\nrouter = InferringRouter()\n\ndef get_msg():\n return \"Original Message\"\n\n@cbv(router)\nclass GreetingsService:\n @router.get(\"/\")\n async def greet(self, msg: str = Depends(get_msg)):\n return f\"Hello from FastAPI {msg}\"\n```\n\n**main.py**\n\n```\nfrom fastapi import FastAPI\nfrom starlette.testclient import TestClient\n\nimport greetings_service\n\napp = FastAPI()\napp.include_router(greetings_service.router)\n\ndef get_new_msg():\n return \"New Message\"\n\n//Tried this, doesn't work\n#app.dependency_overrides[\"get_msg\"] = get_new_msg()\n\n//These 2 lines doesn't work too\napp.dependency_overrides[\"get_msg\"] = get_new_msg()\ngreetings_service.router.dependency_overrides_provider = app\n\nclient = TestClient(app)\n\nres = client.get(\"/\")\nprint(res.content) #\"Hello from FastAPI Original Message\" :(\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi import Depends\nfrom fastapi_utils.cbv import cbv\nfrom fastapi_utils.inferring_router import InferringRouter\n\n\nrouter = InferringRouter()\n\ndef get_msg():\n return \"Original Message\"\n\n@cbv(router)\nclass GreetingsService:\n @router.get(\"/\")\n async def greet(self, msg: str = Depends(get_msg)):\n return f\"Hello from FastAPI {msg}\"\n```\n\n```text\nfrom fastapi import FastAPI\nfrom starlette.testclient import TestClient\n\nimport greetings_service\n\napp = FastAPI()\napp.include_router(greetings_service.router)\n\ndef get_new_msg():\n return \"New Message\"\n\n//Tried this, doesn't work\n#app.dependency_overrides[\"get_msg\"] = get_new_msg()\n\n//These 2 lines doesn't work too\napp.dependency_overrides[\"get_msg\"] = get_new_msg()\ngreetings_service.router.dependency_overrides_provider = app\n\nclient = TestClient(app)\n\nres = client.get(\"/\")\nprint(res.content) #\"Hello from FastAPI Original Message\" :(\n```\n\n```text\napp.dependency_overrides[\"get_msg\"] = get_new_msg()\n```\n\n```text\nfrom fastapi import FastAPI\nfrom starlette.testclient import TestClient\n\nimport greetings_service\n\napp = FastAPI()\napp.include_router(greetings_service.router)\n\n\ndef get_new_msg():\n return \"New Message\"\n\n\napp.dependency_overrides[greetings_service.get_msg] = get_new_msg\n\nclient = TestClient(app)\nres = client.get(\"/\")\nprint(res.content)\n```\n\n========================================\n\nComments:\n- Actually, for me it worked when I changed the dependency to string","metadata":{"transformedAt":"2026-08-18T18:32:29.151Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":128,"estimatedTokens":692}}634{"id":"stack-64375466","source":"stackoverflow","questionId":64375466,"title":"Trying to read a docx file using FastAPI and python-docx library: AttributeError: 'bytes' object has no attribute 'seek' error","tags":["python","python-docx","fastapi"],"text":"Title: Trying to read a docx file using FastAPI and python-docx library: AttributeError: 'bytes' object has no attribute 'seek' error\nTags: python, python-docx, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm using FastAPI (not async) and python-docx library, trying to read a docx file.\nI'm getting an error while trying to read the docx file.\n\nMy code -\n\n```\n@app.post('/translate_docx', response_class=PlainTextResponse)\ndef translateDocx(docFile: UploadFile = File(...), fileExtension: str = Form(...)):\n \n if(fileExtension == 'docx'):\n raw_txt = readDocx(docFile.file.read())\n\n return raw_txt\n\ndef readDocx(file):\n doc = Document(file)\n txt = \"\"\n for para in doc.paragraphs:\n txt = txt + para.text\n return txt\n```\n\n**Logs:**\n\n```\nFile \"/translateProject/.venv/lib/python3.7/site-packages/docx/opc/pkgreader.py\", line 32, in from_file\n phys_reader = PhysPkgReader(pkg_file)\n File \"/translateProject/.venv/lib/python3.7/site-packages/docx/opc/phys_pkg.py\", line 101, in __init__\n self._zipf = ZipFile(pkg_file, 'r')\n \n File \"/usr/lib/python3.7/zipfile.py\", line 1258, in __init__\n self._RealGetContents()\n \n File \"/usr/lib/python3.7/zipfile.py\", line 1321, in _RealGetContents\n endrec = _EndRecData(fp)\n File \"/usr/lib/python3.7/zipfile.py\", line 259, in _EndRecData\n fpin.seek(0, 2)\n \nAttributeError: 'bytes' object has no attribute 'seek'\n```\n\nWhat is wrong in my code ? Any help would be helpful.\n\n========================================\n\nTop Answer:\nUploadFile's object has a File property that contains _file which is io.BytesIO\n\nThis worked for me. It returns all the content of the document.\n\n```\ndef endpoint(file : UploadFile = File(...)):\n\n doc = Document(file.file._file)\n```\n\n========================================\n\nCode:\n```text\n@app.post('/translate_docx', response_class=PlainTextResponse)\ndef translateDocx(docFile: UploadFile = File(...), fileExtension: str = Form(...)):\n \n if(fileExtension == 'docx'):\n raw_txt = readDocx(docFile.file.read())\n\n return raw_txt\n\n\ndef readDocx(file):\n doc = Document(file)\n txt = \"\"\n for para in doc.paragraphs:\n txt = txt + para.text\n return txt\n```\n\n```text\nFile \"/translateProject/.venv/lib/python3.7/site-packages/docx/opc/pkgreader.py\", line 32, in from_file\n phys_reader = PhysPkgReader(pkg_file)\n File \"/translateProject/.venv/lib/python3.7/site-packages/docx/opc/phys_pkg.py\", line 101, in __init__\n self._zipf = ZipFile(pkg_file, 'r')\n \n File \"/usr/lib/python3.7/zipfile.py\", line 1258, in __init__\n self._RealGetContents()\n \n File \"/usr/lib/python3.7/zipfile.py\", line 1321, in _RealGetContents\n endrec = _EndRecData(fp)\n File \"/usr/lib/python3.7/zipfile.py\", line 259, in _EndRecData\n fpin.seek(0, 2)\n \nAttributeError: 'bytes' object has no attribute 'seek'\n```\n\n```text\n.read()\n```\n\n```text\nDocument()\n```\n\n```text\nio.BytesIO\n```\n\n```text\nDocument()\n```\n\n```text\ndocx_file\n```\n\n```text\nDocument(docx_file)\n```\n\n```text\nstr\n```\n\n```text\nopen(...)\n```\n\n```text\nio.BytesIO\n```\n\n```text\nbytes\n```\n\n```text\nfile.read()\n```\n\n```text\ndef endpoint(file : UploadFile = File(...)):\n\n doc = Document(file.file._file)\n```\n\n========================================\n\nComments:\n- I tried your solution for reading a docx file using FastAPI, but I get an AttributeError: `'SpooledTemporaryFile' object has no attribute 'seekable'`. Do you have an idea why?\n- I found a solution. This problem is solved by extracting the binary of UploadFile using await and passing it to the document using bytesio (coder-question.com/cq-blog/607280). The code is `doc = Document(BytesIO(await file.read()))`","metadata":{"transformedAt":"2026-08-18T18:32:29.151Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":14,"totalLines":154,"estimatedTokens":902}}635{"id":"stack-76298462","source":"stackoverflow","questionId":76298462,"title":"How can I fix 'greenlet_spawn has not been called' error when using async_sessionmaker with FastAPI and SQLAlchemy?","tags":["asynchronous","sqlalchemy","fastapi","alembic"],"text":"Title: How can I fix 'greenlet_spawn has not been called' error when using async_sessionmaker with FastAPI and SQLAlchemy?\nTags: asynchronous, sqlalchemy, fastapi, alembic\nSource: Stack Overflow\n\nQuestion:\nFastAPI + SQLAlchemy + Alembic + async_sessionmaker not working\n\nWhen \"alembic revision --autogenerate' I get an error 'sqlalchemy.exc.MissingGreenlet: greenlet_spawn has not been called; can't call await_only() here. Was IO attempted in an unexpected place?'\n\nwhy doesn't this work?\n\ndb.py:\n\n```\nfrom sqlalchemy.ext.asyncio import AsyncSession, create_async_engine, async_sessionmaker\nfrom sqlalchemy.ext.declarative import declarative_base\n\nfrom core.config import config\n\nBase = declarative_base()\nengine = create_async_engine(config.DB_URL)\nasync_session = async_sessionmaker(engine, expire_on_commit=False, class_=AsyncSession)\n```\n\nmodel - user.py:\n\n```\nfrom sqlalchemy import String\nfrom sqlalchemy.orm import Mapped, mapped_column\n\nfrom core.db.session import Base\n\nclass User(Base):\n __tablename__ = 'users'\n\n id: Mapped[int] = mapped_column(primary_key=True)\n name: Mapped[str] = mapped_column(String)\n```\n\nenv.py\n\n```\nfrom core.config import config as app_config\nfrom logging.config import fileConfig\n\nfrom sqlalchemy import engine_from_config\nfrom sqlalchemy import pool\n\nfrom alembic import context\n\nconfig = context.config\ncontext.config.set_main_option('sqlalchemy.url', app_config.DB_URL)\n\nif config.config_file_name is not None:\n fileConfig(config.config_file_name)\n\nfrom app.user.models.user import *\nfrom core.db.session import Base\n\ntarget_metadata = Base.metadata\n...\n```\n\n========================================\n\nCode:\n```text\nfrom sqlalchemy.ext.asyncio import AsyncSession, create_async_engine, async_sessionmaker\nfrom sqlalchemy.ext.declarative import declarative_base\n\nfrom core.config import config\n\nBase = declarative_base()\nengine = create_async_engine(config.DB_URL)\nasync_session = async_sessionmaker(engine, expire_on_commit=False, class_=AsyncSession)\n```\n\n```text\nfrom sqlalchemy import String\nfrom sqlalchemy.orm import Mapped, mapped_column\n\nfrom core.db.session import Base\n\n\nclass User(Base):\n __tablename__ = 'users'\n\n id: Mapped[int] = mapped_column(primary_key=True)\n name: Mapped[str] = mapped_column(String)\n```\n\n```text\nfrom core.config import config as app_config\nfrom logging.config import fileConfig\n\nfrom sqlalchemy import engine_from_config\nfrom sqlalchemy import pool\n\nfrom alembic import context\n\n\nconfig = context.config\ncontext.config.set_main_option('sqlalchemy.url', app_config.DB_URL)\n\nif config.config_file_name is not None:\n fileConfig(config.config_file_name)\n\nfrom app.user.models.user import *\nfrom core.db.session import Base\n\ntarget_metadata = Base.metadata\n...\n```\n\n```text\nalembic init -t async migrations\n```\n\n========================================\n\nComments:\n- when does this error occur? can you show the ORM query you create?\n- I'm sorry, I didn't specify. This error occurs when I call \"alembic revision --autogenerate\".\n- can you show `DB_URL`?\n- DB_URL: str = 'postgresql+asyncpg://postgres:postgres@localhost/postgres'\n- I have only run_migrations_online and run_migrations_offline\n- You probably need this as you are using an async connection string alembic.sqlalchemy.org/en/latest/…, or you can just use a sync driver (only for migration)","metadata":{"transformedAt":"2026-08-18T18:32:29.152Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":127,"estimatedTokens":836}}636{"id":"stack-67966415","source":"stackoverflow","questionId":67966415,"title":"How to persist a connection pool for asyncpg and utilise it in Databases wrapper?","tags":["python","fastapi","asyncpg"],"text":"Title: How to persist a connection pool for asyncpg and utilise it in Databases wrapper?\nTags: python, fastapi, asyncpg\nSource: Stack Overflow\n\nQuestion:\nAs per FastApi documentation, I'm using the Databases wrapper and Sqlalchemy Core to do async operations on the postgres database.\n\nI have come across an issue where the connection gets closed in the middle of operation. As it turns out it is an issue with `asyncpg` and can be resolved by using a pool.\n\nHowever I'm not using asyncpg directly, but use the Database wrapper as it was recommended by FastAPI. How can I create a pool like this:\n\n```\nawait asyncpg.create_pool(database=\"dbname\", \n user=\"username\", \n password=\"dbpw\",\n max_inactive_connection_lifetime=3)\n```\n\nand utilise it within the databases wrapper?\n\n```\nimport databases\nfrom sqlalchemy import MetaData\n\ndb = databases.Database(settings.SQLALCHEMY_DATABASE_URI)\nmetadata = MetaData(schema='main')\n```\n\n========================================\n\nCode:\n```text\nawait asyncpg.create_pool(database=\"dbname\", \n user=\"username\", \n password=\"dbpw\",\n max_inactive_connection_lifetime=3)\n```\n\n```text\nimport databases\nfrom sqlalchemy import MetaData\n\ndb = databases.Database(settings.SQLALCHEMY_DATABASE_URI)\nmetadata = MetaData(schema='main')\n```\n\n```text\nasyncpg\n```\n\n```text\ndb = databases.Database(settings.SQLALCHEMY_DATABASE_URI, max_inactive_connection_lifetime=3)\n```\n\n```text\nasyncpg.create_pool\n```\n\n```text\nasyncpg.create_pool\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.152Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":6,"totalLines":61,"estimatedTokens":366}}637{"id":"stack-78817297","source":"stackoverflow","questionId":78817297,"title":"How to Control Recursion Depth in Pydantic’s model_dump Serialization?","tags":["python","fastapi","pydantic"],"text":"Title: How to Control Recursion Depth in Pydantic’s model_dump Serialization?\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI have the following classes:\n\n```\nclass Info:\n data: str\n \n\nclass Data:\n info: Info\n```\n\nWhen I call `model_dump` in Data class, pydantic will serialize the classe recursively as described here\n\nThis is the primary way of converting a model to a dictionary. Sub-models will be recursively converted to dictionaries.\n\nIs there any way to stop the recursive part or specify how deep we want the serialisation go?\n\nMy desired output would be something like the following:\n\n```\n{\n \"info\": Info\n}\n```\n\ninstead of\n\n```\n{\n \"info\": {\n \"data\":\"some data\"\n }\n}\n```\n\nI tried to search in documentation how to change this behaviour but didn't find anything.\n\n========================================\n\nCode:\n```py\nclass Info:\n data: str\n \n\nclass Data:\n info: Info\n```\n\n```py\n{\n \"info\": Info\n}\n```\n\n```py\n{\n \"info\": {\n \"data\":\"some data\"\n }\n}\n```\n\n```text\nmodel_dump\n```\n\n```py\n>>> data = Data(info=Info(data='test'))\n>>> dict(data)\n{'info': Info(data='test')}\n```\n\n========================================\n\nComments:\n- It works perfectly! I knew there was a way of doing this, thank you!","metadata":{"transformedAt":"2026-08-18T18:32:29.152Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":82,"estimatedTokens":307}}638{"id":"stack-75950294","source":"stackoverflow","questionId":75950294,"title":"How to handle exceptions for all the sub apps in FastAPI","tags":["python","exception","fastapi"],"text":"Title: How to handle exceptions for all the sub apps in FastAPI\nTags: python, exception, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have a FastAPI project containing multiple sub apps (The sample includes just one sub app).\n\n```\nmain_app = FastAPI()\n\nclass CustomException(Exception): \n def __init__(self, message: str, status_code: int, name: str = \"Exception\"):\n Exception.__init__(self)\n self.name = name\n self.status_code = status_code\n self.message = message\n\n@main_app.exception_handler(CustomException)\nasync def custom_exception_handler(exception: CustomException) -> JSONResponse:\n return JSONResponse(\n status_code=exception.status_code, content={\"error\": exception.message}\n )\nmain_app.mount(\"/subapp\", subapp1)\n```\n\nI've handled the exceptions in main app, but not in `subapp1`. Now if I use the `CustomException` in `subapp1`:\n\n```\nraise CustomException(\n status_code=status.HTTP_404_NOT_FOUND,\n message=f\"{self.model.__name__} not found\",\n)\n```\n\nI get this error:\n\nRuntimeError: Caught handled exception, but response already started.\n\nIt seems like when raising `CustomException` in a sub app, it won't be handled by the main app exception handler. So how can I handle the exceptions from all the sub app using the main app exception handler?\n\n========================================\n\nCode:\n```text\nmain_app = FastAPI()\n\nclass CustomException(Exception): \n def __init__(self, message: str, status_code: int, name: str = \"Exception\"):\n Exception.__init__(self)\n self.name = name\n self.status_code = status_code\n self.message = message\n\n@main_app.exception_handler(CustomException)\nasync def custom_exception_handler(exception: CustomException) -> JSONResponse:\n return JSONResponse(\n status_code=exception.status_code, content={\"error\": exception.message}\n )\nmain_app.mount(\"/subapp\", subapp1)\n```\n\n```text\nraise CustomException(\n status_code=status.HTTP_404_NOT_FOUND,\n message=f\"{self.model.__name__} not found\",\n)\n```\n\n```text\nsubapp1\n```\n\n```text\nCustomException\n```\n\n```text\nsubapp1\n```\n\n```text\nCustomException\n```\n\n```text\ndef exception_handler(app: FastAPI):\n @app.exception_handler(CustomException)\n async def custom_exception_handler(request: Request, exception: CustomException) -> JSONResponse:\n return JSONResponse(\n status_code=exception.status_code, content={\"error\": exception.message}\n )\n```\n\n```text\nexception_handler(app)\nexception_handler(subapp1)\n```\n\n========================================\n\nComments:\n- Future readers might find this answer helpful as well.","metadata":{"transformedAt":"2026-08-18T18:32:29.152Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":8,"totalLines":102,"estimatedTokens":645}}639{"id":"stack-66416550","source":"stackoverflow","questionId":66416550,"title":"starlette CORS exclude endpoint","tags":["python","middleware","fastapi","starlette"],"text":"Title: starlette CORS exclude endpoint\nTags: python, middleware, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nI'm using Fastapi (CORSMiddleware) with following configuration\n\n```\napp.add_middleware(\n CORSMiddleware,\n allow_origins=['frontend.domain.com'],\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n```\n\nIs there anyway to exclude some endpoints or add to endpoint a signal to pass CORS check and allow request that not comes from `frontend.domain.com`?\n\nThank you.\n\n========================================\n\nCode:\n```text\napp.add_middleware(\n CORSMiddleware,\n allow_origins=['frontend.domain.com'],\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n```\n\n```text\nfrontend.domain.com\n```\n\n```text\napp.add_middleware(\n CORSMiddleware,\n allow_origins=[\"allowed origins\"],\n allow_credentials=True,\n allow_path_regex=\"(.*)\\\\/endpoint\\\\/[a-f0-9]{32}$\",\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n )\n```\n\n```text\nimport functools\nimport re\nimport typing\n\nfrom starlette.datastructures import Headers, MutableHeaders\nfrom starlette.responses import PlainTextResponse, Response\nfrom starlette.types import ASGIApp, Message, Receive, Scope, Send\n\nALL_METHODS = (\"DELETE\", \"GET\", \"OPTIONS\", \"PATCH\", \"POST\", \"PUT\")\nSAFELISTED_HEADERS = {\"Accept\", \"Accept-Language\", \"Content-Language\", \"Content-Type\"}\n\n\nclass CORSMiddleware:\n \"\"\"\n This middleware added allow_path_regex option to open some endpoints to the world\n \"\"\"\n\n def __init__(\n self,\n app: ASGIApp,\n allow_origins: typing.Sequence[str] = (),\n allow_methods: typing.Sequence[str] = (\"GET\",),\n allow_headers: typing.Sequence[str] = (),\n allow_credentials: bool = False,\n allow_origin_regex: typing.Optional[str] = None,\n allow_path_regex: typing.Optional[str] = None,\n expose_headers: typing.Sequence[str] = (),\n max_age: int = 600,\n ) -> None:\n\n if \"*\" in allow_methods:\n allow_methods = ALL_METHODS\n\n compiled_allow_origin_regex = None\n if allow_origin_regex is not None:\n compiled_allow_origin_regex = re.compile(allow_origin_regex)\n\n compiled_allow_path_regex = None\n if allow_path_regex:\n compiled_allow_path_regex = re.compile(allow_path_regex)\n\n simple_headers = {}\n if \"*\" in allow_origins:\n simple_headers[\"Access-Control-Allow-Origin\"] = \"*\"\n if allow_credentials:\n simple_headers[\"Access-Control-Allow-Credentials\"] = \"true\"\n if expose_headers:\n simple_headers[\"Access-Control-Expose-Headers\"] = \", \".join(expose_headers)\n\n preflight_headers = {}\n if \"*\" in allow_origins:\n preflight_headers[\"Access-Control-Allow-Origin\"] = \"*\"\n else:\n preflight_headers[\"Vary\"] = \"Origin\"\n preflight_headers.update(\n {\n \"Access-Control-Allow-Methods\": \", \".join(allow_methods),\n \"Access-Control-Max-Age\": str(max_age),\n }\n )\n allow_headers = sorted(SAFELISTED_HEADERS | set(allow_headers))\n if allow_headers and \"*\" not in allow_headers:\n preflight_headers[\"Access-Control-Allow-Headers\"] = \", \".join(allow_headers)\n if allow_credentials:\n preflight_headers[\"Access-Control-Allow-Credentials\"] = \"true\"\n\n self.app = app\n self.allow_origins = allow_origins\n self.allow_methods = allow_methods\n self.allow_headers = [h.lower() for h in allow_headers]\n self.allow_all_origins = \"*\" in allow_origins\n self.allow_all_headers = \"*\" in allow_headers\n self.allow_origin_regex = compiled_allow_origin_regex\n self.allow_path_regex = compiled_allow_path_regex\n self.simple_headers = simple_headers\n self.preflight_headers = preflight_headers\n\n async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:\n if scope[\"type\"] != \"http\": # pragma: no cover\n await self.app(scope, receive, send)\n return\n\n method = scope[\"method\"]\n headers = Headers(scope=scope)\n origin = headers.get(\"origin\")\n path = scope[\"path\"]\n\n if origin is None:\n await self.app(scope, receive, send)\n return\n\n if method == \"OPTIONS\" and \"access-control-request-method\" in headers:\n response = self.preflight_response(request_headers=headers, path=path)\n await response(scope, receive, send)\n return\n\n await self.simple_response(scope, receive, send, request_headers=headers, path=path)\n\n def is_allowed_origin(self, origin: str, path: str) -> bool:\n if self.allow_all_origins:\n return True\n\n if self.allow_origin_regex is not None and self.allow_origin_regex.fullmatch(origin):\n return True\n\n if self.allow_path_regex is not None and self.allow_path_regex.fullmatch(path):\n return True\n\n return origin in self.allow_origins\n\n def preflight_response(self, request_headers: Headers, path: str) -> Response:\n requested_origin = request_headers[\"origin\"]\n requested_method = request_headers[\"access-control-request-method\"]\n requested_headers = request_headers.get(\"access-control-request-headers\")\n\n headers = dict(self.preflight_headers)\n failures = []\n\n if self.is_allowed_origin(origin=requested_origin, path=path):\n if not self.allow_all_origins:\n # If self.allow_all_origins is True, then the \"Access-Control-Allow-Origin\"\n # header is already set to \"*\".\n # If we only allow specific origins, then we have to mirror back\n # the Origin header in the response.\n headers[\"Access-Control-Allow-Origin\"] = requested_origin\n else:\n failures.append(\"origin\")\n\n if requested_method not in self.allow_methods:\n failures.append(\"method\")\n\n # If we allow all headers, then we have to mirror back any requested\n # headers in the response.\n if self.allow_all_headers and requested_headers is not None:\n headers[\"Access-Control-Allow-Headers\"] = requested_headers\n elif requested_headers is not None:\n for header in [h.lower() for h in requested_headers.split(\",\")]:\n if header.strip() not in self.allow_headers:\n failures.append(\"headers\")\n\n # We don't strictly need to use 400 responses here, since its up to\n # the browser to enforce the CORS policy, but its more informative\n # if we do.\n if failures:\n failure_text = \"Disallowed CORS \" + \", \".join(failures)\n return PlainTextResponse(failure_text, status_code=400, headers=headers)\n\n return PlainTextResponse(\"OK\", status_code=200, headers=headers)\n\n async def simple_response(\n self, scope: Scope, receive: Receive, send: Send, request_headers: Headers, path: str\n ) -> None:\n send = functools.partial(self.send, send=send, request_headers=request_headers, path=path)\n await self.app(scope, receive, send)\n\n async def send(self, message: Message, send: Send, request_headers: Headers, path: str) -> None:\n if message[\"type\"] != \"http.response.start\":\n await send(message)\n return\n\n message.setdefault(\"headers\", [])\n headers = MutableHeaders(scope=message)\n headers.update(self.simple_headers)\n origin = request_headers[\"Origin\"]\n has_cookie = \"cookie\" in request_headers\n\n # If request includes any cookie headers, then we must respond\n # with the specific origin instead of '*'.\n if self.allow_all_origins and has_cookie:\n headers[\"Access-Control-Allow-Origin\"] = origin\n\n # If we only allow specific origins, then we have to mirror back\n # the Origin header in the response.\n elif not self.allow_all_origins and self.is_allowed_origin(origin=origin, path=path):\n headers[\"Access-Control-Allow-Origin\"] = origin\n headers.add_vary_header(\"Origin\")\n await send(message)\n```\n\n```text\nCORSMiddleware\n```\n\n========================================\n\nComments:\n- I don't think there is the concept of resource specific CORS. Thus, you might need to write your own middleware. Should be straightforward: fastapi.tiangolo.com/tutorial/middleware/?h=middle\n- I was thinking the same, just want to make sure there's a problem before I implement my solution. Anyway thank you @momo\n- I modified original `CORSMiddleware`, it's work for me.","metadata":{"transformedAt":"2026-08-18T18:32:29.152Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":239,"estimatedTokens":2183}}640{"id":"stack-75036773","source":"stackoverflow","questionId":75036773,"title":"pydantic.error_wrappers.ValidationError: FastAPI","tags":["python","fastapi","pydantic"],"text":"Title: pydantic.error_wrappers.ValidationError: FastAPI\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI'm making a crud in fastapiI have a user model and I created another one called showuser to only show some specific fields in the query, but when I execute the request I get an error.\n\nI just want my request to show the fields I have in showuser.\n\nmy schemas\n\n```\nfrom pydantic import BaseModel\nfrom typing import Optional\nfrom datetime import datetime\n\n# Create a User model\n# Create a class for the user\n\nclass User(BaseModel):\n username: str\n password: str\n name: str\n lastname: str\n address: Optional[str] = None\n telephone: Optional[int] = None\n email: str\n creation_user: datetime = datetime.now()\n\n# Create UserId model\n# Create a class for the UserId\nclass UserId(BaseModel):\n id: int\n\n# Create a ShowUser model\n# Create a class for the ShowUser\nclass ShowUser(BaseModel):\n username: str\n name: str\n lastname: str\n email: str\n class Config():\n orm_mode = True\n```\n\nand this is the code from user where I implement the api\n\n```\n@router.get('/{user_id}', response_model=ShowUser)\ndef get_user(user_id: int, db: Session = Depends(get_db)):\n user = db.query(models.User).filter(models.User.id == user_id).first()\n if not user:\n return {\"Error\": \"User not found\"}\n return {\"User\": user}\n```\n\nTerminal Message\n\n```\npydantic.error_wrappers.ValidationError: 4 validation errors for ShowUser \nresponse -> username\n field required (type-value_error.missing)\nresponse -> name\n field required (type=value_error.missing) \nresponse -> lastname\n field required (type=value_error.missing) \nresponse -> email\n field required (type=value_error.missing)\n```\n\n========================================\n\nCode:\n```text\nfrom pydantic import BaseModel\nfrom typing import Optional\nfrom datetime import datetime\n\n# Create a User model\n# Create a class for the user\n\n\nclass User(BaseModel):\n username: str\n password: str\n name: str\n lastname: str\n address: Optional[str] = None\n telephone: Optional[int] = None\n email: str\n creation_user: datetime = datetime.now()\n\n# Create UserId model\n# Create a class for the UserId\nclass UserId(BaseModel):\n id: int\n\n# Create a ShowUser model\n# Create a class for the ShowUser\nclass ShowUser(BaseModel):\n username: str\n name: str\n lastname: str\n email: str\n class Config():\n orm_mode = True\n```\n\n```text\n@router.get('/{user_id}', response_model=ShowUser)\ndef get_user(user_id: int, db: Session = Depends(get_db)):\n user = db.query(models.User).filter(models.User.id == user_id).first()\n if not user:\n return {\"Error\": \"User not found\"}\n return {\"User\": user}\n```\n\n```text\npydantic.error_wrappers.ValidationError: 4 validation errors for ShowUser \nresponse -> username\n field required (type-value_error.missing)\nresponse -> name\n field required (type=value_error.missing) \nresponse -> lastname\n field required (type=value_error.missing) \nresponse -> email\n field required (type=value_error.missing)\n```\n\n```py\n@router.get('/{user_id}', response_model=ShowUser)\ndef get_user(user_id: int, db: Session = Depends(get_db)):\n user = db.query(models.User).filter(models.User.id == user_id).first()\n if not user:\n return {\"Error\": \"User not found\"}\n return user\n```\n\n```py\n@router.get('/{user_id}', response_model=ShowUser)\ndef get_user(user_id: int, db: Session = Depends(get_db)):\n user = db.query(models.User).filter(models.User.id == user_id).first()\n if not user:\n raise HTTPException(\n status_code=int(HTTPStatus.NOT_FOUND),\n detail=f\"No user exists with user.id = {user_id}\"\n )\n return user\n```\n\n```text\nget_user\n```\n\n```text\n{\"User\": user}\n```\n\n```text\nuser\n```\n\n```text\nUser\n```\n\n```text\nuser_id\n```\n\n```text\n{\"Error\": \"User not found\"}\n```\n\n```text\nHTTPException\n```\n\n```text\n404\n```\n\n========================================\n\nComments:\n- Why `return {\"User\": user}`? You explicitly set `response_model=ShowUser`. Just return the `user`.","metadata":{"transformedAt":"2026-08-18T18:32:29.152Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":13,"totalLines":186,"estimatedTokens":1003}}641{"id":"stack-76266682","source":"stackoverflow","questionId":76266682,"title":"How to raise custom exceptions in a FastAPI middleware?","tags":["python","python-3.x","fastapi","middleware","starlette"],"text":"Title: How to raise custom exceptions in a FastAPI middleware?\nTags: python, python-3.x, fastapi, middleware, starlette\nSource: Stack Overflow\n\nQuestion:\nI have a simple FastAPI setup with a custom middleware class inherited from **`BaseHTTPMiddleware`**. Inside this middleware class, I need to terminate the execution flow under certain conditions. So, I created a custom exception class named `CustomError` and ***`raised`*** the exception.\n\n```\nfrom fastapi import FastAPI, Request\nfrom starlette.middleware.base import (\n BaseHTTPMiddleware,\n RequestResponseEndpoint\n)\nfrom starlette.responses import JSONResponse, Response\n\napp = FastAPI()\n\nclass CustomError(Exception):\n def __init__(self, message):\n self.message = message\n\n def __str__(self):\n return self.message\n\nclass CustomMiddleware(BaseHTTPMiddleware):\n def execute_custom_logic(self, request: Request):\n raise CustomError(\"This is from `CustomMiddleware`\")\n\n async def dispatch(\n self,\n request: Request,\n call_next: RequestResponseEndpoint,\n ) -> Response:\n self.execute_custom_logic(request=request)\n response = await call_next(request)\n return response\n\napp.add_middleware(CustomMiddleware)\n\n@app.exception_handler(CustomError)\nasync def custom_exception_handler(request: Request, exc: CustomError):\n return JSONResponse(\n status_code=418,\n content={\"message\": exc.message},\n )\n\n@app.get(path=\"/\")\ndef root_api():\n return {\"message\": \"Hello World\"}\n```\n\nUnfortunately, FastAPI couldn't handle the **`CustomError`** even though I added **`custom_exception_handler(...)`** handler.\n\n### Questions\n\n- What is the *FastAPI* way to handle such situations?\n\n- Why is my code not working?\n\n**Versions**\n\n- FastAPI - 0.95.2\n\n- Python - 3.8.13\n\n========================================\n\nTop Answer:\nFastAPI's custom exception handlers are not handling middleware level exceptions. Although this is not stated anywhere in the docs, there is part about HTTPException, which says that you can raise `HTTPException` *if you are inside a utility function that you are calling inside of your path operation function*. `HTTPException` has default exception handler that acts absolutely the same as custom exception handlers do.\n\nYou can either handle your error (with `try/except`) within the same middleware or have separate middleware e.g. `ExceptionHandlerMiddleware` (but you'll have to keep the order of middleware chain correct).\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI, Request\nfrom starlette.middleware.base import (\n BaseHTTPMiddleware,\n RequestResponseEndpoint\n)\nfrom starlette.responses import JSONResponse, Response\n\napp = FastAPI()\n\n\nclass CustomError(Exception):\n def __init__(self, message):\n self.message = message\n\n def __str__(self):\n return self.message\n\n\nclass CustomMiddleware(BaseHTTPMiddleware):\n def execute_custom_logic(self, request: Request):\n raise CustomError(\"This is from `CustomMiddleware`\")\n\n async def dispatch(\n self,\n request: Request,\n call_next: RequestResponseEndpoint,\n ) -> Response:\n self.execute_custom_logic(request=request)\n response = await call_next(request)\n return response\n\n\napp.add_middleware(CustomMiddleware)\n\n\n@app.exception_handler(CustomError)\nasync def custom_exception_handler(request: Request, exc: CustomError):\n return JSONResponse(\n status_code=418,\n content={\"message\": exc.message},\n )\n\n\n@app.get(path=\"/\")\ndef root_api():\n return {\"message\": \"Hello World\"}\n```\n\n```text\nBaseHTTPMiddleware\n```\n\n```text\nCustomError\n```\n\n```text\nraised\n```\n\n```text\nCustomError\n```\n\n```text\ncustom_exception_handler(...)\n```\n\n```py\nfrom fastapi import FastAPI, Request, HTTPException\nfrom fastapi.responses import JSONResponse\n\napp = FastAPI()\n\n\nclass CustomException(Exception):\n def __init__(self, msg: str):\n self.msg = msg\n \n \ndef exec_custom_logic(request: Request):\n raise CustomException(msg='Something went wrong') \n\n \n@app.middleware(\"http\")\nasync def custom_middleware(request: Request, call_next):\n try: \n exec_custom_logic(request)\n except CustomException as e:\n return JSONResponse(status_code=500, content={'message': e.msg})\n \n return await call_next(request)\n \n \n@app.get('/')\nasync def main(request: Request):\n return 'OK'\n```\n\n```py\nfrom fastapi import FastAPI, APIRouter, Response, Request, HTTPException\nfrom fastapi.routing import APIRoute\nfrom typing import Callable\n\n\ndef exec_custom_logic(request: Request):\n raise HTTPException(status_code=500, detail='Something went wrong')\n \n\nclass CustomAPIRoute(APIRoute):\n def get_route_handler(self) -> Callable:\n original_route_handler = super().get_route_handler()\n\n async def custom_route_handler(request: Request) -> Response:\n exec_custom_logic(request)\n return await original_route_handler(request)\n \n return custom_route_handler\n\n\napp = FastAPI()\nrouter = APIRouter(route_class=CustomAPIRoute)\n\n\n@router.get('/')\nasync def main(request: Request):\n return 'OK'\n \napp.include_router(router)\n```\n\n```text\nHTTPException\n```\n\n```text\nException in ASGI application\n```\n\n```text\nInternal Server Error\n```\n\n```text\nmiddleware\n```\n\n```text\ntry/except\n```\n\n```text\ntry/except\n```\n\n```text\nJSONResponse\n```\n\n```text\nResponse\n```\n\n```text\nmsg\n```\n\n```text\nCustomException\n```\n\n```text\nstatus_code\n```\n\n```text\n500\n```\n\n```text\nAPIRouter\n```\n\n```text\nAPIRoute\n```\n\n```text\nAPIRouter\n```\n\n```text\nAPIRoute\n```\n\n```text\ntry/except\n```\n\n```text\nHTTPException\n```\n\n```text\nHTTPException\n```\n\n```text\ntry/except\n```\n\n```text\nAPIRouter\n```\n\n```text\n@router.get()\n```\n\n```text\napp\n```\n\n```text\n@app.get()\n```\n\n```text\nHTTPException\n```\n\n```text\nHTTPException\n```\n\n```text\ntry/except\n```\n\n```text\nExceptionHandlerMiddleware\n```\n\n========================================\n\nComments:\n- Can you show an example?","metadata":{"transformedAt":"2026-08-18T18:32:29.152Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":36,"totalLines":323,"estimatedTokens":1486}}642{"id":"stack-73603297","source":"stackoverflow","questionId":73603297,"title":"ModuleNotFoundError while importing python files as modules in Azure App Services","tags":["python","azure","import","azure-web-app-service","fastapi"],"text":"Title: ModuleNotFoundError while importing python files as modules in Azure App Services\nTags: python, azure, import, azure-web-app-service, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am getting started with Azure App Services.\n\nI followed this tutorial and was able to get the example **main.py** app running.\n\nThe modules (`fastapi`, `uvicorn`, etc...) specified in the **requirements.txt** are all installed and imported correctly.\n\nHowever, when trying to import Python files located in the *same* directory as the **main.py**, deployment is still successful, but I am getting an application error when trying to browse by webpage: https://i.sstatic.net/r8Bk1.png\n\nFor instance, I created a file called **settings.py**, containing:\n\n```\nMY_TITLE = \"My FastAPI prototype\"\n```\n\nIn this main.py, I simply modified:\n\n```\napp = FastAPI()\n```\n\nWith:\n\n```\nimport settings\napp = FastAPI(title=f\"{settings.MY_TITLE}\")\n```\n\nBut this failed!\nPlease note that when I specify `MY_TITLE` in the main script, I am able to update the page's title correctly.\n\n**How can I import Python files from my `main.py` script on Azure App Services?**\n\n========================================\n\nTop Answer:\nAdding an answer from our comment discussion\n\nI would suggest you enable diagnostic logging on your webapp and Try to look the application logs under **(Diagnose and solve problems--> Availability and performance)** to identify what is causing this issue.\n\nAs you have mentioned in your comments that you are seeing Module not found error. In general, **ModuleNotFoundError:** means that Python could not find one or more of your modules when the application started. This most often occurs if you deploy your virtual environment with your code. Virtual environments are not portable, so a virtual environment should not be deployed with your application code.\n\nYou can refer to this documentation for further troubleshooting on Module not found error\n\n========================================\n\nCode:\n```text\nMY_TITLE = \"My FastAPI prototype\"\n```\n\n```text\napp = FastAPI()\n```\n\n```text\nimport settings\napp = FastAPI(title=f\"{settings.MY_TITLE}\")\n```\n\n```text\nfastapi\n```\n\n```text\nuvicorn\n```\n\n```text\nMY_TITLE\n```\n\n```text\nmain.py\n```\n\n```text\nfrom .settings import MY_TITLE\n```\n\n```text\nfrom .settings import *\n```\n\n```text\nModuleNotFoundError\n```\n\n```text\nsys.modules\n```\n\n```text\nsys.path\n```\n\n```text\nModuleNotFoundError\n```\n\n```text\nPATH\n```\n\n```text\nsettings\n```\n\n```text\n*\n```\n\n```text\n*\n```\n\n```text\nfrom <module> import *\n```\n\n```text\nsys.path\n```\n\n========================================\n\nComments:\n- I would suggest you enable diagnostic logging on your webapp and Try to look the application logs under (Diagnose and solve problems--> Availability and performance) to identify what is causing this issue.\n- Thanks for your suggestion @VenkateshDodda-MSFT. I enabled the logs in my Linux App Service under App Services Logs, where I specified the quota and retention period. I then downloaded the zipped logs using https://.scm.azurewebsites.net/api/logs/docker/zip‌​.\n- This was very useful @VenkateshDodda-MSFT. Checking the logs confirms that I am running into a **ModuleNotFoundError**.\n- Please have a look at this answer and this answer.\n- Thanks for sharing these answers, @Chris. The relative imports (**Option 1** in stackoverflow.com/a/71080756/6440589) did the trick for me: `from .settings import *`. If you end up writing a full-fledged answer, I will gladly accept it.\n- Thanks for your detailed answer, @VenkateshDodda-MSFT. I am aware that **ModuleNotFoundError** means that Python cannot find some of the modules/packages. However, in this specific case, I do not think that this error is related to the virtual environment being deployed with the application code, as I did not upload any virtual environment file onto the Azure DevOps repo that I use as my Source.\n- Apparently when using Azure App Services, one may set the path by typing `set PATH` in the cmd console. I will stick to relative imports for now, though!","metadata":{"transformedAt":"2026-08-18T18:32:29.152Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":19,"totalLines":138,"estimatedTokens":1012}}643{"id":"stack-77989609","source":"stackoverflow","questionId":77989609,"title":"How to enable CORS in FastAPI for local HTML file loaded via a file:/// URL?","tags":["javascript","python","cors","fastapi","local"],"text":"Title: How to enable CORS in FastAPI for local HTML file loaded via a file:/// URL?\nTags: javascript, python, cors, fastapi, local\nSource: Stack Overflow\n\nQuestion:\nI am trying to enable CORS in FastAPI on my localhost with credentials enabled. According to the docs we must explicitly set allow_origins in this case:\n\n```\nfrom fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware, Response\n\napp = FastAPI()\napp.add_middleware(\n CORSMiddleware, allow_origins=['http://localhost:8000'],\n allow_credentials=True, allow_methods=['*'], allow_headers=['*'])\n\n@app.get('/')\ndef main():\n return Response('OK', status_code=200)\n```\n\nHowever, when making a request it does fail with\n\nCORS Missing Allow Origin [Cross-source (cross-origin) request blocked: The same origin policy disallows reading the remote resource at `http://[::1]:8000/create_session/none`. (Reason: CORS header `'Access-Control-Allow-Origin'` is missing). Status code: 200.]\n\n```\nconst response = await fetch('http://localhost:8000/', {credentials: \"include\"});\n```\n\nThe client is Firefox with a local file (file://.../main.html) opened.\n\nI already tried all solutions from How can I enable CORS in FastAPI?. What's wrong?\n\nEdit:\nMy question is not a duplicate of How to access FastAPI backend from a different machine/IP on the same local network?, because the server and the client are on the same (local)host. Nevertheless I tried setting the suggested *--host 0.0.0.0* and the error remains the same.\n\nAlso it's not a duplicate of FastAPI is not returning cookies to React frontend, because it suggests setting the CORS origin in the same way as the official docs, which does not work as I described above.\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware, Response\n\napp = FastAPI()\napp.add_middleware(\n CORSMiddleware, allow_origins=['http://localhost:8000'],\n allow_credentials=True, allow_methods=['*'], allow_headers=['*'])\n\n@app.get('/')\ndef main():\n return Response('OK', status_code=200)\n```\n\n```js\nconst response = await fetch('http://localhost:8000/', {credentials: \"include\"});\n```\n\n```text\nhttp://[::1]:8000/create_session/none\n```\n\n```text\n'Access-Control-Allow-Origin'\n```\n\n```text\nfile:///C:/...index.html\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware\n\napp = FastAPI()\n\norigins = ['null'] # NOT recommended - see details below\n \napp.add_middleware(\n CORSMiddleware,\n allow_origins=origins,\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n\n@app.get('/')\ndef main():\n return 'ok'\n```\n\n```html\n<!DOCTYPE html>\n<html>\n <body>\n <h1>Send JS request</h1>\n <button onclick=\"getData()\">Click me</button>\n <script>\n function getData() {\n fetch('http://localhost:8000/')\n .then(resp => resp.json()) // or resp.text(), etc.\n .then(data => {\n console.log(data);\n })\n .catch(error => {\n console.error(error);\n });\n }\n </script>\n </body>\n</html>\n```\n\n```text\nfile:///\n```\n\n```text\nCORS error\n```\n\n```text\nMissingAllowOriginHeader\n```\n\n```text\nStatus\n```\n\n```text\nNetwork\n```\n\n```text\nAccess-Control-Allow-Origin\n```\n\n```text\n'http://localhost:8000/'\n```\n\n```text\n'null'\n```\n\n```text\n'Access-Control-Allow-Origin'\n```\n\n```text\nhttp://localhost:8000/\n```\n\n```text\nhttp://localhost:8000/\n```\n\n```text\n'Access-Control-Allow-Origin'\n```\n\n```text\nfile:///\n```\n\n```text\nnull\n```\n\n```text\nhttp://localhost:8000\n```\n\n```text\nnull\n```\n\n```text\norigins\n```\n\n```text\nAccess-Control-Allow-Origin: null\n```\n\n```text\nnull\n```\n\n```text\nAccess-Control-Allow-Origin: \"null\"\n```\n\n```text\ndata:\n```\n\n```text\nfile:\n```\n\n```text\n\"null\"\n```\n\n```text\nAccess-Control-Allow-Origin: \"null\"\n```\n\n```text\n\"null\"\n```\n\n```text\n\"null\"\n```\n\n```text\nnull\n```\n\n```text\nindex.html\n```\n\n```text\nHTMLResponse\n```\n\n```text\nJinja2Templates\n```\n\n```text\nnull\n```\n\n```text\norigins\n```\n\n========================================\n\nComments:\n- Hey, according to the doc, your setup is correct. let me try fastapi.tiangolo.com/tutorial/cors\n- If you're opening a `file://` url there won't be any solutions to getting CORS to work - you'll have to load it from `localhost:8000` and not `file://`: developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors/…\n- I found the issue. It's a simple mistake. However, could you please tell me which FastAPI and Python version are you using?\n- If the server runs on `http://localhost:8000`, why are you listing this as an allowed origin in your CORS configuration? Read more about CORS: developer.mozilla.org/en-US/docs/Web/HTTP/CORS\n- @AsMdHabibullah This is Python 3.10.12 with FastAPI 0.105.0\n- @jub0bs Because the client runs on the same machine as the server.\n- @Speech-To-Text.Cloud But surely they don't run on the same Web origin (perhaps `http://localhost` but with a different port); otherwise, CORS simply wouldn't be an issue.\n- @Speech-To-Text.Cloud In fact, you write: *The client is Firefox with a local file (file://.../main.html) opened.* In that case, the client's origin is `null`, which is different from `http://localhost:8000`.\n- Hey, have a look \"Response\" does not exist in this FastAPI version. Even though it exists, but you didn't import it. do fix it first\n- from typing import Union from fastapi import FastAPI, status, Response from fastapi.middleware.cors import CORSMiddleware\n- # Create a FastAPI instance app = FastAPI() # Define origins for CORS (Cross-Origin Resource Sharing) origins = [ \"localhost\", \"localhost:8080\", ] # Add CORS middleware to the FastAPI app app.add_middleware( CORSMiddleware, allow_origins=origins, allow_credentials=True, allow_methods=[\"*\"], allow_headers=[\"*\"], )\n- # Define a root endpoint @app.get(\"/\") def main(): # Option 1: Return a plain Response object with a custom status code # return Response({\"message\": \"OK\"},) # Option 2: Return a plain Response object with a string body and a custom status code return Response(\"OK\", status_code=200) # OR # Define a root endpoint a different way @app.get(\"/\", status_code=200) def main(): # Return a dictionary as a JSON response with a message return {\"message\": \"OK\"}\n- @Speech-To-Text.Cloud My intent was **not** to encourage you to allow the `null` origin in your CORS configuration, though. Doing so is insecure. For more details, see portswigger.net/research/…\n- Thank you for your answer. Actually I *did* mention the CORS error in my question, you may want to have a closer look. Also thanks for mentioning the security implications: I use it for testing only and not in production. I may switch to outputting the code as HTMLResponse in the future.\n- I meant the complete error message shown in the console (as it would help future readers), not just the `CORS Missing Allow Origin` part. Regardless, glad that the answer helped you understand the security implications of it as well. Indeed, despite the fact that it is used for testing purposes only, I would still **strongly suggest** switching to an `HTMLResponse` or `Jinja2Templates.TemplateResponse` instead - the linked answers provided above would help you on how to do that.","metadata":{"transformedAt":"2026-08-18T18:32:29.152Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":39,"totalLines":260,"estimatedTokens":1832}}644{"id":"stack-75644811","source":"stackoverflow","questionId":75644811,"title":"Use @validator in pydantic model for date comparison","tags":["python-3.x","fastapi","pydantic"],"text":"Title: Use @validator in pydantic model for date comparison\nTags: python-3.x, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI'm using Pydantic and i'm trying to compare than date_from is inferior to date_to (both of these fields are optional) in my Pydantic BaseModel and return a 422 error if it's not the case.\n\nI tried to use to method presented in the StackOverflow question: pydantic Multi-field comparison - but I didn't get any success with it, I alway got a 200 succeed.\n\nHere's my model:\n\n```\nclass MyModel(BaseModel):\n startFrom: Optional[date] = Field(\n ...,\n description='XXX',\n example='2023-03-15',\n )\n\n StartTo: Optional[date] = Field(\n ...,\n description='XXX',\n example='2023-03-31',\n )\n\n otherData: str = Field(\n ...,\n description='XXX',\n example='XX',\n )\n\n @validator('startFrom')\n def date_order(cls, startFrom, values, **kwargs):\n if ('StartTo' not in values):\n return startFrom\n\n if (startFrom > values['StartTo']):\n raise ValueError('startFrom must be inferior to StartTo.')\n return startFrom\n```\n\nI don't really know what I do wrong.\n\nThanks to everyone for you help :)\n\n========================================\n\nTop Answer:\n### Use Pydantic to validate incoming start and end dates\n\nI had a lot of Pydantic models which often included `*_start_date` and `*_end_date` fields, e.g. `plan_start_date` and `plan_end_date`. It's certainly going to be convenient and reliable to ensure Pydantic normalises these when the request is received.\n\n### What kind of validation to perform\n\nThe following code ensures that the \"start\" or \"from\" dates are always less than or equal to the \"end\" or \"to\" dates. Having certainty about that in your service greatly simplifies date arithmetic and avoids repeated validation.\n\nIf the client is sending the dates the wrong way round, I think it's worth returning HTTP `400` for that. It's a mistake and there could be other mistakes in the request. But if you want to tolerate that as well, and swap them around, the following method still provides one **DRY** location to do that.\n\n### Derive a new base class from BaseModel\n\nThe following approach sub-classes `pydantic.BaseModel`. This new base class automatically detects \"from\" and \"to\" date fields (by naming convention) and applies the validation, returning HTTP `400` on failure.\n\nTo use, just derive the models that need it from the new base class instead of `pydantic.BaseModel`, and it all happens.\n\n### The new base class\n\nI'm not going to the inconsistent and unconventional field naming in the question, because I don't want to perpetuate bad practice, but I'll try to use similar **PEP-8** equivalent names. The date field detection relies on using particular field name suffixes.\n\nI have a range of custom exceptions for identifying HTTP Server Error (for instance) and others. To simplify I haven't included them here. It may help to refer to **Pydantic's conventions about handling errors**.\n\n```\nimport pydantic\n\nclass DurationModel(pydantic.BaseModel):\n \"\"\"Apply *_from_date and *_to_date field order validation.\"\"\"\n\n @pydantic.model_validator(mode=\"after\")\n def validate_date_order(self) -> \"DurationModel\":\n \"\"\"Validate *_from_date does not come after *_to_date.\"\"\"\n\n from_date_field = [field for field in self.__dict__ if field.endswith(\"from_date\")]\n to_date_field = [field for field in self.__dict__ if field.endswith(\"to_date\")]\n\n if not (from_date_field and to_date_field): # Raise HTTP 500\n msg = self.__class__.__name__ + \" does not contain 'from' and 'to' date fields\" # pragma: nocover\n raise AttributeError(msg) # pragma: nocover: not expecting unit tests for these lines\n\n if (getattr(self, from_date_field[0]) or datetime.date.min) > (getattr(self, to_date_field[0]) or datetime.date.max):\n msg = self.__class__.__name__ + \" 'from' date after 'to' date\"\n raise ValueError(msg) # This should be HTTP 400\n\n return self\n```\n\n`DurationModel` uses a **Pydantic \"after\" mode model validator**. This is a validator that runs after the standard Pydantic validators, so the date fields are already `datetime.date` instances. It's also a whole model validator, so it has access to all the fields in the model, not just one of them.\n\n### How to use\n\nI will **\"late model\" Python** and **Pydantic 2** approaches. Thus I will not be importing `typing.Optional`.\n\nThe `DurationModel` supports \"optional\" `datetime.date` fields for which I use `datetime.date | None`. I've provided a default of `None` and the validator should handle `None` dates. Of course it can be more strict if needed.\n\nAgain, I can't bring myself to perpetuate the \"start from\" and \"start to\" naming as this is inherently contradictory, but I've done my best to fit in. I've skipped the `Field` descriptions to keep it brief. Those are easily added back in if needed.\n\n```\nimport datetime\n\nclass MyModel(DurationModel):\n from_date: datetime.date | None = None\n to_date: datetime.date | None = None\n other: str\n\nmy_data = {\"from_date\": \"2023-01-01\", \"to_date\": \"2023-12-31\", \"other\": \"stuff\"}\nmy_model = MyModel(**my_data)\n```\n\n### Some examples\n\nHere are some quick usage examples of how it works.\n\n```\nmy_data = {\"from_date\": \"2023-01-01\", \"to_date\": \"2023-12-31\", \"other\": \"stuff\"}\nmy_model = MyModel(**my_data)\n# from_date=datetime.date(2023, 1, 1)\n# to_date=datetime.date(2023, 12, 31)\n# other='stuff'\n```\n\n```\nmy_data = {\"from_date\": \"2024-01-01\", \"to_date\": \"2023-12-31\", \"other\": \"stuff\"}\nmy_model = MyModel(**my_data)\n# Value error, MyModel 'from' date after 'to' date\n# [type=value_error, input_value={'from_date': '2024-01-01...}, input_type=dict]\n```\n\n```\nmy_data = {\"from_date\": \"2024-01-01\", \"to_date\": \"\", \"other\": \"stuff\"}\nmy_model = MyModel(**my_data)\n# Input should be a valid date or datetime, input is too short\n# [type=date_from_datetime_parsing, input_value='', input_type=str]\n```\n\n```\nmy_data = {\"from_date\": \"2024-01-01\", \"to_date\": None, \"other\": \"stuff\"}\nmy_model = MyModel(**my_data)\n# from_date=datetime.date(2024, 1, 1)\n# to_date=None\n# other='stuff'\n```\n\n### Simple application to question\n\nAnd at the risk of making this answer too long, I've applied the principles above to implement an answer that fits just the simple use case where a generic base class is overkill.\n\n```\nimport pydantic\nimport datetime\n\nclass MyModel(pydantic.BaseModel):\n from_date: datetime.date | None = None\n to_date: datetime.date | None = None\n other_data: str\n\n @pydantic.model_validator(mode=\"after\")\n def validate_date_order(self) -> \"MyModel\":\n if (self.from_date or datetime.date.min) > (self.to_date or datetime.date.max):\n msg = \"MyModel 'from_date' comes after 'to_date'\"\n raise ValueError(msg)\n return self\n\nmy_data = {\"from_date\": \"2023-01-01\", \"to_date\": \"2023-12-31\", \"other_data\": \"stuff\"}\nmy_model = MyModel(**my_data)\nprint(my_model)\n\nmy_data = {\"from_date\": \"2024-01-01\", \"to_date\": None, \"other_data\": \"stuff\"}\nmy_model = MyModel(**my_data)\nprint(my_model)\n\nmy_data = {\"from_date\": \"2024-01-01\", \"to_date\": \"2023-12-31\", \"other_data\": \"stuff\"}\nmy_model = MyModel(**my_data)\n# Value error, MyModel 'from_date' comes after 'to_date'\n```\n\n========================================\n\nCode:\n```text\nclass MyModel(BaseModel):\n startFrom: Optional[date] = Field(\n ...,\n description='XXX',\n example='2023-03-15',\n )\n\n StartTo: Optional[date] = Field(\n ...,\n description='XXX',\n example='2023-03-31',\n )\n\n otherData: str = Field(\n ...,\n description='XXX',\n example='XX',\n )\n\n @validator('startFrom')\n def date_order(cls, startFrom, values, **kwargs):\n if ('StartTo' not in values):\n return startFrom\n\n if (startFrom > values['StartTo']):\n raise ValueError('startFrom must be inferior to StartTo.')\n return startFrom\n```\n\n```text\nstartFrom\n```\n\n```text\nstartTo\n```\n\n```py\nimport pydantic\n\n\nclass DurationModel(pydantic.BaseModel):\n \"\"\"Apply *_from_date and *_to_date field order validation.\"\"\"\n\n @pydantic.model_validator(mode=\"after\")\n def validate_date_order(self) -> \"DurationModel\":\n \"\"\"Validate *_from_date does not come after *_to_date.\"\"\"\n\n from_date_field = [field for field in self.__dict__ if field.endswith(\"from_date\")]\n to_date_field = [field for field in self.__dict__ if field.endswith(\"to_date\")]\n\n if not (from_date_field and to_date_field): # Raise HTTP 500\n msg = self.__class__.__name__ + \" does not contain 'from' and 'to' date fields\" # pragma: nocover\n raise AttributeError(msg) # pragma: nocover: not expecting unit tests for these lines\n\n if (getattr(self, from_date_field[0]) or datetime.date.min) > (getattr(self, to_date_field[0]) or datetime.date.max):\n msg = self.__class__.__name__ + \" 'from' date after 'to' date\"\n raise ValueError(msg) # This should be HTTP 400\n\n return self\n```\n\n```py\nimport datetime\n\nclass MyModel(DurationModel):\n from_date: datetime.date | None = None\n to_date: datetime.date | None = None\n other: str\n\nmy_data = {\"from_date\": \"2023-01-01\", \"to_date\": \"2023-12-31\", \"other\": \"stuff\"}\nmy_model = MyModel(**my_data)\n```\n\n```py\nmy_data = {\"from_date\": \"2023-01-01\", \"to_date\": \"2023-12-31\", \"other\": \"stuff\"}\nmy_model = MyModel(**my_data)\n# from_date=datetime.date(2023, 1, 1)\n# to_date=datetime.date(2023, 12, 31)\n# other='stuff'\n```\n\n```py\nmy_data = {\"from_date\": \"2024-01-01\", \"to_date\": \"2023-12-31\", \"other\": \"stuff\"}\nmy_model = MyModel(**my_data)\n# Value error, MyModel 'from' date after 'to' date\n# [type=value_error, input_value={'from_date': '2024-01-01...}, input_type=dict]\n```\n\n```py\nmy_data = {\"from_date\": \"2024-01-01\", \"to_date\": \"\", \"other\": \"stuff\"}\nmy_model = MyModel(**my_data)\n# Input should be a valid date or datetime, input is too short\n# [type=date_from_datetime_parsing, input_value='', input_type=str]\n```\n\n```py\nmy_data = {\"from_date\": \"2024-01-01\", \"to_date\": None, \"other\": \"stuff\"}\nmy_model = MyModel(**my_data)\n# from_date=datetime.date(2024, 1, 1)\n# to_date=None\n# other='stuff'\n```\n\n```py\nimport pydantic\nimport datetime\n\n\nclass MyModel(pydantic.BaseModel):\n from_date: datetime.date | None = None\n to_date: datetime.date | None = None\n other_data: str\n\n @pydantic.model_validator(mode=\"after\")\n def validate_date_order(self) -> \"MyModel\":\n if (self.from_date or datetime.date.min) > (self.to_date or datetime.date.max):\n msg = \"MyModel 'from_date' comes after 'to_date'\"\n raise ValueError(msg)\n return self\n\nmy_data = {\"from_date\": \"2023-01-01\", \"to_date\": \"2023-12-31\", \"other_data\": \"stuff\"}\nmy_model = MyModel(**my_data)\nprint(my_model)\n\nmy_data = {\"from_date\": \"2024-01-01\", \"to_date\": None, \"other_data\": \"stuff\"}\nmy_model = MyModel(**my_data)\nprint(my_model)\n\nmy_data = {\"from_date\": \"2024-01-01\", \"to_date\": \"2023-12-31\", \"other_data\": \"stuff\"}\nmy_model = MyModel(**my_data)\n# Value error, MyModel 'from_date' comes after 'to_date'\n```\n\n```text\n*_start_date\n```\n\n```text\n*_end_date\n```\n\n```text\nplan_start_date\n```\n\n```text\nplan_end_date\n```\n\n```text\n400\n```\n\n```text\npydantic.BaseModel\n```\n\n```text\n400\n```\n\n```text\npydantic.BaseModel\n```\n\n```text\nDurationModel\n```\n\n```text\ndatetime.date\n```\n\n```text\ntyping.Optional\n```\n\n```text\nDurationModel\n```\n\n```text\ndatetime.date\n```\n\n```text\ndatetime.date | None\n```\n\n```text\nNone\n```\n\n```text\nNone\n```\n\n```text\nField\n```\n\n========================================\n\nComments:\n- Please have a look at this answer and this answer\n- Or you can use a `root_validator`, which will get all the field values instead of depending on the order of the fields in the class.\n- but the error will no have the location `startFrom` or `startTo`","metadata":{"transformedAt":"2026-08-18T18:32:29.152Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":27,"totalLines":395,"estimatedTokens":2917}}645{"id":"stack-75867644","source":"stackoverflow","questionId":75867644,"title":"How to return Pydantic object with a specific http response code in FastAPI?","tags":["python","http","fastapi","pydantic"],"text":"Title: How to return Pydantic object with a specific http response code in FastAPI?\nTags: python, http, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI have an endpoint which returns a Pydantic object. However, I would like a response code other than 200 in some cases (for example if my service in not healthy). How can I achieve that with FastAPI?\n\n```\nclass ServiceHealth(BaseModel):\n http_ok: bool = True\n database_ok: bool = False\n\n def is_everything_ok(self) -> bool:\n return self.http_ok and self.database_ok\n\n@router.get(\"/health\")\ndef health() -> ServiceHealth:\n return ServiceHealth()\n```\n\n========================================\n\nTop Answer:\nJust specify the `status_code` keyword-argument, when initializing your `APIRoute`. It is passed along by all route decorators as far as I know, including `APIRouter.get`.\n\n```\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\n\nclass ServiceHealth(BaseModel):\n http_ok: bool = True\n database_ok: bool = False\n\napi = FastAPI()\n\n@api.get(\"/health\", status_code=299)\ndef health() -> ServiceHealth:\n return ServiceHealth()\n```\n\nPerforming a `GET` on that route still returns the expected JSON `{\"http_ok\":true,\"database_ok\":false}` with the HTTP status code 299 (just to demonstrate, not a \"real\" status code).\n\nThere are a few restrictions that FastAPI places on that argument. Notably, you cannot return a body, if you define a `304` status code or any informational (`1xx`) status code.\n\n========================================\n\nCode:\n```text\nclass ServiceHealth(BaseModel):\n http_ok: bool = True\n database_ok: bool = False\n\n def is_everything_ok(self) -> bool:\n return self.http_ok and self.database_ok\n\n@router.get(\"/health\")\ndef health() -> ServiceHealth:\n return ServiceHealth()\n```\n\n```text\n@router.get(\"/health\")\nasync def health() -> ServiceHealth:\n response = ServiceHealth()\n \n if response.is_everything_ok():\n return JSONResponse(content=response.dict(), status_code=200)\n return JSONResponse(content=response.dict(), status_code=500)\n```\n\n```text\nfrom fastapi import status\n\n@router.get(\"/health\")\nasync def health() -> ServiceHealth:\n response = ServiceHealth()\n \n if response.is_everything_ok():\n return JSONResponse(content=response.dict(), status_code=status.HTTP_200_OK)\n return JSONResponse(content=response.dict(), status_code=status.HTTP_500_INTERNAL_SERVER_ERROR)\n```\n\n```text\nJSONResponse\n```\n\n```text\nstatus\n```\n\n```text\nstatus.py\n```\n\n```text\nfastapi\n```\n\n```py\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\n\n\nclass ServiceHealth(BaseModel):\n http_ok: bool = True\n database_ok: bool = False\n\n\napi = FastAPI()\n\n\n@api.get(\"/health\", status_code=299)\ndef health() -> ServiceHealth:\n return ServiceHealth()\n```\n\n```text\nstatus_code\n```\n\n```text\nAPIRoute\n```\n\n```text\nAPIRouter.get\n```\n\n```text\nGET\n```\n\n```text\n{\"http_ok\":true,\"database_ok\":false}\n```\n\n```text\n304\n```\n\n```text\n1xx\n```\n\n========================================\n\nComments:\n- Did you check fastapi.tiangolo.com/tutorial/handling-errors/… ? Something like: raise HTTPException(status_code=404, detail=\"Service not found.\") can be useful for your intent ?\n- Hum, I still would like to return a Pydantic object.\n- Future readers might want to have a look at the last section of this answer\n- When returning a `JSONResponse(content=some_dict, ....)`, please make sure that all objects in the dictionary that is being returned are JSON-serializable objects, otherwise a `TypeError: Object of type ... is not JSON serializable` would be raised. In that case, one should either convert such objects to a type that is JSON-serializable (e.g., `str`) on their own, or use FastAPI's `jsonable_encoder()` function that would automatically do this (see this answer for more details and examples).\n- @Chris Yes, that is correct! Another thing you can do when you have a Pydantic object (with `datetimes` for example, that are not JSON serializable) in order to make sure they will be serialized correctly is to use the following combo: `json.load(pydantic_instance.json())`\n- I wouldn't do that. Please have a look at the linked answer above, as well as this answer (see Option 1) to find out the reason as to why. Simply, you are converting the model instance into JSON, then the JSON string/object into dictionary, and finally, once again into JSON, since `JSONResponse` will use `json.dumps()` behind the scenes (as explained in the links provided above).\n- You could instead use: `return Response(model.json(), media_type='application/json', status=status.HTTP_200_OK)`. See the linked answers above for more details.\n- as a side note,`status` is now `status_code` for 0.104.1\n- Kind of a bummer that FastAPI doesn't provide a way to do this that is actually type safe. Seems like `JSONResponse` (and maybe `HTTPException`) could be generic so that the return value could be more like `-> JSONResponse[MyResponseBodyType]` and would handle serialization of that instance automatically just like it does when you return a Pydantic model directly.","metadata":{"transformedAt":"2026-08-18T18:32:29.152Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":15,"totalLines":156,"estimatedTokens":1270}}646{"id":"stack-58835803","source":"stackoverflow","questionId":58835803,"title":"dependency_overrides does not override dependency","tags":["python","python-3.x","dependency-injection","fastapi"],"text":"Title: dependency_overrides does not override dependency\nTags: python, python-3.x, dependency-injection, fastapi\nSource: Stack Overflow\n\nQuestion:\nThe following FastApi test should use my `get_mock_db` function instead of the `get_db` function, but it dosen't. Currently the test fails because it uses the real Database.\n\n```\ndef get_mock_db():\n example_todo = Todo(title=\"test title\", done=True, id=1)\n\n class MockDb:\n def query(self, _model):\n mock = Mock()\n mock.get = lambda _param: example_todo\n\n def all(self):\n return [example_todo]\n\n def add(self):\n pass\n\n def commit(self):\n pass\n\n def refresh(self, todo: CreateTodo):\n return Todo(title=todo.title, done=todo.done, id=1)\n\n return MockDb()\n\nclient = TestClient(app)\n\napp.dependency_overrides[get_db] = get_mock_db\n\ndef test_get_all():\n response = client.get(\"/api/v1/todo\")\n assert response.status_code == 200\n assert response.json() == [\n {\n \"title\": \"test title\",\n \"done\": True,\n \"id\": 1,\n }\n ]\n```\n\n========================================\n\nCode:\n```py\ndef get_mock_db():\n example_todo = Todo(title=\"test title\", done=True, id=1)\n\n class MockDb:\n def query(self, _model):\n mock = Mock()\n mock.get = lambda _param: example_todo\n\n def all(self):\n return [example_todo]\n\n def add(self):\n pass\n\n def commit(self):\n pass\n\n def refresh(self, todo: CreateTodo):\n return Todo(title=todo.title, done=todo.done, id=1)\n\n return MockDb()\n\n\nclient = TestClient(app)\n\n\napp.dependency_overrides[get_db] = get_mock_db\n\n\ndef test_get_all():\n response = client.get(\"/api/v1/todo\")\n assert response.status_code == 200\n assert response.json() == [\n {\n \"title\": \"test title\",\n \"done\": True,\n \"id\": 1,\n }\n ]\n```\n\n```text\nget_mock_db\n```\n\n```text\nget_db\n```\n\n```py\ndef get_db():\n return {'db': RealDb()}\n\ndef home(commons: dict= Depends(get_db))\n commons['db'].doStuff()\n \napp.dependency_overrides[get_db] = lambda: {'db': MockDb()}\n```\n\n```py\ndef get_db(connection_string):\n return {'db': RealDb(connection_string)}\n\ndef home(commons: dict= Depends(get_db(os.environ['connectionString']))\n commons['db'].doStuff()\n\n# Does not work \napp.dependency_overrides[get_db] = lambda: {'db': MockDb()}\n```\n\n```text\nDepends\n```\n\n```text\nget_db\n```\n\n```text\ndependency_overrides[get_db]\n```\n\n```text\nDepends\n```\n\n========================================\n\nComments:\n- You may have to add the code where get_db is used in order to see what is happening.","metadata":{"transformedAt":"2026-08-18T18:32:29.152Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":140,"estimatedTokens":639}}647{"id":"stack-65940177","source":"stackoverflow","questionId":65940177,"title":"Asyncio: Fastapi with aio-pika, consumer ignores Await","tags":["websocket","async-await","rabbitmq","python-asyncio","fastapi"],"text":"Title: Asyncio: Fastapi with aio-pika, consumer ignores Await\nTags: websocket, async-await, rabbitmq, python-asyncio, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to hook my websocket endpoint with rabbitmq (aio-pika). Goal is to have listener in that endpoint and on any new message from queue pass the message to browser client over websockets.\n\nI tested the consumer with asyncio in a script with asyncio loop. Works as I followed and used **aio-pika** documentation. (source: https://aio-pika.readthedocs.io/en/latest/rabbitmq-tutorial/2-work-queues.html, **worker.py**)\n\nHowever, when I use it in **fastapi** in websockets endpoint, I cant make it work. Somehow the listener:\n\n```\nawait queue.consume(on_message)\n```\n\nis completely ignored.\n\nThis is my attempt (I put it all in one function, so its more readable):\n\n```\n@app.websocket(\"/ws\")\nasync def websocket_endpoint(websocket: WebSocket):\n print(\"Entering websockets\")\n await manager.connect(websocket)\n print(\"got connection\")\n\n # params\n queue_name = \"task_events\"\n routing_key = \"user_id.task\"\n\n con = \"amqp://rabbitmq:rabbitmq@rabbit:5672/\"\n connection = await connect(con)\n channel = await connection.channel()\n\n await channel.set_qos(prefetch_count=1)\n\n exchange = await channel.declare_exchange(\n \"topic_logs\",\n ExchangeType.TOPIC,\n )\n\n # Declaring queue\n queue = await channel.declare_queue(queue_name)\n\n # Binding the queue to the exchange\n await queue.bind(exchange, routing_key)\n\n async def on_message(message: IncomingMessage):\n async with message.process():\n # here will be the message passed over websockets to browser client\n print(\"sent\", message.body)\n\n \n\n \n try:\n \n ######### Not working as expected ###########\n # await does not await and websockets finishes, as there is no loop\n await queue.consume(on_message) \n #############################################\n\n ################ This Alternative code atleast receives some messages #############\n # If I use this part, I atleast get some messages, when I trigger a backend task that publishes new messages to the queue. \n # It seems like the messages are somehow stuck and new task releases all stucked messages, but does not release new one. \n while True: \n await queue.consume(on_message)\n await asyncio.sleep(1)\n ################## one part #############\n\n except WebSocketDisconnect:\n manager.disconnect(websocket)\n```\n\nI am quite new to async in python. I am not sure where is the problem and I cannot somehow implement async consuming loop while getting inspired with worker.py from aio-pika.\n\n========================================\n\nTop Answer:\nYou could use an async iterator, which is the second canonical way to consume messages from a queue.\n\nIn your case, this means:\n\n```\nasync with queue.iterator() as iter:\n async for message in iter:\n async with message.process():\n # do something with message\n```\n\nIt will block as long as no message is received and will be suspended again after processing a message.\n\n========================================\n\nCode:\n```text\nawait queue.consume(on_message)\n```\n\n```text\n@app.websocket(\"/ws\")\nasync def websocket_endpoint(websocket: WebSocket):\n print(\"Entering websockets\")\n await manager.connect(websocket)\n print(\"got connection\")\n\n # params\n queue_name = \"task_events\"\n routing_key = \"user_id.task\"\n\n\n con = \"amqp://rabbitmq:rabbitmq@rabbit:5672/\"\n connection = await connect(con)\n channel = await connection.channel()\n\n\n await channel.set_qos(prefetch_count=1)\n\n exchange = await channel.declare_exchange(\n \"topic_logs\",\n ExchangeType.TOPIC,\n )\n\n # Declaring queue\n queue = await channel.declare_queue(queue_name)\n\n # Binding the queue to the exchange\n await queue.bind(exchange, routing_key)\n\n async def on_message(message: IncomingMessage):\n async with message.process():\n # here will be the message passed over websockets to browser client\n print(\"sent\", message.body)\n\n \n\n \n try:\n \n ######### Not working as expected ###########\n # await does not await and websockets finishes, as there is no loop\n await queue.consume(on_message) \n #############################################\n\n ################ This Alternative code atleast receives some messages #############\n # If I use this part, I atleast get some messages, when I trigger a backend task that publishes new messages to the queue. \n # It seems like the messages are somehow stuck and new task releases all stucked messages, but does not release new one. \n while True: \n await queue.consume(on_message)\n await asyncio.sleep(1)\n ################## one part #############\n\n except WebSocketDisconnect:\n manager.disconnect(websocket)\n```\n\n```text\nconsumer_tag = await queue.consume(on_message, no_ack=True)\n```\n\n```text\nawait queue.cancel(consumer_tag)\n```\n\n```text\nwhile True:\n data = await websocket.receive_text()\n x = await manager.send_message(data, websocket)\n```\n\n```py\nasync with queue.iterator() as iter:\n async for message in iter:\n async with message.process():\n # do something with message\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.153Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":6,"totalLines":176,"estimatedTokens":1295}}648{"id":"stack-61724245","source":"stackoverflow","questionId":61724245,"title":"FastAPI is not picking up a nested schema despite the data being there in the DB/model","tags":["python","python-3.x","sqlalchemy","fastapi","pydantic"],"text":"Title: FastAPI is not picking up a nested schema despite the data being there in the DB/model\nTags: python, python-3.x, sqlalchemy, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI get an error when trying to return data stored in a relationship between two models. More info below:\n\n`models.py` (relevant models are `Company` and `Address`)\n\n```\nfrom datetime import datetime\n\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import relationship\nfrom sqlalchemy import Column, Integer, String, Date, Sequence, ForeignKey, DateTime\n\ntry:\n from .functions import to_camelcase\nexcept:\n from functions import to_camelcase\n\nBase = declarative_base()\n\nclass ToDictMixin(object):\n def to_dict(self, camelcase=True):\n if camelcase:\n return {to_camelcase(column.key): getattr(self, attr) for attr, column in self.__mapper__.c.items()}\n else:\n return {column.key: getattr(self, attr) for attr, column in self.__mapper__.c.items()}\n\nclass TimestampMixin(object):\n record_created = Column('record_created', DateTime, default=datetime.now())\n\nclass Company(Base, ToDictMixin, TimestampMixin):\n __tablename__ = 'companies'\n\n number = Column(Integer, primary_key=True)\n name = Column(String)\n incorporated = Column(Date)\n\n address = relationship(\"Address\", back_populates=\"occupier\")\n\n def __repr__(self):\n return f\"\"\n\nclass Address(Base, ToDictMixin, TimestampMixin):\n __tablename__ = 'addresses'\n\n id = Column(Integer, primary_key=True)\n address_line1 = Column(String)\n address_line2 = Column(String)\n address_line3 = Column(String)\n po_box = Column(String)\n post_town = Column(String)\n county = Column(String)\n postcode = Column(String)\n country = Column(String)\n occupier_id = Column(Integer, ForeignKey(\"companies.number\"))\n\n occupier = relationship(\"Company\", back_populates=\"address\")\n```\n\n`schemas.py`\n\n```\nimport datetime\n\nfrom pydantic import BaseModel, BaseConfig\nfrom typing import List\n\nfrom functions import to_camelcase\n\nclass APIBase(BaseModel):\n class Config(BaseConfig):\n orm_mode = True\n alias_generator = to_camelcase\n allow_population_by_field_name = True\n\nclass AddressBase(APIBase):\n address_line1 : str\n postcode: str\n\nclass AddressCreate(AddressBase):\n pass\n\nclass Address(AddressBase):\n address_line2 : str\n address_line3 : str\n po_box : str\n post_town : str\n county : str\n postcode : str\n country : str\n\nclass CompanyBase(APIBase):\n number: int\n name: str\n\nclass CompanyCreate(CompanyBase):\n incorporated : datetime.date\n\nclass Company(CompanyBase):\n incorporated : datetime.date\n address: Address\n```\n\nRelevant call in `main.py`:\n\n```\n@app.get(\"/companies\", response_model=List[schemas.Company])\ndef get_companies(\n year: int = None, month: int = None, day: int = None, number: int = None, \n name: str = None, db: Session = Depends(get_db)):\n\n name = name.upper() if name else None\n\n arguments = locals()\n arguments.pop(\"db\")\n\n if not any(arguments.values()):\n return None\n\n myquery = db.query(models.Company)\n datedict = {}\n\n for key, value in arguments.items():\n if key == \"number\" and datedict:\n myquery = crud.get_company_by_date(db, **datedict)\n\n if not value:\n continue\n\n if key == 'year' or key == 'month' or key == 'day':\n datedict[key] = value\n else:\n myquery = crud.filter_query(myquery, **{key:value})\n\n return myquery.all()\n```\n\nNow as far as I can tell from the docs I have got everything set up fine. When I remove `address: Address` from the Company schema this call will return the correct company/companies without the address data. \n\nI have checked that the relevant address data is associated with the company model by testing \n\n```\n>>> x = SESSION.query(Company).filter_by(number=12544331).one_or_none()\n>>> x.address[0].address_line1\n'4 VICTORIA COURT'\n```\n\nSo I know that the data is in the addresses table, the relationship is set up correctly, and the model and schema works before trying to include the address data in the result. However when I try to access `http://127.0.0.1:8000/companies?number=12544331` I get Internal Server Error and the following error message:\n\n```\nINFO: 127.0.0.1:50928 - \"GET /companies?number=12544331 HTTP/1.1\" 500 Internal Server Error\nERROR: Exception in ASGI application\nTraceback (most recent call last):\n File \"c:\\users\\admin\\google~1\\python\\new_co~1\\env\\lib\\site-packages\\uvicorn\\protocols\\http\\h11_impl.py\", line 384, in run_asgi\n result = await app(self.scope, self.receive, self.send)\n File \"c:\\users\\admin\\google~1\\python\\new_co~1\\env\\lib\\site-packages\\uvicorn\\middleware\\proxy_headers.py\", line 45, in __call__\n return await self.app(scope, receive, send)\n File \"c:\\users\\admin\\google~1\\python\\new_co~1\\env\\lib\\site-packages\\fastapi\\applications.py\", line 149, in __call__\n await super().__call__(scope, receive, send)\n File \"c:\\users\\admin\\google~1\\python\\new_co~1\\env\\lib\\site-packages\\starlette\\applications.py\", line 102, in __call__\n await self.middleware_stack(scope, receive, send)\n File \"c:\\users\\admin\\google~1\\python\\new_co~1\\env\\lib\\site-packages\\starlette\\middleware\\errors.py\", line 181, in __call__\n raise exc from None\n File \"c:\\users\\admin\\google~1\\python\\new_co~1\\env\\lib\\site-packages\\starlette\\middleware\\errors.py\", line 159, in __call__\n await self.app(scope, receive, _send)\n File \"c:\\users\\admin\\google~1\\python\\new_co~1\\env\\lib\\site-packages\\starlette\\exceptions.py\", line 82, in __call__\n raise exc from None\n File \"c:\\users\\admin\\google~1\\python\\new_co~1\\env\\lib\\site-packages\\starlette\\exceptions.py\", line 71, in __call__\n await self.app(scope, receive, sender)\n File \"c:\\users\\admin\\google~1\\python\\new_co~1\\env\\lib\\site-packages\\starlette\\routing.py\", line 550, in __call__\n await route.handle(scope, receive, send)\n File \"c:\\users\\admin\\google~1\\python\\new_co~1\\env\\lib\\site-packages\\starlette\\routing.py\", line 227, in handle\n await self.app(scope, receive, send)\n File \"c:\\users\\admin\\google~1\\python\\new_co~1\\env\\lib\\site-packages\\starlette\\routing.py\", line 41, in app\n response = await func(request)\n File \"c:\\users\\admin\\google~1\\python\\new_co~1\\env\\lib\\site-packages\\fastapi\\routing.py\", line 204, in app\n response_data = await serialize_response(\n File \"c:\\users\\admin\\google~1\\python\\new_co~1\\env\\lib\\site-packages\\fastapi\\routing.py\", line 126, in serialize_response\n raise ValidationError(errors, field.type_)\npydantic.error_wrappers.ValidationError: 8 validation errors for Company\nresponse -> 0 -> address -> addressLine1\n field required (type=value_error.missing)\nresponse -> 0 -> address -> postcode\n field required (type=value_error.missing)\nresponse -> 0 -> address -> addressLine2\n field required (type=value_error.missing)\nresponse -> 0 -> address -> addressLine3\n field required (type=value_error.missing)\nresponse -> 0 -> address -> poBox\n field required (type=value_error.missing)\nresponse -> 0 -> address -> postTown\n field required (type=value_error.missing)\nresponse -> 0 -> address -> county\n field required (type=value_error.missing)\nresponse -> 0 -> address -> country\n field required (type=value_error.missing)\n```\n\nIt seems to think that the address data isn't there. I thought this would be something to do with `orm_mode` in `schemas.py` as there is lazyloading but I have `orm_mode` set to `True` to avoid this (see https://fastapi.tiangolo.com/tutorial/sql-databases/#technical-details-about-orm-mode).\n\nPlease, what am I missing?\n\n========================================\n\nCode:\n```text\nfrom datetime import datetime\n\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import relationship\nfrom sqlalchemy import Column, Integer, String, Date, Sequence, ForeignKey, DateTime\n\ntry:\n from .functions import to_camelcase\nexcept:\n from functions import to_camelcase\n\n\nBase = declarative_base()\n\n\nclass ToDictMixin(object):\n def to_dict(self, camelcase=True):\n if camelcase:\n return {to_camelcase(column.key): getattr(self, attr) for attr, column in self.__mapper__.c.items()}\n else:\n return {column.key: getattr(self, attr) for attr, column in self.__mapper__.c.items()}\n\n\nclass TimestampMixin(object):\n record_created = Column('record_created', DateTime, default=datetime.now())\n\n\nclass Company(Base, ToDictMixin, TimestampMixin):\n __tablename__ = 'companies'\n\n number = Column(Integer, primary_key=True)\n name = Column(String)\n incorporated = Column(Date)\n\n address = relationship(\"Address\", back_populates=\"occupier\")\n\n def __repr__(self):\n return f\"<Company(number='{self.number}', name='{self.name}', incorporated='{self.incorporated.isoformat}')>\"\n\n\nclass Address(Base, ToDictMixin, TimestampMixin):\n __tablename__ = 'addresses'\n\n id = Column(Integer, primary_key=True)\n address_line1 = Column(String)\n address_line2 = Column(String)\n address_line3 = Column(String)\n po_box = Column(String)\n post_town = Column(String)\n county = Column(String)\n postcode = Column(String)\n country = Column(String)\n occupier_id = Column(Integer, ForeignKey(\"companies.number\"))\n\n occupier = relationship(\"Company\", back_populates=\"address\")\n```\n\n```text\nimport datetime\n\nfrom pydantic import BaseModel, BaseConfig\nfrom typing import List\n\nfrom functions import to_camelcase\n\n\nclass APIBase(BaseModel):\n class Config(BaseConfig):\n orm_mode = True\n alias_generator = to_camelcase\n allow_population_by_field_name = True\n\n\nclass AddressBase(APIBase):\n address_line1 : str\n postcode: str\n\n\nclass AddressCreate(AddressBase):\n pass\n\n\nclass Address(AddressBase):\n address_line2 : str\n address_line3 : str\n po_box : str\n post_town : str\n county : str\n postcode : str\n country : str\n\n\nclass CompanyBase(APIBase):\n number: int\n name: str\n\n\nclass CompanyCreate(CompanyBase):\n incorporated : datetime.date\n\n\nclass Company(CompanyBase):\n incorporated : datetime.date\n address: Address\n```\n\n```text\n@app.get(\"/companies\", response_model=List[schemas.Company])\ndef get_companies(\n year: int = None, month: int = None, day: int = None, number: int = None, \n name: str = None, db: Session = Depends(get_db)):\n\n name = name.upper() if name else None\n\n arguments = locals()\n arguments.pop(\"db\")\n\n if not any(arguments.values()):\n return None\n\n myquery = db.query(models.Company)\n datedict = {}\n\n for key, value in arguments.items():\n if key == \"number\" and datedict:\n myquery = crud.get_company_by_date(db, **datedict)\n\n if not value:\n continue\n\n if key == 'year' or key == 'month' or key == 'day':\n datedict[key] = value\n else:\n myquery = crud.filter_query(myquery, **{key:value})\n\n return myquery.all()\n```\n\n```text\n>>> x = SESSION.query(Company).filter_by(number=12544331).one_or_none()\n>>> x.address[0].address_line1\n'4 VICTORIA COURT'\n```\n\n```text\nINFO: 127.0.0.1:50928 - \"GET /companies?number=12544331 HTTP/1.1\" 500 Internal Server Error\nERROR: Exception in ASGI application\nTraceback (most recent call last):\n File \"c:\\users\\admin\\google~1\\python\\new_co~1\\env\\lib\\site-packages\\uvicorn\\protocols\\http\\h11_impl.py\", line 384, in run_asgi\n result = await app(self.scope, self.receive, self.send)\n File \"c:\\users\\admin\\google~1\\python\\new_co~1\\env\\lib\\site-packages\\uvicorn\\middleware\\proxy_headers.py\", line 45, in __call__\n return await self.app(scope, receive, send)\n File \"c:\\users\\admin\\google~1\\python\\new_co~1\\env\\lib\\site-packages\\fastapi\\applications.py\", line 149, in __call__\n await super().__call__(scope, receive, send)\n File \"c:\\users\\admin\\google~1\\python\\new_co~1\\env\\lib\\site-packages\\starlette\\applications.py\", line 102, in __call__\n await self.middleware_stack(scope, receive, send)\n File \"c:\\users\\admin\\google~1\\python\\new_co~1\\env\\lib\\site-packages\\starlette\\middleware\\errors.py\", line 181, in __call__\n raise exc from None\n File \"c:\\users\\admin\\google~1\\python\\new_co~1\\env\\lib\\site-packages\\starlette\\middleware\\errors.py\", line 159, in __call__\n await self.app(scope, receive, _send)\n File \"c:\\users\\admin\\google~1\\python\\new_co~1\\env\\lib\\site-packages\\starlette\\exceptions.py\", line 82, in __call__\n raise exc from None\n File \"c:\\users\\admin\\google~1\\python\\new_co~1\\env\\lib\\site-packages\\starlette\\exceptions.py\", line 71, in __call__\n await self.app(scope, receive, sender)\n File \"c:\\users\\admin\\google~1\\python\\new_co~1\\env\\lib\\site-packages\\starlette\\routing.py\", line 550, in __call__\n await route.handle(scope, receive, send)\n File \"c:\\users\\admin\\google~1\\python\\new_co~1\\env\\lib\\site-packages\\starlette\\routing.py\", line 227, in handle\n await self.app(scope, receive, send)\n File \"c:\\users\\admin\\google~1\\python\\new_co~1\\env\\lib\\site-packages\\starlette\\routing.py\", line 41, in app\n response = await func(request)\n File \"c:\\users\\admin\\google~1\\python\\new_co~1\\env\\lib\\site-packages\\fastapi\\routing.py\", line 204, in app\n response_data = await serialize_response(\n File \"c:\\users\\admin\\google~1\\python\\new_co~1\\env\\lib\\site-packages\\fastapi\\routing.py\", line 126, in serialize_response\n raise ValidationError(errors, field.type_)\npydantic.error_wrappers.ValidationError: 8 validation errors for Company\nresponse -> 0 -> address -> addressLine1\n field required (type=value_error.missing)\nresponse -> 0 -> address -> postcode\n field required (type=value_error.missing)\nresponse -> 0 -> address -> addressLine2\n field required (type=value_error.missing)\nresponse -> 0 -> address -> addressLine3\n field required (type=value_error.missing)\nresponse -> 0 -> address -> poBox\n field required (type=value_error.missing)\nresponse -> 0 -> address -> postTown\n field required (type=value_error.missing)\nresponse -> 0 -> address -> county\n field required (type=value_error.missing)\nresponse -> 0 -> address -> country\n field required (type=value_error.missing)\n```\n\n```text\nmodels.py\n```\n\n```text\nCompany\n```\n\n```text\nAddress\n```\n\n```text\nschemas.py\n```\n\n```text\nmain.py\n```\n\n```text\naddress: Address\n```\n\n```text\nhttp://127.0.0.1:8000/companies?number=12544331\n```\n\n```text\norm_mode\n```\n\n```text\nschemas.py\n```\n\n```text\norm_mode\n```\n\n```text\nTrue\n```\n\n```text\nclass Company(Base, ToDictMixin, TimestampMixin):\n __tablename__ = 'companies'\n\n number = Column(Integer, primary_key=True)\n name = Column(String)\n incorporated = Column(Date)\n\n address = relationship(\"Address\", uselist=False, back_populates=\"occupier\")\n\n def __repr__(self):\n return f\"<Company(number='{self.number}', name='{self.name}', incorporated='{self.incorporated.isoformat}')>\"\n```\n\n```text\nmodels.py\n```\n\n```text\nuselist=False\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.153Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":19,"totalLines":467,"estimatedTokens":3644}}649{"id":"stack-61032857","source":"stackoverflow","questionId":61032857,"title":"Gunicorn/ Uvicorn worker times out on AWS Fargate","tags":["docker","gunicorn","aws-fargate","fastapi","uvicorn"],"text":"Title: Gunicorn/ Uvicorn worker times out on AWS Fargate\nTags: docker, gunicorn, aws-fargate, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI try to deploy my FastAPI application on AWS Fargate with an application load balancer in front of it. The application makes calls to AWS Aurora.\nMy stack is as follows\n\n- Python 3.7.4\n\n- uvicorn 0.11.3\n\n- gunicorn 19.9.0\n\n- fastapi 0.53.2\n\n- asyncpg 0.20.1\n\nMy container runs fine when deploying locally or on an EC2 instance, but workers time out during boot when deploying on Fargate. The logs don't give me any clue what is wrong (see below).\n\nThings I tried to overcome this issue:\n\n- increase memory for Fargate Task\n\n- relax security group settings\n\n- increase gunicorn timeout value\n\nNone of it had any effect.\n\nHowever, when trying to deploy a barebone FastAPI application (just one root route, no dependencies) the application manages to boot and I can access it via the Load Balancer. Once I add my custom routes the issue occurs. \n\nWhat other options do I have to debug this? \nIf guincorn can't start my workers, is there a way to log the issue?\n\n```\n03:05:16 Checking for script in /app/prestart.sh\n03:05:16 Running script /app/prestart.sh\n03:05:16 Running inside /app/prestart.sh, you could add migrations to this file, e.g.:\n03:05:16 #! /usr/bin/env bash\n03:05:16 # Let the DB start\n03:05:16 sleep 10;\n03:05:16 # Run migrations\n03:05:16 alembic upgrade head\n03:05:17 [2020-04-03 03:05:17 +0000] [1] [DEBUG] Current configuration:\n03:05:17 config: /app/app/gunicorn_conf.py\n03:05:17 bind: ['0.0.0.0:80']\n03:05:17 backlog: 2048\n03:05:17 workers: 2\n03:05:17 worker_class: uvicorn.workers.UvicornWorker\n03:05:17 threads: 2\n03:05:17 worker_connections: 1000\n03:05:17 max_requests: 0\n03:05:17 max_requests_jitter: 0\n03:05:17 timeout: 120\n03:05:17 graceful_timeout: 30\n03:05:17 keepalive: 120\n03:05:17 limit_request_line: 4094\n03:05:17 limit_request_fields: 100\n03:05:17 limit_request_field_size: 8190\n03:05:17 reload: False\n03:05:17 reload_engine: auto\n03:05:17 reload_extra_files: []\n03:05:17 spew: False\n03:05:17 check_config: False\n03:05:17 preload_app: False\n03:05:17 sendfile: None\n03:05:17 reuse_port: False\n03:05:17 chdir: /app\n03:05:17 daemon: False\n03:05:17 raw_env: []\n03:05:17 pidfile: None\n03:05:17 worker_tmp_dir: None\n03:05:17 user: 0\n03:05:17 group: 0\n03:05:17 umask: 0\n03:05:17 initgroups: False\n03:05:17 tmp_upload_dir: None\n03:05:17 secure_scheme_headers: {'X-FORWARDED-PROTOCOL': 'ssl', 'X-FORWARDED-PROTO': 'https', 'X-FORWARDED-SSL': 'on'}\n03:05:17 forwarded_allow_ips: ['127.0.0.1']\n03:05:17 accesslog: None\n03:05:17 disable_redirect_access_to_syslog: False\n03:05:17 access_log_format: %(h)s %(l)s %(u)s %(t)s \"%(r)s\" %(s)s %(b)s \"%(f)s\" \"%(a)s\"\n03:05:17 errorlog: -\n03:05:17 loglevel: debug\n03:05:17 capture_output: False\n03:05:17 logger_class: gunicorn.glogging.Logger\n03:05:17 logconfig: None\n03:05:17 logconfig_dict: {}\n03:05:17 syslog_addr: udp://localhost:514\n03:05:17 syslog: False\n03:05:17 syslog_prefix: None\n03:05:17 syslog_facility: user\n03:05:17 enable_stdio_inheritance: False\n03:05:17 statsd_host: None\n03:05:17 statsd_prefix:\n03:05:17 proc_name: None\n03:05:17 default_proc_name: app.main:app\n03:05:17 pythonpath: None\n03:05:17 paste: None\n03:05:17 on_starting: \n03:05:17 on_reload: \n03:05:17 when_ready: \n03:05:17 pre_fork: \n03:05:17 post_fork: \n03:05:17 post_worker_init: \n03:05:17 worker_int: \n03:05:17 worker_abort: \n03:05:17 pre_exec: \n03:05:17 pre_request: \n03:05:17 post_request: \n03:05:17 child_exit: \n03:05:17 worker_exit: \n03:05:17 nworkers_changed: \n03:05:17 on_exit: \n03:05:17 proxy_protocol: False\n03:05:17 proxy_allow_ips: ['127.0.0.1']\n03:05:17 keyfile: None\n03:05:17 certfile: None\n03:05:17 ssl_version: 2\n03:05:17 cert_reqs: 0\n03:05:17 ca_certs: None\n03:05:17 suppress_ragged_eofs: True\n03:05:17 do_handshake_on_connect: False\n03:05:17 ciphers: TLSv1\n03:05:17 raw_paste_global_conf: []\n03:05:17 [2020-04-03 03:05:17 +0000] [1] [INFO] Starting gunicorn 19.9.0\n03:05:17 [2020-04-03 03:05:17 +0000] [1] [DEBUG] Arbiter booted\n03:05:17 [2020-04-03 03:05:17 +0000] [1] [INFO] Listening at: http://0.0.0.0:80 (1)\n03:05:17 [2020-04-03 03:05:17 +0000] [1] [INFO] Using worker: uvicorn.workers.UvicornWorker\n03:05:17 [2020-04-03 03:05:17 +0000] [8] [INFO] Booting worker with pid: 8\n03:05:17 [2020-04-03 03:05:17 +0000] [9] [INFO] Booting worker with pid: 9\n03:05:17 [2020-04-03 03:05:17 +0000] [1] [DEBUG] 2 workers\n03:07:17 [2020-04-03 03:07:17 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:8)\n03:07:17 [2020-04-03 03:07:17 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:9)\n03:07:17 [2020-04-03 03:07:17 +0000] [12] [INFO] Booting worker with pid: 12\n03:07:18 [2020-04-03 03:07:18 +0000] [13] [INFO] Booting worker with pid: 13\n03:07:54 [2020-04-03 03:07:54 +0000] [1] [INFO] Handling signal: term\n```\n\n========================================\n\nCode:\n```text\n03:05:16 Checking for script in /app/prestart.sh\n03:05:16 Running script /app/prestart.sh\n03:05:16 Running inside /app/prestart.sh, you could add migrations to this file, e.g.:\n03:05:16 #! /usr/bin/env bash\n03:05:16 # Let the DB start\n03:05:16 sleep 10;\n03:05:16 # Run migrations\n03:05:16 alembic upgrade head\n03:05:17 [2020-04-03 03:05:17 +0000] [1] [DEBUG] Current configuration:\n03:05:17 config: /app/app/gunicorn_conf.py\n03:05:17 bind: ['0.0.0.0:80']\n03:05:17 backlog: 2048\n03:05:17 workers: 2\n03:05:17 worker_class: uvicorn.workers.UvicornWorker\n03:05:17 threads: 2\n03:05:17 worker_connections: 1000\n03:05:17 max_requests: 0\n03:05:17 max_requests_jitter: 0\n03:05:17 timeout: 120\n03:05:17 graceful_timeout: 30\n03:05:17 keepalive: 120\n03:05:17 limit_request_line: 4094\n03:05:17 limit_request_fields: 100\n03:05:17 limit_request_field_size: 8190\n03:05:17 reload: False\n03:05:17 reload_engine: auto\n03:05:17 reload_extra_files: []\n03:05:17 spew: False\n03:05:17 check_config: False\n03:05:17 preload_app: False\n03:05:17 sendfile: None\n03:05:17 reuse_port: False\n03:05:17 chdir: /app\n03:05:17 daemon: False\n03:05:17 raw_env: []\n03:05:17 pidfile: None\n03:05:17 worker_tmp_dir: None\n03:05:17 user: 0\n03:05:17 group: 0\n03:05:17 umask: 0\n03:05:17 initgroups: False\n03:05:17 tmp_upload_dir: None\n03:05:17 secure_scheme_headers: {'X-FORWARDED-PROTOCOL': 'ssl', 'X-FORWARDED-PROTO': 'https', 'X-FORWARDED-SSL': 'on'}\n03:05:17 forwarded_allow_ips: ['127.0.0.1']\n03:05:17 accesslog: None\n03:05:17 disable_redirect_access_to_syslog: False\n03:05:17 access_log_format: %(h)s %(l)s %(u)s %(t)s \"%(r)s\" %(s)s %(b)s \"%(f)s\" \"%(a)s\"\n03:05:17 errorlog: -\n03:05:17 loglevel: debug\n03:05:17 capture_output: False\n03:05:17 logger_class: gunicorn.glogging.Logger\n03:05:17 logconfig: None\n03:05:17 logconfig_dict: {}\n03:05:17 syslog_addr: udp://localhost:514\n03:05:17 syslog: False\n03:05:17 syslog_prefix: None\n03:05:17 syslog_facility: user\n03:05:17 enable_stdio_inheritance: False\n03:05:17 statsd_host: None\n03:05:17 statsd_prefix:\n03:05:17 proc_name: None\n03:05:17 default_proc_name: app.main:app\n03:05:17 pythonpath: None\n03:05:17 paste: None\n03:05:17 on_starting: <function OnStarting.on_starting at 0x7ff9c4742ef0>\n03:05:17 on_reload: <function OnReload.on_reload at 0x7ff9c4757050>\n03:05:17 when_ready: <function WhenReady.when_ready at 0x7ff9c4757170>\n03:05:17 pre_fork: <function Prefork.pre_fork at 0x7ff9c4757290>\n03:05:17 post_fork: <function Postfork.post_fork at 0x7ff9c47573b0>\n03:05:17 post_worker_init: <function PostWorkerInit.post_worker_init at 0x7ff9c47574d0>\n03:05:17 worker_int: <function WorkerInt.worker_int at 0x7ff9c47575f0>\n03:05:17 worker_abort: <function WorkerAbort.worker_abort at 0x7ff9c4757710>\n03:05:17 pre_exec: <function PreExec.pre_exec at 0x7ff9c4757830>\n03:05:17 pre_request: <function PreRequest.pre_request at 0x7ff9c4757950>\n03:05:17 post_request: <function PostRequest.post_request at 0x7ff9c47579e0>\n03:05:17 child_exit: <function ChildExit.child_exit at 0x7ff9c4757b00>\n03:05:17 worker_exit: <function WorkerExit.worker_exit at 0x7ff9c4757c20>\n03:05:17 nworkers_changed: <function NumWorkersChanged.nworkers_changed at 0x7ff9c4757d40>\n03:05:17 on_exit: <function OnExit.on_exit at 0x7ff9c4757e60>\n03:05:17 proxy_protocol: False\n03:05:17 proxy_allow_ips: ['127.0.0.1']\n03:05:17 keyfile: None\n03:05:17 certfile: None\n03:05:17 ssl_version: 2\n03:05:17 cert_reqs: 0\n03:05:17 ca_certs: None\n03:05:17 suppress_ragged_eofs: True\n03:05:17 do_handshake_on_connect: False\n03:05:17 ciphers: TLSv1\n03:05:17 raw_paste_global_conf: []\n03:05:17 [2020-04-03 03:05:17 +0000] [1] [INFO] Starting gunicorn 19.9.0\n03:05:17 [2020-04-03 03:05:17 +0000] [1] [DEBUG] Arbiter booted\n03:05:17 [2020-04-03 03:05:17 +0000] [1] [INFO] Listening at: http://0.0.0.0:80 (1)\n03:05:17 [2020-04-03 03:05:17 +0000] [1] [INFO] Using worker: uvicorn.workers.UvicornWorker\n03:05:17 [2020-04-03 03:05:17 +0000] [8] [INFO] Booting worker with pid: 8\n03:05:17 [2020-04-03 03:05:17 +0000] [9] [INFO] Booting worker with pid: 9\n03:05:17 [2020-04-03 03:05:17 +0000] [1] [DEBUG] 2 workers\n03:07:17 [2020-04-03 03:07:17 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:8)\n03:07:17 [2020-04-03 03:07:17 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:9)\n03:07:17 [2020-04-03 03:07:17 +0000] [12] [INFO] Booting worker with pid: 12\n03:07:18 [2020-04-03 03:07:18 +0000] [13] [INFO] Booting worker with pid: 13\n03:07:54 [2020-04-03 03:07:54 +0000] [1] [INFO] Handling signal: term\n```\n\n========================================\n\nComments:\n- good call -- wasn't my exact problem but you set me on the right path to check around this","metadata":{"transformedAt":"2026-08-18T18:32:29.153Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":1,"totalLines":252,"estimatedTokens":2436}}650{"id":"stack-74015708","source":"stackoverflow","questionId":74015708,"title":"Why when I send an email via FastAPI-mail, the email I receive displays the same message twice?","tags":["python","html","email","fastapi"],"text":"Title: Why when I send an email via FastAPI-mail, the email I receive displays the same message twice?\nTags: python, html, email, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to send an email using `FastAPI-mail`, and even though I am successfully sending it, when I open the email in Gmail or Outlook, **the content (message) appears twice**.\n\nI am looking at the code but I don't think I am attaching the message twice (also note that the top message always shows the tags, while the second doesn't (see below image).\n\nAny help will be appreciated!\n\nhttps://i.sstatic.net/Q8ae4.png\n\n`main.py`\n\n```\nfrom fastapi import FastAPI\nfrom fastapi_mail import FastMail, MessageSchema, ConnectionConfig\nfrom starlette.requests import Request\nfrom starlette.responses import JSONResponse\nfrom pydantic import EmailStr, BaseModel\nfrom typing import List\napp = FastAPI()\n\nclass EmailSchema(BaseModel):\n email: List[EmailStr]\n\nconf = ConnectionConfig(\n MAIL_USERNAME='myGmailAddress',\n MAIL_PASSWORD=\"myPassword\",\n MAIL_FROM='myGmailAddress',\n MAIL_PORT=587,\n MAIL_SERVER=\"smtp.gmail.com\",\n MAIL_TLS=True,\n MAIL_SSL=False\n)\n\n@app.post(\"/send_mail\")\nasync def send_mail(email: EmailSchema):\n\n template = \"\"\"\n \n \n \n\nHi !!!\n \nThanks for using **fastapi mail**!!!\n\n \n \n \"\"\"\n\n message = MessageSchema(\n subject=\"Fastapi-Mail module\",\n recipients=email.dict().get(\"email\"), # List of recipients, as many as you can pass\n body=template,\n subtype=\"html\"\n )\n\n template = \"\"\"\nHi !!!\n\nThanks for using **fastapi mail**!!!\n\n\"\"\"\n\n '''\n template = \"\"\"\nHi !!!\n\nThanks for using **fastapi mail**!!!\n\n\"\"\"\n '''\n\n fm = FastMail(conf)\n await fm.send_message(message)\n\n return JSONResponse(status_code=200, content={\"message\": \"email has been sent\"})\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nfrom fastapi_mail import FastMail, MessageSchema, ConnectionConfig\nfrom starlette.requests import Request\nfrom starlette.responses import JSONResponse\nfrom pydantic import EmailStr, BaseModel\nfrom typing import List\napp = FastAPI()\n\n\nclass EmailSchema(BaseModel):\n email: List[EmailStr]\n\n\nconf = ConnectionConfig(\n MAIL_USERNAME='myGmailAddress',\n MAIL_PASSWORD=\"myPassword\",\n MAIL_FROM='myGmailAddress',\n MAIL_PORT=587,\n MAIL_SERVER=\"smtp.gmail.com\",\n MAIL_TLS=True,\n MAIL_SSL=False\n)\n\n\n@app.post(\"/send_mail\")\nasync def send_mail(email: EmailSchema):\n\n template = \"\"\"\n <html>\n <body>\n \n\n<p>Hi !!!\n <br>Thanks for using <b>fastapi mail</b>!!!</p>\n\n\n </body>\n </html>\n \"\"\"\n\n message = MessageSchema(\n subject=\"Fastapi-Mail module\",\n recipients=email.dict().get(\"email\"), # List of recipients, as many as you can pass\n body=template,\n subtype=\"html\"\n )\n\n template = \"\"\"\n<p>Hi !!!\n<br>Thanks for using <b>fastapi mail</b>!!!\n</p>\"\"\"\n\n '''\n template = \"\"\"\n<p>Hi !!!\n<br>Thanks for using <b>fastapi mail</b>!!!\n</p>\"\"\"\n '''\n\n fm = FastMail(conf)\n await fm.send_message(message)\n\n return JSONResponse(status_code=200, content={\"message\": \"email has been sent\"})\n```\n\n```text\nFastAPI-mail\n```\n\n```text\nmain.py\n```\n\n```text\nmessage = MessageSchema(\n subject=\"Fastapi-Mail module\",\n recipients=email.dict().get(\"email\"), # List of recipients, as many as you can pass\n html=template, # <<<<<<<<< here\n subtype=\"html\"\n)\n```\n\n```text\nbody\n```\n\n```text\nhtml\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.153Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":6,"totalLines":175,"estimatedTokens":851}}651{"id":"stack-71523294","source":"stackoverflow","questionId":71523294,"title":"Logging UUID per API request in Python FastAPI","tags":["python","fastapi","loguru"],"text":"Title: Logging UUID per API request in Python FastAPI\nTags: python, fastapi, loguru\nSource: Stack Overflow\n\nQuestion:\nI have a pure python package(let's call it main) that has a few functions for managing infrastructure. Alongside, I have created a FastAPI service that can make calls to the main module to invoke functionality as per need.\n\nFor logging, I'm using loguru. The API on startup creates a loguru instance, settings are applied and a generic UUID is set (namely, [main]). On every incoming request to the API, a pre_request function generates a new UUID and calls the loguru to configure with that UUID. At the end of the request, the UUID is set back to default UUID [main].\n\nThe problem that I'm facing is on concurrent requests, the new UUID takes over and all the logs are now being written with the UUID that was configured latest. Is there a way I can instantiate the loguru module on every request and make sure there's no cross logging happening for parallelly processed API requests?\n\nImplementation:\n\nIn **init**.py of the main package:\n\n```\nfrom loguru import logger \nlogger.remove() #to delete all existing default loggers \nlogger.add(filename, format, level, retention, rotation) #format\nlogger.configure(extra={\"uuid\": \"main\"})\n```\n\nIn all modules, the logger is imported as\n\n```\nfrom loguru import logger\n```\n\nIn api/ package - on every new request, I have this below code block:\n\n```\nuuid = get_uuid() #calling util func to get a new uuid\nlogger.configure(uuid=uuid) \n# Here onwards, all log messages contain this uuid \n# At the end of the request, I configure it back to default uuid (i.e. \"main\")\n```\n\nThe configure method is updating the root logger, I tried using the bind method instead, which according to the loguru docs, can be used to contextualize extra record attributes, but it does not seem to have any effect (I still see the default UUID, i.e. \"main\", only when I use .configure the UUID gets set).\n\nAny ideas on how should I go about setting the UUID, so that all concurrent requests to the API have their own UUID? Since there are multiple sub-modules that get called to serve one API request and all of them have some logging in it, I need the UUID to persist for all the modules per request. It seems like I need to have a logger instance per API request, but I am not sure how to instantiate it correctly to make this work.\n\nThe current implementation works if the API is serving one request, but the logging breaks when serving more than 1 call (since the UUID that gets logged is the last one that as configured)\n\n========================================\n\nTop Answer:\n- Have a file that contains a contextvar (that you import and set from whatever file you want).\n\n- In the same file, add a method that adds this contextvar to LogRecord Objects by overriding *logging.getLogRecordFactory*.\n\nThe advantage of this solution is that you can use *logging.basicConfig* normally. No loggers need to be configured, and is simple.\n\nSample implementatiom\n\n========================================\n\nCode:\n```text\nfrom loguru import logger \nlogger.remove() #to delete all existing default loggers \nlogger.add(filename, format, level, retention, rotation) #format\nlogger.configure(extra={\"uuid\": \"main\"})\n```\n\n```text\nfrom loguru import logger\n```\n\n```text\nuuid = get_uuid() #calling util func to get a new uuid\nlogger.configure(uuid=uuid) \n# Here onwards, all log messages contain this uuid \n# At the end of the request, I configure it back to default uuid (i.e. \"main\")\n```\n\n```text\nfrom loguru import logger\nfrom contextvars import ContextVar\nfrom starlette.middleware.base import BaseHTTPMiddleware\n\n_request_id = ContextVar(\"request_id\", default=None)\n\n\ndef get_request_id():\n return _request_id.get()\n\nclass ContextualizeRequest(BaseHTTPMiddleware):\n async def dispatch(self, request, call_next):\n uuid = get_uuid()\n request_id = _request_id.set(uuid) # set uuid to context variable\n with logger.contextualize(uuid=get_request_id()):\n try:\n response = await call_next(request)\n except Exception:\n logger.error(\"Request failed\")\n finally:\n _request_id.reset()\n return response\n```\n\n========================================\n\nComments:\n- What does your current code for assigning the uuid and configuring the request context look like?\n- added my implementation details\n- Clearly you need a per request data structure to store your uuid, which this issue shows how to do. a custom di object instead of module level imports for the logger should be pretty clean.\n- Using contextvars, I see. Let me give it a try!","metadata":{"transformedAt":"2026-08-18T18:32:29.153Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":4,"totalLines":107,"estimatedTokens":1169}}652{"id":"stack-74001717","source":"stackoverflow","questionId":74001717,"title":"init_beanie cannot initialize some collections","tags":["mongodb","fastapi","fastapiusers"],"text":"Title: init_beanie cannot initialize some collections\nTags: mongodb, fastapi, fastapiusers\nSource: Stack Overflow\n\nQuestion:\nHaving a well described model and schema using Pydantic and Beanie syntax, there are some collections, represented by their Document classes, which are not been initialized by init_beanie function at the startup event of a Fastapi app.\n\nDid someone know what could be the causes of such a behavior?\n\nFastapi-users set a very special class named User, which is one of the well initialized by the background Beanie engine. After that, I added my entire model which consists in several classes.\n\nFor example, from my product_category module:\n\n```\nfrom typing import Optional \nfrom beanie import Document, Indexed \n\nclass ProductCategory(Document):\n category: Indexed(str, unique=True)\n description: Optional[str]\n\n class Settings:\n name = \"product_categories\"\n```\n\nFrom my product_subcategory module:\n\n```\nfrom typing import Optional \nfrom beanie import Document, Link \nfrom product_category import ProductCategory\n \nclass ProductSubcategory(Document):\n category_id: Link[ProductCategory]\n subcategory: str\n description: Optional[str]\n\n class Settings:\n name = \"product_subcategories\"\n```\n\n...and so.\nThe outcome of init_beanie reflects an initialization of a collection named ProductCategory, not product_categories as I think it would happened, because of the Settings inner class with its property \"name\", and that's it.\n\nSuch a behavior is not documented, and that's why I assume I'm making something wrong. Can anyone know how to fix this?\n\nThanks in advance.\nJorge Olmedo.\n\n========================================\n\nTop Answer:\nWe had a similar issue. When trying to load and change a document from the database it failed. The error looked like this:\n\n```\nTraceback (most recent call last):\n File \"/usr/lib/python3.10/runpy.py\", line 196, in _run_module_as_main\n return _run_code(code, main_globals, None,\n File \"/usr/lib/python3.10/runpy.py\", line 86, in _run_code\n exec(code, run_globals)\n File \"/code/app/main.py\", line 280, in \n asyncio.run(main())\n File \"/usr/lib/python3.10/asyncio/runners.py\", line 44, in run\n return loop.run_until_complete(main)\n File \"/usr/lib/python3.10/asyncio/base_events.py\", line 646, in run_until_complete\n return future.result()\n File \"/code/app/main.py\", line 204, in main\n await rad.set({MyDocument.status: Status.IN_PROGRESS})\nAttributeError: 'NoneType' object has no attribute 'set'\n```\n\nWe figured out that the reference to the document represented by the identifier `rad` was `None` because it was not able to load it from the database using this:\n\n```\nrad = MyDocument.find_one(MyDocument.id == args.rid)\n```\n\nThe first problem was that we forgot to provide the correct collection name in the Document class. We had to add inner `Settings` class with a `name` property containing the name of collection.\n\nBefore:\n\n```\nclass MyDocument(Document):\n id: uuid.UUID = None\n status: Status = None\n```\n\nAfter:\n\n```\nclass MyDocument(Document):\n id: uuid.UUID = None\n status: Status = None\n class Settings:\n name = \"theCorrectCollectionName\"\n```\n\nDo not forget to call the `init_beanie` method. Otherwise the `Settings` class will be ignored (See links below).\n\nIn the end we did the following things to make it work:\n\nUpgrade from beanie 1.10.4 to 1.20.0\n\nUse absolute imports instead of relative imports for our self written code like so (As mentioned also in this answer but without example: https://stackoverflow.com/a/74033006/3623232)\n\nBefore:\n\n```\nimport cfg\nfrom models import MyDocument, Status\n```\n\nAfterwards:\n\n```\nimport app.cfg as cfg\nfrom app.models import MyDocument, Status\n```\n\nThe assumption here is that the there exist files `cfg.py` and `models.py` in a folder `app` that also contains an empty `__init__.py` file to mark the app folder as a module.\n\nRelated links:\n\n- Regarding `Settings` configuration: https://beanie-odm.dev/tutorial/defining-a-document/\n\n- Regarding beanie initialization: https://beanie-odm.dev/tutorial/initialization/\n\n- Absolute vs relative paths in python: https://realpython.com/absolute-vs-relative-python-imports/\n\n========================================\n\nCode:\n```text\nfrom typing import Optional \nfrom beanie import Document, Indexed \n\nclass ProductCategory(Document):\n category: Indexed(str, unique=True)\n description: Optional[str]\n\n class Settings:\n name = \"product_categories\"\n```\n\n```text\nfrom typing import Optional \nfrom beanie import Document, Link \nfrom product_category import ProductCategory\n \nclass ProductSubcategory(Document):\n category_id: Link[ProductCategory]\n subcategory: str\n description: Optional[str]\n\n class Settings:\n name = \"product_subcategories\"\n```\n\n```text\nTraceback (most recent call last):\n File \"/usr/lib/python3.10/runpy.py\", line 196, in _run_module_as_main\n return _run_code(code, main_globals, None,\n File \"/usr/lib/python3.10/runpy.py\", line 86, in _run_code\n exec(code, run_globals)\n File \"/code/app/main.py\", line 280, in <module>\n asyncio.run(main())\n File \"/usr/lib/python3.10/asyncio/runners.py\", line 44, in run\n return loop.run_until_complete(main)\n File \"/usr/lib/python3.10/asyncio/base_events.py\", line 646, in run_until_complete\n return future.result()\n File \"/code/app/main.py\", line 204, in main\n await rad.set({MyDocument.status: Status.IN_PROGRESS})\nAttributeError: 'NoneType' object has no attribute 'set'\n```\n\n```text\nrad = MyDocument.find_one(MyDocument.id == args.rid)\n```\n\n```text\nclass MyDocument(Document):\n id: uuid.UUID = None\n status: Status = None\n```\n\n```text\nclass MyDocument(Document):\n id: uuid.UUID = None\n status: Status = None\n class Settings:\n name = \"theCorrectCollectionName\"\n```\n\n```text\nimport cfg\nfrom models import MyDocument, Status\n```\n\n```text\nimport app.cfg as cfg\nfrom app.models import MyDocument, Status\n```\n\n```text\nrad\n```\n\n```text\nNone\n```\n\n```text\nSettings\n```\n\n```text\nname\n```\n\n```text\ninit_beanie\n```\n\n```text\nSettings\n```\n\n```text\ncfg.py\n```\n\n```text\nmodels.py\n```\n\n```text\napp\n```\n\n```text\n__init__.py\n```\n\n```text\nSettings\n```\n\n========================================\n\nComments:\n- Hi, can you mire precisely state what it means to \"change relative module paths for absolute module paths\"? I'm having the same issue and I can't figure out why beanie is ignoring the inner `Settings` class with the `name` attribute filled.\n- I figured it out. See my answer below with the issue we had and how we solved it. Changing from relative to absolute imports was just one of the necessary changes.","metadata":{"transformedAt":"2026-08-18T18:32:29.153Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":19,"totalLines":252,"estimatedTokens":1648}}653{"id":"stack-73548278","source":"stackoverflow","questionId":73548278,"title":"Python 3 - Hebrew coding problems","tags":["python","fastapi","hebrew","mojibake"],"text":"Title: Python 3 - Hebrew coding problems\nTags: python, fastapi, hebrew, mojibake\nSource: Stack Overflow\n\nQuestion:\nI have a server written in FastAPI, Python 3.8.13 that receives data through a form from an external service, which may include Hebrew letters. Until recently, the data arrived through a back proxy server that was written in Python 2.7 and everything worked well. The proxy code was look something like this:\n\n```\nfrom requests import post\nfrom bottle import route, request\n@route('/', method='POST')\ndef new_req():\n post('https://....', dict(request.forms))\n return ''\n```\n\nThe backend server code looks something like this:\n\n```\n@app.post('/....')\nasync def get_message(request:Request, message:str=Form(...)):\n print(message)\n```\n\nAs long as the data arrived via the proxy, there were no problems with Hebrew letters. From the moment we asked the service to transfer the messages directly to the backend server, string like: 'שלום' were seen: 'שלו×'. The service declares that the data in Hebrew is sent in Unicode, so I tried to do something like this:\n\n```\n@app.post('/....')\nasync def get_message(request:Request, message:bytes=Form(...)):\n print(message)\n message = message.decode('utf-8')\n print(message)\n```\n\nThe result (for: 'שלום'):\n\n```\nb'\\xc3\\x97\\xc2\\xa9\\xc3\\x97\\xc2\\x9c\\xc3\\x97\\xc2\\x95\\xc3\\x97\\xc2\\x9d'\nש×××\n```\n\nI tried replacing `'utf-8'` with different encodings, international or Hebrew, and each time I got new kind of gibberish. Does anyone have an idea what else to try?\n\n========================================\n\nCode:\n```py\nfrom requests import post\nfrom bottle import route, request\n@route('/', method='POST')\ndef new_req():\n post('https://....', dict(request.forms))\n return ''\n```\n\n```py\n@app.post('/....')\nasync def get_message(request:Request, message:str=Form(...)):\n print(message)\n```\n\n```py\n@app.post('/....')\nasync def get_message(request:Request, message:bytes=Form(...)):\n print(message)\n message = message.decode('utf-8')\n print(message)\n```\n\n```text\nb'\\xc3\\x97\\xc2\\xa9\\xc3\\x97\\xc2\\x9c\\xc3\\x97\\xc2\\x95\\xc3\\x97\\xc2\\x9d'\nש×××\n```\n\n```text\n'utf-8'\n```\n\n```text\nb'\\xd7\\xa9\\xd7\\x9c\\xd7\\x95\\xd7\\x9d'\n```\n\n```text\nש×××\n```\n\n```text\nb'\\xc3\\x97\\xc2\\xa9\\xc3\\x97\\xc2\\x9c\\xc3\\x97\\xc2\\x95\\xc3\\x97\\xc2\\x9d'\n```\n\n```text\nbytes\n```\n\n========================================\n\nComments:\n- What are the actual bytes before you try to decode them as `'utf-8'`? The string `'ש×××'` doesn't help much to see what byte values each of the `×` has.\n- Thanks for the comment @RolandIllig. I have edited and completed this information.\n- Since I use FastAPI I could not prevent the double coding, but I restored the original string as follows: `message = message.encode('ISO-8859-1').decode('utf-8')`. Thank you very much!","metadata":{"transformedAt":"2026-08-18T18:32:29.153Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":100,"estimatedTokens":701}}654{"id":"stack-75031831","source":"stackoverflow","questionId":75031831,"title":"How to apply FastAPI Middleware on \"non-async def\" endpoints?","tags":["python","asynchronous","python-asyncio","fastapi","middleware"],"text":"Title: How to apply FastAPI Middleware on \"non-async def\" endpoints?\nTags: python, asynchronous, python-asyncio, fastapi, middleware\nSource: Stack Overflow\n\nQuestion:\nAccording to https://fastapi.tiangolo.com/tutorial/middleware/, we could apply a FastAPI Middleware on `async def` endpoints.\n\nCurrently I have several `non-async def` endpoints, how to apply FastAPI Middleware on `non-async def` endpoint? If I still register an `async` Middleware, will it work for the `non-async def` endpoint ?\n\nFor example:\n\n```\n@app.middleware(\"http\")\nasync def add_process_time_header(request: Request, call_next):\n start_time = time.time()\n response = await call_next(request)\n process_time = time.time() - start_time\n response.headers[\"X-Process-Time\"] = str(process_time)\n return response\n```\n\nWill the Middleware work properly if `call_next` is a non-async def method ?\n\nThank you.\n\n========================================\n\nCode:\n```py\n@app.middleware(\"http\")\nasync def add_process_time_header(request: Request, call_next):\n start_time = time.time()\n response = await call_next(request)\n process_time = time.time() - start_time\n response.headers[\"X-Process-Time\"] = str(process_time)\n return response\n```\n\n```text\nasync def\n```\n\n```text\nnon-async def\n```\n\n```text\nnon-async def\n```\n\n```text\nasync\n```\n\n```text\nnon-async def\n```\n\n```text\ncall_next\n```\n\n========================================\n\nComments:\n- Yes, because the call_next will be a coroutine created by Starlette. Your “sync” endpoints are executed in a thread pool and ran as async methods/functions.\n- @JarroVGIT Thank you for replying. Just curious where could I find the tutorial of `“sync” endpoints are executed in a thread pool and ran as async methods/functions`. It is a new concept for me.","metadata":{"transformedAt":"2026-08-18T18:32:29.153Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":7,"totalLines":67,"estimatedTokens":444}}655{"id":"stack-71966420","source":"stackoverflow","questionId":71966420,"title":"how to send information(data) from a FastAPI server(client) to another FastAPI(model)","tags":["python","post","fastapi"],"text":"Title: how to send information(data) from a FastAPI server(client) to another FastAPI(model)\nTags: python, post, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am a newbie in RESTful API...\n\nso I am trying to deploy two servers (client and model). The main idea is :\n\n- Client uploads his images on the client server, the client server(port 8000) will make some transformations\n\n- then I want the client server to make a post (with transformed data) to another server (also using FastAPI at port 8008).\n\nCurrently, I am strugling with the client server part, how to do a post to another server ?\n\n```\n# Define a flask app\napp = FastAPI()\n\napp.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")\n\ntemplates = Jinja2Templates(directory=\"./templates\")\n\norigins = [\"*\"]\nmethods = [\"*\"]\nheaders = [\"*\"]\n\napp.add_middleware(\n CORSMiddleware, \n allow_origins = origins,\n allow_credentials = True,\n allow_methods = methods,\n allow_headers = headers \n)\n\n@app.get('/', response_class=HTMLResponse)\ndef root(request: Request):\n return templates.TemplateResponse(\"index.html\", {\"request\": request})\n #render_template('index.html')\n\n#here the client will upload his image to the server\n#and then encrypt it in the same button\n@app.post('/encrypt', status_code=200)\nasync def upload_img(f: UploadFile = File(...)):\n\n ret = {}\n logger.debug(f)\n #base_path = \"uploads\"\n # filename = \"predict.jpg\"\n f.filename = \"predict.jpg\"\n base_path = os.path.dirname(__file__)\n file_path = os.path.join(base_path, 'uploads',secure_filename(f.filename))\n os.makedirs(base_path, exist_ok=True)\n try:\n with open(file_path, \"wb\") as buffer:\n shutil.copyfileobj(f.file, buffer)\n except Exception as e:\n print(\"Error: {}\".format(str(e)))\n\n image_info = {\"filename\": f.filename, \"image\": f}\n\n #preprocess image\n plain_input = load_input(f)\n #create a public context and drop sk\n ctx, sk = create_ctx()\n \n #encrypt \n enc_input = prepare_input(ctx, plain_input)\n enc_input_serialize = enc_input.serialize()\n\n # la tu dois faire un post au serveur\n return sk\n\nclass inference_param(BaseModel):\n context : bytes\n enc_input : bytes\n\n@app.post(\"/data\") #send data to the model server\nasync def send_data(data : inference_param):\n return data\n```\n\n========================================\n\nCode:\n```py\n# Define a flask app\napp = FastAPI()\n\napp.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")\n\ntemplates = Jinja2Templates(directory=\"./templates\")\n\norigins = [\"*\"]\nmethods = [\"*\"]\nheaders = [\"*\"]\n\n\napp.add_middleware(\n CORSMiddleware, \n allow_origins = origins,\n allow_credentials = True,\n allow_methods = methods,\n allow_headers = headers \n)\n\n\n@app.get('/', response_class=HTMLResponse)\ndef root(request: Request):\n return templates.TemplateResponse(\"index.html\", {\"request\": request})\n #render_template('index.html')\n\n\n\n#here the client will upload his image to the server\n#and then encrypt it in the same button\n@app.post('/encrypt', status_code=200)\nasync def upload_img(f: UploadFile = File(...)):\n\n ret = {}\n logger.debug(f)\n #base_path = \"uploads\"\n # filename = \"predict.jpg\"\n f.filename = \"predict.jpg\"\n base_path = os.path.dirname(__file__)\n file_path = os.path.join(base_path, 'uploads',secure_filename(f.filename))\n os.makedirs(base_path, exist_ok=True)\n try:\n with open(file_path, \"wb\") as buffer:\n shutil.copyfileobj(f.file, buffer)\n except Exception as e:\n print(\"Error: {}\".format(str(e)))\n\n\n image_info = {\"filename\": f.filename, \"image\": f}\n\n #preprocess image\n plain_input = load_input(f)\n #create a public context and drop sk\n ctx, sk = create_ctx()\n \n #encrypt \n enc_input = prepare_input(ctx, plain_input)\n enc_input_serialize = enc_input.serialize()\n\n # la tu dois faire un post au serveur\n return sk\n\n\n\nclass inference_param(BaseModel):\n context : bytes\n enc_input : bytes\n\n\n@app.post(\"/data\") #send data to the model server\nasync def send_data(data : inference_param):\n return data\n```\n\n========================================\n\nComments:\n- Answers to this topic can be found here and here, as well as here and here","metadata":{"transformedAt":"2026-08-18T18:32:29.153Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":1,"totalLines":164,"estimatedTokens":1062}}656{"id":"stack-74624111","source":"stackoverflow","questionId":74624111,"title":"Application runs with uvicorn but can't find Module (No module named 'app')","tags":["python","fastapi"],"text":"Title: Application runs with uvicorn but can't find Module (No module named 'app')\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\n```\n.\n├── __pycache__\n│ └── api.cpython-310.pyc\n├── app\n│ ├── __pycache__\n│ │ └── main.cpython-310.pyc\n│ ├── api_v1\n│ │ ├── __pycache__\n│ │ │ └── apis.cpython-310.pyc\n│ │ ├── apis.py\n│ │ └── endpoints\n│ │ ├── __pycache__\n│ │ │ └── message_prediction.cpython-310.pyc\n│ │ └── message_prediction.py\n│ ├── config.py\n│ ├── main.py\n│ └── schemas\n│ ├── Messages.py\n│ └── __pycache__\n│ └── Messages.cpython-310.pyc\n├── app.egg-info\n│ ├── PKG-INFO\n│ ├── SOURCES.txt\n│ ├── dependency_links.txt\n│ └── top_level.txt\n├── build\n│ └── bdist.macosx-12.0-arm64\n├── data\n│ ├── processed\n│ │ ├── offers_big.csv_cleaned.xlsx\n│ │ └── requests_big.csv_cleaned.xlsx\n│ ├── processed.dvc\n│ ├── raw\n│ │ ├── offers.csv.old\n│ │ ├── offers_big.csv\n│ │ ├── requests.csv.old\n│ │ └── requests_big.csv\n│ ├── raw.dvc\n│ ├── validated\n│ │ ├── validated_offers.xlsx\n│ │ └── validated_requests.xlsx\n│ └── validated.dvc\n├── dist\n│ └── app-0.1.0-py3.10.egg\n├── model.pkl\n├── model.py\n├── notebooks\n│ └── contact-form.ipynb\n├── requirements.in\n├── requirements.txt\n├── setup.py\n└── test_api.py\n```\n\n```\n# main.py\nimport os\nfrom fastapi import FastAPI\nimport uvicorn\nfrom app.api_v1.apis import api_router\n\n# create the app\nmessages_classification_app = FastAPI()\n\nmessages_classification_app.include_router(api_router)\n\nif __name__ == '__main__':\n uvicorn.run(\"app.main:messages_classification_app\", host=os.getenv(\"HOST\", \"0.0.0.0\"), port=int(os.getenv(\"PORT\", 8000)))\n```\n\n```\n# requirements.in\nfastapi\nuvicorn\n-e file:.#egg=app\n```\n\nTrying to run the fastAPI app with `python`, results in error:\n\n```\npy[learning] ~/r/v/contact-form-classification master ± python app/main.py\nTraceback (most recent call last):\n File \"/Users/xxxxx/repos/visable/contact-form-classification/app/main.py\", line 4, in \n from app.api_v1.apis import api_router\nModuleNotFoundError: No module named 'app'\n```\n\nRunning it with `uvicorn` directly works:\n\n```\npy[learning] ~/r/v/contact-form-classification master ± uvicorn app.main:messages_classification_app\nINFO: Started server process [53665]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\nINFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\n```\n\nAny idea why? Looked into similar questions, don't seem to apply to mine.\n\n========================================\n\nCode:\n```text\n.\n├── __pycache__\n│ └── api.cpython-310.pyc\n├── app\n│ ├── __pycache__\n│ │ └── main.cpython-310.pyc\n│ ├── api_v1\n│ │ ├── __pycache__\n│ │ │ └── apis.cpython-310.pyc\n│ │ ├── apis.py\n│ │ └── endpoints\n│ │ ├── __pycache__\n│ │ │ └── message_prediction.cpython-310.pyc\n│ │ └── message_prediction.py\n│ ├── config.py\n│ ├── main.py\n│ └── schemas\n│ ├── Messages.py\n│ └── __pycache__\n│ └── Messages.cpython-310.pyc\n├── app.egg-info\n│ ├── PKG-INFO\n│ ├── SOURCES.txt\n│ ├── dependency_links.txt\n│ └── top_level.txt\n├── build\n│ └── bdist.macosx-12.0-arm64\n├── data\n│ ├── processed\n│ │ ├── offers_big.csv_cleaned.xlsx\n│ │ └── requests_big.csv_cleaned.xlsx\n│ ├── processed.dvc\n│ ├── raw\n│ │ ├── offers.csv.old\n│ │ ├── offers_big.csv\n│ │ ├── requests.csv.old\n│ │ └── requests_big.csv\n│ ├── raw.dvc\n│ ├── validated\n│ │ ├── validated_offers.xlsx\n│ │ └── validated_requests.xlsx\n│ └── validated.dvc\n├── dist\n│ └── app-0.1.0-py3.10.egg\n├── model.pkl\n├── model.py\n├── notebooks\n│ └── contact-form.ipynb\n├── requirements.in\n├── requirements.txt\n├── setup.py\n└── test_api.py\n```\n\n```py\n# main.py\nimport os\nfrom fastapi import FastAPI\nimport uvicorn\nfrom app.api_v1.apis import api_router\n\n# create the app\nmessages_classification_app = FastAPI()\n\nmessages_classification_app.include_router(api_router)\n\nif __name__ == '__main__':\n uvicorn.run(\"app.main:messages_classification_app\", host=os.getenv(\"HOST\", \"0.0.0.0\"), port=int(os.getenv(\"PORT\", 8000)))\n```\n\n```text\n# requirements.in\nfastapi\nuvicorn\n-e file:.#egg=app\n```\n\n```text\npy[learning] ~/r/v/contact-form-classification master ± python app/main.py\nTraceback (most recent call last):\n File \"/Users/xxxxx/repos/visable/contact-form-classification/app/main.py\", line 4, in <module>\n from app.api_v1.apis import api_router\nModuleNotFoundError: No module named 'app'\n```\n\n```text\npy[learning] ~/r/v/contact-form-classification master ± uvicorn app.main:messages_classification_app\nINFO: Started server process [53665]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\nINFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\n```\n\n```text\npython\n```\n\n```text\nuvicorn\n```\n\n```text\npython app/main.py\n```\n\n```text\napp/\n```\n\n```text\nsys.path\n```\n\n```text\napp\n```\n\n```text\npython -m app.main\n```\n\n```text\napp/main.py\n```\n\n```text\nsys.path\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.153Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":14,"totalLines":237,"estimatedTokens":1238}}657{"id":"stack-69651350","source":"stackoverflow","questionId":69651350,"title":"Custom OpenMetrics Not Being Propagated to DataDog","tags":["python","prometheus","metrics","fastapi","datadog"],"text":"Title: Custom OpenMetrics Not Being Propagated to DataDog\nTags: python, prometheus, metrics, fastapi, datadog\nSource: Stack Overflow\n\nQuestion:\nI am using the `prometheus-fastapi-instrumentator` package to expose my custom metrics but they don't seem to be picked up by DataDog.\n\nI'm experiencing a lot of trouble getting DataDog to scrape my `Counter` metrics. Additionally, `Histogram` buckets don't seem to be going through as distribution metrics.\n\nDoes anyone have any clue as to what the issue could be?\n\nHere is my monitoring.py file: https://github.com/rileyhun/fastapi-ml-example/blob/main/app/core/monitoring.py\n\nReproducible Example:\n\n```\ngit clone https://github.com/rileyhun/fastapi-ml-example.git\n\ndocker build -t ${IMAGE_NAME}:${IMAGE_TAG} -f Dockerfile .\ndocker tag ${IMAGE_NAME}:${IMAGE_TAG} rhun/${IMAGE_NAME}:${IMAGE_TAG}\ndocker push rhun/${IMAGE_NAME}:${IMAGE_TAG}\n\nminikube start --driver=docker --memory 4g --nodes 2\nkubectl create namespace monitoring\nhelm install prometheus-stack prometheus-community/kube-prometheus-stack -n monitoring\n\nkubectl apply -f deployment/wine-model-local.yaml\nkubectl port-forward svc/wine-model-service 8080:80\n\npython api_call.py\n```\n\n========================================\n\nCode:\n```text\ngit clone https://github.com/rileyhun/fastapi-ml-example.git\n\ndocker build -t ${IMAGE_NAME}:${IMAGE_TAG} -f Dockerfile .\ndocker tag ${IMAGE_NAME}:${IMAGE_TAG} rhun/${IMAGE_NAME}:${IMAGE_TAG}\ndocker push rhun/${IMAGE_NAME}:${IMAGE_TAG}\n\nminikube start --driver=docker --memory 4g --nodes 2\nkubectl create namespace monitoring\nhelm install prometheus-stack prometheus-community/kube-prometheus-stack -n monitoring\n\nkubectl apply -f deployment/wine-model-local.yaml\nkubectl port-forward svc/wine-model-service 8080:80\n\npython api_call.py\n```\n\n```text\nprometheus-fastapi-instrumentator\n```\n\n```text\nCounter\n```\n\n```text\nHistogram\n```\n\n```text\nad.datadoghq.com/{name of container declared in spec.containers.name}.check_names : '[\"openmetrics\"]'\n ad.datadoghq.com/{name of container declared in spec.containers.name}.init_configs : '[{}]'\n ad.datadoghq.com/{name of container declared in spec.containers.name}.instances : |\n [\n {\n \"prometheus_url\" : \"http://%%host%%:%%port_0%%/metrics\",\n \"namespace\" : \"\",\n \"metrics\": [\"*\"],\n \"tags\": {\"service\": \"{name of service for datadog}\"},\n \"send_histograms_buckets\": true,\n \"send_distribution_buckets\": true,\n \"send_distribution_counts_as_monotonic\": true\n }\n ]\n```\n\n```text\nDeployment\n```\n\n```text\nspec.template.metadata.annotations\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.153Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":7,"totalLines":88,"estimatedTokens":663}}658{"id":"stack-71374765","source":"stackoverflow","questionId":71374765,"title":"How to select the disk location for UploadFile parameter in FastAPI?","tags":["python","fastapi"],"text":"Title: How to select the disk location for UploadFile parameter in FastAPI?\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am running FastAPI application on a embedded device. The embedded device has limited resources (disk space and RAM). However, an SD card with plenty of space is available. I would like to upload and store a large file on the SD card. The FastAPI documentation suggests using `UploadFile` parameter.\n\nI tried a simple application:\n\n```\nfrom fastapi import FastAPI, File, UploadFile\n\napp = FastAPI()\n\n@app.post(\"/uploadfile/\")\nasync def create_upload_file(file: UploadFile = File(...)):\n return {\"filename\": file.filename}\n```\n\n... and after posting a large file, I get a response with status code `400` and body\n`{\"detail\": \"There was an error parsing the body\"}`.\n\nI was monitoring disk usage during the upload process and I saw the free space on partition `/tmp` was decreasing until it ran out of space. I assume FastAPI figures out that the uploaded file is too big to be stored in memory and decides to store it on disk. Unfortunately, the selected disk is also too small.\n\nHow can I select the location which FastAPI internally uses to store the uploaded file?\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI, File, UploadFile\n\napp = FastAPI()\n\n\n@app.post(\"/uploadfile/\")\nasync def create_upload_file(file: UploadFile = File(...)):\n return {\"filename\": file.filename}\n```\n\n```text\nUploadFile\n```\n\n```text\n400\n```\n\n```text\n{\"detail\": \"There was an error parsing the body\"}\n```\n\n```text\n/tmp\n```\n\n```py\nimport tempfile\n\nprint(\"Temp directory before changing it:\", tempfile.gettempdir())\ntempfile.tempdir = \"path/to/tempdir/here\"\nprint(\"Temp directory after changing it:\", tempfile.gettempdir())\n```\n\n```text\ngettempdir()\n```\n\n```text\ntempfile\n```\n\n```text\ntemporary\n```\n\n```text\n.tempdir\n```\n\n========================================\n\nComments:\n- It uses a SpooledTemporaryFile behind the scenes: docs.python.org/3/library/… - see stackoverflow.com/questions/18280245/… for how you can change where Python's tempfile module stores its temporary files.\n- Specificically, looks like you can set the the env variables TMPDIR. TEMP or TMP with your prefered temp directory docs.python.org/3/library/tempfile.html#tempfile.gettempdir","metadata":{"transformedAt":"2026-08-18T18:32:29.153Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":10,"totalLines":85,"estimatedTokens":580}}659{"id":"stack-74163301","source":"stackoverflow","questionId":74163301,"title":"How to properly use Regex in CORS Middleware for FastAPI?","tags":["python","regex","fastapi","vercel","starlette"],"text":"Title: How to properly use Regex in CORS Middleware for FastAPI?\nTags: python, regex, fastapi, vercel, starlette\nSource: Stack Overflow\n\nQuestion:\nI have an app that uses a FastAPI backend and a Next.js frontend. In development and on production with stable origins, I am able to use the CORSMiddleware with no issues. However, I have deployed the Next.js frontend with Vercel, and want to take advantage of the automatic Preview deployments that Vercel makes with each git commit to allow for staging-type qualitative testing and sanity checks.\n\nI'm running into CORS issues on the Preview deployments: since each Preview deployment uses an auto-generated URL of the pattern: `--.vercel.app`, I can't add them directly to the **allow_origins** argument of the CORSMiddleware. Instead I am trying to add the pattern to the **allow_origin_regex** argument.\n\nI am very new to regex, but was able to figure out a pattern that I've tested to work in REPL. However, because I'm having issues, I've switched to use an ultra-permissive regex of '.*' just to get anything to work but that has failed also.\n\n*main.py (relevant portions)*\n\n```\nfrom fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware\n\napp = FastAPI()\n\norigins = [\n \"http://localhost\",\n \"http://localhost:8080\",\n \"http://localhost:3000\",\n \"https://my-project-name.vercel.app\"\n]\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=origins,\n allow_origin_regex=\".*\",\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n```\n\nI've looked at the FastAPI/Starlette cors.py file to see how it ingests and uses the origin regex and don't see where the problem would be. I've tested the same methods in REPL with no issues. I'm at a loss as to the next avenue to investigate in order to resolve this issue. Any assistance or pointers or \"hey dummy you forgot this\" comments are welcome.\n\n========================================\n\nTop Answer:\nI hesitate to admit how stupid the answer to this actually was once I realized my mistake, but wanted to be intellectually honest and provide an update just in case anyone else has a similar blank and runs into this down the line.\n\nI'm new to anything frontend and development in general for the most part, and had never really dealt with CORS before. I was so concerned with getting the Preview deployments going on the frontend, and checking the auto-built Preview deployments on Vercel, that I forgot where I was actually making changes. I have the frontend and backend of my project as subdirectories within the same repo, so each git push of the backend code causes an automatic Vercel deployment, and I just blanked that it wouldn't cause an update of the actual FastAPI code.\n\nAs soon as I realized and pushed the changes to my backend, everything started working as it should.\n\nI marked the other answer as correct because it was 100% correct in answering the question I asked, but providing this as it's the answer to the problem of where I made the real mistake.\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware\n\napp = FastAPI()\n\norigins = [\n \"http://localhost\",\n \"http://localhost:8080\",\n \"http://localhost:3000\",\n \"https://my-project-name.vercel.app\"\n]\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=origins,\n allow_origin_regex=\".*\",\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n```\n\n```text\n<project-name>-<unique-hash>-<scope-slug>.vercel.app\n```\n\n```text\n<project-name>-<unique-hash>-<scope-slug>.vercel.app\n```\n\n```py\nallow_origin_regex='https://.*\\.vercel\\.app'\n```\n\n```py\nallow_origin_regex='https://<project-name>-.*\\.vercel\\.app'\n```\n\n```py\nallow_origin_regex = 'https://my-site-.*\\.vercel\\.app'\n```\n\n```py\nimport re\n\norigin = 'https://my-site-xadvghg2z-acme.vercel.app'\nallow_origin_regex = 'https://my-site-.*\\.vercel\\.app'\ncompiled_allow_origin_regex = re.compile(allow_origin_regex)\n\nif (compiled_allow_origin_regex is not None\n and compiled_allow_origin_regex.fullmatch(origin)):\n print('Math found')\nelse:\n print('No match found')\n```\n\n```text\nCORSMiddleware\n```\n\n```text\nhttps://my-site-xadvghg2z-acme.vercel.app\n```\n\n```text\nhttp\n```\n\n```text\nhttps\n```\n\n```text\n80\n```\n\n```text\n8000\n```\n\n```text\n3000\n```\n\n```text\nallow_origin_regex\n```\n\n```text\nallow_origin_regex = 'https://<YOUR_VERCEL-PROJECT-NAME>-*\\.vercel\\.app'\n```\n\n```text\nallow_origin_regex\n```\n\n========================================\n\nComments:\n- Note that if you have your frontend and backend deployed separately on Vercel, your CORS could still be blocked by Vercel's edge protection layer. To verify, check the failing response's response headers' \"server\" value for Vercel. If this happens then it means a frontend call to your backend won't even run your allow origin logic above, due to the Vercel Authentication settings in deployment settings.","metadata":{"transformedAt":"2026-08-18T18:32:29.153Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":17,"totalLines":153,"estimatedTokens":1235}}660{"id":"stack-71401847","source":"stackoverflow","questionId":71401847,"title":"how to design a fastapi app with independent background computation?","tags":["python","fastapi","uvicorn"],"text":"Title: how to design a fastapi app with independent background computation?\nTags: python, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI've created a python main application main.py, which I invoke with `uvicorn main.main --reload`. Which of course runs the following code...\n\n```\nif __name__ == '__main__':\n main()\n```\n\nThat part of the application runs constantly, reads data an processes it until the application is aborted manually. I use `asyncio` to run coroutines.\n\n**Task**\n\nI would like to build a small html dashboard on it, which can display the data that is constantly computed.\n\n**Question**\n\nHow can I run these background calculations of main.py and still implement a dashboard/website with fastapi and jinja2?\n\n- What is the best practice/architecture to structure the files: the background and fastapi app code? e.g. Is there a initial startup function in fastapi where I could invoke the background computation in a coroutine or the other way around?\n\n- How would you invoke the application according to your recommendation?\n\n**What I have achieved so far**\n\nI can run the main application without any fastapi code. And I can run the dashboard without the background tasks. Both work fine independently. But fastapi does not run, when I add its code to the main application with the background computation. (How could it?!? I can only invoke either the main application or the fastapi app.)\n\nAny architectural concepts are appreciated.\nThank you.\n\n========================================\n\nTop Answer:\nFastapi doesn't run because it cant be reached by python interpreter untill it complete your computations. You should start your web app independently of the main process, I strongly recommend you to use `docker-compose`.\nAs fastapi recommends you, you should use `Dramatiq` or `Celery` for huge background tasks, or you can just run separate service in compose services, for example:\n\n```\n# background.py\nif __name__ == '__main__':\n main()\n\n# main.py\napp = FastAPI()\n```\n\ndocker-compose.yml:\n\n```\nservices:\n web-app-interface:\n command: uvicorn main.main ...\n my-daemon:\n command: python background.py\n```\n\nYou can make them communicate with a message broker, such as RabbitMQ etc.\nAnd never use multiprocessing with uvicorn, it can cause process leak, bcz uvicorn rules it's own workers.\n\n========================================\n\nCode:\n```text\nif __name__ == '__main__':\n main()\n```\n\n```text\nuvicorn main.main --reload\n```\n\n```text\nasyncio\n```\n\n```text\nmy_service = MyService()\n\n@app.on_event('startup')\nasync def service_tasks_startup():\n \"\"\"Start all the non-blocking service tasks, which run in the background.\"\"\"\n asyncio.create_task(my_service.start_processing_data())\n```\n\n```text\n@app.get(\"/\")\ndef root():\n return my_service.value\n```\n\n```text\non_event\n```\n\n```text\nstartup\n```\n\n```text\nasyncio.create_task\n```\n\n```text\nMyService\n```\n\n```text\nvalue\n```\n\n```text\n# background.py\nif __name__ == '__main__':\n main()\n\n# main.py\napp = FastAPI()\n```\n\n```yaml\nservices:\n web-app-interface:\n command: uvicorn main.main ...\n my-daemon:\n command: python background.py\n```\n\n```text\ndocker-compose\n```\n\n```text\nDramatiq\n```\n\n```text\nCelery\n```\n\n========================================\n\nComments:\n- thanks and yes, that is how I would do it as well. But... I consume data from a kafka topics (in the background process) and then I would want to append the new events to a dataframe (it doesn't matter if the dataframe is lost upon restart). The fastapi REST calls should then return fractions of that dataframe. Thus, I cannot separate the applications. Do you understand the constraint?\n- You can write result of background task to database and read it in your api endpoints.\n- I feel saving it to a database makes little sense since I consume messages, thus they are ALREADY persisted. Repersisting is of no value. The dashboard depends on these messages ( I want to push them with websockets to the dashboard). Thanks for sharing your thoughts.\n- If you don't really need to save them, you can use any MQ, as I mentioned before.\n- Yegor, it makes very little sense to copy an incoming message of a kafka topic again to another MQ. I see no value in duplicating an action (since I know the kafka infrastructure is under my control). But be certain, you have my gratitude for sharing your ideas. Appreciated.\n- Is only non-blocking if `start_processing_data()` is also defined as `async`.\n- asyncio uses weak reference tracking for tasks, so your created task may be GC:ed\n- @Henrik valid point. What do you recommend?\n- make `my_service` hold the task reference, run `start` on IT instead","metadata":{"transformedAt":"2026-08-18T18:32:29.154Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":15,"totalLines":153,"estimatedTokens":1160}}661{"id":"stack-68980427","source":"stackoverflow","questionId":68980427,"title":"How to handle aggregated query results with SQLAlchemy, pydantic and FastAPI","tags":["python","sqlalchemy","mysql-python","fastapi","pydantic"],"text":"Title: How to handle aggregated query results with SQLAlchemy, pydantic and FastAPI\nTags: python, sqlalchemy, mysql-python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI would like to create an API that returns the aggregated values for each department as a response.\nI am new to FastAPI and pydantic and would appreciate any support.\nIt seems the part where the query results are mapped in pydantic is not working well.\n\n**get method in main.py**\n\n```\n@app.get(\"/api/{client_id}\", response_model=List[schemas.Overview])\ndef read_overview(client_id: str, db: Session = Depends(get_db)):\n db_overview = crud.get_overview(db, client_id=client_id)\n if db_overview is None:\n raise HTTPException(status_code=404, detail=\"Overview not found\")\n return db_overview\n```\n\n**crud.py**\nGet the data corresponding to the three department codes, 1000001, 1000002, and 2000001, aggregated by client_id and deptCode.\n\n```\nfrom sqlalchemy.orm import Session\nfrom sqlalchemy import func\nfrom . import models, schemas\nimport datetime\n\ndef get_overview(db: Session, client_id: str):\n text = '1000001,1000002,2000001'\n depts = text.split(',')\n tbl = models.Overview\n overview = db.query(tbl.client_id, tbl.deptCode, tbl.deptName, func.sum(tbl.count), func.sum(tbl.item1), func.sum(tbl.item2), func.sum(tbl.item3), func.sum(tbl.item4), func.sum(tbl.item5), func.sum(tbl.item6)).\\\n filter(tbl.client_id==client_id). \\\n filter(tbl.deptCode.in_(depts)). \\\n group_by(tbl.client_id, tbl.deptCode, tbl.deptName).all()\n # print(“overview”, overview)\n return overview\n```\n\nIf I check the result retrieved by QUERY with print(), I can see that three rows have been retrieved as expected.\n\n**Result - overview on terminal by using print()**\n\n```\n[('C012345', '1000001', 'A地域', Decimal('25'), Decimal('7'), Decimal('0'), Decimal('2'), Decimal('0'), Decimal('0'), Decimal('0')), ('C012345', '1000002', 'Z地域', Decimal('55'), Decimal('15'), Decimal('2'), Decimal('12'), Decimal('0'), Decimal('0'), Decimal('0')), ('C012345', '2000001', 'あ小学校', Decimal('15'), Decimal('5'), Decimal('0'), Decimal('2'), Decimal('0'), Decimal('0'), Decimal('0'))]\n```\n\nHowever, I get the error message \"value is not a valid integer\" and \"field required\", resulting in an error as follows.\n**Error**\n\n```\nFile \"/Users/junya/mr2edu_server/venv/lib/python3.9/site-packages/fastapi/routing.py\", line 137, in serialize_response\n raise ValidationError(errors, field.type_)\npydantic.error_wrappers.ValidationError: 21 validation errors for Overview\nresponse -> 0 -> count\n value is not a valid integer (type=type_error.integer)\nresponse -> 0 -> item1\n field required (type=value_error.missing)\nresponse -> 0 -> item2\n field required (type=value_error.missing)\nresponse -> 0 -> item3\n field required (type=value_error.missing)\nresponse -> 0 -> item4\n field required (type=value_error.missing)\nresponse -> 0 -> item5\n field required (type=value_error.missing)\nresponse -> 0 -> item6\n field required (type=value_error.missing)\n\n…. continued ...\n```\n\nI also show schemas.py and models.py.\n\n**schemas.py**\n\n```\nfrom pydantic import BaseModel\nimport datetime\n\nclass Overview(BaseModel):\n client_id: str\n deptCode: str\n deptName: str\n count: int\n item1: int\n item2: int\n item3: int\n item4: int\n item5: int\n item6: int\n\n class Config:\n orm_mode = True\n```\n\n**models.py**\n\n```\nfrom sqlalchemy import Column, Date, Integer, String\nfrom sqlalchemy.orm import relationship\n\nfrom .database import Base\n\nclass Overview(Base):\n __tablename__ = \"overview\"\n id = Column(String, primary_key=True, index=True)\n client_id = Column(String)\n date = Column(Date)\n deptCode = Column(String)\n deptName = Column(String)\n level = Column(Integer)\n count = Column(Integer)\n item1 = Column(Integer)\n item2 = Column(Integer)\n item3 = Column(Integer)\n item4 = Column(Integer)\n item5 = Column(Integer)\n item6 = Column(Integer)\n```\n\n========================================\n\nCode:\n```text\n@app.get(\"/api/{client_id}\", response_model=List[schemas.Overview])\ndef read_overview(client_id: str, db: Session = Depends(get_db)):\n db_overview = crud.get_overview(db, client_id=client_id)\n if db_overview is None:\n raise HTTPException(status_code=404, detail=\"Overview not found\")\n return db_overview\n```\n\n```text\nfrom sqlalchemy.orm import Session\nfrom sqlalchemy import func\nfrom . import models, schemas\nimport datetime\n\ndef get_overview(db: Session, client_id: str):\n text = '1000001,1000002,2000001'\n depts = text.split(',')\n tbl = models.Overview\n overview = db.query(tbl.client_id, tbl.deptCode, tbl.deptName, func.sum(tbl.count), func.sum(tbl.item1), func.sum(tbl.item2), func.sum(tbl.item3), func.sum(tbl.item4), func.sum(tbl.item5), func.sum(tbl.item6)).\\\n filter(tbl.client_id==client_id). \\\n filter(tbl.deptCode.in_(depts)). \\\n group_by(tbl.client_id, tbl.deptCode, tbl.deptName).all()\n # print(“overview”, overview)\n return overview\n```\n\n```text\n[('C012345', '1000001', 'A地域', Decimal('25'), Decimal('7'), Decimal('0'), Decimal('2'), Decimal('0'), Decimal('0'), Decimal('0')), ('C012345', '1000002', 'Z地域', Decimal('55'), Decimal('15'), Decimal('2'), Decimal('12'), Decimal('0'), Decimal('0'), Decimal('0')), ('C012345', '2000001', 'あ小学校', Decimal('15'), Decimal('5'), Decimal('0'), Decimal('2'), Decimal('0'), Decimal('0'), Decimal('0'))]\n```\n\n```text\nFile \"/Users/junya/mr2edu_server/venv/lib/python3.9/site-packages/fastapi/routing.py\", line 137, in serialize_response\n raise ValidationError(errors, field.type_)\npydantic.error_wrappers.ValidationError: 21 validation errors for Overview\nresponse -> 0 -> count\n value is not a valid integer (type=type_error.integer)\nresponse -> 0 -> item1\n field required (type=value_error.missing)\nresponse -> 0 -> item2\n field required (type=value_error.missing)\nresponse -> 0 -> item3\n field required (type=value_error.missing)\nresponse -> 0 -> item4\n field required (type=value_error.missing)\nresponse -> 0 -> item5\n field required (type=value_error.missing)\nresponse -> 0 -> item6\n field required (type=value_error.missing)\n\n…. continued ...\n```\n\n```text\nfrom pydantic import BaseModel\nimport datetime\n\nclass Overview(BaseModel):\n client_id: str\n deptCode: str\n deptName: str\n count: int\n item1: int\n item2: int\n item3: int\n item4: int\n item5: int\n item6: int\n\n class Config:\n orm_mode = True\n```\n\n```text\nfrom sqlalchemy import Column, Date, Integer, String\nfrom sqlalchemy.orm import relationship\n\nfrom .database import Base\n\nclass Overview(Base):\n __tablename__ = \"overview\"\n id = Column(String, primary_key=True, index=True)\n client_id = Column(String)\n date = Column(Date)\n deptCode = Column(String)\n deptName = Column(String)\n level = Column(Integer)\n count = Column(Integer)\n item1 = Column(Integer)\n item2 = Column(Integer)\n item3 = Column(Integer)\n item4 = Column(Integer)\n item5 = Column(Integer)\n item6 = Column(Integer)\n```\n\n```text\ndb.query(\n tbl.client_id,\n tbl.deptCode,\n tbl.deptName,\n func.sum(tbl.count).label(\"count\"), \n func.sum(tbl.item1).label(\"item1\"),\n)\n```\n\n```text\nlabel()\n```\n\n```text\nsqlalchemy.engine.row.Row\n```\n\n```text\nfastapi.encoders.jsonable_encoder\n```\n\n========================================\n\nComments:\n- Thank you! As adding label(), it worked as expected. Thanks for explaining the logic as well!","metadata":{"transformedAt":"2026-08-18T18:32:29.154Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":10,"totalLines":248,"estimatedTokens":1840}}662{"id":"stack-68165344","source":"stackoverflow","questionId":68165344,"title":"FastAPI websocket connection causes cpu spike to 100% inside the docker container","tags":["python","docker","websocket","publish-subscribe","fastapi"],"text":"Title: FastAPI websocket connection causes cpu spike to 100% inside the docker container\nTags: python, docker, websocket, publish-subscribe, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am developing a private chat for two or more users to communicate with each other. I have an endpoint for the websocket connection where only authenticated users are able to do a handshake between client and the server\n\nThe problem occurs when the websocket connection is accepted. Consumer handler is running smoothly in the infinite loop which waits for the messages from the client side to actually do some specific tasks that are requested, but the producer on the other side, hangs in an infinite loop and that causes the **CPU spike** up to 100%\n\nObviously I need one listener to a specific redis channel where I get all the messages from the users in real time, somehow I should listen to it, while loop does that but because of that **CPU spike** obviously it is not a good solution.\n\n```\n# api.py\n\nasync def consumer_handler(service):\n \"\"\"Messages received on the websocket connection Consumer - (Publisher)\"\"\"\n try:\n while True:\n received_data = await service.websocket.receive_json()\n if received_data['event_type'] == \"online.users\":\n await service.get_online_user_status(received_data['role_id'])\n elif received_data['event_type'] == \"message.user\":\n await service.send_message(received_data['user_id'], received_data['content'])\n elif received_data['event_type'] == \"info\":\n await service.get_info()\n except WebSocketDisconnect:\n logger.debug(\"WebSocketDisconnect - consumer handler disconnected\")\n\nasync def producer_handler(service):\n \"\"\"Messages generated at the backend to send to the websocket Producer - (Subscriber)\"\"\"\n try:\n while True:\n if service.pubsub.subscribed:\n message = await service.pubsub.get_message(ignore_subscribe_messages=True)\n if message:\n await service.websocket.send_json(message['data'].decode())\n except (ConnectionClosedOK, aioredis.exceptions.ConnectionError) as e:\n logger.debug(f\"{e.__class__}\", \"producer handler disconnected\")\n\n@chat_app.websocket(\"/\")\nasync def websocket_endpoint(websocket: WebSocket,\n current_user: User = Depends(is_authenticated_ws)):\n if not current_user:\n return\n\n async with ConnectionContextManager(user_id=current_user.id, websocket=websocket) as service:\n producer_task = asyncio.ensure_future(producer_handler(service))\n consumer_task = asyncio.ensure_future(consumer_handler(service))\n done, pending = await asyncio.wait(\n [consumer_task, producer_task],\n return_when=asyncio.FIRST_COMPLETED\n )\n for task in pending:\n task.cancel()\n```\n\nThis endpoint handles the both producer/subscriber logic as it is described in the websockets documentation\n\n```\n#websocket_utils.py\n\nclass WebsocketService:\n \"\"\"\n This acts like a service for websocket, is returned within the context manager\n this class is used to not interact with consumer directly, instead interact it with the manager\n \"\"\"\n\n def __init__(self, *, user_id: UUID4, websocket: WebSocket, pubsub: PubSub):\n self.user_id = user_id\n self.websocket = websocket\n self.pubsub = pubsub\n\n async def get_online_user_status(self, role_id):\n await consumer.online_user_status_per_role(role_id, self.websocket)\n\n async def send_message(self, user_id: UUID4, content: str):\n await consumer.send_message_to_user(user_id=user_id,\n message=content,\n websocket=self.websocket)\n\n async def get_info(self):\n await consumer.fetch_info(self.websocket)\n\nclass ConnectionContextManager:\n \"\"\"\n This context manager handles the websocket connection\n on enter, it returns a controller for the websocket events\n \"\"\"\n\n websocket_service: WebsocketService\n\n def __init__(self, *, user_id: UUID4, websocket: WebSocket):\n self.websocket_service = WebsocketService(user_id=user_id,\n websocket=websocket,\n pubsub=websocket.app.redis.pubsub())\n\n async def __aenter__(self):\n logger.debug(\"Context manager enter\")\n await consumer.connect(\n user_id=self.websocket_service.user_id,\n websocket=self.websocket_service.websocket,\n pubsub=self.websocket_service.pubsub\n )\n return self.websocket_service\n\n async def __aexit__(self, exc_type, exc_val, exc_tb) -> None:\n await consumer.disconnect(\n user_id=self.websocket_service.user_id,\n pubsub=self.websocket_service.pubsub,\n websocket=self.websocket_service.websocket,\n )\n logger.debug(\"Context manager exit\")\n```\n\nThis context manager ensures that each user has their own pubsub channel and it creates a controller for the actual consumer so that I do not have to pass user_id and other handy parameters all the time when I need a specific resource.\n\n```\nclass ConnectionConsumer:\n __redis: aioredis.Redis\n\n def __init__(self):\n self.__redis = aioredis.from_url(settings.ws_redis_url, encoding='utf-8', decode_responses=True)\n\n async def __send_json(self, obj: dict, websocket: WebSocket):\n await websocket.send_json(obj)\n\n async def connect(self, *, user_id: UUID4, websocket: WebSocket, pubsub: PubSub):\n # Accept connection if authorization is successful, set the user online and subscribe to its channel layer\n await websocket.accept()\n await self.__redis.set(f\"status:{user_id}\", \"1\") # status:UUID4 (means online)\n await pubsub.subscribe(f\"channel:{user_id}\") # subscribe to itself's channel\n\n async def disconnect(self, *, user_id: UUID4, websocket: WebSocket, pubsub: PubSub):\n # Gracefully disconnect from the websocket and remove the channel layer from pubsub\n await self.__redis.delete(f\"status:{user_id}\")\n await pubsub.unsubscribe(f\"channel:{user_id}\")\n await pubsub.close()\n await self.__redis.close()\n await websocket.close()\n```\n\nAnd here is the actual consumer which is called from the service that context manager returns.\n\n```\nCONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS\n4ed80g7fb093 s_be 1.77% 76.09MiB / 15.29GiB 0.49% 37.3kB / 21.1kB 0B / 0B 7\n```\n\nThis is the `docker stats` for the container when only consumer is handled\n\n```\nCONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS\n4ed80g7fb093 s_be 100.36% 76.08MiB / 15.29GiB 0.49% 42.9kB / 25.7kB 0B / 0B 7\n```\n\nAnd this is the `docker stats` for the container when both producer and consumer handlers are running\n\nI have tried to split the connections as well but I have the same issue.\n\n========================================\n\nTop Answer:\nI know this is pretty old question, but I also got similar problem.\n\nThe issue is that `await pubsub.get_message` uses `timeout=0.0` param by default, which causes \"infinite polling\" and high CPU usage.\n\nYou can specify timeout argument (it must be a \"seconds\" float) so the system will wait before returning. Also, you can pass `timeout=None` to make `get_message` function to wait indefinitely for next message.\n\n```\nmessage = await pubsub.get_message(\n ignore_subscribe_messages=True, timeout=None\n) # This will wait for new message indefinitely\nif message:\n ...\n```\n\n========================================\n\nCode:\n```py\n# api.py\n\nasync def consumer_handler(service):\n \"\"\"Messages received on the websocket connection Consumer - (Publisher)\"\"\"\n try:\n while True:\n received_data = await service.websocket.receive_json()\n if received_data['event_type'] == \"online.users\":\n await service.get_online_user_status(received_data['role_id'])\n elif received_data['event_type'] == \"message.user\":\n await service.send_message(received_data['user_id'], received_data['content'])\n elif received_data['event_type'] == \"info\":\n await service.get_info()\n except WebSocketDisconnect:\n logger.debug(\"WebSocketDisconnect - consumer handler disconnected\")\n\nasync def producer_handler(service):\n \"\"\"Messages generated at the backend to send to the websocket Producer - (Subscriber)\"\"\"\n try:\n while True:\n if service.pubsub.subscribed:\n message = await service.pubsub.get_message(ignore_subscribe_messages=True)\n if message:\n await service.websocket.send_json(message['data'].decode())\n except (ConnectionClosedOK, aioredis.exceptions.ConnectionError) as e:\n logger.debug(f\"{e.__class__}\", \"producer handler disconnected\")\n\n\n@chat_app.websocket(\"/\")\nasync def websocket_endpoint(websocket: WebSocket,\n current_user: User = Depends(is_authenticated_ws)):\n if not current_user:\n return\n\n async with ConnectionContextManager(user_id=current_user.id, websocket=websocket) as service:\n producer_task = asyncio.ensure_future(producer_handler(service))\n consumer_task = asyncio.ensure_future(consumer_handler(service))\n done, pending = await asyncio.wait(\n [consumer_task, producer_task],\n return_when=asyncio.FIRST_COMPLETED\n )\n for task in pending:\n task.cancel()\n```\n\n```py\n#websocket_utils.py\n\nclass WebsocketService:\n \"\"\"\n This acts like a service for websocket, is returned within the context manager\n this class is used to not interact with consumer directly, instead interact it with the manager\n \"\"\"\n\n def __init__(self, *, user_id: UUID4, websocket: WebSocket, pubsub: PubSub):\n self.user_id = user_id\n self.websocket = websocket\n self.pubsub = pubsub\n\n async def get_online_user_status(self, role_id):\n await consumer.online_user_status_per_role(role_id, self.websocket)\n\n async def send_message(self, user_id: UUID4, content: str):\n await consumer.send_message_to_user(user_id=user_id,\n message=content,\n websocket=self.websocket)\n\n async def get_info(self):\n await consumer.fetch_info(self.websocket)\n\n\nclass ConnectionContextManager:\n \"\"\"\n This context manager handles the websocket connection\n on enter, it returns a controller for the websocket events\n \"\"\"\n\n websocket_service: WebsocketService\n\n def __init__(self, *, user_id: UUID4, websocket: WebSocket):\n self.websocket_service = WebsocketService(user_id=user_id,\n websocket=websocket,\n pubsub=websocket.app.redis.pubsub())\n\n async def __aenter__(self):\n logger.debug(\"Context manager enter\")\n await consumer.connect(\n user_id=self.websocket_service.user_id,\n websocket=self.websocket_service.websocket,\n pubsub=self.websocket_service.pubsub\n )\n return self.websocket_service\n\n async def __aexit__(self, exc_type, exc_val, exc_tb) -> None:\n await consumer.disconnect(\n user_id=self.websocket_service.user_id,\n pubsub=self.websocket_service.pubsub,\n websocket=self.websocket_service.websocket,\n )\n logger.debug(\"Context manager exit\")\n```\n\n```py\nclass ConnectionConsumer:\n __redis: aioredis.Redis\n\n def __init__(self):\n self.__redis = aioredis.from_url(settings.ws_redis_url, encoding='utf-8', decode_responses=True)\n\n async def __send_json(self, obj: dict, websocket: WebSocket):\n await websocket.send_json(obj)\n\n async def connect(self, *, user_id: UUID4, websocket: WebSocket, pubsub: PubSub):\n # Accept connection if authorization is successful, set the user online and subscribe to its channel layer\n await websocket.accept()\n await self.__redis.set(f\"status:{user_id}\", \"1\") # status:UUID4 (means online)\n await pubsub.subscribe(f\"channel:{user_id}\") # subscribe to itself's channel\n\n async def disconnect(self, *, user_id: UUID4, websocket: WebSocket, pubsub: PubSub):\n # Gracefully disconnect from the websocket and remove the channel layer from pubsub\n await self.__redis.delete(f\"status:{user_id}\")\n await pubsub.unsubscribe(f\"channel:{user_id}\")\n await pubsub.close()\n await self.__redis.close()\n await websocket.close()\n```\n\n```bash\nCONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS\n4ed80g7fb093 s_be 1.77% 76.09MiB / 15.29GiB 0.49% 37.3kB / 21.1kB 0B / 0B 7\n```\n\n```bash\nCONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS\n4ed80g7fb093 s_be 100.36% 76.08MiB / 15.29GiB 0.49% 42.9kB / 25.7kB 0B / 0B 7\n```\n\n```text\ndocker stats\n```\n\n```text\ndocker stats\n```\n\n```py\n@logger.catch\nasync def producer_handler(service):\n \"\"\"Messages generated at the backend to send to the websocket Producer - (Subscriber)\"\"\"\n try:\n while True:\n if service.pubsub.subscribed:\n async for message in service.pubsub.listen():\n if message['type'] == \"subscribe\": continue\n await service.websocket.send_text(message['data'])\n except (ConnectionClosedOK, aioredis.exceptions.ConnectionError) as e:\n sentry_sdk.capture_exception(e)\n logger.debug(f\"{e.__class__}\", \"producer handler disconnected\")\n```\n\n```text\nlisten()\n```\n\n```text\nget_message()\n```\n\n```text\nyield\n```\n\n```text\nawait sleep()\n```\n\n```py\nmessage = await pubsub.get_message(\n ignore_subscribe_messages=True, timeout=None\n) # This will wait for new message indefinitely\nif message:\n ...\n```\n\n```text\nawait pubsub.get_message\n```\n\n```text\ntimeout=0.0\n```\n\n```text\ntimeout=None\n```\n\n```text\nget_message\n```\n\n========================================\n\nComments:\n- Hey, thanks for the reply, yeah this issue is old. I actually solved this the next day but I forgot to edit the question to include the solution. I have just edited it now and you could see what I did to nullify that issue.","metadata":{"transformedAt":"2026-08-18T18:32:29.154Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":17,"totalLines":384,"estimatedTokens":3431}}663{"id":"stack-67403995","source":"stackoverflow","questionId":67403995,"title":"Difference between connecting to the database in app.on_event('startup') vs in a dependency in FastAPI","tags":["python","database","python-asyncio","fastapi"],"text":"Title: Difference between connecting to the database in app.on_event('startup') vs in a dependency in FastAPI\nTags: python, database, python-asyncio, fastapi\nSource: Stack Overflow\n\nQuestion:\nIn Tiangolo's FastAPI, it states that you can create a persistent database connection by using a dependency\n\nhttps://fastapi.tiangolo.com/tutorial/sql-databases/#create-a-dependency\n\nHowever, in the Async database docs, the database is connected to in app startup\n\nhttps://fastapi.tiangolo.com/advanced/async-sql-databases/#connect-and-disconnect\n\nThis same pattern is followed in the encode/databases docs\n\nhttps://www.encode.io/databases/connections_and_transactions/\n\nWhich is the right pattern? It seems to me that using dependencies, one database connection would be created per API call, while connecting the the database during startup would establish one database connection per worker. If this is correct, connecting to the database on startup would be far superior.\n\n**What the difference between the two and is one better?**\n\n========================================\n\nCode:\n```text\nSession\n```\n\n```text\nsession\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.154Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":2,"totalLines":31,"estimatedTokens":280}}664{"id":"stack-70333286","source":"stackoverflow","questionId":70333286,"title":"GitLab health endpoint before integrating code","tags":["deployment","gitlab","fastapi","health-check"],"text":"Title: GitLab health endpoint before integrating code\nTags: deployment, gitlab, fastapi, health-check\nSource: Stack Overflow\n\nQuestion:\nI’m new to deploying ML models and I want to deploy a model that contains several modules, each of which consist of “folders” containing some data files, .py scripts and a Python notebook.\n\nI created a project in GitLab and I’m trying to tutorials on FastAPI since this is what I’m gonna be using. But I’ve been told that before I start integrating the code, I need to set up a health endpoint.\n\nI know about the request `curl \"https://gitlab.example.com/-/health\"`, but do I need to set up anything? Is there anything else I need to do for the project setup before doing the `requirements.txt`, building the skeleton of the application etc.?\n\n========================================\n\nCode:\n```text\ncurl \"https://gitlab.example.com/-/health\"\n```\n\n```text\nrequirements.txt\n```\n\n```py\n# main.py\n\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/health\")\nasync def root():\n return {\"message\": \"Alive!\"}\n```\n\n```py\n# app.routers.health.py\nfrom fastapi import APIRouter, status, Depends\nfrom fastapi_health import health\n\nfrom app.internal.health import healthy_condition, sick_condition\n\nrouter = APIRouter(\n tags=[\"healthcheck\"],\n responses={404: {\"description\": \"not found\"}},\n)\n\n\n@router.get('/health', status_code=status.HTTP_200_OK)\ndef perform_api_healthcheck(health_endpoint=Depends(health([healthy_condition, sick_condition]))):\n return health_endpoint\n```\n\n```py\n# app.internal.health.py\ndef healthy_condition(): # just for testing puposes\n return {\"database\": \"online\"}\n\n\ndef sick_condition(): # just for testing puposes\n return True\n```\n\n========================================\n\nComments:\n- *Git* does not have a health endpoint. Git*Lab* may offer one, but that's GitLab, not Git. (Git, by itself, does not have endpoints. It doesn't do that sort of thing.)\n- @torek Sorry, typo in the title, but in the post I mentioned that specific request in GitLab. But I really don’t understand how do I deal with health endpoints when setting up a project, before integrating the code.\n- I think I only need to return the status of the app (if it runs or not), so something like @app.get(“/“) async def root(): return {“message”: “App is working”}. But I don’t know how to implement this. I need a config file? I’m very new to this.\n- @johnnydoe i have update the answer","metadata":{"transformedAt":"2026-08-18T18:32:29.154Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":69,"estimatedTokens":609}}665{"id":"stack-68033119","source":"stackoverflow","questionId":68033119,"title":"Get data from a dropdown menu with FastAPI","tags":["python","drop-down-menu","jinja2","fastapi","starlette"],"text":"Title: Get data from a dropdown menu with FastAPI\nTags: python, drop-down-menu, jinja2, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nIn a FastAPI project, you can easily get data from a HTML form to the back-end. There are built-in ways to get data from a text input, a file upload, etc. However, dropdown menus don't seem to work in my project. FastAPI developer Tiangolo has addressed the issue after being requested and made a tutorial page including dropdown menus. I tried to the same steps as him but I cannot get data from a dropdown menu into my backend.\n\nMy code looks like this:\n\n- `view.py` : contains the enum with the dropdown values, and generates the html template.\n\n```\nclass dropdownChoices(str, Enum):\n water = \"WATER\"\n fire = \"FIRE\"\n electric = \"ELECTRIC\"\n grass = \"GRASS\"\n donut = \"DONUT\"\n\n@router.get('/upload')\ndef upload(request: Request):\n return templates.TemplateResponse('upload.html', context={'request': request, 'choices': [e.value for e in dropdownChoices]})\n```\n\n- `upload.html` : the template that will display my form, containing the dropdown menu.\n\n```\n\n \n Choose:\n \n {% for choice in choices %}\n {{choice}}\n \n {% endfor %}\n \n \n \n \n Choose Upload File:\n \n Overwrite existing\n \n Upload\n\n```\n\n- `main.py` : handles data from the form.\n\n```\n# Gets data from upload.html\n@app.post(\"/upload\")\nasync def handle_form(request: Request,\n choice: str = \"WATER\",\n upload_file: UploadFile = File(...),\n overwrite_existing: bool = Form(False)):\n print(choice) #does NOT work: always print default (\"WATER\")\n print(overwrite_existing) #Works, prints true or false depending on input\n contents = await upload_file.file.read() #Works, file is later read etc\n return templates.TemplateResponse('upload.html', context={'request': request,\n 'choices': [e.value for e in view.dropdownChoices]})\n```\n\nI feel like I have followed the tutorial thoroughly, yet I **always** get the default choice. If I don't put a default choice in my `handle_form()` method, I get nothing at all.\nI don't understand why the user's choice form the dropdown menu is not transmitted like the rest.\n\n========================================\n\nTop Answer:\nYour name in the form is `dropdown_choices`. Your name in your FastAPI endpoint definition is `choice`. These need to be identical. You also want to tell FastAPI that this is a Form field as well (as you did with your checkbox):\n\n```\nchoice: str = Form(\"WATER\"),\n```\n\nYou should also wrap the option value in `\"\"`:\n\n```\n\n```\n\nThere is nothing magic about select boxes; data gets submitted in the usual ways - either through `GET` or through `POST`.\n\n========================================\n\nCode:\n```text\nclass dropdownChoices(str, Enum):\n water = \"WATER\"\n fire = \"FIRE\"\n electric = \"ELECTRIC\"\n grass = \"GRASS\"\n donut = \"DONUT\"\n\n@router.get('/upload')\ndef upload(request: Request):\n return templates.TemplateResponse('upload.html', context={'request': request, 'choices': [e.value for e in dropdownChoices]})\n```\n\n```text\n<form action=\"/upload\" method=\"post\" enctype=\"multipart/form-data\">\n <div class=\"form-group\">\n <label for=\"choices_dropdown\">Choose:</label>\n <select id=\"choices_dropdown\" name=\"dropdown_choices\">\n {% for choice in choices %}\n <option value={{choice}}>{{choice}}</option>\n <!-- The choices are correctly displayed in the dropdown menu -->\n {% endfor %}\n </select>\n </div>\n <!-- More form actions including file upload and checkbox. These work. -->\n <div class=\"form-group\">\n <label for=\"upload_file\">Choose Upload File:</label>\n <input type=\"file\" class=\"form-control-file\" name='upload_file' id=\"upload_file\">\n <input class=\"form-check-input\" type=\"checkbox\" name='overwrite_existing' id=\"flexCheckChecked\"> Overwrite existing\n </div>\n <button id=\"upload\" type='submit' class=\"btn btn-primary\">Upload</button>\n</form>\n```\n\n```text\n# Gets data from upload.html\n@app.post(\"/upload\")\nasync def handle_form(request: Request,\n choice: str = \"WATER\",\n upload_file: UploadFile = File(...),\n overwrite_existing: bool = Form(False)):\n print(choice) #does NOT work: always print default (\"WATER\")\n print(overwrite_existing) #Works, prints true or false depending on input\n contents = await upload_file.file.read() #Works, file is later read etc\n return templates.TemplateResponse('upload.html', context={'request': request,\n 'choices': [e.value for e in view.dropdownChoices]})\n```\n\n```text\nview.py\n```\n\n```text\nupload.html\n```\n\n```text\nmain.py\n```\n\n```text\nhandle_form()\n```\n\n```text\nchoice: str = \"WATER\",\n```\n\n```text\n<select id=\"choices_dropdown\" name=\"dropdown_choices\">\n```\n\n```text\nasync def handle_form(request: Request,\n dropdown_choices: dropdownChoices = Form(dropdownChoices.water),\n upload_file: UploadFile = File(...),\n overwrite_existing: bool = Form(False)):\n```\n\n```text\nchoice\n```\n\n```text\nstr\n```\n\n```text\n\"WATER\"\n```\n\n```text\ndropdown_choices\n```\n\n```text\nchoice: str = Form(\"WATER\"),\n```\n\n```text\n<option value=\"{{choice}}\">\n```\n\n```text\ndropdown_choices\n```\n\n```text\nchoice\n```\n\n```text\n\"\"\n```\n\n```text\nGET\n```\n\n```text\nPOST\n```\n\n========================================\n\nComments:\n- Good catch, unfortunately this is just a typo I made while anonymizing my code\n- You're right, it works now! Thank you very much. My error was actually in your second paragraph, this: `dropdown_choices: dropdownChoices = Form(dropdownChoices.water)`. I now set the argument name to an enum and it works.","metadata":{"transformedAt":"2026-08-18T18:32:29.154Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":21,"totalLines":214,"estimatedTokens":1425}}666{"id":"stack-67800370","source":"stackoverflow","questionId":67800370,"title":"Recursive logging issue when using Opencensus with FastAPI","tags":["python","logging","azure-application-insights","fastapi","opencensus"],"text":"Title: Recursive logging issue when using Opencensus with FastAPI\nTags: python, logging, azure-application-insights, fastapi, opencensus\nSource: Stack Overflow\n\nQuestion:\nI have a problem with my implementation of Opencensus, logging in Python and FastAPI. I want to log incomming requests to Application Insights in Azure, so I added a FastAPI middleware to my code following the Microsoft docs and this Github post:\n\n```\npropagator = TraceContextPropagator()\n\n@app.middleware('http')\nasync def middleware_opencensus(request: Request, call_next):\n tracer = Tracer(\n span_context=propagator.from_headers(request.headers),\n exporter=AzureExporter(connection_string=os.environ['APPLICATION_INSIGHTS_CONNECTION_STRING']),\n sampler=AlwaysOnSampler(),\n propagator=propagator)\n\n with tracer.span('main') as span:\n span.span_kind = SpanKind.SERVER\n tracer.add_attribute_to_current_span(HTTP_HOST, request.url.hostname)\n tracer.add_attribute_to_current_span(HTTP_METHOD, request.method)\n tracer.add_attribute_to_current_span(HTTP_PATH, request.url.path)\n tracer.add_attribute_to_current_span(HTTP_ROUTE, request.url.path)\n tracer.add_attribute_to_current_span(HTTP_URL, str(request.url))\n\n response = await call_next(request)\n tracer.add_attribute_to_current_span(HTTP_STATUS_CODE, response.status_code)\n\n return response\n```\n\nThis works great when running local, and all incomming requests to the api are logged to Application Insights. Since having Opencensus implemented however, when deployed in a Container Instance on Azure, after a couple of days (approximately 3) an issue arises where it looks like some recursive logging issue happens (+30.000 logs per second!), i.a. stating `Queue is full. Dropping telemetry`, before finally crashing after a few hours of mad logging:\n\nhttps://i.sstatic.net/U1cqd.png\n\nOur `logger.py` file where we define our logging handlers is as follows:\n\n```\nimport logging.config\nimport os\nimport tqdm\nfrom pathlib import Path\nfrom opencensus.ext.azure.log_exporter import AzureLogHandler\n\nclass TqdmLoggingHandler(logging.Handler):\n \"\"\"\n Class for enabling logging during a process with a tqdm progress bar.\n Using this handler logs will be put above the progress bar, pushing the\n process bar down instead of replacing it.\n \"\"\"\n def __init__(self, level=logging.NOTSET):\n super().__init__(level)\n self.formatter = logging.Formatter(fmt='%(asctime)s %(levelname)s: %(message)s',\n datefmt='%d-%m-%Y %H:%M:%S')\n\n def emit(self, record):\n try:\n msg = self.format(record)\n tqdm.tqdm.write(msg)\n self.flush()\n except (KeyboardInterrupt, SystemExit):\n raise\n except:\n self.handleError(record)\n\nlogging_conf_path = Path(__file__).parent\nlogging.config.fileConfig(logging_conf_path / 'logging.conf')\n\nlogger = logging.getLogger(__name__)\nlogger.addHandler(TqdmLoggingHandler(logging.DEBUG)) # Add tqdm handler to root logger to replace the stream handler\nif os.getenv('APPLICATION_INSIGHTS_CONNECTION_STRING'):\n logger.addHandler(AzureLogHandler(connection_string=os.environ['APPLICATION_INSIGHTS_CONNECTION_STRING']))\n\nwarning_level_loggers = ['urllib3', 'requests']\nfor lgr in warning_level_loggers:\n logging.getLogger(lgr).setLevel(logging.WARNING)\n```\n\nDoes anyone have any idea on what could be the cause of this issue, or have people encountered similar issues? I don't know what the 'first' error log is due to the fast amount of logging.\n\nPlease let me know if additional information is required.\n\nThanks in advance!\n\n========================================\n\nCode:\n```text\npropagator = TraceContextPropagator()\n\n@app.middleware('http')\nasync def middleware_opencensus(request: Request, call_next):\n tracer = Tracer(\n span_context=propagator.from_headers(request.headers),\n exporter=AzureExporter(connection_string=os.environ['APPLICATION_INSIGHTS_CONNECTION_STRING']),\n sampler=AlwaysOnSampler(),\n propagator=propagator)\n\n with tracer.span('main') as span:\n span.span_kind = SpanKind.SERVER\n tracer.add_attribute_to_current_span(HTTP_HOST, request.url.hostname)\n tracer.add_attribute_to_current_span(HTTP_METHOD, request.method)\n tracer.add_attribute_to_current_span(HTTP_PATH, request.url.path)\n tracer.add_attribute_to_current_span(HTTP_ROUTE, request.url.path)\n tracer.add_attribute_to_current_span(HTTP_URL, str(request.url))\n\n response = await call_next(request)\n tracer.add_attribute_to_current_span(HTTP_STATUS_CODE, response.status_code)\n\n return response\n```\n\n```text\nimport logging.config\nimport os\nimport tqdm\nfrom pathlib import Path\nfrom opencensus.ext.azure.log_exporter import AzureLogHandler\n\n\nclass TqdmLoggingHandler(logging.Handler):\n \"\"\"\n Class for enabling logging during a process with a tqdm progress bar.\n Using this handler logs will be put above the progress bar, pushing the\n process bar down instead of replacing it.\n \"\"\"\n def __init__(self, level=logging.NOTSET):\n super().__init__(level)\n self.formatter = logging.Formatter(fmt='%(asctime)s <%(name)s> %(levelname)s: %(message)s',\n datefmt='%d-%m-%Y %H:%M:%S')\n\n def emit(self, record):\n try:\n msg = self.format(record)\n tqdm.tqdm.write(msg)\n self.flush()\n except (KeyboardInterrupt, SystemExit):\n raise\n except:\n self.handleError(record)\n\n\nlogging_conf_path = Path(__file__).parent\nlogging.config.fileConfig(logging_conf_path / 'logging.conf')\n\nlogger = logging.getLogger(__name__)\nlogger.addHandler(TqdmLoggingHandler(logging.DEBUG)) # Add tqdm handler to root logger to replace the stream handler\nif os.getenv('APPLICATION_INSIGHTS_CONNECTION_STRING'):\n logger.addHandler(AzureLogHandler(connection_string=os.environ['APPLICATION_INSIGHTS_CONNECTION_STRING']))\n\nwarning_level_loggers = ['urllib3', 'requests']\nfor lgr in warning_level_loggers:\n logging.getLogger(lgr).setLevel(logging.WARNING)\n```\n\n```text\nQueue is full. Dropping telemetry\n```\n\n```text\nlogger.py\n```\n\n```text\nif os.getenv('APPLICATION_INSIGHTS_CONNECTION_STRING'):\n from azure.monitor.opentelemetry.exporter import AzureMonitorTraceExporter\n from opentelemetry import trace\n from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor\n from opentelemetry.propagate import extract\n from opentelemetry.sdk.resources import SERVICE_NAME, SERVICE_NAMESPACE, SERVICE_INSTANCE_ID, Resource\n from opentelemetry.sdk.trace import TracerProvider\n from opentelemetry.sdk.trace.export import BatchSpanProcessor\n\n provider = TracerProvider()\n\n processor = BatchSpanProcessor(AzureMonitorTraceExporter.from_connection_string(\n os.environ['APPLICATION_INSIGHTS_CONNECTION_STRING']))\n provider.add_span_processor(processor)\n trace.set_tracer_provider(provider)\n\n FastAPIInstrumentor.instrument_app(app)\n```\n\n```text\n# These come still from Opencensus for convenience\nHTTP_HOST = COMMON_ATTRIBUTES['HTTP_HOST']\nHTTP_METHOD = COMMON_ATTRIBUTES['HTTP_METHOD']\nHTTP_PATH = COMMON_ATTRIBUTES['HTTP_PATH']\nHTTP_ROUTE = COMMON_ATTRIBUTES['HTTP_ROUTE']\nHTTP_URL = COMMON_ATTRIBUTES['HTTP_URL']\nHTTP_STATUS_CODE = COMMON_ATTRIBUTES['HTTP_STATUS_CODE']\n\nprovider = TracerProvider()\n\nprocessor = BatchSpanProcessor(AzureMonitorTraceExporter.from_connection_string(\n os.environ['APPLICATION_INSIGHTS_CONNECTION_STRING']))\nprovider.add_span_processor(processor)\ntrace.set_tracer_provider(provider)\n\n@app.middleware('http')\nasync def middleware_opentelemetry(request: Request, call_next):\n tracer = trace.get_tracer(__name__)\n\n with tracer.start_as_current_span('main',\n context=extract(request.headers),\n kind=trace.SpanKind.SERVER) as span:\n span.set_attributes({\n HTTP_HOST: request.url.hostname,\n HTTP_METHOD: request.method,\n HTTP_PATH: request.url.path,\n HTTP_ROUTE: request.url.path,\n HTTP_URL: str(request.url)\n })\n\n response = await call_next(request)\n span.set_attribute(HTTP_STATUS_CODE, response.status_code)\n\n return response\n```\n\n```text\nenable_local_storage=False\n```\n\n```text\nAzureLogHandler\n```\n\n```text\nlogger.py\n```\n\n========================================\n\nComments:\n- Hit a similar issue, did you get it resolved?\n- @MarcusRobinson we just decided to revisit this issue this week and we found some other threads and proposed solutions to mitigate this issue. I added our findings in the answer below. Hope it helps!","metadata":{"transformedAt":"2026-08-18T18:32:29.154Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":238,"estimatedTokens":2145}}667{"id":"stack-66222657","source":"stackoverflow","questionId":66222657,"title":"fastapi + aiomysql connection pool stuck after 10 calls","tags":["python","python-asyncio","fastapi","aiopg","aio-mysql"],"text":"Title: fastapi + aiomysql connection pool stuck after 10 calls\nTags: python, python-asyncio, fastapi, aiopg, aio-mysql\nSource: Stack Overflow\n\nQuestion:\nWhy aiomysql connection pool stuck after N calls? (N is the `maxsize` number of connection. Tried the default N=10 and N=3)\n\nI thought the acquired connections are automatically closed on exit with `async with`.\n\nHere's the minimal script to reproduce:\n\n```\nfrom fastapi import FastAPI\nimport aiomysql\nimport secret\n\napp = FastAPI()\n\n@app.on_event(\"startup\")\nasync def _startup():\n app.state.pool = await aiomysql.create_pool(host=secret.DB_URL, port=3306, user=secret.DB_USERNAME, password=secret.DB_PASSWORD, db=secret.DB_DATABASE)\n print(\"startup done\")\n\nasync def _get_query_with_pool(pool):\n async with await pool.acquire() as conn:\n async with conn.cursor(aiomysql.DictCursor) as cur:\n await cur.execute(\"SELECT 1\")\n return await cur.fetchall()\n\n@app.get(\"/v1/get_data\")\nasync def _get_data():\n return await _get_query_with_pool(app.state.pool)\n\nif __name__ == \"__main__\":\n import uvicorn\n\n uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n```\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI\nimport aiomysql\nimport secret\n\napp = FastAPI()\n\n@app.on_event(\"startup\")\nasync def _startup():\n app.state.pool = await aiomysql.create_pool(host=secret.DB_URL, port=3306, user=secret.DB_USERNAME, password=secret.DB_PASSWORD, db=secret.DB_DATABASE)\n print(\"startup done\")\n\nasync def _get_query_with_pool(pool):\n async with await pool.acquire() as conn:\n async with conn.cursor(aiomysql.DictCursor) as cur:\n await cur.execute(\"SELECT 1\")\n return await cur.fetchall()\n\n@app.get(\"/v1/get_data\")\nasync def _get_data():\n return await _get_query_with_pool(app.state.pool)\n\n\nif __name__ == \"__main__\":\n import uvicorn\n\n uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n```\n\n```text\nmaxsize\n```\n\n```text\nasync with\n```\n\n```py\nasync def _get_query_with_pool(pool):\n async with await pool.acquire() as conn:\n async with conn.cursor(aiomysql.DictCursor) as cur:\n await cur.execute(\"SELECT 1\")\n return await cur.fetchall()\n```\n\n```py\nasync def _get_query_with_pool(pool):\n async with pool.acquire() as conn:\n async with conn.cursor(aiomysql.DictCursor) as cur:\n await cur.execute(\"SELECT 1\")\n return await cur.fetchall()\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.154Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":94,"estimatedTokens":600}}668{"id":"stack-66514343","source":"stackoverflow","questionId":66514343,"title":"How to define a separate response_model for HTTP 400 errors?","tags":["fastapi"],"text":"Title: How to define a separate response_model for HTTP 400 errors?\nTags: fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm forced to set all values in a response_model as Optional.\n\n```\nclass ConnectOut(BaseModel):\n product_id: Optional[str]\n expires_at: Optional[datetime]\n detail: Optional[ErrorType]\n```\n\nIf I don't do that the HTTP400 path below throws validation errors, because product_id and expires_at won't be provided in case of a 400 error.\n\n```\n@router_connect.post(\"/\", status_code=200, response_model=ConnectOut)\nasync def connect(\n body: ConnectIn,\n response: Response,\n):\n if account.is_banned:\n response.status_code = status.HTTP_400_BAD_REQUEST\n return {\"detail\": ErrorType.USER_IS_BANNED}\n```\n\nIs there a way to define a response_model for success and response_model for 400 Error messages?\n\nMany Thanks,\n\n========================================\n\nCode:\n```text\nclass ConnectOut(BaseModel):\n product_id: Optional[str]\n expires_at: Optional[datetime]\n detail: Optional[ErrorType]\n```\n\n```text\n@router_connect.post(\"/\", status_code=200, response_model=ConnectOut)\nasync def connect(\n body: ConnectIn,\n response: Response,\n):\n if account.is_banned:\n response.status_code = status.HTTP_400_BAD_REQUEST\n return {\"detail\": ErrorType.USER_IS_BANNED}\n```\n\n```py\nfrom fastapi import HTTPException\n...\nraise HTTPException(status_code=400, detail=\"Example bad request.\")\n```\n\n```py\n@example_router.post(\n \"/example\",\n response_model=schemas.Example,\n status_code=201,\n responses={200: {\"model\": schemas.Example}, 400: {\"model\": schemas.HTTPError}},\n)\ndef create_example(...) -> models.Example:\n ...\n raise HTTPException(status_code=400, detail=\"Example bad request.\")\n```\n\n```py\nfrom pydantic import BaseModel\n\nclass HTTPError(BaseModel):\n \"\"\"\n HTTP error schema to be used when an `HTTPException` is thrown.\n \"\"\"\n\n detail: str\n```\n\n```text\nraise\n```\n\n```text\nHTTPException\n```\n\n```text\nHTTPError\n```\n\n========================================\n\nComments:\n- Yes, I needed it for Swagger/Documentation purposes. This is the perfect solution. I can't thank you enough! Thanks!","metadata":{"transformedAt":"2026-08-18T18:32:29.154Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":8,"totalLines":97,"estimatedTokens":535}}669{"id":"stack-67381171","source":"stackoverflow","questionId":67381171,"title":"Starlette JSONResponse into Pydantic parse_obj_as","tags":["python","fastapi","pydantic","starlette"],"text":"Title: Starlette JSONResponse into Pydantic parse_obj_as\nTags: python, fastapi, pydantic, starlette\nSource: Stack Overflow\n\nQuestion:\nWorking with fastapi and having a function that returns created JSONResponse. My goal is to create custom 200 response and put it into Pydantic `parse_obj_as` with an expected BaseModel.\n\nIs there a way of getting back the JSONResponse data? Or there any workaround? Thanks!\n\n```\nfrom starlette.responses import JSONResponse\n\ndef func():\n model_id = 0\n\n resp = JSONResponse(\n {\"detail\": f\"Model {model_id} created\", \"HTTPStatusCode\": 200},\n status_code=200,\n )\n return parse_obj_as(, MyBaseModel)\n```\n\nBaseModel:\n\n```\nfrom pydantic.types import PositiveInt\nfrom __future__ import annotations, generator_stop\nfrom pydantic import BaseModel\n\nclass MyBaseModel(BaseModel):\n \"\"\"\n Docstring\n \"\"\"\n\n detail: str\n HTTPStatusCode: PositiveInt\n```\n\n========================================\n\nCode:\n```text\nfrom starlette.responses import JSONResponse\n\n\ndef func():\n model_id = 0\n\n resp = JSONResponse(\n {\"detail\": f\"Model {model_id} created\", \"HTTPStatusCode\": 200},\n status_code=200,\n )\n return parse_obj_as(<here I need resp data>, MyBaseModel)\n```\n\n```text\nfrom pydantic.types import PositiveInt\nfrom __future__ import annotations, generator_stop\nfrom pydantic import BaseModel\n\nclass MyBaseModel(BaseModel):\n \"\"\"\n Docstring\n \"\"\"\n\n detail: str\n HTTPStatusCode: PositiveInt\n```\n\n```text\nparse_obj_as\n```\n\n```text\nimport json\nfrom pydantic.types import PositiveInt\nfrom starlette.responses import JSONResponse\nfrom pydantic import BaseModel, parse_obj_as\n\n\nclass MyBaseModel(BaseModel):\n \"\"\"\n Docstring\n \"\"\"\n detail: str\n HTTPStatusCode: PositiveInt\n\n\ndef func():\n model_id = 0\n resp = JSONResponse(\n {\"detail\": f\"Model {model_id} created\", \"HTTPStatusCode\": 200}, status_code=200,\n )\n return parse_obj_as(MyBaseModel, json.loads(resp.body))\n\n\nret = func()\n```\n\n```text\ndetail='Model 0 created' HTTPStatusCode=200\n```\n\n```text\nparse_obj_as\n```\n\n```text\nresponse.body\n```\n\n```text\njson.loads()\n```\n\n========================================\n\nComments:\n- Could you please `MyBaseModel`\n- @PouyaEsmaeili Added the BaseModel.\n- Working great mate, thanks a lot for help!","metadata":{"transformedAt":"2026-08-18T18:32:29.154Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":8,"totalLines":121,"estimatedTokens":566}}670{"id":"stack-67257307","source":"stackoverflow","questionId":67257307,"title":"Fastapi/Tortoise early model init","tags":["python","fastapi","tortoise-orm"],"text":"Title: Fastapi/Tortoise early model init\nTags: python, fastapi, tortoise-orm\nSource: Stack Overflow\n\nQuestion:\nI have the following implementation with fastapi.\n\nMy current problem is that I can't for the life of me do an `early init` on the tortoise models to get the relationship back in the schema.\n\nI've tried dumping the following line basically everywhere and it just doesn't seem to work.\n\n```\nTortoise.init_models([\"models.user\", \"models.group\"], \"models\")\n```\n\ni've also tried using `prefetch_related` this way but that doesn't work either\n\n```\nGetGroup.from_queryset(Group.get(id=3).prefetch_related('owner'))\n```\n\nI've been googling around for hours and haven't found a concrete answer/way to get this to properly work.\n\nFolder structure:\n\n```\napp\n│ main.py\n└───database\n│ │ database.py\n└───models\n| │ user.py\n| │ group.py\n└───routers\n| │ user_router.py\n| │ group_router.py\n└───services\n| │ auth.py\n```\n\nmain.py\n\n```\nfrom fastapi import FastAPI\nfrom database.database import init_db\nfrom routers.user_router import router as UserRouter\nfrom routers.group_router import router as GroupRouter\n\n# Instantiate the Application\napp = FastAPI(title=\"test\", root_path=\"/api/\")\n\n# Include the Routers\napp.include_router(UserRouter, tags=[\"User\"], prefix=\"/user\")\napp.include_router(GroupRouter, tags=[\"Group\"], prefix=\"/group\")\n\n# Start DB Connection on Startup\n@app.on_event(\"startup\")\nasync def startup_event():\n init_db(app)\n```\n\ndatabase/database.py\n\n```\nfrom decouple import config\nfrom fastapi import FastAPI\nfrom tortoise import Tortoise\nfrom tortoise.contrib.fastapi import register_tortoise\n\ndef init_db(app: FastAPI) -> None:\n Tortoise.init_models([\"models.user\", \"models.group\"], \"models\")\n register_tortoise(\n app,\n db_url=f\"mysql://{config('MYSQL_USER')}:{config('MYSQL_PASSWORD')}@{config('MYSQL_HOST')}:{config('MYSQL_EXPOSE')}/{config('MYSQL_DB')}\",\n modules={\"models\": [\"models.user\",\n \"models.group\",\n ]},\n generate_schemas=False,\n add_exception_handlers=True,\n )\n\nTORTOISE_ORM = {\n \"connections\": {\"default\": f\"mysql://{config('MYSQL_USER')}:{config('MYSQL_PASSWORD')}@{config('MYSQL_HOST')}:{config('MYSQL_EXPOSE')}/{config('MYSQL_DB')}\"},\n \"apps\": {\n \"models\": {\n \"models\": [\"models.user\",\n \"models.group\",\n \"aerich.models\"],\n \"default_connection\": \"default\",\n },\n },\n}\n```\n\nmodels/user.py\n\n```\nfrom tortoise import fields\nfrom tortoise.models import Model\nfrom tortoise.contrib.pydantic import pydantic_model_creator\nfrom models.group import Group\n\nclass User(Model):\n # ##### Define Readonly Fields ##### #\n id = fields.BigIntField(pk=True)\n # ##### Define Normal Fields ##### #\n first_name = fields.CharField(max_length=50)\n last_name = fields.CharField(max_length=50)\n username = fields.CharField(max_length=50, unique=True)\n email = fields.CharField(max_length=50, unique=True)\n password = fields.CharField(max_length=128)\n # ##### Define O2M ##### #\n owned_groups: fields.ReverseRelation[Group]\n # ##### Define M2M ##### #\n groups: fields.ManyToManyRelation[Group]\n # ##### Define Time_Stamps ###### #\n created_at = fields.DatetimeField(auto_now_add=True)\n modified_at = fields.DatetimeField(auto_now=True)\n\n class Meta:\n table: str = 'users'\n\nAuthData = pydantic_model_creator(User)\nCreateUser = pydantic_model_creator(User, name=\"CreateUser\", exclude_readonly=True)\nUpdateUser = pydantic_model_creator(User, name=\"UpdateUser\", exclude_readonly=True, exclude=['password'])\nGetUser = pydantic_model_creator(User, name=\"GetUser\", exclude=['password'])\nChangeUserPassword = pydantic_model_creator(User, name=\"ChangeUserPassword\", exclude_readonly=True, include=['password'])\n```\n\nmodels/group.py\n\n```\nfrom tortoise import fields\nfrom tortoise.models import Model\nfrom tortoise.contrib.pydantic import pydantic_model_creator\n\nclass Group(Model):\n # ##### Define Readonly Fields ##### #\n id = fields.BigIntField(pk=True)\n # ##### Define Normal Fields ##### #\n name = fields.CharField(max_length=50, unique=True)\n # ##### Define O2M ##### #\n owner = fields.ForeignKeyField(\"models.User\", related_name=\"owned_groups\")\n # ##### Define M2M ##### #\n members = fields.ManyToManyField(\"models.User\", related_name=\"groups\")\n # ##### Define Time_Stamps ###### #\n created_at = fields.DatetimeField(auto_now_add=True)\n modified_at = fields.DatetimeField(auto_now=True)\n\n class Meta:\n table: str = 'groups'\n\nCreateGroup = pydantic_model_creator(Group, name=\"CreateGroup\", exclude_readonly=True, exclude=['members'])\nUpdateGroup = pydantic_model_creator(Group, name=\"UpdateGroup\", exclude_readonly=True, exclude=['members'])\nGetGroup = pydantic_model_creator(Group, name=\"GetGroup\")\n```\n\nrouters/group_router.py\n\n```\nfrom typing import List\nimport json\nfrom fastapi import HTTPException, APIRouter, Depends, status\nfrom models.user import User\nfrom models.group import Group, CreateGroup, UpdateGroup, GetGroup\nfrom tortoise.contrib.fastapi import HTTPNotFoundError\nfrom services.auth import current_user\n\n# Intialize Router\nrouter = APIRouter()\n\n# ###################### Define Routes ###################### #\n\n# Create A Group\n@router.post(\"/\", dependencies=[Depends(current_user)])\nasync def create_group(group: CreateGroup, user: User = Depends(current_user)):\n user = await user\n try:\n await Group.create(**group.dict(exclude_unset=True), owner_id=user.id)\n except Exception:\n raise HTTPException(\n status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,\n detail=\"Group Name Already Exists\"\n )\n return {\"Group Created Successfully\"}\n\n# Update A Group\n@router.put(\"/{group_id}\", dependencies=[Depends(current_user)], responses={404: {\"model\": HTTPNotFoundError}})\nasync def update_group(group_id: int, group: UpdateGroup, user: User = Depends(current_user)):\n user = await user\n group = await GetGroup.from_queryset_single(Group.get(id=group_id))\n return group\n if user.id == group.id:\n await Group.filter(id=group_id).update(**group.dict(exclude_unset=True))\n return {\"Group Successfully Updated\"}\n else:\n raise HTTPException(\n status_code=status.HTTP_406_NOT_ACCEPTABLE,\n detail=\"You can't edit a group unless you're the owner\"\n )\n\n# Get All Groups\n@router.get(\"/\", dependencies=[Depends(current_user)])\nasync def get_groups():\n return GetGroup.schema()\n```\n\nAs you can see that last line `GetGroup.schema()`, never returns the relationship.\n\nI tried capturing the logs while the container is starting and got the following\n\n```\n[2021-04-24 19:59:53 +0000] [1255] [INFO] Started server process [1255]\n[2021-04-24 19:59:53 +0000] [1255] [INFO] Waiting for application startup.\n[2021-04-24 19:59:53 +0000] [1255] [ERROR] Traceback (most recent call last):\nFile \"/usr/local/lib/python3.8/site-packages/tortoise/__init__.py\", line 358, in _discover_models\nmodule = importlib.import_module(models_path)\nFile \"/usr/local/lib/python3.8/importlib/__init__.py\", line 127, in import_module\nreturn _bootstrap._gcd_import(name[level:], package, level)\nFile \"\", line 1014, in _gcd_import\nFile \"\", line 991, in _find_and_load\nFile \"\", line 973, in _find_and_load_unlocked\nModuleNotFoundError: No module named 'a'\nDuring handling of the above exception, another exception occurred:\nTraceback (most recent call last):\nFile \"/usr/local/lib/python3.8/site-packages/starlette/routing.py\", line 526, in lifespan\nasync for item in self.lifespan_context(app):\nFile \"/usr/local/lib/python3.8/site-packages/starlette/routing.py\", line 467, in default_lifespan\nawait self.startup()\nFile \"/usr/local/lib/python3.8/site-packages/starlette/routing.py\", line 502, in startup\nawait handler()\nFile \"/app/main.py\", line 17, in startup_event\ninit_db(app)\nFile \"/app/database/database.py\", line 8, in init_db\nTortoise.init_models(\"app.models.user\", \"models\")\nFile \"/usr/local/lib/python3.8/site-packages/tortoise/__init__.py\", line 415, in init_models\napp_models += cls._discover_models(models_path, app_label)\nFile \"/usr/local/lib/python3.8/site-packages/tortoise/__init__.py\", line 360, in _discover_models\nraise ConfigurationError(f'Module \"{models_path}\" not found')\ntortoise.exceptions.ConfigurationError: Module \"a\" not found\n[2021-04-24 19:59:53 +0000] [1255] [ERROR] Application startup failed. Exiting.\n```\n\nmind you it does that for a few seconds and then the application starts correctly,\ni've also tried separating the pydantic models creation in a separate folder called 'schema' and that didn't do anything either\n\n========================================\n\nCode:\n```py\nTortoise.init_models([\"models.user\", \"models.group\"], \"models\")\n```\n\n```py\nGetGroup.from_queryset(Group.get(id=3).prefetch_related('owner'))\n```\n\n```text\napp\n│ main.py\n└───database\n│ │ database.py\n└───models\n| │ user.py\n| │ group.py\n└───routers\n| │ user_router.py\n| │ group_router.py\n└───services\n| │ auth.py\n```\n\n```py\nfrom fastapi import FastAPI\nfrom database.database import init_db\nfrom routers.user_router import router as UserRouter\nfrom routers.group_router import router as GroupRouter\n\n# Instantiate the Application\napp = FastAPI(title=\"test\", root_path=\"/api/\")\n\n# Include the Routers\napp.include_router(UserRouter, tags=[\"User\"], prefix=\"/user\")\napp.include_router(GroupRouter, tags=[\"Group\"], prefix=\"/group\")\n\n\n# Start DB Connection on Startup\n@app.on_event(\"startup\")\nasync def startup_event():\n init_db(app)\n```\n\n```py\nfrom decouple import config\nfrom fastapi import FastAPI\nfrom tortoise import Tortoise\nfrom tortoise.contrib.fastapi import register_tortoise\n\n\ndef init_db(app: FastAPI) -> None:\n Tortoise.init_models([\"models.user\", \"models.group\"], \"models\")\n register_tortoise(\n app,\n db_url=f\"mysql://{config('MYSQL_USER')}:{config('MYSQL_PASSWORD')}@{config('MYSQL_HOST')}:{config('MYSQL_EXPOSE')}/{config('MYSQL_DB')}\",\n modules={\"models\": [\"models.user\",\n \"models.group\",\n ]},\n generate_schemas=False,\n add_exception_handlers=True,\n )\n\n\nTORTOISE_ORM = {\n \"connections\": {\"default\": f\"mysql://{config('MYSQL_USER')}:{config('MYSQL_PASSWORD')}@{config('MYSQL_HOST')}:{config('MYSQL_EXPOSE')}/{config('MYSQL_DB')}\"},\n \"apps\": {\n \"models\": {\n \"models\": [\"models.user\",\n \"models.group\",\n \"aerich.models\"],\n \"default_connection\": \"default\",\n },\n },\n}\n```\n\n```py\nfrom tortoise import fields\nfrom tortoise.models import Model\nfrom tortoise.contrib.pydantic import pydantic_model_creator\nfrom models.group import Group\n\n\nclass User(Model):\n # ##### Define Readonly Fields ##### #\n id = fields.BigIntField(pk=True)\n # ##### Define Normal Fields ##### #\n first_name = fields.CharField(max_length=50)\n last_name = fields.CharField(max_length=50)\n username = fields.CharField(max_length=50, unique=True)\n email = fields.CharField(max_length=50, unique=True)\n password = fields.CharField(max_length=128)\n # ##### Define O2M ##### #\n owned_groups: fields.ReverseRelation[Group]\n # ##### Define M2M ##### #\n groups: fields.ManyToManyRelation[Group]\n # ##### Define Time_Stamps ###### #\n created_at = fields.DatetimeField(auto_now_add=True)\n modified_at = fields.DatetimeField(auto_now=True)\n\n class Meta:\n table: str = 'users'\n\n\nAuthData = pydantic_model_creator(User)\nCreateUser = pydantic_model_creator(User, name=\"CreateUser\", exclude_readonly=True)\nUpdateUser = pydantic_model_creator(User, name=\"UpdateUser\", exclude_readonly=True, exclude=['password'])\nGetUser = pydantic_model_creator(User, name=\"GetUser\", exclude=['password'])\nChangeUserPassword = pydantic_model_creator(User, name=\"ChangeUserPassword\", exclude_readonly=True, include=['password'])\n```\n\n```py\nfrom tortoise import fields\nfrom tortoise.models import Model\nfrom tortoise.contrib.pydantic import pydantic_model_creator\n\n\nclass Group(Model):\n # ##### Define Readonly Fields ##### #\n id = fields.BigIntField(pk=True)\n # ##### Define Normal Fields ##### #\n name = fields.CharField(max_length=50, unique=True)\n # ##### Define O2M ##### #\n owner = fields.ForeignKeyField(\"models.User\", related_name=\"owned_groups\")\n # ##### Define M2M ##### #\n members = fields.ManyToManyField(\"models.User\", related_name=\"groups\")\n # ##### Define Time_Stamps ###### #\n created_at = fields.DatetimeField(auto_now_add=True)\n modified_at = fields.DatetimeField(auto_now=True)\n\n class Meta:\n table: str = 'groups'\n\n\nCreateGroup = pydantic_model_creator(Group, name=\"CreateGroup\", exclude_readonly=True, exclude=['members'])\nUpdateGroup = pydantic_model_creator(Group, name=\"UpdateGroup\", exclude_readonly=True, exclude=['members'])\nGetGroup = pydantic_model_creator(Group, name=\"GetGroup\")\n```\n\n```py\nfrom typing import List\nimport json\nfrom fastapi import HTTPException, APIRouter, Depends, status\nfrom models.user import User\nfrom models.group import Group, CreateGroup, UpdateGroup, GetGroup\nfrom tortoise.contrib.fastapi import HTTPNotFoundError\nfrom services.auth import current_user\n\n# Intialize Router\nrouter = APIRouter()\n\n\n# ###################### Define Routes ###################### #\n\n# Create A Group\n@router.post(\"/\", dependencies=[Depends(current_user)])\nasync def create_group(group: CreateGroup, user: User = Depends(current_user)):\n user = await user\n try:\n await Group.create(**group.dict(exclude_unset=True), owner_id=user.id)\n except Exception:\n raise HTTPException(\n status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,\n detail=\"Group Name Already Exists\"\n )\n return {\"Group Created Successfully\"}\n\n\n# Update A Group\n@router.put(\"/{group_id}\", dependencies=[Depends(current_user)], responses={404: {\"model\": HTTPNotFoundError}})\nasync def update_group(group_id: int, group: UpdateGroup, user: User = Depends(current_user)):\n user = await user\n group = await GetGroup.from_queryset_single(Group.get(id=group_id))\n return group\n if user.id == group.id:\n await Group.filter(id=group_id).update(**group.dict(exclude_unset=True))\n return {\"Group Successfully Updated\"}\n else:\n raise HTTPException(\n status_code=status.HTTP_406_NOT_ACCEPTABLE,\n detail=\"You can't edit a group unless you're the owner\"\n )\n\n\n# Get All Groups\n@router.get(\"/\", dependencies=[Depends(current_user)])\nasync def get_groups():\n return GetGroup.schema()\n```\n\n```text\n[2021-04-24 19:59:53 +0000] [1255] [INFO] Started server process [1255]\n[2021-04-24 19:59:53 +0000] [1255] [INFO] Waiting for application startup.\n[2021-04-24 19:59:53 +0000] [1255] [ERROR] Traceback (most recent call last):\nFile \"/usr/local/lib/python3.8/site-packages/tortoise/__init__.py\", line 358, in _discover_models\nmodule = importlib.import_module(models_path)\nFile \"/usr/local/lib/python3.8/importlib/__init__.py\", line 127, in import_module\nreturn _bootstrap._gcd_import(name[level:], package, level)\nFile \"<frozen importlib._bootstrap>\", line 1014, in _gcd_import\nFile \"<frozen importlib._bootstrap>\", line 991, in _find_and_load\nFile \"<frozen importlib._bootstrap>\", line 973, in _find_and_load_unlocked\nModuleNotFoundError: No module named 'a'\nDuring handling of the above exception, another exception occurred:\nTraceback (most recent call last):\nFile \"/usr/local/lib/python3.8/site-packages/starlette/routing.py\", line 526, in lifespan\nasync for item in self.lifespan_context(app):\nFile \"/usr/local/lib/python3.8/site-packages/starlette/routing.py\", line 467, in default_lifespan\nawait self.startup()\nFile \"/usr/local/lib/python3.8/site-packages/starlette/routing.py\", line 502, in startup\nawait handler()\nFile \"/app/main.py\", line 17, in startup_event\ninit_db(app)\nFile \"/app/database/database.py\", line 8, in init_db\nTortoise.init_models(\"app.models.user\", \"models\")\nFile \"/usr/local/lib/python3.8/site-packages/tortoise/__init__.py\", line 415, in init_models\napp_models += cls._discover_models(models_path, app_label)\nFile \"/usr/local/lib/python3.8/site-packages/tortoise/__init__.py\", line 360, in _discover_models\nraise ConfigurationError(f'Module \"{models_path}\" not found')\ntortoise.exceptions.ConfigurationError: Module \"a\" not found\n[2021-04-24 19:59:53 +0000] [1255] [ERROR] Application startup failed. Exiting.\n```\n\n```text\nearly init\n```\n\n```text\nprefetch_related\n```\n\n```text\nGetGroup.schema()\n```\n\n```py\nfrom database.database import init_db\n```\n\n```py\nTortoise.init_models([\"models.user\", \"models.group\"], \"models\")\n```\n\n```text\nmain.py\n```\n\n```text\nregister_tortoise\n```\n\n========================================\n\nComments:\n- How you filter the results for members? For example, I want to get all the groups one user is member? If I want the only the groups the user is owner, would use `filter(owner_id=user.id)`, but how do with members if there is many members to one group?\n- @DiegoGaona I typically prefer to define the relationship in the model and the inverse, tortoise automatically loads it up and you can define the pydantic model to include everything you need or want to omit, so that when you get the user object back, you have an array with all joined groups. same concept but in reverse with groups as well you can define the relationship in the group model and get an array back with all the joined users,this is a sample response codebeautify.org/online-json-editor/cb8e288b\n- I will try to do something like it in a few days (short time right now). I posted a question (related to it), if you could help there: stackoverflow.com/questions/67971593/… . But thanks anyway!!\n- Spend 5 hours on this problem. Args !#!#!# .... One thing I think you should just call `init_db(app)` in your `main.py` (Without the startup event hook ). Because the `register_tortoise` hooks on this event! github.com/tortoise/tortoise-orm/blob/develop/tortoise/contr‌​ib/…","metadata":{"transformedAt":"2026-08-18T18:32:29.154Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":16,"totalLines":506,"estimatedTokens":4433}}671{"id":"stack-67145788","source":"stackoverflow","questionId":67145788,"title":"'async_generator is not a callable object' FastAPI dependency issue app","tags":["python","sqlalchemy","fastapi"],"text":"Title: 'async_generator is not a callable object' FastAPI dependency issue app\nTags: python, sqlalchemy, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to create a FastAPI and async sqlalchemy.\n\nThe get_db dependency causes a weird `TypeError: is not a callable object` issue.\n\nHere's my code:\n\ndb.py\n\n```\nfrom typing import Generator\nfrom .db.session import SessionLocal\n\nasync def get_db() -> Generator:\n try:\n db = SessionLocal()\n yield db\n finally:\n await db.close()\n```\n\nsession.py\n\n```\nfrom sqlalchemy.ext.asyncio import create_async_engine, AsyncSession\nfrom .core.config import settings\n\nengine = create_async_engine(\n settings.SQLALCHEMY_DATABASE_URI,\n pool_pre_ping=True\n)\nSessionLocal = AsyncSession(\n autocommit=False,\n autoflush=False,\n bind=engine\n)\n```\n\nI followed almost of the instructions posted here: https://6060ff4ffd0e7c1b62baa6c7--fastapi.netlify.app/advanced/sql-databases-sqlalchemy/#more-info\n\n========================================\n\nTop Answer:\nThe problem is\n\n```\nengine = create_async_engine(\nsettings.SQLALCHEMY_DATABASE_URI,\npool_pre_ping=True\n)\n```\n\nYou are filling `engine` with a promise that has to be fulfilled yet. Basically the `async` functionality allows you to go on with the code while some I/O or networking stuff is still pending.\n\nSo, you are passing the engine as parameter, although the connection may not have been established yet.\n\nYou should `await` for the return of the engine before using it as a parameter for other functions.\n\nHere's some more information about the `async` functionality of python\n\nhttps://www.educba.com/python-async/\n\n========================================\n\nCode:\n```text\nfrom typing import Generator\nfrom .db.session import SessionLocal\n\nasync def get_db() -> Generator:\n try:\n db = SessionLocal()\n yield db\n finally:\n await db.close()\n```\n\n```text\nfrom sqlalchemy.ext.asyncio import create_async_engine, AsyncSession\nfrom .core.config import settings\n\nengine = create_async_engine(\n settings.SQLALCHEMY_DATABASE_URI,\n pool_pre_ping=True\n)\nSessionLocal = AsyncSession(\n autocommit=False,\n autoflush=False,\n bind=engine\n)\n```\n\n```text\nTypeError: <async_generator object get_db at 0x7ff6d9d9aa60> is not a callable object\n```\n\n```text\nfrom typing import List, Any\n\nfrom fastapi import APIRouter, HTTPException, Depends, status\nfrom sqlalchemy.ext.asyncio import AsyncSession\n\nfrom . import models, crud, schemas\nfrom .deps.db import get_db\n\nrouter = APIRouter()\n\n\n@router.post('/',\n response_model=schemas.StaffAccount,\n status_code=status.HTTP_201_CREATED)\nasync def create_staff_account(\n db: AsyncSession = Depends(get_db),\n staff_acct: schemas.StaffAccountCreate = Depends(schemas.StaffAccountCreate)\n) -> Any:\n q = await crud.staff.create(db=db, obj_in=staff_acct)\n if not q:\n raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,\n detail='An error occurred while processing your request')\n return q\n```\n\n```text\nget_db()\n```\n\n```text\nget_db\n```\n\n```text\nengine = create_async_engine(\nsettings.SQLALCHEMY_DATABASE_URI,\npool_pre_ping=True\n)\n```\n\n```text\nengine\n```\n\n```text\nasync\n```\n\n```text\nawait\n```\n\n```text\nasync\n```\n\n========================================\n\nComments:\n- Upvoting the question and the answer. This saved me a lot of time and headache! Keep it mind the Depends expects this kind of values - fastapi.tiangolo.com/tutorial/dependencies","metadata":{"transformedAt":"2026-08-18T18:32:29.154Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":11,"totalLines":161,"estimatedTokens":871}}672{"id":"stack-62874993","source":"stackoverflow","questionId":62874993,"title":"Send a vector using the R httr GET function's `query` parameter","tags":["r","httr","fastapi"],"text":"Title: Send a vector using the R httr GET function's `query` parameter\nTags: r, httr, fastapi\nSource: Stack Overflow\n\nQuestion:\nFor sending a vector of values, say an array `list_a = c(1,2,3)` FastAPI will accept a URL of the form:\n\n`https://wherever.com/endpoint?list_a=1&list_a=2&list_a=3`\n\nHowever using library httr's query parameter to the GET function, you have to pass a list of key/value pairs. This means you can't have the same field twice because R will not accept a list with duplicate keys obviously.\n\nSo how do I do this? I could build the URL myself, but the problem with that is some of my parameters have double quotes (`\"`) in them which don't seem to be parsed properly if I put them directly into the url. The `query` parameter does seem to handle these properly however.\n\nIs there any way to get the `query` parameter of httr's `GET` to create multiple identical field names?\n\nAlternatively how do I encode a pre-created URL that has double quotes in it like the one below so that it does not cause FastAPI to give at HTTP error?\n\n`\"query/Crude/?actual_table_name=live.crude&report_id=xxxxxxx&fields=IMO&where={\\\"Barrels\\\":{\\\"gt\\\":1},\\\"conjunction\\\":\\\"\\\"}&where={\\\"Load Date\\\":{\\\"gt\\\":\\\"'2000-01-01'\\\"},\\\"conjunction\\\":\\\"\\\"}&offset=1e+05&limit=10000\"`\n\n========================================\n\nCode:\n```text\nlist_a = c(1,2,3)\n```\n\n```text\nhttps://wherever.com/endpoint?list_a=1&list_a=2&list_a=3\n```\n\n```text\n\"\n```\n\n```text\nquery\n```\n\n```text\nquery\n```\n\n```text\nGET\n```\n\n```text\n\"query/Crude/?actual_table_name=live.crude&report_id=xxxxxxx&fields=IMO&where={\\\"Barrels\\\":{\\\"gt\\\":1},\\\"conjunction\\\":\\\"\\\"}&where={\\\"Load Date\\\":{\\\"gt\\\":\\\"'2000-01-01'\\\"},\\\"conjunction\\\":\\\"\\\"}&offset=1e+05&limit=10000\"\n```\n\n```r\nurl <- \"query/Crude/?actual_table_name=live.crude&report_id=xxxxxxx&fields=IMO&where={\\\"Barrels\\\":{\\\"gt\\\":1},\\\"conjunction\\\":\\\"\\\"}&where={\\\"Load Date\\\":{\\\"gt\\\":\\\"'2000-01-01'\\\"},\\\"conjunction\\\":\\\"\\\"}&offset=1e+05&limit=10000\"\n```\n\n```text\nURLencode(url)\n#> [1] \"query/Crude/?actual_table_name=live.crude&report_id=xxxxxxx&fields=IMO&where=%7B%22Barrels%22:%7B%22gt%22:1%7D,%22conjunction%22:%22%22%7D&where=%7B%22Load%20Date%22:%7B%22gt%22:%22'2000-01-01'%22%7D,%22conjunction%22:%22%22%7D&offset=1e+05&limit=10000\"\n```\n\n```text\nURLencode\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.155Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":10,"totalLines":62,"estimatedTokens":568}}673{"id":"stack-65510798","source":"stackoverflow","questionId":65510798,"title":"How can I upload multiple files using JavaScript and FastAPI?","tags":["javascript","fastapi"],"text":"Title: How can I upload multiple files using JavaScript and FastAPI?\nTags: javascript, fastapi\nSource: Stack Overflow\n\nQuestion:\nI followed FastAPI docs and I am trying to send files from my client that wrote in js to my server that wrote in FastAPI.\n\nMy HTML:\n\n```\n\n \n \n \n \n\n \n \n \n \n \n \n \n```\n\nmy uploadfiles.js\n\n```\ndocument.getElementById('buttonid').addEventListener('click', generate);\n\nfunction generate() {\n let file = document.getElementById(\"fileid\").files[0];\n let file2 = document.getElementById(\"fileid2\").files[0];\n let formData = new FormData();\n formData.append(\"file\",file,file.name)\n formData.append(\"file2\",file2,file2.name)\n console.log(formData)\n axios.post('http://127.0.0.1:8000/actions/upload', formData, {\n headers: {\n 'content-Type': 'multipart/form-data'\n }\n})\n}\n```\n\naction.py\n\n```\nfrom typing import List\nfrom fastapi import APIRouter,Header,HTTPException,FastAPI, File, UploadFile\n\nrouter = APIRouter()\n\nimport pandas as pd\n\n@router.post('/upload')\ndef upload_file(files: List[UploadFile] = File(...)):\n print('Arrived')\n```\n\nand cant succesfully get the files and I get the error in my server side:\n\n```\nINFO: 127.0.0.1:59210 - \"POST /actions/upload HTTP/1.1\" 422 Unprocessable Entity\n```\n\nclient:\n\n```\nUncaught (in promise) Error: Request failed with status code 422\n at e.exports (isAxiosError.js:10)\n at e.exports (isAxiosError.js:10)\n at XMLHttpRequest.l.onreadystatechange (isAxiosError.js:10)\n```\n\nHow can I solve this and how can I use those files that I recieve in my upload endpoint?\n\n========================================\n\nTop Answer:\nI recently faced the same problem and could not solve it with the answer Isabi mentioned. But it gave me the right idea:\n\nThe files can be appanded separately from each other, important is that both uses the same name as argument:\n\n```\nformData.append('files',file)\nformData.append('files',file2)\n```\n\nOr if you already using a file array:\n\n```\nlet formData = new FormData();\nfor (var i = 0; i < files.length; i++){\n formData.append('files',files[i])\n}\n```\n\n========================================\n\nCode:\n```text\n<html>\n <head>\n <script src=\"https://code.jquery.com/jquery-2.0.3.js\" integrity=\"sha256-lCf+LfUffUxr81+W0ZFpcU0LQyuZ3Bj0F2DQNCxTgSI=\" crossorigin=\"anonymous\"></script>\n <script src=\"https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js\"></script>\n </head>\n\n <body>\n <input id='fileid' type='file' value=\"Load miRNA data\"/>\n <input id='fileid2' type='file' value=\"Load Target data\"/>\n <input id='buttonid' type='button' value='Upload' />\n </body>\n <script type=\"text/javascript\" src=\"./uplaodfiles.js\"></script>\n </html>\n```\n\n```text\ndocument.getElementById('buttonid').addEventListener('click', generate);\n\nfunction generate() {\n let file = document.getElementById(\"fileid\").files[0];\n let file2 = document.getElementById(\"fileid2\").files[0];\n let formData = new FormData();\n formData.append(\"file\",file,file.name)\n formData.append(\"file2\",file2,file2.name)\n console.log(formData)\n axios.post('http://127.0.0.1:8000/actions/upload', formData, {\n headers: {\n 'content-Type': 'multipart/form-data'\n }\n})\n}\n```\n\n```text\nfrom typing import List\nfrom fastapi import APIRouter,Header,HTTPException,FastAPI, File, UploadFile\n\nrouter = APIRouter()\n\nimport pandas as pd\n\n@router.post('/upload')\ndef upload_file(files: List[UploadFile] = File(...)):\n print('Arrived')\n```\n\n```text\nINFO: 127.0.0.1:59210 - \"POST /actions/upload HTTP/1.1\" 422 Unprocessable Entity\n```\n\n```text\nUncaught (in promise) Error: Request failed with status code 422\n at e.exports (isAxiosError.js:10)\n at e.exports (isAxiosError.js:10)\n at XMLHttpRequest.l.onreadystatechange (isAxiosError.js:10)\n```\n\n```text\nlet formData = new FormData();\nformData.append(\"files\",[file, file2]);\n```\n\n```text\nfile1\n```\n\n```text\nfile2\n```\n\n```text\nList\n```\n\n```text\nfiles\n```\n\n```text\nFormData\n```\n\n```text\nfiles\n```\n\n```text\nformData.append('files',file)\nformData.append('files',file2)\n```\n\n```text\nlet formData = new FormData();\nfor (var i = 0; i < files.length; i++){\n formData.append('files',files[i])\n}\n```\n\n========================================\n\nComments:\n- Related posts can be found here, as well as here and here","metadata":{"transformedAt":"2026-08-18T18:32:29.155Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":14,"totalLines":204,"estimatedTokens":1067}}674{"id":"stack-63910234","source":"stackoverflow","questionId":63910234,"title":"Calling internal api from another api function","tags":["python-3.x","rest","fastapi"],"text":"Title: Calling internal api from another api function\nTags: python-3.x, rest, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have implemented two endpoints:\n\n```\nPost - /users/ #endpoint to add a user\nPost - /confirmemail/ #endpoint to confirm email\n```\n\nNow I have function implemented for both endpoints, But I am thinking of calling the email endpoint after adding the user, directly. How can I achieve this in Fastapi?\n\n========================================\n\nCode:\n```text\nPost - /users/ #endpoint to add a user\nPost - /confirmemail/ #endpoint to confirm email\n```\n\n```text\ndef send_confirm_email():\n pass\n```\n\n```py\nfrom .utils import send_confirm_email\n\n@app.post(\"/users\")\ndef add_user():\n # ...\n send_confirm_email()\n return {\"message\": \"User added, confirm email sent.\"}\n\n@app.post(\"/confirmemail\")\ndef confirm_email():\n send_confirm_email()\n return {\"message\": \"confirm email sent.\"}\n```\n\n========================================\n\nComments:\n- Why do you need to call an API if you're running in the same program? Won't a function call do get the job done?\n- I have added both the endpoints in the different routers, So I was thinking of making this call generic","metadata":{"transformedAt":"2026-08-18T18:32:29.155Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":3,"totalLines":47,"estimatedTokens":298}}675{"id":"stack-79686564","source":"stackoverflow","questionId":79686564,"title":"Cannot send a request through FastAPI in Python (Failed to connect to localhost port 8000 after 0 ms: Couldn't connect to server)","tags":["python","docker","fastapi","pydantic"],"text":"Title: Cannot send a request through FastAPI in Python (Failed to connect to localhost port 8000 after 0 ms: Couldn't connect to server)\nTags: python, docker, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI devised a spam detecter for my example but I cannot send any request through Postman\n\nHere is the **requirement.txt** file\n\n```\nfastapi\nuvicorn[standard]\ntransformers\ntorch\n```\n\nHere is my **python file** shown below\n\n```\nfrom fastapi import FastAPI, HTTPException\nfrom pydantic import BaseModel, Field\nfrom transformers import pipeline\n\nclass ClassifyRequest(BaseModel):\n text: str = Field(..., example=\"\")\n lang: str = Field(\n \"en\",\n pattern=r\"^(en|tr|de|fr|es|it|pt|ru|ar|zh|ja|ko|hi|bn|ur|fa|th|vi|id|ms|nl|sv|no|da|fi|pl|cs|sk|hu|ro|bg|hr|sr|sl|et|lv|lt|el|he|uk|be|ky|uz|km|my|tg|az|hy|ga|cy|is|mk|bs|sq|mn|ne|pa|gl|la)$\",\n description=\"ISO language code\",\n example=\"tr\"\n )\n\nclass ClassifyResponse(BaseModel):\n label: str\n score: float\n\napp = FastAPI(title=\"Spam & Abuse Detector\")\n\nclassifier = pipeline(\n \"zero-shot-classification\",\n model=\"joeddav/xlm-roberta-large-xnli\"\n)\n\nCANDIDATE_LABELS = [\"spam\", \"adult_content\", \"drugs\", \"non_spam\"]\n\n@app.post(\"/classify\", response_model=ClassifyResponse)\ndef classify(req: ClassifyRequest):\n res = classifier(\n sequences=req.text,\n candidate_labels=CANDIDATE_LABELS\n )\n best_idx = res[\"scores\"].index(max(res[\"scores\"]))\n label = res[\"labels\"][best_idx]\n score = res[\"scores\"][best_idx]\n return ClassifyResponse(label=label, score=score)\n```\n\nHere is **Dockerfile**\n\n```\nFROM python:3.10-slim\n\nWORKDIR /app\nCOPY requirements.txt .\nRUN pip install --no-cache-dir -r requirements.txt\n\nCOPY app ./app\n\nEXPOSE 8000\nCMD [\"uvicorn\", \"app.main:app\", \"--host\", \"0.0.0.0\", \"--port\", \"8000\", \"--reload\", \"--log-level\", \"info\"]\n```\n\nWhen I run these commands shown below\n\n```\ndocker build -t spam-detector .\ndocker run -p 8000:8000 spam-detector\n```\n\nI got this console output\n\n```\nINFO: Will watch for changes in these directories: ['/app']\nINFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)\nINFO: Started reloader process [1] using WatchFiles\n```\n\nWhen I send a request through Postman\n\n```\ncurl -X POST http://127.0.0.1:8000/classify \\\n -H \"Content-Type: application/json\" \\\n -d '{\"text\":\"bla bla\",\"lang\":\"en\"}'\n```\n\nI get \"Failed to connect to localhost port 8000 after 0 ms: Couldn't connect to server\"\n\nHow can I fix the issue?\n\n========================================\n\nCode:\n```text\nfastapi\nuvicorn[standard]\ntransformers\ntorch\n```\n\n```text\nfrom fastapi import FastAPI, HTTPException\nfrom pydantic import BaseModel, Field\nfrom transformers import pipeline\n\nclass ClassifyRequest(BaseModel):\n text: str = Field(..., example=\"\")\n lang: str = Field(\n \"en\",\n pattern=r\"^(en|tr|de|fr|es|it|pt|ru|ar|zh|ja|ko|hi|bn|ur|fa|th|vi|id|ms|nl|sv|no|da|fi|pl|cs|sk|hu|ro|bg|hr|sr|sl|et|lv|lt|el|he|uk|be|ky|uz|km|my|tg|az|hy|ga|cy|is|mk|bs|sq|mn|ne|pa|gl|la)$\",\n description=\"ISO language code\",\n example=\"tr\"\n )\n\nclass ClassifyResponse(BaseModel):\n label: str\n score: float\n\napp = FastAPI(title=\"Spam & Abuse Detector\")\n\nclassifier = pipeline(\n \"zero-shot-classification\",\n model=\"joeddav/xlm-roberta-large-xnli\"\n)\n\nCANDIDATE_LABELS = [\"spam\", \"adult_content\", \"drugs\", \"non_spam\"]\n\n@app.post(\"/classify\", response_model=ClassifyResponse)\ndef classify(req: ClassifyRequest):\n res = classifier(\n sequences=req.text,\n candidate_labels=CANDIDATE_LABELS\n )\n best_idx = res[\"scores\"].index(max(res[\"scores\"]))\n label = res[\"labels\"][best_idx]\n score = res[\"scores\"][best_idx]\n return ClassifyResponse(label=label, score=score)\n```\n\n```text\nFROM python:3.10-slim\n\nWORKDIR /app\nCOPY requirements.txt .\nRUN pip install --no-cache-dir -r requirements.txt\n\nCOPY app ./app\n\nEXPOSE 8000\nCMD [\"uvicorn\", \"app.main:app\", \"--host\", \"0.0.0.0\", \"--port\", \"8000\", \"--reload\", \"--log-level\", \"info\"]\n```\n\n```text\ndocker build -t spam-detector .\ndocker run -p 8000:8000 spam-detector\n```\n\n```text\nINFO: Will watch for changes in these directories: ['/app']\nINFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)\nINFO: Started reloader process [1] using WatchFiles\n```\n\n```text\ncurl -X POST http://127.0.0.1:8000/classify \\\n -H \"Content-Type: application/json\" \\\n -d '{\"text\":\"bla bla\",\"lang\":\"en\"}'\n```\n\n```text\nfrom fastapi import FastAPI, HTTPException\nfrom pydantic import BaseModel, Field\n\nclass ClassifyRequest(BaseModel):\n text: str = Field(..., example=\"\")\n lang: str = Field(\n \"en\",\n pattern=r\"^(en|tr|de|fr|es|it|pt|ru|ar|zh|ja|ko|hi|bn|ur|fa|th|vi|id|ms|nl|sv|no|da|fi|pl|cs|sk|hu|ro|bg|hr|sr|sl|et|lv|lt|el|he|uk|be|ky|uz|km|my|tg|az|hy|ga|cy|is|mk|bs|sq|mn|ne|pa|gl|la)$\",\n description=\"ISO language code\",\n example=\"tr\"\n )\n\nclass ClassifyResponse(BaseModel):\n label: str\n score: float\n\napp = FastAPI(title=\"Spam & Abuse Detector\")\n\n@app.get(\"/\")\ndef index():\n return {\"Hello\": \"World\"}\n\nCANDIDATE_LABELS = [\"spam\", \"adult_content\", \"drugs\", \"non_spam\"]\n\n@app.post(\"/classify\", response_model=ClassifyResponse)\ndef classify(req: ClassifyRequest):\n label = req.text # <-- fake data\n score = float(len(req.text)) # <-- fake data\n return ClassifyResponse(label=label, score=score)\n```\n\n```none\nINFO: Will watch for changes in these directories: ['/app']\nINFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)\nINFO: Started reloader process [1] using WatchFiles\nINFO: Started server process [8]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\n```\n\n```text\nDockerfile\n```\n\n```text\nmain.py\n```\n\n```text\npipeline\n```\n\n```text\nDockerfile\n```\n\n```text\nFastAPI\n```\n\n```text\npipeline\n```\n\n```text\n--reload\n```\n\n```text\nStarted reloader ...\n```\n\n========================================\n\nComments:\n- do you mean `postman` in web browser which runs on server on internet, or local command on the same computer as your docker?\n- @furas I just ran the app in my computer through Docker and sent a request through Postman but I get \"Could not get Response\"\n- but: do you run Postman in web browser or you run local comman `curl`? Postman in browser runs code on external server and it may not have access to your local computer - it would need your external IP instead of `127.0.0.1`, and it would need to configure (provider) routers to redirect it to your computer.\n- I think there can be problem in python file or Dockerfile but I still couldn't fix it.\n- first check local command `curl` instead of `Postman`\n- It shows \"Failed to connect to localhost port 8000 after 0 ms: Couldn't connect to server\"\n- I tried to build it and first I had to add `protobuf` and `tiktoken` to `requirement.txt`. Next I added some `print()` to see which part of code is executed. Now it raises error before `pipeline()` - probably some problem with token for tiktoken. Now I wait for print() which I have after `pipeline()` and I wait few minutes and it still doesn't show up. maybe it needs longer time to run pipeline and you may have to wait until it finish\n- if I remove `transformers`, `pipeline`, `classifier` and create ClassifyResponse with fake data then container works without problems, and `curl` can connect without problem (it get response with fake data). So Dockerfile is OK, FastAPI is OK.\n- @furas Can you the code if you don't mind?","metadata":{"transformedAt":"2026-08-18T18:32:29.155Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":16,"totalLines":263,"estimatedTokens":1856}}676{"id":"stack-63043259","source":"stackoverflow","questionId":63043259,"title":"Fastapi - openapi authorize button goes away","tags":["swagger","openapi","fastapi","openapi-generator"],"text":"Title: Fastapi - openapi authorize button goes away\nTags: swagger, openapi, fastapi, openapi-generator\nSource: Stack Overflow\n\nQuestion:\nI have created a python app using fastapi and therefore I have generated an openapi document `http://localhost:8084/docs`. I am building the app locally using docker-compose. In the beginning I was able to see the `authorize` button but now when I load the page `http://localhost:8084/docs` it just appears for a blink of an eye and then disappears. This is quite strange for me as it was working fine.\n\nThis question could be a possible duplicate but it shows that locally it works fine and there was a problem when it was deployed to Google App Engine. In my case, it was working fine locally and after deployment as well but now I cna't see that `authorize` button anywhere. Any ideas or experiences with this?\n\n========================================\n\nCode:\n```text\nhttp://localhost:8084/docs\n```\n\n```text\nauthorize\n```\n\n```text\nhttp://localhost:8084/docs\n```\n\n```text\nauthorize\n```\n\n```text\n3.30.1\n```\n\n```text\n0.60.1\n```\n\n```text\n3.30.0\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.155Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":7,"totalLines":39,"estimatedTokens":271}}677{"id":"stack-79271620","source":"stackoverflow","questionId":79271620,"title":"FastAPI RuntimeError: Expected ASGI message 'websocket.accept', 'websocket.close', or 'websocket.http.response.start' but got 'http.response.start'","tags":["websocket","fastapi","uvicorn","starlette","python-socketio"],"text":"Title: FastAPI RuntimeError: Expected ASGI message 'websocket.accept', 'websocket.close', or 'websocket.http.response.start' but got 'http.response.start'\nTags: websocket, fastapi, uvicorn, starlette, python-socketio\nSource: Stack Overflow\n\nQuestion:\nI have server like:\n\nmain.py\n\n```\nimport socketio\nfrom fastapi import FastAPI\n\napp = FastAPI()\nsio = socketio.AsyncServer(async_mode=\"asgi\", cors_allowed_origins=\"*\")\nsio_app = socketio.ASGIApp(socketio_server=sio, socketio_path=\"socket.io\")\napp.mount(\"/ws\", sio_app)\n\n@sio.on(\"connect\")\nasync def handle_connect(sid, *args, **kwargs):\n await sio.emit(\"msg\", \"Test msg from FastAPI\")\n```\n\nLaunch server with `uvicorn main:app --reload --host 0.0.0.0`\n\nAnd I try to connect to it with postman with `ws://127.0.0.1:8000/ws/socket.io/?EIO=4&transport=websocket`\n\nor `curl -v \"http://127.0.0.1:8000/ws/socket.io/?EIO=4\"`\n\nOn fastapi version 0.108 and lower - I receive **127.0.0.1:58484 - \"GET /socket.io/?EIO=4 HTTP/1.1\" 200 OK** with both\n\nBut if I try to use fastapii ^0.109:\n\n- For curl I receive **\"GET /ws/socket.io/?EIO=4 HTTP/1.1\" 404 Not Found**\n\n- For Postman even worse:\n\n```\nException in ASGI application\nTraceback (most recent call last):\n File \"/Users/eugene/Library/Caches/pypoetry/virtualenvs/websocket-test-j4LebyL2-py3.12/lib/python3.12/site-packages/uvicorn/protocols/websockets/websockets_impl.py\", line 242, in run_asgi\n result = await self.app(self.scope, self.asgi_receive, self.asgi_send) # type: ignore[func-returns-value]\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/Users/eugene/Library/Caches/pypoetry/virtualenvs/websocket-test-j4LebyL2-py3.12/lib/python3.12/site-packages/uvicorn/middleware/proxy_headers.py\", line 60, in __call__\n return await self.app(scope, receive, send)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/Users/eugene/Library/Caches/pypoetry/virtualenvs/websocket-test-j4LebyL2-py3.12/lib/python3.12/site-packages/fastapi/applications.py\", line 1054, in __call__\n await super().__call__(scope, receive, send)\n File \"/Users/eugene/Library/Caches/pypoetry/virtualenvs/websocket-test-j4LebyL2-py3.12/lib/python3.12/site-packages/starlette/applications.py\", line 123, in __call__\n await self.middleware_stack(scope, receive, send)\n File \"/Users/eugene/Library/Caches/pypoetry/virtualenvs/websocket-test-j4LebyL2-py3.12/lib/python3.12/site-packages/starlette/middleware/errors.py\", line 151, in __call__\n await self.app(scope, receive, send)\n File \"/Users/eugene/Library/Caches/pypoetry/virtualenvs/websocket-test-j4LebyL2-py3.12/lib/python3.12/site-packages/starlette/middleware/exceptions.py\", line 62, in __call__\n await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)\n File \"/Users/eugene/Library/Caches/pypoetry/virtualenvs/websocket-test-j4LebyL2-py3.12/lib/python3.12/site-packages/starlette/_exception_handler.py\", line 64, in wrapped_app\n raise exc\n File \"/Users/eugene/Library/Caches/pypoetry/virtualenvs/websocket-test-j4LebyL2-py3.12/lib/python3.12/site-packages/starlette/_exception_handler.py\", line 53, in wrapped_app\n await app(scope, receive, sender)\n File \"/Users/eugene/Library/Caches/pypoetry/virtualenvs/websocket-test-j4LebyL2-py3.12/lib/python3.12/site-packages/starlette/routing.py\", line 762, in __call__\n await self.middleware_stack(scope, receive, send)\n File \"/Users/eugene/Library/Caches/pypoetry/virtualenvs/websocket-test-j4LebyL2-py3.12/lib/python3.12/site-packages/starlette/routing.py\", line 782, in app\n await route.handle(scope, receive, send)\n File \"/Users/eugene/Library/Caches/pypoetry/virtualenvs/websocket-test-j4LebyL2-py3.12/lib/python3.12/site-packages/starlette/routing.py\", line 485, in handle\n await self.app(scope, receive, send)\n File \"/Users/eugene/Library/Caches/pypoetry/virtualenvs/websocket-test-j4LebyL2-py3.12/lib/python3.12/site-packages/engineio/async_drivers/asgi.py\", line 77, in __call__\n await self.not_found(receive, send)\n File \"/Users/eugene/Library/Caches/pypoetry/virtualenvs/websocket-test-j4LebyL2-py3.12/lib/python3.12/site-packages/engineio/async_drivers/asgi.py\", line 125, in not_found\n await send({'type': 'http.response.start',\n File \"/Users/eugene/Library/Caches/pypoetry/virtualenvs/websocket-test-j4LebyL2-py3.12/lib/python3.12/site-packages/starlette/_exception_handler.py\", line 50, in sender\n await send(message)\n File \"/Users/eugene/Library/Caches/pypoetry/virtualenvs/websocket-test-j4LebyL2-py3.12/lib/python3.12/site-packages/uvicorn/protocols/websockets/websockets_impl.py\", line 319, in asgi_send\n raise RuntimeError(msg % message_type)\nRuntimeError: Expected ASGI message 'websocket.accept', 'websocket.close', or 'websocket.http.response.start' but got 'http.response.start'.\n```\n\n- I also tried to create html file and connect to socket\n\n```\n\n \n\n \n \n const socket = io(\"http://127.0.0.1:8000\", { path: \"/ws/socket.io\" , transports: [\"websocket\"]});\n\n socket.on(\"connect\", () => {\n console.log(\"Connected to WebSocket server!\");\n });\n socket.on(\"disconnect\", () => {\n console.log(\"Disconnected from WebSocket server\");\n });\n \n\n```\n\nOn fastapi 0.108 I receive hello message from Fastapi\nenter image description here\nOn 0.109+ - server error like with Postman\n\nAs far as I can see there something wrong with routes, but I can't get what exactly. Any ideas?\n\nI want to find a problem and understand - should I downgrade fastapi to 0.108 to work with websockets or I can fix it somehow.\n\n========================================\n\nCode:\n```text\nimport socketio\nfrom fastapi import FastAPI\n\napp = FastAPI()\nsio = socketio.AsyncServer(async_mode=\"asgi\", cors_allowed_origins=\"*\")\nsio_app = socketio.ASGIApp(socketio_server=sio, socketio_path=\"socket.io\")\napp.mount(\"/ws\", sio_app)\n\n\n@sio.on(\"connect\")\nasync def handle_connect(sid, *args, **kwargs):\n await sio.emit(\"msg\", \"Test msg from FastAPI\")\n```\n\n```text\nException in ASGI application\nTraceback (most recent call last):\n File \"/Users/eugene/Library/Caches/pypoetry/virtualenvs/websocket-test-j4LebyL2-py3.12/lib/python3.12/site-packages/uvicorn/protocols/websockets/websockets_impl.py\", line 242, in run_asgi\n result = await self.app(self.scope, self.asgi_receive, self.asgi_send) # type: ignore[func-returns-value]\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/Users/eugene/Library/Caches/pypoetry/virtualenvs/websocket-test-j4LebyL2-py3.12/lib/python3.12/site-packages/uvicorn/middleware/proxy_headers.py\", line 60, in __call__\n return await self.app(scope, receive, send)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/Users/eugene/Library/Caches/pypoetry/virtualenvs/websocket-test-j4LebyL2-py3.12/lib/python3.12/site-packages/fastapi/applications.py\", line 1054, in __call__\n await super().__call__(scope, receive, send)\n File \"/Users/eugene/Library/Caches/pypoetry/virtualenvs/websocket-test-j4LebyL2-py3.12/lib/python3.12/site-packages/starlette/applications.py\", line 123, in __call__\n await self.middleware_stack(scope, receive, send)\n File \"/Users/eugene/Library/Caches/pypoetry/virtualenvs/websocket-test-j4LebyL2-py3.12/lib/python3.12/site-packages/starlette/middleware/errors.py\", line 151, in __call__\n await self.app(scope, receive, send)\n File \"/Users/eugene/Library/Caches/pypoetry/virtualenvs/websocket-test-j4LebyL2-py3.12/lib/python3.12/site-packages/starlette/middleware/exceptions.py\", line 62, in __call__\n await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)\n File \"/Users/eugene/Library/Caches/pypoetry/virtualenvs/websocket-test-j4LebyL2-py3.12/lib/python3.12/site-packages/starlette/_exception_handler.py\", line 64, in wrapped_app\n raise exc\n File \"/Users/eugene/Library/Caches/pypoetry/virtualenvs/websocket-test-j4LebyL2-py3.12/lib/python3.12/site-packages/starlette/_exception_handler.py\", line 53, in wrapped_app\n await app(scope, receive, sender)\n File \"/Users/eugene/Library/Caches/pypoetry/virtualenvs/websocket-test-j4LebyL2-py3.12/lib/python3.12/site-packages/starlette/routing.py\", line 762, in __call__\n await self.middleware_stack(scope, receive, send)\n File \"/Users/eugene/Library/Caches/pypoetry/virtualenvs/websocket-test-j4LebyL2-py3.12/lib/python3.12/site-packages/starlette/routing.py\", line 782, in app\n await route.handle(scope, receive, send)\n File \"/Users/eugene/Library/Caches/pypoetry/virtualenvs/websocket-test-j4LebyL2-py3.12/lib/python3.12/site-packages/starlette/routing.py\", line 485, in handle\n await self.app(scope, receive, send)\n File \"/Users/eugene/Library/Caches/pypoetry/virtualenvs/websocket-test-j4LebyL2-py3.12/lib/python3.12/site-packages/engineio/async_drivers/asgi.py\", line 77, in __call__\n await self.not_found(receive, send)\n File \"/Users/eugene/Library/Caches/pypoetry/virtualenvs/websocket-test-j4LebyL2-py3.12/lib/python3.12/site-packages/engineio/async_drivers/asgi.py\", line 125, in not_found\n await send({'type': 'http.response.start',\n File \"/Users/eugene/Library/Caches/pypoetry/virtualenvs/websocket-test-j4LebyL2-py3.12/lib/python3.12/site-packages/starlette/_exception_handler.py\", line 50, in sender\n await send(message)\n File \"/Users/eugene/Library/Caches/pypoetry/virtualenvs/websocket-test-j4LebyL2-py3.12/lib/python3.12/site-packages/uvicorn/protocols/websockets/websockets_impl.py\", line 319, in asgi_send\n raise RuntimeError(msg % message_type)\nRuntimeError: Expected ASGI message 'websocket.accept', 'websocket.close', or 'websocket.http.response.start' but got 'http.response.start'.\n```\n\n```text\n<!DOCTYPE html>\n<html>\n<head>\n <script src=\"https://cdn.socket.io/4.5.4/socket.io.min.js\"></script>\n</head>\n<body>\n \n <script>\n const socket = io(\"http://127.0.0.1:8000\", { path: \"/ws/socket.io\" , transports: [\"websocket\"]});\n\n socket.on(\"connect\", () => {\n console.log(\"Connected to WebSocket server!\");\n });\n socket.on(\"disconnect\", () => {\n console.log(\"Disconnected from WebSocket server\");\n });\n </script>\n</body>\n</html>\n```\n\n```text\nuvicorn main:app --reload --host 0.0.0.0\n```\n\n```text\nws://127.0.0.1:8000/ws/socket.io/?EIO=4&transport=websocket\n```\n\n```text\ncurl -v \"http://127.0.0.1:8000/ws/socket.io/?EIO=4\"\n```\n\n```py\nfastapi_app = FastAPI()\nsio = socketio.AsyncServer(async_mode=\"asgi\", cors_allowed_origins=\"*\")\napp = socketio.ASGIApp(socketio_server=sio, other_asgi_app=fastapi_app, socketio_path=\"/ws/socket.io\")\n```\n\n```text\nsocketio_path\n```\n\n```text\n/ws/socket.io\n```\n\n```text\nASGIApp\n```\n\n========================================\n\nComments:\n- Both of your ideas are working! But, to be honest, I don't understand why does it work. In previous versions of fastapi part of mounting path (\"/ws\") was added to socketio_path? And in newer versions they removed it and we have to mount fastapi route to full WebSocket path? Great thanks for your help, but I don't understand the reason why it works like that.\n- I'm not familiar with the implementation of the `mount()` function in FastAPI, but my guess is that they've made a breaking change in its implementation if the code in your question used to work with older versions. I honestly don't like the idea of having FastAPI at the top level and routing to Socket.IO. The `ASGIApp` class is a simpler and much more lightweight solution that routes anything that does not start with the Socket.IO path to the `other_asgi_app`, transparently and without changing any paths or anything else in the requests.\n- Thank you very much! Yeah, the way with ASGIApp look much more logical and understandable. Now it`s pretty clear what happened and how to deal with it.","metadata":{"transformedAt":"2026-08-18T18:32:29.155Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":10,"totalLines":217,"estimatedTokens":2896}}678{"id":"stack-78844871","source":"stackoverflow","questionId":78844871,"title":"Locking resource in FastAPI - using a multiprocessing Worker","tags":["python","python-asyncio","fastapi","python-multiprocessing"],"text":"Title: Locking resource in FastAPI - using a multiprocessing Worker\nTags: python, python-asyncio, fastapi, python-multiprocessing\nSource: Stack Overflow\n\nQuestion:\nI would like to make an `FastAPI` service with one `/get` endpoint which will return a ML-model inference result. It is pretty easy to implement that, but the catch is I periodically need to update the model with a newer version (trough request on another server with models, but that is beside the point), and here I see a problem!\n\nWhat will happen if one request calls old model, but the old model is currently being replaced by a newer one?? How can I implement this kind of locking mechanism with `asyncio` ?\n\nHere is the code:\n\n```\nimport asyncio\nimport time\nfrom concurrent.futures import ProcessPoolExecutor\n\nfrom fastapi import FastAPI, Request\nfrom sentence_transformers import SentenceTransformer\n\napp = FastAPI()\nsbertmodel = None\n\ndef create_model():\n global sbertmodel\n sbertmodel = SentenceTransformer('multi-qa-MiniLM-L6-cos-v1')\n\n# if you try to run all predicts concurrently, it will result in CPU trashing.\npool = ProcessPoolExecutor(max_workers=1, initializer=create_model)\n\ndef model_predict():\n ts = time.time()\n vector = sbertmodel.encode('How big is London')\n return vector\n\nasync def vector_search(vector):\n # simulate I/O call (e.g. Vector Similarity Search using a VectorDB)\n await asyncio.sleep(0.005)\n\n@app.get(\"/\")\nasync def entrypoint(request: Request):\n loop = asyncio.get_event_loop()\n ts = time.time()\n # worker should be initialized outside endpoint to avoid cold start\n vector = await loop.run_in_executor(pool, model_predict)\n print(f\"Model : {int((time.time() - ts) * 1000)}ms\")\n ts = time.time()\n await vector_search(vector)\n print(f\"io task: {int((time.time() - ts) * 1000)}ms\")\n return \"ok\"\n```\n\nMy model update would be implemented trough Repeated tasks (but that is not important now) : https://fastapi-utils.davidmontague.xyz/user-guide/repeated-tasks/\n\nThis is the idea of a model serving : https://luis-sena.medium.com/how-to-optimize-fastapi-for-ml-model-serving-6f75fb9e040d\n\nEDIT: what is important to run multiple requests concurrently, and while model is updating, acquire lock so that requests wouldnt fail, they should just wait a little bit longer because it is a small model.\n\n========================================\n\nCode:\n```text\nimport asyncio\nimport time\nfrom concurrent.futures import ProcessPoolExecutor\n\nfrom fastapi import FastAPI, Request\nfrom sentence_transformers import SentenceTransformer\n\napp = FastAPI()\nsbertmodel = None\n\n\ndef create_model():\n global sbertmodel\n sbertmodel = SentenceTransformer('multi-qa-MiniLM-L6-cos-v1')\n\n\n# if you try to run all predicts concurrently, it will result in CPU trashing.\npool = ProcessPoolExecutor(max_workers=1, initializer=create_model)\n\n\ndef model_predict():\n ts = time.time()\n vector = sbertmodel.encode('How big is London')\n return vector\n\n\nasync def vector_search(vector):\n # simulate I/O call (e.g. Vector Similarity Search using a VectorDB)\n await asyncio.sleep(0.005)\n\n\n@app.get(\"/\")\nasync def entrypoint(request: Request):\n loop = asyncio.get_event_loop()\n ts = time.time()\n # worker should be initialized outside endpoint to avoid cold start\n vector = await loop.run_in_executor(pool, model_predict)\n print(f\"Model : {int((time.time() - ts) * 1000)}ms\")\n ts = time.time()\n await vector_search(vector)\n print(f\"io task: {int((time.time() - ts) * 1000)}ms\")\n return \"ok\"\n```\n\n```text\nFastAPI\n```\n\n```text\n/get\n```\n\n```text\nasyncio\n```\n\n```text\nimport asyncio\nimport time\nimport threading\nfrom concurrent.futures import ProcessPoolExecutor\nfrom multiprocessing import Manager\n\n\nfrom fastapi import FastAPI, Request\nfrom sentence_transformers import SentenceTransformer\n\nsbertmodel = None\nlocal_model_iteration = -1\nshared_namespace = None\n\n# pool, and other multi-processing objects can`t simply\n# be started in the top level of the body, or they't be re\n# created in each subprocess!!\n# check https://fastapi.tiangolo.com/advanced/events/#lifespan\n\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI):\n global pool, root_namespace\n manager = Manager()\n\n root_namespace = manager.NameSpace()\n \n # Values assigned to the \"namespace\" object are \n # visible on the subprocess created by the pool\n \n root_namspace.model_iteration = 0\n root_namespace.model_parameters = \"multi-qa-MiniLM-L6-cos-v1\"\n \n # (as long as we send the namespace object to each subprocess\n # and store it there)\n pool = ProcessPoolExecutor(max_workers=1, initializer=initialize_subprocess, initargs=(root_namespace,))\n with pool, manager:\n # pass control to fastapi: all the app is executed\n yield\n # end of \"with\" block:\n # both the pool and manager are shutdown when fastapi server exits!\n \n\napp = FastAPI(lifespan=lifespan)\n\n# if you try to run all predicts concurrently, it will result in CPU trashing.\n\n\ndef initialize_subprocess(shared_namespace_arg):\n global shared_namespace\n # Store the shared namespace in _this_ process:\n shared_namespace = shared_namespac_arg\n update_model()\n \ndef update_model():\n \"called on worker subprocess start, and at any time the model is outdated\" \n global local_model_iteration, sbertmodel\n local_model_iteration = shared_namespace.model_iteration\n # retrieve parameter posted by root process:\n sbertmodel = SentenceTransformer(shared_namespace.model_parameters)\n\n\n\ndef model_predict():\n ts = time.time()\n # verify if model was updatd from the root process\n if shared_namespace.model_iteration > local_model_iteration:\n # if so, just update the model\n update_model()\n # model is synchronied, just do our job:\n vector = sbertmodel.encode('How big is London')\n return vector\n\n\nasync def vector_search(vector):\n # simulate I/O call (e.g. Vector Similarity Search using a VectorDB)\n await asyncio.sleep(0.005)\n\n\n@app.get(\"/\")\nasync def entrypoint(request: Request):\n loop = asyncio.get_event_loop()\n ts = time.time()\n # worker should be initialized outside endpoint to avoid cold start\n vector = await loop.run_in_executor(pool, model_predict)\n print(f\"Model : {int((time.time() - ts) * 1000)}ms\")\n ts = time.time()\n await vector_search(vector)\n print(f\"io task: {int((time.time() - ts) * 1000)}ms\")\n return \"ok\"\n\n@app.get(\"/update_model\")\nasync def update_model_endpoint(request: Request):\n # extract from the request the needed paramters for the new model\n ...\n new_model_parameters = ...\n # uodate the model parameters and model iteration so they are visible\n # in the worker(s)\n root_namespace.model_parameters = new_model_parameters\n # This increment taking place _after_ the \"model_parameters\" are set \n # is all that is needed to keep things running in order here:\n root_namespace.model_iteration += 1\n return {} # whatever response needed by the endpoint\n```\n\n```text\nmultiprocessing.Manager\n```\n\n```text\nManager.Namespace()\n```\n\n```text\ninitargs\n```\n\n```text\nProcessPoolExecutor\n```\n\n========================================\n\nComments:\n- Did you try `asyncio.Lock`?\n- It would depend on how you're currently accessing the model, but a common way to handle updating resources while running is to not replace the original reference before you've loaded and processed everything - so if you have a dependency or global state in your application, don't replace that part before you've loaded the new resource - serve the old one until the new one is ready. If you need locking you might also need it to be cross process (i.e. multiple workers), so you might want to look at something like redis (or compatible) to create a cross process lock.\n- @MatsLindh if my API is online, it is constantly serving models, I need to implement some sort of background task that will lock the current resource, and replace it with the old one. I thought of only doing locking when the model has finished downloading. Then I would need to somehow acquire lock (models are small) on a function that serves model. I just dont know what will happen if multiple requests are wanting to access the model while updating ??\n- In the example you've linked, replacing the `sbertmodel` variable with an updated model shouldn't cause any issues, since there is only a single call to the model - you're either calling it or not, and there is no subsequent calls where two different variables can be used - so in that case, no locking should be necessary (which is why I said it depends on your current code). If you have multiple calls, you can assign the reference to your own variable that won't get replaced while you're calling the model (or use a dependency) (i.e. copy it over from the old one).\n- \"since there is only a single call to the model\" Sorry I dont understand that. I blog there is ProcessPoolExecutor invoked and that enables (from what I can see) a multiple request concurrently access the model. Lets say there are 10 coroutines wanting to access the model, and one coroutine wants to update it, what will happen ??? I was thinking I need to implement read-write lock. THe update method should have a write lock.... Tnx for response btw\n- It is possible to give a straigfrward answer, with code, if there is code in your question, with a minimal reproducible example. A 20-30 line py file with the setup for the model, the replacing model endpoint, and a common endpoitn that will make use of the model. With that in place, I, or other person could add a couple lines to your example showing how to add an asyncio.Lock (if it is needed at all). Without code, the answer is \"you could, maybe, use an asyncio.Lock\" is as a complete thing as you will get. Sorry.\n- Tnx for the answer, but I didnt get one thing. If I want to implement a \"repeated-task\" (fastapi-utils.davidmontague.xyz/user-guide/repeated-tasks) that will fetch every X hours a new model, and serve that as a new model, can I replace your \"/update_model\" endpoint with \"repeated-task()\" ? Because the entire model file must be changed/replaced with a newer one. So If \"/\" endpoint is reading that file, a new update must replace that file, so the point is to not have any resource deadlocks\n- yes, of course - as you didn't mention what would trigger the model change, I just added an example as an endpoint - it can be trigered in anyway - i- he only important thing is to update the cross-process visible variables, as this method does.\n- So if a model is downloaded trough this \"repeated-task\", it would be represented as a file (lets call it \"model-new\"). While model is downloading, concurrent requests are being made on a \"old-model\" which is loaded on api. So when I update model, I want \"model-new\" to be used, and the old one to be deleted. But I think that would be a problem because maybe maybe other older requests are still trying to access \"old-model\" (I dont know if this is a possibility). Is there any way to ensure that model can be deleted only if it is not accessed ?\n- in the way it is in this code, for example, there is no problem. The old-model is loaded into the \"sbertmodel\" global variable for each worker - it will complete its task, and when a new task is started, it verifies for a new model before anything, updates the model in memory, and there are no references left of the older model. Now, even if each subprocess had background tasks working with the models when a new model is started, all they´d need would be to have a reference to the model in a local variable - so even for far more complicated cases, the plan above would work with ease.\n- Is it possible to avoid global variables in \"initialize_subprocess()\" and \"update_model()\" ? Something like this comes to mind : github.com/fastapi/fastapi/issues/592#issuecomment-538764818\n- the global variables are object references which have to exist in a single place in a process. You can use whatever mechanism you want for those - there could be a class used as namespace, or a contextvars.ContextVar variable, a `types.SimpleNameSpace` instance - global variables are just the simplest and more straightforward thing to do, and easier to write in this example.\n- Tnx for help, and I also dont understand if I run gunicorn with 2 workers on dual-core cpu. That means 2 workers are analogous as 2 processes that will run a \"main\" fast-api process with an event loop, and another subprocess with \"initialize_subprocess()\" invoked. So I have 2 processes, and each of them have its own subprocess ? If that is true, that means I have to load model 2 times in two workers. Theoretically what can happen is one worker gets updated model and serves it, and another is still at the old model version, so 2 (same) requests can give different results ?\n- Continuing on my previous comment, --preload (Load application code before the worker processes are forked.) Is it possible to load model trough preload worker, and update model only in that \"preload space\" ?","metadata":{"transformedAt":"2026-08-18T18:32:29.155Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":256,"estimatedTokens":3259}}679{"id":"stack-62962110","source":"stackoverflow","questionId":62962110,"title":"How to get next itereration of async generator after calling `async for in`","tags":["python","python-asyncio","fastapi","starlette"],"text":"Title: How to get next itereration of async generator after calling `async for in`\nTags: python, python-asyncio, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nUsing FastAPI I am trying to detect if a StreamingResponse has been entirely been consumed by the client or if it was cancelled.\n\nI have the following example app:\n\n```\nimport asyncio\n\nimport uvicorn\nfrom fastapi import FastAPI\nfrom fastapi.responses import StreamingResponse\n\napp = FastAPI()\n\nasync def ainfinite_generator():\n while True:\n yield b\"some fake data \"\n await asyncio.sleep(.001)\n\nasync def astreamer(generator):\n try:\n async for data in generator:\n yield data\n except Exception as e:\n # this isn't triggered by a cancelled request\n print(e)\n finally:\n # this always throws a StopAsyncIteration exception\n # no matter whether the generator was consumed or not\n leftover = await generator.__anext__()\n if leftover:\n print(\"we didn't finish\")\n else:\n print(\"we finished\")\n\n@app.get(\"/\")\nasync def infinite_stream():\n return StreamingResponse(astreamer(ainfinite_generator()))\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n```\n\nIt seems like the first `async for in generator` in `astreamer` \"consumes\" the async generator. After that loop, further attempts to get the next iteration fail with a `StopAsyncIteration` exception, even if the generator is \"infinite\" as defined above.\n\nI've looked through PEP-525 and the only thing I am seeing is that if an exception is thrown into the generator it will cause any further attempts to read from the generator to throw that StopAsyncIteration exception, but I don't see where that would be happening. At least, I'm not seeing that in Starlette's StreamingResponse class (it doesn't seem to do much with \"content\"). Does the generator not get \"released\" after doing an `async for in gen`?\n\n========================================\n\nCode:\n```py\nimport asyncio\n\nimport uvicorn\nfrom fastapi import FastAPI\nfrom fastapi.responses import StreamingResponse\n\napp = FastAPI()\n\n\nasync def ainfinite_generator():\n while True:\n yield b\"some fake data \"\n await asyncio.sleep(.001)\n\n\nasync def astreamer(generator):\n try:\n async for data in generator:\n yield data\n except Exception as e:\n # this isn't triggered by a cancelled request\n print(e)\n finally:\n # this always throws a StopAsyncIteration exception\n # no matter whether the generator was consumed or not\n leftover = await generator.__anext__()\n if leftover:\n print(\"we didn't finish\")\n else:\n print(\"we finished\")\n\n\n@app.get(\"/\")\nasync def infinite_stream():\n return StreamingResponse(astreamer(ainfinite_generator()))\n\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n```\n\n```text\nasync for in generator\n```\n\n```text\nastreamer\n```\n\n```text\nStopAsyncIteration\n```\n\n```text\nasync for in gen\n```\n\n```py\nimport asyncio\nimport time\n\nimport uvicorn\nfrom fastapi import FastAPI\nfrom fastapi.responses import StreamingResponse\n\napp = FastAPI()\n\n\ndef infinite_generator():\n # not blocking, so doesn't need to be async\n # but if it was blocking, you could make this async and await it\n while True:\n yield b\"some fake data \"\n\n\ndef finite_generator():\n # not blocking, so doesn't need to be async\n # but if it was blocking, you could make this async and await it\n x = 0\n while x < 10000:\n yield f\"{x}\"\n x += 1\n\n\nasync def astreamer(generator):\n try:\n # if it was an async generator we'd do:\n # \"async for data in generator:\"\n # (there is no yield from async_generator)\n for i in generator:\n yield i\n await asyncio.sleep(.001)\n\n except asyncio.CancelledError as e:\n print('cancelled')\n\n\ndef streamer(generator):\n try:\n # note: normally we would do \"yield from generator\"\n # but that won't work with next(generator) in the finally statement\n for i in generator:\n yield i\n time.sleep(.001)\n\n except GeneratorExit:\n print(\"cancelled\")\n finally:\n # showing that we can check here to see if all data was consumed\n # the except statement above effectively does the same thing\n try:\n next(generator)\n print(\"we didn't finish\")\n return\n except StopIteration:\n print(\"we finished\")\n\n\n@app.get(\"/infinite\")\nasync def infinite_stream():\n return StreamingResponse(streamer(infinite_generator()))\n\n\n@app.get(\"/finite\")\nasync def finite_stream():\n return StreamingResponse(streamer(finite_generator()))\n\n\n@app.get(\"/ainfinite\")\nasync def infinite_stream():\n return StreamingResponse(astreamer(infinite_generator()))\n\n\n@app.get(\"/afinite\")\nasync def finite_stream():\n return StreamingResponse(astreamer(finite_generator()))\n\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n```\n\n```text\nStopAsyncIteration\n```\n\n```text\nasyncio.CancelledError\n```\n\n```text\nBaseException\n```\n\n```text\nGeneratorExit\n```\n\n```text\nBaseException\n```\n\n```text\nStopIteration\n```\n\n```text\nException\n```\n\n========================================\n\nComments:\n- How does your `astreamer` leave the `async for`?\n- good question. I'm not entirely sure. It looks like it might get cancelled by this code here: github.com/encode/starlette/blob/master/starlette/… after that it would get canceled here: github.com/encode/starlette/blob/…\n- In newer Python `CancelledError` no longer inherits from `Exception` but from `BaseException`, which is why you don't see it in the `except` clause. Since an exception injected into the generator effectively leaves the `while` loop, the generator has no way of continuing execution...\n- huh... I didn't know about CancelledError and that perfectly explains why I wasn't able to catch the cancellation. That would certainly be a bit cleaner approach. I'm not sure I entirely the flow though with the while loop, unless that exception is actually being injected into the generator. I'm not sure where that would happen.\n- `CancelledError` is injected into any coroutine that gets cancelled, simply at the place where it awaits something (e.g. `sleep(.001)` in your case). So \"injected\" just means that, when someone cancels a coroutine, the `await` it was suspended in just magically (from the POV of the coroutine) resumes and raises a `CancelledError`. This error gets propagated to your consumer, and there is no way such a generator can ever continue because it is done executing, it raised an exception.","metadata":{"transformedAt":"2026-08-18T18:32:29.155Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":13,"totalLines":233,"estimatedTokens":1654}}680{"id":"stack-79063091","source":"stackoverflow","questionId":79063091,"title":"FastAPI stateful dependencies","tags":["python","fastapi"],"text":"Title: FastAPI stateful dependencies\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI've been reviewing the Depends docs, official example\n\n```\nfrom typing import Annotated\n\nfrom fastapi import Depends, FastAPI\n\napp = FastAPI()\n\nasync def common_parameters(q: str | None = None, skip: int = 0, limit: int = 100):\n return {\"q\": q, \"skip\": skip, \"limit\": limit}\n\n@app.get(\"/items/\")\nasync def read_items(commons: Annotated[dict, Depends(common_parameters)]):\n return commons\n```\n\nHowever, in my use case, I need to serve an ML model, which will be updated at a recurring cadence (hourly, daily, etc.) The solution from docs (above) depends on a callable function; I believe that it is cached not generated each time. Nonetheless, my use case is not some scaffolding that needs to go up/down with each invocation. But rather, I need a custom class with state. The idea is that the ML model (a class attribute) can be updated scheduled and/or async and the `./invocations/` method will serve said model, reflecting updates as they occur.\n\nIn current state, I use global variables. This works well when my entire application fits on a single script. However, as my application grows, I will be interested in using the router yet I'm concerned that `global state` will cause failures.\n\nIs there an appropriate way to pass a stateful instance of a class object across methods?\n\nSee example class and method\n\n```\nclass StateManager:\n def __init__(self):\n self.bucket = os.environ.get(\"BUCKET_NAME\", \"artifacts_bucket\")\n self.s3_model_path = \"./model.joblib\"\n self.local_model_path = './model.joblib'\n\n def get_clients(self):\n self.s3 = boto3.client('s3')\n\n def download_model(self):\n self.s3.download_file(self.bucket, self.s3_model_path, self.local_model_path)\n self.model = joblib.load(self.local_model_path)\n\n...\n\nstate = StateManager()\nstate.download_model()\n\n...\n\n@app.post(\"/invocations\")\ndef invocations(request: InferenceRequest):\n input_data = pd.DataFrame(dict(request), index=[0])\n try: \n predictions = state.model.predict(input_data)\n return JSONResponse({\"predictions\": predictions.tolist()},\n status_code=status.HTTP_200_OK)\n except Exception as e:\n return JSONResponse({\"error\": str(e)},\n status_code=status.HTTP_500_INTERNAL_SERVER_ERROR)\n```\n\n========================================\n\nCode:\n```py\nfrom typing import Annotated\n\nfrom fastapi import Depends, FastAPI\n\napp = FastAPI()\n\n\nasync def common_parameters(q: str | None = None, skip: int = 0, limit: int = 100):\n return {\"q\": q, \"skip\": skip, \"limit\": limit}\n\n\n@app.get(\"/items/\")\nasync def read_items(commons: Annotated[dict, Depends(common_parameters)]):\n return commons\n```\n\n```py\nclass StateManager:\n def __init__(self):\n self.bucket = os.environ.get(\"BUCKET_NAME\", \"artifacts_bucket\")\n self.s3_model_path = \"./model.joblib\"\n self.local_model_path = './model.joblib'\n\n def get_clients(self):\n self.s3 = boto3.client('s3')\n\n def download_model(self):\n self.s3.download_file(self.bucket, self.s3_model_path, self.local_model_path)\n self.model = joblib.load(self.local_model_path)\n\n...\n\nstate = StateManager()\nstate.download_model()\n\n...\n\n\n@app.post(\"/invocations\")\ndef invocations(request: InferenceRequest):\n input_data = pd.DataFrame(dict(request), index=[0])\n try: \n predictions = state.model.predict(input_data)\n return JSONResponse({\"predictions\": predictions.tolist()},\n status_code=status.HTTP_200_OK)\n except Exception as e:\n return JSONResponse({\"error\": str(e)},\n status_code=status.HTTP_500_INTERNAL_SERVER_ERROR)\n```\n\n```text\n./invocations/\n```\n\n```text\nglobal state\n```\n\n```py\nimport asyncio\nfrom contextlib import asynccontextmanager\nfrom fastapi import FastAPI, Depends, Request\nfrom typing import AsyncIterator, TypedDict\nimport joblib\nimport boto3\nimport os\n\nclass State(TypedDict):\n model: any\n\nclass StateManager:\n def __init__(self):\n self.bucket = os.environ.get(\"BUCKET_NAME\", \"artifacts_bucket\")\n self.s3_model_path= \"./model.joblib\"\n self.local_model_path = './model.joblib'\n\n def get_clients(self):\n self.s3 = boto3.client('s3')\n\n def download_model(self):\n self.s3.download_file(self.bucket, self.s3_model_path, self.local_model_path)\n self.model = joblib.load(self.local_model_path)\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI) -> AsyncIterator[State]:\n state_manager =StateManager()\n state_manager.get_clients()\n state_manager.download_model()\n \n state: State ={\n \"model\": state_manager.model\n }\n yield state\n\napp = FastAPI(lifespan=lifespan)\n```\n\n```py\nfrom fastapi import Request\n\n\ndef get_model(request: Request):\n return request.app.state.model\n```\n\n```py\n@app.post(\"/invocations\")\nasync def invocations(request: InferenceRequest, model = Depends(get_model)):\n ...\n```\n\n```py\nclass StateManager:\n ...\n async def update_model_periodically(self, interval: int = 3600):\n while True:\n self.download_model()\n print(\"Model updated...\")\n await asyncio.sleep(interval)\n```\n\n```py\n@asynccontextmanager\nasync def lifespan(app: FastAPI):\n ...\n asyncio.create_task(state_manager.update_model_periodically(interval=3600))\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.155Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":194,"estimatedTokens":1330}}681{"id":"stack-79694182","source":"stackoverflow","questionId":79694182,"title":"Memory Not Released After Each Request Despite Cleanup Attempts","tags":["python","fastapi","python-polars","pyarrow"],"text":"Title: Memory Not Released After Each Request Despite Cleanup Attempts\nTags: python, fastapi, python-polars, pyarrow\nSource: Stack Overflow\n\nQuestion:\nWe're running a FastAPI service that fetches data from Trino, processes it using PyArrow and Polars, and uploads the result to AWS S3 in Parquet format. However, we're facing a persistent issue where memory is not released after each request, even after explicitly attempting cleanup.\n\nArchitecture overview:\n\n- Framework: FastAPI\n\n- Data Source: Trino\n\n- Processing: PyArrow, Polars\n\n- Storage: AWS S3 (Parquet format)\n\nFlow:\n\n- API receives a request\n\n- Fetch data from Trino\n\n- Convert to PyArrow Table\n\n- Upload to S3 using `write_to_dataset`\n\n- Attempt memory cleanup\n\nWe've tried:\n\nUsing del to delete large objects\n\nDeleted PyArrow tables and Polars DataFrames after upload.\n\n```\nimport pyarrow as pa\nimport pyarrow.parquet as pq\nimport pyarrow.fs as pafs\n# Fetch and process data\ndata = fetch_data_from_trino()\narrow_table = pa.table(list(zip(*data)))\n# Initialize S3 filesystem with optimal configuration for high-performance writes\ns3_filesystem = pafs.S3FileSystem()\n# Upload to S3\npq.write_to_dataset(\n arrow_table,\n root_path=f\"{RESULT_STORAGE_BUCKET}/{s3_storage_path}\",\n partition_cols=['organisation'],\n filesystem=s3_filesystem\n)\n# Attempt to free memory\ndel data\ndel arrow_table\n```\n\nObservation: Memory usage remained high even after deletion.\n\n```\n\"resource_stats\": { \n \"memory_mb\": { \n \"start\": 140.3004568,\n \"peak\": 589.02921865, \n \"end\": 587.01258 \n } \n}\n```\n\nForcing garbage collection with `gc.collect()`\n\nCalled after `del`.\n\n```\nimport os\nimport psutil\n\ndef force_garbage_collection_and_cleanup() -> Dict[str, int]:\n try:\n # Get memory usage before cleanup\n memory_before = psutil.Process(os.getpid()).memory_info().rss / (1024 ** 2)\n\n # Force garbage collection - run multiple times for thorough cleanup\n objects_collected = 0\n for _ in range(3): # Run GC multiple times for better cleanup\n collected = gc.collect()\n objects_collected += collected\n\n # Get memory usage after cleanup\n memory_after = psutil.Process(os.getpid()).memory_info().rss / (1024 ** 2)\n\n except Exception as cleanup_error:\n logger.warning(f\"Failed to perform garbage collection: {str(cleanup_error)}\")\n```\n\nObservation: no significant drop in memory usage.\n\n```\n\"resource_stats\": { \n \"memory_mb\": {\n \"start\": 190.56,\n \"peak\": 579.6, \n \"end\": 579.7 \n } \n}\n```\n\nManual memory release with `malloc_trim` and deep GC\n\nCustom `force_memory_release()` function:\n\n- Runs `gc.collect()` across all generations\n\n- Calls `malloc_trim(0)` (Linux)\n\n```\nimport gc\nimport sys\nimport psutil\nimport platform\nimport ctypes\n\ndef force_memory_release():\n \"\"\"\n Force Python to release memory back to the operating system.\n\n This method:\n 1. Runs garbage collection multiple times to ensure all unreferenced objects are cleaned\n 2. On Linux (ECS), calls malloc_trim() to force glibc to release memory to OS\n 3. Tracks and reports memory freed\n\n Returns:\n dict: Memory statistics before and after cleanup\n \"\"\"\n # Get memory usage before cleanup\n process = psutil.Process()\n memory_before_mb = process.memory_info().rss / 1024 / 1024\n\n # Force garbage collection multiple times\n # First pass: collect unreferenced objects\n collected_gen0 = gc.collect(0) # Young generation\n collected_gen1 = gc.collect(1) # Middle generation\n collected_gen2 = gc.collect(2) # Old generation\n\n # Second pass: ensure all cyclic references are broken\n collected_final = gc.collect()\n\n total_objects_collected = collected_gen0 + collected_gen1 + collected_gen2 + collected_final\n\n # Force memory release to OS on Linux systems (ECS containers)\n malloc_trim_success = False\n if platform.system() == 'Linux':\n try:\n # Load glibc and call malloc_trim to release memory to OS\n libc = ctypes.CDLL(\"libc.so.6\")\n malloc_trim = libc.malloc_trim\n malloc_trim.argtypes = [ctypes.c_size_t]\n malloc_trim.restype = ctypes.c_int\n\n # malloc_trim(0) releases all possible memory to OS\n result = malloc_trim(0)\n malloc_trim_success = bool(result)\n\n if malloc_trim_success:\n print(\"Successfully called malloc_trim() to release memory to OS\")\n else:\n print(\"malloc_trim() was called but returned 0 (no memory released)\")\n\n except Exception as e:\n print(f\"Could not call malloc_trim(): {e}\")\n malloc_trim_success = False\n\n # Get memory usage after cleanup\n memory_after_mb = process.memory_info().rss / 1024 / 1024\n memory_freed_mb = max(0, memory_before_mb - memory_after_mb)\n\n cleanup_stats = {\n 'objects_collected': total_objects_collected,\n 'memory_before_mb': round(memory_before_mb, 2),\n 'memory_after_mb': round(memory_after_mb, 2),\n 'memory_freed_mb': round(memory_freed_mb, 2),\n 'malloc_trim_success': malloc_trim_success,\n 'platform': platform.system()\n }\n\n print(\n f\"Memory cleanup completed: \"\n f\"Objects collected: {total_objects_collected}, \"\n f\"Memory freed: {memory_freed_mb:.2f}MB \"\n f\"({memory_before_mb:.2f}MB -> {memory_after_mb:.2f}MB), \"\n f\"malloc_trim: {'success' if malloc_trim_success else 'not available/failed'}\"\n )\n\n return cleanup_stats\n\nforce_memory_release()\n```\n\nObservation: this method showed partial success in reducing memory usage. However, memory was not fully returned to baseline, indicating potential native memory fragmentation or memory held by external libraries.\n\n```\n\"resource_stats\": { \n \"memory_mb\": { \n \"start\": 216.47,\n \"peak\": 460, \n \"end\": 460 \n } \n}\n```\n\nPeriodic memory cleanup script\n\nBackground script runs every 10 seconds:\n\n- Triggers GC\n\n- Attempts to release PyArrow memory\n\n- Calls `malloc_trim`\n\n```\n#!/bin/bash\n\n# Run a Python script that performs memory cleanup\n/usr/local/bin/python3 Observation: while PyArrow memory usage dropped significantly, RSS memory did not fully return to baseline. This suggests native memory fragmentation or memory still held by other libraries.\n\n```\n\"resource_stats\": { \n \"memory_mb\": { \n \"start\": 141.30078125,\n \"peak\": 634.94921875, \n \"end\": 635.0 \n } \n}\n```\n\nQuestions:\n\n- What could be causing memory to remain high after each request, even after aggressive cleanup attempts?\n\n- Are there known memory retention issues with PyArrow, Polars, or Trino clients in long-running FastAPI services?\n\n- Any best practices for managing native memory in such a pipeline?\n\n========================================\n\nCode:\n```py\nimport pyarrow as pa\nimport pyarrow.parquet as pq\nimport pyarrow.fs as pafs\n# Fetch and process data\ndata = fetch_data_from_trino()\narrow_table = pa.table(list(zip(*data)))\n# Initialize S3 filesystem with optimal configuration for high-performance writes\ns3_filesystem = pafs.S3FileSystem()\n# Upload to S3\npq.write_to_dataset(\n arrow_table,\n root_path=f\"{RESULT_STORAGE_BUCKET}/{s3_storage_path}\",\n partition_cols=['organisation'],\n filesystem=s3_filesystem\n)\n# Attempt to free memory\ndel data\ndel arrow_table\n```\n\n```json\n\"resource_stats\": { \n \"memory_mb\": { \n \"start\": 140.3004568,\n \"peak\": 589.02921865, \n \"end\": 587.01258 \n } \n}\n```\n\n```py\nimport os\nimport psutil\n\n\ndef force_garbage_collection_and_cleanup() -> Dict[str, int]:\n try:\n # Get memory usage before cleanup\n memory_before = psutil.Process(os.getpid()).memory_info().rss / (1024 ** 2)\n\n # Force garbage collection - run multiple times for thorough cleanup\n objects_collected = 0\n for _ in range(3): # Run GC multiple times for better cleanup\n collected = gc.collect()\n objects_collected += collected\n\n # Get memory usage after cleanup\n memory_after = psutil.Process(os.getpid()).memory_info().rss / (1024 ** 2)\n\n except Exception as cleanup_error:\n logger.warning(f\"Failed to perform garbage collection: {str(cleanup_error)}\")\n```\n\n```json\n\"resource_stats\": { \n \"memory_mb\": {\n \"start\": 190.56,\n \"peak\": 579.6, \n \"end\": 579.7 \n } \n}\n```\n\n```py\nimport gc\nimport sys\nimport psutil\nimport platform\nimport ctypes\n\n\ndef force_memory_release():\n \"\"\"\n Force Python to release memory back to the operating system.\n\n This method:\n 1. Runs garbage collection multiple times to ensure all unreferenced objects are cleaned\n 2. On Linux (ECS), calls malloc_trim() to force glibc to release memory to OS\n 3. Tracks and reports memory freed\n\n Returns:\n dict: Memory statistics before and after cleanup\n \"\"\"\n # Get memory usage before cleanup\n process = psutil.Process()\n memory_before_mb = process.memory_info().rss / 1024 / 1024\n\n # Force garbage collection multiple times\n # First pass: collect unreferenced objects\n collected_gen0 = gc.collect(0) # Young generation\n collected_gen1 = gc.collect(1) # Middle generation\n collected_gen2 = gc.collect(2) # Old generation\n\n # Second pass: ensure all cyclic references are broken\n collected_final = gc.collect()\n\n total_objects_collected = collected_gen0 + collected_gen1 + collected_gen2 + collected_final\n\n # Force memory release to OS on Linux systems (ECS containers)\n malloc_trim_success = False\n if platform.system() == 'Linux':\n try:\n # Load glibc and call malloc_trim to release memory to OS\n libc = ctypes.CDLL(\"libc.so.6\")\n malloc_trim = libc.malloc_trim\n malloc_trim.argtypes = [ctypes.c_size_t]\n malloc_trim.restype = ctypes.c_int\n\n # malloc_trim(0) releases all possible memory to OS\n result = malloc_trim(0)\n malloc_trim_success = bool(result)\n\n if malloc_trim_success:\n print(\"Successfully called malloc_trim() to release memory to OS\")\n else:\n print(\"malloc_trim() was called but returned 0 (no memory released)\")\n\n except Exception as e:\n print(f\"Could not call malloc_trim(): {e}\")\n malloc_trim_success = False\n\n # Get memory usage after cleanup\n memory_after_mb = process.memory_info().rss / 1024 / 1024\n memory_freed_mb = max(0, memory_before_mb - memory_after_mb)\n\n cleanup_stats = {\n 'objects_collected': total_objects_collected,\n 'memory_before_mb': round(memory_before_mb, 2),\n 'memory_after_mb': round(memory_after_mb, 2),\n 'memory_freed_mb': round(memory_freed_mb, 2),\n 'malloc_trim_success': malloc_trim_success,\n 'platform': platform.system()\n }\n\n print(\n f\"Memory cleanup completed: \"\n f\"Objects collected: {total_objects_collected}, \"\n f\"Memory freed: {memory_freed_mb:.2f}MB \"\n f\"({memory_before_mb:.2f}MB -> {memory_after_mb:.2f}MB), \"\n f\"malloc_trim: {'success' if malloc_trim_success else 'not available/failed'}\"\n )\n\n return cleanup_stats\n\n\nforce_memory_release()\n```\n\n```json\n\"resource_stats\": { \n \"memory_mb\": { \n \"start\": 216.47,\n \"peak\": 460, \n \"end\": 460 \n } \n}\n```\n\n```bash\n#!/bin/bash\n\n# Run a Python script that performs memory cleanup\n/usr/local/bin/python3 <<EOF\nimport gc\nimport pyarrow as pa\nimport psutil\nimport os\nimport ctypes\nimport time\n\ndef log(msg):\n print(f\"[{time.strftime('%Y-%m-%d %H:%M:%S')}] {msg}\")\n\nprocess = psutil.Process(os.getpid())\nrss_before = process.memory_info().rss / (1024 ** 2)\narrow_before = pa.total_allocated_bytes() / (1024 ** 2)\n\nlog(f\"Memory before cleanup: {rss_before:.2f} MB (RSS), {arrow_before:.2f} MB (PyArrow)\")\n\n# Perform garbage collection\ngc.collect()\n\n# Release unused memory from PyArrow\npa.default_memory_pool().release_unused()\n\n# Try to return memory to OS (glibc only)\ntry:\n ctypes.CDLL(\"libc.so.6\").malloc_trim(0)\nexcept Exception as e:\n log(f\"malloc_trim failed: {e}\")\n\nrss_after = process.memory_info().rss / (1024 ** 2)\narrow_after = pa.total_allocated_bytes() / (1024 ** 2)\n\nlog(f\"Memory after cleanup: {rss_after:.2f} MB (RSS), {arrow_after:.2f} MB (PyArrow)\")\nEOF\n```\n\n```json\n\"resource_stats\": { \n \"memory_mb\": { \n \"start\": 141.30078125,\n \"peak\": 634.94921875, \n \"end\": 635.0 \n } \n}\n```\n\n```text\nwrite_to_dataset\n```\n\n```text\ngc.collect()\n```\n\n```text\ndel\n```\n\n```text\nmalloc_trim\n```\n\n```text\nforce_memory_release()\n```\n\n```text\ngc.collect()\n```\n\n```text\nmalloc_trim(0)\n```\n\n```text\nmalloc_trim\n```\n\n```text\nimport pyarrow as pa\nimport pyarrow.parquet as pq\nimport pyarrow.fs as pafs\nfrom multiprocessing import Process\nimport gc\nimport ctypes\n\ndef worker(data, s3_path, bucket):\n # Process data\n arrow_table = pa.table(list(zip(*data)))\n\n # Upload to S3\n s3_filesystem = pafs.S3FileSystem()\n pq.write_to_dataset(\n arrow_table,\n root_path=f\"{bucket}/{s3_path}\",\n partition_cols=['organisation'],\n filesystem=s3_filesystem\n )\n\n # Force cleanup\n ## add your cleanup logic\n ## Even if memory is not released by it\n ## once the subprocess exist memory will be released\n gc.collect()\n try:\nctypes.CDLL(\"libc.so.6\").malloc_trim(0)\n except:\n pass # Not on Linux or malloc_trim unsupported\n \n\n# Prepare args\ndata = fetch_data_from_trino()\ns3_path = \"output/\"\nbucket = \"s3://my-bucket\"\n\n# Launch subprocess\np = Process(target=worker, args=(data, s3_path, bucket))\np.start()\np.join()\n```\n\n========================================\n\nComments:\n- What's your fastapi route(s) look like? The issue you're facing seems like a memory leak which, unfortunately, can't be remedied by manually invoking `gc`, `del` or otherwise. I've seen other memory complaints about fastapi and polars although I'm not sure how/if they were resolved. I think, if you move execution of the operation which leaks to its own process then the leak won't accumulate.\n- I think you should check memory after having some time delay after the del statements. Freeing up memory can take some time and its good to have time delay before you check memory usage. Clearing memory can take some secs depending on the hardware.\n- This might help as well.\n- Hey @Aren, Yes this kind of work for me, But I did a couple of changes in adding some batches to process the data to s3. and all good. Thanks.\n- @DonOfDen Your welcome, It seems like an hack but will work just fine you can even set it up to monitor each subprocess + their result\n- @Aren this is great solution but I have problem where I am not able to implement sub process. Would you like to address stackoverflow.com/q/79729226/9541464","metadata":{"transformedAt":"2026-08-18T18:32:29.155Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":17,"totalLines":539,"estimatedTokens":4488}}682{"id":"stack-65051581","source":"stackoverflow","questionId":65051581,"title":"How to trigger lifespan startup and shutdown while testing FastAPI app?","tags":["python","testing","redis","pytest","fastapi"],"text":"Title: How to trigger lifespan startup and shutdown while testing FastAPI app?\nTags: python, testing, redis, pytest, fastapi\nSource: Stack Overflow\n\nQuestion:\nBeing very new to FastAPI I am strugling to test slightly more difficult code than I saw in the tutorial. I use `fastapi_cache` module and Redis like this:\n\n```\nfrom fastapi import Depends, FastAPI, Query, Request\nfrom fastapi_cache.backends.redis import CACHE_KEY, RedisCacheBackend\nfrom fastapi_cache import caches, close_caches\n\napp = FastAPI()\n\ndef redis_cache():\n return caches.get(CACHE_KEY) \n\n@app.get('/cache')\nasync def test(\n cache: RedisCacheBackend = Depends(redis_cache),\n n: int = Query(\n ..., \n gt=-1\n )\n): \n # code that uses redis cache\n\n@app.on_event('startup')\nasync def on_startup() -> None:\n rc = RedisCacheBackend('redis://redis')\n caches.set(CACHE_KEY, rc)\n\n@app.on_event('shutdown')\nasync def on_shutdown() -> None:\n await close_caches()\n```\n\ntest_main.py looks like this:\n\n```\nimport pytest\nfrom httpx import AsyncClient\nfrom .main import app\n\n@pytest.mark.asyncio\nasync def test_cache():\n async with AsyncClient(app=app, base_url=\"http://test\") as ac:\n response = await ac.get(\"/cache?n=150\")\n```\n\nWhen I run `pytest`, it sets `cache` variable to `None` and test fails. I think I understand why the code is not working. But how do I fix it to test my caching properly?\n\n========================================\n\nTop Answer:\nIn case if you don't want to add dependency just for a tests, here is the simple implementation for `asyncio`:\n\n```\nimport asyncio\n\nclass LifespanWaiter:\n def __init__(self, app):\n self.app = app\n self.startup = asyncio.Future()\n self.shutdown = asyncio.Future()\n\n async def send(self, obj):\n if obj['type'] == 'lifespan.startup.complete':\n self.startup.set_result(None)\n\n async def receive(self):\n if self.startup.done():\n await self.shutdown\n\n async def __aenter__(self):\n asyncio.create_task(\n self.app({\"type\": \"lifespan\"}, receive=self.receive, send=self.send)\n )\n await self.startup\n return self\n\n async def __aexit__(self, exc_type, exc_val, exc_tb):\n self.shutdown.set_result(None)\n```\n\nI use it like this:\n\n```\n@fixture(scope='session')\nasync def app(test_db_name):\n \"\"\"Creates app instance and apply migrations.\n \"\"\"\n DATABASES[\"db_options\"][\"database\"] = test_db_name\n\n app = make_app()\n\n @app.on_event(\"startup\")\n async def db_setup():\n async with app.state.db_pool.acquire() as conn:\n await apply_migrations(conn, 'local')\n\n async with LifespanWaiter(app):\n yield app\n\n@fixture(scope='session')\nasync def client(app: FastAPI):\n async with AsyncClient(app=app, base_url=\"http://test\") as client:\n yield client\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi import Depends, FastAPI, Query, Request\nfrom fastapi_cache.backends.redis import CACHE_KEY, RedisCacheBackend\nfrom fastapi_cache import caches, close_caches\n\napp = FastAPI()\n\ndef redis_cache():\n return caches.get(CACHE_KEY) \n\n@app.get('/cache')\nasync def test(\n cache: RedisCacheBackend = Depends(redis_cache),\n n: int = Query(\n ..., \n gt=-1\n )\n): \n # code that uses redis cache\n\n@app.on_event('startup')\nasync def on_startup() -> None:\n rc = RedisCacheBackend('redis://redis')\n caches.set(CACHE_KEY, rc)\n\n@app.on_event('shutdown')\nasync def on_shutdown() -> None:\n await close_caches()\n```\n\n```text\nimport pytest\nfrom httpx import AsyncClient\nfrom .main import app\n\n@pytest.mark.asyncio\nasync def test_cache():\n async with AsyncClient(app=app, base_url=\"http://test\") as ac:\n response = await ac.get(\"/cache?n=150\")\n```\n\n```text\nfastapi_cache\n```\n\n```text\npytest\n```\n\n```text\ncache\n```\n\n```text\nNone\n```\n\n```text\nimport pytest\nfrom asgi_lifespan import LifespanManager\nfrom httpx import AsyncClient\nfrom .main import app\n\n\n@pytest.mark.asyncio\nasync def test_cache():\n async with LifespanManager(app):\n async with AsyncClient(app=app, base_url=\"http://localhost\") as ac:\n response = await ac.get(\"/cache\")\n```\n\n```text\nhttpx\n```\n\n```text\nstartup\n```\n\n```text\nLifespanManager\n```\n\n```text\npip install asgi_lifespan\n```\n\n```py\nimport asyncio\n\n\nclass LifespanWaiter:\n def __init__(self, app):\n self.app = app\n self.startup = asyncio.Future()\n self.shutdown = asyncio.Future()\n\n async def send(self, obj):\n if obj['type'] == 'lifespan.startup.complete':\n self.startup.set_result(None)\n\n async def receive(self):\n if self.startup.done():\n await self.shutdown\n\n async def __aenter__(self):\n asyncio.create_task(\n self.app({\"type\": \"lifespan\"}, receive=self.receive, send=self.send)\n )\n await self.startup\n return self\n\n async def __aexit__(self, exc_type, exc_val, exc_tb):\n self.shutdown.set_result(None)\n```\n\n```py\n@fixture(scope='session')\nasync def app(test_db_name):\n \"\"\"Creates app instance and apply migrations.\n \"\"\"\n DATABASES[\"db_options\"][\"database\"] = test_db_name\n\n app = make_app()\n\n @app.on_event(\"startup\")\n async def db_setup():\n async with app.state.db_pool.acquire() as conn:\n await apply_migrations(conn, 'local')\n\n async with LifespanWaiter(app):\n yield app\n\n\n@fixture(scope='session')\nasync def client(app: FastAPI):\n async with AsyncClient(app=app, base_url=\"http://test\") as client:\n yield client\n```\n\n```text\nasyncio\n```\n\n```py\nfrom fastapi.testclient import TestClient\n\nfrom app.main import app\n\ndef test_read_prediction():\nwith TestClient(app) as client:\nmodel_input= \"test\"\nresponse = client.get(f\"/prediction/?model_input={model_input}\")\nassert response.status_code == 200\n```\n\n```text\nTestClient\n```\n\n========================================\n\nComments:\n- I am using pytest 8.3.3, there seem to be no `pytest.mark.asyncio`.","metadata":{"transformedAt":"2026-08-18T18:32:29.156Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":16,"totalLines":277,"estimatedTokens":1450}}683{"id":"stack-69543228","source":"stackoverflow","questionId":69543228,"title":"Trouble fixing \"'cannot convert dictionary update sequence element #0 to a sequence'\" with Uvicorn","tags":["python","tensorflow","server","fastapi","uvicorn"],"text":"Title: Trouble fixing \"'cannot convert dictionary update sequence element #0 to a sequence'\" with Uvicorn\nTags: python, tensorflow, server, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI have the following code with FastApi and Uvicorn for ASGI sever implementation. It's supposed to take an uploaded image via post request and classify it with a model before returning a response. The error seems related to Uvicorn but I am at a loss. Any help would be much appreciated. Has anyone seen an error like this before? Here is the code:\n\n```\nimport uvicorn\nfrom fastapi import FastAPI, File, UploadFile\nimport sys\n\nfrom PIL import Image\nfrom io import BytesIO\nimport numpy as np\n\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras import layers\nimport matplotlib.pyplot as plt\nfrom tensorflow.keras.preprocessing import image\nimport PIL\nimport sys \nfrom cv2 import cv2\nfrom scipy import misc\nimport os\n\nimport shutil\nfrom pathlib import Path\nfrom tempfile import NamedTemporaryFile\nfrom typing import Callable\n\napp = FastAPI()\n\nmodel = keras.models.load_model('best_model6.h5')\ninput_shape = (180, 180) \n\n@app.post('/api/predict')\nasync def predict_image(file: UploadFile = File(...)):\n\n suffix = Path(file.filename).suffix\n\n with NamedTemporaryFile(delete=False, suffix=suffix) as tmp:\n shutil.copyfileobj(file.file, tmp)\n tmp_path = Path(tmp.name)\n \n img = keras.preprocessing.image.load_img(\n tmp_path, target_size=input_shape\n)\n \n img_array = image.img_to_array(img)\n\n img_array = tf.expand_dims(img_array, 0) # Create batch axis\n\n predictions = model.predict(img_array)\n score = predictions[0]\n\n file.file.close()\n tmp_path.unlink()\n \n return score\n\nif __name__ == \"__main__\":\n uvicorn.run(app, port=8080, host='0.0.0.0', debug=True)\n```\n\nThe error is:\n\n```\nValueError: [TypeError('cannot convert dictionary update sequence element #0 to a sequence'), TypeError('vars() argument must have __dict__ attribute')]\n```\n\nAnd the whole traceback:\n\n```\nTraceback (most recent call last):\n File \"/Users/.../Desktop/project/venv/lib/python3.9/site-packages/uvicorn/protocols/http/h11_impl.py\", line 373, in run_asgi\n result = await app(self.scope, self.receive, self.send)\n File \"/Users/.../Desktop/project/venv/lib/python3.9/site-packages/uvicorn/middleware/proxy_headers.py\", line 75, in __call__\n return await self.app(scope, receive, send)\n File \"/Users/.../Desktop/project/venv/lib/python3.9/site-packages/uvicorn/middleware/debug.py\", line 96, in __call__\n raise exc from None\n File \"/Users/.../Desktop/project/venv/lib/python3.9/site-packages/uvicorn/middleware/debug.py\", line 93, in __call__\n await self.app(scope, receive, inner_send)\n File \"/Users/.../Desktop/project/venv/lib/python3.9/site-packages/fastapi/applications.py\", line 208, in __call__\n await super().__call__(scope, receive, send)\n File \"/Users/.../Desktop/project/venv/lib/python3.9/site-packages/starlette/applications.py\", line 112, in __call__\n await self.middleware_stack(scope, receive, send)\n File \"/Users/.../Desktop/project/venv/lib/python3.9/site-packages/starlette/middleware/errors.py\", line 181, in __call__\n raise exc\n File \"/Users/.../Desktop/project/venv/lib/python3.9/site-packages/starlette/middleware/errors.py\", line 159, in __call__\n await self.app(scope, receive, _send)\n File \"/Users/.../Desktop/project/venv/lib/python3.9/site-packages/starlette/exceptions.py\", line 82, in __call__\n raise exc\n File \"/Users/.../Desktop/project/venv/lib/python3.9/site-packages/starlette/exceptions.py\", line 71, in __call__\n await self.app(scope, receive, sender)\n File \"/Users/.../Desktop/project/venv/lib/python3.9/site-packages/starlette/routing.py\", line 656, in __call__\n await route.handle(scope, receive, send)\n File \"/Users/.../Desktop/project/venv/lib/python3.9/site-packages/starlette/routing.py\", line 259, in handle\n await self.app(scope, receive, send)\n File \"/Users/.../Desktop/project/venv/lib/python3.9/site-packages/starlette/routing.py\", line 61, in app\n response = await func(request)\n File \"/Users/.../Desktop/project/venv/lib/python3.9/site-packages/fastapi/routing.py\", line 234, in app\n response_data = await serialize_response(\n File \"/Users/.../Desktop/project/venv/lib/python3.9/site-packages/fastapi/routing.py\", line 148, in serialize_response\n return jsonable_encoder(response_content)\n File \"/Users/.../Desktop/project/venv/lib/python3.9/site-packages/fastapi/encoders.py\", line 144, in jsonable_encoder\n raise ValueError(errors)\nValueError: [TypeError('cannot convert dictionary update sequence element #0 to a sequence'), TypeError('vars() argument must have __dict__ attribute')]\n```\n\n========================================\n\nCode:\n```text\nimport uvicorn\nfrom fastapi import FastAPI, File, UploadFile\nimport sys\n\nfrom PIL import Image\nfrom io import BytesIO\nimport numpy as np\n\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras import layers\nimport matplotlib.pyplot as plt\nfrom tensorflow.keras.preprocessing import image\nimport PIL\nimport sys \nfrom cv2 import cv2\nfrom scipy import misc\nimport os\n\nimport shutil\nfrom pathlib import Path\nfrom tempfile import NamedTemporaryFile\nfrom typing import Callable\n\napp = FastAPI()\n\nmodel = keras.models.load_model('best_model6.h5')\ninput_shape = (180, 180) \n\n@app.post('/api/predict')\nasync def predict_image(file: UploadFile = File(...)):\n\n suffix = Path(file.filename).suffix\n\n with NamedTemporaryFile(delete=False, suffix=suffix) as tmp:\n shutil.copyfileobj(file.file, tmp)\n tmp_path = Path(tmp.name)\n \n img = keras.preprocessing.image.load_img(\n tmp_path, target_size=input_shape\n)\n \n img_array = image.img_to_array(img)\n\n img_array = tf.expand_dims(img_array, 0) # Create batch axis\n\n predictions = model.predict(img_array)\n score = predictions[0]\n\n file.file.close()\n tmp_path.unlink()\n \n return score\n\n\nif __name__ == \"__main__\":\n uvicorn.run(app, port=8080, host='0.0.0.0', debug=True)\n```\n\n```text\nValueError: [TypeError('cannot convert dictionary update sequence element #0 to a sequence'), TypeError('vars() argument must have __dict__ attribute')]\n```\n\n```text\nTraceback (most recent call last):\n File \"/Users/.../Desktop/project/venv/lib/python3.9/site-packages/uvicorn/protocols/http/h11_impl.py\", line 373, in run_asgi\n result = await app(self.scope, self.receive, self.send)\n File \"/Users/.../Desktop/project/venv/lib/python3.9/site-packages/uvicorn/middleware/proxy_headers.py\", line 75, in __call__\n return await self.app(scope, receive, send)\n File \"/Users/.../Desktop/project/venv/lib/python3.9/site-packages/uvicorn/middleware/debug.py\", line 96, in __call__\n raise exc from None\n File \"/Users/.../Desktop/project/venv/lib/python3.9/site-packages/uvicorn/middleware/debug.py\", line 93, in __call__\n await self.app(scope, receive, inner_send)\n File \"/Users/.../Desktop/project/venv/lib/python3.9/site-packages/fastapi/applications.py\", line 208, in __call__\n await super().__call__(scope, receive, send)\n File \"/Users/.../Desktop/project/venv/lib/python3.9/site-packages/starlette/applications.py\", line 112, in __call__\n await self.middleware_stack(scope, receive, send)\n File \"/Users/.../Desktop/project/venv/lib/python3.9/site-packages/starlette/middleware/errors.py\", line 181, in __call__\n raise exc\n File \"/Users/.../Desktop/project/venv/lib/python3.9/site-packages/starlette/middleware/errors.py\", line 159, in __call__\n await self.app(scope, receive, _send)\n File \"/Users/.../Desktop/project/venv/lib/python3.9/site-packages/starlette/exceptions.py\", line 82, in __call__\n raise exc\n File \"/Users/.../Desktop/project/venv/lib/python3.9/site-packages/starlette/exceptions.py\", line 71, in __call__\n await self.app(scope, receive, sender)\n File \"/Users/.../Desktop/project/venv/lib/python3.9/site-packages/starlette/routing.py\", line 656, in __call__\n await route.handle(scope, receive, send)\n File \"/Users/.../Desktop/project/venv/lib/python3.9/site-packages/starlette/routing.py\", line 259, in handle\n await self.app(scope, receive, send)\n File \"/Users/.../Desktop/project/venv/lib/python3.9/site-packages/starlette/routing.py\", line 61, in app\n response = await func(request)\n File \"/Users/.../Desktop/project/venv/lib/python3.9/site-packages/fastapi/routing.py\", line 234, in app\n response_data = await serialize_response(\n File \"/Users/.../Desktop/project/venv/lib/python3.9/site-packages/fastapi/routing.py\", line 148, in serialize_response\n return jsonable_encoder(response_content)\n File \"/Users/.../Desktop/project/venv/lib/python3.9/site-packages/fastapi/encoders.py\", line 144, in jsonable_encoder\n raise ValueError(errors)\nValueError: [TypeError('cannot convert dictionary update sequence element #0 to a sequence'), TypeError('vars() argument must have __dict__ attribute')]\n```\n\n```text\nscore.tolist()\n```\n\n========================================\n\nComments:\n- This was very helpful, thank you! score.tolist() didn't work but directly building a json object with json.dumps and returning that did the trick, so your suggestion was on point.\n- Cool. trouble fixed","metadata":{"transformedAt":"2026-08-18T18:32:29.156Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":224,"estimatedTokens":2284}}684{"id":"stack-67932330","source":"stackoverflow","questionId":67932330,"title":"How to restrict content-type in FastAPI request header","tags":["python","fastapi"],"text":"Title: How to restrict content-type in FastAPI request header\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm quite new to the FastAPI framework, I want to restrict my request header content type with \"application/vnd.api+json\", But I can't able to find a way to configure my content type with the Fast API route instance.\n\nAny info will be really useful.\n\n========================================\n\nTop Answer:\nA better approach is to declare dependency:\n\n```\nfrom fastapi import FastAPI, HTTPException, status, Header, Depends\n\napp = FastAPI()\n\ndef application_vnd(content_type: str = Header(...)):\n \"\"\"Require request MIME-type to be application/vnd.api+json\"\"\"\n\n if content_type != \"application/vnd.api+json\":\n raise HTTPException(\n status.HTTP_415_UNSUPPORTED_MEDIA_TYPE,\n f\"Unsupported media type: {content_type}.\"\n \" It must be application/vnd.api+json\",\n )\n\n@app.post(\"/some-path\", dependencies=[Depends(application_vnd)])\ndef some_path(q: str = None):\n return {\"result\": \"All is OK!\", \"q\": q}\n```\n\nSo it can be reused if needed.\n\nFor successful request it'll return something like this:\n\n```\n{\n \"result\": \"All is OK!\",\n \"q\": \"Some query\"\n}\n```\n\nAnd for unsuccessful something like this:\n\n```\n{\n \"detail\": \"Unsupported media type: type/unknown-type. It must be application/vnd.api+json\"\n}\n```\n\n========================================\n\nCode:\n```py\nimport uvicorn\nfrom fastapi import FastAPI, HTTPException\nfrom starlette import status\n\nfrom starlette.requests import Request\n\napp = FastAPI()\n\n\n@app.get(\"/hello\")\nasync def hello(request: Request):\n content_type = request.headers.get(\"content-type\", None)\n if content_type != \"application/vnd.api+json\":\n raise HTTPException(\n status_code=status.HTTP_415_UNSUPPORTED_MEDIA_TYPE,\n detail=f\"Unsupported media type {content_type}\")\n\n return {\"content-type\": content_type}\n\n\nif __name__ == '__main__':\n uvicorn.run(\"main\", host=\"127.0.0.1\", port=8080)\n```\n\n```text\ncontent-type\n```\n\n```py\nfrom fastapi import FastAPI, HTTPException, status, Header, Depends\n\n\napp = FastAPI()\n\n\ndef application_vnd(content_type: str = Header(...)):\n \"\"\"Require request MIME-type to be application/vnd.api+json\"\"\"\n\n if content_type != \"application/vnd.api+json\":\n raise HTTPException(\n status.HTTP_415_UNSUPPORTED_MEDIA_TYPE,\n f\"Unsupported media type: {content_type}.\"\n \" It must be application/vnd.api+json\",\n )\n\n\n@app.post(\"/some-path\", dependencies=[Depends(application_vnd)])\ndef some_path(q: str = None):\n return {\"result\": \"All is OK!\", \"q\": q}\n```\n\n```json\n{\n \"result\": \"All is OK!\",\n \"q\": \"Some query\"\n}\n```\n\n```json\n{\n \"detail\": \"Unsupported media type: type/unknown-type. It must be application/vnd.api+json\"\n}\n```\n\n========================================\n\nComments:\n- Does it resolves your question? r=requests.get(\"example.com\", headers={\"content-type\":\"whateveryouwant\"})\n- Just a heads up, this won't work for some content types like multipart/form-data where they also include a boundary value. So you get Content-type: multipart/formdata; bondary.... Slightly more cautious answer: `parts = [part.strip() for part in content_type.split(\";\")]` ` if expected_type not in parts:` ` ....` Otherwise this is great and helped me out, thanks!","metadata":{"transformedAt":"2026-08-18T18:32:29.156Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":5,"totalLines":126,"estimatedTokens":827}}685{"id":"stack-79694234","source":"stackoverflow","questionId":79694234,"title":"Does FastAPI still need Gunicorn?","tags":["python","fastapi","gunicorn","uvicorn","asgi"],"text":"Title: Does FastAPI still need Gunicorn?\nTags: python, fastapi, gunicorn, uvicorn, asgi\nSource: Stack Overflow\n\nQuestion:\nFor a long time Gunicorn+Uvicorn was the default setup for running FastAPI in production. However, I recently came across a blog post saying:\n\nIn the meantime, this combination of Gunicorn and Uvicorn is no longer\nneeded, as Uvicorn now also handles worker management itself\n\nI haven't found any other sources to verify this statement. Beside this, the official documentation only mention that the `tiangolo/uvicorn-gunicorn-fastapi` base Docker image is deprecated, but say nothing about Gunicorn+Uvicorn setup itself\n\nSo:\n\n- Does modern FastAPI need Gunicorn?\n\n- Is there any difference between `fastapi run --workers 4 main.py` and `gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker` now?\n\n========================================\n\nCode:\n```text\ntiangolo/uvicorn-gunicorn-fastapi\n```\n\n```text\nfastapi run --workers 4 main.py\n```\n\n```text\ngunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker\n```\n\n```text\n--workers\n```\n\n```text\n--limit-max-requests\n```\n\n```text\ntiangolo/uvicorn-gunicorn-fastapi\n```\n\n```text\n--workers\n```\n\n```text\nfastapi run\n```\n\n```text\nuvicorn\n```\n\n```text\nfastapi run\n```\n\n========================================\n\nComments:\n- Upstream uvicorn (not FastAPI!) no longer recommends gunicorn. That said, yes, absolutely there's \"any difference\"; they're very different implementations. (The main reason I would give to use gunicorn today is its systemd integration, which goes as far as support for inheriting listen sockets, and fully implements the sd_notify protocol when started as a service of `Type=notify`).\n- ...that said, I don't think this is on-topic here; Stack Overflow is for questions about *developing* code, not deploying it -- system administration is a Server Fault topic.\n- True as far as it goes, but I wouldn't call this complete. There are still good reasons to use guvicorn, even if they're niche and don't apply to everyone.\n- @CharlesDuffy Can you give an example of what such a reason would be?\n- @RayB systemd integration, for one. I can have systemd `.socket` units trigger gunicorn service startup, and gunicorn will inherit the listen sockets created by systemd instead of opening new ports itself. That means clients can connect much earlier at boot time -- *before* your services and their dependencies have finished starting up -- and their connections just stall for a bit until the server is ready, instead of having the connections fail.","metadata":{"transformedAt":"2026-08-18T18:32:29.156Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":10,"totalLines":69,"estimatedTokens":632}}686{"id":"stack-64891825","source":"stackoverflow","questionId":64891825,"title":"How to use HTTP Basic Auth as separate FastAPI service?","tags":["python","authentication","microservices","basic-authentication","fastapi"],"text":"Title: How to use HTTP Basic Auth as separate FastAPI service?\nTags: python, authentication, microservices, basic-authentication, fastapi\nSource: Stack Overflow\n\nQuestion:\n**What I want to achieve?** Have one service responsible for HTTP Basic Auth (access) and two services (a, b) where some endpoints are protected by access service.\n\n**Why?** In scenario where there will be much more services with protected endpoints to not duplicate authorize function in each service. Also to do modification in one place in case of changing to OAuth2 (maybe in future).\n\n**What I did?**\nI followed guide on official website and created example service which works totally fine.\n\n**Problem** occurs when I try to move authorization to separate service and then use it within few other\nservices with protected endpoints. I can't figure out how to do it. Could you please help me out?\n\nI have tried different functions setup. Nothing helped, so far my code looks like this:\n\n**access-service**\n\n```\nimport os\nimport secrets\n\nfrom fastapi import FastAPI, Depends, HTTPException, status\nfrom fastapi.security import HTTPBasic, HTTPBasicCredentials\n\nsecurity = HTTPBasic()\n\ndef authorize(credentials: HTTPBasicCredentials = Depends(security)):\n is_user_ok = secrets.compare_digest(credentials.username, os.getenv('LOGIN'))\n is_pass_ok = secrets.compare_digest(credentials.password, os.getenv('PASSWORD'))\n\n if not (is_user_ok and is_pass_ok):\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail='Incorrect email or password.',\n headers={'WWW-Authenticate': 'Basic'},\n )\n\napp = FastAPI(openapi_url=\"/api/access/openapi.json\", docs_url=\"/api/access/docs\")\n\n@app.get('/api/access/auth', dependencies=[Depends(authorize)])\ndef auth():\n return {\"Granted\": True}\n```\n\n**a-service**\n\n```\nimport httpx\nimport os\n\nfrom fastapi import Depends, FastAPI, HTTPException, status\n\nACCESS_SERVICE_URL = os.getenv('ACCESS_SERVICE_URL')\n\napp = FastAPI(openapi_url=\"/api/a/openapi.json\", docs_url=\"/api/a/docs\")\n\ndef has_access():\n result = httpx.get(os.getenv('ACCESS_SERVICE_URL'))\n if result.status_code == 401:\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail='No access to resource. Login first.',\n )\n\n@app.get('/api/a/unprotected_a')\nasync def unprotected_a():\n return {\"Protected\": False}\n\n@app.get('/api/a/protected_a', dependencies=[Depends(has_access)])\nasync def protected_a():\n return {\"Protected\": True}\n\n@app.get('/api/a/protected_b', dependencies=[Depends(has_access)])\nasync def protected_b():\n return {\"Protected\": True}\n```\n\n========================================\n\nTop Answer:\nThanks to Soumojit Ghosh answer and FastAPI Issue 1037 I figured out how should I modify my code. **a-service** after changes:\n\n```\nimport httpx\nimport os\n\nfrom fastapi import Depends, FastAPI, Header, HTTPException, status\nfrom typing import Optional\nfrom fastapi.security import HTTPBasicCredentials, HTTPBearer\n\nsecurity = HTTPBearer()\n\nACCESS_SERVICE_URL = os.getenv('ACCESS_SERVICE_URL')\n\napp = FastAPI(openapi_url=\"/api/a/openapi.json\", docs_url=\"/api/a/docs\")\n\ndef has_access(credentials: HTTPBasicCredentials = Depends(security)):\n response = httpx.get(os.getenv('ACCESS_SERVICE_URL'), headers={'Authorization': credentials.credentials})\n if response.status_code == 401:\n raise HTTPException(status_code=401)\n\n@app.get('/api/a/unprotected_a')\nasync def unprotected_a():\n return {\"Protected\": False}\n\n@app.get('/api/a/protected_a', dependencies=[Depends(has_access)])\nasync def protected_a():\n return {\"Protected\": True}\n\n@app.get('/api/a/protected_b', dependencies=[Depends(has_access)])\nasync def protected_b():\n return {\"Protected\": True}\n```\n\nNow header can be sent through SwaggerUI. Click Authorize and then enter it in Value field. To generate your header from login and password you can use for example this tool. It will look like: `Basic YWRtaW46cGFzc3dvcmQ=`.\n\n========================================\n\nCode:\n```text\nimport os\nimport secrets\n\nfrom fastapi import FastAPI, Depends, HTTPException, status\nfrom fastapi.security import HTTPBasic, HTTPBasicCredentials\n\nsecurity = HTTPBasic()\n\n\ndef authorize(credentials: HTTPBasicCredentials = Depends(security)):\n is_user_ok = secrets.compare_digest(credentials.username, os.getenv('LOGIN'))\n is_pass_ok = secrets.compare_digest(credentials.password, os.getenv('PASSWORD'))\n\n if not (is_user_ok and is_pass_ok):\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail='Incorrect email or password.',\n headers={'WWW-Authenticate': 'Basic'},\n )\n\n\napp = FastAPI(openapi_url=\"/api/access/openapi.json\", docs_url=\"/api/access/docs\")\n\n\n@app.get('/api/access/auth', dependencies=[Depends(authorize)])\ndef auth():\n return {\"Granted\": True}\n```\n\n```text\nimport httpx\nimport os\n\nfrom fastapi import Depends, FastAPI, HTTPException, status\n\nACCESS_SERVICE_URL = os.getenv('ACCESS_SERVICE_URL')\n\napp = FastAPI(openapi_url=\"/api/a/openapi.json\", docs_url=\"/api/a/docs\")\n\n\ndef has_access():\n result = httpx.get(os.getenv('ACCESS_SERVICE_URL'))\n if result.status_code == 401:\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail='No access to resource. Login first.',\n )\n\n\n@app.get('/api/a/unprotected_a')\nasync def unprotected_a():\n return {\"Protected\": False}\n\n\n@app.get('/api/a/protected_a', dependencies=[Depends(has_access)])\nasync def protected_a():\n return {\"Protected\": True}\n\n\n@app.get('/api/a/protected_b', dependencies=[Depends(has_access)])\nasync def protected_b():\n return {\"Protected\": True}\n```\n\n```text\nresult = httpx.get(os.getenv('ACCESS_SERVICE_URL'))\n```\n\n```text\nfrom typing import Optional\nfrom fastapi import Header \n\ndef has_access(authorization: Optional[str] = Header(None)):\n if not authorization:\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail='No access to resource. Credentials missing!',\n )\n headers = {'Authorization': authorization}\n result = httpx.get(os.getenv('ACCESS_SERVICE_URL'), headers=headers)\n if result.status_code == 401:\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail='No access to resource. Login first.',\n )\n```\n\n```text\n@app.get('/api/access/auth', dependencies=[Depends(authorize)])\ndef auth():\n return {\"Granted\": True}\n```\n\n```text\nfrom fastapi.security import HTTPBasic, HTTPBasicCredentials\n\nsecurity = HTTPBasic()\n\ndef has_access(credentials: HTTPBasicCredentials = Depends(security), authorization: Optional[str] = Header(None)):\n```\n\n```text\nimport httpx\nimport os\n\nfrom fastapi import Depends, FastAPI, Header, HTTPException, status\nfrom typing import Optional\nfrom fastapi.security import HTTPBasicCredentials, HTTPBearer\n\nsecurity = HTTPBearer()\n\nACCESS_SERVICE_URL = os.getenv('ACCESS_SERVICE_URL')\n\napp = FastAPI(openapi_url=\"/api/a/openapi.json\", docs_url=\"/api/a/docs\")\n\n\ndef has_access(credentials: HTTPBasicCredentials = Depends(security)):\n response = httpx.get(os.getenv('ACCESS_SERVICE_URL'), headers={'Authorization': credentials.credentials})\n if response.status_code == 401:\n raise HTTPException(status_code=401)\n\n\n@app.get('/api/a/unprotected_a')\nasync def unprotected_a():\n return {\"Protected\": False}\n\n\n@app.get('/api/a/protected_a', dependencies=[Depends(has_access)])\nasync def protected_a():\n return {\"Protected\": True}\n\n\n@app.get('/api/a/protected_b', dependencies=[Depends(has_access)])\nasync def protected_b():\n return {\"Protected\": True}\n```\n\n```text\nBasic YWRtaW46cGFzc3dvcmQ=\n```\n\n========================================\n\nComments:\n- please check my answer\n- Thank you for taking look at it. I have checked your answer, but I get `AttributeError: 'NoneType' object has no attribute 'encode'`. Here is updated repo,\n- Where are you making the API call from, browser or Postman?\n- I'm making it from browser. I'm using Swagger UI at 0.0.0.0:8080/api/a/docs\n- @Ethr - I have updated the code, the error is happening because while calling Service_A you are not entering the credentials, I was able to reproduce it!\n- @Ether - localhost:8080/api/a/docs#/default/… - you need to place the authorization string here before clicking Execute.\n- What form this string should have? I have tried: user@password, {\"user\": \"password\"}, but it still throws error.\n- Let us continue this discussion in chat.\n- For example, if the browser uses Aladdin as the username and OpenSesame as the password, then the field's value is the Base64 encoding of Aladdin:OpenSesame, or QWxhZGRpbjpPcGVuU2VzYW1l. Then the Authorization header will appear as: Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l\n- @laplace its access service url - access_service:8000/api/access/auth . Application was built with docker-compose. That url was added as environment variable.","metadata":{"transformedAt":"2026-08-18T18:32:29.156Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":8,"totalLines":276,"estimatedTokens":2219}}687{"id":"stack-66178227","source":"stackoverflow","questionId":66178227,"title":"Fast API - how to show an image from POST in GET?","tags":["python","fastapi"],"text":"Title: Fast API - how to show an image from POST in GET?\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm creating an app using FastAPI that is supposed to generate resized version of uploaded images. The upload should be done through POST/images and after calling a path /images/800x400 it should show a random image from the database with 800x400 size.\nI'm getting an error while trying to display an image.\n\n```\nfrom fastapi.responses import FileResponse\n import uuid\n\n app = FastAPI()\n\n db = []\n\n@app.post(\"/images/\")\nasync def create_upload_file(file: UploadFile = File(...)):\n\n contents = await file.read() \n\n db.append(file)\n\n with open(file.filename, \"wb\") as f:\n f.write(contents)\n\n return {\"filename\": file.filename}\n\n@app.get(\"/images/\")\nasync def show_image(): \n return db[0]\n```\n\nAs a response I get:\n\n```\n{\n \"filename\": \"70188bdc-923c-4bd3-be15-8e71966cab31.jpg\",\n \"content_type\": \"image/jpeg\",\n \"file\": {}\n}\n```\n\nI would like to use: return FileResponse(some_file_path)\nand in the file path put the filename from above. Is it right way of thinking?\n\n========================================\n\nCode:\n```text\nfrom fastapi.responses import FileResponse\n import uuid\n\n app = FastAPI()\n\n db = []\n\n@app.post(\"/images/\")\nasync def create_upload_file(file: UploadFile = File(...)):\n\n contents = await file.read() \n\n db.append(file)\n\n with open(file.filename, \"wb\") as f:\n f.write(contents)\n\n return {\"filename\": file.filename}\n\n@app.get(\"/images/\")\nasync def show_image(): \n return db[0]\n```\n\n```text\n{\n \"filename\": \"70188bdc-923c-4bd3-be15-8e71966cab31.jpg\",\n \"content_type\": \"image/jpeg\",\n \"file\": {}\n}\n```\n\n```py\nfrom fastapi import FastAPI, File, UploadFile\nfrom fastapi.responses import Response\nimport os\nfrom random import randint\nimport uuid\n\napp = FastAPI()\n\ndb = []\n\n\n@app.post(\"/images/\")\nasync def create_upload_file(file: UploadFile = File(...)):\n\n file.filename = f\"{uuid.uuid4()}.jpg\"\n contents = await file.read() # <-- Important!\n\n db.append(contents)\n\n return {\"filename\": file.filename}\n\n\n@app.get(\"/images/\")\nasync def read_random_file():\n\n # get a random file from the image db\n random_index = randint(0, len(db) - 1)\n\n # return a response object directly as FileResponse expects a file-like object\n # and StreamingResponse expects an iterator/generator\n response = Response(content=db[random_index])\n\n return response\n```\n\n```py\nfrom fastapi import FastAPI, File, UploadFile\nfrom fastapi.responses import FileResponse\nimport os\nfrom random import randint\nimport uuid\n\nIMAGEDIR = \"fastapi-images/\"\n\napp = FastAPI()\n\n\n@app.post(\"/images/\")\nasync def create_upload_file(file: UploadFile = File(...)):\n\n file.filename = f\"{uuid.uuid4()}.jpg\"\n contents = await file.read() # <-- Important!\n\n # example of how you can save the file\n with open(f\"{IMAGEDIR}{file.filename}\", \"wb\") as f:\n f.write(contents)\n\n return {\"filename\": file.filename}\n\n\n@app.get(\"/images/\")\nasync def read_random_file():\n\n # get a random file from the image directory\n files = os.listdir(IMAGEDIR)\n random_index = randint(0, len(files) - 1)\n\n path = f\"{IMAGEDIR}{files[random_index]}\"\n \n # notice you can use FileResponse now because it expects a path\n return FileResponse(path)\n```\n\n========================================\n\nComments:\n- please fix indents in your code\n- Sorry, I didn't realize it was without indents here. I edited it and now it is the version I have and it's the one that doesn't show me an outcome I need. How can I show the image uploaded with POST using GET method?\n- Future readers might find the following answers helpful: this, this, as well as this and this. Further related answers can be found here, here, as well as here and here\n- Done. Actually I have another doubt at this point. It's about resizing the image. I opened a new question.","metadata":{"transformedAt":"2026-08-18T18:32:29.156Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":163,"estimatedTokens":969}}688{"id":"stack-69261606","source":"stackoverflow","questionId":69261606,"title":"how can i make a key dynamic in a pydantic model","tags":["python","fastapi","pydantic"],"text":"Title: how can i make a key dynamic in a pydantic model\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\ni have an api entrypoint:\n\n```\n@app.get('/dealers_get_users/', response_model = schemas.SellSideUserId, status_code=200)\ndef getdata(db: database.SessionLocal = _Depends(database.get_db)):\n result = {}\n i = db.query(models.sellSideUser).all()\n for dealer_users in i:\n result[str(dealer_users.user_id)] = {\n 'user_name' : dealer_users.user_name,\n 'user_pass' : dealer_users.user_pass,\n }\n m = schemas.SellSideUserId(user_id=result)\n return m\n```\n\nthe data coming in from the db is just 3 fields: user_id,user_name,user_pass\n\nwhen i call the api, i get this:\n\n```\n{\n\"user_id\": {\n \"1\": {\n \"user_name\": \"testname\",\n \"user_pass\": \"testpass\"\n }\n }\n}\n```\n\nok, cool - i got my data. but i'm still trying to understand how these models work, and am not really grasping how to move in or out of a nested dictionary.\n\nfor example, i would like it to look like this, instead:\n\n```\n{\n \"1\": {\n \"user_name\": \"testname\",\n \"user_pass\": \"testpass\"\n }\n}\n```\n\nbut i'm not sure how to pass the 'result' variable into this class - any way i do it, i'm met with an error.\n\n**my model:**\n\n```\nclass SellSideUserId(_BaseModel):\n user_id : dict\n class Config:\n orm_mode = True\n```\n\nam i supposed to build two pydantic models - one being based on another? could use some help with this\n\nthanks!\n\n========================================\n\nCode:\n```text\n@app.get('/dealers_get_users/', response_model = schemas.SellSideUserId, status_code=200)\ndef getdata(db: database.SessionLocal = _Depends(database.get_db)):\n result = {}\n i = db.query(models.sellSideUser).all()\n for dealer_users in i:\n result[str(dealer_users.user_id)] = {\n 'user_name' : dealer_users.user_name,\n 'user_pass' : dealer_users.user_pass,\n }\n m = schemas.SellSideUserId(user_id=result)\n return m\n```\n\n```text\n{\n\"user_id\": {\n \"1\": {\n \"user_name\": \"testname\",\n \"user_pass\": \"testpass\"\n }\n }\n}\n```\n\n```text\n{\n \"1\": {\n \"user_name\": \"testname\",\n \"user_pass\": \"testpass\"\n }\n}\n```\n\n```text\nclass SellSideUserId(_BaseModel):\n user_id : dict\n class Config:\n orm_mode = True\n```\n\n```py\nclass User(BaseModel):\n name: str\n password: str\n\nclass ProductModel(BaseModel):\n __root__: Dict[str, User]\n```\n\n```py\nUserId = constr(regex=r'^\\d+$')\n\nclass ProductModel(BaseModel):\n __root__: Dict[UserId, User]\n```\n\n```text\ndict\n```\n\n```text\nconstr\n```\n\n```text\npatternProperties\n```\n\n```text\npropertyNames\n```\n\n========================================\n\nComments:\n- If you want to return more than one user, why don't you use a list instead of a dict?\n- @HernánAlarcón i suppose i can do that, but i'd like to just know how to do this - theres obviously a misunderstanding of how these models work on my part\n- As far as I know, keys in basic pydantic models are not supposed to be dynamic. That is how it is designed. You define them when you write the classes and you can even give them an alias, but that is it. The documentation describes dynamic model creation but it might be too complex if you just want to return some users.\n- @HernánAlarcón ahh, got it. i mean, i can obviously put it in the json format that i want without using a response model..for example: result[user_id] = {'user_name':user_name, 'user_pass':user_pass} | but, i figured it would be preferable using a well-known library?","metadata":{"transformedAt":"2026-08-18T18:32:29.156Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":10,"totalLines":147,"estimatedTokens":898}}689{"id":"stack-66169994","source":"stackoverflow","questionId":66169994,"title":"TypeError: post() missing 1 required positional argument: 'path' in FastApi?","tags":["python","fastapi"],"text":"Title: TypeError: post() missing 1 required positional argument: 'path' in FastApi?\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nWhere is mistake in FastApi?\n\nError is:\n\n@video_router.post('/info')\n\nTypeError: post() missing 1 required positional argument: 'path'\n\napi.py\n\n```\nfrom fastapi import APIRouter\nvideo_router = APIRouter\n@video_router.post('/info')\nasync def info_set(info: UploadVideo):\n return info\n```\n\nmain.py:\n\n```\nfrom fastapi import FastAPI\nfrom api import video_router\napp = FastAPI()\napp.include_router(video_router)\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi import APIRouter\nvideo_router = APIRouter\n@video_router.post('/info')\nasync def info_set(info: UploadVideo):\n return info\n```\n\n```text\nfrom fastapi import FastAPI\nfrom api import video_router\napp = FastAPI()\napp.include_router(video_router)\n```\n\n```text\nvideo_router = APIRouter\n```\n\n```text\nvideo_router = APIRouter()\n```\n\n```text\nvideo_router\n```\n\n```text\nAPIRouter\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.156Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":6,"totalLines":65,"estimatedTokens":249}}690{"id":"stack-76322342","source":"stackoverflow","questionId":76322342,"title":"FastAPI SQLAlchemy cannot convert dictionary update sequence element #0 to a sequence","tags":["python","sqlalchemy","fastapi"],"text":"Title: FastAPI SQLAlchemy cannot convert dictionary update sequence element #0 to a sequence\nTags: python, sqlalchemy, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm trying to return list of operations and getting error\n\n```\n@router.get(\"/\")\nasync def get_specific_operations(operation_type: str, session: AsyncSession = Depends(get_async_session)):\n query = select(operation).where(operation.c.type == operation_type)\n result = await session.execute(query)\n return result.all()\n```\n\nError:\n\n```\nValueError: [TypeError('cannot convert dictionary update sequence element #0 to a sequence'), TypeError('vars() argument must have __dict__ attribute')]\n```\n\n========================================\n\nTop Answer:\ntry instead of `result.all()` to do this `result.scalars().all()`\n\n========================================\n\nCode:\n```text\n@router.get(\"/\")\nasync def get_specific_operations(operation_type: str, session: AsyncSession = Depends(get_async_session)):\n query = select(operation).where(operation.c.type == operation_type)\n result = await session.execute(query)\n return result.all()\n```\n\n```text\nValueError: [TypeError('cannot convert dictionary update sequence element #0 to a sequence'), TypeError('vars() argument must have __dict__ attribute')]\n```\n\n```text\nresults = session.exec(statement).all()\nhead= [\"headerName1\", \"headerName2\", \"headerName3\"]\ndata = {\n \"head\": [{\"title\": column} for column in head],\n \"rows\": [list(result) for result in results]\n }\n```\n\n```text\nresults = session.exec(statement).all()\n if results:\n data = []\n for r in results:\n data.append({\n \"full_name\": f\"{r.firstname} {r.lastname}\",\n \"value\": r.value,\n \"x\": r.x,\n \"y\": r.y,\n }\n )\n return JSONResponse(content=data, status_code=200)\n```\n\n```text\nsqlmodel\n```\n\n```text\nresults\n```\n\n```text\nlist\n```\n\n```text\nlist(result)\n```\n\n```text\nsqlmodel\n```\n\n```text\nsqlmodel\n```\n\n```text\n.all()\n```\n\n```text\n.scalars().all()\n```\n\n```text\nresult.all()\n```\n\n```text\nresult.scalars().all()\n```\n\n```text\nclass Operation(BaseModel):\n model_config: ConfigDict(from_attributes=True)\n\n prop1: type1\n prop2: type2\n ...\n```\n\n```text\nfrom typing import List\nfrom schemas import Operation\n...\n@router.get(\"/\", response_model=List[Operation])\n```\n\n```text\nschemas.py\n```\n\n```text\nmodel_config\n```\n\n```text\nConfigDict\n```\n\n```text\npydantic\n```\n\n```text\nList[Operation]\n```\n\n```text\nresponse.all()\n```\n\n```text\npydantic\n```\n\n```text\nresult.all()\n```\n\n```text\nresult.mappings().all()\n```\n\n========================================\n\nComments:\n- Python version 3.8\n- The `all()` method in SQLAlchemy returns a `Sequence` object with `Row` values - FastAPIs default JSON encoder has no idea what do with that type of object. Define a pydantic response model with config set to `orm_mode=True` or return a list of dictionaries instead.\n- With `sqlalchemy2` + `sqlmodel` this seems to be the right approach!","metadata":{"transformedAt":"2026-08-18T18:32:29.156Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":25,"totalLines":163,"estimatedTokens":752}}691{"id":"stack-76635770","source":"stackoverflow","questionId":76635770,"title":"how to test fastapi application without sharing the same application between tests using pytest","tags":["python","pytest","python-asyncio","fastapi"],"text":"Title: how to test fastapi application without sharing the same application between tests using pytest\nTags: python, pytest, python-asyncio, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm trying to test my `FastAPI` code using pytest. some of the tests I'm doing require the application be in an initial state (some configuration to be reset, object data to be cleared and so on).\n\nboth of the methods I tried put the app in the same state during the test session, I also tried to reload the module in which the app is in, but with no success.\n\nhere is a minimal reproducible example of the code:\n\n*file :main.py*\n\n```\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\nmy_state = False\n\n@app.get(\"/my_state/\")\ndef return_my_state():\n return {\"state\": my_state }\n\n@app.post(\"/my_state/\")\ndef set_my_state(content:dict):\n global my_state\n my_state = content['set']\n```\n\n*file: test_file1.py*\n\n```\nfrom fastapi.testclient import TestClient\nfrom main import app\nimport pytest\n\nclient = TestClient(app)\n\n@pytest.mark.asyncio\nasync def test_check_status():\n global client\n client.post(\"/my_state/\", json={\"set\": True})\n print(client.get(\"/my_state/\").json()['state']) #prints True\n```\n\n*file: test_file2.py*\n\n```\nfrom fastapi.testclient import TestClient\nfrom main import app\nimport pytest\n\nclient = TestClient(app)\n\n@pytest.mark.asyncio\nasync def test_check_status_other_file():\n global client\n print(client.get(\"/my_state/\").json()['state']) #prints True\n```\n\nthis prevents me from properly testing the application.\nis there another way that I can use other than running the application outside of test cases ??\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\nmy_state = False\n\n@app.get(\"/my_state/\")\ndef return_my_state():\n return {\"state\": my_state }\n\n@app.post(\"/my_state/\")\ndef set_my_state(content:dict):\n global my_state\n my_state = content['set']\n```\n\n```py\nfrom fastapi.testclient import TestClient\nfrom main import app\nimport pytest\n\nclient = TestClient(app)\n\n@pytest.mark.asyncio\nasync def test_check_status():\n global client\n client.post(\"/my_state/\", json={\"set\": True})\n print(client.get(\"/my_state/\").json()['state']) #prints True\n```\n\n```py\nfrom fastapi.testclient import TestClient\nfrom main import app\nimport pytest\n\nclient = TestClient(app)\n\n@pytest.mark.asyncio\nasync def test_check_status_other_file():\n global client\n print(client.get(\"/my_state/\").json()['state']) #prints True\n```\n\n```text\nFastAPI\n```\n\n```text\nfrom fastapi import FastAPI\n\n\ndef create_app():\n app = FastAPI()\n app.state.my_state = False\n\n @app.get(\"/my_state/\")\n def return_my_state():\n return {\"state\": app.state.my_state}\n\n @app.post(\"/my_state/\")\n def set_my_state(content: dict):\n app.state.my_state = content[\"set\"]\n\n return app\n\n\napp = create_app()\n```\n\n```text\nimport pytest\n\nfrom fastapi.testclient import TestClient\nfrom main import create_app\n\n\n@pytest.fixture\ndef app():\n return create_app()\n\n\n@pytest.fixture\ndef client(app):\n return TestClient(app)\n```\n\n```text\nfrom fastapi.testclient import TestClient\nfrom main import app\nimport pytest\n\n@pytest.mark.asyncio\nasync def test_check_status(client):\n client.post(\"/my_state/\", json={\"set\": True})\n assert client.get(\"/my_state/\").json()['state']\n```\n\n```text\nfrom fastapi.testclient import TestClient\nfrom main import app\nimport pytest\n\n\n@pytest.mark.asyncio\nasync def test_check_status_other_file(client):\n assert not client.get(\"/my_state/\").json()[\"state\"]\n```\n\n```text\n============================= test session starts ==============================\nplatform linux -- Python 3.11.4, pytest-7.4.0, pluggy-1.2.0 -- /home/lars/tmp/python/.venv/bin/python\ncachedir: .pytest_cache\nrootdir: /home/lars/tmp/python/testapi\nplugins: xdist-3.3.1, mock-3.11.1, anyio-3.7.1, asyncio-0.21.0\nasyncio: mode=Mode.STRICT\ncollecting ... collected 2 items\n\ntest_file1.py::test_check_status PASSED [ 50%]\ntest_file2.py::test_check_status_other_file PASSED [100%]\n\n============================== 2 passed in 0.03s ===============================\n```\n\n```text\nmain.py\n```\n\n```text\nconftest.py\n```\n\n```text\ntest_file1.py\n```\n\n```text\ntest_file2.py\n```\n\n```text\npytest -v\n```\n\n========================================\n\nComments:\n- Your question isn't clear to me. Are you saying that you want to preserve state between test functions or that you want to start with a clean slate each time?\n- I want a clean state each time\n- In that case, any reason why you can't do `client = TestClient(app)` in each test function rather than at the top of the module? Also, you will need to empty the database between each function call if `client.post(\"/mystate\")` writes to the database. If you are using the databases library, you may be able to do that with `databases.connect(..., force_rollback=True)`.\n- I tried using the `TestClient(app)` in each function but this won't work either, I guess the application is the one that is shared.\n- as for the database part, the code I'm testing has nothing to do with a database, I'm just checking some object configurations, I could reset all the configurations using a function but this would take so much time, I was hoping that `pytest` or `fastapi` contain such functionality\n- This question would benefit from a minimal reproducible example -- code that we could run locally to reproduce the problem you're asking about.","metadata":{"transformedAt":"2026-08-18T18:32:29.156Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":14,"totalLines":220,"estimatedTokens":1362}}692{"id":"stack-71176314","source":"stackoverflow","questionId":71176314,"title":"File upload using FastAPI returns error 422","tags":["python","file-upload","fastapi","http-status-code-422"],"text":"Title: File upload using FastAPI returns error 422\nTags: python, file-upload, fastapi, http-status-code-422\nSource: Stack Overflow\n\nQuestion:\nI am using the example from the official documentation: https://fastapi.tiangolo.com/tutorial/request-files/#import-file\n\nServer code:\n\n```\n@app.post(\"/uploadfile\")\nasync def create_upload_file(data: UploadFile = File(...)):\n print(\"> uploaded file:\",data.filename)\n return {\"filename\": data.filename}\n```\n\nClient code:\n\n```\nfiles = {'upload_file': open('config.txt', 'rb')}\nresp = requests.post(\n url = URL,\n files = files)\nprint(resp.json())\n```\n\nThe problem is that the server always responds with error 422:\n\n```\n{'detail': [{'loc': ['body', 'data'], 'msg': 'field required', 'type': 'value_error.missing'}]}\n```\n\nI am using Python 3 on both server and client and the python-multipart package is already installed.\n\nCan someone please tell me what I am doing wrong, what am I missing, how should I fix the code?\n\nAny hints are much appreciated.\n\n========================================\n\nTop Answer:\nWell, I just realized my error (which is not immediately obvious for newbies like me :))\n\nThe parameter you pass on client side (`'upload_file'`)\n\n```\nfiles = {'upload_file': open('config.txt', 'rb')}\n```\n\nmust match the parameter on the server side (`'data'`):\n\n```\nasync def create_upload_file(data: UploadFile = File(...)):\n```\n\nSo in order to work I had to rename on client side '`upload_file`' to '`data`':\n\n```\nfiles = {'data': open('config.txt', 'rb')} # renamed 'upload_file' to 'data'\n```\n\nThat's it. Hopefully this helps some others as well.\n\n========================================\n\nCode:\n```text\n@app.post(\"/uploadfile\")\nasync def create_upload_file(data: UploadFile = File(...)):\n print(\"> uploaded file:\",data.filename)\n return {\"filename\": data.filename}\n```\n\n```text\nfiles = {'upload_file': open('config.txt', 'rb')}\nresp = requests.post(\n url = URL,\n files = files)\nprint(resp.json())\n```\n\n```text\n{'detail': [{'loc': ['body', 'data'], 'msg': 'field required', 'type': 'value_error.missing'}]}\n```\n\n```py\n@app.post('/uploadfile')\nasync def create_upload_file(data: UploadFile = File(...)):\n ^^^^\n```\n\n```py\nurl = 'http://127.0.0.1:8000/uploadfile'\nfiles = {'data': open('config.txt', 'rb')}\nr = requests.post(url=url, files=files)\n```\n\n```text\ndata\n```\n\n```text\nupload_file\n```\n\n```text\ndata\n```\n\n```text\nfiles = {'upload_file': open('config.txt', 'rb')}\n```\n\n```text\nasync def create_upload_file(data: UploadFile = File(...)):\n```\n\n```text\nfiles = {'data': open('config.txt', 'rb')} # renamed 'upload_file' to 'data'\n```\n\n```text\n'upload_file'\n```\n\n```text\n'data'\n```\n\n```text\nupload_file\n```\n\n```text\ndata\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.156Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":15,"totalLines":136,"estimatedTokens":681}}693{"id":"stack-64489679","source":"stackoverflow","questionId":64489679,"title":"Download PDF file using pdfkit and FastAPI","tags":["python","download","pdf-generation","fastapi","pdfkit"],"text":"Title: Download PDF file using pdfkit and FastAPI\nTags: python, download, pdf-generation, fastapi, pdfkit\nSource: Stack Overflow\n\nQuestion:\nI am going to create an API, using FastAPI, that converts an `HTML` page to a PDF file, using `pdfkit`. However, it saves the file to my local disk. After I serve this API online, how could users download this PDF file to their computer?\n\n```\nfrom typing import Optional\nfrom fastapi import FastAPI\nimport pdfkit\n\napp = FastAPI()\n@app.post(\"/htmltopdf/{url}\")\ndef convert_url(url:str):\n pdfkit.from_url(url, 'converted.pdf')\n```\n\n========================================\n\nTop Answer:\nOnce you get the `bytes` of the PDF file, you can simply return a custom `Response`, specifying the `content`, `headers` and `media_type`. Thus, no need for saving the file to the disk or generating temporary files, as suggested by another answer. Similar to this answer, you can set the `Content-Disposition` header to let the web browser know whether the PDF file should be *viewed* or *downloaded*.\n\n### Example\n\n```\nfrom fastapi import FastAPI, Response\nimport pdfkit\n\napp = FastAPI()\nconfig = pdfkit.configuration(wkhtmltopdf=r'YOUR_DIR_TO/wkhtmltopdf/bin/wkhtmltopdf.exe')\n\n@app.get('/')\ndef main():\n pdf = pdfkit.from_url('http://google.com', configuration=config)\n headers = {'Content-Disposition': 'attachment; filename=\"out.pdf\"'}\n return Response(pdf, headers=headers, media_type='application/pdf')\n```\n\nTo have the PDF file *viewed* in the borwser instead of *downloaded*, use:\n\n```\nheaders = {'Content-Disposition': 'inline; filename=\"out.pdf\"'}\n```\n\nSee this answer on how to install and use `pdfkit`.\n\n========================================\n\nCode:\n```py\nfrom typing import Optional\nfrom fastapi import FastAPI\nimport pdfkit\n\napp = FastAPI()\n@app.post(\"/htmltopdf/{url}\")\ndef convert_url(url:str):\n pdfkit.from_url(url, 'converted.pdf')\n```\n\n```text\nHTML\n```\n\n```text\npdfkit\n```\n\n```text\nfrom typing import Optional\nfrom fastapi import FastAPI\nfrom starlette.responses import FileResponse\nimport pdfkit\n\napp = FastAPI()\nconfig = pdfkit.configuration(wkhtmltopdf=r\"C:\\Program Files\\wkhtmltopdf\\bin\\wkhtmltopdf.exe\")\n\n@app.get(\"/\")\ndef read_root():\n pdfkit.from_url(\"https://nakhal.expo.com.tr/nakhal/preview\",\"file.pdf\", configuration=config)\n return FileResponse(\n \"file.pdf\",\n media_type=\"application/pdf\",\n filename=\"ticket.pdf\")\n```\n\n```text\nfrom typing import Optional\nfrom fastapi import FastAPI\nfrom starlette.responses import FileResponse\nimport tempfile\nimport pdfkit\n\n\n\napp = FastAPI()\n\nconfig = pdfkit.configuration(wkhtmltopdf=r\"C:\\Program Files\\wkhtmltopdf\\bin\\wkhtmltopdf.exe\")\n\n\n@app.get(\"/\")\ndef read_root():\n pdf = pdfkit.from_url(\"https://nakhal.expo.com.tr/nakhal/preview\",False, configuration=config)\n\n with tempfile.NamedTemporaryFile(mode=\"w+b\", suffix=\".pdf\", delete=False) as TPDF:\n TPDF.write(pdf)\n return FileResponse(\n TPDF.name,\n media_type=\"application/pdf\",\n filename=\"ticket.pdf\")\n```\n\n```py\nfrom fastapi import FastAPI, Response\nimport pdfkit\n\n\napp = FastAPI()\nconfig = pdfkit.configuration(wkhtmltopdf=r'YOUR_DIR_TO/wkhtmltopdf/bin/wkhtmltopdf.exe')\n\n\n@app.get('/')\ndef main():\n pdf = pdfkit.from_url('http://google.com', configuration=config)\n headers = {'Content-Disposition': 'attachment; filename=\"out.pdf\"'}\n return Response(pdf, headers=headers, media_type='application/pdf')\n```\n\n```py\nheaders = {'Content-Disposition': 'inline; filename=\"out.pdf\"'}\n```\n\n```text\nbytes\n```\n\n```text\nResponse\n```\n\n```text\ncontent\n```\n\n```text\nheaders\n```\n\n```text\nmedia_type\n```\n\n```text\nContent-Disposition\n```\n\n```text\npdfkit\n```\n\n========================================\n\nComments:\n- did you try returning the object? perhaps returning its path?\n- Does this answer your question? As @PaulH said, you should be returning the object\n- @clmno yes it worked for me. thank you. Now im looking to make it without saving to a path in server. I used tempfile.NamedTemporaryFile() but got empty pdf pages. looking for another solution...\n- Good solution 👍\n- How to use it in `POST` requests?\n- It gives a `307 Redirect` and then `200 OK` in `POST` requests but nothing seems to happen. Do not get any download popups or inline PDFs.\n- @AmitPathak The example above works as expected for both `GET` and `POST` requests. As for the `307 Temporary Redirect` status response code, see here and here\n- @AmitPathak Please have a look at this answer. You might also find this answer helpful.","metadata":{"transformedAt":"2026-08-18T18:32:29.156Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":14,"totalLines":172,"estimatedTokens":1142}}694{"id":"stack-69913998","source":"stackoverflow","questionId":69913998,"title":"How to get current active user in middleware FastAPI python","tags":["python","authentication","logging","fastapi"],"text":"Title: How to get current active user in middleware FastAPI python\nTags: python, authentication, logging, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have developed an auth on FastAPI Python using the doc here https://fastapi.tiangolo.com/tutorial/security/oauth2-jwt/ (I use exactly the code shown, nothing special to mention, auth works like a charm);\n\nNow, I need to log things in a database at each call to each route: time spent for the request, method for current req, etc. - and username (the one that used the path).\n\nFor that I have developed an http middleware that looks like this:\n\n```\n@app.middleware(\"http\")\nasync def log_things(request: Request, call_next):\n start_time = time.time()\n response = await call_next(request)\n\n path = request.url.path\n method = request[\"method\"]\n params = request.path_params\n host = request.client.host + \":\" + str(request.client.port)\n process_time = time.time() - start_time\n user = await security_management.get_current_active_user() \n user = \"dev\" # MOCK todo how to get user\n\n db.write_log(path, method, params, host, process_time, user)\n\n response.headers[\"X-Process-Time\"] = str(process_time)\n return response\n```\n\nProblem: I am unable to retrieve usernames. The content I retrieve is encapsulated in a \"Depend\" object that I am unable to resolve.\n\nI've tried few things:\n\n- using await on Depend,\n\n- using `current_user: User = Depends(get_current_user)` as a parameter for my middleware function,\n\nI'm kinda stuck, unable to extract valuable data from this Depend object, even if it works very well in the security part with these two functions below (that I tried to reproduce as well in terms of parameters...)\n\n```\nasync def get_current_user(\n token: str = Depends(oauth2_scheme),\n):\n credentials_exception = HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Could not validate credentials\",\n headers={\"WWW-Authenticate\": \"Bearer\"},\n )\n try:\n payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])\n username: str = payload.get(\"sub\")\n if username is None:\n raise credentials_exception\n token_data = TokenData(username=username)\n except JWTError:\n raise credentials_exception\n user = UserManager.get_user(real_user_db, username=token_data.username)\n if user is None:\n raise credentials_exception\n return user\n\nasync def get_current_active_user(current_user: User = Depends(get_current_user)):\n if current_user.disabled:\n raise HTTPException(status_code=400, detail=\"Inactive user\")\n return current_user # I can read current_user well...\n```\n\nAny thoughts? Thanks :)\n\n========================================\n\nCode:\n```text\n@app.middleware(\"http\")\nasync def log_things(request: Request, call_next):\n start_time = time.time()\n response = await call_next(request)\n\n path = request.url.path\n method = request[\"method\"]\n params = request.path_params\n host = request.client.host + \":\" + str(request.client.port)\n process_time = time.time() - start_time\n user = await security_management.get_current_active_user() \n user = \"dev\" # MOCK todo how to get user\n\n db.write_log(path, method, params, host, process_time, user)\n\n response.headers[\"X-Process-Time\"] = str(process_time)\n return response\n```\n\n```text\nasync def get_current_user(\n token: str = Depends(oauth2_scheme),\n):\n credentials_exception = HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Could not validate credentials\",\n headers={\"WWW-Authenticate\": \"Bearer\"},\n )\n try:\n payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])\n username: str = payload.get(\"sub\")\n if username is None:\n raise credentials_exception\n token_data = TokenData(username=username)\n except JWTError:\n raise credentials_exception\n user = UserManager.get_user(real_user_db, username=token_data.username)\n if user is None:\n raise credentials_exception\n return user\n\nasync def get_current_active_user(current_user: User = Depends(get_current_user)):\n if current_user.disabled:\n raise HTTPException(status_code=400, detail=\"Inactive user\")\n return current_user # I can read current_user well...\n```\n\n```text\ncurrent_user: User = Depends(get_current_user)\n```\n\n```py\n@app.middleware(\"http\")\n async def request_middleware(request, call_next):\n \n # some operation\n \n if request.headers.get('Authorization'):\n HttpRequestUtil.set_current_user_context(request=request)\n \n return await call_next(request)\n\n\n class HttpRequestUtil:\n \n @staticmethod\n def get_bearer_token(request: Request):\n auth_token = request.headers.get('Authorization')\n if 'Bearer' in auth_token:\n bearer_token: str = auth_token.split('Bearer')[1].strip()\n return bearer_token\n \n @staticmethod\n def set_current_user_context(request: Request):\n jwt_token=HttpRequestUtil.get_bearer_token(request)\n \n # if you want jwt claims, you can do below operation\n jwt_claims = jwt.get_unverified_claims(jwt_token)\n # ...\n # ...\n # Other Operation\n # ...\n```\n\n========================================\n\nComments:\n- I couldn't find method `jwt.get_unverified_claims` in jwt. Instead use `jwt.decode(jwt_token, options={\"verify_signature\": False})` which works.\n- @AnkitJain I am using jwt from jose to get that method: from jose import jwt","metadata":{"transformedAt":"2026-08-18T18:32:29.156Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":164,"estimatedTokens":1375}}695{"id":"stack-67335107","source":"stackoverflow","questionId":67335107,"title":"FastAPI - how to generate random ID?","tags":["python","database","fastapi"],"text":"Title: FastAPI - how to generate random ID?\nTags: python, database, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm making simple CRUD API using FastAPI and what I want to do is generate unique random when creating new item (other fields are address and name which should be filled by user). How can I do that?\n\nThere is fragment of my code with class and a POST function.\n\n```\napp = FastAPI()\n\nuserdb = []\n\nclass User(BaseModel):\n id: int\n address: str\n name: str\n\n@app.post(\"/users\")\ndef add_user(user: User):\n userdb.append(users.dict())\n return userdb[-1]\n```\n\n========================================\n\nTop Answer:\nuuid4 is often the way to go\n\nIt'll be absolutely unique amongst any id *ever* generated with the function *anywhere* with astronomical likelihood (refer to RFC-4122 Section 4.4) and is very fast\n\n```\nfrom uuid import uuid4\n\n...\n unique_id = str(uuid4())\n```\n\n========================================\n\nCode:\n```text\napp = FastAPI()\n\nuserdb = []\n\nclass User(BaseModel):\n id: int\n address: str\n name: str\n\n@app.post(\"/users\")\ndef add_user(user: User):\n userdb.append(users.dict())\n return userdb[-1]\n```\n\n```text\n...\n\nnotes = sqlalchemy.Table(\n \"notes\",\n metadata,\n sqlalchemy.Column(\"id\", sqlalchemy.Integer, primary_key=True),\n sqlalchemy.Column(\"text\", sqlalchemy.String),\n sqlalchemy.Column(\"completed\", sqlalchemy.Boolean),\n)\n\n...\nclass NoteIn(BaseModel):\n text: str\n completed: bool\n\nclass Note(BaseModel):\n id: int\n text: str\n completed: bool\n\n...\n\n@app.post(\"/notes/\", response_model=Note)\nasync def create_note(note: NoteIn):\n query = notes.insert().values(text=note.text, completed=note.completed)\n last_record_id = await database.execute(query)\n return {**note.dict(), \"id\": last_record_id}\n```\n\n```text\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\n\napp = FastAPI()\n\nuserdb = []\n\nclass UserIn(BaseModel):\n address: str\n name: str\n\nclass User(BaseModel):\n id: int\n address: str\n name: str\n\n@app.post(\"/users\")\ndef add_user(user_in: UserIn) -> User:\n userdb.append(user_in)\n user_out_dict = userdb[-1].dict()\n user_out_dict.update({\"id\": len(userdb)-1})\n return User(**user_out_dict)\n```\n\n```text\nUserIn\n```\n\n```text\nUser\n```\n\n```text\nuserdb\n```\n\n```py\nfrom uuid import uuid4\n\n...\n unique_id = str(uuid4())\n```\n\n========================================\n\nComments:\n- this sounds like completely broken design. Why is api generating item id? it should be created by code that handles object creation or storage.\n- Thank you but it is just an exercise, I don't have any external database\n- I updated with an example of an ID that indicates the index in your list. The code in the second block should run as-is.","metadata":{"transformedAt":"2026-08-18T18:32:29.156Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":7,"totalLines":138,"estimatedTokens":683}}696{"id":"stack-70947573","source":"stackoverflow","questionId":70947573,"title":"FASTAPI run in conjunction with Alembic, but autogenerate does not detect the models","tags":["python","fastapi","alembic"],"text":"Title: FASTAPI run in conjunction with Alembic, but autogenerate does not detect the models\nTags: python, fastapi, alembic\nSource: Stack Overflow\n\nQuestion:\nI am relatively new to FASTAPI but decided to setup a project with Postgres and Alembic. I managed to get the migrations create new versions everytime i use an automigrate, but for some reason I do not get any updates from my models, alas they stay blank. I am kind of lost what is going wrong.\n\nMain.py\n\n```\nfrom fastapi import FastAPI\nimport os\napp = FastAPI()\n\n@app.get(\"/\")\nasync def root():\n return {\"message\": os.getenv(\"SQLALCHEMY_DATABASE_URL\")}\n\n@app.get(\"/hello/{name}\")\nasync def say_hello(name: str):\n return {\"message\": f\"Hello {name}\"}\n```\n\nDatabase.py\n\n```\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import sessionmaker\nimport os\n\nSQLALCHEMY_DATABASE_URL = os.getenv(\"SQLALCHEMY_DATABASE_URL\")\n\nengine = create_engine(\"postgresql://postgres:mysuperpassword@localhost/rodney\")\nSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)\n\nBase = declarative_base()\n\ndef get_db():\n db = SessionLocal()\n try:\n yield db\n except:\n db.close()\n```\n\nMy only model so far\n\n```\nfrom sqlalchemy import Integer, String\nfrom sqlalchemy.sql.schema import Column\nfrom ..db.database import Base\n\nclass CounterParty(Base):\n __tablename__ = \"Counterparty\"\n\n id = Column(Integer, primary_key=True)\n Name = Column(String, nullable=False)\n```\n\nenv.py (alembic)\n\n```\nfrom logging.config import fileConfig\n\nfrom sqlalchemy import engine_from_config\nfrom sqlalchemy import pool\n\nfrom alembic import context\n\n# this is the Alembic Config object, which provides\n# access to the values within the .ini file in use.\nconfig = context.config\n\n# Interpret the config file for Python logging.\n# This line sets up loggers basically.\nfileConfig(config.config_file_name)\n\n# add your model's MetaData object here\n# for 'autogenerate' support\nfrom app.db.database import Base\ntarget_metadata = Base.metadata\n\n# other values from the config, defined by the needs of env.py,\n# can be acquired:\n# my_important_option = config.get_main_option(\"my_important_option\")\n# ... etc.\n\ndef run_migrations_offline():\n \"\"\"Run migrations in 'offline' mode.\n\n This configures the context with just a URL\n and not an Engine, though an Engine is acceptable\n here as well. By skipping the Engine creation\n we don't even need a DBAPI to be available.\n\n Calls to context.execute() here emit the given string to the\n script output.\n\n \"\"\"\n url = config.get_main_option(\"sqlalchemy.url\")\n context.configure(\n url=url,\n target_metadata=target_metadata,\n literal_binds=True,\n dialect_opts={\"paramstyle\": \"named\"},\n )\n\n with context.begin_transaction():\n context.run_migrations()\n\ndef run_migrations_online():\n \"\"\"Run migrations in 'online' mode.\n\n In this scenario we need to create an Engine\n and associate a connection with the context.\n\n \"\"\"\n connectable = engine_from_config(\n config.get_section(config.config_ini_section),\n prefix=\"sqlalchemy.\",\n poolclass=pool.NullPool,\n )\n\n with connectable.connect() as connection:\n context.configure(\n connection=connection, target_metadata=target_metadata\n )\n\n with context.begin_transaction():\n context.run_migrations()\n\nif context.is_offline_mode():\n run_migrations_offline()\nelse:\n run_migrations_online()\n```\n\nNow Alembic creates ampty migrations when I run \"alembic revision --autogenerate -m \"initial setup\"\"\nhttps://i.sstatic.net/TuGyg.png\n\nMy folder structure\nhttps://i.sstatic.net/QWBa1.png\n\nIf anyone has any idea I would be very greatful. Cheers!\n\n========================================\n\nTop Answer:\nThe env.py file does not find the models because you haven't imported them. One solution to it, you just import them right away in your env.py file as:\n\nfrom ..models import *\n\nHowever, you need to have an **init**.py file in your models directory, and include there all your models.\n\nAnother way (however, not recommended): if you have only one model, you can import it directly as:\n\nfrom ..models.counterPartyModel import\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nimport os\napp = FastAPI()\n\n\n@app.get(\"/\")\nasync def root():\n return {\"message\": os.getenv(\"SQLALCHEMY_DATABASE_URL\")}\n\n\n@app.get(\"/hello/{name}\")\nasync def say_hello(name: str):\n return {\"message\": f\"Hello {name}\"}\n```\n\n```text\nfrom sqlalchemy import create_engine\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import sessionmaker\nimport os\n\nSQLALCHEMY_DATABASE_URL = os.getenv(\"SQLALCHEMY_DATABASE_URL\")\n\nengine = create_engine(\"postgresql://postgres:mysuperpassword@localhost/rodney\")\nSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)\n\nBase = declarative_base()\n\ndef get_db():\n db = SessionLocal()\n try:\n yield db\n except:\n db.close()\n```\n\n```text\nfrom sqlalchemy import Integer, String\nfrom sqlalchemy.sql.schema import Column\nfrom ..db.database import Base\n\n\nclass CounterParty(Base):\n __tablename__ = \"Counterparty\"\n\n id = Column(Integer, primary_key=True)\n Name = Column(String, nullable=False)\n```\n\n```text\nfrom logging.config import fileConfig\n\nfrom sqlalchemy import engine_from_config\nfrom sqlalchemy import pool\n\nfrom alembic import context\n\n# this is the Alembic Config object, which provides\n# access to the values within the .ini file in use.\nconfig = context.config\n\n# Interpret the config file for Python logging.\n# This line sets up loggers basically.\nfileConfig(config.config_file_name)\n\n# add your model's MetaData object here\n# for 'autogenerate' support\nfrom app.db.database import Base\ntarget_metadata = Base.metadata\n\n# other values from the config, defined by the needs of env.py,\n# can be acquired:\n# my_important_option = config.get_main_option(\"my_important_option\")\n# ... etc.\n\n\ndef run_migrations_offline():\n \"\"\"Run migrations in 'offline' mode.\n\n This configures the context with just a URL\n and not an Engine, though an Engine is acceptable\n here as well. By skipping the Engine creation\n we don't even need a DBAPI to be available.\n\n Calls to context.execute() here emit the given string to the\n script output.\n\n \"\"\"\n url = config.get_main_option(\"sqlalchemy.url\")\n context.configure(\n url=url,\n target_metadata=target_metadata,\n literal_binds=True,\n dialect_opts={\"paramstyle\": \"named\"},\n )\n\n with context.begin_transaction():\n context.run_migrations()\n\n\ndef run_migrations_online():\n \"\"\"Run migrations in 'online' mode.\n\n In this scenario we need to create an Engine\n and associate a connection with the context.\n\n \"\"\"\n connectable = engine_from_config(\n config.get_section(config.config_ini_section),\n prefix=\"sqlalchemy.\",\n poolclass=pool.NullPool,\n )\n\n with connectable.connect() as connection:\n context.configure(\n connection=connection, target_metadata=target_metadata\n )\n\n with context.begin_transaction():\n context.run_migrations()\n\n\nif context.is_offline_mode():\n run_migrations_offline()\nelse:\n run_migrations_online()\n```\n\n```text\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\n\nclass Entities(BaseModel):\n text: str\n\nclass EntitesOut(BaseModel):\n headings: str\n Probability: str\n Prediction: str\n\nmodel_load = load_model('BERT_HATESPEECH')\ntokenizer = DistilBertTokenizerFast.from_pretrained('BERT_HATESPEECH_TOKENIZER')\nfile_to_read = open(\"label_encoder_bert_hatespeech.pkl\", \"rb\")\nlabel_encoder = pickle.load(file_to_read)\n\napp = FastAPI()\n\n@app.post('/predict', response_model=EntitesOut)\ndef prep_data(text:Entities):\n text = text.text\n tokens = tokenizer(text, max_length=150, truncation=True, \n padding='max_length', \n add_special_tokens=True, \n return_tensors='tf')\n tokens = {'input_ids': tf.cast(tokens['input_ids'], tf.float64), 'attention_mask': tf.cast(tokens['attention_mask'], tf.float64)}\n headings = '''Non-offensive', 'identity_hate', 'neither', 'obscene','offensive', 'sexism'''\n probs = model_load.predict(tokens)[0]\n pred = label_encoder.inverse_transform([np.argmax(probs)])\n return {\"headings\":headings,\n \"Probability\":str(np.round(probs,3)),\n \"Prediction\":str(pred)}\n```\n\n```text\ntext:str as input\n```\n\n```text\nheadings, Probability, and prediction as Outputs in EntitiesOut class\n```\n\n```text\nrevision\n```\n\n```text\nupgrade\n```\n\n```text\ndowngrade\n```\n\n========================================\n\nComments:\n- You are not getting any output from the model right?\n- no it, doesn't recognise my models somehow. though I import Base from db.database and also in env.py I set target_metadata = Base.metadata\n- Yes, for me I was also getting this issue. hope my case helps you understand the problem in your case. I was using ML model to deploy with FastApi. let me explain you\n- Were you able to solve this?\n- thanks for your code snippet. looking at your code I realised maybe it could find it all because its in 1 file. I do not understand why it would suddenly work by added a DTO as scheme in the file. but it did trigger me to import the scheme and model in my env.py file. It turned out that I explicity need to import the model into the database for it to recognise my model. So your code still pointed me in the right direction. Thanks mate.\n- How was this answer useful? I don't see sqlalchemy in the context in the code above.\n- His output weren't recognised by the model. This is done by adding classes or json syntax.\n- Ah you're a lifesaver! This was what I was missing. thank you","metadata":{"transformedAt":"2026-08-18T18:32:29.157Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":10,"totalLines":357,"estimatedTokens":2427}}697{"id":"stack-64788026","source":"stackoverflow","questionId":64788026,"title":"Can't open and read content of an uploaded zip file with FastAPI","tags":["python","rest","multipartform-data","fastapi"],"text":"Title: Can't open and read content of an uploaded zip file with FastAPI\nTags: python, rest, multipartform-data, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am currently developing a little backend project for myself with the Python Framework FastAPI. I made an endpoint, where the user should be able to upload 2 files, while the first one is a zip-file (which contains X .xmls) and the latter a normal .xml file.\n\nThe code is as follows:\n\n```\n@router.post(\"/sendxmlinzip/\")\ndef create_upload_files_with_zip(files: List[UploadFile] = File(...)):\n if not len(files) == 2:\n raise Httpex.EXPECTEDTWOFILES\n my_file = files[0].file\n zfile = zipfile.ZipFile(my_file, 'r')\n filelist = []\n for finfo in zfile.infolist():\n print(finfo)\n ifile = zfile.open(finfo)\n line_list = ifile.readlines()\n print(line_list)\n```\n\nThis should print the content of the files, that are in the .zip file, but it raises the Exception\n\nAttributeError: 'SpooledTemporaryFile' object has no attribute 'seekable'\n\nIn the row `ifile = zfile.open(finfo)`\n\nUpon approximately 3 days research with a lot of trial and error involved, trying to use different functions such as .read() or .extract(), I gave up. Because the python docs literally state, that this should be possible in this way...\n\nFor you, who do not know about FastAPI, it's a backend fw for Restful Webservices and is using the starlette datastructure for UploadFile. Please forgive me, if I have overseen something VERY obvious, but I literally tried to check every corner, that may have been the possible cause of the error such as:\n\n- Check, whether another implementation is possible\n\n- Check, that the .zip file is correct\n\n- Check, that I attach the correct file (lol)\n\n- Debug to see, whether the actual data, that comes to the backend is indeed the .zip file\n\n========================================\n\nTop Answer:\nThis is my workaround\n\n```\nwith zipfile.ZipFile(io.BytesIO(file.read()), 'r') as zip:\n```\n\n========================================\n\nCode:\n```text\n@router.post(\"/sendxmlinzip/\")\ndef create_upload_files_with_zip(files: List[UploadFile] = File(...)):\n if not len(files) == 2:\n raise Httpex.EXPECTEDTWOFILES\n my_file = files[0].file\n zfile = zipfile.ZipFile(my_file, 'r')\n filelist = []\n for finfo in zfile.infolist():\n print(finfo)\n ifile = zfile.open(finfo)\n line_list = ifile.readlines()\n print(line_list)\n```\n\n```text\nifile = zfile.open(finfo)\n```\n\n```text\nseekable\n```\n\n```text\nreadable\n```\n\n```text\nwritable\n```\n\n```text\nTemporaryFile\n```\n\n```text\nwith zipfile.ZipFile(io.BytesIO(file.read()), 'r') as zip:\n```\n\n========================================\n\nComments:\n- I also tried to run the SAME code snippet by only using a LOCAL zipfile and i did work perfectly fine, so i reckon the issue is due to the Starlette Datastructure... I just can't seem to find a workaround for this\n- It's true that a `SpooledTemporaryFile` does not have a `seekable` method, but I'm not convinced that's a problem. You could try to work around the issue by writing the contents of `my_file` to a local `TemporaryFile` and then opening that with `zipfile.ZipFile`, maybe.\n- Thanks for the short and concise answer! Worked perfectly\n- Can confirm python3.11 fixed this bug github.com/python/cpython/issues/70363","metadata":{"transformedAt":"2026-08-18T18:32:29.157Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":7,"totalLines":100,"estimatedTokens":825}}698{"id":"stack-79382645","source":"stackoverflow","questionId":79382645,"title":"FastAPI - Why does synchronous code do not block the event Loop?","tags":["python","multithreading","asynchronous","fastapi","gil"],"text":"Title: FastAPI - Why does synchronous code do not block the event Loop?\nTags: python, multithreading, asynchronous, fastapi, gil\nSource: Stack Overflow\n\nQuestion:\nI’ve been digging into FastAPI’s handling of synchronous and asynchronous endpoints, and I’ve come across a few things that I’m trying to understand more clearly, especially with regards to how blocking operations behave in Python.\n\nFrom what I understand, when a synchronous route (defined with def) is called, FastAPI offloads it to a separate thread from the thread pool to avoid blocking the main event loop. This makes sense, as the thread can be blocked (e.g., time.sleep()), but the event loop itself doesn’t get blocked because it continues handling other requests.\n\nBut here’s my confusion: If the function is truly blocking (e.g., it’s waiting for something like time.sleep()), how is the event loop still able to execute other tasks concurrently? Isn’t the Python interpreter supposed to execute just one thread at a time?\n\nHere an example:\n\n```\nfrom fastapi import APIRouter\nimport os\nimport threading\nimport asyncio\n\napp = APIRouter()\n\n@app.get('/sync')\ndef tarefa_sincrona():\n print('Sync')\n total = 0\n for i in range(10223424*1043):\n total += i\n print('Sync task done')\n\n@app.get('/async')\nasync def tarefa_sincrona():\n print('Async task')\n await asyncio.sleep(5)\n print('Async task done')\n```\n\nIf I make two requests — the first one to the sync endpoint and the second one to the async endpoint — almost at the same time, I expected the event loop to be blocked. However, in reality, what happens is that the two requests are executed \"in parallel.\"\n\n========================================\n\nTop Answer:\ntime.sleep() block the current process but it doesnt completly render the interpreter useless since it need to measure the time. So it keeps working.\n\nThink it like a person looking his clock and waiting. The person is capable to do other things and keeps breathing for example but their main foucs it to wait for sometime. Maybe waiting for their meal to cook.\n\nIn your scenerio where you use asynchronous, python interpreter just pauses one task and looks at other. So it is not completly usesless. Think it like a round-robin. Works for one process for limited cpu clock time (waiting for the time sleep in this example) then pauses it and looks at other process.\n\"the function is truly blocking\" doesnt mean it renders interpreter to unable to do anything other but it just tells it to wait for something.\n\nSo our person in example does some other task like loading the dishes in dishwasher and for every 4 dish placed they check their clock to see if their meal is ready. So cooking the meal is a blocking process for preapering dinner since you need to wait for it to be cooked. But you can asyncly load the dishes and check for the time to see if meal is ready.\n\n========================================\n\nCode:\n```text\nfrom fastapi import APIRouter\nimport os\nimport threading\nimport asyncio\n\napp = APIRouter()\n\n@app.get('/sync')\ndef tarefa_sincrona():\n print('Sync')\n total = 0\n for i in range(10223424*1043):\n total += i\n print('Sync task done')\n\n@app.get('/async')\nasync def tarefa_sincrona():\n print('Async task')\n await asyncio.sleep(5)\n print('Async task done')\n```\n\n```py\n# main.py\n\nfrom fastapi import FastAPI\nimport time\nimport os\nimport threading\n\napp = FastAPI()\n\ndef bind_cpu(id: int):\n thread_id = threading.get_ident()\n\n print(f\"{time.perf_counter():.4f}: BIND GIL for ID: {id}, internals: PID({os.getpid()}), thread({thread_id})\")\n\n start = time.perf_counter()\n total = 0\n for i in range(100_000_000):\n total += i\n\n end = time.perf_counter()\n print(f\"{time.perf_counter():.4f}: REL GIL for ID: {id}, internals: PID({os.getpid()}), thread({thread_id}). Duration: {end-start:.4f}s\")\n\n return total\n\ndef endpoint_handler(method: str, id: int):\n print(f\"{time.perf_counter():.4f}: Worker reads {method} endpoint with ID: {id} - internals: PID({os.getpid()}), thread({threading.get_ident()})\")\n result = bind_cpu(id)\n print(f\"{time.perf_counter():.4f}: Worker finished ID: {id} - internals: PID({os.getpid()}), thread({threading.get_ident()})\")\n return f\"ID: {id}, {result}\"\n\n\n@app.get(\"/async/{id}\")\nasync def async_endpoint_that_gets_blocked(id: int):\n return endpoint_handler(\"async\", id)\n\n@app.get(\"/sync/{id}\")\ndef sync_endpoint_that_gets_blocked(id: int):\n return endpoint_handler(\"sync\", id)\n\nif __name__ == \"__main__\":\n import uvicorn\n uvicorn.run(\"main:app\", host=\"0.0.0.0\", port=8000, reload=True, workers=1)\n```\n\n```py\n# test.py\n\nimport asyncio\nimport httpx\nimport time\n\nasync def send_requests():\n async with httpx.AsyncClient(timeout=httpx.Timeout(25.0)) as client:\n tasks = []\n for i in range(1, 5):\n print(f\"{time.perf_counter():.4f}: Sending HTTP request for id: {i}\")\n if i % 2 == 0:\n tasks.append(client.get(f\"http://localhost:8000/async/{i}\"))\n else:\n tasks.append(client.get(f\"http://localhost:8000/sync/{i}\"))\n responses = await asyncio.gather(*tasks)\n for response in responses:\n print(f\"{time.perf_counter():.4f}: {response.text}\")\n\nasyncio.run(send_requests())\n```\n\n```text\n[...]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\n\n10755.6897: Sending HTTP request for id: 1\n10755.6900: Sending HTTP request for id: 2\n10755.6902: Sending HTTP request for id: 3\n10755.6904: Sending HTTP request for id: 4\n\n10755.9722: Worker reads async endpoint with ID: 4 - internals: PID(24492), thread(8972)\n10755.9725: BIND GIL for ID: 4, internals: PID(24492), thread(8972)\n10759.4551: REL GIL for ID: 4, internals: PID(24492), thread(8972). Duration: 3.4823s\n10759.4554: Worker finished ID: 4 - internals: PID(24492), thread(8972)\nINFO: 127.0.0.1:56883 - \"GET /async/4 HTTP/1.1\" 200 OK\n\n10759.4566: Worker reads async endpoint with ID: 2 - internals: PID(24492), thread(8972)\n10759.4568: BIND GIL for ID: 2, internals: PID(24492), thread(8972)\n10762.6428: REL GIL for ID: 2, internals: PID(24492), thread(8972). Duration: 3.1857s\n10762.6431: Worker finished ID: 2 - internals: PID(24492), thread(8972)\nINFO: 127.0.0.1:56884 - \"GET /async/2 HTTP/1.1\" 200 OK\n\n10762.6446: Worker reads sync endpoint with ID: 3 - internals: PID(24492), thread(22648)\n10762.6448: BIND GIL for ID: 3, internals: PID(24492), thread(22648)\n10762.6968: Worker reads sync endpoint with ID: 1 - internals: PID(24492), thread(9144)\n10762.7127: BIND GIL for ID: 1, internals: PID(24492), thread(9144)\n10768.9234: REL GIL for ID: 3, internals: PID(24492), thread(22648). Duration: 6.2784s\n10768.9338: Worker finished ID: 3 - internals: PID(24492), thread(22648)\nINFO: 127.0.0.1:56882 - \"GET /sync/3 HTTP/1.1\" 200 OK\n10769.2121: REL GIL for ID: 1, internals: PID(24492), thread(9144). Duration: 6.4835s\n10769.2124: Worker finished ID: 1 - internals: PID(24492), thread(9144)\nINFO: 127.0.0.1:56885 - \"GET /sync/1 HTTP/1.1\" 200 OK\n\n10769.2138: \"ID: 1, 4999999950000000\"\n10769.2141: \"ID: 2, 4999999950000000\"\n10769.2143: \"ID: 3, 4999999950000000\"\n10769.2145: \"ID: 4, 4999999950000000\"\n```\n\n```text\ntime.sleep()\n```\n\n```text\ntime.sleep()\n```\n\n```text\nC\n```\n\n```text\nCPython\n```\n\n```text\nC\n```\n\n```text\nPy_BEGIN_ALLOW_THREADS\n```\n\n```text\n{ PyThreadState *_save; _save = PyEval_SaveThread();\n```\n\n```text\nPyEval_SaveThread()\n```\n\n```text\ntime.sleep()\n```\n\n```text\nfunc_1\n```\n\n```text\nfunc_2\n```\n\n```text\nfunc_1\n```\n\n```text\nfunc_1\n```\n\n```text\nfunc_2\n```\n\n```text\nasyncio\n```\n\n```text\nCPython\n```\n\n```text\ntime.sleep()\n```\n\n```text\nsync\n```\n\n```text\nasync\n```\n\n```text\nasync\n```\n\n```text\nsync\n```\n\n```text\nsync\n```\n\n```text\nmultiprocessing\n```\n\n```text\nthreading\n```\n\n```text\npython main.py\n```\n\n```text\npython test.py\n```\n\n```text\nasync\n```\n\n```text\nsync\n```\n\n```text\nasync\n```\n\n```text\nasync\n```\n\n```text\nsync\n```\n\n```text\nPy_BEGIN_ALLOW_THREADS\n```\n\n```text\nPy_END_ALLOW_THREADS\n```\n\n========================================\n\nComments:\n- You block *the thread*, but the whole point of threading is that others can continue - see e.g. stackoverflow.com/q/92928/3001761\n- You're misunderstanding Python's Global Interpreter Lock. Only one thread can be actively running Python code at any one time. But if one thread is sleeping others can run. Likewise, if a thread is executing C code (e.g. numpy), it can release the lock if it wants, and then wait for the lock before returning back to the Python caller.\n- @Chris, I think this is a different question. The other post's focus was on understanding how FastAPI works. Here, however, the focus is on why a blocking code in one thread doesn’t make other threads wait for its completion before executing. I apologize if I wasn’t clear about my doubt. Anyway, I found the answer in another forum. Here it is: \"Yes, if you're doing math or string manipulation or whatever, then the GIL will be exchanged between bytecodes, but you'll never get two bytecodes running at the same time.\" and this makes sense for me. Thank you for your response nonetheless! 😊\n- That answer is much more than *\"how FastAPI works.\"* Please read it thoroughly, in order to get a complete answer to your question. I have now added a section, complementing the rest, related to your query above. Also, the answer from another forum that you are refering to is not entirely correct. Please have a look at the latest section added in the duplicate question about GIL (but again, please read the whole answer), where you would find when the GIL is released, as well as that certain math operations would not guarantee its release.\n- Thank you, I understand what you're saying. However, in this case, if my synchronous code is performing heavy computations instead of using time.sleep(), the interpreter should be locked and unable to execute anything else until the code is completed, right? For async code, I can use await to instruct the interpreter when to switch to another task, but for sync code, I still don't fully understand how it works.\n- This would be accurate for multiprocess concurrency, but it's less accurate for threading in a GIL context. Threads that execute code will block the event loop, but threads that wait for some kind of I/O will not. So it is actually the case that if a function is *truly* blocking, e.g. executes continually on the CPU, the GIL will be locked to that thread until such a time that the function either finishes or waits for an I/O operation.\n- @Vegard, yes, that's what I thought as well. However, I would appreciate it if you could take a look at the example in my question, as it’s what’s confusing me. :)\n- @JoãoPedroZimmermann No matter what if you do hard calculation, wait for input or for time you pc do not just focus on that, and mindlesly do only that job. If some process overhelms your system you see the \"program not responding\" error, so if your program/code executes without freezing it means it is still responsive even performas a hard calculation. There are aproaches like round-robin, priority-based scheduling to divide your cpu resources by your OS allows divding interpreters focus for multiprocess or event-loop from interpreter to divide focus on async tasks.","metadata":{"transformedAt":"2026-08-18T18:32:29.157Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":37,"totalLines":326,"estimatedTokens":2824}}699{"id":"stack-75145424","source":"stackoverflow","questionId":75145424,"title":"FastAPI/Starlette: How to handle exceptions inside background tasks?","tags":["python","exception","fastapi","background-task","starlette"],"text":"Title: FastAPI/Starlette: How to handle exceptions inside background tasks?\nTags: python, exception, fastapi, background-task, starlette\nSource: Stack Overflow\n\nQuestion:\nI developed some API endpoints using FastAPI. These endpoints are allowed to run `BackgroundTasks`. Unfortunately, I do not know how to handle unpredictable issues from theses tasks.\n\nAn example of my API is shown below:\n\n```\n# main.py\n\nfrom fastapi import FastAPI\nimport uvicorn\n\napp = FastAPI()\n\ndef test_func(a, b):\n raise ...\n\n@app.post(\"/test\", status_code=201)\nasync def test(request: Request, background_task: BackgroundTasks):\n background_task.add_task(test_func, a, b)\n return {\n \"message\": \"The test task was successfully sent.\",\n }\nif __name__ == \"__main__\":\n uvicorn.run(\n app=app,\n host=\"0.0.0.0\",\n port=8000\n )\n# python3 main.py to run\n# fastapi == 0.78.0\n# uvicorn == 0.16.0\n```\n\nCan you help me to handle any type of exception from such a background task?\nShould I add any `exception_middleware` from Starlette, in order to achieve this?\n\n========================================\n\nCode:\n```py\n# main.py\n\nfrom fastapi import FastAPI\nimport uvicorn\n\n\napp = FastAPI()\n\n\ndef test_func(a, b):\n raise ...\n\n\n@app.post(\"/test\", status_code=201)\nasync def test(request: Request, background_task: BackgroundTasks):\n background_task.add_task(test_func, a, b)\n return {\n \"message\": \"The test task was successfully sent.\",\n }\nif __name__ == \"__main__\":\n uvicorn.run(\n app=app,\n host=\"0.0.0.0\",\n port=8000\n )\n# python3 main.py to run\n# fastapi == 0.78.0\n# uvicorn == 0.16.0\n```\n\n```text\nBackgroundTasks\n```\n\n```text\nexception_middleware\n```\n\n```py\ndef test_func(a, b):\n try:\n # some background task logic here...\n raise <some_exception>\n except Exception as e:\n print('Something went wrong')\n # use `print(e.detail)` to print out the Exception's details\n```\n\n```text\nBackground tasks\n```\n\n```text\nraise\n```\n\n```text\nException\n```\n\n```text\nException\n```\n\n```text\ntry-except\n```\n\n```text\nException\n```\n\n```text\nlogging\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\nevent loop\n```\n\n========================================\n\nComments:\n- why you can't use `try / except` statement?\n- Okay. Thank you a lot :) I was not aware about good practices to handle background tasks error. I will develop an entire logging system for the API.","metadata":{"transformedAt":"2026-08-18T18:32:29.157Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":14,"totalLines":137,"estimatedTokens":598}}700{"id":"stack-67203611","source":"stackoverflow","questionId":67203611,"title":"Fastapi alias for url/router/endpoint (set same handler for them)","tags":["fastapi"],"text":"Title: Fastapi alias for url/router/endpoint (set same handler for them)\nTags: fastapi\nSource: Stack Overflow\n\nQuestion:\nHow I can make alias (call the same handler) for similar url/routers like `https://myapi/users/5` and `https://myapi/users/me` (my id placed in token and it's 5).\n\n```\n@router.get(\"/{employee_id}}\", status_code=200, response_model=schemas.EmployeeOut)\n async def get_employee(\n employee_id: int = Path(default=..., ge=0, description='Id получаемого сотрудника.', example=8),\n token: str = Depends(config.oauth2_scheme),\n postgres_session: AsyncSession = Depends(database.get_db)):\n try:\n token_payload = services.get_token_payload(token=token)\n if token_payload['role'] in (config.OPERATOR_ROLE, config.OPERATOR_ROLE, config.CLINIC_ROLE):\n return (await postgres_session.execute(statement=models.employees.select().where(\n models.employees.c.id == employee_id))).fetchone()\n else:\n raise config.known_errors['forbidden']\n except Exception as error:\n services.error_handler(error)\n \n # Just as example!\n @router.get(\"/me}\", status_code=200, response_model=List[schemas.TicketOut])\n async def get_me(\n token: str = Depends(config.oauth2_scheme)):\n token_payload = services.get_token_payload(token=token)\n get_employee(employee_id=token_payload['sub'])\n```\n\nThese functions is almost identical, the one difference is that in the second function no path parameter `employee_id`, but it's anyway are present in the token.\n\nYou can wonder why you need `me` url - it's just for convenience\n\n========================================\n\nTop Answer:\nThe `/me` endpoint needs to be above the `/{employee_id}`\n\nCheck out this link: https://fastapi.tiangolo.com/tutorial/path-params/#order-matters\n\n========================================\n\nCode:\n```py\n@router.get(\"/{employee_id}}\", status_code=200, response_model=schemas.EmployeeOut)\n async def get_employee(\n employee_id: int = Path(default=..., ge=0, description='Id получаемого сотрудника.', example=8),\n token: str = Depends(config.oauth2_scheme),\n postgres_session: AsyncSession = Depends(database.get_db)):\n try:\n token_payload = services.get_token_payload(token=token)\n if token_payload['role'] in (config.OPERATOR_ROLE, config.OPERATOR_ROLE, config.CLINIC_ROLE):\n return (await postgres_session.execute(statement=models.employees.select().where(\n models.employees.c.id == employee_id))).fetchone()\n else:\n raise config.known_errors['forbidden']\n except Exception as error:\n services.error_handler(error)\n \n # Just as example!\n @router.get(\"/me}\", status_code=200, response_model=List[schemas.TicketOut])\n async def get_me(\n token: str = Depends(config.oauth2_scheme)):\n token_payload = services.get_token_payload(token=token)\n get_employee(employee_id=token_payload['sub'])\n```\n\n```text\nhttps://myapi/users/5\n```\n\n```text\nhttps://myapi/users/me\n```\n\n```text\nemployee_id\n```\n\n```text\nme\n```\n\n```py\n@router.post('/api/action1')\n@router.post('/api/action2')\ndef do_action():\n pass\n```\n\n```text\nrouter.post\n```\n\n```text\n/me\n```\n\n```text\n/{employee_id}\n```\n\n========================================\n\nComments:\n- Thank u for the refinement, but a question in another words, - is how to set multiple decorators for the same handler\n- I want to write a function which takes an image id and read the database table for imageID = img001 and will show all the metadata for that image. like localhost:8000/photo/?id=img001 Then I wanted aliases like below... localhost:8000/myimage/001 -> localhost:8000/photo/?id=img001 There is a separate system to add the images into the database and that is dynamic and anytime a new image can come so I cannot configure and populate these aliases beforehand - they need to be dynamically aliased like above. Is it possible in fastapi ?\n- @NDS do you mean you nead to dynamically create routes? Like `/myimage/,,,`, `/photo/...`, `/great-photo/...` etc.? I think for this you need at least some part of route being static, like having prefix `/images/`. Then you can go with only 2 routes: @router.get('/images/{suffix}/{image_id}') def get_image(suffix: str, image_id: str): handle_image(suffix, image_id) @router.get('/images/{suffix}') def get_image_by_query(suffix: str, image_id: str = Query(...)): handle_image(suffix, image_id)\n- Thanks @Minstel, Yes /myimage/... can be fixed - just want the rest as dynamic so anytime imagN is added into the database then localhost:8000/myimage/N will auto-redirect to localhost:8000/photo/?id=imgN - without manually adding that particular route alias...","metadata":{"transformedAt":"2026-08-18T18:32:29.157Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":9,"totalLines":111,"estimatedTokens":1176}}701{"id":"stack-70611806","source":"stackoverflow","questionId":70611806,"title":"FastAPI server running on AWS App Runner fails after 24 hours","tags":["python","amazon-web-services","gunicorn","fastapi"],"text":"Title: FastAPI server running on AWS App Runner fails after 24 hours\nTags: python, amazon-web-services, gunicorn, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have a FastAPI server configured with Gunicorn, deployed on AWS App Runner. When I try to access the endpoint, it works perfectly, however, after 24 hours, when I try to access the same endpoint, I get a 502 bad gateway error, and nothing is logged on cloudWatch after this point, until I redeploy the application, then it starts working fine again.\n\nI suspect this has to do with my Gunicorn configuration itself which was somehow shutting down my API after some time, and not AWS App Runner, but I have not found any solution. I have also shown my Gunicorn setup below. Any hep will be appreciated.\n\n```\nfrom fastapi import FastAPI\nimport uvicorn\nfrom fastapi.middleware.cors import CORSMiddleware\nfrom gunicorn.app.base import BaseApplication\nimport os\nimport multiprocessing\n\napi = FastAPI()\n\ndef number_of_workers():\n print((multiprocessing.cpu_count() * 2) + 1)\n return (multiprocessing.cpu_count() * 2) + 1\n\nclass StandaloneApplication(BaseApplication):\n def __init__(self, app, options=None):\n self.options = options or {}\n self.application = app\n super().__init__()\n\n def load_config(self):\n config = {\n key: value for key, value in self.options.items()\n if key in self.cfg.settings and value is not None\n }\n for key, value in config.items():\n self.cfg.set(key.lower(), value)\n\n def load(self):\n return self.application\n\n@api.get(\"/test\")\nasync def root():\n return 'Success'\n\nif __name__ == \"__main__\":\n if os.environ.get('APP_ENV') == \"development\":\n uvicorn.run(\"api:api\", host=\"0.0.0.0\", port=2304, reload=True)\n\n else:\n options = {\n \"bind\": \"0.0.0.0:2304\",\n \"workers\": number_of_workers(),\n \"accesslog\": \"-\",\n \"errorlog\": \"-\",\n \"worker_class\": \"uvicorn.workers.UvicornWorker\",\n \"timeout\": \"0\"\n }\n\n StandaloneApplication(api, options).run()\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nimport uvicorn\nfrom fastapi.middleware.cors import CORSMiddleware\nfrom gunicorn.app.base import BaseApplication\nimport os\nimport multiprocessing\n\napi = FastAPI()\n\n\ndef number_of_workers():\n print((multiprocessing.cpu_count() * 2) + 1)\n return (multiprocessing.cpu_count() * 2) + 1\n\n\nclass StandaloneApplication(BaseApplication):\n def __init__(self, app, options=None):\n self.options = options or {}\n self.application = app\n super().__init__()\n\n def load_config(self):\n config = {\n key: value for key, value in self.options.items()\n if key in self.cfg.settings and value is not None\n }\n for key, value in config.items():\n self.cfg.set(key.lower(), value)\n\n def load(self):\n return self.application\n\n\n@api.get(\"/test\")\nasync def root():\n return 'Success'\n\n\nif __name__ == \"__main__\":\n if os.environ.get('APP_ENV') == \"development\":\n uvicorn.run(\"api:api\", host=\"0.0.0.0\", port=2304, reload=True)\n\n else:\n options = {\n \"bind\": \"0.0.0.0:2304\",\n \"workers\": number_of_workers(),\n \"accesslog\": \"-\",\n \"errorlog\": \"-\",\n \"worker_class\": \"uvicorn.workers.UvicornWorker\",\n \"timeout\": \"0\"\n }\n\n StandaloneApplication(api, options).run()\n```\n\n```text\n--timeout-keep-alive\n```\n\n```text\n--keep-alive\n```\n\n```text\naws apprunner update-service --service-arn <arn> --health-check-configuration Protocol=HTTP,Path=/test\n```\n\n========================================\n\nComments:\n- #2 resolved the issue. Thanks!","metadata":{"transformedAt":"2026-08-18T18:32:29.157Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":136,"estimatedTokens":897}}702{"id":"stack-69936050","source":"stackoverflow","questionId":69936050,"title":"How to rename keys in response from database by pydantic schema - FastAPI","tags":["python-3.x","sqlalchemy","orm","fastapi","pydantic"],"text":"Title: How to rename keys in response from database by pydantic schema - FastAPI\nTags: python-3.x, sqlalchemy, orm, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI have a model from my database in `models.py`:\n\n```\nclass Something(Base):\n __tablename__ = \"something\"\n\n DATE = Column(Date, primary_key=True, index=True ) \n a = Column(String, primary_key=True, index=True)\n b = Column(Integer, primary_key=True, index=True)\n c = Column(Float, index=True) \n d = Column(Integer, index=True)\n e = Column(Integer, index=True)\n f = Column(Float, index=True)\n g = Column(Float, index=True) \n h = Column(Integer, index=True)\n```\n\nand a pydantic model in `schema.py`:\n\n```\nclass Something(BaseModel):\n DATE: date\n a: str\n b: int\n c: float = None\n d: int = None\n e: int = None\n f: float = None\n g: float = None\n h: int = None\n\n class Config:\n orm_mode = True\n```\n\nI get data from the database which go through the ORM and in `app.get()` I declare the response model equal to `List[schema.Something]`, but I want to change the names from the database `a, b, c, d` to more beautiful names.\nIs there a solution like mapping names in NestJS?\n\n========================================\n\nCode:\n```py\nclass Something(Base):\n __tablename__ = \"something\"\n\n DATE = Column(Date, primary_key=True, index=True ) \n a = Column(String, primary_key=True, index=True)\n b = Column(Integer, primary_key=True, index=True)\n c = Column(Float, index=True) \n d = Column(Integer, index=True)\n e = Column(Integer, index=True)\n f = Column(Float, index=True)\n g = Column(Float, index=True) \n h = Column(Integer, index=True)\n```\n\n```py\nclass Something(BaseModel):\n DATE: date\n a: str\n b: int\n c: float = None\n d: int = None\n e: int = None\n f: float = None\n g: float = None\n h: int = None\n\n class Config:\n orm_mode = True\n```\n\n```text\nmodels.py\n```\n\n```text\nschema.py\n```\n\n```text\napp.get()\n```\n\n```text\nList[schema.Something]\n```\n\n```text\na, b, c, d\n```\n\n```text\nclass Person(BaseModel):\n first_name: str = Field(..., alias='first')\n last_name: str = Field(..., alias='second')\n\n class Config:\n allow_population_by_field_name = True\n\n\np = Person(**{'first': 'John', 'second': 'White'})\nprint(p.__dict__)\n\n# {'first_name': 'John', 'last_name': 'White'}\n```\n\n```text\nallow_population_by_field_name\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.157Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":115,"estimatedTokens":587}}703{"id":"stack-74019260","source":"stackoverflow","questionId":74019260,"title":"How to specify dependencies for the entire router?","tags":["python","dependency-injection","fastapi"],"text":"Title: How to specify dependencies for the entire router?\nTags: python, dependency-injection, fastapi\nSource: Stack Overflow\n\nQuestion:\n```\nclass User(BaseModel):\n name: str\n token: str\n\nfake_db = [\n User(name='foo', token='a1'),\n User(name='bar', token='a2')\n]\n\nasync def get_user_by_token(token: str = Header()):\n for user in fake_db:\n if user.token == token:\n return user\n else:\n raise HTTPException(status_code=401, detail='Invalid token')\n\n@router.get(path='/test_a', summary='Test route A')\nasync def test_route_a(user: User = Depends(get_user_by_token)):\n return {'name': user.name}\n\n@router.get(path='/test_b', summary='Test route B')\nasync def test_route_a(user: User = Depends(get_user_by_token)):\n return {'name': user.name}\n```\n\nI would like to avoid code duplication. Is it possible to somehow set the line `user: User = Depends(get_user_by_token)` for the entire router? At the same time, I need the `user` object to be available in each method.\n\nIt is very important that the openapi says that you need to specify a header with a token for the method.\n\nhttps://i.sstatic.net/P6uQr.png\n\n========================================\n\nCode:\n```py\nclass User(BaseModel):\n name: str\n token: str\n\nfake_db = [\n User(name='foo', token='a1'),\n User(name='bar', token='a2')\n]\n\nasync def get_user_by_token(token: str = Header()):\n for user in fake_db:\n if user.token == token:\n return user\n else:\n raise HTTPException(status_code=401, detail='Invalid token')\n\n\n@router.get(path='/test_a', summary='Test route A')\nasync def test_route_a(user: User = Depends(get_user_by_token)):\n return {'name': user.name}\n\n\n@router.get(path='/test_b', summary='Test route B')\nasync def test_route_a(user: User = Depends(get_user_by_token)):\n return {'name': user.name}\n```\n\n```text\nuser: User = Depends(get_user_by_token)\n```\n\n```text\nuser\n```\n\n```py\nrouter = APIRouter(dependencies=[Depends(get_user_by_token)])\n```\n\n```py\napp.include_router(router, dependencies=[Depends(get_user_by_token)])\n```\n\n```py\ndef get_user_by_token(request: Request, token: str = Header()):\n for user in fake_db:\n if user.token == token:\n request.state.user = user\n # ...\n```\n\n```text\ndependencies\n```\n\n```text\nrouter\n```\n\n```text\nrouter\n```\n\n```text\napp\n```\n\n```text\nrequest.state\n```\n\n```text\nState\n```\n\n```text\nrequest.state.user\n```\n\n========================================\n\nComments:\n- Does this answer your question? How to add a custom decorator to a FastAPI route?\n- @WederRibas no because it just does token verification but i need to get the user object in the method\n- TMK, if you want the return value of the dependency, you have to specify it on each individual endpoint method\n- i know i can do that, but how can i get the data that the `get_user_by_token` function returns?\n- @kshnkvn You add it to the function where you need it as well. The result from the dependency will be cached, so it isn't reevaluated. Or you can use `request.state` as Christ has edited to show; but generally I prefer using the dependency in both locations, as it makes it more expressive about which values are available to the controller function.","metadata":{"transformedAt":"2026-08-18T18:32:29.157Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":13,"totalLines":128,"estimatedTokens":797}}704{"id":"stack-73234675","source":"stackoverflow","questionId":73234675,"title":"How to Download a File after POSTing data using FastAPI?","tags":["python","html","file","download","fastapi"],"text":"Title: How to Download a File after POSTing data using FastAPI?\nTags: python, html, file, download, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am creating a web application that receives some text, converts the text into speech, and returns an mp3 file, which is saved to a temporary directory.\n\nI want to be able to download the file from the html page (i.e., the frontend), but I don't know how to do that properly.\n\nI know with Flask you can do this:\n\n```\nfrom app import app\nfrom flask import Flask, send_file, render_template\n \n@app.route('/')\ndef upload_form():\n return render_template('download.html')\n\n@app.route('/download')\ndef download_file():\n path = \"html2pdf.pdf\"\n\n return send_file(path, as_attachment=True)\n\nif __name__ == \"__main__\":\n app.run()\n```\n\nHTML Example:\n\n```\n\nPython Flask File Download Example\n\n### Download a file\n\nDownload\n\n```\n\nSo how do I replicate this with FastAPI?\n\nFastAPI Code:\n\n```\nfrom fastapi import FastAPI, File, Request, Response, UploadFile\nfrom fastapi.middleware.cors import CORSMiddleware\nfrom fastapi.responses import FileResponse, HTMLResponse, StreamingResponse\nfrom fastapi.templating import Jinja2Templates\nfrom gtts import gTTS\n\ntemplates = Jinja2Templates(directory=\"templates\")\n\ndef text_to_speech(language:str, text: str) -> str:\n tts = gTTS(text=text, lang=language, slow=False)\n tts.save(\"./temp/welcome.mp3\")\n #os.system(\"mpg321 /temp/welcome.mp3\")\n return \"Text to speech conversion successful\"\n\n@app.get(\"/\")\ndef home(request: Request):\n return templates.TemplateResponse(\"index.html\", {\"request\": request})\n\n@app.get(\"/text2speech\")\nasync def home(request: Request):\n if request.method == \"POST\":\n form = await request.form()\n if form[\"message\"] and form[\"language\"]:\n language = form[\"language\"]\n text = form[\"message\"]\n translate = text_to_speech(language, text)\n path = './temp/welcome.mp3'\n value = FileResponse(\"./temp/welcome.mp3\", media_type=\"audio/mp3\")\n return value\n # return templates.TemplateResponse(\n # \"index.html\",\n # {\"request\": request, \"message\": text, \"language\": language, \"download\": value},\n # )\n```\n\nSample HTML File:\n\n```\n\nDownload MP3 File\n\n### Download a file\n\nDownload\n\n```\n\n========================================\n\nCode:\n```py\nfrom app import app\nfrom flask import Flask, send_file, render_template\n \n@app.route('/')\ndef upload_form():\n return render_template('download.html')\n\n@app.route('/download')\ndef download_file():\n path = \"html2pdf.pdf\"\n\n return send_file(path, as_attachment=True)\n\nif __name__ == \"__main__\":\n app.run()\n```\n\n```html\n<!doctype html>\n<title>Python Flask File Download Example</title>\n<h2>Download a file</h2>\n<p><a href=\"{{ url_for('.download_file') }}\">Download</a></p>\n```\n\n```py\nfrom fastapi import FastAPI, File, Request, Response, UploadFile\nfrom fastapi.middleware.cors import CORSMiddleware\nfrom fastapi.responses import FileResponse, HTMLResponse, StreamingResponse\nfrom fastapi.templating import Jinja2Templates\nfrom gtts import gTTS\n\ntemplates = Jinja2Templates(directory=\"templates\")\n\n\ndef text_to_speech(language:str, text: str) -> str:\n tts = gTTS(text=text, lang=language, slow=False)\n tts.save(\"./temp/welcome.mp3\")\n #os.system(\"mpg321 /temp/welcome.mp3\")\n return \"Text to speech conversion successful\"\n\n\n@app.get(\"/\")\ndef home(request: Request):\n return templates.TemplateResponse(\"index.html\", {\"request\": request})\n\n@app.get(\"/text2speech\")\nasync def home(request: Request):\n if request.method == \"POST\":\n form = await request.form()\n if form[\"message\"] and form[\"language\"]:\n language = form[\"language\"]\n text = form[\"message\"]\n translate = text_to_speech(language, text)\n path = './temp/welcome.mp3'\n value = FileResponse(\"./temp/welcome.mp3\", media_type=\"audio/mp3\")\n return value\n # return templates.TemplateResponse(\n # \"index.html\",\n # {\"request\": request, \"message\": text, \"language\": language, \"download\": value},\n # )\n```\n\n```html\n<!doctype html>\n<title>Download MP3 File</title>\n<h2>Download a file</h2>\n<p><a href=\"{{ url_for('text2speech') }}\">Download</a></p>\n```\n\n```py\nfrom fastapi import FastAPI, Request, Form\nfrom fastapi.templating import Jinja2Templates\nfrom fastapi.responses import FileResponse\nimport os\n\napp = FastAPI()\ntemplates = Jinja2Templates(directory=\"templates\")\n\n\n@app.get('/')\nasync def main(request: Request):\n return templates.TemplateResponse(\"index.html\", {\"request\": request})\n\n\n@app.post('/text2speech')\ndef convert(request: Request, message: str = Form(...), language: str = Form(...)):\n # do some processing here\n filepath = './temp/welcome.mp3'\n filename = os.path.basename(filepath)\n headers = {'Content-Disposition': f'attachment; filename=\"{filename}\"'}\n return FileResponse(filepath, headers=headers, media_type=\"audio/mp3\")\n```\n\n```py\nfrom fastapi import Response\n\n@app.post('/text2speech')\n ...\n with open(filepath, \"rb\") as f:\n contents = f.read() # file contents could be already fully loaded into RAM\n \n headers = {'Content-Disposition': f'attachment; filename=\"{filename}\"'}\n return Response(contents, headers=headers, media_type='audio/mp3')\n```\n\n```py\nfrom fastapi.responses import StreamingResponse\n\n@app.post('/text2speech')\n ...\n def iterfile():\n with open(filepath, \"rb\") as f:\n yield from f\n\n headers = {'Content-Disposition': f'attachment; filename=\"{filename}\"'}\n return StreamingResponse(iterfile(), headers=headers, media_type=\"audio/mp3\")\n```\n\n```html\n<!DOCTYPE html>\n<html>\n <head>\n <title>Convert Text to Speech</title>\n </head>\n <body>\n <form method=\"post\" action=\"http://127.0.0.1:8000/text2speech\">\n message : <input type=\"text\" name=\"message\" value=\"This is a sample message\"><br>\n language : <input type=\"text\" name=\"language\" value=\"en\"><br>\n <input type=\"submit\" value=\"submit\">\n </form>\n </body>\n</html>\n```\n\n```py\nfrom fastapi import FastAPI, Request, Form\nfrom fastapi.templating import Jinja2Templates\nfrom fastapi.responses import FileResponse\nimport uuid\nimport os\n\napp = FastAPI()\ntemplates = Jinja2Templates(directory=\"templates\")\nfiles = {}\n\n\n@app.get('/')\nasync def main(request: Request):\n return templates.TemplateResponse(\"index.html\", {\"request\": request})\n\n\n@app.get('/download')\ndef download_file(request: Request, fileId: str):\n filepath = files.get(fileId)\n if filepath:\n filename = os.path.basename(filepath)\n headers = {'Content-Disposition': f'attachment; filename=\"{filename}\"'}\n return FileResponse(filepath, headers=headers, media_type='audio/mp3') \n\n\n@app.post('/text2speech')\ndef convert(request: Request, message: str = Form(...), language: str = Form(...)):\n # do some processing here\n filepath = './temp/welcome.mp3'\n file_id = str(uuid.uuid4())\n files[file_id] = filepath\n file_url = f'/download?fileId={file_id}'\n return {\"fileURL\": file_url}\n```\n\n```html\n<!DOCTYPE html>\n<html>\n <head>\n <title>Convert Text to Speech</title>\n </head>\n <body>\n <form method=\"post\" id=\"myForm\">\n message : <input type=\"text\" name=\"message\" value=\"This is a sample message\"><br>\n language : <input type=\"text\" name=\"language\" value=\"en\"><br>\n <input type=\"button\" value=\"Submit\" onclick=\"submitForm()\">\n </form>\n\n <a id=\"downloadLink\" href=\"\"></a>\n\n <script type=\"text/javascript\">\n function submitForm() {\n var formElement = document.getElementById('myForm');\n var data = new FormData(formElement);\n fetch('/text2speech', {\n method: 'POST',\n body: data,\n })\n .then(response => response.json())\n .then(data => {\n document.getElementById(\"downloadLink\").href = data.fileURL;\n document.getElementById(\"downloadLink\").innerHTML = \"Download\";\n })\n .catch(error => {\n console.error(error);\n });\n }\n </script>\n </body>\n</html>\n```\n\n```py\nfrom fastapi import BackgroundTasks\nimport os\n\n@app.post('/text2speech')\ndef convert(request: Request, background_tasks: BackgroundTasks, ...):\n filepath = 'welcome.mp3'\n # ...\n background_tasks.add_task(os.remove, path=filepath)\n return FileResponse(filepath, headers=headers, media_type=\"audio/mp3\")\n```\n\n```py\nfrom fastapi import BackgroundTasks\nimport os\n\nfiles = {}\n\n\ndef remove_file(filepath, fileId):\n os.remove(filepath)\n del files[fileId]\n\n\n@app.get('/download')\ndef download_file(request: Request, fileId: str, background_tasks: BackgroundTasks):\n filepath = files.get(fileId)\n if filepath:\n # ...\n background_tasks.add_task(remove_file, filepath=filepath, fileId=fileId)\n return FileResponse(filepath, headers=headers, media_type='audio/mp3')\n```\n\n```text\nForm\n```\n\n```text\nForm-data\n```\n\n```text\nForm(...)\n```\n\n```text\nawait request.form()\n```\n\n```text\nFileResponse\n```\n\n```text\nheaders\n```\n\n```text\nFileResponse\n```\n\n```text\nContent-Disposition\n```\n\n```text\nattachment\n```\n\n```text\nheaders\n```\n\n```text\ninline\n```\n\n```text\n405 Method Not Allowed\n```\n\n```text\nGET\n```\n\n```text\nPOST\n```\n\n```text\n/text2speech\n```\n\n```text\n/text2speech\n```\n\n```text\nGET\n```\n\n```text\nPOST\n```\n\n```text\n@app.api_route(\"/text2speech\", methods=[\"GET\", \"POST\"])\n```\n\n```text\nrequest.method\n```\n\n```text\nGET\n```\n\n```text\nPOST\n```\n\n```text\n@app.post('/text2speech')\n```\n\n```text\n@app.get('/text2speech')\n```\n\n```text\nrequest.method\n```\n\n```text\nDownload\n```\n\n```text\nstatic\n```\n\n```text\nStaticFiles\n```\n\n```text\nHTTP\n```\n\n```text\nDownload\n```\n\n```text\ndict\n```\n\n```text\n/download\n```\n\n```text\nResponse\n```\n\n```text\nStreamingResponse\n```\n\n```text\nyield from f\n```\n\n```text\nFileResponse\n```\n\n```text\nFileResponse\n```\n\n```text\nStreamingResponse\n```\n\n```text\n<form>\n```\n\n```text\nBackgroundTask\n```\n\n```text\nfile_id\n```\n\n========================================\n\nComments:\n- Have you read anything about Jinja templating? I would start there and see how you can insert a variable somewhere in the template.","metadata":{"transformedAt":"2026-08-18T18:32:29.157Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":53,"totalLines":505,"estimatedTokens":2547}}705{"id":"stack-77404746","source":"stackoverflow","questionId":77404746,"title":"CORS Policy error on second render of React app from FastAPI backend","tags":["python","reactjs","cors","fastapi","fetch-api"],"text":"Title: CORS Policy error on second render of React app from FastAPI backend\nTags: python, reactjs, cors, fastapi, fetch-api\nSource: Stack Overflow\n\nQuestion:\nI am working on a React frontend to chart some data from a fastapi backend. I am using a couple of dropdown components to change the month and year for the requested data. With the initial render the fetch request works fine and returns the data and the charts display. Once I change the dropdowns, I get the following CORS Policy Error in the browser console.\n\nAccess to fetch at 'https://fake-url.com/endpoint/' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.\n\nReact code snippet with the fetch call:\n\n```\nconst [month, setMonth] = useState(1);\n const [year, setYear] = useState('2023');\n const [revenueData, setRevenueData] = useState({});\n\n useEffect(() => {\n const inputs = {\n \"month\": month,\n \"year\": year,\n \"duration\": 1\n }\n\n const myHeaders = new Headers();\n myHeaders.append(\"X-API-KEY\", \"fake-api-key\");\n myHeaders.append(\"Content-Type\", \"application/json\");\n\n const requestOptions = {\n method: 'POST',\n headers: myHeaders,\n body: JSON.stringify(inputs),\n redirect: ''\n };\n\n fetch(\"https://fake-url.com/endpoint/\", requestOptions)\n .then(response => response.json())\n .then(data => {\n setRevenueData((data))\n }).catch(error => {\n console.log('error', error)\n });\n }, [month, year]);\n```\n\nI confirmed that I am using CORSMiddleware in fastapi with the following settings:\n\n```\napp.add_middleware(HTTPSRedirectMiddleware)\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=['*'],\n allow_methods=['*'],\n allow_headers=['*']\n)\n```\n\nI also confirmed that the **backend** is **returning** access-control headers for preflight with an options request in postman as shown:\nhttps://i.sstatic.net/kPJJ2.png\n\n**UPDATE**\n\nThe network panel shows that the second request preflight is successful but ultimately fails in an Internal Server Error. Which lead me to:\n\nCORS and Internal Server Error responses\n\nhttps://i.sstatic.net/svt17.png\n\n========================================\n\nTop Answer:\nYou can resolve this question by the code,\nthe solution is add cors manually in exception_handler.\n\n```\napp = FastAPI()\n\norigins = [\n \"http://localhost\",\n \"http://localhost:8080\",\n # 其他你希望允许的源\n]\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=origins,\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n\n@app.get(\"/\")\nasync def read_root():\n return {\"message\": \"Hello World\"}\n\n@app.get(\"/error\")\nasync def create_error():\n raise ValueError(\"This is a test error\")\n\n@app.exception_handler(Exception)\nasync def exception_handler(request: Request, exception: Union[Exception, RuntimeError]):\n headers = {\n 'Access-Control-Allow-Origin': ', '.join(origins),\n 'Access-Control-Allow-Credentials': 'true',\n 'Access-Control-Allow-Methods': '*',\n 'Access-Control-Allow-Headers': '*',\n }\n if isinstance(exception, EntityException):\n response = JSONResponse(\n jsonable_encoder(\n {\n \"code\": exception.code,\n \"message\": exception.message,\n \"exception\": exception.exception\n }\n ),\n headers=headers\n )\n else:\n response = JSONResponse(\n jsonable_encoder(\n {\n \"exception\": str(exception),\n \"code\": 500,\n }\n ),\n headers=headers\n )\n return response\n\nif __name__ == \"__main__\":\n import uvicorn\n uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n```\n\n========================================\n\nCode:\n```js\nconst [month, setMonth] = useState(1);\n const [year, setYear] = useState('2023');\n const [revenueData, setRevenueData] = useState({});\n\n useEffect(() => {\n const inputs = {\n \"month\": month,\n \"year\": year,\n \"duration\": 1\n }\n\n const myHeaders = new Headers();\n myHeaders.append(\"X-API-KEY\", \"fake-api-key\");\n myHeaders.append(\"Content-Type\", \"application/json\");\n\n const requestOptions = {\n method: 'POST',\n headers: myHeaders,\n body: JSON.stringify(inputs),\n redirect: 'follow'\n };\n\n fetch(\"https://fake-url.com/endpoint/\", requestOptions)\n .then(response => response.json())\n .then(data => {\n setRevenueData((data))\n }).catch(error => {\n console.log('error', error)\n });\n }, [month, year]);\n```\n\n```js\napp.add_middleware(HTTPSRedirectMiddleware)\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=['*'],\n allow_methods=['*'],\n allow_headers=['*']\n)\n```\n\n```text\n4xx\n```\n\n```text\n5xx\n```\n\n```text\n/dashboard_data\n```\n\n```text\n500 Internal Server Error\n```\n\n```text\nAccess-Control-Allow-Headers\n```\n\n```text\nAccess-Control-Allow-Origin\n```\n\n```text\napp = FastAPI()\n\norigins = [\n \"http://localhost\",\n \"http://localhost:8080\",\n # 其他你希望允许的源\n]\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=origins,\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n\n@app.get(\"/\")\nasync def read_root():\n return {\"message\": \"Hello World\"}\n\n@app.get(\"/error\")\nasync def create_error():\n raise ValueError(\"This is a test error\")\n\n@app.exception_handler(Exception)\nasync def exception_handler(request: Request, exception: Union[Exception, RuntimeError]):\n headers = {\n 'Access-Control-Allow-Origin': ', '.join(origins),\n 'Access-Control-Allow-Credentials': 'true',\n 'Access-Control-Allow-Methods': '*',\n 'Access-Control-Allow-Headers': '*',\n }\n if isinstance(exception, EntityException):\n response = JSONResponse(\n jsonable_encoder(\n {\n \"code\": exception.code,\n \"message\": exception.message,\n \"exception\": exception.exception\n }\n ),\n headers=headers\n )\n else:\n response = JSONResponse(\n jsonable_encoder(\n {\n \"exception\": str(exception),\n \"code\": 500,\n }\n ),\n headers=headers\n )\n return response\n\nif __name__ == \"__main__\":\n import uvicorn\n uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n```\n\n```py\nfrom fastapi import FastAPI, Request, status\nfrom fastapi.responses import JSONResponse\nfrom fastapi.encoders import jsonable_encoder\nfrom fastapi.exceptions import RequestValidationError\n\n@app.exception_handler(RequestValidationError)\nasync def validation_exception_handler(request, exc):\n\n headers = {\n 'Access-Control-Allow-Origin' : ', '.join(origins),\n 'Access-Control-Allow-Credentials' : 'true',\n 'Access-Control-Allow-Methods' : '*',\n 'Access-Control-Allow-Headers' : '*',\n }\n\n exc_str = ''\n\n for err in exc._errors:\n exc_str += f\"{err['msg']} for input `{err['input']}` in the field {'->'.join(err['loc'])}. \"\n\n return JSONResponse(\n jsonable_encoder(\n {\n \"status_code\" : 422,\n \"message\" : exc_str,\n \"exception\" : \"HTTP_422_UNPROCESSABLE_ENTITY\"\n }\n ),\n status_code = status.HTTP_422_UNPROCESSABLE_ENTITY,\n headers = headers\n )\n```\n\n========================================\n\nComments:\n- I'm going to assume the headers you are posting are from whatever is serving your web page rather than `https://fake-url.com`. You need to add the headers to the server `https://fake-url.com`. If you do not control or own `https://fake-url.com` you need to convince whoever does to add them. This is the whole purpose of CORS If this is not the case you need to explicitly add that information to your post to avoid confusion and more debugging details as to why your browser isn't respecting the headers it is given.\n- @possum Doing the best I can here. Your assumption is incorrect. Those are the headers **returned** from `https://fake-url.com` from the preflight request. I made a couple of words bold in the sentence prior to emphasize this. I get that CORS headers need to be coming from the backend server. Which is why I looked at my fastapi implementation first. Sorry it is a confusing situation for me. If it wasn't so, I probably would not be asking for help from the community here... can you point me in the direction of how I might troubleshoot further?\n- Use your browser's dev tools *Network* panel to inspect the requests. Compare the one that works with the one that doesn't. How do they differ besides just the request body? Do they have the same request headers? Perhaps the failing request has an error response without CORS headers\n- From where did you import `EntityException`?\n- It's my customized Exception which you can find easily on FastAPI official doc.","metadata":{"transformedAt":"2026-08-18T18:32:29.157Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":10,"totalLines":309,"estimatedTokens":2222}}706{"id":"stack-77086128","source":"stackoverflow","questionId":77086128,"title":"How to pass worker options/parameters in gunicorn","tags":["python","python-asyncio","fastapi","gunicorn","uvicorn"],"text":"Title: How to pass worker options/parameters in gunicorn\nTags: python, python-asyncio, fastapi, gunicorn, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI am running an app which needed `uvicorn`'s asycio loop, by default it uses auto and some time it randomly assign it to `uvloop` whihc breaks the behavior. So I use the following command\n\n```\nuvicorn myapp.server.api:app --loop asyncio --port 7474\n```\n\nThis forces uvicorn to use `asyncio` loop. This works as expected.\n\nNow I am trying to move this changes to `gunicorn` and `uvicorn` as worker, but I am couldn't find a way to pass this `loop` to uvicorn.\n\n```\ngunicorn myapp.server.api:app -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:7474\n```\n\nBut this end up using default value i.e. auto and end up selecting loop type as uvloop. How can I force it to use `asyncio` worker. Help is appreciated.\n\n========================================\n\nCode:\n```text\nuvicorn myapp.server.api:app --loop asyncio --port 7474\n```\n\n```text\ngunicorn myapp.server.api:app -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:7474\n```\n\n```text\nuvicorn\n```\n\n```text\nuvloop\n```\n\n```text\nasyncio\n```\n\n```text\ngunicorn\n```\n\n```text\nuvicorn\n```\n\n```text\nloop\n```\n\n```text\nasyncio\n```\n\n```py\n# myapp/server/custom_worker.py\n\nfrom uvicorn.workers import UvicornWorker\n\nclass CustomUvicornWorker(UvicornWorker):\n CONFIG_KWARGS = {\"loop\": \"asyncio\"}\n```\n\n```text\ngunicorn myapp.server.api:app -k myapp.server.custom_worker.CustomUvicornWorker --bind 0.0.0.0:7474\n```\n\n```text\ngunicorn\n```\n\n```text\nuvicorn\n```\n\n```text\nUvicornWorker\n```\n\n========================================\n\nComments:\n- Thanks, Yeah I figured that out and did the custom class implementation that worked for me. Forgot to update the answer. Thanks again for the answer.","metadata":{"transformedAt":"2026-08-18T18:32:29.157Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":14,"totalLines":89,"estimatedTokens":442}}707{"id":"stack-74463116","source":"stackoverflow","questionId":74463116,"title":"How to create multi-part paths with FastAPI","tags":["python","url","path","fastapi"],"text":"Title: How to create multi-part paths with FastAPI\nTags: python, url, path, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm working on a FastAPI application, and I want to create multi-part paths. What I mean by this is I know how to create a path like this for all the REST methods:\n\n```\n/api/people/{person_id}\n```\n\nbut what's a good way to create this:\n\n```\n/api/people/{person_id}/accounts/{account_id}\n```\n\nI could just keep adding routes in the \"people\" routes module to create the additional accounts paths, but I feel like there should be a separate \"accounts\" routes module that could be included in the \"people\" routes module, and I'm just missing something.\n\nAm I over-thinking this?\n\n========================================\n\nCode:\n```text\n/api/people/{person_id}\n```\n\n```text\n/api/people/{person_id}/accounts/{account_id}\n```\n\n```text\nfrom fastapi import FastAPI, APIRouter\n\napp = FastAPI()\n\npeople_router = APIRouter(prefix='/people')\naccount_router = APIRouter(prefix='/{person_id}/accounts')\n\n\n@people_router.get('/{person_id}')\ndef get_person_id(person_id: int) -> dict[str, int]:\n return {'person_id': person_id}\n\n\n@account_router.get('/{account_id}')\ndef get_account_id(person_id: int, account_id: int) -> dict[str, int]:\n return {'person_id': person_id, 'account_id': account_id}\n\n\npeople_router.include_router(account_router)\napp.include_router(people_router, prefix='/api')\n```\n\n========================================\n\nComments:\n- fastapi.tiangolo.com/tutorial/bigger-applications/… seems to be useful for what you mention\n- Thanks for the reply, but look at that documentation it looks like that creates: /items/{item_id} and /users/{user_id} What I'm looking for is: /first_collection/{first_collection_id}/second_collection/{s‌​econd_collection_id} Thanks though, Doug\n- will this work for you? `router = APIRouter(prefix='/people/{person_id}/accounts')` then you can do `@router.get('/{account_id}')`? your function can then accept both `person_id` and `account_id` as parameters\n- Hmmm, that looks interesting. I hadn't thought about adding a path parameter to the APIRouter prefix parameter. I'll give that a try.\n- That did work; thanks a lot! I'm going to refactor my code to take advantage of this.","metadata":{"transformedAt":"2026-08-18T18:32:29.157Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":3,"totalLines":63,"estimatedTokens":568}}708{"id":"stack-75958222","source":"stackoverflow","questionId":75958222,"title":"Can I return 400 error instead of 422 error","tags":["python","fastapi","pydantic"],"text":"Title: Can I return 400 error instead of 422 error\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI validate data using Pydantic schema in my FastAPI project and if it is not ok it returns 422. Can I change it to 400?\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI, Request, status\nfrom fastapi.exceptions import RequestValidationError\nfrom fastapi.responses import JSONResponse\n\napp = FastAPI()\n\n@app.exception_handler(RequestValidationError)\nasync def validation_exception_handler(request: Request, exc: RequestValidationError):\n return JSONResponse(\n status_code=status.HTTP_400_BAD_REQUEST,\n content={\"detail\": exc.errors()},\n )\n\n# your routes and endpoints here\n```\n\n```text\nexc.errors()\n```\n\n========================================\n\nComments:\n- you saved my day ....","metadata":{"transformedAt":"2026-08-18T18:32:29.157Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":2,"totalLines":35,"estimatedTokens":213}}709{"id":"stack-76446783","source":"stackoverflow","questionId":76446783,"title":"Question about FastAPI's dependency injection and its reusability","tags":["python","dependency-injection","fastapi"],"text":"Title: Question about FastAPI's dependency injection and its reusability\nTags: python, dependency-injection, fastapi\nSource: Stack Overflow\n\nQuestion:\n```\nfrom fastapi import Depends, FastAPI\n\nclass MyDependency:\n def __init__(self):\n # Perform initialization logic here\n pass\n\n def some_method(self):\n # Perform some operation\n pass\n\ndef get_dependency():\n # Create and return an instance of the dependency\n return MyDependency()\n\napp = FastAPI()\n\n@app.get(\"/example\")\ndef example(dependency: MyDependency = Depends(get_dependency)):\n dependency.some_method()\n```\n\nFor the code snippet above, does subsequent visits to /example create a new instance of the MyDependency object each time? If so, how can I avoid that?\n\n========================================\n\nCode:\n```text\nfrom fastapi import Depends, FastAPI\n\nclass MyDependency:\n def __init__(self):\n # Perform initialization logic here\n pass\n\n def some_method(self):\n # Perform some operation\n pass\n\ndef get_dependency():\n # Create and return an instance of the dependency\n return MyDependency()\n\napp = FastAPI()\n\n@app.get(\"/example\")\ndef example(dependency: MyDependency = Depends(get_dependency)):\n dependency.some_method()\n```\n\n```py\nfrom functools import lru_cache\n\n...\n\n@lru_cache\ndef get_dependency():\n # Create and return an instance of the dependency\n return MyDependency()\n```\n\n========================================\n\nComments:\n- Alternatively, one could use a `lifespan` handler to instantiate the object and it between requests\n- Really interesting answer. In the example code you provided, you have not set the value of parameter `maxsize`. Based on the documentation of `lru_cache`, does this mean that the cache can grow indefinitely? Is that a potential problem? I've never dealt with an lru or caching approach so I might be quite off here.\n- @waykiki caching happens based on the input arguments; since there are no arguments, there will only be one entry in the cache. If you try to call the decorated function with an argument, an error will be generated just as `get_dependency` by itself would.","metadata":{"transformedAt":"2026-08-18T18:32:29.157Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":2,"totalLines":73,"estimatedTokens":531}}710{"id":"stack-77008824","source":"stackoverflow","questionId":77008824,"title":"How to set cookies on Jinja2 TemplateResponse in FastAPI?","tags":["python","cookies","jinja2","fastapi","httpresponse"],"text":"Title: How to set cookies on Jinja2 TemplateResponse in FastAPI?\nTags: python, cookies, jinja2, fastapi, httpresponse\nSource: Stack Overflow\n\nQuestion:\nI am using Python FastAPI and Jinja2, all of which I am new to. I am able to set cookies alone or return html templates on their own, but I cannot work out how to do both at once.\n\nSetting cookies only works as expected, but returning a template seems to overwrite that and just returns html with no cookies.\n\n```\n@app.get(\"/oauth/auth\", response_class=HTMLResponse)\nasync def login_page(request: Request, response: Response):\n client_Code_Req_Schema = ClientCodeReqSchema(client_id=request.query_params.get(\"client_id\"), redirect_uri=request.query_params.get(\"redirect_uri\"), response_type=request.query_params.get(\"response_type\"))\n if check_client(client_Code_Req_Schema): \n response.set_cookie(key=\"redirect_uri\", value=\"test\")\n return templates.TemplateResponse(\"authorize.html\", {\"request\": request})\n else:\n raise HTTPException(status_code=400, detail=\"Invalid request\")\n```\n\nMany thanks for any advice. Happy to provide more info if I missed something.\n\n========================================\n\nCode:\n```py\n@app.get(\"/oauth/auth\", response_class=HTMLResponse)\nasync def login_page(request: Request, response: Response):\n client_Code_Req_Schema = ClientCodeReqSchema(client_id=request.query_params.get(\"client_id\"), redirect_uri=request.query_params.get(\"redirect_uri\"), response_type=request.query_params.get(\"response_type\"))\n if check_client(client_Code_Req_Schema): \n response.set_cookie(key=\"redirect_uri\", value=\"test\")\n return templates.TemplateResponse(\"authorize.html\", {\"request\": request})\n else:\n raise HTTPException(status_code=400, detail=\"Invalid request\")\n```\n\n```py\n@app.get(\"/oauth/auth\", response_class=HTMLResponse)\nasync def login_page(request: Request):\n if ... \n response = templates.TemplateResponse(\"authorize.html\", {\"request\": request})\n response.set_cookie(key=\"redirect_uri\", value=\"test\")\n return response\n else:\n raise HTTPException(status_code=400, detail=\"Invalid request\")\n```\n\n```text\nTemplateResponse\n```\n\n```text\nResponse\n```\n\n```text\nreturn {'msg': 'OK'}\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.157Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":58,"estimatedTokens":558}}711{"id":"stack-77049666","source":"stackoverflow","questionId":77049666,"title":"Deploying FastAPI in Azure","tags":["python","azure","azure-web-app-service","fastapi"],"text":"Title: Deploying FastAPI in Azure\nTags: python, azure, azure-web-app-service, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to deploy my application which is built using Python and FastAPI for backend and the HTML for the frontend.\n\nUsing the student login i created an app service and uploaded my code using github.\n\nMy project directory is like\n\n```\nFrontend/\n|- file.html\n|- x.css\nFastAPI/\n|- main.py\n|- other.py\n|- requirements.txt\n```\n\nin my .yml files, I changed the directory of the requirements.txt and package in deploy to ./fastAPI. But the website url shows the following message.\n\nHey, Python developers!\n\nYour app service is up and running. Time to take the next step and\ndeploy your code.\n\nAnd it displays the error message in github workflow\n\nDeployment Failed, Error: Failed to deploy web package to App Service.\nConflict (CODE: 409)\n\nI tried to use startup-command in the yml file to start the FastAPI, it didn't work and gave the following error message\n\nDeployment Failed, Error: startup-command is not a valid input for\nWindows web app or with publish-profile auth scheme.\n\nI changed the configuration on the azure portal to add `WEBSITES_CONTAINER_STARTUP_COMMAND = uvicorn main:app --host 0.0.0.0 --port 80` in the application settings, didn't work.\n\n========================================\n\nCode:\n```text\nFrontend/\n|- file.html\n|- x.css\nFastAPI/\n|- main.py\n|- other.py\n|- requirements.txt\n```\n\n```text\nWEBSITES_CONTAINER_STARTUP_COMMAND = uvicorn main:app --host 0.0.0.0 --port 80\n```\n\n```text\n- FastAPI\n - templates\n - index.html\n -static\n - style.css\n - main.py\n - requirements.txt\n```\n\n```yaml\nname: Build and deploy Python app to Azure Web App - <web_app_Name>\n\non:\n push:\n branches:\n - main\n workflow_dispatch:\n\njobs:\n build:\n runs-on: ubuntu-latest\n\n steps:\n - uses: actions/checkout@v2\n\n - name: Set up Python version\n uses: actions/setup-python@v1\n with:\n python-version: '3.10'\n\n - name: Create and start virtual environment\n run: |\n python -m venv venv\n source venv/bin/activate\n \n - name: Install dependencies\n run: pip install -r requirements.txt\n \n # Optional: Add step to run tests here (PyTest, Django test suites, etc.)\n \n - name: Upload artifact for deployment jobs\n uses: actions/upload-artifact@v2\n with:\n name: python-app\n path: |\n . \n !venv/\n deploy:\n runs-on: ubuntu-latest\n needs: build\n environment:\n name: 'Production'\n url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}\n\n steps:\n - name: Download artifact from build job\n uses: actions/download-artifact@v2\n with:\n name: python-app\n path: .\n \n - name: 'Deploy to Azure Web App'\n uses: azure/webapps-deploy@v2\n id: deploy-to-webapp\n with:\n app-name: '<web_app_Name>'\n slot-name: 'Production'\n publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_XXXXXXXXXXX }}\nAd\n```\n\n```text\nReview+Create\n```\n\n```text\nGitHub repository=>Actions\n```\n\n```text\ngunicorn --bind=0.0.0.0 main:app\n```\n\n```text\nmain\n```\n\n```text\nmain.py\n```\n\n```text\nmain.py\n```\n\n========================================\n\nComments:\n- Please provide your GitHub repository link if you don't have any sensitive information.\n- Hey! There are a few keys which are required for the app to run.\n- Please replace those keys with any random value/variable and provide code link.\n- Hi thanks for the answer, I refered to some documents and followed similar steps to deploy the fastapi app, the problem is that the website is not loading only now :/ Ill try the \"Add new application settings\". Unfortunately I cannot the code with you but I do appreciate you help!\n- gunicorn --bind=0.0.0.0 main:app, if my main.py file is in fastAPI/main.py will this command change? This is the only thing I can think of\n- Try with `gunicorn --bind=0.0.0.0 fastAPI. main:app`","metadata":{"transformedAt":"2026-08-18T18:32:29.158Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":10,"totalLines":162,"estimatedTokens":1013}}712{"id":"stack-71599282","source":"stackoverflow","questionId":71599282,"title":"How to pass **kwargs as params to FastAPI endpoint?","tags":["python","json","fastapi","optional-parameters","keyword-argument"],"text":"Title: How to pass **kwargs as params to FastAPI endpoint?\nTags: python, json, fastapi, optional-parameters, keyword-argument\nSource: Stack Overflow\n\nQuestion:\nI have a function generating a `dict` template. This function consists of several generators and requires one parameter (i.e., `carrier`) and has many optional parameters (keyword arguments - `**kwargs`).\n\n```\ndef main_builder(carrier, **params):\n output = SamplerBuilder(DEFAULT_JSON)\n output.generate_flight(carrier)\n output.generate_airline_info(carrier)\n output.generate_locations()\n output.generate_passengers()\n output.generate_contact_info()\n output.generate_payment_card_info()\n output.configs(**params)\n result = output.input_json\n return result \n\n# example of function call\nexamplex = main_builder(\"3M\", proxy=\"5.39.69.171:8888\", card=Visa, passengers={\"ADT\":2, \"CHD\":1}, bags=2)\n```\n\nI want to deploy this function to FastAPI endpoint. I managed to do it for `carrier` but how can I set `**kwargs` as params to the function?\n\n```\n@app.get(\"/carrier/{carrier_code}\", response_class=PrettyJSONResponse) # params/kwargs??\nasync def get_carrier(carrier_code):\n output_json = main_builder(carrier_code)\n return airline_input_json\n```\n\n========================================\n\nCode:\n```py\ndef main_builder(carrier, **params):\n output = SamplerBuilder(DEFAULT_JSON)\n output.generate_flight(carrier)\n output.generate_airline_info(carrier)\n output.generate_locations()\n output.generate_passengers()\n output.generate_contact_info()\n output.generate_payment_card_info()\n output.configs(**params)\n result = output.input_json\n return result \n\n# example of function call\nexamplex = main_builder(\"3M\", proxy=\"5.39.69.171:8888\", card=Visa, passengers={\"ADT\":2, \"CHD\":1}, bags=2)\n```\n\n```text\n@app.get(\"/carrier/{carrier_code}\", response_class=PrettyJSONResponse) # params/kwargs??\nasync def get_carrier(carrier_code):\n output_json = main_builder(carrier_code)\n return airline_input_json\n```\n\n```text\ndict\n```\n\n```text\ncarrier\n```\n\n```text\n**kwargs\n```\n\n```text\ncarrier\n```\n\n```text\n**kwargs\n```\n\n```py\nfrom pydantic import BaseModel\nfrom typing import Optional\n\nclass MyModel(BaseModel):\n proxy: Optional[str] = None\n card: Optional[str] = None\n passengers: Optional[dict] = None \n bags: Optional[int] = None\n\n@app.post(\"/carrier/{carrier_code}\")\nasync def get_carrier(carrier_code: int, m: MyModel):\n return main_builder(carrier_code, **m.dict()) # In Pydantic V2, use **m.model_dump()\n```\n\n```text\npassengers\n```\n\n```text\nJSON\n```\n\n```text\ndict()\n```\n\n```text\ndict()\n```\n\n```text\nmodel_dump()\n```\n\n========================================\n\nComments:\n- `json` payload preferably but would like to see both solutions\n- Thanks for the comment. When I run the API (`docker-compose up`) it works but when I try to get to `http://0.0.0.0:8080/carrier/3M` (3M is carrier code) without any parameters I get reponse code 422: `422 Unprocessable Entity` and in browser I get an error `{\"detail\":[{\"loc\":[\"body\"],\"msg\":\"field required\",\"type\":\"value_error.missing\"}]}` Am I missing something?\n- @PetrSevcik I think you need to use default values, `carrier_code: int = None` ...worked for me.","metadata":{"transformedAt":"2026-08-18T18:32:29.158Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":13,"totalLines":121,"estimatedTokens":802}}713{"id":"stack-76867554","source":"stackoverflow","questionId":76867554,"title":"FastAPI how to access bearer token","tags":["python","fastapi"],"text":"Title: FastAPI how to access bearer token\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm using FastAPI to create a simple api for automating my emails. I want to protect certain routes and I'm using this class:\n\n```\nimport time\n\nimport jwt\nfrom fastapi import HTTPException, Request\nfrom fastapi.security import HTTPAuthorizationCredentials, HTTPBearer\n\n#if you need to try it out just swap the following\nfrom exchange_api.auth.jwt_handler import JWT_ALGORITHM, JWT_SECRET \n\nclass JWTBearer(HTTPBearer):\n def __init__(self, auto_error: bool = True):\n super(JWTBearer, self).__init__(auto_error=auto_error)\n\n async def __call__(self, request: Request):\n credentials: HTTPAuthorizationCredentials = await super(JWTBearer, self).__call__(request)\n if credentials:\n if not credentials.scheme == \"Bearer\":\n raise HTTPException(status_code=403, detail=\"Invalid authentication scheme.\")\n if not self.verify_jwt(credentials.credentials):\n raise HTTPException(status_code=403, detail=\"Invalid token or expired token.\")\n return credentials.credentials\n else:\n raise HTTPException(status_code=403, detail=\"Invalid authorization code.\")\n\n def verify_jwt(self, jwtoken: str) -> bool:\n isTokenValid: bool = False\n\n try:\n payload = decodeJWT(jwtoken)\n except:\n payload = None\n if payload:\n isTokenValid = True\n return isTokenValid\n\ndef decodeJWT(token: str) -> dict:\n try:\n decoded_token = jwt.decode(token, JWT_SECRET, algorithms=[JWT_ALGORITHM])\n return decoded_token if decoded_token[\"expiration\"] >= time.time() else None\n except:\n return {}\n```\n\nThen I wanted to protect certain routes:\n\n```\nfrom fastapi import APIRouter, Depends, HTTPException, Request, Header\n\nfrom exchange_api.auth.jwt_bearer import JWTBearer\n\n@auth_router.get(\"/protected\", dependencies=[Depends(JWTBearer())], tags=[\"auth test\"])\ndef get_user_data():\n #my issue: I'd like to access the token and its payload\n return {}\n```\n\nI have no issues with my code so far. But I'd like to periodically refresh the token and I need its payload anyway to do things inside my functions. How can I do that? I don't want my users to get kicked out in the middle of their session because their token expired.\n\nIt works fine without depends and using the token as the body of the various routes but I don't think that's the right way to do this. fastapi-jwt-auth is too old and it generates dependencies conflicts with my already installed libraries.\n\nEDIT: What I mean is that I want to access the bearer token that my users submitted to authenticate to do various things and also because I plan to substitute it with a new one every time the users call a protected route but WITHOUT the need to authenticate again.\n\nEDIT: I managed to get the token:\n\n```\n@auth_router.get(\"/protected\", dependencies=[Depends(JWTBearer())], tags=[\"auth test\"])\ndef get_user_data(request: Request):\n token = request.headers[\"authorization\"]\n return {token}\n```\n\n========================================\n\nTop Answer:\nI will show you how I approach JWT tokens in my FastAPI apps. I use library python-jose.\n\nIn my `auth.py` file I have the following code:\n\n```\nfrom datetime import datetime, timedelta\nfrom typing import Literal\n\nfrom fastapi import Depends, HTTPException, status\nfrom fastapi.security import OAuth2PasswordBearer\nfrom jose import JWTError, jwt\n\nfrom app.models import User\nfrom app.settings import access_token_jwk, refresh_token_jwk\n\noauth2_scheme = OAuth2PasswordBearer(tokenUrl=\"auth/token\")\n\ndef authenticate_user(email: str, password: str) -> User:\n # Here you would verify password against hash from database\n # or authenticate any other way you want. This function\n # will be used in endpoint /token.\n ...\n\ndef create_token(\n user: User,\n token_type: Literal[\"refresh\", \"access\"],\n ttl: int\n) -> str:\n # This function generates token with any claims you want\n\n payload = {\n \"sub\": user.email,\n \"iat\": datetime.utcnow(),\n \"exp\": datetime.utcnow() + timedelta(minutes=ttl),\n \"user_role\": user.role,\n }\n\n if token_type == \"access\":\n key = access_token_jwk\n elif token_type == \"refresh\":\n key = refresh_token_jwk\n\n encoded_jwt = jwt.encode(\n payload,\n key,\n \"HS256\"\n )\n\n return encoded_jwt\n\nasync def decode_access_token(token: str = Depends(oauth2_scheme) -> dict:\n # This function will be used as dependency in endpoints\n # we want secured. Basically it verifies the JWT and\n # returns its contents as dictionary.\n\n try:\n payload = jwt.decode(\n token,\n access_token_jwk,\n algorithms=\"HS256\",\n )\n except JWTError as e:\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED, detail=f\"Invalid token: {e}\"\n )\n\n return payload\n\nasync def decode_refresh_token(token: str = Depends(oauth2_scheme) -> dict:\n # This function will be used as dependency only\n # when you want to refresh your access token.\n # Since access and refresh tokens have different signing keys,\n # user won't be able to use refresh token to access endpoints\n # protected by access token.\n\n try:\n payload = jwt.decode(\n token,\n refresh_token_jwk,\n algorithms=\"HS256\",\n )\n except JWTError as e:\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED, detail=f\"Invalid token: {e}\"\n )\n\n return payload\n```\n\nThen my endpoint for getting token looks like this:\n\n```\nfrom fastapi import APIRouter, Depends\nfrom fastapi.security import OAuth2PasswordRequestForm\n\nfrom app.auth import authenticate_user, create_token, decode_refresh_token\nfrom app.users import get_user\n\nrouter = APIRouter()\n\n@router.post(\"/token\")\nasync def login_for_access_token(\n form_data: OAuth2PasswordRequestForm = Depends()\n):\n # If authenticate_user() fails, exception from within the function\n # will be raised.\n user = authenticate_user(form_data.username, form_data.password)\n\n access_token = create_token(user, \"access\", 60)\n refresh_token = create_token(user, \"refresh\", 60*24*3)\n return {\n \"access_token\": access_token,\n \"refresh_token\": refresh_token,\n \"token_type\": \"bearer\"\n }\n\n@router.post(\"/token/refresh\")\nasync def refresh_access_token(\n token: dict = Depends(decode_refresh_token)\n):\n user = get_user(token.get[\"sub\"]) # arbitrary function to get user by email\n access_token = create_token(user, \"access\", 60)\n refresh_token = create_token(user, \"refresh\", 60*24*3)\n return {\n \"access_token\": access_token,\n \"refresh_token\": refresh_token,\n \"token_type\": \"bearer\"\n }\n```\n\nThat's it, use `decode_access_token()` as dependency in any endpoint you want to secure and it will automatically read token from header and verify it:\n\n```\nfrom fastapi import APIRouter, Depends\nfrom app.auth import decode_access_token\n\nrouter = APIRouter()\n\n@router.get(\"/secure/route\")\ndef get_secured_data(token: dict = Depends(decode_access_token)):\n # under token variable you can access token data and claims\n ...\n```\n\n========================================\n\nCode:\n```text\nimport time\n\nimport jwt\nfrom fastapi import HTTPException, Request\nfrom fastapi.security import HTTPAuthorizationCredentials, HTTPBearer\n\n#if you need to try it out just swap the following\nfrom exchange_api.auth.jwt_handler import JWT_ALGORITHM, JWT_SECRET \n\nclass JWTBearer(HTTPBearer):\n def __init__(self, auto_error: bool = True):\n super(JWTBearer, self).__init__(auto_error=auto_error)\n\n async def __call__(self, request: Request):\n credentials: HTTPAuthorizationCredentials = await super(JWTBearer, self).__call__(request)\n if credentials:\n if not credentials.scheme == \"Bearer\":\n raise HTTPException(status_code=403, detail=\"Invalid authentication scheme.\")\n if not self.verify_jwt(credentials.credentials):\n raise HTTPException(status_code=403, detail=\"Invalid token or expired token.\")\n return credentials.credentials\n else:\n raise HTTPException(status_code=403, detail=\"Invalid authorization code.\")\n\n\n def verify_jwt(self, jwtoken: str) -> bool:\n isTokenValid: bool = False\n\n try:\n payload = decodeJWT(jwtoken)\n except:\n payload = None\n if payload:\n isTokenValid = True\n return isTokenValid\n\ndef decodeJWT(token: str) -> dict:\n try:\n decoded_token = jwt.decode(token, JWT_SECRET, algorithms=[JWT_ALGORITHM])\n return decoded_token if decoded_token[\"expiration\"] >= time.time() else None\n except:\n return {}\n```\n\n```text\nfrom fastapi import APIRouter, Depends, HTTPException, Request, Header\n\nfrom exchange_api.auth.jwt_bearer import JWTBearer\n\n@auth_router.get(\"/protected\", dependencies=[Depends(JWTBearer())], tags=[\"auth test\"])\ndef get_user_data():\n #my issue: I'd like to access the token and its payload\n return {}\n```\n\n```text\n@auth_router.get(\"/protected\", dependencies=[Depends(JWTBearer())], tags=[\"auth test\"])\ndef get_user_data(request: Request):\n token = request.headers[\"authorization\"]\n return {token}\n```\n\n```text\nasync def some_function(auth: AuthJWT = Depends()):\n auth.access_token_required()\n```\n\n```text\nuser_id = auth.get_jwt_subject()\n```\n\n```text\nnew_access_token = auth.create_access_token()\nauth.set_access_token(new_access_token)\n```\n\n```py\nfrom datetime import datetime, timedelta\nfrom typing import Literal\n\nfrom fastapi import Depends, HTTPException, status\nfrom fastapi.security import OAuth2PasswordBearer\nfrom jose import JWTError, jwt\n\nfrom app.models import User\nfrom app.settings import access_token_jwk, refresh_token_jwk\n\noauth2_scheme = OAuth2PasswordBearer(tokenUrl=\"auth/token\")\n\n\ndef authenticate_user(email: str, password: str) -> User:\n # Here you would verify password against hash from database\n # or authenticate any other way you want. This function\n # will be used in endpoint /token.\n ...\n\ndef create_token(\n user: User,\n token_type: Literal[\"refresh\", \"access\"],\n ttl: int\n) -> str:\n # This function generates token with any claims you want\n\n payload = {\n \"sub\": user.email,\n \"iat\": datetime.utcnow(),\n \"exp\": datetime.utcnow() + timedelta(minutes=ttl),\n \"user_role\": user.role,\n }\n\n if token_type == \"access\":\n key = access_token_jwk\n elif token_type == \"refresh\":\n key = refresh_token_jwk\n\n encoded_jwt = jwt.encode(\n payload,\n key,\n \"HS256\"\n )\n\n return encoded_jwt\n\nasync def decode_access_token(token: str = Depends(oauth2_scheme) -> dict:\n # This function will be used as dependency in endpoints\n # we want secured. Basically it verifies the JWT and\n # returns its contents as dictionary.\n\n try:\n payload = jwt.decode(\n token,\n access_token_jwk,\n algorithms=\"HS256\",\n )\n except JWTError as e:\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED, detail=f\"Invalid token: {e}\"\n )\n\n return payload\n\nasync def decode_refresh_token(token: str = Depends(oauth2_scheme) -> dict:\n # This function will be used as dependency only\n # when you want to refresh your access token.\n # Since access and refresh tokens have different signing keys,\n # user won't be able to use refresh token to access endpoints\n # protected by access token.\n\n try:\n payload = jwt.decode(\n token,\n refresh_token_jwk,\n algorithms=\"HS256\",\n )\n except JWTError as e:\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED, detail=f\"Invalid token: {e}\"\n )\n\n return payload\n```\n\n```py\nfrom fastapi import APIRouter, Depends\nfrom fastapi.security import OAuth2PasswordRequestForm\n\nfrom app.auth import authenticate_user, create_token, decode_refresh_token\nfrom app.users import get_user\n\nrouter = APIRouter()\n\n\n@router.post(\"/token\")\nasync def login_for_access_token(\n form_data: OAuth2PasswordRequestForm = Depends()\n):\n # If authenticate_user() fails, exception from within the function\n # will be raised.\n user = authenticate_user(form_data.username, form_data.password)\n\n access_token = create_token(user, \"access\", 60)\n refresh_token = create_token(user, \"refresh\", 60*24*3)\n return {\n \"access_token\": access_token,\n \"refresh_token\": refresh_token,\n \"token_type\": \"bearer\"\n }\n\n@router.post(\"/token/refresh\")\nasync def refresh_access_token(\n token: dict = Depends(decode_refresh_token)\n):\n user = get_user(token.get[\"sub\"]) # arbitrary function to get user by email\n access_token = create_token(user, \"access\", 60)\n refresh_token = create_token(user, \"refresh\", 60*24*3)\n return {\n \"access_token\": access_token,\n \"refresh_token\": refresh_token,\n \"token_type\": \"bearer\"\n }\n```\n\n```py\nfrom fastapi import APIRouter, Depends\nfrom app.auth import decode_access_token\n\nrouter = APIRouter()\n\n@router.get(\"/secure/route\")\ndef get_secured_data(token: dict = Depends(decode_access_token)):\n # under token variable you can access token data and claims\n ...\n```\n\n```text\nauth.py\n```\n\n```text\ndecode_access_token()\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.158Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":11,"totalLines":451,"estimatedTokens":3241}}714{"id":"stack-73322634","source":"stackoverflow","questionId":73322634,"title":"How to call an API endpoint from a different API endpoint in the same FastAPI application?","tags":["python","request","fastapi"],"text":"Title: How to call an API endpoint from a different API endpoint in the same FastAPI application?\nTags: python, request, fastapi\nSource: Stack Overflow\n\nQuestion:\n(I did find the following question on SO, but it didn't help me: Is it possible to have an api call another api, having them both in same application?)\n\nI am making an app using Fastapi with the following folder structure\n\nhttps://i.sstatic.net/YPor6.png\n\n`main.py` is the entry point to the app\n\n```\nfrom fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware\n\nfrom app.api.v1 import lines, upload\nfrom app.core.config import settings\n\napp = FastAPI(\n title=settings.PROJECT_NAME,\n version=0.1,\n openapi_url=f'{settings.API_V1_STR}/openapi.json',\n root_path=settings.ROOT_PATH\n)\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=settings.BACKEND_CORS_ORIGINS,\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n\napp.include_router(upload.router, prefix=settings.API_V1_STR)\napp.include_router(lines.router, prefix=settings.API_V1_STR)\n```\n\nIn the `lines.py`, I have 2 GET endpoints:\n\n- `/one-random-line` --> returns a random line from a `.txt` file\n\n- `/one-random-line-backwards` --> should return the output of the `/one-random-line`\n\nSince the output of the second GET endpoint should be the reversed string of the output of the first GET endpoint, I tried doing the following steps mentioned here\n\nThe codes:\n\n```\nimport random\n\nfrom fastapi import APIRouter, Request\nfrom starlette.responses import RedirectResponse\n\nrouter = APIRouter(\n prefix=\"/get-info\",\n tags=[\"Get Information\"],\n responses={\n 200: {'description': 'Success'},\n 400: {'description': 'Bad Request'},\n 403: {'description': 'Forbidden'},\n 500: {'description': 'Internal Server Error'}\n }\n)\n\n@router.get('/one-random-line')\ndef get_one_random_line(request: Request):\n lines = open('netflix_list.txt').read().splitlines()\n if request.headers.get('accept') in ['application/json', 'application/xml']:\n random_line = random.choice(lines)\n else:\n random_line = 'This is an example'\n return {'line': random_line}\n\n@router.get('/one-random-line-backwards')\ndef get_one_random_line_backwards():\n url = router.url_path_for('get_one_random_line')\n response = RedirectResponse(url=url)\n return {'message': response[::-1]}\n```\n\nWhen I do this, I get the following error:\n\n```\nTypeError: 'RedirectResponse' object is not subscriptable\n```\n\nWhen I change the `return` of the second GET endpoint to `return {'message': response}`, I get the following output\n\nhttps://i.sstatic.net/AYVPc.png\n\nWhat is the mistake I am doing?\n\n**Example:**\n\nIf the output of `/one-random-line` endpoint is 'Maverick', then the output of `/one-random-line-backwards` should be 'kcirevam'\n\n========================================\n\nTop Answer:\nYou can just call any endpoint from your code directly as a function call, you don't have to deal with `RedirectResponse()` or anything. Below is an example of how this would look like and will run as is:\n\n```\nfrom fastapi import FastAPI, Request\n\napp = FastAPI()\n\n@app.get(\"/one-random-line\")\nasync def get_one_random_line(request: Request):\n # implement your own logic here, this will only return a static line\n return {\"line\": \"This is an example\"}\n\n@app.get(\"/one-random-line-backwards\")\nasync def get_one_random_line_backwards(request: Request):\n # You don't have to do fancy http stuff, just call your endpoint:\n one_line = await get_one_random_line(request)\n return {\"line\": one_line[\"line\"][::-1]}\n\nif __name__ == \"__main__\":\n import uvicorn\n uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n```\n\nUsing `curl` we get the following result:\n\n```\n% curl localhost:8000/one-random-line \n{\"line\":\"This is an example\"}% \n% curl localhost:8000/one-random-line-backwards\n{\"line\":\"elpmaxe na si sihT\"}%\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware\n\nfrom app.api.v1 import lines, upload\nfrom app.core.config import settings\n\napp = FastAPI(\n title=settings.PROJECT_NAME,\n version=0.1,\n openapi_url=f'{settings.API_V1_STR}/openapi.json',\n root_path=settings.ROOT_PATH\n)\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=settings.BACKEND_CORS_ORIGINS,\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\n\napp.include_router(upload.router, prefix=settings.API_V1_STR)\napp.include_router(lines.router, prefix=settings.API_V1_STR)\n```\n\n```text\nimport random\n\nfrom fastapi import APIRouter, Request\nfrom starlette.responses import RedirectResponse\n\nrouter = APIRouter(\n prefix=\"/get-info\",\n tags=[\"Get Information\"],\n responses={\n 200: {'description': 'Success'},\n 400: {'description': 'Bad Request'},\n 403: {'description': 'Forbidden'},\n 500: {'description': 'Internal Server Error'}\n }\n)\n\n\n@router.get('/one-random-line')\ndef get_one_random_line(request: Request):\n lines = open('netflix_list.txt').read().splitlines()\n if request.headers.get('accept') in ['application/json', 'application/xml']:\n random_line = random.choice(lines)\n else:\n random_line = 'This is an example'\n return {'line': random_line}\n\n\n@router.get('/one-random-line-backwards')\ndef get_one_random_line_backwards():\n url = router.url_path_for('get_one_random_line')\n response = RedirectResponse(url=url)\n return {'message': response[::-1]}\n```\n\n```text\nTypeError: 'RedirectResponse' object is not subscriptable\n```\n\n```text\nmain.py\n```\n\n```text\nlines.py\n```\n\n```text\n/one-random-line\n```\n\n```text\n.txt\n```\n\n```text\n/one-random-line-backwards\n```\n\n```text\n/one-random-line\n```\n\n```text\nreturn\n```\n\n```text\nreturn {'message': response}\n```\n\n```text\n/one-random-line\n```\n\n```text\n/one-random-line-backwards\n```\n\n```py\n# this function could live as LineService.get_random_line for example\n# its responsibility is to fetch a random line from a file\ndef get_random_line(path=\"netflix_list.txt\"):\n lines = open(path).read().splitlines()\n return random.choice(lines)\n\n\n# this function encodes the rule that \"if the accepted response is json or xml\n# we do the random value, otherwise we return a default value\"\ndef get_random_or_default_line_for_accept_value(accept, path=\"netflix_list.txt\", default_value=\"This is an example\"):\n if accept not in (\"application/json\", \"application/xml\"):\n return default_value\n\n return get_random_line(path=path)\n\n\n@router.get('/one-random-line')\ndef get_one_random_line(request: Request):\n return {\n \"line\": get_random_or_default_line_for_accept_value(\n accept=request.headers.get('accept'),\n ),\n }\n\n\n@router.get('/one-random-line-backwards')\ndef get_one_random_line_backwards(request: Request):\n return {\n \"line\": get_random_or_default_line_for_accept_value(\n accept=request.headers.get('accept'),\n )[::-1],\n }\n```\n\n```py\nfrom fastapi import FastAPI, Request\n\napp = FastAPI()\n\n\n@app.get(\"/one-random-line\")\nasync def get_one_random_line(request: Request):\n # implement your own logic here, this will only return a static line\n return {\"line\": \"This is an example\"}\n\n\n@app.get(\"/one-random-line-backwards\")\nasync def get_one_random_line_backwards(request: Request):\n # You don't have to do fancy http stuff, just call your endpoint:\n one_line = await get_one_random_line(request)\n return {\"line\": one_line[\"line\"][::-1]}\n\n\nif __name__ == \"__main__\":\n import uvicorn\n uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n```\n\n```bash\n% curl localhost:8000/one-random-line \n{\"line\":\"This is an example\"}% \n% curl localhost:8000/one-random-line-backwards\n{\"line\":\"elpmaxe na si sihT\"}%\n```\n\n```text\nRedirectResponse()\n```\n\n```text\ncurl\n```\n\n```text\nthread = threading.Thread(target=request_foo, args=(arg1, arg2))\nthread.start()\n```\n\n========================================\n\nComments:\n- Refactor your code to move the common part out to a separate function, then call that function in both endpoints - it'll provide proper separation of concerns (the controller methods will be just controller methods handling the request, fetching the relevant data and returning it, while the function does the actual work). Don't think about it as calling another API, just refactor the common code into a function that can be used from both controller endpoints.\n- And a `RedirectResponse` is to tell an HTTP client that what they're looking for is somewhere else, not that you want to return the result from another endpoint - and you can't subscript a response, since it's not a list (or iterable).\n- Future readers looking for how to return a `RedirectResponse` instead, please see this answer and this answer. Also, if interested in making **external** API calls instead, please have a look at this answer.\n- Sorry, I see we both answered roughly at the same time. If you want, I will delete my answer (it is already available to OP through Github, where he asked the same question in the FastAPI issues).\n- More documentation is better; they both solve the same issue in different ways. I prefer to move the common functionality out to a separate function instead of using a controller endpoint as the source of truth, since that could have non-obvious consequences if you think you're just changing that single endpoint. However, in some cases it might be what you want. In this case the reverse endpoint will break if you change the key from `line` for example.\n- @MatsLindh Thanks for the answer. But in this case, the output of both the endpoints is different. Is it possible that the output of the `one-random-line` is passed on to `one-random-line-backwards` endpoint and is reversed? The line should be the same, but just reversed in the second endpoint.\n- Sorry, but I don't understand what the issue is. There is no state kept between requests in either case, so if you make a new request that retrieves a random line, it'll be selected at random in any case. If you don't match the supported content-types in Accept, a static text will be returned (and this will be reversed properly). If you want to first retrieve a string, then retrieve *that same string* returned, you need to either have some state for what string was returned last (and how you'd handle multiple clients), or you'll have to include the string to be reversed in your second request.","metadata":{"transformedAt":"2026-08-18T18:32:29.158Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":19,"totalLines":330,"estimatedTokens":2589}}715{"id":"stack-75466872","source":"stackoverflow","questionId":75466872,"title":"Integration testing FastAPI with user authentication","tags":["python","testing","integration-testing","fastapi"],"text":"Title: Integration testing FastAPI with user authentication\nTags: python, testing, integration-testing, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to write some integration tests for my FastAPI endpoints and am not sure what the best solution is to testing the endpoints that require a user to be logged in.\n\nI am following the FastAPI authentication documentation for my auth flow which is just username password and then receiving a token.\n\nHow can I test endpoints using a logged in user?\n\nExample endpoint to test:\n\n```\n@app.get(\"/lists/{id}\", response_model=ListDto)\nasync def get_list(\n id: int,\n current_user: User = Depends(get_current_active_user),\n):\n usecase = GetList(list_id=id, current_user=current_user)\n list = usecase()\n if not llist:\n raise HTTPException(status_code=404, detail=f\"List with id:{id} not found\")\n return list\n```\n\n========================================\n\nCode:\n```text\n@app.get(\"/lists/{id}\", response_model=ListDto)\nasync def get_list(\n id: int,\n current_user: User = Depends(get_current_active_user),\n):\n usecase = GetList(list_id=id, current_user=current_user)\n list = usecase()\n if not llist:\n raise HTTPException(status_code=404, detail=f\"List with id:{id} not found\")\n return list\n```\n\n```text\nfrom fastapi.testclient import TestClient\nfrom app.main import app\n\n@pytest.fixture(scope=\"module\")\ndef client():\n with TestClient(app) as c:\n yield c\n\n@pytest.fixture(scope=\"module\")\ndef test_user():\n return {\"username\": \"testuser\", \"password\": \"testpass\"}\n```\n\n```text\ndef test_login(client, test_user):\n response = client.post(\"/login\", data=test_user)\n assert response.status_code == 200\n token = response.json()[\"access_token\"]\n assert token is not None\n return token\n```\n\n```text\ndef test_get_list(client, test_user):\n token = test_login(client, test_user)\n response = client.get(\"/lists/1\", headers={\"Authorization\": f\"Bearer {token}\"})\n assert response.status_code == 200\n assert response.json()[\"id\"] == 1\n```\n\n========================================\n\nComments:\n- Thanks so much! This was just the clarification I needed.","metadata":{"transformedAt":"2026-08-18T18:32:29.158Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":77,"estimatedTokens":531}}716{"id":"stack-76070545","source":"stackoverflow","questionId":76070545,"title":"FastAPI difference between `json.dumps()` and `JSONResponse()`","tags":["python","json","rest","fastapi","jsonresponse"],"text":"Title: FastAPI difference between `json.dumps()` and `JSONResponse()`\nTags: python, json, rest, fastapi, jsonresponse\nSource: Stack Overflow\n\nQuestion:\nI am exploring FastAPI, and got it working on my Docker Desktop on Windows. Here's my `main.py` which is deployed successfully in Docker:\n\n```\n#main.py\nimport fastapi\nimport json\nfrom fastapi.responses import JSONResponse\n\napp = fastapi.FastAPI()\n\n@app.get('/api/get_weights1')\nasync def get_weights1():\n weights = {'aa': 10, 'bb': 20}\n return json.dumps(weights)\n\n@app.get('/api/get_weights2')\nasync def get_weights2():\n weights = {'aa': 10, 'bb': 20}\n return JSONResponse(content=weights, status_code=200)\n```\n\nAnd I have a simple python file `get_weights.py` to make requests to those 2 APIs:\n\n```\n#get_weights.py\nimport requests\nimport json\n\nresp = requests.get('http://127.0.0.1:8000/api/get_weights1')\nprint('ok', resp.status_code)\nif resp.status_code == 200:\n print(resp.json())\n\nresp = requests.get('http://127.0.0.1:8000/api/get_weights2')\nprint('ok', resp.status_code)\nif resp.status_code == 200:\n print(resp.json())\n```\n\nI get the same responses from the 2 APIs, output:\n\n```\nok 200\n{\"aa\": 10, \"bb\": 20}\nok 200\n{'aa': 10, 'bb': 20}\n```\n\nThe response seems the same whether I use `json.dumps()` or `JSONResponse()`. I've read the FastAPI documentation on JSONResponse, but I still have below questions:\n\nMay I know if there is any difference between the 2 methods?\n\nIf there is a difference, which method is recommended (and why?)?\n\n========================================\n\nTop Answer:\nI've experimented a few variations and found the following...\n\n(1) Both methods are not able to serialize a datetime object. For example if the weights are:\n\n```\nweights = {'aa': 10, 'bb': 20, 'date': datetime.date.today()}\n```\n\nthen both methods will have the same returned status and error:\n\n500 Internal Server Error\n\nTypeError: Object of type date is not JSON serializable\n\nTo overcome this use\n\n```\nreturn json.dumps(weights, default=str)\n```\n\nand\n\n```\nfrom fastapi.encoders import jsonable_encoder\n#blah\nreturn JSONResponse(content=jsonable_encoder(weights), status_code=200)\n```\n\n(2) I've also experimented returning the plain `dict` as it is, especially if there is a datetime object in it. As @Matija has mentioned, FastAPI will automatically stringify this `dict` and wrap it in the response. For example:\n\n```\n@app.get('/api/get_weights1')\nasync def get_weights1():\n weights = {'aa': 10, 'bb': 20, 'date': datetime.date.today()}\n return weights #Output:\n\n```\nok 200\n{\"aa\": 10, \"bb\": 20, \"date\": \"2023-04-21\"}\n```\n\n(3) As @Matija has mentioned, `JSONResponse()` method allows customization of the returned response. For example, the response status could be customized as 201 (instead of 200). And also different types of objects to be returned. This is probably the advantage of using this method over `json.dumps()` method. For example:\n\n```\n#main.py\n@app.get('/api/get_weights2')\nasync def get_weights2():\n weights = {'aa': 10, 'bb': 20}\n return JSONResponse(content=weights, status_code=201) #Same output as before:\n\n```\nok 200\n{'aa': 10, 'bb': 20}\n```\n\n========================================\n\nCode:\n```text\n#main.py\nimport fastapi\nimport json\nfrom fastapi.responses import JSONResponse\n\napp = fastapi.FastAPI()\n\n@app.get('/api/get_weights1')\nasync def get_weights1():\n weights = {'aa': 10, 'bb': 20}\n return json.dumps(weights)\n\n@app.get('/api/get_weights2')\nasync def get_weights2():\n weights = {'aa': 10, 'bb': 20}\n return JSONResponse(content=weights, status_code=200)\n```\n\n```text\n#get_weights.py\nimport requests\nimport json\n\nresp = requests.get('http://127.0.0.1:8000/api/get_weights1')\nprint('ok', resp.status_code)\nif resp.status_code == 200:\n print(resp.json())\n\nresp = requests.get('http://127.0.0.1:8000/api/get_weights2')\nprint('ok', resp.status_code)\nif resp.status_code == 200:\n print(resp.json())\n```\n\n```text\nok 200\n{\"aa\": 10, \"bb\": 20}\nok 200\n{'aa': 10, 'bb': 20}\n```\n\n```text\nmain.py\n```\n\n```text\nget_weights.py\n```\n\n```text\njson.dumps()\n```\n\n```text\nJSONResponse()\n```\n\n```py\nreturn dict # Or model or ...\n```\n\n```text\nreturn JSONResponse(content=dict) # Here we need to have dict.\n```\n\n```py\nreturn JSONResponse(content=jsonable_encoder(some_model), status_code=201, headers={\"REMOTE-USER\": username})\n```\n\n```py\nreturn Response('Hello, world!', media_type='text/plain')\n```\n\n```text\ndict\n```\n\n```text\nJSONResponse\n```\n\n```text\nREMOTE-USER=username\n```\n\n```text\nJSONResponse\n```\n\n```text\njsonable_encoder(some_model) # -> dict\n```\n\n```text\nResponse\n```\n\n```text\nmedia_type\n```\n\n```text\nweights = {'aa': 10, 'bb': 20, 'date': datetime.date.today()}\n```\n\n```text\nreturn json.dumps(weights, default=str)\n```\n\n```text\nfrom fastapi.encoders import jsonable_encoder\n#blah\nreturn JSONResponse(content=jsonable_encoder(weights), status_code=200)\n```\n\n```text\n@app.get('/api/get_weights1')\nasync def get_weights1():\n weights = {'aa': 10, 'bb': 20, 'date': datetime.date.today()}\n return weights #<--- this is dict\n```\n\n```text\nok 200\n{\"aa\": 10, \"bb\": 20, \"date\": \"2023-04-21\"}\n```\n\n```text\n#main.py\n@app.get('/api/get_weights2')\nasync def get_weights2():\n weights = {'aa': 10, 'bb': 20}\n return JSONResponse(content=weights, status_code=201) #<--201\n\n#get_weights.py\nresp = requests.get('http://127.0.0.1:8000/api/get_weights2')\nprint('ok', resp.status_code)\nif resp.status_code == 201: #<---201\n print(resp.json())\n```\n\n```text\nok 200\n{'aa': 10, 'bb': 20}\n```\n\n```text\ndict\n```\n\n```text\ndict\n```\n\n```text\nJSONResponse()\n```\n\n```text\njson.dumps()\n```\n\n========================================\n\nComments:\n- To sum it up: don't use either, just return a dict-like object, or with `orm_mode=True` on your response model, an object that supports attribute lookup (an SQLAlchemy row, for example). Use `response_model` on the route decorator or give a return type for the function that defines how you want the response to be serialized.\n- Thanks, the answer from @Matija is clear!\n- I'm afraid you’re mistaken about `JSONResponse` and `json.dumps()`, as well as the assumption of how FastAPI/Starlette works under the hood. If you took the time to have a look at the link provided in the comments section above, your questions would be answered (as your question is essentially a duplicate one). @Matija's answer is also not very accurate, as there are more than three ways to return a `Response` (e.g., `StreamingResponse`, `HTMLResponse`, etc.), as well as one could also use other (faster) JSON encoders than the standard `json` lib. All is described in the linked answer above\n- thanks Chris, I'd have a closer read about how FastAPI/Starlette works!\n- Please have a look at the link provided above. You might find this answer (see Option 1) helpful as well.\n- the new link (Option 1) is clearer, I get the picture, thanks!","metadata":{"transformedAt":"2026-08-18T18:32:29.158Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":29,"totalLines":292,"estimatedTokens":1711}}717{"id":"stack-76122326","source":"stackoverflow","questionId":76122326,"title":"How to return separate JSON responses using FastAPI?","tags":["python","fastapi","jsonresponse"],"text":"Title: How to return separate JSON responses using FastAPI?\nTags: python, fastapi, jsonresponse\nSource: Stack Overflow\n\nQuestion:\nI am not sure if this is part of OpenAPI standard. I am trying to develop an API server to replace an existing one, which is not open source and vendor is gone. One particular challenge I am facing is it returns multiple JSON objects **without enclosing them** either in a `list` or `array`.\nFor example, it returns the following 3 JSON objects as they are, in separate lines:\n\n```\n{\"items\": 10}\n{\"order\": \"shelf\", \"amount\": 100}\n{\"id\": 100, \"date\": \"2022-01-01\", \"status\": \"X\"}\n```\n\n**Not** in a `list` format `()` or in array `[]`.\n\nFor example, the code below returns all 3 objects in an array:\n\n```\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/\")\ndef read_root():\n data_1 = {\"items\": 10}\n data_2 = {\"order\": \"shelf\", \"amount\": 100}\n data_3 = {\"id\": 100, \"date\": \"2022-01-01\", \"status\": \"X\"}\n return data_1, data_2, data_3\n```\n\nCan anyone help me to get this done with FastAPI?\n\n========================================\n\nCode:\n```text\n{\"items\": 10}\n{\"order\": \"shelf\", \"amount\": 100}\n{\"id\": 100, \"date\": \"2022-01-01\", \"status\": \"X\"}\n```\n\n```text\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/\")\ndef read_root():\n data_1 = {\"items\": 10}\n data_2 = {\"order\": \"shelf\", \"amount\": 100}\n data_3 = {\"id\": 100, \"date\": \"2022-01-01\", \"status\": \"X\"}\n return data_1, data_2, data_3\n```\n\n```text\nlist\n```\n\n```text\narray\n```\n\n```text\nlist\n```\n\n```text\n()\n```\n\n```text\n[]\n```\n\n```py\nfrom fastapi import FastAPI, Response\nimport json\n\napp = FastAPI()\n\n\ndef to_json(d):\n return json.dumps(d, default=str)\n \n \n@app.get('/')\nasync def main():\n data_1 = {'items': 10}\n data_2 = {'order': 'shelf', 'amount': 100}\n data_3 = {'id': 100, 'date': '2022-01-01', 'status': 'X'}\n json_str = '\\n'.join([to_json(data_1), to_json(data_2), to_json(data_3)])\n return Response(json_str, media_type='application/json')\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.responses import StreamingResponse\nimport json\n\napp = FastAPI()\n\n\n@app.get('/')\nasync def main():\n data_1 = {'items': 10}\n data_2 = {'order': 'shelf', 'amount': 100}\n data_3 = {'id': 100, 'date': '2022-01-01', 'status': 'X'}\n \n async def gen():\n for d in [data_1, data_2, data_3]:\n yield json.dumps(d, default=str) + '\\n'\n\n return StreamingResponse(gen(), media_type='application/json')\n```\n\n```py\nfrom fastapi import FastAPI, Response\n\napp = FastAPI()\n\n\n@app.get('/')\nasync def main():\n data_1 = {'items': 10}\n data_2 = {'order': 'shelf', 'amount': 100}\n data_3 = {'id': 100, 'date': '2022-01-01', 'status': 'X'}\n return {1: data_1, 2: data_2, 3: data_3}\n```\n\n```text\nResponse\n```\n\n```text\nStreamingResponse\n```\n\n```text\ngen()\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\niterate_in_threadpool()\n```\n\n```text\nawait\n```\n\n```text\ndict\n```\n\n```text\nmedia_type\n```\n\n```text\napplication/json\n```\n\n```text\n\\\\n\n```\n\n```text\n/docs\n```\n\n```text\ncan't parse JSON. Raw result:\n```\n\n```text\nmedia_type\n```\n\n```text\ntext/plain\n```\n\n```text\napplication/json\n```\n\n```text\nStreamingResponse\n```\n\n```text\ntext/plain\n```\n\n```text\ntext/event-stream\n```\n\n========================================\n\nComments:\n- return JsonResponse({1:data_1, 2:data_2, 3:data_3})\n- Thank you very much. \"\\n\".join works. 100% agree this is not json format. It works with the existing client. Documentation? What is that? :-)\n- FastAPI provides automatic API documentation based on OpenAPI and Swagger UI, which people can use to test their API directly from the browser. You can find the docs at `/docs`; for instance, `http://127.0.0.1:8000/docs`. If you would like to disable the doucmentation in production, please have a look here, here and here.","metadata":{"transformedAt":"2026-08-18T18:32:29.158Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":29,"totalLines":212,"estimatedTokens":953}}718{"id":"stack-76322524","source":"stackoverflow","questionId":76322524,"title":"How to use AsyncSession from sqlalchemy in celery tasks?","tags":["python","asynchronous","sqlalchemy","celery","fastapi"],"text":"Title: How to use AsyncSession from sqlalchemy in celery tasks?\nTags: python, asynchronous, sqlalchemy, celery, fastapi\nSource: Stack Overflow\n\nQuestion:\nUse AsyncSession in celery tasks\n\nI use fastapi and sqlalchemy, I must create celery task, that will go to the database and check does any objects of my Event (table) has end_time There is my code:\n\n```\n@asynccontextmanager\nasync def scoped_session():\n scoped_factory = async_scoped_session(\n async_session,\n scopefunc=asyncio.current_task()\n )\n try:\n async with scoped_factory() as s:\n yield s\n finally:\n await scoped_factory().remove()\n\nasync def logic():\n async with scoped_session() as session:\n stmt = select(event.models.Event).where(\n event.models.Event.end_time here is my async_session\n\n```\nengine = create_async_engine(settings.db_url, echo=True)\n\nasync_session = sessionmaker(\n engine,\n class_=AsyncSession,\n expire_on_commit=False\n)\n```\n\nso I got `\\'_asyncio.Task\\' object is not callable`\n\n========================================\n\nCode:\n```text\n@asynccontextmanager\nasync def scoped_session():\n scoped_factory = async_scoped_session(\n async_session,\n scopefunc=asyncio.current_task()\n )\n try:\n async with scoped_factory() as s:\n yield s\n finally:\n await scoped_factory().remove()\n\n\nasync def logic():\n async with scoped_session() as session:\n stmt = select(event.models.Event).where(\n event.models.Event.end_time <= datetime.now()\n )\n results = await session.execute(stmt)\n for res in results.fetchall():\n print(res.is_event_done)\n\n\n@celery.task(name='is_event_done', bind=True, ignore_result=True)\ndef is_event_done(self):\n asyncio.run(logic())\n```\n\n```text\nengine = create_async_engine(settings.db_url, echo=True)\n\nasync_session = sessionmaker(\n engine,\n class_=AsyncSession,\n expire_on_commit=False\n)\n```\n\n```text\n\\'_asyncio.Task\\' object is not callable\n```\n\n```text\nasync def update_event() -> None:\n async with async_session() as session:\n stmt = update(event.models.Event).where(\n event.models.Event.end_time <= datetime.now(),\n event.models.Event.is_active is True\n ).values(is_done=True)\n await session.execute(stmt)\n\n\n@celery.task(name='is_event_done', bind=True, ignore_result=True)\ndef is_event_done(self) -> None:\n loop.run_until_complete(update_event())\n```\n\n========================================\n\nComments:\n- Is this `is_event_done` really testable (unit tests) ?","metadata":{"transformedAt":"2026-08-18T18:32:29.158Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":104,"estimatedTokens":629}}719{"id":"stack-72685197","source":"stackoverflow","questionId":72685197,"title":"Upload files from FastAPI to Azure Blob Storage","tags":["reactjs","azure","azure-web-app-service","azure-blob-storage","fastapi"],"text":"Title: Upload files from FastAPI to Azure Blob Storage\nTags: reactjs, azure, azure-web-app-service, azure-blob-storage, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm trying to create a function that let me select a file from input on the frontend, then pass the file to the backend FastAPI, and eventually upload the file to Azure Blob storage. My Frontend code is below:\n\n```\n//front end\nasync function handleSubmit(){\n \n const formdata = new FormData();\n formdata.append(\n \"file\",\n file[0],\n )\n\n const headers={'Content-Type': file[0].type}\n\n await axios.post(\"/uploadfile\",formdata,headers)\n .then(function (response) {\n console.log(response)\n });\n }\n```\n\nBackend FastAPI - two methods I tried\n\n```\n//Backend FastAPI\n@app.post(\"/uploadfile\") //currently using \nasync def create_upload_file(file: UploadFile):\n name = file.filename\n type = file.content_type\n return uploadtoazure(file,name,type)\n\n@app.post(\"/files\") //another method I tried\nasync def create_file(file: bytes= File()):\n \n await uploadtoazure(file)\n```\n\nAnd the uploadtoazure() function\n\n```\n//Backend uploadtoazure() function\nasync def uploadtoazure(f,n,t):\n connect_str = \"\"//removed from sample code\n \n blob_service_client = BlobServiceClient.from_connection_string(connect_str)\n container_name = \"notes\"\n\n file = f.read()\n local_file_name = n\n cnt_settings = ContentSettings(content_type=t)\n\n blob_client = blob_service_client.get_blob_client(container=container_name, blob=local_file_name)\n \n blob_client.upload_blob(file,cnt_settings)\n```\n\nThe error kept coming at me and when I tried another method another new error prevents me from moving forward.\n\nSome problem I'm aware:\n\n- `blob_client.upload_blob()` only accept some types of files, in which the file type I passed in from API isn't one of it.\n\n- I used the sample code in https://fastapi.tiangolo.com/tutorial/request-files/In which I am not quite sure of the characteristic of the class `UploadFile` and `File()`.\n\n- When I use the method which the file passed to API is `file: bytes= File()`, the file type seems able to upload to the blob storage, however it does not have a content type or suffix, hence I think finding a way to pass in the content_type of the file could be another solution, but it was harder than I thought.\n\nI hope there's enough information, I desperately need someone to clear my confusion. Thank you very much.\n\n========================================\n\nCode:\n```text\n//front end\nasync function handleSubmit(){\n \n const formdata = new FormData();\n formdata.append(\n \"file\",\n file[0],\n )\n\n const headers={'Content-Type': file[0].type}\n\n await axios.post(\"/uploadfile\",formdata,headers)\n .then(function (response) {\n console.log(response)\n });\n }\n```\n\n```text\n//Backend FastAPI\n@app.post(\"/uploadfile\") //currently using \nasync def create_upload_file(file: UploadFile):\n name = file.filename\n type = file.content_type\n return uploadtoazure(file,name,type)\n\n@app.post(\"/files\") //another method I tried\nasync def create_file(file: bytes= File()):\n \n await uploadtoazure(file)\n```\n\n```text\n//Backend uploadtoazure() function\nasync def uploadtoazure(f,n,t):\n connect_str = \"\"//removed from sample code\n \n blob_service_client = BlobServiceClient.from_connection_string(connect_str)\n container_name = \"notes\"\n\n file = f.read()\n local_file_name = n\n cnt_settings = ContentSettings(content_type=t)\n\n blob_client = blob_service_client.get_blob_client(container=container_name, blob=local_file_name)\n \n blob_client.upload_blob(file,cnt_settings)\n```\n\n```text\nblob_client.upload_blob()\n```\n\n```text\nUploadFile\n```\n\n```text\nFile()\n```\n\n```text\nfile: bytes= File()\n```\n\n```py\nfrom fastapi import FastAPI, HTTPException, UploadFile\nfrom azure.storage.blob.aio import BlobServiceClient\n\napp = FastAPI()\n\n@app.post(\"/uploadfile\")\nasync def create_upload_file(file: UploadFile):\n name = file.filename\n type = file.content_type\n return await uploadtoazure(file,name,type)\n\n\nasync def uploadtoazure(file: UploadFile,file_name: str,file_type:str):\n connect_str = \"HERE_YUOUR_CONNECTION_STRING\"\n blob_service_client = BlobServiceClient.from_connection_string(connect_str)\n container_name = \"stackoverflow\"\n async with blob_service_client:\n container_client = blob_service_client.get_container_client(container_name)\n try:\n blob_client = container_client.get_blob_client(file_name)\n f = await file.read()\n await blob_client.upload_blob(f)\n except Exception as e:\n print(e)\n return HTTPException(401, \"Something went terribly wrong..\")\n \n return \"{'did_it_work':'yeah it did!'}\"\n\n\nif __name__ == \"__main__\":\n import uvicorn\n uvicorn.run(app, host=\"0.0.0.0\", port=8000, )\n```\n\n```text\nf.read()\n```\n\n========================================\n\nComments:\n- The type of files is managed in the storage account. Default settings should be broad enough for many file-types. What kind of files do you use? We use FastAPI for uploading images to Azure Blob Storage and that works perfectly. Can you the errors you face?\n- Hi: I think the problem is how I handle the UploadFile type parameter, and how I treat the async and await in the function that causes the problem. The errors I received include `TypeError: Unsupported data type: ` and `ValueError: [TypeError(\"'coroutine' object is not iterable\"), TypeError('vars() argument must have __dict__ attribute')]` . And I think it is all associated with the uploadtoazure() function during handling of the file passed in from API, specifically when doing `upload_blob`. If you do know why the error occur it would be a great help.\n- Thank you so much. I have one additional question, what's the difference between importing `BlobServiceClient` from `azure.storage.blob.aio` and `azure.storage.blob`, as I think the code works for the \"aio\" version. Also, sometimes the Axios post returns `AxiosError {message: 'Network Error', name: 'AxiosError', code: 'ERR_NETWORK'`. I have set the proxy to `\"proxy\": \"http://localhost:8000/\"` in package.json, but sometimes, the previous post works, and the next post, it returns error. If you need any extra information, I would be glad to up.\n- **Update**: I have fixed the AxiosError problem, and I think the `azure.storage.blob.aio` is the async version of `azure.storage.blob`? When I used the \"non async version\" and does `f = await file.read()`, I remember when uploading it returns error like `TypeError: Unsupported data type: ` and `ValueError: [TypeError(\"'coroutine' object is not iterable\")`. Does the async version is the key to solve this problem? And what is the role of `async with` plays in the code?\n- `azure.storage.blob.aio` is indeed the async version of the the BlobServiceClient, allowing blocking calls to be awaited. An async function (e.g. a method defined with `async def` doesn't actually return the return object, but a `coroutine` object when called. Only when it is awaited, it will execute the code in the async method and return the actual return object. I found a fantastic tutorial on async, which will explain it in better detail and I highly recommend you give it a good read: bbc.github.io/cloudfit-public-docs","metadata":{"transformedAt":"2026-08-18T18:32:29.158Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":189,"estimatedTokens":1826}}720{"id":"stack-75554263","source":"stackoverflow","questionId":75554263,"title":"beanie.exceptions.CollectionWasNotInitialized error","tags":["python","mongodb","fastapi","odm"],"text":"Title: beanie.exceptions.CollectionWasNotInitialized error\nTags: python, mongodb, fastapi, odm\nSource: Stack Overflow\n\nQuestion:\nI'm new to the `Beanie` library which is\n\nan asynchronous Python object-document mapper (ODM) for MongoDB. Data models are based on Pydantic.\n\nI was trying this library with `fastAPI` framework, and made an ODM for some document, let's say it's name is `SomeClass` and then tried to insert some data in the db using this ODM.\n\nHere's the code for ODM and the method to create a document (in`someClass.py`):\n\n```\nfrom beanie import Document\nfrom pydantic import Field, BaseModel\n \nclass SomeClassDto(BaseModel):\n \"\"\"\n A Class for Data Transferring.\n \"\"\"\n name: str = Field(max_length=maxsize, min_length=1)\n\nclass SomeClassDao:\n \"\"\"\n This is a class which holds the 'SomeClass' class (inherited from Beanie Document),\n and also, the methods which use the 'SomeClass' class.\n \"\"\"\n class SomeClass(Document):\n name: str = Field(max_length=20, min_length=1)\n \n\n @classmethod\n async def create_some_class(cls, body: SomeClassDto):\n some_class = cls.SomeClass(**body.dict())\n return await cls.SomeClass.insert_one(some_class)\n```\n\nI've used and called the `create_some_class` function, but it throwed this error:\n\n`beanie.exceptions.CollectionWasNotInitialized`\n\nHowever the error is self-explanatory but I didn't understand at first, and couldn't find any relatable question about my problem in SO, so I decided to post this question and answer it, for the sake of future.\n\n========================================\n\nTop Answer:\nMake sure there are no import problems. If you have correctly initialized beanie, but are not importing the class correctly that stores this class, this error can occur.\n\nIt can also occur when a linked object is not properly initialized, or even a backlinked object that references your object. Try debugging with `fetch_links=False` to test if it's an issue with a linked or backlinked object.\n\nI'm also answering for myself for future reference (because this one can be tough to track down).\n\n========================================\n\nCode:\n```py\nfrom beanie import Document\nfrom pydantic import Field, BaseModel\n \nclass SomeClassDto(BaseModel):\n \"\"\"\n A Class for Data Transferring.\n \"\"\"\n name: str = Field(max_length=maxsize, min_length=1)\n\n\nclass SomeClassDao:\n \"\"\"\n This is a class which holds the 'SomeClass' class (inherited from Beanie Document),\n and also, the methods which use the 'SomeClass' class.\n \"\"\"\n class SomeClass(Document):\n name: str = Field(max_length=20, min_length=1)\n \n\n @classmethod\n async def create_some_class(cls, body: SomeClassDto):\n some_class = cls.SomeClass(**body.dict())\n return await cls.SomeClass.insert_one(some_class)\n```\n\n```text\nBeanie\n```\n\n```text\nfastAPI\n```\n\n```text\nSomeClass\n```\n\n```text\nsomeClass.py\n```\n\n```text\ncreate_some_class\n```\n\n```text\nbeanie.exceptions.CollectionWasNotInitialized\n```\n\n```py\nfrom beanie import init_beanie\nimport motor.motor_asyncio\nfrom someClass import SomeClassDao\n\nasync def init_db(cls):\n MONGO_DB_DATABASE_NAME = \"SomeDBName\"\n MOTOR_CLIENT = motor.motor_asyncio.AsyncIOMotorClient()\n DATABASE = MOTOR_CLIENT[MONGO_DB_DATABASE_NAME]\n document_models = [SomeClassDao.SomeClass,]\n await init_beanie(database=cls.DATABASE, document_models=document_models)\n```\n\n```py\nfrom fastapi import FastAPI\nfrom database import init_db\n\napp = FastAPI()\n@app.on_event(\"startup\")\nasync def start_db():\n await init_db()\n```\n\n```text\ninit_beanie\n```\n\n```text\ndatabse.py\n```\n\n```text\nmain.py\n```\n\n```text\ninit_beanie\n```\n\n```text\ndocument\n```\n\n```text\ndocument_models\n```\n\n```text\nfetch_links=False\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.158Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":16,"totalLines":156,"estimatedTokens":934}}721{"id":"stack-75724033","source":"stackoverflow","questionId":75724033,"title":"Set the media type of a custom Error Response via a pydantic model in FastAPI","tags":["python","swagger","fastapi","swagger-ui","openapi"],"text":"Title: Set the media type of a custom Error Response via a pydantic model in FastAPI\nTags: python, swagger, fastapi, swagger-ui, openapi\nSource: Stack Overflow\n\nQuestion:\nIn my FastAPI application I want to return my errors as RFC Problem JSON:\n\n```\nfrom pydantic import BaseModel\n\nclass RFCProblemJSON(BaseModel):\n type: str\n title: str\n detail: str | None\n status: int | None\n```\n\nI can set the response model in the OpenAPI docs with the `responses` argument of the FastAPI class:\n\n```\nfrom fastapi import FastAPI, status\n\napi = FastAPI(\n responses={\n status.HTTP_401_UNAUTHORIZED: {'model': RFCProblemJSON},\n status.HTTP_422_UNPROCESSABLE_ENTITY: {'model': RFCProblemJSON},\n status.HTTP_500_INTERNAL_SERVER_ERROR: {'model': RFCProblemJSON}\n }\n)\n```\n\nHowever, I want to set the media type as 'application/problem+json'. I tried two methods, first just adding a 'media type' field on to the basemodel:\n\n```\nclass RFCProblemJSON(BaseModel):\n media_type = \"application/problem+json\"\n type: str\n title: str\n detail: str | None\n status: int | None\n```\n\nand also, inheriting from `fastapi.responses.Response`:\n\n```\nclass RFCProblemJSON(Response):\n media_type = \"application/problem+json\"\n type: str\n title: str\n detail: str | None\n status: int | None\n```\n\nHowever neither of these modify the media_type in the openapi.json file/the swagger UI.\n\nWhen you add the media_type field to the basemodel, the media type in the SwaggerUI is not modified::\nhttps://i.sstatic.net/tiPq5.png\n\nAnd when you make the model inherit from Response, you just get an error (this was a long shot from working but tried it anyway).\n\n```\nraise fastapi.exceptions.FastAPIError(\nfastapi.exceptions.FastAPIError: Invalid args for response field! Hint: check that is a valid Pydantic field type. If you are using a return type annotation that is not a valid Pydantic field (e.g. Union[Response, dict, None]) you can disable generating the response model from the type annotation with the path operation decorator parameter response_model=None. Read more: https://fastapi.tiangolo.com/tutorial/response-model/\n```\n\nIt is possible to get the swagger UI to show the correct media type if you manually fill out the OpenAPI definition:\n\n```\napi = FastAPI(\n debug=debug,\n version=API_VERSION,\n title=\"RoutingServer API\",\n openapi_tags=tags_metadata,\n swagger_ui_init_oauth={\"clientID\": oauth2_scheme.client_id},\n responses={\n status.HTTP_401_UNAUTHORIZED: {\n \"content\": {\"application/problem+json\": {\n \"example\": {\n \"type\": \"string\",\n \"title\": \"string\",\n \"detail\": \"string\"\n }}},\n \"description\": \"Return the JSON item or an image.\",\n },\n }\n)\n```\n\nHowever, I want to try and implement this with a BaseModel so that I can inherit from RFCProblemJSON and provide some optional extras for some specific errors.\n\nThe minimal example to reproduce my problem is:\n\n```\nfrom pydantic import BaseModel\nfrom fastapi import FastAPI, status, Response, Request\nfrom fastapi.exceptions import RequestValidationError\nfrom pydantic import error_wrappers\nimport json\nimport uvicorn\nfrom typing import List, Tuple, Union, Dict, Any\nfrom typing_extensions import TypedDict\n\nLoc = Tuple[Union[int, str], ...]\n\nclass _ErrorDictRequired(TypedDict):\n loc: Loc\n msg: str\n type: str\n\nclass ErrorDict(_ErrorDictRequired, total=False):\n ctx: Dict[str, Any]\n\nclass RFCProblemJSON(BaseModel):\n type: str\n title: str\n detail: str | None\n status: int | None\n\nclass RFCUnprocessableEntity(RFCProblemJSON):\n instance: str\n issues: List[ErrorDict]\n\nclass RFCProblemResponse(Response):\n media_type = \"application/problem+json\"\n\n def render(self, content: RFCProblemJSON) -> bytes:\n return json.dumps(\n content.dict(),\n ensure_ascii=False,\n allow_nan=False,\n indent=4,\n separators=(\", \", \": \"),\n ).encode(\"utf-8\")\n\napi = FastAPI(\n responses={\n status.HTTP_422_UNPROCESSABLE_ENTITY: {'model': RFCUnprocessableEntity},\n }\n)\n\n@api.get(\"/{x}\")\ndef hello(x: int) -> int:\n return x\n\n@api.exception_handler(RequestValidationError)\ndef format_validation_error_as_problem_json(request: Request, exc: error_wrappers.ValidationError):\n status_code = status.HTTP_422_UNPROCESSABLE_ENTITY\n content = RFCUnprocessableEntity(\n type=\"/errors/unprocessable_entity\",\n title=\"Unprocessable Entity\",\n status=status_code,\n detail=\"The request has validation errors.\",\n instance=request.url.path,\n issues=exc.errors()\n )\n return RFCProblemResponse(content, status_code=status_code)\n\nuvicorn.run(api)\n```\n\nWhen you go to `http://localhost:8000/hello`, it will return as `application/problem+json` in the headers, however if you go to the swagger ui docs the ui shows the response will be `application/json`. I dont know how to keep the style of my code, but update the openapi definition to show that it will return as 'application/problem+json` in a nice way.\n\nIs this possible to do?\n\n========================================\n\nCode:\n```text\nfrom pydantic import BaseModel\n\nclass RFCProblemJSON(BaseModel):\n type: str\n title: str\n detail: str | None\n status: int | None\n```\n\n```text\nfrom fastapi import FastAPI, status\n\napi = FastAPI(\n responses={\n status.HTTP_401_UNAUTHORIZED: {'model': RFCProblemJSON},\n status.HTTP_422_UNPROCESSABLE_ENTITY: {'model': RFCProblemJSON},\n status.HTTP_500_INTERNAL_SERVER_ERROR: {'model': RFCProblemJSON}\n }\n)\n```\n\n```text\nclass RFCProblemJSON(BaseModel):\n media_type = \"application/problem+json\"\n type: str\n title: str\n detail: str | None\n status: int | None\n```\n\n```text\nclass RFCProblemJSON(Response):\n media_type = \"application/problem+json\"\n type: str\n title: str\n detail: str | None\n status: int | None\n```\n\n```text\nraise fastapi.exceptions.FastAPIError(\nfastapi.exceptions.FastAPIError: Invalid args for response field! Hint: check that <class 'RoutingServer.RestAPI.schema.errors.RFCProblemJSON'> is a valid Pydantic field type. If you are using a return type annotation that is not a valid Pydantic field (e.g. Union[Response, dict, None]) you can disable generating the response model from the type annotation with the path operation decorator parameter response_model=None. Read more: https://fastapi.tiangolo.com/tutorial/response-model/\n```\n\n```text\napi = FastAPI(\n debug=debug,\n version=API_VERSION,\n title=\"RoutingServer API\",\n openapi_tags=tags_metadata,\n swagger_ui_init_oauth={\"clientID\": oauth2_scheme.client_id},\n responses={\n status.HTTP_401_UNAUTHORIZED: {\n \"content\": {\"application/problem+json\": {\n \"example\": {\n \"type\": \"string\",\n \"title\": \"string\",\n \"detail\": \"string\"\n }}},\n \"description\": \"Return the JSON item or an image.\",\n },\n }\n)\n```\n\n```text\nfrom pydantic import BaseModel\nfrom fastapi import FastAPI, status, Response, Request\nfrom fastapi.exceptions import RequestValidationError\nfrom pydantic import error_wrappers\nimport json\nimport uvicorn\nfrom typing import List, Tuple, Union, Dict, Any\nfrom typing_extensions import TypedDict\n\nLoc = Tuple[Union[int, str], ...]\n\n\nclass _ErrorDictRequired(TypedDict):\n loc: Loc\n msg: str\n type: str\n\n\nclass ErrorDict(_ErrorDictRequired, total=False):\n ctx: Dict[str, Any]\n\n\nclass RFCProblemJSON(BaseModel):\n type: str\n title: str\n detail: str | None\n status: int | None\n\n\nclass RFCUnprocessableEntity(RFCProblemJSON):\n instance: str\n issues: List[ErrorDict]\n\n\nclass RFCProblemResponse(Response):\n media_type = \"application/problem+json\"\n\n def render(self, content: RFCProblemJSON) -> bytes:\n return json.dumps(\n content.dict(),\n ensure_ascii=False,\n allow_nan=False,\n indent=4,\n separators=(\", \", \": \"),\n ).encode(\"utf-8\")\n\n\napi = FastAPI(\n responses={\n status.HTTP_422_UNPROCESSABLE_ENTITY: {'model': RFCUnprocessableEntity},\n }\n)\n\n\n@api.get(\"/{x}\")\ndef hello(x: int) -> int:\n return x\n\n\n@api.exception_handler(RequestValidationError)\ndef format_validation_error_as_problem_json(request: Request, exc: error_wrappers.ValidationError):\n status_code = status.HTTP_422_UNPROCESSABLE_ENTITY\n content = RFCUnprocessableEntity(\n type=\"/errors/unprocessable_entity\",\n title=\"Unprocessable Entity\",\n status=status_code,\n detail=\"The request has validation errors.\",\n instance=request.url.path,\n issues=exc.errors()\n )\n return RFCProblemResponse(content, status_code=status_code)\n\n\nuvicorn.run(api)\n```\n\n```text\nresponses\n```\n\n```text\nfastapi.responses.Response\n```\n\n```text\nhttp://localhost:8000/hello\n```\n\n```text\napplication/problem+json\n```\n\n```text\napplication/json\n```\n\n```py\nfrom fastapi import FastAPI, Response, Request, status\nfrom fastapi.exceptions import RequestValidationError\nfrom fastapi.openapi.constants import REF_PREFIX\nfrom fastapi.responses import JSONResponse\nfrom pydantic import BaseModel\nimport json\n\n\nclass Item(BaseModel):\n id: str\n value: str\n\n\nclass SubMessage(BaseModel):\n msg: str\n\n\nclass Message(BaseModel):\n msg: str\n sub: SubMessage\n\n\nclass CustomResponse(Response):\n media_type = 'application/problem+json'\n\n def render(self, content: Message) -> bytes:\n return json.dumps(\n content.dict(),\n ensure_ascii=False,\n allow_nan=False,\n indent=4,\n separators=(', ', ': '),\n ).encode('utf-8')\n\n\ndef get_422_schema():\n return {\n 'model': Message,\n 'content': {\n 'application/problem+json': {\n 'schema': {'$ref': REF_PREFIX + Message.__name__}\n }\n },\n }\n\n\napp = FastAPI(responses={status.HTTP_422_UNPROCESSABLE_ENTITY: get_422_schema()})\n\n\n@app.exception_handler(RequestValidationError)\nasync def validation_exception_handler(request: Request, exc: RequestValidationError):\n msg = Message(msg='main message', sub=SubMessage(msg='sub message'))\n return CustomResponse(content=msg, status_code=status.HTTP_422_UNPROCESSABLE_ENTITY)\n\n\n@app.post('/items')\nasync def submit(item: Item):\n return item\n```\n\n```text\nresponses\n```\n\n```text\ndict\n```\n\n```text\n200\n```\n\n```text\ndict\n```\n\n```text\ndict\n```\n\n```text\nmodel\n```\n\n```text\nresponse_model\n```\n\n```text\nmodel\n```\n\n```text\nJSON Schema\n```\n\n```text\ndict\n```\n\n```text\napplication/json\n```\n\n```text\nschema\n```\n\n```text\nmedia_type\n```\n\n```text\nBaseModel\n```\n\n```text\n422 UNPROCESSABLE ENTITY\n```\n\n```text\napplication/problem+json\n```\n\n```text\nmodel\n```\n\n```text\nschema\n```\n\n```text\n422\n```\n\n========================================\n\nComments:\n- Try creating Response object for the endpoint that returns RFCProblemJSOn and specify the content and media_type, instead of directly providing to fastapi.\n- @Prudhviraj by default, the endpoints dont return a RFC Problem JSON, only when an error happens it will return RFC Problem JSON. My code has an exception handler that catches errors and converts them into RFC Problem JSON.\n- If you already have an exception handler, similar to this or this, you could then return a custom `Response` (as shown in Option 2 of this answer, for instance) from the exception handler, specifying the desired `media_type`.\n- Thanks for the answer. I am having a bug with this where if I put a basemodel field inside Message, then swagger ui returns an error (i.e. `Could not resolve reference: Could not resolve pointer: /definitions/SubMessage does not exist in document`)\n- Thanks for letting me know. Please have a look at the updated example above.","metadata":{"transformedAt":"2026-08-18T18:32:29.158Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":32,"totalLines":475,"estimatedTokens":2874}}722{"id":"stack-75192148","source":"stackoverflow","questionId":75192148,"title":"FastAPI and PostgreSQL in docker-compose file connection error","tags":["python","postgresql","docker-compose","sqlalchemy","fastapi"],"text":"Title: FastAPI and PostgreSQL in docker-compose file connection error\nTags: python, postgresql, docker-compose, sqlalchemy, fastapi\nSource: Stack Overflow\n\nQuestion:\nThis question has been asked already\nfor example\nDocker: Is the server running on host \"localhost\" (::1) and accepting TCP/IP connections on port 5432?\nbut I still can't figure out how to properly connect the application to the database.\n\nFiles:\n\nDockerfile\n\n```\nFROM python:3.10-slim\nWORKDIR /app\nCOPY . .\nRUN pip install --upgrade pip\nRUN pip install \"fastapi[all]\" sqlalchemy psycopg2-binary\n```\n\ndocker-compose.yml\n\n```\nversion: '3.8'\nservices:\n ylab:\n container_name: ylab\n build:\n context: .\n entrypoint: >\n sh -c \"uvicorn main:app --reload --host 0.0.0.0\"\n ports:\n - \"8000:8000\"\n postgres:\n container_name: postgr\n image: postgres:15.1-alpine\n environment:\n POSTGRES_DB: \"fastapi_database\"\n POSTGRES_PASSWORD: \"password\"\n ports:\n - \"5433:5432\"\n```\n\nmain.py\n\n```\nimport fastapi as _fastapi\nimport sqlalchemy as _sql\nimport sqlalchemy.ext.declarative as _declarative\nimport sqlalchemy.orm as _orm\n\nDATABASE_URL = \"postgresql://postgres:password@localhost:5433/fastapi_database\"\nengine = _sql.create_engine(DATABASE_URL)\nSessionLocal = _orm.sessionmaker(autocommit=False, autoflush=False, bind=engine)\nBase = _declarative.declarative_base()\n\nclass Menu(Base):\n __tablename__ = \"menu\"\n id = _sql.Column(_sql.Integer, primary_key=True, index=True)\n title = _sql.Column(_sql.String, index=True)\n description = _sql.Column(_sql.String, index=True)\n\napp = _fastapi.FastAPI()\n\n# Create table 'menu'\nBase.metadata.create_all(bind=engine)\n```\n\nThis works if I host only the postgres database in the container and my application is running locally, but if the database and application are in their own containers, no matter how I try to change the settings, the error always comes up:\n\n\"sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) connection to server at \"localhost\" (127.0.0.1), port 5433 failed: Connection refused\nylab | Is the server running on that host and accepting TCP/IP connections?\nylab | connection to server at \"localhost\" (::1), port 5433 failed: Cannot assign requested address\nylab | Is the server running on that host and accepting TCP/IP connections?\"\n\nThe error comes up in\n\n```\nBase.metadata.create_all(bind=engine)\n```\n\nI also tried\n\n```\nDATABASE_URL = \"postgresql://postgres:password@postgres:5433/fastapi_database\"\n```\n\nbut still error:\n\n\"sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) connection to server at \"postgres\" (172.23.0.2), port 5433 failed: Connection refused\nylab | Is the server running on that host and accepting TCP/IP connections?\"\n\nThere is some kind of config file or something mentioned in the answer above but I can't figure out how to manage that config.\n\n========================================\n\nCode:\n```text\nFROM python:3.10-slim\nWORKDIR /app\nCOPY . .\nRUN pip install --upgrade pip\nRUN pip install \"fastapi[all]\" sqlalchemy psycopg2-binary\n```\n\n```text\nversion: '3.8'\nservices:\n ylab:\n container_name: ylab\n build:\n context: .\n entrypoint: >\n sh -c \"uvicorn main:app --reload --host 0.0.0.0\"\n ports:\n - \"8000:8000\"\n postgres:\n container_name: postgr\n image: postgres:15.1-alpine\n environment:\n POSTGRES_DB: \"fastapi_database\"\n POSTGRES_PASSWORD: \"password\"\n ports:\n - \"5433:5432\"\n```\n\n```text\nimport fastapi as _fastapi\nimport sqlalchemy as _sql\nimport sqlalchemy.ext.declarative as _declarative\nimport sqlalchemy.orm as _orm\n\nDATABASE_URL = \"postgresql://postgres:password@localhost:5433/fastapi_database\"\nengine = _sql.create_engine(DATABASE_URL)\nSessionLocal = _orm.sessionmaker(autocommit=False, autoflush=False, bind=engine)\nBase = _declarative.declarative_base()\n\nclass Menu(Base):\n __tablename__ = \"menu\"\n id = _sql.Column(_sql.Integer, primary_key=True, index=True)\n title = _sql.Column(_sql.String, index=True)\n description = _sql.Column(_sql.String, index=True)\n\napp = _fastapi.FastAPI()\n\n# Create table 'menu'\nBase.metadata.create_all(bind=engine)\n```\n\n```text\nBase.metadata.create_all(bind=engine)\n```\n\n```text\nDATABASE_URL = \"postgresql://postgres:password@postgres:5433/fastapi_database\"\n```\n\n```none\nDATABASE_URL = \"postgresql://postgres:password@postgres:5432/fastapi_database\"\n```\n\n```text\nlocalhost:5433\n```\n\n```text\n5433\n```\n\n```text\n5432\n```\n\n========================================\n\nComments:\n- What happens if you try your config as `DATABASE_URL = \"postgresql://postgres:password@postgres:5432/fastapi_databa‌​se\"` In your first example with the app running locally and postgres in the container this works as you map `localhost:5433` into the postgres containers port `5432`. When you try to do this in the app container it doesnt work since the database is not running locally in the app container. When you change `localhost` to `postgres` this will start targetting the correct container with the db, but the port the db runs on inside the container is port 5432 no port 5433\n- I tried to do as you suggested and it works! But I would like to say that since yesterday morning I have tried every possible and impossible combination, including yours. And it turns out that it works on the second try, i.e. i create containers with \"docker-compose up\" command and i get error. I stop the server and start it again with the same \"docker-compose up\" command and for some reason it works. In any case, you have been a great help to me. I am very grateful to you.\n- You probably want to look at docs.docker.com/compose/startup-order as chances are fastapi will start up before the db and get a connection error. you can use depends on to tell the app not to start until the db is up and running. I will type up the answer for you to accept","metadata":{"transformedAt":"2026-08-18T18:32:29.159Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":181,"estimatedTokens":1449}}723{"id":"stack-67729239","source":"stackoverflow","questionId":67729239,"title":"How to use an endpoint with multiple body params and fileupload in FastAPI?","tags":["python","python-3.x","post","fastapi"],"text":"Title: How to use an endpoint with multiple body params and fileupload in FastAPI?\nTags: python, python-3.x, post, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have an application that stores files and additional information e.g. author, comments DB. I can pass an file to FastAPI, but getting issue by passing it together with parameters.\n\nI checked following question How to add multiple body params with fileupload in FastAPI? and this issue [QUESTION] Use UploadFile in Pydantic model #657 but without success.\n\nI tried 2 definitions in the FastAPI endpoint\n\n**Option 1**\n\n```\nclass Properties(BaseModel):\n language: Optional[str] = None\n author: Optional[str] = None\n\n@app.post(\"/uploadfile/\")\nasync def uploadfile(params: Properties, file: UploadFile = File(...)):\n #internal logic\n```\n\n**Option 2**\n\n```\n@app.post(\"/uploadfile/\")\nasync def uploadfile(file: UploadFile = File(...),\n language: str = Form(...),\n author: Optional[str] = Form(None)):\n #internal logic\n```\n\n**Client code**:\nFollowing code is used on client side, but response is **422 Unprocessable Entity** for both options.\n\n```\nwith open(path, 'rb') as f:\n response = requests.post('http://localhost:8005/uploadfile/', data={'language':'en', \n 'author':'me'}, files={'file': f})\n```\n\nBoth options can't be tested from swagger, there I am getting response: **value is not a valid dict**. Data looks good for me, but maybe I am missing something.\n\nIt seems that the client code is wrong, but also there I tried several changes without success.\n\nIn advance, thanks for your support!\n\n**Solution that works for me**\n\nAs 'Drdilyor' wrote in his comment I have use option 2, as we are sending file. My issue was within order of arguments. After changing them everything starts working.\n\n========================================\n\nCode:\n```text\nclass Properties(BaseModel):\n language: Optional[str] = None\n author: Optional[str] = None\n\n@app.post(\"/uploadfile/\")\nasync def uploadfile(params: Properties, file: UploadFile = File(...)):\n #internal logic\n```\n\n```text\n@app.post(\"/uploadfile/\")\nasync def uploadfile(file: UploadFile = File(...),\n language: str = Form(...),\n author: Optional[str] = Form(None)):\n #internal logic\n```\n\n```text\nwith open(path, 'rb') as f:\n response = requests.post('http://localhost:8005/uploadfile/', data={'language':'en', \n 'author':'me'}, files={'file': f})\n```\n\n```py\n@app.post(\"/uploadfile/\")\nasync def uploadfile(author: Optional[str] = Form(...),\n language: Optional[str] = Form(...),\n file: UploadFile = File(...)):\n```\n\n```text\napplication/json\n```\n\n```text\nmultipart/formdata\n```\n\n```text\nmultipart/formdata\n```\n\n```text\ncurl http://localhost:8000/uploadfile/ -X POST -F author=me -F language=en -F file=@/path/to/file\n```\n\n```text\nrequests\n```\n\n========================================\n\nComments:\n- I tried passing `data={'params': ''}` and it somehow returned 200\n- this doesn't worked for me. However your comment helped me to think about the issue from another angle. Thanks!\n- Thanks, for your help. I added information to my post. Client code that I was using initially is working now with Option 2. Issue was in the order of the arguments.","metadata":{"transformedAt":"2026-08-18T18:32:29.159Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":112,"estimatedTokens":813}}724{"id":"stack-78816624","source":"stackoverflow","questionId":78816624,"title":"Why dart:convert :: json.encoder turns everything into a string?","tags":["json","flutter","dart","fastapi"],"text":"Title: Why dart:convert :: json.encoder turns everything into a string?\nTags: json, flutter, dart, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to send an HTTP PUT request to FastAPI backend from flutter code. I jsonify the data before I put into the request body. Here are my data classes:\n\n```\nclass ListeningHistory {\n final String userId;\n List podcasts;\n\n ListeningHistory({required this.userId, required this.podcasts});\n\n Map toJson() {\n podcasts = []; // for simplicity's sake\n return {'user_id': userId, 'podcasts': jsonEncode(podcasts)};\n }\n```\n\n**Please note that I intentionally replaced the actual podcasts with an empty array above for the sake of simplicity for this example.**\n\n```\nclass BareMinPost {\n final String title;\n final String publishedDate;\n final int pausedAt;\n\n BareMinPost({\n required this.title,\n required this.publishedDate,\n required this.pausedAt,\n });\n\n BareMinPost.fromJson(Map json)\n : title = json['title'] as String,\n publishedDate = json['publishedDate'] as String,\n pausedAt = json['pausedAt'] as int;\n\n Map toJson() =>\n {'title': title, 'publishedDate': publishedDate, 'pausedAt': pausedAt};\n\n @override\n String toString() {\n return \"BareMinPost - title: $title publishedDate: $publishedDate puasedAt: $pausedAt\";\n }\n}\n```\n\nI use the following piece of code to json encode the data:\n\n```\nimport 'dart:convert';\n...\n ListeningHistory hist = ListeningHistory(\n userId: \"$userId\", podcasts: previouslyListenedTo);\n String reqBody = json.encode(hist);\n dualLog(logger, '------------------->>>>-----$reqBody');\n```\n\nlog line prints out as follows:\n\n```\n------------------->>>>-----{\"user_id\":\"org.couchdb.users:alp\",\"podcasts\":\"[]\"}\n```\n\nPlease note the double quotes around the array at the end. These, I believe should not be there but they are for some reason.\n\nAnd eventually when I send this request the fastapi server, it complains as follows:\n\n```\nERROR: {\"detail\":[{\"type\":\"list_type\",\"loc\":[\"body\",\"podcasts\"],\"msg\":\"Input should be a valid list\",\"input\":\"[]\"}]}\n```\n\nWhat am I missing here ?\n\n========================================\n\nCode:\n```text\nclass ListeningHistory {\n final String userId;\n List<BareMinPost> podcasts;\n\n ListeningHistory({required this.userId, required this.podcasts});\n\n Map<String, dynamic> toJson() {\n podcasts = []; // for simplicity's sake\n return {'user_id': userId, 'podcasts': jsonEncode(podcasts)};\n }\n```\n\n```text\nclass BareMinPost {\n final String title;\n final String publishedDate;\n final int pausedAt;\n\n BareMinPost({\n required this.title,\n required this.publishedDate,\n required this.pausedAt,\n });\n\n BareMinPost.fromJson(Map<String, dynamic> json)\n : title = json['title'] as String,\n publishedDate = json['publishedDate'] as String,\n pausedAt = json['pausedAt'] as int;\n\n Map<String, dynamic> toJson() =>\n {'title': title, 'publishedDate': publishedDate, 'pausedAt': pausedAt};\n\n @override\n String toString() {\n return \"BareMinPost - title: $title publishedDate: $publishedDate puasedAt: $pausedAt\";\n }\n}\n```\n\n```text\nimport 'dart:convert';\n...\n ListeningHistory hist = ListeningHistory(\n userId: \"$userId\", podcasts: previouslyListenedTo);\n String reqBody = json.encode(hist);\n dualLog(logger, '------------------->>>>-----$reqBody');\n```\n\n```text\n------------------->>>>-----{\"user_id\":\"org.couchdb.users:alp\",\"podcasts\":\"[]\"}\n```\n\n```text\nERROR: {\"detail\":[{\"type\":\"list_type\",\"loc\":[\"body\",\"podcasts\"],\"msg\":\"Input should be a valid list\",\"input\":\"[]\"}]}\n```\n\n```text\nimport 'dart:convert' show JsonUnsupportedObjectError, jsonEncode, jsonDecode;\n\nclass BareMinPost {\n BareMinPost({required this.title});\n final String title;\n\n Map<String, dynamic> toJson() => {'title': title};\n\n factory BareMinPost.fromJson(Map<String, dynamic> json) {\n // Validate input\n if (json\n case {\n 'title': String title,\n }) {\n return BareMinPost(title: title);\n } else {\n throw JsonUnsupportedObjectError(json,\n cause: 'BareMinPost: Json validation failed');\n }\n }\n}\n\nclass ListeningHistory {\n final String userId;\n List<BareMinPost> podcasts;\n\n ListeningHistory({required this.userId, required this.podcasts});\n\n Map<String, dynamic> toJson() {\n return {\n 'user_id': userId,\n 'podcasts': podcasts\n .map(\n (e) => e.toJson(),\n )\n .toList()\n };\n }\n\n factory ListeningHistory.fromJson(Map<String, dynamic> json) {\n // Validate input\n if (json\n case {\n 'user_id': String userId,\n 'podcasts': List podcasts,\n }) {\n return ListeningHistory(\n userId: userId,\n podcasts: podcasts.map((e) => BareMinPost.fromJson(e)).toList(),\n );\n } else {\n throw JsonUnsupportedObjectError(json,\n cause: 'ListeningHistory: Json validation failed');\n }\n }\n}\n```\n\n```text\nvoid main(List<String> args) {\n final history = ListeningHistory(userId: 'json1997', podcasts: [\n BareMinPost(title: 'Song A'),\n BareMinPost(title: 'Song B'),\n ]);\n\n // Encoding\n print('Encoding: ...');\n print(\n history.toJson(),\n ); // Prints: {user_id: json1997, podcasts: [{title: Song A}, {title: Song B}]}\n final jsonString = jsonEncode(history.toJson());\n print(\n jsonString,\n ); // Prints: {\"user_id\":\"json1997\",\"podcasts\":[{\"title\":\"Song A\"},{\"title\":\"Song B\"}]}\n\n // Decoding\n print('\\nDecoding ...');\n final jsonMap = jsonDecode(jsonString);\n print(jsonMap);\n final historyClone = ListeningHistory.fromJson(jsonMap);\n}\n```\n\n```text\nEncoding: ...\n{user_id: json1997, podcasts: [{title: Song A}, {title: Song B}]}\n{\"user_id\":\"json1997\",\"podcasts\":[{\"title\":\"Song A\"},{\"title\":\"Song B\"}]}\n\nDecoding ...\n{user_id: json1997, podcasts: [{title: Song A}, {title: Song B}]}\n```\n\n========================================\n\nComments:\n- Looking at the method `toJson` of your class `ListeningHistory` that is exactly the output I would expect.\n- thanks for the comment. but I didn't quite understand what you meant. if you meant that I had made a mistake in my toJson implementation in ListeningHistory class, mind elaborating a bit? @DanR\n- I meant to add that `jsonEncode(podcasts)` returns the String \"[ ]\".\n- but having a [ ] as a string is causing a problem on the server side. How can I remove those double quotes ? any ideas ?\n- Instead of a String you need to return an object of type `List`. The function `jsonEncode` (which is just an alias of `json.encode`) is called later to create the String `reqBody`.\n- Thanks, that was the issue. if you send your last comment as an answer, I will gladly accept it. Thanks much. I think I over analyzed it and messed up there. @DanR","metadata":{"transformedAt":"2026-08-18T18:32:29.159Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":8,"totalLines":238,"estimatedTokens":1678}}725{"id":"stack-70034524","source":"stackoverflow","questionId":70034524,"title":"Swagger ui RangeError: Maximum call stack size exceeded in FastAPI","tags":["python","swagger-ui","fastapi"],"text":"Title: Swagger ui RangeError: Maximum call stack size exceeded in FastAPI\nTags: python, swagger-ui, fastapi\nSource: Stack Overflow\n\nQuestion:\nIn my `FastAPI` project's Swagger UI, when I execute an API after a while I get this error:\n\nRangeError: Maximum call stack size exceeded in FastAPI\n\nWhen I check the *Network* tab in browser's inspect, I can see that the status code is 200 and I can view the result response there. But the loading icon is still spinning in Swagger UI and after a while I get that error.\n\n**UPDATE**\n\nAfter lots of investigations, I realized that Swagger UI has issue with large responses (2MB+ in my case ).\n\nI tried this:\n\n```\napp = FastAPI(\n swagger_ui_parameters={'syntaxHighlight.theme': 'obsidian'}\n)\n```\n\nBut it didn't work.\n\nDoes anyone has any idea how to do it right?\n\n========================================\n\nCode:\n```text\napp = FastAPI(\n swagger_ui_parameters={'syntaxHighlight.theme': 'obsidian'}\n)\n```\n\n```text\nFastAPI\n```\n\n```text\napp = FastAPI(\n swagger_ui_parameters={'syntaxHighlight': False}\n)\n```\n\n========================================\n\nComments:\n- I am getting same. did you get any solution?\n- @UpasanaMittal The solution I suggest works now in new versions of FastAPI\n- Thanks. Setting `swagger_ui_parameters={'syntaxHighlight': False}`worked for me. I think you can move your updated information into an answer to this question.","metadata":{"transformedAt":"2026-08-18T18:32:29.159Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":3,"totalLines":52,"estimatedTokens":349}}726{"id":"stack-68675594","source":"stackoverflow","questionId":68675594,"title":"Raw SQL with FastApi and SqlAlchemy (get all columns)","tags":["sqlalchemy","fastapi","feature-engineering"],"text":"Title: Raw SQL with FastApi and SqlAlchemy (get all columns)\nTags: sqlalchemy, fastapi, feature-engineering\nSource: Stack Overflow\n\nQuestion:\nI have a simple FastApi endpoint that connects to a MySQL database using SqlAlchemy (based of the tutorial: https://fastapi.tiangolo.com/tutorial/sql-databases/)\n\nI create a session using:\n\n```\nengine = create_engine(\n SQLALCHEMY_DATABASE_URL\n)\nSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)\n```\n\nI create the dependency:\n\n```\ndef get_db():\n db = SessionLocal()\n try:\n yield db\n finally:\n db.close()\n```\n\nIn my route I want to execute an arbitrary SQL statement but I am not sure how to handle session, connection, cursor etc. correctly (including closing) which I learned the hard way is super important for correct performance\n\n```\n@app.get(\"/get_data\")\ndef get_data(db: Session = Depends(get_db)):\n ???\n```\n\nUltimately the reason for this is that my table contains machine learning features with columns that are undetermined beforehand. If there is a way to define a Base model with \"all columns\" that would work too, but I couldnt find that either.\n\n========================================\n\nTop Answer:\n```\nimport pymysql, pandas as pd\n\nengine = create_engine('mysql+pymysql://'+uname+':'+password+'@'+server+':'+port+'/'+db) \ncon = engine.connect()\ndf = pd.read_sql('SELECT schema_name FROM information_schema.schemata', con)\nreturn df\n```\n\n========================================\n\nCode:\n```text\nengine = create_engine(\n SQLALCHEMY_DATABASE_URL\n)\nSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)\n```\n\n```text\ndef get_db():\n db = SessionLocal()\n try:\n yield db\n finally:\n db.close()\n```\n\n```text\n@app.get(\"/get_data\")\ndef get_data(db: Session = Depends(get_db)):\n ???\n```\n\n```text\ndatabase = databases.Database(DATABASE_URL)\n \n@app.get(\"/read_db\")\nasync def read_db():\n data = await database.fetch_all(\"SELECT * FROM USER_TABLE\")\n return data\n```\n\n```text\nimport pymysql, pandas as pd\n\n\nengine = create_engine('mysql+pymysql://'+uname+':'+password+'@'+server+':'+port+'/'+db) \ncon = engine.connect()\ndf = pd.read_sql('SELECT schema_name FROM information_schema.schemata', con)\nreturn df\n```\n\n========================================\n\nComments:\n- is it possible to connect to Microsoft SQL Server using databases? I googled but did not get a definitive answer. I tried using following URL but it did not work. Following works well if I use it directly with SQLAlchemy without databases library. DATABASE_URL = f\"mssql+pyodbc://{settings.DATABASE_USER}:{settings.DATABASE‌​_PASSWORD}@{settings‌​.DATABASE_HOSTNAME}/‌​{settings.DATABASE_N‌​AME}?driver=ODBC+Dri‌​ver+17+for+SQL+Serve‌​r\"","metadata":{"transformedAt":"2026-08-18T18:32:29.159Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":5,"totalLines":97,"estimatedTokens":697}}727{"id":"stack-63673223","source":"stackoverflow","questionId":63673223,"title":"Build API using FastAPI for Classification Model produced using pycaret","tags":["python","machine-learning","production","fastapi","pycaret"],"text":"Title: Build API using FastAPI for Classification Model produced using pycaret\nTags: python, machine-learning, production, fastapi, pycaret\nSource: Stack Overflow\n\nQuestion:\nI'm using pycaret as my ML workflow, I tried to create an API using FastAPI. This is my first time playing into production level, so I'm bit confused about API\n\nI have 10 features; age: float, live_province: str, live_city: str, live_area_big: str, live_area_small: str, sex: float, marital: float, bank: str, salary: float, amount: float and a label which it contains the binary value (0 and 1).\n\nThis is what my script for building the API\n\n```\nfrom pydantic import BaseModel\nimport numpy as np\nfrom pycaret.classification import *\n\nimport uvicorn\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\nmodel = load_model('catboost_cm_creditable')\n\nclass Data(BaseModel):\n age: float\n live_province: str\n live_city: str\n live_area_big: str\n live_area_small: str\n sex: float\n marital: float\n bank: str\n salary: float\n amount: float\n\ninput_dict = Data\n\n@app.post(\"/predict\")\ndef predict(model, input_dict):\n predictions_df = predict_model(estimator=model, data=input_dict)\n predictions = predictions_df['Score'][0]\n return predictions\n```\n\nWhen I tried to run `uvicorn script:app` and went to the documentation I can't find the parameter for my features, the parameters only show model and input_dict\nhttps://i.sstatic.net/ex4og.png\n\nHow to take my Features onto Parameters in the API?\n\n========================================\n\nTop Answer:\nYour problem is with the definition of the API's function. You added an argument for you data input but you didn't tell FastAPI it's type.\nAlso I assume that you mean't to use the model that you've loaded globally instead of received it as a parameter. Also you don't need to create a global instance for your input data, as you want to get it from the user.\n\nTherefore, simply change the signature of your function to:\n\n```\ndef predict(input_dict: Data):\n```\n\nand remove the line:\n\n```\ninput_dict = Data\n```\n\n(Which just creates an Alias to your class `Data`, named `input_dict`)\n\nYou'll end up with:\n\n```\napp = FastAPI()\n\nmodel = load_model('catboost_cm_creditable')\n\nclass Data(BaseModel):\n age: float\n live_province: str\n live_city: str\n live_area_big: str\n live_area_small: str\n sex: float\n marital: float\n bank: str\n salary: float\n amount: float\n\n@app.post(\"/predict\")\ndef predict(input_dict: Data):\n predictions_df = predict_model(estimator=model, data=input_dict)\n predictions = predictions_df['Score'][0]\n return predictions\n```\n\nAlso, I would recommend changing the name of the class `Data` to something more clear and easier to understand, even `DataUnit` would be better in my opinion as `Data` is too general.\n\n========================================\n\nCode:\n```py\nfrom pydantic import BaseModel\nimport numpy as np\nfrom pycaret.classification import *\n\nimport uvicorn\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\nmodel = load_model('catboost_cm_creditable')\n\nclass Data(BaseModel):\n age: float\n live_province: str\n live_city: str\n live_area_big: str\n live_area_small: str\n sex: float\n marital: float\n bank: str\n salary: float\n amount: float\n\ninput_dict = Data\n\n@app.post(\"/predict\")\ndef predict(model, input_dict):\n predictions_df = predict_model(estimator=model, data=input_dict)\n predictions = predictions_df['Score'][0]\n return predictions\n```\n\n```text\nuvicorn script:app\n```\n\n```text\ndef some_function(price: int) ->int:\n return price\n```\n\n```text\nfrom fastapi import Depends\n\nclass Data(BaseModel):\n age: float\n live_province: str\n live_city: str\n live_area_big: str\n live_area_small: str\n sex: float\n marital: float\n bank: str\n salary: float\n amount: float\n\n\n@app.post(\"/predict\")\ndef predict(data: Data = Depends()):\n predictions_df = predict_model(estimator=model, data=data)\n predictions = predictions_df[\"Score\"][0]\n return predictions\n```\n\n```text\nclass Data\n```\n\n```text\n@dataclass\n```\n\n```text\ndef predict(input_dict: Data):\n```\n\n```text\ninput_dict = Data\n```\n\n```text\napp = FastAPI()\n\nmodel = load_model('catboost_cm_creditable')\n\nclass Data(BaseModel):\n age: float\n live_province: str\n live_city: str\n live_area_big: str\n live_area_small: str\n sex: float\n marital: float\n bank: str\n salary: float\n amount: float\n\n@app.post(\"/predict\")\ndef predict(input_dict: Data):\n predictions_df = predict_model(estimator=model, data=input_dict)\n predictions = predictions_df['Score'][0]\n return predictions\n```\n\n```text\nData\n```\n\n```text\ninput_dict\n```\n\n```text\nData\n```\n\n```text\nDataUnit\n```\n\n```text\nData\n```\n\n========================================\n\nComments:\n- Hi, I tried this and my API works perfectly but when I tried to run the API it returns `500 Internal Server Error ERROR: Exception in ASGI application` I believe because I did not call the model correctly, but I can't figured out the correct ways to load the pickle file. Can you help me?\n- @ebuzz168 can you provide a traceback ?\n- it throws `AttributeError: 'Data' object has no attribute 'columns'` error, this is not related to the question, you should ask a new question, but as far as i understand you are doing `data.columns = [str(i) for i in data.columns]` , which is seems weird for me because, but you are just reiterating it and the error says Data object has no attr columns, it does hasattr(Data \"columns\") underneath.","metadata":{"transformedAt":"2026-08-18T18:32:29.159Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":14,"totalLines":231,"estimatedTokens":1360}}728{"id":"stack-75449889","source":"stackoverflow","questionId":75449889,"title":"Check if request is coming from Swagger UI","tags":["python","request","fastapi","starlette"],"text":"Title: Check if request is coming from Swagger UI\nTags: python, request, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nUsing `Python` and `Starlette` or `FastAPI`, How can I know if the request is coming from the Swagger UI or anywhere else (Postman, Frontend app)?\n\nI tried to see if there's something in `Request` object which I can use:\n\n```\nfrom fastapi import Request\n\n@app.get(\"/\")\nasync def root(request: Request):\n # request.client.host just returns some IP\n # request.headers doesn't contain any hint\n # request.scope ?\n request_from_swagger = request.hints_on_whether_request_is_coming_from_swagger_ui\n if request_from_swagger:\n return {\"message\": \"Hello Swagger UI\"}\n\n return {\"message\": \"Hello World\"}\n```\n\nI need to take some actions based of that. So is there anyway I can tell, whether the request is coming from the Swagger UI?\n\n========================================\n\nCode:\n```text\nfrom fastapi import Request\n\n@app.get(\"/\")\nasync def root(request: Request):\n # request.client.host just returns some IP\n # request.headers doesn't contain any hint\n # request.scope ?\n request_from_swagger = request.hints_on_whether_request_is_coming_from_swagger_ui\n if request_from_swagger:\n return {\"message\": \"Hello Swagger UI\"}\n\n return {\"message\": \"Hello World\"}\n```\n\n```text\nPython\n```\n\n```text\nStarlette\n```\n\n```text\nFastAPI\n```\n\n```text\nRequest\n```\n\n```text\nfrom fastapi import Request\n\n@app.get(\"/\")\nasync def root(request: Request):\n request_from_swagger = request.headers['referer'].endswith(app.docs_url)\n if request_from_swagger:\n return {\"message\": \"Hello Swagger UI\"}\n\n return {\"message\": \"Hello World\"}\n```\n\n========================================\n\nComments:\n- Why don't you use the `Referer` key in the headers ? It will contain the url of the page.","metadata":{"transformedAt":"2026-08-18T18:32:29.159Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":6,"totalLines":76,"estimatedTokens":455}}729{"id":"stack-74785215","source":"stackoverflow","questionId":74785215,"title":"How to yield a db connection in a python sqlalchemy function similar to how it is done in FastAPI?","tags":["python","sqlalchemy","fastapi","yield"],"text":"Title: How to yield a db connection in a python sqlalchemy function similar to how it is done in FastAPI?\nTags: python, sqlalchemy, fastapi, yield\nSource: Stack Overflow\n\nQuestion:\nIn FastAPI I had the following function that I used to open and close a DB session:\n\n```\ndef get_db():\n try:\n db = SessionLocal()\n yield db\n finally:\n db.close()\n```\n\nAnd within the routes of my API I would do something like that:\n\n```\n@router.get(\"/\")\nasync def read_all_events(user: dict = Depends(get_current_user), db: Session = Depends(get_db)):\n logger.info(\"API read_all_events\")\n if user is None:\n raise http_user_credentials_not_valid_exception()\n return db.query(models.Events).all()\n```\n\nYou can see that I am injectin the session in the api call.\n\nSo now i want to do something similar within a python function:\n\n```\ndef do_something():\n #get person data from database\n #play with person data\n #save new person data in database\n #get cars data from database\n```\n\nSo i am wondering if I should use the same approach than in FastAPI (i do not know how) or if i just should be openning and clossing the connection manually like that:\n\n```\ndef do_something():\n try:\n db = SessionLocal()\n yield db\n \n #get person data from database\n #play with person data\n #save new person data in database\n #get cars data from database\n finally:\n db.close()\n```\n\nThanks\n\n========================================\n\nCode:\n```py\ndef get_db():\n try:\n db = SessionLocal()\n yield db\n finally:\n db.close()\n```\n\n```text\n@router.get(\"/\")\nasync def read_all_events(user: dict = Depends(get_current_user), db: Session = Depends(get_db)):\n logger.info(\"API read_all_events\")\n if user is None:\n raise http_user_credentials_not_valid_exception()\n return db.query(models.Events).all()\n```\n\n```text\ndef do_something():\n #get person data from database\n #play with person data\n #save new person data in database\n #get cars data from database\n```\n\n```text\ndef do_something():\n try:\n db = SessionLocal()\n yield db\n \n #get person data from database\n #play with person data\n #save new person data in database\n #get cars data from database\n finally:\n db.close()\n```\n\n```text\ndef do_something():\n db = SessionLocal()\n event = db.query(models.Events).first()\n db.delete(event)\n db.commit()\n db.close()\n```\n\n```text\nDepends(get_db)\n```\n\n```text\ndb.close()\n```\n\n```text\ndb = SessionLocal()\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.159Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":8,"totalLines":120,"estimatedTokens":615}}730{"id":"stack-76522582","source":"stackoverflow","questionId":76522582,"title":"How to pass parameters to an endpoint using `add_route()` in FastAPI?","tags":["python","fastapi","starlette"],"text":"Title: How to pass parameters to an endpoint using `add_route()` in FastAPI?\nTags: python, fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nI'm developing a simple application with FastAPI.\n\nI need a function to be called as endpoint for a certain route. Everything works just fine with the function's default parameters, but wheels come off the bus as soon as I try to override one of them.\n\nExample. This works just fine:\n\n```\nasync def my_function(request=Request, clientname='my_client'):\n print(request.method)\n print(clientname)\n ## DO OTHER STUFF...\n return SOMETHING\n\nprivate_router.add_route('/api/my/test/route', my_function, ['GET'])\n```\n\nThis returns an error instead:\n\n```\nasync def my_function(request=Request, clientname='my_client'):\n print(request.method)\n print(clientname)\n ## DO OTHER STUFF...\n return SOMETHING\n\nprivate_router.add_route('/api/my/test/route', my_function(clientname='my_other_client'), ['GET'])\n```\n\nThe Error:\n\n```\nINFO: 127.0.0.1:60005 - \"GET /api/my/test/route HTTP/1.1\" 500 Internal Server Error\nERROR: Exception in ASGI application\nTraceback (most recent call last):\n...\n...\nTypeError: 'coroutine' object is not callable\n```\n\nThe only difference is I'm trying to override the `clientname` value in `my_function`.\n\nIt is apparent that this isn't the right syntax but I looked everywhere and I'm just appalled that the documentation about the `add_route` method is nowhere to be found.\n\nIs anyone able to point me to the right way to do this supposedly simple thing?\n\nThanks!\n\n========================================\n\nCode:\n```py\nasync def my_function(request=Request, clientname='my_client'):\n print(request.method)\n print(clientname)\n ## DO OTHER STUFF...\n return SOMETHING\n\nprivate_router.add_route('/api/my/test/route', my_function, ['GET'])\n```\n\n```py\nasync def my_function(request=Request, clientname='my_client'):\n print(request.method)\n print(clientname)\n ## DO OTHER STUFF...\n return SOMETHING\n\nprivate_router.add_route('/api/my/test/route', my_function(clientname='my_other_client'), ['GET'])\n```\n\n```bash\nINFO: 127.0.0.1:60005 - \"GET /api/my/test/route HTTP/1.1\" 500 Internal Server Error\nERROR: Exception in ASGI application\nTraceback (most recent call last):\n...\n...\nTypeError: 'coroutine' object is not callable\n```\n\n```text\nclientname\n```\n\n```text\nmy_function\n```\n\n```text\nadd_route\n```\n\n```py\ndef partial(func, /, *args, **keywords):\n def newfunc(*fargs, **fkeywords):\n newkeywords = {**keywords, **fkeywords}\n return func(*args, *fargs, **newkeywords)\n newfunc.func = func\n newfunc.args = args\n newfunc.keywords = keywords\n return newfunc\n```\n\n```py\nfrom fastapi import FastAPI, Request, APIRouter, Response\nfrom functools import partial\n\n\nasync def my_endpoint(request: Request, client_name: str ='my_client'):\n print(request.method)\n return Response(client_name)\n\n\napp = FastAPI()\nrouter = APIRouter()\nrouter.add_route('/', partial(my_endpoint, client_name='my_other_client'), ['GET']) \napp.include_router(router)\n```\n\n```py\nfrom fastapi import FastAPI, Request, APIRouter, Response\n\ndef my_endpoint(client_name: str ='my_client'): \n async def newfunc(request: Request): \n print(request.method)\n return Response(client_name)\n return newfunc\n\napp = FastAPI()\nrouter = APIRouter()\nrouter.add_route('/', my_endpoint(client_name='my_other_client'), ['GET']) \napp.include_router(router)\n```\n\n```text\nfunctools.partial\n```\n\n```text\nfunctools.partial\n```\n\n```text\nfunctools.partial(func, /, *args, **keywords)\n```\n\n```text\nadd_route()\n```\n\n```text\nRoute\n```\n\n```text\nendpoint_handler\n```\n\n```text\nadd_route()\n```\n\n```text\nfunctools.partial\n```\n\n```text\nResponse\n```\n\n```text\nJSONResponse\n```\n\n```text\nstr\n```\n\n```text\ndict\n```\n\n```text\nreturn client_name\n```\n\n```text\nTypeError: 'str' object is not callable\n```\n\n```text\nTypeError: 'dict' object is not callable\n```\n\n```text\nResponse\n```\n\n```text\nfunctools.partial\n```\n\n```text\nadd_api_route()\n```\n\n```text\nadd_route()\n```\n\n```text\ndependencies\n```\n\n========================================\n\nComments:\n- You're *calling* the (endpoint) function, not registering it with a predetermined parameter - in that case you'd probaly want a helper function that returns an inner function - which is the function that should be registered to the endpoint (i.e. something like `def client(client_name): async def wrapped(): print(client_name) ... return wrapped`); this will bind the given `client_name` to the function that gets returned (which has the given values in the scope). This also matches that the API requirement for the function is (no parameters), since client_name is given when creating the api.\n- Thanks @MatsLindh, it's still not clear to me how to override that parameter in the route definition, once I wrapped the function. What the add_route definition should look like in my example? My need is to be able to pass different `clientname` values to different routes.\n- Hi @Chris, I tried both `:` and `=` the function works both ways. It returns the expected payload when called as in my first example.\n- Used Option 2 ant it works perfectly! Thank you so much @Chris! I still cannot wrap my head around the fact that it's impossible to find any documentation about this, I assume, quite common need...","metadata":{"transformedAt":"2026-08-18T18:32:29.159Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":29,"totalLines":225,"estimatedTokens":1327}}731{"id":"stack-69355510","source":"stackoverflow","questionId":69355510,"title":"FastAPI conflict path parameter in endpoint - good practices?","tags":["python","rest","backend","fastapi","endpoint"],"text":"Title: FastAPI conflict path parameter in endpoint - good practices?\nTags: python, rest, backend, fastapi, endpoint\nSource: Stack Overflow\n\nQuestion:\nI am creating 2 GET methods for a resource `student` using FastAPI. I'm looking to GET a `student` in 2 ways: by `student_id` or by `student_name`.\n\nThe issue is that, I initially created the 2 endpoints as follows\n\n```\n@app.get(\"/student/{student_name}\", response_model=schemas.Student, status_code=200)\ndef get_student_by_name(student_name: str, db: Session = Depends(get_db)):\n db_student = crud.get_student_by_name(db, student_name)\n if db_student is None:\n raise HTTPException(status_code=404, detail=\"Student not found\")\n return db_student\n\n@app.get(\"/student/{student_id}\", response_model=schemas.Student, status_code=200)\ndef get_student_by_id(student_id: int, db: Session = Depends(get_db)):\n db_student = crud.get_student_by_id(db, student_id)\n if db_student is None:\n raise HTTPException(status_code=404, detail=\"Student not found\")\n return db_student\n```\n\nThe problem is that the endpoint names are conflicting with each other, it is both `/student` followed by a parameter and only one of them could work - in this case only `/student/{student_name}` because it is defined in the front. So I came up with this simple workaround by adding a bit more to the endpoint names:\n\n```\n@app.get(\"/student/{student_name}\", response_model=schemas.Student, status_code=200)\ndef get_student_by_name(student_name: str, db: Session = Depends(get_db)):\n db_student = crud.get_student_by_name(db, student_name)\n if db_student is None:\n raise HTTPException(status_code=404, detail=\"Student not found\")\n return db_student\n\n@app.get(\"/student/byid/{student_id}\", response_model=schemas.Student, status_code=200)\ndef get_student_by_id(student_id: int, db: Session = Depends(get_db)):\n db_student = crud.get_student_by_id(db, student_id)\n if db_student is None:\n raise HTTPException(status_code=404, detail=\"Student not found\")\n return db_student\n```\n\nI added `/byid` to the endpoint name of the `get_student)by_id` method. While both endpoints could work now, I am wondering if this is considered a good practice? WHat would be the best practice when one resource needed to be queried with a single path parameter to differentiate the endpoint names?\n\n========================================\n\nTop Answer:\nBeen having this same issue for hours now, and just found a perfect solution by pure dumb luck while experimenting:\n\n```\n@app.get(\"/student/{student_name:str}\", response_model=schemas.Student, status_code=200)\ndef get_student_by_name(student_name: str, db: Session = Depends(get_db)):\n ...\n\n@app.get(\"/student/{student_id:int}\", response_model=schemas.Student, status_code=200)\ndef get_student_by_id(student_id: int, db: Session = Depends(get_db)):\n ...\n```\n\nAdding these \"convertors\" to your path will route your requests to the correct endpoint based on the specified type :)\n\nI was able to find the docs for this in Starlette, which I'm not too familiar with, but FastAPI is built on top of it. https://www.starlette.io/routing/\n\n========================================\n\nCode:\n```py\n@app.get(\"/student/{student_name}\", response_model=schemas.Student, status_code=200)\ndef get_student_by_name(student_name: str, db: Session = Depends(get_db)):\n db_student = crud.get_student_by_name(db, student_name)\n if db_student is None:\n raise HTTPException(status_code=404, detail=\"Student not found\")\n return db_student\n\n\n@app.get(\"/student/{student_id}\", response_model=schemas.Student, status_code=200)\ndef get_student_by_id(student_id: int, db: Session = Depends(get_db)):\n db_student = crud.get_student_by_id(db, student_id)\n if db_student is None:\n raise HTTPException(status_code=404, detail=\"Student not found\")\n return db_student\n```\n\n```py\n@app.get(\"/student/{student_name}\", response_model=schemas.Student, status_code=200)\ndef get_student_by_name(student_name: str, db: Session = Depends(get_db)):\n db_student = crud.get_student_by_name(db, student_name)\n if db_student is None:\n raise HTTPException(status_code=404, detail=\"Student not found\")\n return db_student\n\n\n@app.get(\"/student/byid/{student_id}\", response_model=schemas.Student, status_code=200)\ndef get_student_by_id(student_id: int, db: Session = Depends(get_db)):\n db_student = crud.get_student_by_id(db, student_id)\n if db_student is None:\n raise HTTPException(status_code=404, detail=\"Student not found\")\n return db_student\n```\n\n```text\nstudent\n```\n\n```text\nstudent\n```\n\n```text\nstudent_id\n```\n\n```text\nstudent_name\n```\n\n```text\n/student\n```\n\n```text\n/student/{student_name}\n```\n\n```text\n/byid\n```\n\n```text\nget_student)by_id\n```\n\n```text\n@app.get(\"/student/{student_id}\", response_model=schemas.Student, status_code=200)\ndef get_student(student_id: str, db: Session = Depends(get_db)):\n db_student = crud.get_student_by_id(db, student_id)\n if db_student is None:\n raise HTTPException(status_code=404, detail=\"Student not found\")\n return db_student\n\n\n# use search criterias as query params\n@app.get(\"/student/\", response_model=List[schemas.Student], status_code=200)\ndef get_students(student_name: string = None, db: Session = Depends(get_db)):\n # Query inside your crud file\n query = db.query(Student)\n if student_name:\n # if you want to search similar items\n query = query.filter(Student.name.like(f\"%{student_name}%\"))\n # if you want to search an exact match\n query = query.filter(Student.name == student_name)\n \n return query.all()\n```\n\n```py\n@app.get(\"/student/{student_id}\",\n response_model=schemas.Student,\n status_code=200)\ndef get_student_by_id(\n student_id: int = Path(\n title=\"The ID of the student to get\"),\n db: Session = Depends(get_db)):\n db_student = crud.get_student_by_id(db, student_id)\n if db_student is None:\n raise HTTPException(status_code=404, detail=\"Student not found\")\n return db_student\n...\n\n\n@app.get(\"/student/{student_name}\",\n response_model=schemas.Student,\n status_code=200)\ndef get_student_by_name(\n student_name: str,\n db: Session = Depends(get_db)):\n db_student = crud.get_student_by_name(db, student_name)\n if db_student is None:\n raise HTTPException(status_code=404, detail=\"Student not found\")\n return db_student\n```\n\n```py\n@app.get(\"/student/{student_name_or_id}\",\n response_model=schemas.Student,\n status_code=200)\nasync def get_student(\n student_name_or_id: str = Path(\n title=\"The ID or name of the student to get\"),\n db: Session = Depends(get_db)):\n if student_name_or_id.isdigit():\n db_student = crud.get_student_by_id(db, int(student_name_or_id))\n else:\n db_student = crud.get_student_by_name(db, student_name_or_id)\n if db_student is None:\n raise HTTPException(status_code=404, detail=\"Student not found\")\n return db_student\n```\n\n```text\nint\n```\n\n```text\nint\n```\n\n```text\n/2022/08\n```\n\n```text\n/python/faster-fastapi\n```\n\n```text\n@app.get(\"/student/{student_name:str}\", response_model=schemas.Student, status_code=200)\ndef get_student_by_name(student_name: str, db: Session = Depends(get_db)):\n ...\n\n@app.get(\"/student/{student_id:int}\", response_model=schemas.Student, status_code=200)\ndef get_student_by_id(student_id: int, db: Session = Depends(get_db)):\n ...\n```\n\n```text\n/student?student_id=10\n\n/student?student_name=Mike\n```\n\n```text\n@app.get(\"/student\", response_model=schemas.Student, status_code=200)\ndef get_student(student_id: int = None, student_name: str = None, db: Session = Depends(get_db)):\n if student_id:\n db_student = crud.get_student_by_id(db, student_id)\n elif student_name:\n db_student = crud.get_student_by_name(db, student_name)\n else:\n raise HTTPException(status_code=400, detail=\"Either student_id or student_name must be provided\")\n\n if db_student is None:\n raise HTTPException(status_code=404, detail=\"Student not found\")\n \n return db_student\n```\n\n========================================\n\nComments:\n- Why you not use Query Parameter for get students data filter by name and id ?\n- Note that the **order** in which endpoints are evaluated **matters**. You might find this answer helpful as well.","metadata":{"transformedAt":"2026-08-18T18:32:29.159Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":20,"totalLines":253,"estimatedTokens":2085}}732{"id":"stack-76056906","source":"stackoverflow","questionId":76056906,"title":"Secure route in FastAPI","tags":["python","flask","fastapi"],"text":"Title: Secure route in FastAPI\nTags: python, flask, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have a Flask-based backend REST API and I want to migrate to FastAPI. However, I am not sure how to implement secure routes and create access tokens in FastAPI.\n\nIn Flask, we have methods from the flask_jwt_extended library such as:\n@jwt_required() decorator for secure routes\ncreate_access_token() function for creating JWT tokens.\n\nDoes FastAPI have a similar feature or capability, or how can I implement this in FastAPI?\n\nThank you in advance.\n\nHere is an example implementation of secure route and create access token in Flask:\n\n```\nimport hashlib\nimport traceback\nfrom datetime import timedelta\nfrom http import HTTPStatus\nfrom flask import Flask, jsonify, request\nfrom flask_jwt_extended import JWTManager, jwt_required, get_jwt_identity, create_access_token\n\napp = Flask(__name__)\njwt = JWTManager(app)\napp.config[\"JWT_SECRET_KEY\"] = \"very-secret1234567890\"\napp.config[\"JWT_ACCESS_TOKEN_EXPIRES\"] = timedelta(minutes=15)\napp.config[\"JWT_REFRESH_TOKEN_EXPIRES\"] = timedelta(days=30)\nhost = \"localhost\"\nport = 5000\ntest_password = \"test_password\"\ndb = [\n {\n \"username\": \"test_user\",\n \"email\": \"test_email.gmail.com\",\n \"password\": hashlib.sha256(test_password.encode()).hexdigest()\n }\n]\n\n@app.route('/login', methods=['POST'])\ndef login():\n try:\n json_data = request.get_json()\n email = json_data.get(\"email\")\n password = json_data.get(\"password\")\n if not email or not password:\n response = jsonify(error=\"'email' and 'password' are required\")\n return response, HTTPStatus.BAD_REQUEST\n # Check if email exists in DB\n user_result = [user for user in db if user[\"email\"].lower() == email.lower()]\n # Check if the password is correct\n encoded_password = hashlib.sha256(password.encode()).hexdigest()\n if not user_result or user_result[0][\"password\"] != encoded_password:\n response = jsonify(error=\"Wrong credentials\")\n return response, HTTPStatus.BAD_REQUEST\n user = user_result[0]\n # Generate JWT token and return it\n access_token = create_access_token(identity=user[\"username\"])\n response = jsonify(username=user[\"username\"], token=access_token)\n return response, HTTPStatus.OK\n except Exception as e:\n print(f\"Error: {e}\")\n print(traceback.format_exc())\n response = jsonify(result={\"error\": \"Server error\"})\n return response, HTTPStatus.INTERNAL_SERVER_ERROR\n\n@app.route('/secured_page', methods=['GET'])\n@jwt_required()\ndef __create_participant():\n try:\n response = jsonify(message=\"You are logged in as {}\".format(get_jwt_identity()))\n return response, HTTPStatus.OK\n except Exception as e:\n print(f\"Error: {e}\")\n print(traceback.format_exc())\n response = jsonify(result={\"error\": \"Server error\"})\n return response, HTTPStatus.INTERNAL_SERVER_ERROR\n\nif __name__ == '__main__':\n app.run(host=host, port=port, debug=True)\n```\n\n========================================\n\nCode:\n```text\nimport hashlib\nimport traceback\nfrom datetime import timedelta\nfrom http import HTTPStatus\nfrom flask import Flask, jsonify, request\nfrom flask_jwt_extended import JWTManager, jwt_required, get_jwt_identity, create_access_token\n\napp = Flask(__name__)\njwt = JWTManager(app)\napp.config[\"JWT_SECRET_KEY\"] = \"very-secret1234567890\"\napp.config[\"JWT_ACCESS_TOKEN_EXPIRES\"] = timedelta(minutes=15)\napp.config[\"JWT_REFRESH_TOKEN_EXPIRES\"] = timedelta(days=30)\nhost = \"localhost\"\nport = 5000\ntest_password = \"test_password\"\ndb = [\n {\n \"username\": \"test_user\",\n \"email\": \"test_email.gmail.com\",\n \"password\": hashlib.sha256(test_password.encode()).hexdigest()\n }\n]\n\n\n@app.route('/login', methods=['POST'])\ndef login():\n try:\n json_data = request.get_json()\n email = json_data.get(\"email\")\n password = json_data.get(\"password\")\n if not email or not password:\n response = jsonify(error=\"'email' and 'password' are required\")\n return response, HTTPStatus.BAD_REQUEST\n # Check if email exists in DB\n user_result = [user for user in db if user[\"email\"].lower() == email.lower()]\n # Check if the password is correct\n encoded_password = hashlib.sha256(password.encode()).hexdigest()\n if not user_result or user_result[0][\"password\"] != encoded_password:\n response = jsonify(error=\"Wrong credentials\")\n return response, HTTPStatus.BAD_REQUEST\n user = user_result[0]\n # Generate JWT token and return it\n access_token = create_access_token(identity=user[\"username\"])\n response = jsonify(username=user[\"username\"], token=access_token)\n return response, HTTPStatus.OK\n except Exception as e:\n print(f\"Error: {e}\")\n print(traceback.format_exc())\n response = jsonify(result={\"error\": \"Server error\"})\n return response, HTTPStatus.INTERNAL_SERVER_ERROR\n\n\n@app.route('/secured_page', methods=['GET'])\n@jwt_required()\ndef __create_participant():\n try:\n response = jsonify(message=\"You are logged in as {}\".format(get_jwt_identity()))\n return response, HTTPStatus.OK\n except Exception as e:\n print(f\"Error: {e}\")\n print(traceback.format_exc())\n response = jsonify(result={\"error\": \"Server error\"})\n return response, HTTPStatus.INTERNAL_SERVER_ERROR\n\n\nif __name__ == '__main__':\n app.run(host=host, port=port, debug=True)\n```\n\n```text\nfrom jose import JWTError, jwt\nfrom datetime import datetime, timedelta\n\ndef create_access_token(data: dict):\n to_encode = data.copy()\n expire = datetime.utcnow() + timedelta(minutes=15)\n to_encode.update({\"exp\": expire})\n encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)\n return encoded_jwt\n```\n\n```text\nfrom fastapi import Depends, HTTPException, status\nfrom fastapi.security import OAuth2PasswordBearer\nfrom jose import JWTError, jwt\n\noauth2_scheme = OAuth2PasswordBearer(tokenUrl=\"token\")\n\nasync def jwt_required(token: str = Depends(oauth2_scheme)):\n credentials_exception = HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Could not validate credentials\",\n headers={\"WWW-Authenticate\": \"Bearer\"},\n )\n try:\n payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])\n username: str = payload.get(\"sub\")\n if username is None:\n raise credentials_exception\n except JWTError:\n raise credentials_exception\n user = get_user(username=username)\n if user is None:\n raise credentials_exception\n\n@app.get('/secured_page', dependencies=[jwt_required])\ndef __create_participant():\n...\n```\n\n```text\njwt_required\n```\n\n```text\ncreate_access_token\n```\n\n========================================\n\nComments:\n- btw JWT is not very secure\n- Does this answer your question? Redirect to login page if user not logged in using FastAPI-Login package","metadata":{"transformedAt":"2026-08-18T18:32:29.159Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":211,"estimatedTokens":1704}}733{"id":"stack-75510207","source":"stackoverflow","questionId":75510207,"title":"How can I use \"206 Partial Content\" response in a Video component for use in any browser?","tags":["python-3.x","video-streaming","fastapi"],"text":"Title: How can I use \"206 Partial Content\" response in a Video component for use in any browser?\nTags: python-3.x, video-streaming, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm using the Fast API framework, I'm trying to use it as a stream type response to visualize the videos by loading parts.\n\n```\n@router.get(\"/video/{name_video}\")\nasync def get_video(name_video: str, range: str = Header(None)):\n # bytes=0-\n start, end = range.replace(\"bytes=\", \"\").split(\"-\")\n start = int(start)\n end = int(start + PORTION_SIZE)\n\n with open(current_directory + name_video, \"rb\") as myfile:\n myfile.seek(start)\n data = myfile.read(end - start)\n size_video = str(os.path.getsize(current_directory + name_video))\n\n headers = {\n 'Content-Range': f'bytes {str(start)}-{str(end)}/{size_video}',\n 'Accept-Ranges': 'bytes'\n }\n return Response(content=data, status_code=206, headers=headers, media_type=\"video/mp4\")\n```\n\nIt happens that it responds with blob data type and I try to use it in the video component as is:\n\n```\n\n \n\n```\n\nI have tried to use it in browsers like Google Chrome and Edge and they do not work, the curious thing is that with Mozilla FireFox if it works. if you have to use request using js and then insert it there would be no problem, the question is that I do not know how to do it.\n\nI would like to know in general how it would work this way and if there is a charitable soul that optimizes the response using this procedure I would be very happy.\n\nThank you very much for your help.\n\n========================================\n\nCode:\n```text\n@router.get(\"/video/{name_video}\")\nasync def get_video(name_video: str, range: str = Header(None)):\n # bytes=0-\n start, end = range.replace(\"bytes=\", \"\").split(\"-\")\n start = int(start)\n end = int(start + PORTION_SIZE)\n\n with open(current_directory + name_video, \"rb\") as myfile:\n myfile.seek(start)\n data = myfile.read(end - start)\n size_video = str(os.path.getsize(current_directory + name_video))\n\n headers = {\n 'Content-Range': f'bytes {str(start)}-{str(end)}/{size_video}',\n 'Accept-Ranges': 'bytes'\n }\n return Response(content=data, status_code=206, headers=headers, media_type=\"video/mp4\")\n```\n\n```text\n<video width=\"1200\" controls>\n <source src=\"http://127.0.0.1:8000/api/stream_video/video_tet.mp4\" type=\"video/mp4\">\n</video>\n```\n\n```text\nimport os\nfrom typing import BinaryIO\n\nfrom fastapi import FastAPI, HTTPException, Request, status\nfrom fastapi.responses import StreamingResponse\n\n\ndef send_bytes_range_requests(\n file_obj: BinaryIO, start: int, end: int, chunk_size: int = 10_000\n):\n \"\"\"Send a file in chunks using Range Requests specification RFC7233\n\n `start` and `end` parameters are inclusive due to specification\n \"\"\"\n with file_obj as f:\n f.seek(start)\n while (pos := f.tell()) <= end:\n read_size = min(chunk_size, end + 1 - pos)\n yield f.read(read_size)\n\n\ndef _get_range_header(range_header: str, file_size: int) -> tuple[int, int]:\n def _invalid_range():\n return HTTPException(\n status.HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE,\n detail=f\"Invalid request range (Range:{range_header!r})\",\n )\n\n try:\n h = range_header.replace(\"bytes=\", \"\").split(\"-\")\n start = int(h[0]) if h[0] != \"\" else 0\n end = int(h[1]) if h[1] != \"\" else file_size - 1\n except ValueError:\n raise _invalid_range()\n\n if start > end or start < 0 or end > file_size - 1:\n raise _invalid_range()\n return start, end\n\n\ndef range_requests_response(\n request: Request, file_path: str, content_type: str\n):\n \"\"\"Returns StreamingResponse using Range Requests of a given file\"\"\"\n\n file_size = os.stat(file_path).st_size\n range_header = request.headers.get(\"range\")\n\n headers = {\n \"content-type\": content_type,\n \"accept-ranges\": \"bytes\",\n \"content-encoding\": \"identity\",\n \"content-length\": str(file_size),\n \"access-control-expose-headers\": (\n \"content-type, accept-ranges, content-length, \"\n \"content-range, content-encoding\"\n ),\n }\n start = 0\n end = file_size - 1\n status_code = status.HTTP_200_OK\n\n if range_header is not None:\n start, end = _get_range_header(range_header, file_size)\n size = end - start + 1\n headers[\"content-length\"] = str(size)\n headers[\"content-range\"] = f\"bytes {start}-{end}/{file_size}\"\n status_code = status.HTTP_206_PARTIAL_CONTENT\n\n return StreamingResponse(\n send_bytes_range_requests(open(file_path, mode=\"rb\"), start, end),\n headers=headers,\n status_code=status_code,\n )\n\n\napp = FastAPI()\n\n\n@app.get(\"/video\")\ndef get_video(request: Request):\n return range_requests_response(\n request, file_path=\"path_to_my_video.mp4\", content_type=\"video/mp4\"\n )\n```\n\n```text\nStreamingResponse\n```\n\n```text\nangel-langdon\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.159Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":164,"estimatedTokens":1239}}734{"id":"stack-75476058","source":"stackoverflow","questionId":75476058,"title":"How to implement callback functionality in FastAPI?","tags":["python","callback","fastapi"],"text":"Title: How to implement callback functionality in FastAPI?\nTags: python, callback, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm trying to implement a service that will get a request from an external API, do some work (which might take time) and then return a response to the external API with the parsed data. However I'm at a loss on how to achieve this. I'm using FastAPI as my API service and have been looking at the following documentation: OpenAPI Callbacks\nBy following that documentation I can get the OpenAPI docs looking all pretty and nice. However I'm stumped on how to implement the actual callback and the docs don't have much information about that.\nMy current implementation is as follows:\n\n```\nfrom typing import Union\n\nfrom fastapi import APIRouter, FastAPI\nfrom pydantic import BaseModel, AnyHttpUrl\n\nimport requests\nimport time\n\nfrom threading import Thread\n\napp = FastAPI()\n\nclass Invoice(BaseModel):\n id: str\n title: Union[str, None] = None\n customer: str\n total: float\n\nclass InvoiceEvent(BaseModel):\n description: str\n paid: bool\n\nclass InvoiceEventReceived(BaseModel):\n ok: bool\n\ninvoices_callback_router = APIRouter()\n\n@invoices_callback_router.post(\n \"{$callback_url}/invoices/{$request.body.id}\", response_model=InvoiceEventReceived\n)\ndef invoice_notification(body: InvoiceEvent):\n pass\n\n@app.post(\"/invoices/\", callbacks=invoices_callback_router.routes)\nasync def create_invoice(invoice: Invoice, callback_url: Union[AnyHttpUrl, None] = None):\n # Send the invoice, collect the money, send the notification (the callback)\n thread = Thread(target=do_invoice(invoice, callback_url))\n thread.start()\n return {\"msg\": \"Invoice received\"}\n\ndef do_invoice(invoice: Invoice, callback_url: AnyHttpUrl):\n time.sleep(10)\n url = callback_url + \"/invoices/\" + invoice.id\n json = {\n \"data\": [\"Payment celebration\"],\n }\n requests.post(url=url, json=json)\n```\n\nI thought putting the actual callback in a separate thread might work and that the `{\"msg\": \"Invoice received\"}` would be returned immediately and then 10s later the external api would recieve the result from the `do_invoice` function. But this doesn't seem to be the case so perhaps I'm doing something wrong.\n\nI've also tried putting the logic in the `invoice_notification` function but that doesn't seem to do anything at all.\n\nSo what is the correct to implement a callback like the one I want? Thankful for any help!\n\n========================================\n\nCode:\n```py\nfrom typing import Union\n\nfrom fastapi import APIRouter, FastAPI\nfrom pydantic import BaseModel, AnyHttpUrl\n\nimport requests\nimport time\n\nfrom threading import Thread\n\napp = FastAPI()\n\n\nclass Invoice(BaseModel):\n id: str\n title: Union[str, None] = None\n customer: str\n total: float\n\n\nclass InvoiceEvent(BaseModel):\n description: str\n paid: bool\n\n\nclass InvoiceEventReceived(BaseModel):\n ok: bool\n\n\ninvoices_callback_router = APIRouter()\n\n\n@invoices_callback_router.post(\n \"{$callback_url}/invoices/{$request.body.id}\", response_model=InvoiceEventReceived\n)\ndef invoice_notification(body: InvoiceEvent):\n pass\n\n\n@app.post(\"/invoices/\", callbacks=invoices_callback_router.routes)\nasync def create_invoice(invoice: Invoice, callback_url: Union[AnyHttpUrl, None] = None):\n # Send the invoice, collect the money, send the notification (the callback)\n thread = Thread(target=do_invoice(invoice, callback_url))\n thread.start()\n return {\"msg\": \"Invoice received\"}\n\ndef do_invoice(invoice: Invoice, callback_url: AnyHttpUrl):\n time.sleep(10)\n url = callback_url + \"/invoices/\" + invoice.id\n json = {\n \"data\": [\"Payment celebration\"],\n }\n requests.post(url=url, json=json)\n```\n\n```text\n{\"msg\": \"Invoice received\"}\n```\n\n```text\ndo_invoice\n```\n\n```text\ninvoice_notification\n```\n\n```text\n{\"msg\": \"Invoice received\"}\n```\n\n```text\ndo_invoice\n```\n\n```text\nBackgroundTask\n```\n\n```text\nThreadPool\n```\n\n```text\nProcessPool\n```\n\n```text\nawait\n```\n\n```text\nasync\n```\n\n```text\nhttpx\n```\n\n```text\nrequests\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.159Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":13,"totalLines":171,"estimatedTokens":1000}}735{"id":"stack-73843521","source":"stackoverflow","questionId":73843521,"title":"Awaiting multiple async functions in sequence","tags":["python","asynchronous","async-await","concurrency","fastapi"],"text":"Title: Awaiting multiple async functions in sequence\nTags: python, asynchronous, async-await, concurrency, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have been learning and exploring Python `asyncio` for a while. Before starting this journey I have read loads of articles to understand the subtle differences between `multithreading`, `multiprocessing`, and `asyncio`. But, as far as I know, I missed something on about a fundamental issue. I'll try to explain what I mean by pseudocodes below.\n\n```\nimport asyncio\nimport time\n\nasync def io_bound():\n print(\"Running io_bound...\")\n await asyncio.sleep(3)\n\nasync def main():\n start = time.perf_counter()\n\n result_1 = await io_bound()\n result_2 = await io_bound()\n\n end = time.perf_counter()\n\n print(f\"Finished in {round(end - start, 0)} second(s).\")\n\nasyncio.run(main())\n```\n\nFor sure, it will take around 6 seconds because we called the `io_bound` coroutine directly twice and didn't put them to the event loop. This also means that they were not run concurrently. If I would like to run them concurrently I will have to use `asyncio.gather(*tasks)` feature. I run them concurrently it would only take 3 seconds for sure.\n\nLet's imagine this `io_bound` coroutine is a coroutine that queries a database to get back some data. This application could be built with FastAPI roughly as follows.\n\n```\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/async-example\")\nasync def async_example():\n result_1 = await get_user()\n result_2 = await get_countries()\n\n if result_1:\n return {\"result\": result_2}\n \n return {\"result\": None}\n```\n\nLet's say the `get_user` and `get_countries` methods take 3 seconds each and have asynchronous queries implemented correctly. My questions are:\n\n- Do I need to use `asyncio.gather(*tasks)` for these two database queries? If necessary, why? If not, why?\n\n- What is the difference between `io_bound`, which I call twice, and `get_user` and `get_countries`, which I call back to back, in the above example?\n\n- In the `io_bound` example, if I did the same thing in FastAPI, wouldn't it take only 6 seconds to give a response back? If so, why not 3 seconds?\n\n- In the context of FastAPI, when would be the right time to use `asyncio.gather(*tasks)` in an endpoint?\n\n========================================\n\nCode:\n```py\nimport asyncio\nimport time\n\n\nasync def io_bound():\n print(\"Running io_bound...\")\n await asyncio.sleep(3)\n\n\nasync def main():\n start = time.perf_counter()\n\n result_1 = await io_bound()\n result_2 = await io_bound()\n\n end = time.perf_counter()\n\n print(f\"Finished in {round(end - start, 0)} second(s).\")\n\n\nasyncio.run(main())\n```\n\n```py\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n\n@app.get(\"/async-example\")\nasync def async_example():\n result_1 = await get_user()\n result_2 = await get_countries()\n\n if result_1:\n return {\"result\": result_2}\n \n return {\"result\": None}\n```\n\n```text\nasyncio\n```\n\n```text\nmultithreading\n```\n\n```text\nmultiprocessing\n```\n\n```text\nasyncio\n```\n\n```text\nio_bound\n```\n\n```text\nasyncio.gather(*tasks)\n```\n\n```text\nio_bound\n```\n\n```text\nget_user\n```\n\n```text\nget_countries\n```\n\n```text\nasyncio.gather(*tasks)\n```\n\n```text\nio_bound\n```\n\n```text\nget_user\n```\n\n```text\nget_countries\n```\n\n```text\nio_bound\n```\n\n```text\nasyncio.gather(*tasks)\n```\n\n```text\nasync def main():\n start = time.perf_counter()\n\n result_1_task = asyncio.create_task(io_bound())\n result_2_task = asyncio.create_task(io_bound())\n\n result_1 = await result_1_task\n result_2 = await result_2_task\n\n end = time.perf_counter()\n\n print(f\"Finished in {round(end - start, 0)} second(s).\")\n```\n\n```text\nasync def main_2():\n start = time.perf_counter()\n\n results = await asyncio.gather(io_bound(), io_bound())\n\n end = time.perf_counter()\n\n print(f\"Finished in {round(end - start, 0)} second(s).\")\n```\n\n```text\nasyncio.gather\n```\n\n========================================\n\nComments:\n- If both `get_user` and `get_countries` coroutines need to be used with `asyncio.gather` as you said in order to increase the performance, isn't it the same reason why it took 6 seconds within the `io_bound` example? i.e. FastAPI or any other implementation doesn't magically add awaitables to the event loop. For this reason, `asyncio.gather` or another method must be used in order to make them work together the awaitable that will be called sequentially if they are not independent. So adding these tasks to the event loop is like creating a thread to run each of these database queries, right?\n- @vildhjarta asyncio is a single thread, single process. It will use a socket for network communication, such as to a database. See this article for how asyncronous code is implemented.","metadata":{"transformedAt":"2026-08-18T18:32:29.159Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":20,"totalLines":197,"estimatedTokens":1181}}736{"id":"stack-72359755","source":"stackoverflow","questionId":72359755,"title":"Aws Api gateway Unable to load fast api swagger docs page","tags":["amazon-web-services","aws-api-gateway","fastapi"],"text":"Title: Aws Api gateway Unable to load fast api swagger docs page\nTags: amazon-web-services, aws-api-gateway, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have deployed a simple fast api to aws API gateway .All the end points working fine however i am unable to load the swagger docs page I see below error\n\nhttps://i.sstatic.net/iytsb.png\n\n**Api Code:**\n\n```\nfrom fastapi import FastAPI\nfrom mangum import Mangum\nimport os\nfrom fastapi.middleware.cors import CORSMiddleware\nstage = os.environ.get('STAGE', None)\nopenapi_prefix = f\"/{stage}\" if stage else \"/\"\napp = FastAPI(title=\"MyAwesomeApp\",root_path=\"stage\")\n\n@app.get(\"/\")\ndef get_root():\n return {\"message\": \"FastAPI running in a Lambda function\"}\n\n@app.get(\"/info\")\ndef get_root():\n return {\"message\": \"TestInfo\"}\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=[\"*\"],\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\nhandler = Mangum(app)\n```\n\nI tried adding the root as mentioned below\nhttps://fastapi.tiangolo.com/advanced/behind-a-proxy/\nAny help on this will be appreciated .\n\n========================================\n\nTop Answer:\nAs the OP mentioned, the documentation gives some examples of how you can get around the API Gateway problem with the stage name. For flexibility, I thought it might be useful make the root path environment variable.\n\n`ENV=dev`\n`app = FastAPI(title=settings.NAME, root_path=os.environ[\"ENV\"])`\n\nSimilarly, you can make it work with multiple versions by concatenating the environment variable with the version path.\n\n`root_path=os.path.join(\"/\", os.environ[\"ENV\"], \"api/v1\")`\n\nHope this helps!\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nfrom mangum import Mangum\nimport os\nfrom fastapi.middleware.cors import CORSMiddleware\nstage = os.environ.get('STAGE', None)\nopenapi_prefix = f\"/{stage}\" if stage else \"/\"\napp = FastAPI(title=\"MyAwesomeApp\",root_path=\"stage\")\n\n\n@app.get(\"/\")\ndef get_root():\n return {\"message\": \"FastAPI running in a Lambda function\"}\n\n\n@app.get(\"/info\")\ndef get_root():\n return {\"message\": \"TestInfo\"}\n\n\napp.add_middleware(\n CORSMiddleware,\n allow_origins=[\"*\"],\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"],\n)\nhandler = Mangum(app)\n```\n\n```text\nroot_path=\"/dev\"\n```\n\n```text\napp = FastAPI(title=settings.NAME,root_path=\"/dev\")\n```\n\n```text\nENV=dev\n```\n\n```text\napp = FastAPI(title=settings.NAME, root_path=os.environ[\"ENV\"])\n```\n\n```text\nroot_path=os.path.join(\"/\", os.environ[\"ENV\"], \"api/v1\")\n```\n\n========================================\n\nComments:\n- I'm having the same problem. But in my case sometime it works but most of the time it fail to load the API docs.\n- same problem reported on Github github.com/tiangolo/fastapi/issues/2787\n- Hey man! I solved it. In my case that was because my AWS lambda function time out is too short 3 seconds!!!. I updated it to 30 seconds and the API docs works as expected. Refer this one: bobbyhadz.com/blog/aws-lambda-task-timed-out-after-seconds\n- I figured it out by enable CloudWatch for the Gateway. And It showed the exact error for me. Maybe your case is a little different. Please enable it and check for the error\n- I found the solution we need to add root_path=\"/dev\" while creating fast api app .This root path should be same as the api gatway stage but with fastapi versioning this does not work\n- @qangdev are you using api versioning of fast api by using fastapi_versioning or without that\n- But the docs is not working if I ran the code locally when we put `root_path=/dev`. `Fetch error Not Found /dev/openapi.json`.","metadata":{"transformedAt":"2026-08-18T18:32:29.159Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":6,"totalLines":119,"estimatedTokens":903}}737{"id":"stack-79758380","source":"stackoverflow","questionId":79758380,"title":"How to add objects/links to a set of links in beanie?","tags":["python","mongodb","fastapi","pydantic","beanie"],"text":"Title: How to add objects/links to a set of links in beanie?\nTags: python, mongodb, fastapi, pydantic, beanie\nSource: Stack Overflow\n\nQuestion:\nAssume that I have these `Beanie Document`s which are based, by the way, on `Pydantic Model`s:\n\n**File name:** `models.py`\n\n```\nfrom beanie import Document, Link\n\nclass A(Document):\n first: int\n second: str\n\nclass B(Document):\n third: float\n a_links: set[Link[A]] = {}\n```\n\nand I have this `FastAPI route`:\n\n**File name:** `main.py`\n\n```\nfrom fastapi import FastAPI, HTTPException, status\n\nfrom beanie import PydanticObjectId, Link\n\nfrom .models import A, B\n\napp = FastAPI()\n\n@app.post('/b/{b_object_id}/add-link/{a_object_id}')\nasync def add_link(b_object_id: PydanticObjectId, a_object_id: PydanticObjectId):\n b = await B.get(b_object_id)\n if not b:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)\n a = await A.get(a_object_id)\n if not a:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)\n b.a_links.add(Link(a))\n await b.save()\n return b\n```\n\nI am talking about this line of code:\n\n```\nb.a_links.add(Link(a))\n```\n\nIf I wrote it as it is, I will get this error: `Parameter 'document_class' unfilled`\n\nAlso, if I wrote it as:\n\n```\nb.a_links.add(Link(a, document_class=A))\n```\n\nI will get this error: `Expected type 'DBRef', got 'A' instead`\n\nFinally, if I wrote it as:\n\n```\nb.a_links.add(Link(ref=a.id, document_class=A))\n```\n\nI will get this error: `Expected type 'DBRef', got 'PydanticObjectId | None' instead`\n\nHow to add it in a correct way?\n\n========================================\n\nCode:\n```py\nfrom beanie import Document, Link\n\nclass A(Document):\n first: int\n second: str\n\nclass B(Document):\n third: float\n a_links: set[Link[A]] = {}\n```\n\n```py\nfrom fastapi import FastAPI, HTTPException, status\n\nfrom beanie import PydanticObjectId, Link\n\nfrom .models import A, B\n\napp = FastAPI()\n\n@app.post('/b/{b_object_id}/add-link/{a_object_id}')\nasync def add_link(b_object_id: PydanticObjectId, a_object_id: PydanticObjectId):\n b = await B.get(b_object_id)\n if not b:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)\n a = await A.get(a_object_id)\n if not a:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)\n b.a_links.add(Link(a))\n await b.save()\n return b\n```\n\n```py\nb.a_links.add(Link(a))\n```\n\n```py\nb.a_links.add(Link(a, document_class=A))\n```\n\n```py\nb.a_links.add(Link(ref=a.id, document_class=A))\n```\n\n```text\nBeanie Document\n```\n\n```text\nPydantic Model\n```\n\n```text\nmodels.py\n```\n\n```text\nFastAPI route\n```\n\n```text\nmain.py\n```\n\n```text\nParameter 'document_class' unfilled\n```\n\n```text\nExpected type 'DBRef', got 'A' instead\n```\n\n```text\nExpected type 'DBRef', got 'PydanticObjectId | None' instead\n```\n\n```text\nLink\n```\n\n```text\nDBRef\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.160Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":15,"totalLines":161,"estimatedTokens":695}}738{"id":"stack-73069550","source":"stackoverflow","questionId":73069550,"title":"FastAPI - Best practices for writing REST APIs with multiple conditions","tags":["python","rest","design-patterns","sqlalchemy","fastapi"],"text":"Title: FastAPI - Best practices for writing REST APIs with multiple conditions\nTags: python, rest, design-patterns, sqlalchemy, fastapi\nSource: Stack Overflow\n\nQuestion:\nLet's say I have two entities, `Users` and `Councils`, and a M2M association table `UserCouncils`. `Users` can be added/removed from `Councils` and only admins can do that (defined in a `role` attribute in the `UserCouncil` relation).\nNow, when creating endpoints for `/councils/{council_id}/remove`, I am faced with the issue of checking multiple constraints before the operation, such as the following:\n\n```\n@router.delete(\"/{council_id}/remove\", response_model=responses.CouncilDetail)\ndef remove_user_from_council(\n council_id: int | UUID = Path(...),\n *,\n user_in: schemas.CouncilUser,\n db: Session = Depends(get_db),\n current_user: Users = Depends(get_current_user),\n council: Councils = Depends(council_id_dep),\n) -> dict[str, Any]:\n \"\"\"\n\n DELETE /councils/:id/remove (auth)\n\n remove user with `user_in` from council\n current user must be ADMIN of council\n \"\"\"\n\n # check if input user exists\n if not Users.get(db=db, id=user_in.user_id):\n raise HTTPException(\n status_code=status.HTTP_404_NOT_FOUND, detail=\"User not found\"\n )\n\n if not UserCouncil.get(db=db, user_id=user_in.user_id, council_id=council.id):\n raise HTTPException(\n status_code=status.HTTP_400_BAD_REQUEST,\n detail=\"Cannot delete user who is not part of council\",\n )\n\n # check if current user exists in council\n if not (\n relation := UserCouncil.get(\n db=db, user_id=current_user.id, council_id=council.id\n )\n ):\n raise HTTPException(\n status_code=status.HTTP_403_FORBIDDEN,\n detail=\"Current user not part of council\",\n )\n\n # check if current user is Admin\n if relation.role != Roles.ADMIN:\n raise HTTPException(\n status_code=status.HTTP_403_FORBIDDEN, detail=\"Unauthorized\"\n )\n\n elif current_user.id == user_in.user_id:\n raise HTTPException(\n status_code=status.HTTP_400_BAD_REQUEST,\n detail=\"Admin cannot delete themselves\",\n )\n\n else:\n updated_users = council.remove_member(db=db, user_id=user_in.user_id)\n result = {\"council\": council, \"users\": updated_users}\n return result\n```\n\nThese checks are pretty self-explanatory. However, this adds a lot of code in the endpoint definition. Should the endpoint definitions be generally minimalistic? I could wrap all these checks inside the `Councils` crud method (i.e., `council.remove_member()`), but that would mean adding `HTTPException`s inside crud classes, which I don't want to do.\n\nWhat are the general best practices for solving situations like these, and where can I read more about this? Any kind of help would be appreciated.\n\nThanks.\n\n========================================\n\nCode:\n```py\n@router.delete(\"/{council_id}/remove\", response_model=responses.CouncilDetail)\ndef remove_user_from_council(\n council_id: int | UUID = Path(...),\n *,\n user_in: schemas.CouncilUser,\n db: Session = Depends(get_db),\n current_user: Users = Depends(get_current_user),\n council: Councils = Depends(council_id_dep),\n) -> dict[str, Any]:\n \"\"\"\n\n DELETE /councils/:id/remove (auth)\n\n remove user with `user_in` from council\n current user must be ADMIN of council\n \"\"\"\n\n # check if input user exists\n if not Users.get(db=db, id=user_in.user_id):\n raise HTTPException(\n status_code=status.HTTP_404_NOT_FOUND, detail=\"User not found\"\n )\n\n if not UserCouncil.get(db=db, user_id=user_in.user_id, council_id=council.id):\n raise HTTPException(\n status_code=status.HTTP_400_BAD_REQUEST,\n detail=\"Cannot delete user who is not part of council\",\n )\n\n # check if current user exists in council\n if not (\n relation := UserCouncil.get(\n db=db, user_id=current_user.id, council_id=council.id\n )\n ):\n raise HTTPException(\n status_code=status.HTTP_403_FORBIDDEN,\n detail=\"Current user not part of council\",\n )\n\n # check if current user is Admin\n if relation.role != Roles.ADMIN:\n raise HTTPException(\n status_code=status.HTTP_403_FORBIDDEN, detail=\"Unauthorized\"\n )\n\n elif current_user.id == user_in.user_id:\n raise HTTPException(\n status_code=status.HTTP_400_BAD_REQUEST,\n detail=\"Admin cannot delete themselves\",\n )\n\n else:\n updated_users = council.remove_member(db=db, user_id=user_in.user_id)\n result = {\"council\": council, \"users\": updated_users}\n return result\n```\n\n```text\nUsers\n```\n\n```text\nCouncils\n```\n\n```text\nUserCouncils\n```\n\n```text\nUsers\n```\n\n```text\nCouncils\n```\n\n```text\nrole\n```\n\n```text\nUserCouncil\n```\n\n```text\n/councils/{council_id}/remove\n```\n\n```text\nCouncils\n```\n\n```text\ncouncil.remove_member()\n```\n\n```text\nHTTPException\n```\n\n```py\nclass UnauthorizedException(Exception):\n def __init__(self, message: str):\n super().__init__(message)\n self.message = message\n\n\nclass InvalidActionException(Exception):\n ...\n\n\nclass NotFoundException(Exception):\n ...\n```\n\n```py\n@app.exception_handler(UnauthorizedException)\nasync def unauthorized_exception_handler(request: Request, exc: UnauthorizedException):\n return JSONResponse(\n status_code=status.HTTP_403_FORBIDDEN,\n content={\"message\": exc.message},\n )\n\n@app.exception_handler(InvalidActionException)\nasync def unauthorized_exception_handler(request: Request, exc: InvalidActionException):\n ...\n```\n\n```py\nclass CouncilService:\n def __init__(self, db: Session):\n self.db = db\n\n def ensure_admin_council_member(self, user_id: int, council_id: int):\n # check if current user exists in council\n if not (\n relation := UserCouncil.get(\n db=self.db, user_id=user_id, council_id=council_id\n )\n ):\n raise UnauthorizedException(\"Current user not part of council\")\n\n # check if current user is Admin\n if relation.role != Roles.ADMIN:\n raise UnauthorizedException(\"Unauthorized\")\n\n def remove_council_member(self, user_in: schemas.CouncilUser, council: Councils):\n # check if input user exists\n if not Users.get(db=self.db, id=user_in.user_id):\n raise NotFoundException(\"User not found\")\n\n if not UserCouncil.get(db=self.db, user_id=user_in.user_id, council_id=council.id):\n raise InvalidActionException(\"Cannot delete user who is not part of council\")\n\n if current_user.id == user_in.user_id:\n raise InvalidActionException(\"Admin cannot delete themselves\")\n\n updated_users = council.remove_member(db=self.db, user_id=user_in.user_id)\n result = {\"council\": council, \"users\": updated_users}\n return result\n```\n\n```py\n@router.delete(\"/{council_id}\", response_model=responses.CouncilDetail)\ndef remove_user_from_council(\n council_id: int | UUID = Path(...),\n *,\n user_in: schemas.CouncilUser,\n current_user: Users = Depends(get_current_user),\n council: Councils = Depends(council_id_dep),\n council_service: CouncilService = Depends(get_council_service),\n) -> responses.CouncilDetail:\n \"\"\"\n\n DELETE /councils/:id (auth)\n\n remove user with `user_in` from council\n current user must be ADMIN of council\n \"\"\"\n council_service.ensure_admin_council_member(current_user.id, council_id)\n return council_service.remove_council_member(user_in, council)\n```\n\n```text\n/remove\n```\n\n========================================\n\nComments:\n- Why do you have to check that user exists *after* using a dependency that fetches the current user? That dependency should verify that the user exists and is a valid user; the same can be said for the code fetching the council; make it depend on both the user and the council id, and resolve that in your depenendency. You can also make that dependency a `council_with_current_user_as_admin`, so that it's all hidden away behind layers of dependencies. Your view becomes very effective and succinct, and your dependencies can easily be reused to compose different needs.\n- The check for user exists is for the input user `user_in`. `current_user` only parses the header to fetch the currently logged in user. But you're right. A relationship dependency would clear the clutter.\n- In general, adding verbs like \"remove\" from a HTTP DELETE method should be avoided. You already knowingly are calling \"delete this id\" from the API path and HTTP method itself. There is no need for the verb\n- @OneCricketeer very good point, I have edited the answer","metadata":{"transformedAt":"2026-08-18T18:32:29.160Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":17,"totalLines":273,"estimatedTokens":2139}}739{"id":"stack-74962787","source":"stackoverflow","questionId":74962787,"title":"SQLAlchemy module not found despite definitely being installed with Pipenv","tags":["python","sqlalchemy","fastapi","pipenv"],"text":"Title: SQLAlchemy module not found despite definitely being installed with Pipenv\nTags: python, sqlalchemy, fastapi, pipenv\nSource: Stack Overflow\n\nQuestion:\nI'm learning to use FastAPI, psycopg2 and SQLAlchemy with python, which has been working fine. Now for some reason whenever I run my web app, the SQLAlchemy module cannot be found.\n\nI am running this in a Pipenv, with python 3.11.1 and SQLAlchemy 1.4.45, and running pip freeze shows SQLAlchemy is definitely installed, and my source is definitely my pipenv environment, the same from which I'm running my fastAPI server.\n\nI have tried uninstalling and reinstalling SQLAlchemy with Pipenv, and when I run python in interactive mode, it is the expected python version and I'm able to import SQLAlchemy and check sqalalchemy.**version** .\n\nAny ideas why it's saying it can't import when I run FastAPI?\n\n### Code from my models.py module being imported into main.py:\n\n```\nfrom sqlalchemy import Column, Integer, String, Boolean\nfrom app.database import Base\n\nclass Post(Base):\n __tablename__ = \"posts\"\n\n id = Column(Integer, primary_key=True, nullable=False)\n title = Column(String, nullable=False)\n content = Column(String, nullable=False)\n published = Column(Boolean, default=True)\n # timestamp = Column(TIMESTAMP, default=now())\n```\n\n### main.py:\n\n```\nfrom fastapi import FastAPI, Response, status, HTTPException, Depends\nfrom pydantic import BaseModel\nimport psycopg2\nfrom psycopg2.extras import RealDictCursor\nimport time\nfrom app import models\nfrom sqlalchemy.orm import Session\nfrom app.database import engine, SessionLocal\n\nmodels.Base.metadata.create_all(bind=engine)\n\n# FastAPI initialisation\napp = FastAPI()\n\n# function to initialise SQlAlchemy DB session dependency\ndef get_db():\n db = SessionLocal()\n try:\n yield db\n finally:\n db.close()\n\n# psycopg2 DB connection initialisation\nwhile True:\n try:\n conn = psycopg2.connect(host=\"localhost\", dbname=\"fastapi\", user=\"postgres\",\n password=\"*********\", cursor_factory=RealDictCursor)\n cursor = conn.cursor()\n print('Database connection successful.')\n break\n except Exception as error:\n print(\"Connecting to database failed.\")\n print(\"Error: \", error)\n print(\"Reconnecting after 2 seconds\")\n time.sleep(2)\n\n# this class defines the expected fields for the posts extending the BaseModel class\n# from Pydantic for input validation and exception handling ==> a \"schema\"\nclass Post(BaseModel):\n title: str\n content: str\n published: bool = True\n\n# this list holds posts, with 2 hard coded for testing purposes\nmy_posts = [{\"title\": \"title of post 1\", \"content\": \"content of post 1\", \"id\": 1},\n {\"title\": \"title of post 2\", \"content\": \"content of post 2\", \"id\": 2}]\n\n# this small function simply finds posts by id by iterating though the my_posts list\ndef find_post(find_id):\n for post in my_posts:\n if post[\"id\"] == find_id:\n return post\n\ndef find_index(find_id):\n try:\n index = my_posts.index(find_post(find_id))\n except:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f\"Post of id: {find_id} not found.\")\n return index\n\n# these decorated functions act as routes for FastAPI.\n# the decorator is used to define the HTTP request verb (e.g. get, post, delete, patch, put),\n# as well as API endpoints within the app (e.g. \"/\" is root),\n# and default HTTP status codes.\n@app.get(\"/\")\nasync def root():\n return {\"message\": \"Hello World\"}\n\n# \"CRUD\" (Create, Read, Update, Delete) says to use same endpoint\n# but with different HTTP request verbs for the different request types.\n# (e.g. using \"/posts\" for all four CRUD operations, but using POST, GET, PUT/PATCH, DELETE respectively.)\n@app.get(\"/posts\")\ndef get_data():\n cursor.execute(\"SELECT * FROM posts\")\n posts = cursor.fetchall()\n print(posts)\n return {\"data\": posts}\n\n@app.post(\"/posts\", status_code=status.HTTP_201_CREATED)\ndef create_posts(post: Post):\n cursor.execute(\"INSERT INTO posts (title, content, published) VALUES (%s, %s, %s) RETURNING *\",\n (post.title, post.content, post.published))\n new_post = cursor.fetchone()\n\n conn.commit()\n\n return {\"created post\": new_post}\n\n@app.delete(\"/posts/{id}\")\ndef delete_post(id: int):\n cursor.execute(\"DELETE FROM posts * WHERE id = %s RETURNING *\", str(id))\n deleted_post = cursor.fetchone()\n conn.commit()\n\n if deleted_post is None:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f\"post with id: {id} not found.\")\n else:\n print(\"deleted post:\", deleted_post)\n return Response(status_code=status.HTTP_204_NO_CONTENT)\n\n@app.get(\"/posts/{id}\")\ndef get_post(id: int):\n cursor.execute(\"SELECT * FROM posts WHERE id = %s\", str(id))\n post = cursor.fetchone()\n if post is None:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f\"post with id: {id} was not found.\")\n return {\"post_detail\": post}\n\n@app.put(\"/posts/{id}\")\ndef update_post(id: int, put: Post):\n cursor.execute(\"UPDATE posts SET title = %s, content = %s, published= %s WHERE id = %s RETURNING *\",\n (put.title, put.content, put.published, str(id)))\n updated_post = cursor.fetchone()\n if updated_post is None:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f\"post with id: {id} was not found.\")\n return {\"updated_post_detail\": updated_post}\n\n@app.get(\"/sqlalchemy\")\ndef test_posts(db: Session = Depends(get_db)):\n return {\"status\": \"success\"}\n```\n\n### ERROR LOG:\n\n```\nlouisgreenhalgh@MacBook-Pro ~/PycharmProjects/FASTAPI uvicorn app.main:app --reload ✔ FASTAPI-3Pf2tu2f\nINFO: Will watch for changes in these directories: ['/Users/louisgreenhalgh/PycharmProjects/FASTAPI']\nINFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\nINFO: Started reloader process [32662] using WatchFiles\nProcess SpawnProcess-1:\nTraceback (most recent call last):\n File \"/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n self.run()\n File \"/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/multiprocessing/process.py\", line 108, in run\n self._target(*self._args, **self._kwargs)\n File \"/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/uvicorn/_subprocess.py\", line 76, in subprocess_started\n target(sockets=sockets)\n File \"/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/uvicorn/server.py\", line 60, in run\n return asyncio.run(self.serve(sockets=sockets))\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/runners.py\", line 190, in run\n return runner.run(main)\n ^^^^^^^^^^^^^^^^\n File \"/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/runners.py\", line 118, in run\n return self._loop.run_until_complete(task)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"uvloop/loop.pyx\", line 1517, in uvloop.loop.Loop.run_until_complete\n File \"/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/uvicorn/server.py\", line 67, in serve\n config.load()\n File \"/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/uvicorn/config.py\", line 477, in load\n self.loaded_app = import_from_string(self.app)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/uvicorn/importer.py\", line 24, in import_from_string\n raise exc from None\n File \"/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/uvicorn/importer.py\", line 21, in import_from_string\n module = importlib.import_module(module_str)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/importlib/__init__.py\", line 126, in import_module\n return _bootstrap._gcd_import(name[level:], package, level)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"\", line 1206, in _gcd_import\n File \"\", line 1178, in _find_and_load\n File \"\", line 1149, in _find_and_load_unlocked\n File \"\", line 690, in _load_unlocked\n File \"\", line 940, in exec_module\n File \"\", line 241, in _call_with_frames_removed\n File \"/Users/louisgreenhalgh/PycharmProjects/FASTAPI/app/main.py\", line 6, in \n from app import models\n File \"/Users/louisgreenhalgh/PycharmProjects/FASTAPI/app/models.py\", line 1, in \n from sqlalchemy import Column, Integer, String, Boolean\nModuleNotFoundError: No module named 'sqlalchemy'\n```\n\n### Pipenv Graph Output:\n\n```\nfastapi==0.88.0\n - pydantic [required: >=1.6.2,=4.2.0, installed: 4.4.0]\n - starlette [required: ==0.22.0, installed: 0.22.0]\n - anyio [required: >=3.4.0,=2.8, installed: 3.4]\n - sniffio [required: >=1.1, installed: 1.3.0]\ngreenlet==2.0.1\npsycopg2-binary==2.9.5\nSQLAlchemy==1.4.45\n```\n\n========================================\n\nCode:\n```text\nfrom sqlalchemy import Column, Integer, String, Boolean\nfrom app.database import Base\n\n\nclass Post(Base):\n __tablename__ = \"posts\"\n\n id = Column(Integer, primary_key=True, nullable=False)\n title = Column(String, nullable=False)\n content = Column(String, nullable=False)\n published = Column(Boolean, default=True)\n # timestamp = Column(TIMESTAMP, default=now())\n```\n\n```text\nfrom fastapi import FastAPI, Response, status, HTTPException, Depends\nfrom pydantic import BaseModel\nimport psycopg2\nfrom psycopg2.extras import RealDictCursor\nimport time\nfrom app import models\nfrom sqlalchemy.orm import Session\nfrom app.database import engine, SessionLocal\n\nmodels.Base.metadata.create_all(bind=engine)\n\n# FastAPI initialisation\napp = FastAPI()\n\n\n# function to initialise SQlAlchemy DB session dependency\ndef get_db():\n db = SessionLocal()\n try:\n yield db\n finally:\n db.close()\n\n\n# psycopg2 DB connection initialisation\nwhile True:\n try:\n conn = psycopg2.connect(host=\"localhost\", dbname=\"fastapi\", user=\"postgres\",\n password=\"*********\", cursor_factory=RealDictCursor)\n cursor = conn.cursor()\n print('Database connection successful.')\n break\n except Exception as error:\n print(\"Connecting to database failed.\")\n print(\"Error: \", error)\n print(\"Reconnecting after 2 seconds\")\n time.sleep(2)\n\n\n# this class defines the expected fields for the posts extending the BaseModel class\n# from Pydantic for input validation and exception handling ==> a \"schema\"\nclass Post(BaseModel):\n title: str\n content: str\n published: bool = True\n\n\n# this list holds posts, with 2 hard coded for testing purposes\nmy_posts = [{\"title\": \"title of post 1\", \"content\": \"content of post 1\", \"id\": 1},\n {\"title\": \"title of post 2\", \"content\": \"content of post 2\", \"id\": 2}]\n\n\n# this small function simply finds posts by id by iterating though the my_posts list\ndef find_post(find_id):\n for post in my_posts:\n if post[\"id\"] == find_id:\n return post\n\n\ndef find_index(find_id):\n try:\n index = my_posts.index(find_post(find_id))\n except:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f\"Post of id: {find_id} not found.\")\n return index\n\n\n# these decorated functions act as routes for FastAPI.\n# the decorator is used to define the HTTP request verb (e.g. get, post, delete, patch, put),\n# as well as API endpoints within the app (e.g. \"/\" is root),\n# and default HTTP status codes.\n@app.get(\"/\")\nasync def root():\n return {\"message\": \"Hello World\"}\n\n\n# \"CRUD\" (Create, Read, Update, Delete) says to use same endpoint\n# but with different HTTP request verbs for the different request types.\n# (e.g. using \"/posts\" for all four CRUD operations, but using POST, GET, PUT/PATCH, DELETE respectively.)\n@app.get(\"/posts\")\ndef get_data():\n cursor.execute(\"SELECT * FROM posts\")\n posts = cursor.fetchall()\n print(posts)\n return {\"data\": posts}\n\n\n@app.post(\"/posts\", status_code=status.HTTP_201_CREATED)\ndef create_posts(post: Post):\n cursor.execute(\"INSERT INTO posts (title, content, published) VALUES (%s, %s, %s) RETURNING *\",\n (post.title, post.content, post.published))\n new_post = cursor.fetchone()\n\n conn.commit()\n\n return {\"created post\": new_post}\n\n\n@app.delete(\"/posts/{id}\")\ndef delete_post(id: int):\n cursor.execute(\"DELETE FROM posts * WHERE id = %s RETURNING *\", str(id))\n deleted_post = cursor.fetchone()\n conn.commit()\n\n if deleted_post is None:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f\"post with id: {id} not found.\")\n else:\n print(\"deleted post:\", deleted_post)\n return Response(status_code=status.HTTP_204_NO_CONTENT)\n\n\n@app.get(\"/posts/{id}\")\ndef get_post(id: int):\n cursor.execute(\"SELECT * FROM posts WHERE id = %s\", str(id))\n post = cursor.fetchone()\n if post is None:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f\"post with id: {id} was not found.\")\n return {\"post_detail\": post}\n\n\n@app.put(\"/posts/{id}\")\ndef update_post(id: int, put: Post):\n cursor.execute(\"UPDATE posts SET title = %s, content = %s, published= %s WHERE id = %s RETURNING *\",\n (put.title, put.content, put.published, str(id)))\n updated_post = cursor.fetchone()\n if updated_post is None:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f\"post with id: {id} was not found.\")\n return {\"updated_post_detail\": updated_post}\n\n\n@app.get(\"/sqlalchemy\")\ndef test_posts(db: Session = Depends(get_db)):\n return {\"status\": \"success\"}\n```\n\n```text\nlouisgreenhalgh@MacBook-Pro ~/PycharmProjects/FASTAPI uvicorn app.main:app --reload ✔ FASTAPI-3Pf2tu2f\nINFO: Will watch for changes in these directories: ['/Users/louisgreenhalgh/PycharmProjects/FASTAPI']\nINFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\nINFO: Started reloader process [32662] using WatchFiles\nProcess SpawnProcess-1:\nTraceback (most recent call last):\n File \"/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/multiprocessing/process.py\", line 314, in _bootstrap\n self.run()\n File \"/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/multiprocessing/process.py\", line 108, in run\n self._target(*self._args, **self._kwargs)\n File \"/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/uvicorn/_subprocess.py\", line 76, in subprocess_started\n target(sockets=sockets)\n File \"/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/uvicorn/server.py\", line 60, in run\n return asyncio.run(self.serve(sockets=sockets))\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/runners.py\", line 190, in run\n return runner.run(main)\n ^^^^^^^^^^^^^^^^\n File \"/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/runners.py\", line 118, in run\n return self._loop.run_until_complete(task)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"uvloop/loop.pyx\", line 1517, in uvloop.loop.Loop.run_until_complete\n File \"/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/uvicorn/server.py\", line 67, in serve\n config.load()\n File \"/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/uvicorn/config.py\", line 477, in load\n self.loaded_app = import_from_string(self.app)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/uvicorn/importer.py\", line 24, in import_from_string\n raise exc from None\n File \"/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/uvicorn/importer.py\", line 21, in import_from_string\n module = importlib.import_module(module_str)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/importlib/__init__.py\", line 126, in import_module\n return _bootstrap._gcd_import(name[level:], package, level)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"<frozen importlib._bootstrap>\", line 1206, in _gcd_import\n File \"<frozen importlib._bootstrap>\", line 1178, in _find_and_load\n File \"<frozen importlib._bootstrap>\", line 1149, in _find_and_load_unlocked\n File \"<frozen importlib._bootstrap>\", line 690, in _load_unlocked\n File \"<frozen importlib._bootstrap_external>\", line 940, in exec_module\n File \"<frozen importlib._bootstrap>\", line 241, in _call_with_frames_removed\n File \"/Users/louisgreenhalgh/PycharmProjects/FASTAPI/app/main.py\", line 6, in <module>\n from app import models\n File \"/Users/louisgreenhalgh/PycharmProjects/FASTAPI/app/models.py\", line 1, in <module>\n from sqlalchemy import Column, Integer, String, Boolean\nModuleNotFoundError: No module named 'sqlalchemy'\n```\n\n```text\nfastapi==0.88.0\n - pydantic [required: >=1.6.2,<2.0.0,!=1.8.1,!=1.8,!=1.7.3,!=1.7.2,!=1.7.1,!=1.7, installed: 1.10.4]\n - typing-extensions [required: >=4.2.0, installed: 4.4.0]\n - starlette [required: ==0.22.0, installed: 0.22.0]\n - anyio [required: >=3.4.0,<5, installed: 3.6.2]\n - idna [required: >=2.8, installed: 3.4]\n - sniffio [required: >=1.1, installed: 1.3.0]\ngreenlet==2.0.1\npsycopg2-binary==2.9.5\nSQLAlchemy==1.4.45\n```\n\n========================================\n\nComments:\n- That indeed was the issue: I had switched to pipenv from venv midway through and must have forgotten to reinstall uvicorn. Thank you so much!\n- Please accept this answer since you've indicated it solved your issue @louistheone48, thanks!\n- And sometimes you may need to uninstall the other uvicorn executable via pip, prior to this working. To be safe, you can always jump into the Pipenv environment via `pipenv shell` and then install the package you need.","metadata":{"transformedAt":"2026-08-18T18:32:29.160Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":440,"estimatedTokens":4454}}740{"id":"stack-66440530","source":"stackoverflow","questionId":66440530,"title":"Python: Call asynchronous code from synchronous method when there is already an event loop running","tags":["python","asynchronous","python-asyncio","fastapi"],"text":"Title: Python: Call asynchronous code from synchronous method when there is already an event loop running\nTags: python, asynchronous, python-asyncio, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am working with FastAPI and uvloop to serve a REST API in an efficient way.\n\nI have a lot of asynchronous code that make calls to remote resources such as a database, a storage, etc, those functions looks like this:\n\n```\nasync def _get_remote_resource(key: str) -> Resource:\n # do some async work\n return resource\n```\n\nI'm implementing an interface to an existing Abstract Base Class where I need to use the asynchronous function from above in a synchronous method. I have done something like:\n\n```\nclass Resource:\n def __str__(self):\n resource = asyncio.run_until_complete(_get_remote_resource(self.key))\n return f\"{resource.pk}\"\n```\n\nGreat! Now I do an endpoint in fastapi to make this work accesible:\n\n```\n@app.get(\"\")\nasync def get(key):\n return str(Resource(key))\n```\n\nThe problem is that FastAPI already gets and event loop running, using uvloop, and then the asynchronous code fails because the loop is already running.\n\nIs there any way I can call the asynchronous method from the synchronous method in the class? Or do I have to rethink the structure of the code?\n\n========================================\n\nTop Answer:\nI would like to complement the @user4815162342 answer.\n\n`FastAPI` is an asychronous framework. I would suggest sticking to a few principles:\n\n- Do not execute IO operations in synchronous functions in a blocking way. Prepare this resource asynchronously and already pass the ready data to the synchronous function (this principle can be called an asynchronous dependency for synchronous code).\n\n- If you still need to perform a blocking IO operation in a synchronous code, then do it in a separate thread. And wait for this result asynchronously by means of `asyncio` (`def` endpoint, `run_in_executor` with `ThreadPoolExecutor` or `def` background task).\n\n- If you need to do a blocking CPU-bound operation, then delegate its execution to a separate process (the simplest way `run_in_executor` with `ProcessPoolExecutor` or any task queue).\n\n========================================\n\nCode:\n```py\nasync def _get_remote_resource(key: str) -> Resource:\n # do some async work\n return resource\n```\n\n```py\nclass Resource:\n def __str__(self):\n resource = asyncio.run_until_complete(_get_remote_resource(self.key))\n return f\"{resource.pk}\"\n```\n\n```py\n@app.get(\"\")\nasync def get(key):\n return str(Resource(key))\n```\n\n```text\nclass Resource:\n def name(self):\n return loop.run_until_complete(self.name_async())\n\n async def name_async(self):\n resource = await _get_remote_resource(self.key)\n return f\"{resource.pk}\"\n```\n\n```text\n@app.get(\"\")\nasync def get(key):\n return await Resource(key).name_async()\n```\n\n```text\nrun_until_complete\n```\n\n```text\n__str__(self)\n```\n\n```text\nself.name()\n```\n\n```text\nstr()\n```\n\n```text\nFastAPI\n```\n\n```text\nasyncio\n```\n\n```text\ndef\n```\n\n```text\nrun_in_executor\n```\n\n```text\nThreadPoolExecutor\n```\n\n```text\ndef\n```\n\n```text\nrun_in_executor\n```\n\n```text\nProcessPoolExecutor\n```\n\n========================================\n\nComments:\n- Yes, I agree the straightforward fix is using an async method, however, the class Resource is actually an implementation of a Abstract Base Class so the methods are already defined.\n- @NicolasMartinez That's new information. I don't think such a design is going to work - you'll need to switch to an async-aware ABC.\n- Yes, I forgot to include that in the question! Editing ASAP. Thanks for your help.\n- We did switch to an async-aware aBC (which provides sync and async methods for almost everything) did fix the problem. Thanks!\n- Should \"a synchronous code\" in the second bullet be \"asynchronous code\"?\n- By synchronous code, I mean here a piece of code that does not contain asynchronous calls, but includes preparatory actions and a call to a synchronous blocking function.","metadata":{"transformedAt":"2026-08-18T18:32:29.160Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":17,"totalLines":144,"estimatedTokens":1004}}741{"id":"stack-75839415","source":"stackoverflow","questionId":75839415,"title":"Kafka + FastAPI + Docker template","tags":["docker","apache-kafka","fastapi","consumer","kafka-python"],"text":"Title: Kafka + FastAPI + Docker template\nTags: docker, apache-kafka, fastapi, consumer, kafka-python\nSource: Stack Overflow\n\nQuestion:\n### Introduction\n\nI am currently experimenting with Kafka and FastAPI and trying to build a template to enable me to quickly write programs in a microservice pattern.\n\n### Goal - Vision\n\nBuilding a repository of design patterns that implement very easy microservice infrastructures. The examples should only demonstrate how messages are sent between different services and offer a user to easily integrate their custom code without the hassle of spending a lot of time with the setup.\n\n### Motivation\n\nI searched a lot but I was not able to find simple examples. Most examples are highly customized and do not really generalize.\n\n### Tech Stack\n\n- Kafka\n\n- FastApi\n\n- Docker\n\n### Open to other implementations\n\nPlease let me know if you have any other recommendations. I am quite new to microservice architectures and would be very happy to explore further designs.\n\n### Current Problem\n\nMy current template involves building a Zookeeper, Kafka, consumer, and producer service. However, I am encountering an issue where my consumer is not able to consume messages generated by my producer. The producer seems to work fine and successfully publishes messages, which I have confirmed using the `docker-compose exec kafka kafka-console-consumer.sh --bootstrap-server kafka:9092 --topic my-topic --from-beginning` command.\n\nMy consumer appears to not do anything at all.\n\nThank you in advance for all your suggestions on this issue.\n\n### my folder structure:\n\nhttps://i.sstatic.net/sOe2W.png\n\n### my docker-compose file:\n\n```\nversion: '3'\n\nservices:\n zookeeper:\n image: confluentinc/cp-zookeeper:latest\n environment:\n ZOOKEEPER_CLIENT_PORT: 2181\n ZOOKEEPER_TICK_TIME: 2000\n ports:\n - 2181:2181\n - 2888:2888\n - 3888:3888\n\n kafka:\n image: confluentinc/cp-kafka:latest\n restart: \"no\"\n links:\n - zookeeper\n ports:\n - 9092:9092\n environment:\n KAFKA_BROKER_ID: 1\n KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1\n KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181\n KAFKA_LISTENERS: INTERNAL://:29092,EXTERNAL://:9092\n KAFKA_ADVERTISED_LISTENERS: INTERNAL://kafka:29092,EXTERNAL://localhost:9092\n KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT\n KAFKA_INTER_BROKER_LISTENER_NAME: INTERNAL\n\n producer:\n build: ./producer\n ports:\n - '8000:8000'\n environment:\n - KAFKA_BOOTSTRAP_SERVERS=kafka:29092\n depends_on:\n - kafka\n\n consumer:\n build: ./consumer\n environment:\n - KAFKA_BOOTSTRAP_SERVERS=kafka:29092\n - KAFKA_GROUP_ID=my-group\n depends_on:\n - kafka\n\n kafdrop:\n image: obsidiandynamics/kafdrop\n restart: \"no\"\n environment:\n - KAFKA_BOOTSTRAP_SERVERS=kafka:29092\n ports:\n - 9000:9000\n depends_on:\n - kafka\n```\n\n### my producer docker file:\n\n```\nFROM python:3.8-slim-buster\n\nCOPY . /app\nWORKDIR /app\n\nCOPY requirements.txt .\nRUN pip install --no-cache-dir -r requirements.txt\n\nCMD [\"uvicorn\", \"main:app\", \"--host\", \"0.0.0.0\", \"--port\", \"8000\"]\n```\n\n### my producer req file:\n\n```\nfastapi\nuvicorn\nconfluent-kafka\n```\n\n### my producer main.py:\n\n```\nimport json\nfrom confluent_kafka import Producer\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\nproducer_conf = {\n 'bootstrap.servers': 'kafka:9092',\n 'client.id': 'my-app'\n}\n\nproducer = Producer(producer_conf)\n\ndef produce(data: dict):\n try:\n data = json.dumps(data).encode('utf-8')\n producer.produce('my-topic', value=data)\n producer.flush()\n return {\"status\": \"success\", \"message\": data}\n except Exception as e:\n return {\"status\": \"error\", \"message\": str(e)}\n```\n\n### my consumer docker file:\n\n```\nFROM python:3.8-slim-buster\n\nCOPY . /app\nWORKDIR /app\n\nCOPY requirements.txt .\nRUN pip install --no-cache-dir -r requirements.txt\n\nCMD [ \"python\", \"main.py\" ]\n```\n\n### my consumer req file:\n\n```\nconfluent-kafka\n```\n\n### my consumer main.py:\n\n```\nfrom confluent_kafka import Consumer, KafkaError\n\nconf = {\n 'bootstrap.servers': 'kafka:9092',\n 'auto.offset.reset': 'earliest',\n 'enable.auto.commit': True,\n 'group.id': 'my-group',\n 'api.version.request': True,\n 'api.version.fallback.ms': 0\n}\n\ndef consume_messages():\n consumer = Consumer(conf)\n\n consumer.subscribe(['my-topic'])\n\n try:\n while True:\n msg = consumer.poll(1.0)\n\n if msg is None:\n continue\n\n if msg.error():\n if msg.error().code() == KafkaError._PARTITION_EOF:\n print(f'Reached end of partition: {msg.topic()}[{msg.partition()}]')\n else:\n print(f'Error while consuming messages: {msg.error()}')\n else:\n print(f\"Received message: {msg.value().decode('utf-8')}\")\n\n except Exception as e:\n print(f\"Exception occurred while consuming messages: {e}\")\n finally:\n consumer.close()\n\ndef startup():\n consume_messages()\n\nif __name__ == \"__main__\":\n try:\n print(\"Starting consumer...\")\n startup()\n except Exception as e:\n print(f\"Exception occurred: {e}\")\n```\n\n### Build system via:\n\n```\ndocker-compose up\n```\n\n### You can activate the producer with this curl:\n\n```\ncurl -X POST http://localhost:8000/produce -H \"Content-Type: application/json\" -d '{\"key\": \"nice nice nice\"}'\n```\n\nI tried to re-write the consumer multiple times. Changed ports and docker compose configurations. Unfortunatly, I am unable to pin-point my issue.\n\n========================================\n\nCode:\n```yaml\nversion: '3'\n\nservices:\n zookeeper:\n image: confluentinc/cp-zookeeper:latest\n environment:\n ZOOKEEPER_CLIENT_PORT: 2181\n ZOOKEEPER_TICK_TIME: 2000\n ports:\n - 2181:2181\n - 2888:2888\n - 3888:3888\n\n kafka:\n image: confluentinc/cp-kafka:latest\n restart: \"no\"\n links:\n - zookeeper\n ports:\n - 9092:9092\n environment:\n KAFKA_BROKER_ID: 1\n KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1\n KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181\n KAFKA_LISTENERS: INTERNAL://:29092,EXTERNAL://:9092\n KAFKA_ADVERTISED_LISTENERS: INTERNAL://kafka:29092,EXTERNAL://localhost:9092\n KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT\n KAFKA_INTER_BROKER_LISTENER_NAME: INTERNAL\n\n\n producer:\n build: ./producer\n ports:\n - '8000:8000'\n environment:\n - KAFKA_BOOTSTRAP_SERVERS=kafka:29092\n depends_on:\n - kafka\n\n consumer:\n build: ./consumer\n environment:\n - KAFKA_BOOTSTRAP_SERVERS=kafka:29092\n - KAFKA_GROUP_ID=my-group\n depends_on:\n - kafka\n\n kafdrop:\n image: obsidiandynamics/kafdrop\n restart: \"no\"\n environment:\n - KAFKA_BOOTSTRAP_SERVERS=kafka:29092\n ports:\n - 9000:9000\n depends_on:\n - kafka\n```\n\n```text\nFROM python:3.8-slim-buster\n\n\nCOPY . /app\nWORKDIR /app\n\nCOPY requirements.txt .\nRUN pip install --no-cache-dir -r requirements.txt\n\nCMD [\"uvicorn\", \"main:app\", \"--host\", \"0.0.0.0\", \"--port\", \"8000\"]\n```\n\n```text\nfastapi\nuvicorn\nconfluent-kafka\n```\n\n```py\nimport json\nfrom confluent_kafka import Producer\nfrom fastapi import FastAPI\n\n\napp = FastAPI()\n\nproducer_conf = {\n 'bootstrap.servers': 'kafka:9092',\n 'client.id': 'my-app'\n}\n\nproducer = Producer(producer_conf)\n\ndef produce(data: dict):\n try:\n data = json.dumps(data).encode('utf-8')\n producer.produce('my-topic', value=data)\n producer.flush()\n return {\"status\": \"success\", \"message\": data}\n except Exception as e:\n return {\"status\": \"error\", \"message\": str(e)}\n```\n\n```text\nFROM python:3.8-slim-buster\n\nCOPY . /app\nWORKDIR /app\n\nCOPY requirements.txt .\nRUN pip install --no-cache-dir -r requirements.txt\n\n\n\nCMD [ \"python\", \"main.py\" ]\n```\n\n```text\nconfluent-kafka\n```\n\n```py\nfrom confluent_kafka import Consumer, KafkaError\n\nconf = {\n 'bootstrap.servers': 'kafka:9092',\n 'auto.offset.reset': 'earliest',\n 'enable.auto.commit': True,\n 'group.id': 'my-group',\n 'api.version.request': True,\n 'api.version.fallback.ms': 0\n}\n\ndef consume_messages():\n consumer = Consumer(conf)\n\n consumer.subscribe(['my-topic'])\n\n try:\n while True:\n msg = consumer.poll(1.0)\n\n if msg is None:\n continue\n\n if msg.error():\n if msg.error().code() == KafkaError._PARTITION_EOF:\n print(f'Reached end of partition: {msg.topic()}[{msg.partition()}]')\n else:\n print(f'Error while consuming messages: {msg.error()}')\n else:\n print(f\"Received message: {msg.value().decode('utf-8')}\")\n\n except Exception as e:\n print(f\"Exception occurred while consuming messages: {e}\")\n finally:\n consumer.close()\n\ndef startup():\n consume_messages()\n\nif __name__ == \"__main__\":\n try:\n print(\"Starting consumer...\")\n startup()\n except Exception as e:\n print(f\"Exception occurred: {e}\")\n```\n\n```bash\ndocker-compose up\n```\n\n```text\ncurl -X POST http://localhost:8000/produce -H \"Content-Type: application/json\" -d '{\"key\": \"nice nice nice\"}'\n```\n\n```text\ndocker-compose exec kafka kafka-console-consumer.sh --bootstrap-server kafka:9092 --topic my-topic --from-beginning\n```\n\n```yaml\nversion: '3'\n\nservices:\n zookeeper:\n image: confluentinc/cp-zookeeper:latest\n environment:\n ZOOKEEPER_CLIENT_PORT: 2181\n ZOOKEEPER_TICK_TIME: 2000\n ports:\n - 2181:2181\n - 2888:2888\n - 3888:3888\n\n kafka:\n image: confluentinc/cp-kafka:latest\n restart: \"no\"\n links:\n - zookeeper\n ports:\n - 9092:9092\n environment:\n KAFKA_BROKER_ID: 1\n KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1\n KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181\n KAFKA_LISTENERS: INTERNAL://:29092,EXTERNAL://:9092\n KAFKA_ADVERTISED_LISTENERS: INTERNAL://kafka:29092,EXTERNAL://localhost:9092\n KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT\n KAFKA_INTER_BROKER_LISTENER_NAME: INTERNAL\n\n kafdrop:\n image: obsidiandynamics/kafdrop\n restart: \"no\"\n environment:\n KAFKA_BROKERCONNECT: \"kafka:29092\"\n ports:\n - 9000:9000\n depends_on:\n - kafka\n\n producer:\n build: ./producer\n ports:\n - '8000:8000'\n environment:\n - KAFKA_BOOTSTRAP_SERVERS=kafka:29092\n depends_on:\n - kafka\n\n consumer:\n build: ./consumer\n environment:\n - KAFKA_BOOTSTRAP_SERVERS=kafka:29092\n - KAFKA_GROUP_ID=my-group\n depends_on:\n - kafka\n```\n\n```text\nFROM python:3.8-slim-buster\n\n\nCOPY . /app\nWORKDIR /app\n\nCOPY requirements.txt .\nRUN pip install --no-cache-dir -r requirements.txt\n\nCMD [\"uvicorn\", \"main:app\", \"--host\", \"0.0.0.0\", \"--port\", \"8000\"]\n```\n\n```text\nfastapi\nuvicorn\nconfluent-kafka\n```\n\n```py\nimport json\nfrom confluent_kafka import Producer\nfrom fastapi import FastAPI\n\n\napp = FastAPI()\n\nproducer_conf = {\n 'bootstrap.servers': 'kafka:29092',\n 'client.id': 'my-app'\n}\n\nproducer = Producer(producer_conf)\n\n@app.post(\"/produce\")\ndef produce(data: dict):\n producer.produce('my-topic', value=json.dumps(data).encode('utf-8'))\n producer.flush()\n return {\"status\": \"success\"}\n```\n\n```text\nFROM python:3.8-slim-buster\n\nCOPY . /app\nWORKDIR /app\n\nCOPY requirements.txt .\nRUN pip install --no-cache-dir -r requirements.txt\n\n\n\nCMD [ \"python\", \"main.py\" ]\n```\n\n```text\nconfluent-kafka\n```\n\n```py\nfrom confluent_kafka import Consumer, KafkaError\nimport time \n\nimport logging\nlogging.basicConfig(level=logging.DEBUG)\n\n\nconf = {\n 'bootstrap.servers': 'kafka:29092',\n 'auto.offset.reset': 'earliest',\n 'enable.auto.commit': True,\n 'group.id': 'my-group',\n 'api.version.request': True,\n 'api.version.fallback.ms': 0\n}\n\ndef consume_messages():\n consumer = Consumer(conf)\n\n consumer.subscribe(['my-topic'])\n\n try:\n while True:\n msg = consumer.poll(1.0)\n logging.info(\"Polling\")\n logging.info(msg)\n\n if msg is None:\n logging.info(\"No message\")\n continue\n\n if msg.error():\n logging.info(\"Error\")\n if msg.error().code() == KafkaError._PARTITION_EOF:\n print(f'Reached end of partition: {msg.topic()}[{msg.partition()}]')\n else:\n print(f'Error while consuming messages: {msg.error()}')\n logging.info(msg.error())\n else:\n print(f\"Received message: {msg.value().decode('utf-8')}\")\n logging.info(msg.value().decode('utf-8'))\n\n except Exception as e:\n print(f\"Exception occurred while consuming messages: {e}\")\n logging.info(e)\n finally:\n consumer.close()\n logging.info(\"Consumer closed\")\n\n\ndef startup():\n logging.info(\"Starting consumer...\")\n time.sleep(30)\n consume_messages()\n\nif __name__ == \"__main__\":\n try:\n startup()\n except Exception as e:\n print(f\"Exception occurred: {e}\")\n```\n\n```bash\ndocker-compose up\n```\n\n```text\ncurl -X POST http://localhost:8000/produce -H \"Content-Type: application/json\" -d '{\"key\": \"nice nice nice\"}'\n```\n\n========================================\n\nComments:\n- can you please `requirements.txt` for producer and consumer and `docker-compose` commands you used to raise the stack?\n- Hey @rok, I updated the post and included more detail.\n- ok, thanks. Please note, that `kafka-python` is an old package not developed since 2020. In addition,`docker-compose up` fails to raise both producer and consumer... They exit with 1 error code with exception...\n- @rok Interesting, I am able to compose the stack actually. Would you recommend confluent-kafka instead?\n- yes, exactly, as it's supported by Confluent\n- @rok, is confluent-kafka open source? I know that confluent is also offering a paid service. My goal is to develop templates that can be implemented by anyone without the need to create an account on some website etc. Do you have an idea of how to convert my code in the above? Many thanks for your input.\n- Yes the Confluent Python library is open source, but that has nothing to do with the problem here. If you want to use asyncio, use aiokafka\n- @OneCricketeer, could asyncio cause this issue? Just switched the code to confluent-kafka. Will update the code in the above shortly. I am now getting an error from my consumer container saying: thrd:kafka:9092/bootstrap]: kafka:9092/bootstrap: Connect to ipv4#172.19.0.3:9092 failed: Connection refused (after 0ms in state CONNECT, 1 identical error(s) suppressed)\n- 1) Kafka broker doesn't start immediately, so neither should your consumer 2) Please see stackoverflow.com/questions/51630260/…\n- @OneCricketeer, please excuse my basic questions on this but how do I delay the startup of my producer and consumer? Had a look at the link and played further around with my configs but still was not successful. I added Kafdrop to have some more visibility. It's quite odd to me that my producer appears to work as intended. Only the consumer causes issues...thanks again for all the help\n- Producers buffer data and do not send immediately to the brokers, so don't need the server to be available immediately. The consumer, on the other hand need to query for offsets, which may not be available yet... In docker-compose, `depends_on` does not \"wait\". You need to add `time.sleep(10)` for example before you call your startup function\n- @OneCricketeer amazing! this finally worked. Thanks a lot for this. Will post the solution here and create a repo to collect and publish further designs + improvements. Would love to get further feedback from you on this :)\n- You may want a try-except around the producer actions and not default to return `success`\n- @OneCricketeer good point, will update this accordingly\n- @mm117 glad you made it. You can find similar implementation of Kafka Producer and Consumer in Python at my blog","metadata":{"transformedAt":"2026-08-18T18:32:29.160Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":19,"totalLines":623,"estimatedTokens":3907}}742{"id":"stack-73509582","source":"stackoverflow","questionId":73509582,"title":"Initialise fastapi web service fully before listening on port","tags":["python","docker","docker-compose","fastapi","google-cloud-run"],"text":"Title: Initialise fastapi web service fully before listening on port\nTags: python, docker, docker-compose, fastapi, google-cloud-run\nSource: Stack Overflow\n\nQuestion:\nI have a fastapi web app which is running inside of a docker container. The web app hosts multiple machine learning models which on startup it needs to read into memory. This process can take around 30 seconds.\n\nWhat I am trying to achieve is to have the container startup and load all the models, classes etc before listening to any requests. This is useful because on platforms such as Google Cloud Run, you have a max of 4 minutes of startup before your container must start listening to traffic. Right now my container will drop any traffic whilst it is in this startup mode.\n\nI was wondering if there was a way to achieve this either with some docker or fastapi magic!\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI\n\n\ndef fake_answer_to_everything_ml_model(x: float):\n return True\n\n\nml_models = {}\n\napp = FastAPI()\n\n@app.on_event(\"startup\")\nasync def app_startup():\n # Load your ML model:\n ml_models[\"answer_to_everything\"] = fake_answer_to_everything_ml_model\n```\n\n```py\nfrom contextlib import asynccontextmanager\n\nfrom fastapi import FastAPI\n\n\ndef fake_answer_to_everything_ml_model(x: float):\n return True\n\n\nml_models = {}\n\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI):\n # Load your ML model\n ml_models[\"answer_to_everything\"] = fake_answer_to_everything_ml_model\n yield\n # If you want you can define your shutdown logic after the `yield` keyword.\n\n\napp = FastAPI(lifespan=lifespan)\n```\n\n```text\n0.93.0\n```\n\n```text\n0.93.0\n```\n\n========================================\n\nComments:\n- Can you make the loading of models async? Then the startup would be fast, but you could put in an app level dependency that would check if loading is done or not and raises accordingly?\n- That is quite the opposite of what I would like to do (unless I misunderstood you). The models are read from disk, not over a network, so async is no help here I believe. I want the service to first spend time loading the models and only then to signify it is ready for handling traffic.\n- apologies, I misunderstood what you are trying to achieve, ignore my previous comment!\n- It's an interesting question and I've not had cause to need to solve for something like this. I think the solution would be to rely upon HTTP response codes and have your service respond with 503 (unavailable) until it's ready to serve requests.Clients should retry requests until it becomes available. Be mindful that Cloud Run will scale down instances after non-use. If you want to avoid repeated restarts, you'll want to consider keeping a minimum number of instances running (which will incur cost).\n- You may want to consider decomposing the app into a frontend and separate processes to host the models. This way you can scale|deploy the frontend and models independently.\n- @DazWilkin I do think you are correct - this is what I have been thinking about for some time, but will require a large refactor. Do you have any references, or tools which help with such an architecture?\n- It's difficult (and discouraged by Stack overflow) to provide architectural guidance.","metadata":{"transformedAt":"2026-08-18T18:32:29.160Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":74,"estimatedTokens":817}}743{"id":"stack-70740267","source":"stackoverflow","questionId":70740267,"title":"Insert local image in the FastAPI automatic documentation","tags":["python","swagger","markdown","fastapi","openapi"],"text":"Title: Insert local image in the FastAPI automatic documentation\nTags: python, swagger, markdown, fastapi, openapi\nSource: Stack Overflow\n\nQuestion:\n### Introduction\n\nFastAPI can autogenerate your documentation when you are using FastAPI to create an API.\n\nI am trying to insert an image in the description (markdown) of one of my endpoints, but I can't do it when the image is located in the local hardrive.\n\nI have tried to insert it directly (view the end of this post), but it doesn't work.\n\nI have tried to create an endpoint to serve the images, in this case it only works if the IP of the address is my public IP. It doesn't work if I put `localhost` or `127.0.0.1`. I think I am missing something here.\n\n### Minimal example\n\nInstallation:\n\n```\n$ pip install fastapi\n$ pip install \"uvicorn[standard]\"\n```\n\nFile: `main.py`\n\n```\nfrom fastapi import FastAPI\nfrom fastapi.responses import FileResponse\n\napp = FastAPI()\n\n@app.get(\"/\")\ndef read_root():\n return {\"Hello\": \"World\"}\n\n@app.get(\"/my-endpoint\")\ndef example_function():\n \"\"\"\n Documentation for my enpoint. Insert some images\n\n 1) This online image works:\n\n \n \n 2) This local image doesn't work:\n \n \n\n 3) This local image served by the api works if the link is to the public IP:\n\n \n\n 4) This local image served by the api doesn't work because when specified as localhost:\n\n \n\n \n\n \"\"\"\n return {\"This is my endpoint\"}\n\n# An endpoint to serve images for documentation\n@app.get(\"/img/example-photo.jpg\")\nasync def read_image():\n return FileResponse(\"example-photo.jpg\")\n```\n\nExecute the API with the following command:\n\n```\n$ uvicorn main:app --reload --host 0.0.0.0 --port 8000\n```\n\nYou can access the automatic documentation at:\n\n`http://:8000/docs`\n\n### Result of the example\n\nhttps://i.sstatic.net/yO03b.png\n\n### Extra\n\nIn my real case the folder structure is the following:\n\n```\n/myProject/\n|\n|---/docs/\n| |---/img/\n| |---example-photo.jpg\n|\n|---/src/\n |---/myApp/\n |----main.py\n```\n\nIf I try to insert the image directly it doesn't show anything.\n\n```\n\n```\n\n========================================\n\nTop Answer:\nYou can use a relative URL in the documentation, for example:\n\n```\n\n```\n\nThen the browser uses the same domain for accessing the image as it does for fetching the documentation page.\n\n========================================\n\nCode:\n```sh\n$ pip install fastapi\n$ pip install \"uvicorn[standard]\"\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.responses import FileResponse\n\napp = FastAPI()\n\n@app.get(\"/\")\ndef read_root():\n return {\"Hello\": \"World\"}\n\n@app.get(\"/my-endpoint\")\ndef example_function():\n \"\"\"\n Documentation for my enpoint. Insert some images\n\n 1) This online image works:\n\n \n \n 2) This local image doesn't work:\n \n \n\n 3) This local image served by the api works if the link is to the public IP:\n\n \n\n 4) This local image served by the api doesn't work because when specified as localhost:\n\n \n\n \n\n \"\"\"\n return {\"This is my endpoint\"}\n\n\n# An endpoint to serve images for documentation\n@app.get(\"/img/example-photo.jpg\")\nasync def read_image():\n return FileResponse(\"example-photo.jpg\")\n```\n\n```sh\n$ uvicorn main:app --reload --host 0.0.0.0 --port 8000\n```\n\n```text\n/myProject/\n|\n|---/docs/\n| |---/img/\n| |---example-photo.jpg\n|\n|---/src/\n |---/myApp/\n |----main.py\n```\n\n```text\n\n```\n\n```text\nlocalhost\n```\n\n```text\n127.0.0.1\n```\n\n```text\nmain.py\n```\n\n```text\nhttp://<you-ip>:8000/docs\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.responses import FileResponse\nimport os\n\napp = FastAPI()\n\n@app.get(\"/\")\ndef main():\n \"\"\"\n 1) This online image works:\n\n \n\n 2) This local image works:\n\n \n \n 3) This local image works:\n\n \n \"\"\"\n return \"success\"\n\n\n# An endpoint to serve images for documentation\n@app.get(\"/img/{filename}\")\ndef get_img(filename: str):\n filepath = os.path.join('images/', os.path.basename(filename))\n return FileResponse(filepath)\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.responses import FileResponse\nfrom fastapi.staticfiles import StaticFiles\n\napp = FastAPI()\napp.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")\n\n@app.get(\"/\")\ndef main():\n \"\"\"\n 1) This online image works:\n\n \n\n 2) This local image works:\n\n \n \n 3) This local image works:\n\n \n \"\"\"\n return \"success\"\n```\n\n```text\nexample-photo.jpg\n```\n\n```text\nmain.py\n```\n\n```text\nreturn FileResponse(\"example-photo.jpg\")\n```\n\n```text\nimages\n```\n\n```text\nmain.py\n```\n\n```text\nStaticFiles\n```\n\n```text\nstatic\n```\n\n```text\nmain.py\n```\n\n```text\n/static\n```\n\n```text\ndirectory=\"static\"\n```\n\n```text\n\n```\n\n========================================\n\nComments:\n- Thank you, but it doesn't work. If I try the following the image doesn't work. ``\n- How about the example in the answer, starting with the slash (ie., relative to the domain, not to the document address)? The idea is that then the browser would fetch it from the `/img/example-photo.jpg` endpoint you expose in your `read_image` function","metadata":{"transformedAt":"2026-08-18T18:32:29.160Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":22,"totalLines":309,"estimatedTokens":1636}}744{"id":"stack-77897298","source":"stackoverflow","questionId":77897298,"title":"storing and retrieving hashed password in postgres","tags":["python","postgresql","fastapi","bcrypt"],"text":"Title: storing and retrieving hashed password in postgres\nTags: python, postgresql, fastapi, bcrypt\nSource: Stack Overflow\n\nQuestion:\nI am watching a tutorial on FastAPI, where it switched the database from SQLite to PostgreSQL, before generating a token. It was working before but now it has an error, shown below\n\n`return bcrypt.checkpw(password=password_byte_enc, hashed_password=hashed_password) TypeError: argument 'hashed_password': 'str' object cannot be converted to 'PyBytes'`\n\nI think this is the code concerning the error:\n\n```\ndef get_password_hash(password):\n # return bcrypt_context.hash(password)\n pwd_bytes = password.encode('utf-8')\n salt = bcrypt.gensalt()\n hashed_password = bcrypt.hashpw(password=pwd_bytes, salt=salt)\n return hashed_password\n\ndef verify_password(plain_password, hashed_password):\n password_byte_enc = plain_password.encode('utf-8')\n return bcrypt.checkpw(password=password_byte_enc, hashed_password=hashed_password)\n```\n\nThe entirity of the auth.py file is here https://pastebin.com/mHcd0YLU\n\nThis is where I input the username and password to generate a token but it gets an error:\nhttps://i.sstatic.net/oU8cw.png\n\n========================================\n\nCode:\n```text\ndef get_password_hash(password):\n # return bcrypt_context.hash(password)\n pwd_bytes = password.encode('utf-8')\n salt = bcrypt.gensalt()\n hashed_password = bcrypt.hashpw(password=pwd_bytes, salt=salt)\n return hashed_password\n\n\ndef verify_password(plain_password, hashed_password):\n password_byte_enc = plain_password.encode('utf-8')\n return bcrypt.checkpw(password=password_byte_enc, hashed_password=hashed_password)\n```\n\n```text\nreturn bcrypt.checkpw(password=password_byte_enc, hashed_password=hashed_password) TypeError: argument 'hashed_password': 'str' object cannot be converted to 'PyBytes'\n```\n\n```text\ndef get_password_hash(password):\n pwd_bytes = password.encode('utf-8')\n salt = bcrypt.gensalt()\n hashed_password = bcrypt.hashpw(password=pwd_bytes, salt=salt)\n string_password = hashed_password.decode('utf8')\n return string_password\n\n\ndef verify_password(plain_password, hashed_password):\n password_byte_enc = plain_password.encode('utf-8')\n hashed_password = hashed_password.encode('utf-8')\n return bcrypt.checkpw(password_byte_enc, hashed_password)\n```\n\n========================================\n\nComments:\n- It's complaining about `hashed_password` not being a byte string - you're only converting the plain text password. The reason why this changes is because you probably have differing column types in sqlite vs postgres, or their libraries convert those column types to different python types.\n- @MatsLindh when i created the column in postgres it is `hashed_password varchar(200) DEFAULT NULL` i tried also convertion using `hashed_password = hashed_password.encode('utf-8')` `but it gave me an error invalid salt\n- yes, `varchar` will be returned as str - but you might want to look at what `hashed_password` contains then, and verify that it's in the expected format (and that it doesn't suddenly include `b'...'` in the actual string - which can happen if you just use `str` on a bytes sequence before storing it.\n- @MatsLindh looking at pgadmin the hash password is stored as `\\x2432622431322475325a7444453836457945747a726b43477a5a484c4f‌​2e594e49747739587256‌​6f6f666b2f6963364248‌​6b366f494e7450395a6c‌​79`\n- You'll want to confirm what you're getting back from postgres, not what pgadmin is displaying to you (that's a binary value being displayed). Those are hexadecimal values that describe the byte values in your string, so it comes down to what you've actually stored and what you're actually retrieving, and what stage of the process where the problem is. `\\x24\\x32\\x62\\x24\\x31\\x32` is `$2b$12` when decoded, which seems to be the start of the expected hash format.\n- @MatsLindh so used a print to check the user pass input and the db pass, the user pass input does indeed have a `b` at the start, the password is `test1234!` when it is printed in the terminal it is `b'test1234!'`, im a beginner at this so i have no idea how to fix it\n- the hash value is the same when printed `\\x2432622431322475325a7444453836457945747a726b43477a5a484c4f‌​2e594e49747739587256‌​6f6f666b2f6963364248‌​6b366f494e7450395a6c‌​79`","metadata":{"transformedAt":"2026-08-18T18:32:29.160Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":3,"totalLines":75,"estimatedTokens":1097}}745{"id":"stack-71426756","source":"stackoverflow","questionId":71426756,"title":"FastAPI POST request with List input raises 422 Unprocessable Entity error","tags":["python","list","python-requests","fastapi","http-status-code-422"],"text":"Title: FastAPI POST request with List input raises 422 Unprocessable Entity error\nTags: python, list, python-requests, fastapi, http-status-code-422\nSource: Stack Overflow\n\nQuestion:\nI would like to write a `POST` request in which an input parameter is a `list`, but I got error `422 unprocessable entity`:\n\n```\n{\n \"detail\": [\n {\n \"loc\": [\n \"body\"\n ],\n \"msg\": \"field required\",\n \"type\": \"value_error.missing\"\n }\n ]\n}\n```\n\nMy `POST` request is:\n\n```\n@router.post('',status_code=200)\ndef register(reg_id: int, reg_name: str, reg_option_list:List[int]):\n reg_item = My_DB(\n id=reg_id,\n name=reg_name,\n option_list=reg_option_list,\n )\n item = db.query(My_DB).filter(My_DB.id == service_id).first()\n\n if item is not None:\n raise HTTPException(status_code=400, detail=\"Item exists.\")\n db.add(reg_item)\n db.commit()\n return reg_item\n```\n\nBut when I change my code like below, remove list input and set the value in code as a list, everything works fine:\n\n```\n@router.post('',status_code=200)\ndef register(reg_id: int, reg_name: str,):\n reg_item = My_DB(\n id=reg_id,\n name=reg_name,\n option_list=[1,2,3],\n )\n item = db.query(My_DB).filter(My_DB.id == service_id).first()\n\n if item is not None:\n raise HTTPException(status_code=400, detail=\"Item exists.\")\n db.add(reg_item)\n db.commit()\n return reg_item\n```\n\nI will appreciate any help about my `list` input parameter. Thanks.\n\n========================================\n\nCode:\n```text\n{\n \"detail\": [\n {\n \"loc\": [\n \"body\"\n ],\n \"msg\": \"field required\",\n \"type\": \"value_error.missing\"\n }\n ]\n}\n```\n\n```text\n@router.post('',status_code=200)\ndef register(reg_id: int, reg_name: str, reg_option_list:List[int]):\n reg_item = My_DB(\n id=reg_id,\n name=reg_name,\n option_list=reg_option_list,\n )\n item = db.query(My_DB).filter(My_DB.id == service_id).first()\n\n if item is not None:\n raise HTTPException(status_code=400, detail=\"Item exists.\")\n db.add(reg_item)\n db.commit()\n return reg_item\n```\n\n```text\n@router.post('',status_code=200)\ndef register(reg_id: int, reg_name: str,):\n reg_item = My_DB(\n id=reg_id,\n name=reg_name,\n option_list=[1,2,3],\n )\n item = db.query(My_DB).filter(My_DB.id == service_id).first()\n\n if item is not None:\n raise HTTPException(status_code=400, detail=\"Item exists.\")\n db.add(reg_item)\n db.commit()\n return reg_item\n```\n\n```text\nPOST\n```\n\n```text\nlist\n```\n\n```text\n422 unprocessable entity\n```\n\n```text\nPOST\n```\n\n```text\nlist\n```\n\n```py\nfrom fastapi import FastAPI, Query\nfrom typing import List\n\n\napp = FastAPI()\n\n\n@app.get('/')\ndef register(reg_id: int, reg_name: str, reg_options: List[int] = Query(...)):\n return reg_options\n```\n\n```text\nhttp://127.0.0.1:8000/?reg_id=1®_name=foo®_options=1®_options=2®_options=3\n```\n\n```py\nimport requests\n\nurl = 'http://127.0.0.1:8000/?reg_id=1®_name=foo®_options=1®_options=2®_options=3'\nr = requests.get(url)\nprint(r.text)\n```\n\n```py\nimport requests\n\nurl = 'http://127.0.0.1:8000/'\nparams = {'reg_id': 1, 'reg_name': 'foo', 'reg_options': [1, 2, 3]}\nr = requests.get(url, params=params)\nprint(r.text)\n```\n\n```text\nlist\n```\n\n```text\nQuery\n```\n\n```text\nrequest body\n```\n\n```text\nList\n```\n\n```text\nbody\n```\n\n```text\nquery\n```\n\n```text\n422 unprocessable entity\n```\n\n```text\nbody\n```\n\n```text\n/docs\n```\n\n```text\nhttp://127.0.0.1:8000/docs\n```\n\n```text\nreg_option_list\n```\n\n```text\nRequest body\n```\n\n```text\nList\n```\n\n```text\nQuery\n```\n\n```text\nGET\n```\n\n```text\nPOST\n```\n\n```text\nQuery\n```\n\n```text\nList\n```\n\n```text\nList\n```\n\n```text\nPOST\n```\n\n```text\nreg_options\n```\n\n```text\n= Query(...)\n```\n\n========================================\n\nComments:\n- thanks for your answer, I tried this as documentation but got error 500 and \"invalid input syntax for type integer\"\n- I used `option_list = {\"option\": reg_option_list}` and it is about the option value with this details `invalid input syntax for type integer: \"option\"`\n- I edited it to : option_list =[reg_option_list] and it works perfectly.","metadata":{"transformedAt":"2026-08-18T18:32:29.160Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":34,"totalLines":260,"estimatedTokens":1012}}746{"id":"stack-71404138","source":"stackoverflow","questionId":71404138,"title":"FastAPI rejecting POST request from JavaScript code, but not from a 3rd party request application (insomnia)","tags":["javascript","python","http","httprequest","fastapi"],"text":"Title: FastAPI rejecting POST request from JavaScript code, but not from a 3rd party request application (insomnia)\nTags: javascript, python, http, httprequest, fastapi\nSource: Stack Overflow\n\nQuestion:\nWhen I use insomnia to send a post request I get a 200 code and everything works just fine, but when I send a fetch request through javascript, I get a 405 'method not allowed error', even though I've allowed post requests from the server side.\n(Server side code uses python).\n\n**Server side code**\n\n```\nfrom pydantic import BaseModel\nfrom typing import Optional\nfrom fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware\n\napp = FastAPI()\n\norigins = [\"*\"]\napp.add_middleware(\n CORSMiddleware,\n allow_origins=origins,\n allow_credentials=True,\n allow_methods=[\"POST\", \"GET\"],\n allow_headers=[\"*\"],\n)\n\nclass data_format(BaseModel): \n comment_id : int\n username : str\n comment_body : Optional[str] = None\n\n@app.post('/post/submit_post')\nasync def sumbit_post(somename_3: data_format):\n comment_id = somename_3.comment_id\n username = somename_3.username\n comment_body = somename_3.comment_body\n # add_table_data(comment_id, username, comment_body) //Unrelated code\n return {\n 'Response': 'Submission received',\n 'Data' : somename_3\n }\n```\n\n**JS code**\n\n```\nvar payload = {\n \"comment_id\" : 4,\n \"username\" : \"user4\",\n \"comment_body\": \"comment_4\"\n};\nfetch(\"/post/submit_post\",\n{\n method: \"POST\",\n body: JSON.stringify(payload),\n\n headers: {\n 'Content-Type': 'application/json'\n }\n})\n.then(function(res){ return res.json(); })\n.then(function(data){ alert( JSON.stringify( data ) ) })\n```\n\n**The error**\n\nhttps://i.sstatic.net/qJVYH.png\n\nWhat should I do to get around this error?\n\nThanks in advance.\n\n========================================\n\nTop Answer:\nIt's and old issue, described here. You need `Access-Control-Request-Method: POST` header in your request.\n\n========================================\n\nCode:\n```text\nfrom pydantic import BaseModel\nfrom typing import Optional\nfrom fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware\n\napp = FastAPI()\n\norigins = [\"*\"]\napp.add_middleware(\n CORSMiddleware,\n allow_origins=origins,\n allow_credentials=True,\n allow_methods=[\"POST\", \"GET\"],\n allow_headers=[\"*\"],\n)\n\nclass data_format(BaseModel): \n comment_id : int\n username : str\n comment_body : Optional[str] = None\n\n@app.post('/post/submit_post')\nasync def sumbit_post(somename_3: data_format):\n comment_id = somename_3.comment_id\n username = somename_3.username\n comment_body = somename_3.comment_body\n # add_table_data(comment_id, username, comment_body) //Unrelated code\n return {\n 'Response': 'Submission received',\n 'Data' : somename_3\n }\n```\n\n```text\nvar payload = {\n \"comment_id\" : 4,\n \"username\" : \"user4\",\n \"comment_body\": \"comment_4\"\n};\nfetch(\"/post/submit_post\",\n{\n method: \"POST\",\n body: JSON.stringify(payload),\n\n headers: {\n 'Content-Type': 'application/json'\n }\n})\n.then(function(res){ return res.json(); })\n.then(function(data){ alert( JSON.stringify( data ) ) })\n```\n\n```text\nfetch()\n```\n\n```text\n/post/submit_post\n```\n\n```text\nhttp://127.0.0.1:8000/post/submit_post\n```\n\n```text\n405 Method Not Allowed\n```\n\n```text\nPOST\n```\n\n```text\nallow_methods\n```\n\n```text\n400 Bad Request\n```\n\n```text\n405 Method Not Allowed\n```\n\n```text\nAllow\n```\n\n```text\nPOST\n```\n\n```text\n@app.post\n```\n\n```text\n@app.get\n```\n\n```text\nredirect\n```\n\n```text\nPOST\n```\n\n```text\nGET\n```\n\n```text\n303\n```\n\n```text\n*\n```\n\n```text\nallow_methods=['*']\n```\n\n```text\nAccess-Control-Request-Method: POST\n```\n\n========================================\n\nComments:\n- What is the definition of the variable ‘origins‘ and what is the origin of your JavaScript? Seems like there is a mismatch there?\n- @JarroVGIT that was the variable I used for the methods attribute in the middleware. Basically it was methods = origin = ['*']. I thought maybe the asterisk didn't include POST requests, so I specified it directly.\n- I tried adding it to the header list (header list as in the one I've written in the above code right?) but it didn't work.\n- In fact its quite weird, even though I added it to the header list, it doesn't show up on the list of headers in the console. I tried adding a 'test' header, and that worked just fine.\n- I'm sorry but if you don't mind could you elaborate a bit further on what you mean by 'redirecting a post to a get request'? Also, I commented out all the other code in the programme so that the above code is the only thing in it but it still didn't work.\n- If your `/post/submit_post` endpoint triggers a `RedirectResponse` to some `GET` route or other domain, as shown here, this could also be a cause for that error. You said, *\" I commented out all the other code \"*. Have you restarted your application after that? Also, the code you provided works just fine. Have you tried running that code locally, as well as on the hosting service you might be using?\n- I did indeed restart the application plus I'm hosting this on my own computer. Like I said in the initial question, when I use insomnia to send a request I get back the desired response and a 200 code. It's only the JS application that doesn't work. You say that, the code works just fine, does that mean you get a 200 response when you try it? (also I'm certain there's no redirection going on).\n- Yes, the Javascript code works just fine and a `200` status code is returned, plus the response data from that endpoint. If it is hosted on your own PC, then why did you erase the domain in your screenshot? Are you using any other service locally? Also, have you included the domain name in the `fetch` URL (as described in the first paragraph of the answer above), or is it still just `/post/submit_post`?\n- Goddammit I mixed up the server side and JS url format. I'm really sorry for wasting your time, you're right it does work. Regarding the domain name thing, I'm still pretty new to this and I thought that was information was unique (apparently not).","metadata":{"transformedAt":"2026-08-18T18:32:29.161Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":21,"totalLines":222,"estimatedTokens":1533}}747{"id":"stack-77860398","source":"stackoverflow","questionId":77860398,"title":"How to zip multiple csv files into archive and return it in FastAPI?","tags":["python","python-3.x","csv","zip","fastapi"],"text":"Title: How to zip multiple csv files into archive and return it in FastAPI?\nTags: python, python-3.x, csv, zip, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm attempting to compose a response to enable the download of reports. I retrieve the relevant data through a database query and aim to store it in memory to avoid generating unnecessary files on the server. My current challenge involves saving the CSV file within a zip file. Regrettably, I've spent several hours on this issue without finding a satisfactory solution, and I'm uncertain about the specific mistake I may be making. The CSV file in question is approximately 40 MB in size.\n\nThis is my FastAPI code. I successfully saved the CSV file locally, and all the data within it is accurate. I also managed to correctly create a zip file containing the CSV. However, the FastAPI response is not behaving as expected. After downloading it returns me zip with error:\n\nThe ZIP file is corrupted, or there's an unexpected end of the archive.\n\n```\nfrom fastapi import APIRouter, Depends\nfrom sqlalchemy import text\nfrom libs.auth_common import veryfi_admin\nfrom libs.database import database\nimport csv\nimport io\nimport zipfile\nfrom fastapi.responses import Response\n\nrouter = APIRouter(\n tags=['report'],\n responses={404: {'description': 'not found'}}\n)\n\n@router.get('/raport', dependencies=[Depends(veryfi_admin)])\nasync def get_raport():\n query = text(\n \"\"\"\n some query\n \"\"\"\n )\n\n data_de = await database.fetch_all(query)\n\n csv_buffer = io.StringIO()\n csv_writer_de = csv.writer(csv_buffer, delimiter=';', lineterminator='\\n')\n\n csv_writer_de.writerow([\n \"id\", \"name\", \"date\", \"stock\",\n ])\n\n for row in data_de:\n csv_writer_de.writerow([\n row.id,\n row.name,\n row.date,\n row.stock,\n\n ])\n csv_buffer.seek(0)\n\n zip_buffer = io.BytesIO()\n with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zip_file:\n zip_file.writestr(\"data.csv\", csv_buffer.getvalue())\n\n response = Response(content=zip_buffer.getvalue())\n response.headers[\"Content-Disposition\"] = \"attachment; filename=data.zip\"\n response.headers[\"Content-Type\"] = \"application/zip\"\n response.headers[\"Content-Length\"] = str(len(zip_buffer.getvalue()))\n\n print(\"CSV Buffer Contents:\")\n print(csv_buffer.getvalue())\n return response\n```\n\nHere is also the vue3 code\n\n```\nconst downloadReport = () => {\n loading.value = true;\n instance\n .get(`/raport`)\n .then((res) => {\n const blob = new Blob([res.data], { type: \"application/zip\" });\n const link = document.createElement(\"a\");\n link.href = window.URL.createObjectURL(blob);\n link.download = \"raport.zip\";\n link.click();\n loading.value = false;\n })\n .catch(() => (loading.value = false));\n};\n\n Download Report\n\n```\n\nThank you for your understanding as I navigate through my first question on this platform.\n\n========================================\n\nCode:\n```text\nfrom fastapi import APIRouter, Depends\nfrom sqlalchemy import text\nfrom libs.auth_common import veryfi_admin\nfrom libs.database import database\nimport csv\nimport io\nimport zipfile\nfrom fastapi.responses import Response\n\nrouter = APIRouter(\n tags=['report'],\n responses={404: {'description': 'not found'}}\n)\n\n\n@router.get('/raport', dependencies=[Depends(veryfi_admin)])\nasync def get_raport():\n query = text(\n \"\"\"\n some query\n \"\"\"\n )\n\n data_de = await database.fetch_all(query)\n\n csv_buffer = io.StringIO()\n csv_writer_de = csv.writer(csv_buffer, delimiter=';', lineterminator='\\n')\n\n csv_writer_de.writerow([\n \"id\", \"name\", \"date\", \"stock\",\n ])\n\n for row in data_de:\n csv_writer_de.writerow([\n row.id,\n row.name,\n row.date,\n row.stock,\n\n ])\n csv_buffer.seek(0)\n\n zip_buffer = io.BytesIO()\n with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zip_file:\n zip_file.writestr(\"data.csv\", csv_buffer.getvalue())\n\n response = Response(content=zip_buffer.getvalue())\n response.headers[\"Content-Disposition\"] = \"attachment; filename=data.zip\"\n response.headers[\"Content-Type\"] = \"application/zip\"\n response.headers[\"Content-Length\"] = str(len(zip_buffer.getvalue()))\n\n print(\"CSV Buffer Contents:\")\n print(csv_buffer.getvalue())\n return response\n```\n\n```text\nconst downloadReport = () => {\n loading.value = true;\n instance\n .get(`/raport`)\n .then((res) => {\n const blob = new Blob([res.data], { type: \"application/zip\" });\n const link = document.createElement(\"a\");\n link.href = window.URL.createObjectURL(blob);\n link.download = \"raport.zip\";\n link.click();\n loading.value = false;\n })\n .catch(() => (loading.value = false));\n};\n<button @click=\"downloadReport\" :disabled=\"loading\">\n Download Report\n</button>\n```\n\n```py\nfrom fastapi import FastAPI, HTTPException, BackgroundTasks, Response\nimport zipfile\nimport csv\nimport io\n\n\napp = FastAPI()\n\n\nfake_data = [\n {\n \"Id\": \"1\",\n \"name\": \"Alice\",\n \"age\": \"20\",\n \"height\": \"62\",\n \"weight\": \"120.6\"\n },\n {\n \"Id\": \"2\",\n \"name\": \"Freddie\",\n \"age\": \"21\",\n \"height\": \"74\",\n \"weight\": \"190.6\"\n }\n]\n\n\ndef create_csv(data: list):\n s = io.StringIO()\n try:\n writer = csv.writer(s, delimiter='\\t')\n writer.writerow(data[0].keys())\n for row in data:\n writer.writerow([row['Id'], row['name'], row['age'], row['height'], row['weight']])\n s.seek(0)\n return s.getvalue().encode('utf-16')\n except:\n raise HTTPException(detail='There was an error processing the data', status_code=400)\n finally:\n s.close()\n\n\n@app.get('/')\ndef get_data():\n zip_buffer = io.BytesIO()\n try:\n with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zip_file:\n for i in range(5):\n zip_info = zipfile.ZipInfo(f'data_{i}.csv')\n csv_data = create_csv(fake_data)\n zip_file.writestr(zip_info, csv_data)\n \n zip_buffer.seek(0)\n headers = {\"Content-Disposition\": \"attachment; filename=files.zip\"}\n return Response(zip_buffer.getvalue(), headers=headers, media_type=\"application/zip\")\n except:\n raise HTTPException(detail='There was an error processing the data', status_code=400)\n finally:\n zip_buffer.close()\n```\n\n```text\ncsv\n```\n\n```text\nzip\n```\n\n```text\nzip\n```\n\n```text\nzipfile\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\nasync\n```\n\n```text\nawait\n```\n\n```text\nasync def\n```\n\n```text\nzipfile\n```\n\n```text\nThreadPool\n```\n\n```text\nasync\n```\n\n```text\nawait\n```\n\n```text\nasync def\n```\n\n```text\ndef\n```\n\n```text\nStreamingResponse\n```\n\n```text\nResponse\n```\n\n```text\nutf-16\n```\n\n```text\ncsv\n```\n\n```text\nutf-8\n```\n\n```text\nlist\n```\n\n```text\ndict\n```\n\n```text\ncsv\n```\n\n```text\ncsv.DictWriter()\n```\n\n```text\nwriterows()\n```\n\n```text\nlist\n```\n\n========================================\n\nComments:\n- did you try with StreamingResponse or FileResponse?\n- Yes I tried with StreamingResponse and FileResponse but it didn't work either @AminTaghikhani\n- Because there will be several queries and I would like to save all the csv to one zip to make it easier to download them. @Chris","metadata":{"transformedAt":"2026-08-18T18:32:29.161Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":29,"totalLines":343,"estimatedTokens":1788}}748{"id":"stack-73688641","source":"stackoverflow","questionId":73688641,"title":"How to stream DataFrame using FastAPI without saving the data to csv file?","tags":["python","pandas","dataframe","csv","fastapi"],"text":"Title: How to stream DataFrame using FastAPI without saving the data to csv file?\nTags: python, pandas, dataframe, csv, fastapi\nSource: Stack Overflow\n\nQuestion:\nI would like to know how to stream a DataFrame using FastAPI without having to save the DataFrame to a csv file on disk. Currently, what I managed to do is to stream data from the csv file, but the speed was not very fast compared to returning a `FileResponse`. The `/option7` below is what I'm trying to do.\n\nMy goal is to stream data from FastAPI backend without saving the DataFrame to a csv file.\n\nThank you.\n\n```\nfrom fastapi import FastAPI, Response,Query\nfrom fastapi.responses import FileResponse,HTMLResponse,StreamingResponse\napp = FastAPI()\n\ndf = pd.read_csv(\"data.csv\")\n\n@app.get(\"/option4\")\ndef load_questions():\n return FileResponse(path=\"C:Downloads/data.csv\", filename=\"data.csv\")\n\n@app.get(\"/option5\")\ndef load_questions():\n def iterfile(): # \n with open('data.csv', mode=\"rb\") as file_like: # \n yield from file_like # \n\n return StreamingResponse(iterfile(), media_type=\"text/csv\")\n\n@app.get(\"/option7\")\ndef load_questions():\n def iterfile(): # \n #with open(df, mode=\"rb\") as file_like: # \n yield from df # \n\n return StreamingResponse(iterfile(), media_type=\"application/json\")\n```\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI, Response,Query\nfrom fastapi.responses import FileResponse,HTMLResponse,StreamingResponse\napp = FastAPI()\n\ndf = pd.read_csv(\"data.csv\")\n\n@app.get(\"/option4\")\ndef load_questions():\n return FileResponse(path=\"C:Downloads/data.csv\", filename=\"data.csv\")\n\n@app.get(\"/option5\")\ndef load_questions():\n def iterfile(): # \n with open('data.csv', mode=\"rb\") as file_like: # \n yield from file_like # \n\n return StreamingResponse(iterfile(), media_type=\"text/csv\")\n\n@app.get(\"/option7\")\ndef load_questions():\n def iterfile(): # \n #with open(df, mode=\"rb\") as file_like: # \n yield from df # \n\n return StreamingResponse(iterfile(), media_type=\"application/json\")\n```\n\n```text\nFileResponse\n```\n\n```text\n/option7\n```\n\n```py\nfrom fastapi import Response\n\n@app.get(\"/\")\ndef main():\n return Response(df.to_json(orient=\"records\"), media_type=\"application/json\")\n```\n\n```py\n@app.get(\"/\")\ndef main():\n headers = {'Content-Disposition': 'attachment; filename=\"data.json\"'}\n return Response(df.to_json(orient=\"records\"), headers=headers, media_type='application/json')\n```\n\n```py\n@app.get(\"/\")\ndef main():\n headers = {'Content-Disposition': 'attachment; filename=\"data.csv\"'}\n return Response(df.to_csv(), headers=headers, media_type=\"text/csv\")\n```\n\n```py\n@app.get(\"/\")\ndef main():\n def iter_df():\n for _, row in df.iterrows():\n yield json.dumps(row.to_dict()) + '\\n'\n\n return StreamingResponse(iter_df(), media_type=\"application/json\")\n```\n\n```py\nfrom fastapi import BackgroundTasks\nfrom fastapi.responses import FileResponse \nimport uuid\nimport os\n\n@app.get(\"/\")\ndef main(background_tasks: BackgroundTasks):\n filename = str(uuid.uuid4()) + \".csv\"\n df.to_csv(filename)\n del df # release the memory\n background_tasks.add_task(os.remove, filename) \n return FileResponse(filename, filename=\"data.csv\", media_type=\"text/csv\")\n # or return StreamingResponse - see the linked answers above\n```\n\n```text\nDataFrame\n```\n\n```text\nStreamingResponse\n```\n\n```text\nStreamingResponse\n```\n\n```text\nDataFrame\n```\n\n```text\nResponse\n```\n\n```text\n.to_json()\n```\n\n```text\nDataFrame\n```\n\n```text\n.json\n```\n\n```text\nContent-Disposition\n```\n\n```text\nResponse\n```\n\n```text\nattachment\n```\n\n```text\n.csv\n```\n\n```text\n.to_csv()\n```\n\n```text\nreturn df.to_csv()\n```\n\n```text\n\\r\\n\n```\n\n```text\nResponse\n```\n\n```text\nContent-Disposition\n```\n\n```text\n.csv\n```\n\n```text\nStreamingResponse\n```\n\n```text\nDataFrame\n```\n\n```text\njson\n```\n\n```text\nbyte\n```\n\n```text\n\"iter\"\n```\n\n```text\n.to_json()\n```\n\n```text\n.to_csv()\n```\n\n```text\nDataFrame\n```\n\n```text\nDataFrame\n```\n\n```text\nStreamingResponse\n```\n\n```text\niterrows()\n```\n\n```text\norjson\n```\n\n```text\nujson\n```\n\n```text\nNamedTemporaryFile\n```\n\n```text\nDataFrame\n```\n\n```text\ngc.collect()\n```\n\n```text\nFileResponse\n```\n\n```text\nStreamingResponse\n```\n\n```text\nBackgroundTask\n```\n\n```text\nDataFrame\n```\n\n```text\ndef\n```\n\n```text\nrun_in_threadpool()\n```\n\n```text\nconcurrency\n```\n\n```text\nto_csv()\n```\n\n```text\nto_json()\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\nasync def\n```\n\n========================================\n\nComments:\n- There is no dataframe in this question that I could see?\n- yeah, because the code that i build for dataframe didnt work\n- Does this answer your question? How to return a .csv file/Pandas DataFrame in JSON format using FastAPI?\n- Thanks for your reply, i tried these function but issue is that i have huge data and if i make options in the link then my ram will be full\n- Why even use Pandas to load a CSV into a DF if you're just going to emit the same CSV anyway..?\n- currently what im doing is saving the dataframe as csv after i did full prepossing in order to make it accessible in api. i need a way to eliminate the need for saving dataframe as csv\n- @new_dev a dataframe isn't a file format. It's an in-memory data structure. If you want to send its data to a caller you'll have to serialize it to some file format that the client can understand. It could be any format: JSON, CSV, parquet, whatever you want.\n- @new_dev where does the data come from in the first place? Why not send that data directly instead of loading it into a dataframe first? If your data is in a CSV file, just send the file\n- @Chris not exactly. `to_csv()` without a path will do the same. In either cases, the entire string will be allocated in memory before it's returned. That's not scalable.\n- `to_csv()` without a path will do the same. Whether `to_json()` or `to_csv()` is used though, the entire output string will be allocated in memory, doubling RAM usage or worse. There's a *very* good reason to search for streaming instead of allocating the entire string in memory.","metadata":{"transformedAt":"2026-08-18T18:32:29.161Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":54,"totalLines":323,"estimatedTokens":1511}}749{"id":"stack-78739451","source":"stackoverflow","questionId":78739451,"title":"Get path template from starlette request from a middleware","tags":["python","fastapi","starlette","asgi"],"text":"Title: Get path template from starlette request from a middleware\nTags: python, fastapi, starlette, asgi\nSource: Stack Overflow\n\nQuestion:\nI am building a middleware to log calls to functions among other things.\nI have read about\nFastAPI: How to get raw URL path from request?, which suggests to use `request.scope.get(\"route\")`, which works when used in the endpoint function. However, in the middleware, request.scope has no attribute \"route\". I am unsure of what a scope really is and why it changes in the middleware, but how can i work around this ?\n\n```\n@app.get(\"/success/{id}\", status_code=201)\ndef success():\n return \n\napp.add_middleware(RequestInfo)\n```\n\n```\nfrom starlette.middleware.base import BaseHTTPMiddleware\nfrom fastapi import Request\n\nclass RequestInfo(BaseHTTPMiddleware):\n async def dispatch(self, request: Request, call_next):\n logger.info(\"Hello\")\n # Doing some things\n```\n\n========================================\n\nTop Answer:\nThis is old but I actually found a solution to to this for anyone else searching.\n\nI'm not exactly sure when this was added, but I ran into the same problem when I was trying to filter metrics sent to Prometheus for scraping and I found this solution in a github showing a Grafana setup for FastAPI/Prometheus (https://github.com/blueswen/fastapi-observability/blob/main/fastapi_app/utils.py)\n\nThe fastapi APIRoute class has this method `matches(self, scope: Scope) -> Tuple[str, Scope]` that returns the matching generic route.\n\nSo if you add the following classmethod to your middleware like so:\n\n```\n@staticmethod\ndef get_route(request: Request) -> str:\n for route in request.app.routes:\n match, _ = route.matches(request.scope)\n if match == Match.FULL:\n return route.path\n return request.url.path\n```\n\nYou can use `self.get_route(request)` before `call_next` is awaited to get the route.\n\n========================================\n\nCode:\n```text\n@app.get(\"/success/{id}\", status_code=201)\ndef success():\n return \n\napp.add_middleware(RequestInfo)\n```\n\n```text\nfrom starlette.middleware.base import BaseHTTPMiddleware\nfrom fastapi import Request\n\nclass RequestInfo(BaseHTTPMiddleware):\n async def dispatch(self, request: Request, call_next):\n logger.info(\"Hello\")\n # Doing some things\n```\n\n```text\nrequest.scope.get(\"route\")\n```\n\n```text\nfrom typing import Callable\nfrom fastapi import FastAPI\nfrom fastapi.routing import APIRoute\n\nclass LoggingRouter(APIRoute):\n def get_route_handler(self) -> Callable:\n print(self.dependant.path)\n return super().get_route_handler()\n\napp = FastAPI()\napp.router.route_class = LoggingRouter\n\n@app.get(\"/success/{id}\", status_code=201)\ndef success(id: str):\n return id\n```\n\n```text\n@staticmethod\ndef get_route(request: Request) -> str:\n for route in request.app.routes:\n match, _ = route.matches(request.scope)\n if match == Match.FULL:\n return route.path\n return request.url.path\n```\n\n```text\nmatches(self, scope: Scope) -> Tuple[str, Scope]\n```\n\n```text\nself.get_route(request)\n```\n\n```text\ncall_next\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.161Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":8,"totalLines":114,"estimatedTokens":766}}750{"id":"stack-66142981","source":"stackoverflow","questionId":66142981,"title":"How to redirect FastAPI Documentation while running on Docker","tags":["python","docker","dockerfile","backend","fastapi"],"text":"Title: How to redirect FastAPI Documentation while running on Docker\nTags: python, docker, dockerfile, backend, fastapi\nSource: Stack Overflow\n\nQuestion:\nI need to redirect \"**/swagger-ui.html**\" to the documentation page.\n\nI tried:\n\n```\napp = FastAPI()\n\n@app.get(\"/swagger-ui.html\")\nasync def docs_redirect():\n response = RedirectResponse(url='/docs')\n return response\n```\n\nand\n\n```\napp = FastAPI(docs_url=\"/swagger-ui.html\")\n\n@app.get(\"/\")\nasync def docs_redirect():\n response = RedirectResponse(url='/swagger-ui.html')\n return response\n```\n\nBut, running the project directly (using uvicorn command) I works, but when I put it on a Docker container, it outputs this message on the browser, asking for the location, where nothing works as input:\n\nUnable to infer base url. This is common when using dynamic servlet\nregistration or when the API is behind an API Gateway. The base url is\nthe root of where all the swagger resources are served. For e.g. if\nthe api is available at http://example.org/api/v2/api-docs then the\nbase url is http://example.org/api/. Please enter the location\nmanually:\n\nHere's my dockerfile:\n\n```\nFROM python:3.8\nUSER root\nRUN mkdir -p /usr/local/backend\nWORKDIR /usr/local/backend\nEXPOSE 8080\nARG BUILD_ENV=dev \nENV BUILD_ENV=$BUILD_ENV\nCOPY . /usr/local/backend\nRUN pip install -r requirements.txt\nENTRYPOINT [\"uvicorn\", \"app.main:app\", \"--port\", \"8080\"]\n```\n\n========================================\n\nTop Answer:\nTo avoid showing the redirect in the docs page\n\n```\n@app.get(\"/\", include_in_schema=False)\nasync def docs_redirect():\n return RedirectResponse(url='/docs')\n```\n\nDocumentation here: https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/#exclude-from-openapi\n\n========================================\n\nCode:\n```text\napp = FastAPI()\n\n@app.get(\"/swagger-ui.html\")\nasync def docs_redirect():\n response = RedirectResponse(url='/docs')\n return response\n```\n\n```text\napp = FastAPI(docs_url=\"/swagger-ui.html\")\n\n@app.get(\"/\")\nasync def docs_redirect():\n response = RedirectResponse(url='/swagger-ui.html')\n return response\n```\n\n```text\nFROM python:3.8\nUSER root\nRUN mkdir -p /usr/local/backend\nWORKDIR /usr/local/backend\nEXPOSE 8080\nARG BUILD_ENV=dev \nENV BUILD_ENV=$BUILD_ENV\nCOPY . /usr/local/backend\nRUN pip install -r requirements.txt\nENTRYPOINT [\"uvicorn\", \"app.main:app\", \"--port\", \"8080\"]\n```\n\n```py\nfrom fastapi.responses import RedirectResponse\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/\")\nasync def docs_redirect():\n return RedirectResponse(url='/docs')\n```\n\n```text\ndocker-compose\n```\n\n```py\n@app.get(\"/\", include_in_schema=False)\nasync def docs_redirect():\n return RedirectResponse(url='/docs')\n```\n\n========================================\n\nComments:\n- `from starlette.responses import RedirectResponse`\n- `from fastapi.responses import RedirectResponse`\n- Adding `include_in_schema=False` in the decorator will exclude this endpoint from showing in the Swagger UI","metadata":{"transformedAt":"2026-08-18T18:32:29.161Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":6,"totalLines":127,"estimatedTokens":742}}751{"id":"stack-79573221","source":"stackoverflow","questionId":79573221,"title":"Keep context vars values between FastAPI/starlette middlewares depending on the middleware order","tags":["python","fastapi","starlette","python-contextvars","fastapi-middleware"],"text":"Title: Keep context vars values between FastAPI/starlette middlewares depending on the middleware order\nTags: python, fastapi, starlette, python-contextvars, fastapi-middleware\nSource: Stack Overflow\n\nQuestion:\nI am developing a FastAPI app, and my goal is to record some information in a Request scope and then reuse this information later in log records.\n\nMy idea was to use context vars to store the \"request context\", use a middleware to manipulate the request and set the context var, and finally use a LogFilter to attach the context vars values to the LogRecord.\n\nThis is my app skeleton\n\n```\nlogger = logging.getLogger(__name__)\napp = FastAPI()\napp.add_middleware(SetterMiddlware)\napp.add_middleware(FooMiddleware)\n\n@app.get(\"/\")\ndef read_root(setter = Depends(set_request_id)):\n print(\"Adding req_id to body\", req_id.get()) # This is 1234567890\n logging.info(\"hello\")\n return {\"Req_id\": str(req_id.get())}\n```\n\nand those are my middlewares\n\n```\nclass SetterMiddlware(BaseHTTPMiddleware):\n async def dispatch(self, request: Request, call_next):\n calculated_id = \"1234567890\"\n req_id.set(calculated_id)\n request.state.req_id = calculated_id\n response = await call_next(request)\n return response\n\nclass FooMiddleware(BaseHTTPMiddleware):\n async def dispatch(self, request: Request, call_next):\n response = await call_next(request)\n return response\n```\n\nand the Logging Filter\n\n```\nfrom vars import req_id\n\nclass CustomFilter(Filter):\n \"\"\"Logging filter to attach the user's authorization to log records\"\"\"\n\n def filter(self, record: LogRecord) -> bool:\n\n record.req_id = req_id.get()\n return True\n```\n\nAnd finally following a part of my log configuration\n\n```\n...\n\"formatters\": {\n \"default\": {\n \"format\": \"%(levelname)-9s %(asctime)s [%(req_id)s]| %(message)s\",\n \"datefmt\": \"%Y-%m-%d,%H:%M:%S\",\n },\n },\n \"handlers\": {\n...\n\"handlers\": {\n \"console\": {\n \"class\": \"logging.StreamHandler\",\n \"formatter\": \"default\",\n \"stream\": \"ext://sys.stderr\",\n \"filters\": [\n \"custom_filter\",\n ],\n \"level\": logging.NOTSET,\n },\n...\n\"loggers\": {\n \"\": {\n \"handlers\": [\"console\"],\n \"level\": logging.DEBUG,\n },\n \"uvicorn\": {\"handlers\": [\"console\"], \"propagate\": False},\n },\n```\n\nWhen `SetterMiddlware` is the latest added in the app (`FooMiddleware` commented in the example), my app logs as expected\n\n```\nAdding req_id to body 1234567890\nINFO 2025-04-14,15:02:28 [1234567890]| hello\nINFO 2025-04-14,15:02:28 [1234567890]| 127.0.0.1:52912 - \"GET / HTTP/1.1\" 200\n```\n\nBut if I add some other middleware after `SetterMiddlware`, uvicorn logger does not find anymore the context_var `req_id` set.\n\n```\nAdding req_id to body 1234567890\nINFO 2025-04-14,15:03:56 [1234567890]| hello\nINFO 2025-04-14,15:03:56 [None]| 127.0.0.1:52919 - \"GET / HTTP/1.1\" 200\n```\n\nI tried using the package `https://starlette-context.readthedocs.io/en/latest/` but I wasn't luckier; it looks like it suffers the same problems.\n\nI would like to know why this behavior happens and how I can fix it, without the constraint of having the SetterMiddleware in the last middleware position.\n\n========================================\n\nTop Answer:\nThe problem most likely lies in that if you are using FastAPI/Starlette with synchronous code (in opposition to assynchronous code, with `async def`'ed calls everywhere), the framework code has to call your functions in other *threads* -\n\nAnd upon making a call in other thread to call your view (likely with asyncio's `loop.run_in_executor` ) - your view will get an unitialized context in the other thread - the contextvar values set on the main loop thread won't be available there.\n\n(For what is now a side note, Commit a214db0c to main CPython code made on 2025-04-10 (aka last Thursday) creates a new feature in the language itself that will make this possible - as an opt-in for the frameworks - but that is for Python 3.14 onwards (post Oct. 2025) )\n\nIn my package \"extracontext\" I also offer an alternative `executor` class which can preserve the contextvar values across threads - but that can only be used when YOUR code is the one making the `loop.run_in_executor` call - in this example, the code making this is the framework code, and it calls your view.\n\nREPL snippet demonstrating the issue:\n\n```\nIn [1]: import contextvars, threading\n\nIn [2]: var = contextvars.ContextVar(\"var\", default=\"root value\")\n\nIn [3]: def onthread():\n ...: print(var.get())\n ...: \n\nIn [4]: async def middleware():\n ...: var.set(\"child value\")\n ...: loop = asyncio.get_running_loop()\n ...: await loop.run_in_executor(None, onthread)\n ...: print(var.get())\n ...: \n\nIn [5]: import asyncio\n\nIn [6]: asyncio.run(middleware()); print(var.get())\nroot value\nchild value\nroot value\n```\n\n### Too complex! What to do?\n\nThe simple fix is move all your code do async code: in the case of views, just declare them with `async def` - if you are performing no I/O (external network requests, database queries, etc) in your view, that is as simple as that. If you are, you have to turn that calls into asynchronous (and then, the way to do that requiring fewer modifications is to place all synchronous calls in `loop.run_in_executor` calls yourself) - but that should make the contextvars values available in your view.\n\n```\n@app.get(\"/\")\nasync def read_root(setter = Depends(set_request_id)):\n print(\"Adding req_id to body\", req_id.get()) # This is 1234567890\n logging.info(\"hello\")\n # need to make long network request with \"requests\":\n loop = asyncio.get_running_loop()\n result = await loop.run_in_executor(None, requests.get, )\n ...\n \n return {\"Req_id\": str(req_id.get())}\n```\n\n========================================\n\nCode:\n```py\nlogger = logging.getLogger(__name__)\napp = FastAPI()\napp.add_middleware(SetterMiddlware)\napp.add_middleware(FooMiddleware)\n\n@app.get(\"/\")\ndef read_root(setter = Depends(set_request_id)):\n print(\"Adding req_id to body\", req_id.get()) # This is 1234567890\n logging.info(\"hello\")\n return {\"Req_id\": str(req_id.get())}\n```\n\n```py\nclass SetterMiddlware(BaseHTTPMiddleware):\n async def dispatch(self, request: Request, call_next):\n calculated_id = \"1234567890\"\n req_id.set(calculated_id)\n request.state.req_id = calculated_id\n response = await call_next(request)\n return response\n\nclass FooMiddleware(BaseHTTPMiddleware):\n async def dispatch(self, request: Request, call_next):\n response = await call_next(request)\n return response\n```\n\n```py\nfrom vars import req_id\n\n\nclass CustomFilter(Filter):\n \"\"\"Logging filter to attach the user's authorization to log records\"\"\"\n\n def filter(self, record: LogRecord) -> bool:\n\n record.req_id = req_id.get()\n return True\n```\n\n```py\n...\n\"formatters\": {\n \"default\": {\n \"format\": \"%(levelname)-9s %(asctime)s [%(req_id)s]| %(message)s\",\n \"datefmt\": \"%Y-%m-%d,%H:%M:%S\",\n },\n },\n \"handlers\": {\n...\n\"handlers\": {\n \"console\": {\n \"class\": \"logging.StreamHandler\",\n \"formatter\": \"default\",\n \"stream\": \"ext://sys.stderr\",\n \"filters\": [\n \"custom_filter\",\n ],\n \"level\": logging.NOTSET,\n },\n...\n\"loggers\": {\n \"\": {\n \"handlers\": [\"console\"],\n \"level\": logging.DEBUG,\n },\n \"uvicorn\": {\"handlers\": [\"console\"], \"propagate\": False},\n },\n```\n\n```console\nAdding req_id to body 1234567890\nINFO 2025-04-14,15:02:28 [1234567890]| hello\nINFO 2025-04-14,15:02:28 [1234567890]| 127.0.0.1:52912 - \"GET / HTTP/1.1\" 200\n```\n\n```console\nAdding req_id to body 1234567890\nINFO 2025-04-14,15:03:56 [1234567890]| hello\nINFO 2025-04-14,15:03:56 [None]| 127.0.0.1:52919 - \"GET / HTTP/1.1\" 200\n```\n\n```text\nSetterMiddlware\n```\n\n```text\nFooMiddleware\n```\n\n```text\nSetterMiddlware\n```\n\n```text\nreq_id\n```\n\n```text\nhttps://starlette-context.readthedocs.io/en/latest/\n```\n\n```py\nfrom starlette.types import ASGIApp, Receive, Scope, Send\n\nclass SetterMiddlware:\n def __init__(self, app: ASGIApp) -> None:\n self.app = app\n\n async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:\n calculated_id = \"1234567890\"\n req_id.set(calculated_id)\n request = Request(scope, receive)\n request.state.req_id = calculated_id\n response = await self.app(scope, receive, send)\n return response\n\nclass FooMiddleware:\n def __init__(self, app: ASGIApp) -> None:\n self.app = app\n\n async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:\n response = await self.app(scope, receive, send)\n return response\n```\n\n```text\nBaseHTTPMiddleware\n```\n\n```text\nBaseHTTPMiddleware\n```\n\n```text\nIn [1]: import contextvars, threading\n\nIn [2]: var = contextvars.ContextVar(\"var\", default=\"root value\")\n\nIn [3]: def onthread():\n ...: print(var.get())\n ...: \n\nIn [4]: async def middleware():\n ...: var.set(\"child value\")\n ...: loop = asyncio.get_running_loop()\n ...: await loop.run_in_executor(None, onthread)\n ...: print(var.get())\n ...: \n\nIn [5]: import asyncio\n\nIn [6]: asyncio.run(middleware()); print(var.get())\nroot value\nchild value\nroot value\n```\n\n```py\n@app.get(\"/\")\nasync def read_root(setter = Depends(set_request_id)):\n print(\"Adding req_id to body\", req_id.get()) # This is 1234567890\n logging.info(\"hello\")\n # need to make long network request with \"requests\":\n loop = asyncio.get_running_loop()\n result = await loop.run_in_executor(None, requests.get, <*args_to_requests.get>)\n ...\n \n return {\"Req_id\": str(req_id.get())}\n```\n\n```text\nasync def\n```\n\n```text\nloop.run_in_executor\n```\n\n```text\nexecutor\n```\n\n```text\nloop.run_in_executor\n```\n\n```text\nasync def\n```\n\n```text\nloop.run_in_executor\n```\n\n========================================\n\nComments:\n- Did you try reversing the order of the middlewares? The middlewares are executed in the reverse order of their addition.\n- @npk I know about the order, and they were in that order for a dependency reason unfortuntaly\n- thank you for the answer. The problem persists even with async routes. And the weird stuff is that the route can access the context vars and find it set properly; it's just the uvicorn logger that can't. I was thinking about something like you said about the context copy, but in that case I would expect that alsot he router could not access the context\n- Logging `threading.get_ident()` in different middlewares and request handler might help, but this didn't solve it for me as I suspect there is some anyio thread switching going on which messes up the contextvars context. See my answer.\n- I came up with the same conclusion a few days ago with the same chain of thought. I also dug into the Starlette code and it was clear that BaseHTTPmiddleware were run a in task group, therefore the context was copied, but when the child middleware/app exited the root middleware lost the changes in the context... as general approach asgi middleware should be the last added (therefore the first run) in an app\n- Is this the only solution?\n- @Christian I'm having the same issue as you\n- @coding-cat You can either 1. Use ASGI middleware only 2. Put Your ASGI middleware as the first in the chain of the execution (pay attention that order should be reversed)","metadata":{"transformedAt":"2026-08-18T18:32:29.161Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":22,"totalLines":371,"estimatedTokens":2817}}752{"id":"stack-72904923","source":"stackoverflow","questionId":72904923,"title":"How to sort methods by method type in FastAPI Swagger API?","tags":["python","swagger","fastapi"],"text":"Title: How to sort methods by method type in FastAPI Swagger API?\nTags: python, swagger, fastapi\nSource: Stack Overflow\n\nQuestion:\nHow can I set a sort order for the API methods in the FastAPI Swagger autodocs? I would like all my methods grouped by type (GET, POST, PUT, DELETE).\n\nThis answer shows how to do it in Java. How can I do it in Python?\n\n```\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/\")\ndef list_all_components():\n pass\n\n@app.get(\"/{component_id}\")\ndef get_component(component_id: int):\n pass\n\n@app.post(\"/\")\ndef create_component():\n pass\n\n@app.put(\"/{component_id}\")\ndef update_component(component_id: int):\n pass\n\n@app.delete(\"/{component_id}\")\ndef delete_component(component_id: int):\n pass\n```\n\nhttps://i.sstatic.net/m4ZDf.png\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/\")\ndef list_all_components():\n pass\n\n@app.get(\"/{component_id}\")\ndef get_component(component_id: int):\n pass\n\n@app.post(\"/\")\ndef create_component():\n pass\n\n@app.put(\"/{component_id}\")\ndef update_component(component_id: int):\n pass\n\n@app.delete(\"/{component_id}\")\ndef delete_component(component_id: int):\n pass\n```\n\n```py\napp = FastAPI(swagger_ui_parameters={\"operationsSorter\": \"method\"})\n```\n\n========================================\n\nComments:\n- Can you clarify why the answer doesn't work in python? Do you have a link to docs that show how you're using it in python?\n- The linked answer is written in Java. I am looking for a pure Python solution.\n- Any idea if there's a way in Python to use a custom sorting method?\n- I'm guessing you'll have to implement a custom openapi schema in that case and reorder the routes returned from `get_openapi` as shown here: fastapi.tiangolo.com/advanced/extending-openapi/… - you can also implement a custom sort in Javascript and give that function to operationsSorter, but you can't include it from the `swagger_ui_parameters` property - so I think you'll have to do a custom openapi endpoint for that as well. I might have time to dig further into it later.\n- Since the answer is more involved and nuanced, I've asked a separate question here: stackoverflow.com/questions/72915808/…","metadata":{"transformedAt":"2026-08-18T18:32:29.161Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":2,"totalLines":78,"estimatedTokens":557}}753{"id":"stack-74939164","source":"stackoverflow","questionId":74939164,"title":"i want to validate password for user input in fastapi python","tags":["python","passwords","fastapi"],"text":"Title: i want to validate password for user input in fastapi python\nTags: python, passwords, fastapi\nSource: Stack Overflow\n\nQuestion:\ni need a password validation in fastapi python, in this when user signup and create a password and passowrd are too sort not capital letter, special character etc. than fastapi give validation error\n\ni make a password validation code in python but i don't know how to use in fastapi\n\n```\ndef validate_password(s):\n l, u, p, d = 0, 0, 0, 0\n capitalalphabets=\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n smallalphabets=\"abcdefghijklmnopqrstuvwxyz\"\n specialchar=\"\"\" ~`!@#$%^&*()_-+={[}]|\\:;\"'.?/ \"\"\"\n digits=\"0123456789\"\n if (len(s) >= 8):\n for i in s:\n \n # counting lowercase alphabets\n if (i in smallalphabets):\n l+=1 \n \n # counting uppercase alphabets\n if (i in capitalalphabets):\n u+=1 \n \n # counting digits\n if (i in digits):\n d+=1 \n \n # counting the mentioned special characters\n if(i in specialchar):\n p+=1 \n if (l>=1 and u>=1 and p>=1 and d>=1 and l+p+u+d==len(s)):\n print(\"Valid Password\")\n else:\n print(\"Invalid Password\")\n\ns = input(\"Enter the password: \") \nvalidate_password(s)\n```\n\n========================================\n\nCode:\n```text\ndef validate_password(s):\n l, u, p, d = 0, 0, 0, 0\n capitalalphabets=\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n smallalphabets=\"abcdefghijklmnopqrstuvwxyz\"\n specialchar=\"\"\" ~`!@#$%^&*()_-+={[}]|\\:;\"'<,>.?/ \"\"\"\n digits=\"0123456789\"\n if (len(s) >= 8):\n for i in s:\n \n # counting lowercase alphabets\n if (i in smallalphabets):\n l+=1 \n \n # counting uppercase alphabets\n if (i in capitalalphabets):\n u+=1 \n \n # counting digits\n if (i in digits):\n d+=1 \n \n # counting the mentioned special characters\n if(i in specialchar):\n p+=1 \n if (l>=1 and u>=1 and p>=1 and d>=1 and l+p+u+d==len(s)):\n print(\"Valid Password\")\n else:\n print(\"Invalid Password\")\n\ns = input(\"Enter the password: \") \nvalidate_password(s)\n```\n\n```text\nfrom pydantic import BaseModel, validator\n\nclass User(BaseModel):\n password: str\n\n @validator(\"password\")\n def validate_password(cls, password, **kwargs):\n # Put your validations here\n return password\n```\n\n```text\nfrom pydantic import BaseModel, Field\n\npassword_regex = \"((?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[\\W]).{8,64})\"\n\n\nclass User(BaseModel):\n password: str = Field(..., regex=password_regex)\n```\n\n========================================\n\nComments:\n- What have you tried? Is there an error or something?\n- validator is deprecated with the latest pydantic, suggested to use field_validator","metadata":{"transformedAt":"2026-08-18T18:32:29.161Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":3,"totalLines":107,"estimatedTokens":682}}754{"id":"stack-76632543","source":"stackoverflow","questionId":76632543,"title":"Google Cloud Working not working with Gunicorn","tags":["python-3.x","fastapi","gunicorn","python-logging","google-cloud-logging"],"text":"Title: Google Cloud Working not working with Gunicorn\nTags: python-3.x, fastapi, gunicorn, python-logging, google-cloud-logging\nSource: Stack Overflow\n\nQuestion:\nUp until now I've been using uvicorn directly to run a fastapi app running on Render which has google cloud logging enabled as such:\n\n```\ndef configure_logging():\n # Reset root logger config\n logging.root.handlers = []\n logging.root.setLevel(level)\n\n stream_handler = logging.StreamHandler(sys.stdout)\n stream_handler.setFormatter(ConsoleFormatter(fmt=LOG_FORMAT, access_fmt=ACCESS_FORMAT))\n stream_handler.setLevel(level)\n logging.root.addHandler(stream_handler)\n\n logging.root.info(\n f\"/etc/secrets/google-service-account.json exists? {os.path.exists('/etc/secrets/google-service-account.json')}\"\n )\n gcp_client = google_logging.Client.from_service_account_json(\"/etc/secrets/google-service-account.json\")\n gcp_client.setup_logging(log_level=level, labels={\"source\": \"render\", \"external\": \"true\"})\n```\n\nAnd I have an endpoint like the following to test the logging:\n\n```\n# main.py\nlogging.configure_logging()\napp = FastAPI()\napp.include_router(healthcheck_router.router)\n\n# healthcheck_router.py\nfrom fastapi import APIRouter\n\nimport logging as py_logging\nfrom logging_tree import printout\n\nfrom easel.api.common import logging\n\nlog = logging.get_logger(__name__)\nrouter = APIRouter()\n\n@router.get(\"/healthcheck\")\nasync def healthcheck():\n log.info(\"Test log\")\n log.info(f\"Py Logging root handlers: {py_logging.root.handlers}\")\n printout()\n return {\"healthy\": True}\n```\n\nThis was all working fine with my logs showing up in Google Cloud Logging with the label: 'source': 'render' until I decided to run Gunicorn with Uvicorn workers as they recommend on the fastapi website: https://fastapi.tiangolo.com/deployment/server-workers/\n\nNow with gunicorn i'm running it as follows:\n\n```\ngunicorn --bind '0.0.0.0:10000' -w 1 -k uvicorn.workers.UvicornWorker easel.api.main:app\n```\n\nI can see the logs getting printed to stdout using my ConsoleFormatter totally fine, however the logs arent showing up in Google Cloud Logging (with the label or without)... When I revert it to just using uvicorn it works again, unfortunately running without gunicorn is not possible due to other reasons.\n\nPython v3.8, Uvicorn 0.22.0, Gunicorn v20.1.0, google-cloud-logging v3.5.0\n\nI've tried running a python interpreter on the box and instantiating a logger, that works as expected and my logs show up in GCL.\n\nI've triple checked that the secrets file is present.\n\nI've tried using the logging_tree library to see if for some reason gunicorn is disabling my loggers, however there is no significant difference between the logging tree output with and without gunicorn.\n\nUnfortunately I am not able to run gunicorn locally due to it always crashing with a segfault (seems to be some issue with macos) so i have to rely on debugging this on the running box on Render.\n\n========================================\n\nCode:\n```py\ndef configure_logging():\n # Reset root logger config\n logging.root.handlers = []\n logging.root.setLevel(level)\n\n stream_handler = logging.StreamHandler(sys.stdout)\n stream_handler.setFormatter(ConsoleFormatter(fmt=LOG_FORMAT, access_fmt=ACCESS_FORMAT))\n stream_handler.setLevel(level)\n logging.root.addHandler(stream_handler)\n\n logging.root.info(\n f\"/etc/secrets/google-service-account.json exists? {os.path.exists('/etc/secrets/google-service-account.json')}\"\n )\n gcp_client = google_logging.Client.from_service_account_json(\"/etc/secrets/google-service-account.json\")\n gcp_client.setup_logging(log_level=level, labels={\"source\": \"render\", \"external\": \"true\"})\n```\n\n```py\n# main.py\nlogging.configure_logging()\napp = FastAPI()\napp.include_router(healthcheck_router.router)\n\n# healthcheck_router.py\nfrom fastapi import APIRouter\n\nimport logging as py_logging\nfrom logging_tree import printout\n\nfrom easel.api.common import logging\n\nlog = logging.get_logger(__name__)\nrouter = APIRouter()\n\n\n@router.get(\"/healthcheck\")\nasync def healthcheck():\n log.info(\"Test log\")\n log.info(f\"Py Logging root handlers: {py_logging.root.handlers}\")\n printout()\n return {\"healthy\": True}\n```\n\n```text\ngunicorn --bind '0.0.0.0:10000' -w 1 -k uvicorn.workers.UvicornWorker easel.api.main:app\n```\n\n```text\nlogging.configure_logging\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.161Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":126,"estimatedTokens":1084}}755{"id":"stack-75180598","source":"stackoverflow","questionId":75180598,"title":"TypeError: Object of type 'type' is not JSON serializable","tags":["python","swagger","fastapi","swagger-ui","openapi"],"text":"Title: TypeError: Object of type 'type' is not JSON serializable\nTags: python, swagger, fastapi, swagger-ui, openapi\nSource: Stack Overflow\n\nQuestion:\nThe code works fine in Postman and provides a valid response but fails to generate the OpenAPI/Swagger UI automatic docs.\n\n```\nclass Role(str, Enum):\n Internal = \"internal\"\n External = \"external\"\n\nclass Info(BaseModel):\n id: int\n role: Role\n\nclass AppInfo(Info):\n info: str\n\n@app.post(\"/api/v1/create\", status_code=status.HTTP_200_OK)\nasync def create(info: Info, apikey: Union[str, None] = Header(str)):\n if info:\n alias1 = AppInfo(info=\"Portal Gun\", id=123, role=info.role)\n alias2 = AppInfo(info=\"Plumbus\", id=123, , role=info.role)\n info_dict.append(alias1.dict())\n info_dict.append(alias2.dict())\n\n \n return {\"data\": info_dict}\n else:\n \n raise HTTPException(\n status_code=status.HTTP_404_NOT_FOUND,\n detail=f\"Please provide the input\"\n )\n```\n\nError received:\n\n```\nTypeError: Object of type 'type' is not JSON serializable\n```\n\n========================================\n\nTop Answer:\nI think the problem might be at:\n\n```\napikey: Union[str, None] = Header(str)\n```\n\nin the async function `create()`\n\nMaybe the function or class `Header()` doesn't accept `str` as an input?\n\nAlthough I don't really know what that function does tho//what library it is from.\n\n========================================\n\nCode:\n```py\nclass Role(str, Enum):\n Internal = \"internal\"\n External = \"external\"\n\n\nclass Info(BaseModel):\n id: int\n role: Role\n\nclass AppInfo(Info):\n info: str\n\n\n@app.post(\"/api/v1/create\", status_code=status.HTTP_200_OK)\nasync def create(info: Info, apikey: Union[str, None] = Header(str)):\n if info:\n alias1 = AppInfo(info=\"Portal Gun\", id=123, role=info.role)\n alias2 = AppInfo(info=\"Plumbus\", id=123, , role=info.role)\n info_dict.append(alias1.dict())\n info_dict.append(alias2.dict())\n\n \n return {\"data\": info_dict}\n else:\n \n raise HTTPException(\n status_code=status.HTTP_404_NOT_FOUND,\n detail=f\"Please provide the input\"\n )\n```\n\n```text\nTypeError: Object of type 'type' is not JSON serializable\n```\n\n```text\nTypeError: Object of type 'type' is not JSON serializable\n```\n\n```text\nFetch error\nInternal Server Error /openapi.json\n```\n\n```py\napikey: Union[str, None] = Header(str)\n ^^^\n```\n\n```py\napikey: Union[str, None] = Header(None)\n```\n\n```text\n/docs\n```\n\n```text\nHeader\n```\n\n```text\nPath\n```\n\n```text\nQuery\n```\n\n```text\nCookie\n```\n\n```text\nHeader\n```\n\n```text\n__init__\n```\n\n```text\ndefault\n```\n\n```text\nNone\n```\n\n```text\n'some-api-key'\n```\n\n```text\nstr\n```\n\n```text\nOptional\n```\n\n```text\nNone\n```\n\n```text\nOptional\n```\n\n```py\napikey: Union[str, None] = Header(str)\n```\n\n```text\ncreate()\n```\n\n```text\nHeader()\n```\n\n```text\nstr\n```\n\n========================================\n\nComments:\n- What command are you running?\n- uvicorn app.main:app --reload I have a main.py in app folder\n- I suspect the line `role: Role` because `type` is the type of all classes in Python.\n- Your code does not run (`info_dict` is undefined). Please provide enough code to actually diagnose your problem\n- I am providing the header in postman and it works fine\n- Can you maybe provide a backtrace to your error code?","metadata":{"transformedAt":"2026-08-18T18:32:29.161Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":24,"totalLines":196,"estimatedTokens":824}}756{"id":"stack-67942766","source":"stackoverflow","questionId":67942766,"title":"FastApi - api key as parameter secure enough","tags":["python","fastapi"],"text":"Title: FastApi - api key as parameter secure enough\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\ni am new in this part of programming and i have few questions. First of all my project. At one side i have a Flutter App and at the other side a MS SQL Server with data. This data i need on my device logically. I read the best way is to use FastAPI, its easy and has a good performance but i am not sure about security. I read something about OAuth2 but it looks to much because just one user will have permission to use the data (the server owner). Is it possible just to use a simple api key as a parameter? Something like this...\n\n```\nfrom fastapi import FastAPI\nfrom SqlServerRequest import SqlServerRequest\n\napp = FastAPI()\n\n@app.get(\"/openOrders/{key}\")\nasync def openOrders(key):\n if key == \"myverysecurekey\":\n return \"SQLDATA\"\n else\n return \"Wrong key\"\n```\n\nThat way works but i am not sure about the security\nWhat would you say?\n\n========================================\n\nTop Answer:\nI have been dealing with the same issue for a while. Instead of using a oauth I needed a simple X-API-Key in the header.\n\nYou can do that with the following code\n\n```\nfrom fastapi import FastAPI, Depends\nfrom fastapi.security import APIKeyHeader\nimport os\n\nos.environ['API-KEY'] = '1234'. \n# You would use as an environment var in real life\n\nX_API_KEY = APIKeyHeader(name='X-API-Key')\n\ndef api_key_auth(x_api_key: str = Depends(X_API_KEY)):\n \"\"\" takes the X-API-Key header and validate it with the X-API-Key in the database/environment\"\"\"\n if x_api_key != os.environ['API-KEY']:\n raise HTTPException(\n status_code=401,\n detail=\"Invalid API Key. Check that you are passing a 'X-API-Key' on your header.\"\n )\n\napp = FastAPI()\n\n@app.get(\"/do_something\", dependencies=[Depends(api_key_auth)])\nasync def do_something():\n return \"API is working OK.\"\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nfrom SqlServerRequest import SqlServerRequest\n\napp = FastAPI()\n\n\n@app.get(\"/openOrders/{key}\")\nasync def openOrders(key):\n if key == \"myverysecurekey\":\n return \"SQLDATA\"\n else\n return \"Wrong key\"\n```\n\n```py\nimport os\n\nimport uvicorn\nfrom fastapi import FastAPI, Depends, HTTPException\nfrom fastapi.security import OAuth2PasswordBearer\nfrom starlette import status\n\n# Use token based authentication\noauth2_scheme = OAuth2PasswordBearer(tokenUrl=\"token\")\n\n\n# Ensure the request is authenticated\ndef auth_request(token: str = Depends(oauth2_scheme)) -> bool:\n authenticated = token == os.getenv(\"API_KEY\", \"DUMMY-API-KEY\")\n return authenticated\n\n\napp = FastAPI()\n\n\n@app.get(\"/openOrders\")\nasync def open_orders(authenticated: bool = Depends(auth_request)):\n # Check for authentication like so\n if not authenticated:\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Not authenticated\")\n\n # Business logic here\n return {\"message\": \"Authentication Successful\"}\n\n\nif __name__ == '__main__':\n uvicorn.run(\"main:app\", host=\"127.0.0.1\", port=8080)\n```\n\n```py\nimport requests\n\nurl = \"http://127.0.0.1:8080/openOrders\"\npayload={}\n# The client would pass the API-KEY in the headers\nheaders = {\n 'Content-Type': 'application/json',\n 'Authorization': 'Bearer DUMMY-API-KEY'\n}\nresponse = requests.request(\"GET\", url, headers=headers, data=payload)\nprint(response.text)\n```\n\n```dart\nfinal response = await http.get(\n Uri.parse('http://127.0.0.1:8080/openOrders'),\n // Send authorization headers to the backend.\n headers: {\n HttpHeaders.authorizationHeader: 'Bearer DUMMY-API-KEY',\n },\n);\n```\n\n```text\npython main.py\n```\n\n```text\nDart\n```\n\n```py\nfrom fastapi import FastAPI, Depends\nfrom fastapi.security import APIKeyHeader\nimport os\n\nos.environ['API-KEY'] = '1234'. \n# You would use as an environment var in real life\n\nX_API_KEY = APIKeyHeader(name='X-API-Key')\n\n\ndef api_key_auth(x_api_key: str = Depends(X_API_KEY)):\n \"\"\" takes the X-API-Key header and validate it with the X-API-Key in the database/environment\"\"\"\n if x_api_key != os.environ['API-KEY']:\n raise HTTPException(\n status_code=401,\n detail=\"Invalid API Key. Check that you are passing a 'X-API-Key' on your header.\"\n )\n\n\napp = FastAPI()\n\n\n@app.get(\"/do_something\", dependencies=[Depends(api_key_auth)])\nasync def do_something():\n return \"API is working OK.\"\n```\n\n========================================\n\nComments:\n- Thx, for quick answer, but a few things i dont get. This line: authenticated = token == os.getenv(\"API_KEY\", \"DUMMY-API-KEY\") - Where i get this api keys? Is this generating by fastapi? And the code for client is for what? i have to connect with my flutter mobile app with an url?! to get the response in json and sorry when i don't get something obvious like i said i am new at this things\n- When the client (you flutter app) makes a request, it needs to add ` 'Authorization': `Bearer DUMMY-API-KEY'` to the request header. When the FastAPI application receives this request, the request will have have to be authenticated. How? `authenticated: bool = Depends(auth_request)` takes care of that.\n- I have added an edit with Dart code that you can use in your flutter app to call the FastAPI app. I do not know any Dart or Flutter 😅\n- ok thx, one more think, how it looks like if i just want to open it in chrome, how would look the url?\n- I would use something like Postman or Insomnia for API development. It is much easier in my opinion than to use a browser for API development. The URL will look like `http://127.0.0.1:8080/openOrders` but as you are using browser, I am not sure how you would send headers in a browser.\n- I wanted somethink like that: api.bittrex.com/api/v1.1/account/getbalances?apikey=API_KEY for example and use a fix apikey and that was is\n- That in my opinion is very bad practice. What you are trying to do is a query parameter, you can find information about it here. Highly not recommended\n- Why? Its not enough secure? Thx for the link but i tried already and it works. See my first post\n- From my knowledge, I do not think it is. See stackoverflow.com/questions/187655/are-https-headers-encrypt‌​ed\n- @Rapib Do you maybe know how to rum the server in background, I mean without console?","metadata":{"transformedAt":"2026-08-18T18:32:29.161Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":7,"totalLines":184,"estimatedTokens":1574}}757{"id":"stack-72975593","source":"stackoverflow","questionId":72975593,"title":"Where to store tokens/secrets with FastAPI?","tags":["python","fastapi"],"text":"Title: Where to store tokens/secrets with FastAPI?\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm working with FastAPI and Python on the backend to make external calls to a public API. After authentication, the public API gives an access token that grants access to a specific user's data. Where would be the best place to store/save this access token? I want to easily access it for all my future API calls with the public API service. I don't want a DB or long term storage as it only needs to last the session for the user. Appreciate all help!\n\n========================================\n\nCode:\n```text\nfrom fastapi import Request\n...\n@router.get(\"/callback\")\nasync def callback(request: Request):\n ...\n request.session[\"access_token\"] = access_token\n```\n\n```text\n@router.get(\"/top_artists\")\nasync def get_top_songs(request: Request):\n ...\n access_token = request.session.get(\"access_token\")\n```\n\n========================================\n\nComments:\n- I would probably store this as an encrypted cookie on the request session.\n- @flakes So I would use a requests.Session to store the token and then would I need to pull that token out of the cookie everytime to pass it to the public API in a GET request for example?\n- Yeah, that would be how I do it. Make sure the cookie is secured with a secret by the server, such that the cookie can't be parsed by client-side code to call your APIs directly.\n- Thanks. Sorry, I'm pretty new to this stuff. Could that mean storing a secret in the FastAPI/backend py files and then using that secret to encode and decode the cookie stored in requests.Session?\n- You shouldn't be storing secrets in the code, store them in environment variables which you set during deployment of the app.\n- @PeterHenry gotcha I will store my secrets in env vars, but do you know of a better way to store the access token, like maybe in a User class field that I can access across files for different API requests?\n- @oscar-lauth, try some of the options here -> stackoverflow.com/questions/55212497/…\n- @PeterHenry thanks, I ended up storing client secrets/id (which are permanent) in .env and then creating a global User class that gets initialized and stores the access token as well as some other data.\n- just to clarify, FastAPI handles this 'session_id' cookie for us, correct? We don't have to manually store and pass this cookie between our frontend/backend?","metadata":{"transformedAt":"2026-08-18T18:32:29.161Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":2,"totalLines":38,"estimatedTokens":602}}758{"id":"stack-68884040","source":"stackoverflow","questionId":68884040,"title":"Websockets messages only sent at the end and not in instances using async / await, yield in nested for loops","tags":["python","websocket","async-await","fastapi","jax"],"text":"Title: Websockets messages only sent at the end and not in instances using async / await, yield in nested for loops\nTags: python, websocket, async-await, fastapi, jax\nSource: Stack Overflow\n\nQuestion:\nI have a computationally heavy process that takes several minutes to complete in the server. So I want to send the results of every iteration to the client via websockets.\n\nThe overall application works but my problem is that all the messages are arriving at the client in one big chunk after the entire simulation finishes. I must be missing something here as I expect the `await websocket.send_json()` to send the message during the process and not all of them at the end.\n\n### Server python (FastAPI)\n\n```\n# A very simplified abstraction of the actual app.\n\ndef simulate_intervals(data):\n for t in range(data.n_intervals):\n state = interval(data) # returns a JAX NumPy array\n yield state\n\ndef simulate(data):\n for key in range(data.n_trials):\n trial = simulate_intervals(data)\n yield trial\n\n@app.websocket(\"/ws\")\nasync def socket(websocket: WebSocket):\n\n await websocket.accept()\n while True:\n # Get model inputs from client\n data = await websocket.receive_text()\n # Minimal computation\n nodes = distributions(data)\n\n nodosJson = json.dumps(nodes, cls=NumpyEncoder)\n # I expect this message to be sent early on,\n # but the client gets it at the end with all the other messages. \n await websocket.send_json({\"tipo\": \"nodos\", \"datos\": json.loads(nodosJson)})\n \n # Heavy computation\n trials = simulate(data)\n\n for trialI, trial in enumerate(trials):\n for stateI, state in enumerate(trial):\n stateString = json.dumps(state, cls=NumpyEncoder)\n\n await websocket.send_json(\n {\n \"tipo\": \"estado\",\n \"datos\": json.loads(stateString),\n \"trialI\": trialI,\n \"stateI\": stateI,\n }\n )\n\n await websocket.send_json({\"tipo\": \"estado\", \"msg\": \"fin\"})\n```\n\nFor completeness, here is the basic client code.\n\n### Client\n\n```\nconst ws = new WebSocket('ws://localhost:8000/ws');\n\nws.onopen = () => {\n console.log('Conexión exitosa');\n};\n\nws.onmessage = (e) => {\n const mensaje = JSON.parse(e.data);\n console.log(mensaje);\n};\n\nbotonEnviarDatos.onclick = () => {\n ws.send(JSON.stringify({...}));\n}\n```\n\n========================================\n\nTop Answer:\nI got a similar issue, and was able to resolve it by adding a small `await asyncio.sleep(0.1)` after sending json messages. I have not dived into asyncios internals yet, but my guess is that `websocker.send` shedules a message to be sent, but since the async function continues to run it never has a chance to do it in the background. Sleeping the async function makes asyncio pick up other tasks while it is waiting.\n\n========================================\n\nCode:\n```py\n# A very simplified abstraction of the actual app.\n\ndef simulate_intervals(data):\n for t in range(data.n_intervals):\n state = interval(data) # returns a JAX NumPy array\n yield state\n\ndef simulate(data):\n for key in range(data.n_trials):\n trial = simulate_intervals(data)\n yield trial\n\n@app.websocket(\"/ws\")\nasync def socket(websocket: WebSocket):\n\n await websocket.accept()\n while True:\n # Get model inputs from client\n data = await websocket.receive_text()\n # Minimal computation\n nodes = distributions(data)\n\n nodosJson = json.dumps(nodes, cls=NumpyEncoder)\n # I expect this message to be sent early on,\n # but the client gets it at the end with all the other messages. \n await websocket.send_json({\"tipo\": \"nodos\", \"datos\": json.loads(nodosJson)})\n \n # Heavy computation\n trials = simulate(data)\n\n for trialI, trial in enumerate(trials):\n for stateI, state in enumerate(trial):\n stateString = json.dumps(state, cls=NumpyEncoder)\n\n await websocket.send_json(\n {\n \"tipo\": \"estado\",\n \"datos\": json.loads(stateString),\n \"trialI\": trialI,\n \"stateI\": stateI,\n }\n )\n\n await websocket.send_json({\"tipo\": \"estado\", \"msg\": \"fin\"})\n```\n\n```js\nconst ws = new WebSocket('ws://localhost:8000/ws');\n\nws.onopen = () => {\n console.log('Conexión exitosa');\n};\n\nws.onmessage = (e) => {\n const mensaje = JSON.parse(e.data);\n console.log(mensaje);\n};\n\nbotonEnviarDatos.onclick = () => {\n ws.send(JSON.stringify({...}));\n}\n```\n\n```text\nawait websocket.send_json()\n```\n\n```py\n# A very simplified abstraction of the actual app.\n\ndef simulate_intervals(data):\n for t in range(data.n_intervals):\n state = interval(data) # returns a JAX NumPy array\n yield state\n\ndef simulate(data):\n for key in range(data.n_trials):\n trial = simulate_intervals(data)\n yield trial\n\n@app.websocket(\"/ws\")\nasync def socket(websocket: WebSocket):\n\n await websocket.accept()\n while True:\n # Get messages from client\n data = await websocket.receive_text()\n \n # \"tipo\" is basically the type of data being sent from client or server to the other one.\n # In this case, \"tipo\": \"inicio\" is the client sending inputs and requesting for a certain data in response.\n if data[\"tipo\"] == \"inicio\":\n # Minimal computation\n nodes = distributions(data)\n\n nodosJson = json.dumps(nodes, cls=NumpyEncoder)\n # In this first interaction, the client gets the first message without delay. \n await websocket.send_json({\"tipo\": \"nodos\", \"datos\": json.loads(nodosJson)})\n\n # Since this is a generator (def returns yield) it does not actually\n # trigger that actual computationally heavy process. \n trials = simulate(data)\n \n # define some initial variables to count the iterations\n trialI = 0\n stateI = 0\n trialsLen = args.number_trials\n statesLen = 600\n \n # load the first trial (also a generator)\n # without the for loop used before, the counters and next()\n # allow us to do the same as being done before in the for loop\n trial = next(trials)\n\n # With the use of generators and next() it is possible to keep\n # this first message light on the server and send the first response\n # as quickly as possible.\n \n # This type of message asks for the next instance of the simluation\n # without processing the entire model.\n elif data[\"tipo\"] == \"sim\":\n # check if we are within the limits (before this was a nested for loop)\n if trialI < trialsLen and stateI < statesLen:\n # Trigger the next instance of the simulation\n state = next(trial)\n # update counter\n stateI = stateI + 1\n \n # Send the message with 1 instance of the simulation.\n # \n stateString = json.dumps(state, cls=NumpyEncoder)\n await websocket.send_json(\n {\n \"tipo\": \"estado\",\n \"datos\": json.loads(stateString),\n \"trialI\": trialI,\n \"stateI\": stateI,\n }\n )\n \n # Check if the second loop is done\n if stateI == statesLen:\n # update counter of first loop\n trialI = trialI + 1\n # update counter of second loop\n stateI = 0\n \n # Check if there are more pending trials,\n # otherwise stop and notify the client we are done.\n try:\n trial = next(trials)\n except StopIteration:\n await websocket.send_json({\"tipo\": \"fin\"})\n```\n\n```js\nws.onmessage = (e) => {\n const mensaje = JSON.parse(e.data);\n \n // Simply check the type of incoming message so it can be processed\n if (mensaje.tipo === 'fin') {\n viz.calcularResultados();\n } else if (mensaje.tipo === 'nodos') {\n viz.pintarNodos(mensaje.datos);\n } else if (mensaje.tipo === 'estado') {\n viz.sumarEstado(mensaje.datos);\n }\n\n // After receiving a message, ping the server for the next one \n ws.send(\n JSON.stringify({\n tipo: 'sim',\n })\n );\n};\n```\n\n```text\nawait asyncio.sleep(0.1)\n```\n\n```text\nwebsocker.send\n```\n\n========================================\n\nComments:\n- literally saved my life\n- Ohhh, finally, that was stacked in my code for 5 days\n- Haven't you try to use zero, i.e. asyncio.sleep(0) ? For me that worked too.","metadata":{"transformedAt":"2026-08-18T18:32:29.161Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":7,"totalLines":278,"estimatedTokens":2018}}759{"id":"stack-74634957","source":"stackoverflow","questionId":74634957,"title":"How do I validate a JWT that's sent as an HttpOnly cookie in FastAPI?","tags":["oauth-2.0","jwt","fetch","fastapi","cookie-httponly"],"text":"Title: How do I validate a JWT that's sent as an HttpOnly cookie in FastAPI?\nTags: oauth-2.0, jwt, fetch, fastapi, cookie-httponly\nSource: Stack Overflow\n\nQuestion:\n### Problem\n\nI'm working on a FastAPI application that requires authentication for certain endpoints to be reached by users. I'm using Oauth2 and Jose from FastAPI to create JWTs for my authentication process. After doing some research, it seems that the best way to ensure tokens are protected on the frontend is to store them in HttpOnly Cookies. I am struggling to understand how to CORRECTLY pass the JWT through HttpOnly Cookies so that my FastAPI server is able to validate the JWT in my headers. Currently, when I try to pass the JWT token as an HttpOnly Cookie, I get a `401 Unauthorized Error`.\n\n### What I've Tried\n\nI have been able to successfully authenticate the user with the JWT token when I code the token into the headers as a template string. However, when I pass the JWT to the FastAPI server through the headers as a Cookie, my FastAPI server is unable to authenticate the user and returns a `401 unauthorized error`. I've tried looking into the network tab to see what headers are being sent in my requests to the FastApi server in order to better understand what is different between the two scenarios.\n\n### Successful example with code\n\nThis is in the header when I pass the JWT as a template string and get a 200 response:\n\nAuthentication: Bearer token\n\n```\nasync function getPosts() {\n const url = \"http://localhost:8000/posts\";\n const fetchConfig = {\n headers: {\n Authorization: `Bearer ${tokenValue}`,\n },\n };\n const response = await fetch(url, fetchConfig);\n const posts = await response.json();\n }\n```\n\n### Unsuccessful example with code\n\nThis is in the header when I pass the JWT as an HttpOnly Cookie and get a 401 response:\n\nCookie: access_token=\"Bearer token\"\n\nI've also tried changing the way I set my cookie on the server so that the header looks like this:\n\nCookie: Authentication=\"Bearer token\"\n\n```\nasync function getPosts() {\n const url = \"http://localhost:8000/posts\";\n const fetchConfig = {\n credentials: \"include\",\n };\n const response = await fetch(url, fetchConfig);\n const posts = await response.json();\n console.log(posts);\n }\n```\n\n### FastAPI Code\n\nHere is the code for my Oauth2 token validation that protects my API endpoints. This is based off of the example in the FastAPI docs:\nFastApi Oauth2\n\n```\noauth2_scheme = OAuth2PasswordBearer(tokenUrl='login')\n\nSECRET_KEY = settings.SECRET_KEY\nALGORITHM = settings.ALGORITHM\nACCESS_TOKEN_EXPIRE_MINUTES = settings.ACCESS_TOKEN_EXPIRE_MINUTES\n\ndef verify_access_token(token: str, credentials_exception):\n try:\n payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])\n id: str = payload.get(\"user_id\")\n if id is None:\n raise credentials_exception\n token_data = schemas.TokenData(id=id)\n \n except JWTError:\n raise credentials_exception\n\n return token_data\n\ndef get_current_user(token: str = Depends(oauth2_scheme), db: Session = Depends(database.get_db)):\n credentials_exception = HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=f\"Could not validate credentials\",\n headers={\"WWW-Authenticate\": \"Bearer\"}\n )\n\n token = verify_access_token(token, credentials_exception)\n user = db.query(models.User).filter(models.User.id == token.id).first()\n\n return user\n```\n\nHere is an example of a protected endpoint that depends on the get_current_user function from the oauth2 file listed above.\n\n```\n@router.get(\"/\", response_model=List[schemas.PostOut])\ndef get_posts(db: Session = Depends(get_db), current_user: int = Depends(oauth2.get_current_user):\n return {\"Message\": \"Protected Endpoint Reached\"}\n```\n\nIt seems like I'm running into the issue because my get_current_user function in the Oauth2 is only able to grab the JWT from the header when it is in the following format:\n\nAuthentication: Bearer token\n\nIt doesn't seem to be able to authenticate the token from the header when it is in either of the following formats:\n\nCookie: access_token=\"Bearer token\"\n\nCookie: Authentication=\"Bearer token\"\n\nDo I need to somehow change the way I'm sending the headers when I send them via HttpOnly Cookies or do I maybe need to change something about my get_current_user function that will enable it to read the cookie headers correctly.\n\nAny suggestions are greatly appreciated, and thank you for taking the time to read this!\n\n========================================\n\nCode:\n```js\nasync function getPosts() {\n const url = \"http://localhost:8000/posts\";\n const fetchConfig = {\n headers: {\n Authorization: `Bearer ${tokenValue}`,\n },\n };\n const response = await fetch(url, fetchConfig);\n const posts = await response.json();\n }\n```\n\n```js\nasync function getPosts() {\n const url = \"http://localhost:8000/posts\";\n const fetchConfig = {\n credentials: \"include\",\n };\n const response = await fetch(url, fetchConfig);\n const posts = await response.json();\n console.log(posts);\n }\n```\n\n```py\noauth2_scheme = OAuth2PasswordBearer(tokenUrl='login')\n\nSECRET_KEY = settings.SECRET_KEY\nALGORITHM = settings.ALGORITHM\nACCESS_TOKEN_EXPIRE_MINUTES = settings.ACCESS_TOKEN_EXPIRE_MINUTES\n\n\ndef verify_access_token(token: str, credentials_exception):\n try:\n payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])\n id: str = payload.get(\"user_id\")\n if id is None:\n raise credentials_exception\n token_data = schemas.TokenData(id=id)\n \n except JWTError:\n raise credentials_exception\n\n return token_data\n\ndef get_current_user(token: str = Depends(oauth2_scheme), db: Session = Depends(database.get_db)):\n credentials_exception = HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=f\"Could not validate credentials\",\n headers={\"WWW-Authenticate\": \"Bearer\"}\n )\n\n token = verify_access_token(token, credentials_exception)\n user = db.query(models.User).filter(models.User.id == token.id).first()\n\n return user\n```\n\n```py\n@router.get(\"/\", response_model=List[schemas.PostOut])\ndef get_posts(db: Session = Depends(get_db), current_user: int = Depends(oauth2.get_current_user):\n return {\"Message\": \"Protected Endpoint Reached\"}\n```\n\n```text\n401 Unauthorized Error\n```\n\n```text\n401 unauthorized error\n```\n\n```py\ndef get_current_user(access_token: str = Cookie(...), db: Session = Depends(database.get_db)):\n```\n\n```text\nAuthorization\n```\n\n```text\naccess_token\n```\n\n========================================\n\nComments:\n- `access_token: str = Cookie()` should give you the value from a cookie named `access_token`. See fastapi.tiangolo.com/tutorial/cookie-params for reference. The `OAuth2PasswordBearer` expects the `Authorization` header to be used.\n- @MatsLindh Thank you so much for pointing me in this direction. This seems to have solved part of the issue. Now I get to play around with some new errors :D Thanks again for taking the time to read through this and respond. It has really helped me understand what is going on.\n- In addition to @MatsLindh's comment, you may find this answer helpful as well, which, among other things, provides important information around cookies and how to send/receive them.","metadata":{"transformedAt":"2026-08-18T18:32:29.162Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":208,"estimatedTokens":1793}}760{"id":"stack-71794990","source":"stackoverflow","questionId":71794990,"title":"Fast API : How to return a str as JSON","tags":["python","fastapi"],"text":"Title: Fast API : How to return a str as JSON\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nIn python, using Fast API, I have a str that when print show (this is an example, the real str is more complex) :\n\n```\n[1592494390, 'test', -0.2761097089544078, -0.0852381808812182, -0.101153, nan]\n```\n\nI want to return this using Fast API as a JSON array.\n\n**Using JSONResponse**\n\n```\ndef get_json(dataset: str, timeseries: str):\n\n test = \"[1592494390, 'test', -0.2761097089544078, -0.0852381808812182, -0.101153, nan]\"\n print(test)\n return JSONResponse(content=test)\n```\n\nThe print is as expecting showing:\n\n```\n[1592494390, 'test', -0.2761097089544078, -0.0852381808812182, -0.101153, nan]\n```\n\nBut the answer of the API when hitting the call is:\n\n```\n\"[1592494390, 'test', -0.2761097089544078, -0.0852381808812182, -0.101153, nan]\"\n```\n\nSo my `str` is being serialised again and I don't know how to by-pass that.\n\n**Using Response :**\n\nThe documentation of Fast API includes a page that describes how to return a Response directly (https://fastapi.tiangolo.com/advanced/response-directly/) where it is written:\n\nWhen you return a Response directly its data is not validated, converted (serialized), nor documented automatically.\n\nBut using this method leads to an error :\n\n```\ndef get_json(dataset: str, timeseries: str):\n\n test = \"[1592494390, 'test', -0.2761097089544078, -0.0852381808812182, -0.101153, nan]\"\n print(test)\n return Response(content=test, media_type=\"application/json\")\n```\n\n```\n> line 53, in get_json\n return Response(content=test, media_type=\"application/json\")\n File \"pydantic/main.py\", line 331, in pydantic.main.BaseModel.__init__\npydantic.error_wrappers.ValidationError: 2 validation errors for Response\ndescription\n field required (type=value_error.missing)\ncontent\n value is not a valid dict (type=type_error.dict)\n```\n\nBy the way the exact xml example of the documentation gives the same error:\n\n```\n> line 61, in get_json\n return Response(content=data, media_type=\"application/xml\")\n File \"pydantic/main.py\", line 331, in pydantic.main.BaseModel.__init__\npydantic.error_wrappers.ValidationError: 2 validation errors for Response\ndescription\n field required (type=value_error.missing)\ncontent\n value is not a valid dict (type=type_error.dict)\n```\n\nI know I can convert my data to a an array or dict to be serialized I how want but as I already have the right str and don't want the job to be done several times.\n\n========================================\n\nTop Answer:\nAs per FastAPI's docs:\n\nWhen you create a FastAPI path operation you can normally return any data from it: a `dict`, a `list`, a Pydantic model, a database model, etc.\n\nBy default, FastAPI would automatically convert that return value to JSON using the `jsonable_encoder`\n\nThis means, when you return a string, it will be converted into a JSON string.\n\nOne way to verify this is by `curl`ing your endpoint and piping the result into `jq`.\n\nGenerally, you should leave the serialisation to FastAPI which is doing a great job at it.\n\nOn top of that, `nan` (not a number) is *not* part of the JSON standard\n\nMy suggestion is to make sure that the data that is supposed to be returned is a `list` or a `dict`, e.g.:\n\n```\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/get-json\")\nasync def get_json():\n test = [\n 1592494390,\n \"test\",\n -0.2761097089544078,\n -0.0852381808812182,\n -0.101153,\n None,\n ]\n return test\n # You could be explicit here and return a JSONResponse.\n # return JSONResponse(content=test)\n```\n\nNow, here's what this endpoint returns:\n\n```\ncurl localhost:8080/get-json | jq type\n\"array\"\n```\n\nIf you run this command on your endpoint, it will probably show a `\"string\"` instead of `\"array\"`.\n\nIf your data is already serialised and you cannot get the original data directly, I would go with one of the suggested methods and deserialise it first.\n\nHowever, in that case, you would have to escape all double quotes properly and replace the `nan` with something that JSON understands (e.g. `null`):\n\n```\nimport json\n...\n@app.get(\"/get-json\")\nasync def get_json():\n test = \"[1592494390, \\\"test\\\", -0.2761097089544078, -0.0852381808812182, -0.101153, null]\"\n# ^^ ^^ ^^^^\n# need to be escaped cannot be nan\n\n return json.loads(test)\n```\n\nNow, this endpoint returns:\n\n```\ncurl localhost:8080/get-json | jq type\n\"array\"\n```\n\n========================================\n\nCode:\n```none\n[1592494390, 'test', -0.2761097089544078, -0.0852381808812182, -0.101153, nan]\n```\n\n```py\ndef get_json(dataset: str, timeseries: str):\n\n test = \"[1592494390, 'test', -0.2761097089544078, -0.0852381808812182, -0.101153, nan]\"\n print(test)\n return JSONResponse(content=test)\n```\n\n```none\n[1592494390, 'test', -0.2761097089544078, -0.0852381808812182, -0.101153, nan]\n```\n\n```none\n\"[1592494390, 'test', -0.2761097089544078, -0.0852381808812182, -0.101153, nan]\"\n```\n\n```py\ndef get_json(dataset: str, timeseries: str):\n\n test = \"[1592494390, 'test', -0.2761097089544078, -0.0852381808812182, -0.101153, nan]\"\n print(test)\n return Response(content=test, media_type=\"application/json\")\n```\n\n```none\n> line 53, in get_json\n return Response(content=test, media_type=\"application/json\")\n File \"pydantic/main.py\", line 331, in pydantic.main.BaseModel.__init__\npydantic.error_wrappers.ValidationError: 2 validation errors for Response\ndescription\n field required (type=value_error.missing)\ncontent\n value is not a valid dict (type=type_error.dict)\n```\n\n```none\n> line 61, in get_json\n return Response(content=data, media_type=\"application/xml\")\n File \"pydantic/main.py\", line 331, in pydantic.main.BaseModel.__init__\npydantic.error_wrappers.ValidationError: 2 validation errors for Response\ndescription\n field required (type=value_error.missing)\ncontent\n value is not a valid dict (type=type_error.dict)\n```\n\n```text\nstr\n```\n\n```text\nfrom fastapi import Response\n```\n\n```text\nfrom fastapi import Response\n\n\n\ndef get_json(dataset: str, timeseries: str):\n\ntest = \"[1592494390, 'test', -0.2761097089544078, -0.0852381808812182, -0.101153, nan]\"\nprint(test)\nreturn Response(content=test, media_type=\"application/json\")\n```\n\n```py\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/get-json\")\nasync def get_json():\n test = [\n 1592494390,\n \"test\",\n -0.2761097089544078,\n -0.0852381808812182,\n -0.101153,\n None,\n ]\n return test\n # You could be explicit here and return a JSONResponse.\n # return JSONResponse(content=test)\n```\n\n```none\ncurl localhost:8080/get-json | jq type\n\"array\"\n```\n\n```py\nimport json\n...\n@app.get(\"/get-json\")\nasync def get_json():\n test = \"[1592494390, \\\"test\\\", -0.2761097089544078, -0.0852381808812182, -0.101153, null]\"\n# ^^ ^^ ^^^^\n# need to be escaped cannot be nan\n\n return json.loads(test)\n```\n\n```none\ncurl localhost:8080/get-json | jq type\n\"array\"\n```\n\n```text\ndict\n```\n\n```text\nlist\n```\n\n```text\njsonable_encoder\n```\n\n```text\ncurl\n```\n\n```text\njq\n```\n\n```text\nnan\n```\n\n```text\nlist\n```\n\n```text\ndict\n```\n\n```text\n\"string\"\n```\n\n```text\n\"array\"\n```\n\n```text\nnan\n```\n\n```text\nnull\n```\n\n========================================\n\nComments:\n- What does your view decorator (`@app.get(..)`) look like?","metadata":{"transformedAt":"2026-08-18T18:32:29.162Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":26,"totalLines":317,"estimatedTokens":1835}}761{"id":"stack-75825362","source":"stackoverflow","questionId":75825362,"title":"\"AttributeError: encode\" when returning StreamingResponse in FastAPI","tags":["python-3.x","streaming","fastapi","server-sent-events","openai-api"],"text":"Title: \"AttributeError: encode\" when returning StreamingResponse in FastAPI\nTags: python-3.x, streaming, fastapi, server-sent-events, openai-api\nSource: Stack Overflow\n\nQuestion:\nI am using Python 3.10 and FastAPI `0.92.0` to write a Server-Sent Events (SSE) stream api. This is how the Python code looks like:\n\n```\nfrom fastapi import APIRouter, FastAPI, Header\n\nfrom src.chat.completions import chat_stream\nfrom fastapi.responses import StreamingResponse\n\nrouter = APIRouter()\n\n@router.get(\"/v1/completions\",response_class=StreamingResponse)\ndef stream_chat(q: str, authorization: str = Header(None)):\n auth_mode, auth_token = authorization.split(' ')\n if auth_token is None:\n return \"Authorization token is missing\"\n answer = chat_stream(q, auth_token)\n return StreamingResponse(answer, media_type=\"text/event-stream\")\n```\n\nand this is the `chat_stream` function:\n\n```\nimport openai\n\ndef chat_stream(question: str, key: str):\n openai.api_key = key\n # create a completion\n completion = openai.Completion.create(model=\"text-davinci-003\",\n prompt=question,\n stream=True)\n return completion\n```\n\nWhen I am using this command to invoke the api:\n\n```\ncurl -N -H \"Authorization: Bearer sk-the openai key\" https://chat.poemhub.top/v1/completions?q=hello\n```\n\nthe server side shows the following error:\n\n```\nINFO: 123.146.17.54:0 - \"GET /v1/completions?q=hello HTTP/1.0\" 200 OK\nERROR: Exception in ASGI application\nTraceback (most recent call last):\n File \"/usr/local/lib/python3.10/dist-packages/uvicorn/protocols/http/h11_impl.py\", line 429, in run_asgi\n result = await app( # type: ignore[func-returns-value]\n File \"/usr/local/lib/python3.10/dist-packages/uvicorn/middleware/proxy_headers.py\", line 78, in __call__\n return await self.app(scope, receive, send)\n File \"/usr/local/lib/python3.10/dist-packages/fastapi/applications.py\", line 276, in __call__\n await super().__call__(scope, receive, send)\n File \"/usr/local/lib/python3.10/dist-packages/starlette/applications.py\", line 122, in __call__\n await self.middleware_stack(scope, receive, send)\n File \"/usr/local/lib/python3.10/dist-packages/starlette/middleware/errors.py\", line 184, in __call__\n raise exc\n File \"/usr/local/lib/python3.10/dist-packages/starlette/middleware/errors.py\", line 162, in __call__\n await self.app(scope, receive, _send)\n File \"/usr/local/lib/python3.10/dist-packages/starlette/middleware/exceptions.py\", line 79, in __call__\n raise exc\n File \"/usr/local/lib/python3.10/dist-packages/starlette/middleware/exceptions.py\", line 68, in __call__\n await self.app(scope, receive, sender)\n File \"/usr/local/lib/python3.10/dist-packages/fastapi/middleware/asyncexitstack.py\", line 21, in __call__\n raise e\n File \"/usr/local/lib/python3.10/dist-packages/fastapi/middleware/asyncexitstack.py\", line 18, in __call__\n await self.app(scope, receive, send)\n File \"/usr/local/lib/python3.10/dist-packages/starlette/routing.py\", line 718, in __call__\n await route.handle(scope, receive, send)\n File \"/usr/local/lib/python3.10/dist-packages/starlette/routing.py\", line 276, in handle\n await self.app(scope, receive, send)\n File \"/usr/local/lib/python3.10/dist-packages/starlette/routing.py\", line 69, in app\n await response(scope, receive, send)\n File \"/usr/local/lib/python3.10/dist-packages/starlette/responses.py\", line 270, in __call__\n async with anyio.create_task_group() as task_group:\n File \"/usr/local/lib/python3.10/dist-packages/anyio/_backends/_asyncio.py\", line 662, in __aexit__\n raise exceptions[0]\n File \"/usr/local/lib/python3.10/dist-packages/starlette/responses.py\", line 273, in wrap\n await func()\n File \"/usr/local/lib/python3.10/dist-packages/starlette/responses.py\", line 264, in stream_response\n chunk = chunk.encode(self.charset)\n File \"/usr/local/lib/python3.10/dist-packages/openai/openai_object.py\", line 61, in __getattr__\n raise AttributeError(*err.args)\nAttributeError: encode\n```\n\nWhy did this error happen? What should I do to fixed it?\n\n========================================\n\nCode:\n```text\nfrom fastapi import APIRouter, FastAPI, Header\n\nfrom src.chat.completions import chat_stream\nfrom fastapi.responses import StreamingResponse\n\nrouter = APIRouter()\n\n@router.get(\"/v1/completions\",response_class=StreamingResponse)\ndef stream_chat(q: str, authorization: str = Header(None)):\n auth_mode, auth_token = authorization.split(' ')\n if auth_token is None:\n return \"Authorization token is missing\"\n answer = chat_stream(q, auth_token)\n return StreamingResponse(answer, media_type=\"text/event-stream\")\n```\n\n```text\nimport openai\n\ndef chat_stream(question: str, key: str):\n openai.api_key = key\n # create a completion\n completion = openai.Completion.create(model=\"text-davinci-003\",\n prompt=question,\n stream=True)\n return completion\n```\n\n```text\ncurl -N -H \"Authorization: Bearer sk-the openai key\" https://chat.poemhub.top/v1/completions?q=hello\n```\n\n```text\nINFO: 123.146.17.54:0 - \"GET /v1/completions?q=hello HTTP/1.0\" 200 OK\nERROR: Exception in ASGI application\nTraceback (most recent call last):\n File \"/usr/local/lib/python3.10/dist-packages/uvicorn/protocols/http/h11_impl.py\", line 429, in run_asgi\n result = await app( # type: ignore[func-returns-value]\n File \"/usr/local/lib/python3.10/dist-packages/uvicorn/middleware/proxy_headers.py\", line 78, in __call__\n return await self.app(scope, receive, send)\n File \"/usr/local/lib/python3.10/dist-packages/fastapi/applications.py\", line 276, in __call__\n await super().__call__(scope, receive, send)\n File \"/usr/local/lib/python3.10/dist-packages/starlette/applications.py\", line 122, in __call__\n await self.middleware_stack(scope, receive, send)\n File \"/usr/local/lib/python3.10/dist-packages/starlette/middleware/errors.py\", line 184, in __call__\n raise exc\n File \"/usr/local/lib/python3.10/dist-packages/starlette/middleware/errors.py\", line 162, in __call__\n await self.app(scope, receive, _send)\n File \"/usr/local/lib/python3.10/dist-packages/starlette/middleware/exceptions.py\", line 79, in __call__\n raise exc\n File \"/usr/local/lib/python3.10/dist-packages/starlette/middleware/exceptions.py\", line 68, in __call__\n await self.app(scope, receive, sender)\n File \"/usr/local/lib/python3.10/dist-packages/fastapi/middleware/asyncexitstack.py\", line 21, in __call__\n raise e\n File \"/usr/local/lib/python3.10/dist-packages/fastapi/middleware/asyncexitstack.py\", line 18, in __call__\n await self.app(scope, receive, send)\n File \"/usr/local/lib/python3.10/dist-packages/starlette/routing.py\", line 718, in __call__\n await route.handle(scope, receive, send)\n File \"/usr/local/lib/python3.10/dist-packages/starlette/routing.py\", line 276, in handle\n await self.app(scope, receive, send)\n File \"/usr/local/lib/python3.10/dist-packages/starlette/routing.py\", line 69, in app\n await response(scope, receive, send)\n File \"/usr/local/lib/python3.10/dist-packages/starlette/responses.py\", line 270, in __call__\n async with anyio.create_task_group() as task_group:\n File \"/usr/local/lib/python3.10/dist-packages/anyio/_backends/_asyncio.py\", line 662, in __aexit__\n raise exceptions[0]\n File \"/usr/local/lib/python3.10/dist-packages/starlette/responses.py\", line 273, in wrap\n await func()\n File \"/usr/local/lib/python3.10/dist-packages/starlette/responses.py\", line 264, in stream_response\n chunk = chunk.encode(self.charset)\n File \"/usr/local/lib/python3.10/dist-packages/openai/openai_object.py\", line 61, in __getattr__\n raise AttributeError(*err.args)\nAttributeError: encode\n```\n\n```text\n0.92.0\n```\n\n```text\nchat_stream\n```\n\n```py\nasync for chunk in self.body_iterator:\n if not isinstance(chunk, bytes):\n chunk = chunk.encode(self.charset)\n await send({\"type\": \"http.response.body\", \"body\": chunk, \"more_body\": True})\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.responses import StreamingResponse\nimport asyncio\nimport json\n\napp = FastAPI()\n\n\n@app.get('/')\nasync def main():\n async def gen():\n while True:\n #yield (json.dumps({'msg': 'Hello World!'}) + '\\n\\n').encode('utf-8')\n # or, simply use the below, and FastAPI/Starlette will take care of the encoding\n yield json.dumps({'msg': 'Hello World!'}) + '\\n\\n'\n await asyncio.sleep(0.5)\n\n return StreamingResponse(gen(), media_type='text/event-stream')\n```\n\n```py\n# ...\n\n@app.get('/')\nasync def main():\n async def gen():\n while True:\n yield json.dumps({'msg': 'Hello World!'})\n await asyncio.sleep(0.5)\n\n return StreamingResponse(gen(), media_type='application/json')\n```\n\n```text\nStreamingResponse\n```\n\n```text\nasync def\n```\n\n```text\ndef\n```\n\n```text\nStreamingResponse\n```\n\n```text\niterate_in_threadpool()\n```\n\n```text\nawait\n```\n\n```text\niterate_in_threadpool()\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\nasync def\n```\n\n```text\nStreamingResponse\n```\n\n```text\nResponse\n```\n\n```text\nbytes\n```\n\n```text\nbytes\n```\n\n```text\nbytes\n```\n\n```text\nutf-8\n```\n\n```text\nchunk\n```\n\n```text\nstr\n```\n\n```text\nAttributeError\n```\n\n```text\nAttributeError: ... has no attribute 'encode'\n```\n\n```text\nutf-8\n```\n\n```text\nUnicodeEncodeError: ... codec can't encode character\n```\n\n```text\nAttributeError: encode\n```\n\n```text\nstr\n```\n\n```text\nasync def gen()\n```\n\n```text\ndict\n```\n\n```text\nstr\n```\n\n```text\njson.dumps()\n```\n\n```text\norjson\n```\n\n```text\n.encode('utf-8')\n```\n\n```text\ntext/event-stream\n```\n\n```text\napplication/json\n```\n\n```text\ntext/plain\n```\n\n```text\ntext/plain\n```\n\n```text\ntext/plain\n```\n\n========================================\n\nComments:\n- I have already tried what you said to transfer the response to bytes, seems did not work. I am doing it like this right now: `def chat_stream(question: str, key: str): openai.api_key = key completion = openai.Completion.create(model=\"text-davinci-003\", prompt=question, stream=True) for _ in completion: yield f\"data:{json.dumps(_)}\\n\\n\"` so I am not sure the problem is what you said. @Chris\n- I think it maybe the encode issue. you can paste your answer and I will try it and also give other people some clue to avoid this problem. @Chris\n- Sincere thanks for your valuable time and I will tried what you said. @Chris","metadata":{"transformedAt":"2026-08-18T18:32:29.162Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":44,"totalLines":365,"estimatedTokens":2568}}762{"id":"stack-75078242","source":"stackoverflow","questionId":75078242,"title":"How to generate a PNG image in PIL and display it in Jinja2 template using FastAPI?","tags":["python","jinja2","python-imaging-library","fastapi"],"text":"Title: How to generate a PNG image in PIL and display it in Jinja2 template using FastAPI?\nTags: python, jinja2, python-imaging-library, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have a FastAPI endpoint that is generating PIL images. I want to then send the resulting image as a stream to a Jinja2 `TemplateResponse`. This is a simplified version of what I am doing:\n\n```\nimport io\nfrom PIL import Image\n\n@api.get(\"/test_image\", status_code=status.HTTP_200_OK)\ndef test_image(request: Request):\n '''test displaying an image from a stream.\n '''\n test_img = Image.new('RGBA', (300,300), (0, 255, 0, 0))\n\n # I've tried with and without this:\n test_img = test_img.convert(\"RGB\")\n\n test_img = test_img.tobytes()\n base64_encoded_image = base64.b64encode(test_img).decode(\"utf-8\")\n\n return templates.TemplateResponse(\"display_image.html\", {\"request\": request, \"myImage\": base64_encoded_image})\n```\n\nWith this simple html:\n\n```\n\n \n Display Uploaded Image\n \n \n My Image\n \n \n\n```\n\nI've been working from these answers and have tried multiple permutations of these:\n\nHow to display uploaded image in HTML page using FastAPI & Jinja2?\n\nHow to convert PIL Image.image object to base64 string?\n\nHow can I display PIL image to html with render_template flask?\n\nThis seems like it ought to be very simple but all I get is the html icon for an image that didn't render.\n\nWhat am I doing wrong? Thank you.\n\nI used Mark Setchell's answer, which clearly shows what I was doing wrong, but still am not getting an image in html. My FastAPI is:\n\n```\n@api.get(\"/test_image\", status_code=status.HTTP_200_OK)\ndef test_image(request: Request):\n# Create image\n im = Image.new('RGB',(1000,1000),'red')\n\n im.save('red.png')\n\n print(im.tobytes())\n\n # Create buffer\n buffer = io.BytesIO()\n\n # Tell PIL to save as PNG into buffer\n im.save(buffer, 'PNG')\n\n # get the PNG-encoded image from buffer\n PNG = buffer.getvalue()\n\n print()\n print(PNG)\n\n base64_encoded_image = base64.b64encode(PNG)\n\n return templates.TemplateResponse(\"display_image.html\", {\"request\": request, \"myImage\": base64_encoded_image})\n```\n\nand my html:\n\n```\n\n \n Display Uploaded Image\n \n \n My Image 3\n \n \n\n```\n\nWhen I run, if I generate a 1x1 image I get the exact printouts in Mark's answer. If I run this version, with 1000x1000 image, it saves a red.png that I can open and see. But in the end, the html page has the heading and the icon for no image rendered. I'm clearly doing something wrong now in how I send to html.\n\n========================================\n\nTop Answer:\nI used Mark Setchell's answer and comments to come up with this full code. I thought it useful to show what works:\n\n```\nimport base64\nfrom PIL import Image\n\n@api.get(\"/test_image\", status_code=status.HTTP_200_OK)\ndef test_image(request: Request):\n# Create image\n im = Image.new('RGB',(1000,1000),'red')\n\n # Create buffer\n buffer = io.BytesIO()\n\n # Tell PIL to save as PNG into buffer\n im.save(buffer, 'PNG')\n\n # get the PNG-encoded image from buffer\n PNG = buffer.getvalue()\n\n # the only difference is the .decode(\"utf-8\") added here:\n base64_encoded_image = base64.b64encode(PNG).decode(\"utf-8\")\n\n return templates.TemplateResponse(\"display_image.html\", {\"request\": request, \"myImage\": base64_encoded_image})\n```\n\n```\n\n \n Display Uploaded Image\n \n \n My Image 3\n \n \n\n```\n\nThis included some troubleshooting from:\nHow to display a bytes type image in HTML/Jinja2 template using FastAPI?\n\n========================================\n\nCode:\n```py\nimport io\nfrom PIL import Image\n\n@api.get(\"/test_image\", status_code=status.HTTP_200_OK)\ndef test_image(request: Request):\n '''test displaying an image from a stream.\n '''\n test_img = Image.new('RGBA', (300,300), (0, 255, 0, 0))\n\n # I've tried with and without this:\n test_img = test_img.convert(\"RGB\")\n\n test_img = test_img.tobytes()\n base64_encoded_image = base64.b64encode(test_img).decode(\"utf-8\")\n\n return templates.TemplateResponse(\"display_image.html\", {\"request\": request, \"myImage\": base64_encoded_image})\n```\n\n```html\n<html>\n <head>\n <title>Display Uploaded Image</title>\n </head>\n <body>\n <h1>My Image<h1>\n <img src=\"data:image/jpeg;base64,{{ myImage | safe }}\">\n </body>\n</html>\n```\n\n```py\n@api.get(\"/test_image\", status_code=status.HTTP_200_OK)\ndef test_image(request: Request):\n# Create image\n im = Image.new('RGB',(1000,1000),'red')\n\n im.save('red.png')\n\n print(im.tobytes())\n\n # Create buffer\n buffer = io.BytesIO()\n\n # Tell PIL to save as PNG into buffer\n im.save(buffer, 'PNG')\n\n # get the PNG-encoded image from buffer\n PNG = buffer.getvalue()\n\n print()\n print(PNG)\n\n base64_encoded_image = base64.b64encode(PNG)\n\n return templates.TemplateResponse(\"display_image.html\", {\"request\": request, \"myImage\": base64_encoded_image})\n```\n\n```html\n<html>\n <head>\n <title>Display Uploaded Image</title>\n </head>\n <body>\n <h1>My Image 3<h1>\n <img src=\"data:image/png;base64,{{ myImage | safe }}\">\n </body>\n</html>\n```\n\n```text\nTemplateResponse\n```\n\n```text\n<img src=\"data:image/png;base64,{{ myImage | safe }}\">\n```\n\n```text\nim = Image.new('RGB',(1,1),'red')\nprint(im.tobytes())\n```\n\n```text\nb'\\xff\\x00\\x00'\n```\n\n```text\nim.save('red.png')\n```\n\n```text\nxxd red.png\n\n00000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452 .PNG........IHDR\n00000010: 0000 0001 0000 0001 0802 0000 0090 7753 ..............wS\n00000020: de00 0000 0c49 4441 5478 9c63 f8cf c000 .....IDATx.c....\n00000030: 0003 0101 00c9 fe92 ef00 0000 0049 454e .............IEN\n00000040: 44ae 4260 82 D.B`.\n```\n\n```text\nimport io\nimport base64\nfrom PIL import image\n\n# Create image\nim = Image.new('RGB',(1,1),'red')\n\n# Create buffer\nbuffer = io.BytesIO()\n\n# Tell PIL to save as PNG into buffer\nim.save(buffer, 'PNG')\n```\n\n```text\nPNG = buffer.getvalue()\n```\n\n```text\nb'\\x89PNG\\r\\n\\x1a\\n\\x00\\x00\\x00\\rIHDR\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x01\\x08\\x02\\x00\\x00\\x00\\x90wS\\xde\\x00\\x00\\x00\\x0cIDATx\\x9cc\\xf8\\xcf\\xc0\\x00\\x00\\x03\\x01\\x01\\x00\\xc9\\xfe\\x92\\xef\\x00\\x00\\x00\\x00IEND\\xaeB`\\x82'\n```\n\n```text\nbase64_encoded_image = base64.b64encode(PNG)\n```\n\n```text\n#ff0000\n```\n\n```py\nimport base64\nfrom PIL import Image\n\n@api.get(\"/test_image\", status_code=status.HTTP_200_OK)\ndef test_image(request: Request):\n# Create image\n im = Image.new('RGB',(1000,1000),'red')\n\n # Create buffer\n buffer = io.BytesIO()\n\n # Tell PIL to save as PNG into buffer\n im.save(buffer, 'PNG')\n\n # get the PNG-encoded image from buffer\n PNG = buffer.getvalue()\n\n # the only difference is the .decode(\"utf-8\") added here:\n base64_encoded_image = base64.b64encode(PNG).decode(\"utf-8\")\n\n return templates.TemplateResponse(\"display_image.html\", {\"request\": request, \"myImage\": base64_encoded_image})\n```\n\n```html\n<html>\n <head>\n <title>Display Uploaded Image</title>\n </head>\n <body>\n <h1>My Image 3<h1>\n <img src=\"data:image/png;base64,{{ myImage | safe }}\">\n </body>\n</html>\n```\n\n========================================\n\nComments:\n- Thank you for this very instructive answer, I can see what I was doing wrong with the PNG but it is still not working. I edited my answer to show what I have now. I get the results exactly as you say (in the prints and the saved file) but still do not get a rendered image in html. Any idea what I am doing wrong here?\n- Go in your web browser, and go to *\"Developer Tools\"* and open *\"Page Source\"* or however these are named in your browser and look at what your app sent as HTML, specifically the `` part.\n- Thank you, I was not decoding the base64 PNG. Although the first code in the question I posted had it, I lost it in my revision. To make it more clear, I posted an answer with the full functional code based on your answer. Thank you.\n- Please remember to properly `close` the `Image` and `BytesIO` objects, in order to release their memory (see related answers **here**, as well as **here**).","metadata":{"transformedAt":"2026-08-18T18:32:29.162Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":17,"totalLines":319,"estimatedTokens":1979}}763{"id":"stack-71681068","source":"stackoverflow","questionId":71681068,"title":"How to customize error response for a specific route in FastAPI?","tags":["python","fastapi","pydantic","http-status-code-422"],"text":"Title: How to customize error response for a specific route in FastAPI?\nTags: python, fastapi, pydantic, http-status-code-422\nSource: Stack Overflow\n\nQuestion:\nI want to make an `HTTP` endpoint in FastAPI that requires a specific `Header`, produces a custom `response` code when the `Header` is absent, as well as shows the `Header` as *required* in the OpenAPI docs generated by FastAPI.\n\nFor example, if I make this endpoint to require `some-custom-header`:\n\n```\n@app.post(\"/\")\nasync def fn(some_custom_header: str = Header(...)):\n pass\n```\n\nwhen a client request lacks `some-custom-header`, the server will produce a `response` with error code `422 Unprocessable entity`. However I'd like to be able to change that to `401 Unauthorized`. In other words, I would like to **customise the `RequestValidationError` for that specific route** in my API.\n\nI thought a possible solution would be to use `Header(None)`, and do a test for `None` in the function body, but, unfortunately, this results in the OpenAPI docs indicating that the header is *optional*.\n\n========================================\n\nCode:\n```py\n@app.post(\"/\")\nasync def fn(some_custom_header: str = Header(...)):\n pass\n```\n\n```text\nHTTP\n```\n\n```text\nHeader\n```\n\n```text\nresponse\n```\n\n```text\nHeader\n```\n\n```text\nHeader\n```\n\n```text\nsome-custom-header\n```\n\n```text\nsome-custom-header\n```\n\n```text\nresponse\n```\n\n```text\n422 Unprocessable entity\n```\n\n```text\n401 Unauthorized\n```\n\n```text\nRequestValidationError\n```\n\n```text\nHeader(None)\n```\n\n```text\nNone\n```\n\n```py\nfrom fastapi import Header, HTTPException\n\n@app.post(\"/\")\ndef some_route(some_custom_header: Optional[str] = Header(None)):\n if not some_custom_header:\n raise HTTPException(status_code=401, detail=\"Unauthorized\")\n return {\"some-custom-header\": some_custom_header}\n```\n\n```py\nfrom fastapi import FastAPI, Request, Header, status\nfrom fastapi.exceptions import RequestValidationError\nfrom fastapi.responses import JSONResponse\nfrom fastapi.encoders import jsonable_encoder\n\napp = FastAPI()\nroutes_with_custom_exception = ['/']\n\n\n@app.exception_handler(RequestValidationError)\nasync def validation_exception_handler(request: Request, exc: RequestValidationError):\n if request.url.path in routes_with_custom_exception:\n # check whether the error relates to the `some_custom_header` parameter\n for err in exc.errors():\n if err['loc'][0] == 'header' and err['loc'][1] == 'some-custom-header':\n return JSONResponse(content={'401': 'Unauthorized'}, status_code=401)\n \n return JSONResponse(\n status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,\n content=jsonable_encoder({'detail': exc.errors(), 'body': exc.body}),\n )\n\n\n@app.get('/')\ndef some_route(some_custom_header: str = Header(...)):\n return {'some-custom-header': some_custom_header}\n```\n\n```py\nfrom fastapi import FastAPI, Request, Header\nfrom fastapi.exceptions import RequestValidationError\nfrom fastapi.responses import JSONResponse\n\napp = FastAPI()\n\n\n@app.get('/')\nasync def main():\n return {'message': 'Hello from main API'}\n \n\nsubapi = FastAPI()\n\n\n@subapi.exception_handler(RequestValidationError)\nasync def validation_exception_handler(request: Request, exc: RequestValidationError):\n # if there are other parameters defined in the endpoint other than\n # `some_custom_header`, then perform a check, as demonstrated in Option 2\n return JSONResponse(content={'401': 'Unauthorized'}, status_code=401)\n\n \n@subapi.get('/')\nasync def sub_api_route(some_custom_header: str = Header(...)):\n return {'some-custom-header': some_custom_header} \n\n\napp.mount('/sub', subapi)\n```\n\n```py\nimport requests\n\n# Test main API\nurl = 'http://127.0.0.1:8000/'\n\nr = requests.get(url=url)\nprint(r.status_code, r.json())\n\n# Test sub API\nurl = 'http://127.0.0.1:8000/sub/'\n\nr = requests.get(url=url)\nprint(r.status_code, r.json())\n\nheaders = {'some-custom-header': 'this is some custom header'}\nr = requests.get(url=url, headers=headers)\nprint(r.status_code, r.json())\n```\n\n```py\nfrom fastapi import FastAPI, APIRouter, Response, Request, Header, HTTPException\nfrom fastapi.responses import JSONResponse\nfrom fastapi.exceptions import RequestValidationError\nfrom fastapi.routing import APIRoute\nfrom typing import Callable\n\n\nclass ValidationErrorHandlingRoute(APIRoute):\n def get_route_handler(self) -> Callable:\n original_route_handler = super().get_route_handler()\n\n async def custom_route_handler(request: Request) -> Response:\n try:\n return await original_route_handler(request)\n except RequestValidationError as e:\n # if there are other parameters defined in the endpoint other than\n # `some_custom_header`, then perform a check, as demonstrated in Option 2\n raise HTTPException(status_code=401, detail='401 Unauthorized')\n \n return custom_route_handler\n\n\napp = FastAPI()\nrouter = APIRouter(route_class=ValidationErrorHandlingRoute)\n\n\n@app.get('/')\nasync def main():\n return {'message': 'Hello from main API'}\n \n\n@router.get('/custom')\nasync def custom_route(some_custom_header: str = Header(...)):\n return {'some-custom-header': some_custom_header}\n\n\napp.include_router(router)\n```\n\n```py\nimport requests\n\n# Test main API\nurl = 'http://127.0.0.1:8000/'\n\nr = requests.get(url=url)\nprint(r.status_code, r.json())\n\n# Test custom route\nurl = 'http://127.0.0.1:8000/custom'\n\nr = requests.get(url=url)\nprint(r.status_code, r.json())\n\nheaders = {'some-custom-header': 'this is some custom header'}\nr = requests.get(url=url, headers=headers)\nprint(r.status_code, r.json())\n```\n\n```text\nHeader\n```\n\n```text\nOptional\n```\n\n```text\nHeader\n```\n\n```text\nRequestValidationError\n```\n\n```text\nRequestValidationError\n```\n\n```text\nRequestValidationError\n```\n\n```text\nValidationError\n```\n\n```text\nHeader\n```\n\n```text\nstr\n```\n\n```text\nHeader\n```\n\n```text\nsome_custom_header\n```\n\n```text\nRequestValidationError\n```\n\n```text\nHeader\n```\n\n```text\nexception_handler\n```\n\n```text\nRequestValidationError\n```\n\n```text\nrequest.url.path\n```\n\n```text\nsubapi\n```\n\n```text\n'/'\n```\n\n```text\nsubapi\n```\n\n```text\n'/'\n```\n\n```text\nhttp://127.0.0.1:8000/\n```\n\n```text\nsubapi\n```\n\n```text\n'/sub'\n```\n\n```text\nAPIRouter\n```\n\n```text\nAPIRoute\n```\n\n```text\ntry-except\n```\n\n```text\nRequestValidationError\n```\n\n========================================\n\nComments:\n- Thanks Chris, this looks like a solution. It's a bit of a shame that it has to be done in a 'global' exception handler, rather than something specific to the route that's generating the error, but it'll do the job.\n- @RobGilton The answer above has been further updated with more options. Please have a look.","metadata":{"transformedAt":"2026-08-18T18:32:29.162Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":47,"totalLines":343,"estimatedTokens":1688}}764{"id":"stack-72159217","source":"stackoverflow","questionId":72159217,"title":"List of items in FastAPI response","tags":["python","fastapi","pydantic"],"text":"Title: List of items in FastAPI response\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nIn my Fast API app I have this pydantic model\n\n```\nclass UserInArticleView(BaseModel):\n \"\"\"What fields will be in nested sent_to_user list.\"\"\"\n\n telegram_id: int\n\n class Config:\n \"\"\"Enable ORM mode.\"\"\"\n\n orm_mode = True\n\nclass ArticleBase(BaseModel):\n id: int\n text: str = Field(..., min_length=50, max_length=1024)\n image_url: HttpUrl = Field(..., title=\"Image URL\")\n language_code: str = Field(\"ru\", max_length=3, min_length=2)\n sent_to_user: List[UserInArticleView] = []\n\n class Config:\n orm_mode = True\n```\n\nThe response is\n\n```\n[\n {\n \"id\": 1,\n \"text\": \"Some text\",\n \"image_url\": \"http://test.tt/\",\n \"language_code\": \"ru\",\n \"sent_to_user\": [\n {\n \"telegram_id\": 444444444\n },\n {\n \"telegram_id\": 111111111\n }\n ]\n }\n]\n```\n\nIs there a way to have a response with \"sent_to_user\" as a list of values, like below?\nThe reason is I need to check IN condition.\n\n```\n\"sent_to_user\": [\n 444444444,\n 111111111\n]\n```\n\nThe final solution is:\n\n```\n@app.get(\"/articles/{article_id}\", tags=[\"article\"])\ndef read_article(article_id: int, db: Session = Depends(get_db)):\n \"\"\"Read single article by id.\"\"\"\n db_article = crud.get_article(db, article_id=article_id)\n if db_article is None:\n raise HTTPException(status_code=404, detail=\"Article not found\")\n list_sent_to_user = [i.telegram_id for i in db_article.sent_to_user]\n print(\"list\", list_sent_to_user)\n return list_sent_to_user\n```\n\n========================================\n\nCode:\n```text\nclass UserInArticleView(BaseModel):\n \"\"\"What fields will be in nested sent_to_user list.\"\"\"\n\n telegram_id: int\n\n class Config:\n \"\"\"Enable ORM mode.\"\"\"\n\n orm_mode = True\n\nclass ArticleBase(BaseModel):\n id: int\n text: str = Field(..., min_length=50, max_length=1024)\n image_url: HttpUrl = Field(..., title=\"Image URL\")\n language_code: str = Field(\"ru\", max_length=3, min_length=2)\n sent_to_user: List[UserInArticleView] = []\n\n class Config:\n orm_mode = True\n```\n\n```text\n[\n {\n \"id\": 1,\n \"text\": \"Some text\",\n \"image_url\": \"http://test.tt/\",\n \"language_code\": \"ru\",\n \"sent_to_user\": [\n {\n \"telegram_id\": 444444444\n },\n {\n \"telegram_id\": 111111111\n }\n ]\n }\n]\n```\n\n```text\n\"sent_to_user\": [\n 444444444,\n 111111111\n]\n```\n\n```text\n@app.get(\"/articles/{article_id}\", tags=[\"article\"])\ndef read_article(article_id: int, db: Session = Depends(get_db)):\n \"\"\"Read single article by id.\"\"\"\n db_article = crud.get_article(db, article_id=article_id)\n if db_article is None:\n raise HTTPException(status_code=404, detail=\"Article not found\")\n list_sent_to_user = [i.telegram_id for i in db_article.sent_to_user]\n print(\"list\", list_sent_to_user)\n return list_sent_to_user\n```\n\n```py\nclass ArticleBase(BaseModel):\n id: int\n text: str = Field(..., min_length=50, max_length=1024)\n image_url: HttpUrl = Field(..., title=\"Image URL\")\n language_code: str = Field(\"ru\", max_length=3, min_length=2)\n sent_to_user: List[UserInArticleView] = []\n\n class Config:\n orm_mode = True\n\n\nclass ArticleResponse(ArticleBase):\n sent_to_user: List[int] = []\n```\n\n```py\nlist_int = [elt['telegram_id'] for elt in result_articles['sent_to_user']]\n```\n\n```py\n@router.get('/articles/{article_id}',\n summary=\"get article\"\n status_code=status.HTTP_200_OK,\n response_model=ArticleResponse)\ndef update_date(article_id:int):\n articles = get_article(article_id)\n articles.sent_to_user = [elt.telegram_id for elt in articles.sent_to_user]\n\n return articles\n```\n\n```text\nArticleBase\n```\n\n```text\nsent_to_user\n```\n\n```text\nList\n```\n\n```text\nint\n```\n\n========================================\n\nComments:\n- Thanks for reply. But it doesn't work as expected\n- Editing of the answer. You need to format your model's answer before returning it\n- I can't understand where do I need to add this code?\n- Editing of the answer again for add an integration example.\n- Well, it worked this way `list_sent_to_user = [i.telegram_id for i in db_article.sent_to_user]`\n- But I still can not get right response `AttributeError: 'Article' object has no attribute 'dict'`\n- It was just an example to adapt. But I modified it to make it work\n- This way we need to remove response_model as well, otherwise it gives an error\n- Normally, that work. Edit your first message and add your code, where you fit that","metadata":{"transformedAt":"2026-08-18T18:32:29.162Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":11,"totalLines":197,"estimatedTokens":1111}}765{"id":"stack-70568070","source":"stackoverflow","questionId":70568070,"title":"Running an Asyncio Subprocess in FastApi results in NotImplementedError","tags":["python","python-asyncio","fastapi"],"text":"Title: Running an Asyncio Subprocess in FastApi results in NotImplementedError\nTags: python, python-asyncio, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm trying to run a Subprocess in a FastApi route, but the execution results in `NotImplementedError`. I've read similar questions on the issue:\n\nWhy am I getting NotImplementedError with async and await on Windows?\n\nAsyncio.create_subprocess_exec NotImplementedError - Fastapi Background Task\n\nBut it doesn't seem they have any viable solutions.\n\nMy FastApi route looks like this:\n\n```\n@app.get(\"/test/subprocess\")\nasync def subprocess_test():\n parsed_json = await(probe_video_file(Path(r\"G:\\ffmpeg testing\\ffmpeg\\ffprobe.exe\"),\n Path(r\"G:\\ffmpeg testing\\input_file\\test_file.wmv\")))\n print(parsed_json)\n return parsed_json\n```\n\nWhen I navigate to this rout, an exception is raised and the code crushes.\nThe `probe_video_file` function has a subprocess call inside it, like so:\n\n```\nasync def probe_video_file(ffprobe_path: Path, file_to_probe: Path) -> dict:\n \"\"\"\n Probes a video file with FFprobe.\n :param ffprobe_path: Path to ffprobe executable\n :param file_to_probe: Path to file to probe\n :returns Parsed JSON dict of the output\n \"\"\"\n args = [f'{str(ffprobe_path)}', f'{str(file_to_probe)}']\n args += [\"-hide_banner\", \"-loglevel\", \"fatal\", \"-show_error\", \"-show_format\", \"-show_streams\", \"-show_chapters\",\n \"-show_private_data\", \"-print_format\", \"json\"]\n\n #sub process is here, and here is where the exception happens.\n proc = await asyncio.create_subprocess_exec(\n *args,\n stdout=asyncio.subprocess.PIPE,\n stderr=asyncio.subprocess.PIPE)\n\n stdout, stderr = await proc.communicate()\n\n print(f'exited with {proc.returncode}]')\n if stdout:\n print(f'[stdout]\\n{stdout.decode()}')\n if stderr:\n print(f'[stderr]\\n{stderr.decode()}')\n raise Exception(f\"Failed to probe file {file_to_probe}\")\n\n return json.loads(stdout)\n```\n\nWhen I run `probe_video_file` without FastAPI, like so:\n\n```\nasync def main():\n json_output = await probe_video_file(Path(r\"G:\\ffmpeg testing\\ffmpeg\\ffprobe.exe\"),\n Path(r\"G:\\ffmpeg testing\\input_file\\test_file.wmv\"))\n print(json_output)\n\nif __name__ == '__main__':\n asyncio.run(main())\n```\n\nIt runs just fine and prints the correct output:\n\n```\n[['G:\\\\ffmpeg testing\\\\ffmpeg\\\\ffprobe.exe', 'G:\\\\ffmpeg testing\\\\input_file\\\\test_file.wmv', '-hide_banner', '-loglevel', 'fatal', '-show_error', '-show_format', '-show_streams', '-show_chapters', '-show_private_data', '-print_format', 'json'] exited with 0]\n[stdout]\n{\n \"streams\": [\n {\n \"index\": 0,\n \"codec_name\": \"wmav2\",\n \"codec_long_name\": \"Windows Media Audio 2\",\n \"codec_type\": \"audio\",\n \"codec_tag_string\": \"a[1][0][0]\",\n \"codec_tag\": \"0x0161\",\n \"sample_fmt\": \"fltp\",\n \"sample_rate\": \"48000\",\n \"channels\": 2,\n \"bits_per_sample\": 0,\n \"r_frame_rate\": \"0/0\",\n \"avg_frame_rate\": \"0/0\",\n \"time_base\": \"1/1000\",\n \"start_pts\": 0,\n \"start_time\": \"0.000000\",\n \"duration_ts\": 2155050,\n \"duration\": \"2155.050000\",\n \"bit_rate\": \"96000\",\n \"disposition\": {\n \"default\": 0,\n \"dub\": 0,\n \"original\": 0,\n \"comment\": 0,\n \"lyrics\": 0,\n \"karaoke\": 0,\n \"forced\": 0,\n \"hearing_impaired\": 0,\n \"visual_impaired\": 0,\n \"clean_effects\": 0,\n \"attached_pic\": 0,\n \"timed_thumbnails\": 0\n },\n \"tags\": {\n \"language\": \"eng\"\n }\n },\n {\n \"index\": 1,\n \"codec_name\": \"wmv3\",\n \"codec_long_name\": \"Windows Media Video 9\",\n \"profile\": \"Main\",\n \"codec_type\": \"video\",\n \"codec_tag_string\": \"WMV3\",\n \"codec_tag\": \"0x33564d57\",\n \"width\": 850,\n \"height\": 480,\n \"coded_width\": 850,\n \"coded_height\": 480,\n \"closed_captions\": 0,\n \"has_b_frames\": 0,\n \"pix_fmt\": \"yuv420p\",\n \"level\": -99,\n \"chroma_location\": \"left\",\n \"refs\": 1,\n \"r_frame_rate\": \"30000/1001\",\n \"avg_frame_rate\": \"30000/1001\",\n \"time_base\": \"1/1000\",\n \"start_pts\": 0,\n \"start_time\": \"0.000000\",\n \"duration_ts\": 2155050,\n \"duration\": \"2155.050000\",\n \"bit_rate\": \"2000000\",\n \"disposition\": {\n \"default\": 0,\n \"dub\": 0,\n \"original\": 0,\n \"comment\": 0,\n \"lyrics\": 0,\n \"karaoke\": 0,\n \"forced\": 0,\n \"hearing_impaired\": 0,\n \"visual_impaired\": 0,\n \"clean_effects\": 0,\n \"attached_pic\": 0,\n \"timed_thumbnails\": 0\n },\n \"tags\": {\n \"language\": \"eng\"\n }\n }\n ],\n \"chapters\": [\n\n ],\n \"format\": {\n \"filename\": \"G:\\\\ffmpeg testing\\\\input_file\\\\test_file.wmv\",\n \"nb_streams\": 2,\n \"nb_programs\": 0,\n \"format_name\": \"asf\",\n \"format_long_name\": \"ASF (Advanced / Active Streaming Format)\",\n \"start_time\": \"0.000000\",\n \"duration\": \"2155.050000\",\n \"size\": \"567194391\",\n \"bit_rate\": \"2105545\",\n \"probe_score\": 100,\n \"tags\": {\n \"WMFSDKNeeded\": \"0.0.0.0000\",\n \"DeviceConformanceTemplate\": \"MP@HL\",\n \"WMFSDKVersion\": \"11.0.5721.5265\",\n \"IsVBR\": \"0\"\n }\n }\n}\n\n{'streams': [{'index': 0, 'codec_name': 'wmav2', 'codec_long_name': 'Windows Media Audio 2', 'codec_type': 'audio', 'codec_tag_string': 'a[1][0][0]', 'codec_tag': '0x0161', 'sample_fmt': 'fltp', 'sample_rate': '48000', 'channels': 2, 'bits_per_sample': 0, 'r_frame_rate': '0/0', 'avg_frame_rate': '0/0', 'time_base': '1/1000', 'start_pts': 0, 'start_time': '0.000000', 'duration_ts': 2155050, 'duration': '2155.050000', 'bit_rate': '96000', 'disposition': {'default': 0, 'dub': 0, 'original': 0, 'comment': 0, 'lyrics': 0, 'karaoke': 0, 'forced': 0, 'hearing_impaired': 0, 'visual_impaired': 0, 'clean_effects': 0, 'attached_pic': 0, 'timed_thumbnails': 0}, 'tags': {'language': 'eng'}}, {'index': 1, 'codec_name': 'wmv3', 'codec_long_name': 'Windows Media Video 9', 'profile': 'Main', 'codec_type': 'video', 'codec_tag_string': 'WMV3', 'codec_tag': '0x33564d57', 'width': 850, 'height': 480, 'coded_width': 850, 'coded_height': 480, 'closed_captions': 0, 'has_b_frames': 0, 'pix_fmt': 'yuv420p', 'level': -99, 'chroma_location': 'left', 'refs': 1, 'r_frame_rate': '30000/1001', 'avg_frame_rate': '30000/1001', 'time_base': '1/1000', 'start_pts': 0, 'start_time': '0.000000', 'duration_ts': 2155050, 'duration': '2155.050000', 'bit_rate': '2000000', 'disposition': {'default': 0, 'dub': 0, 'original': 0, 'comment': 0, 'lyrics': 0, 'karaoke': 0, 'forced': 0, 'hearing_impaired': 0, 'visual_impaired': 0, 'clean_effects': 0, 'attached_pic': 0, 'timed_thumbnails': 0}, 'tags': {'language': 'eng'}}], 'chapters': [], 'format': {'filename': 'G:\\\\ffmpeg testing\\\\input_file\\\\test_file.wmv', 'nb_streams': 2, 'nb_programs': 0, 'format_name': 'asf', 'format_long_name': 'ASF (Advanced / Active Streaming Format)', 'start_time': '0.000000', 'duration': '2155.050000', 'size': '567194391', 'bit_rate': '2105545', 'probe_score': 100, 'tags': {'WMFSDKNeeded': '0.0.0.0000', 'DeviceConformanceTemplate': 'MP@HL', 'WMFSDKVersion': '11.0.5721.5265', 'IsVBR': '0'}}}\n\nProcess finished with exit code 0\n```\n\nI've tried 'setting' the event loop to `ProactorEventLoop` like it's suggested in the other questions:\n\n```\n@app.on_event(\"startup\")\nasync def startup_event():\n \"\"\"Code runs at startup...\"\"\"\n loop = asyncio.ProactorEventLoop()\n asyncio.set_event_loop(loop)\n```\n\nBut it had no effect.\n\nHere is the exception traceback:\n\n```\nERROR: Exception in ASGI application\nTraceback (most recent call last):\n File \"E:\\pycharm\\my_project\\venv\\lib\\site-packages\\uvicorn\\protocols\\http\\httptools_impl.py\", line 375, in run_asgi\n result = await app(self.scope, self.receive, self.send)\n File \"E:\\pycharm\\my_project\\venv\\lib\\site-packages\\uvicorn\\middleware\\proxy_headers.py\", line 75, in __call__\n return await self.app(scope, receive, send)\n File \"E:\\pycharm\\my_project\\venv\\lib\\site-packages\\fastapi\\applications.py\", line 208, in __call__\n await super().__call__(scope, receive, send)\n File \"E:\\pycharm\\my_project\\venv\\lib\\site-packages\\starlette\\applications.py\", line 112, in __call__\n await self.middleware_stack(scope, receive, send)\n File \"E:\\pycharm\\my_project\\venv\\lib\\site-packages\\starlette\\middleware\\errors.py\", line 181, in __call__\n raise exc\n File \"E:\\pycharm\\my_project\\venv\\lib\\site-packages\\starlette\\middleware\\errors.py\", line 159, in __call__\n await self.app(scope, receive, _send)\n File \"E:\\pycharm\\my_project\\venv\\lib\\site-packages\\starlette\\middleware\\cors.py\", line 84, in __call__\n await self.app(scope, receive, send)\n File \"E:\\pycharm\\my_project\\venv\\lib\\site-packages\\starlette\\exceptions.py\", line 82, in __call__\n raise exc\n File \"E:\\pycharm\\my_project\\venv\\lib\\site-packages\\starlette\\exceptions.py\", line 71, in __call__\n await self.app(scope, receive, sender)\n File \"E:\\pycharm\\my_project\\venv\\lib\\site-packages\\starlette\\routing.py\", line 656, in __call__\n await route.handle(scope, receive, send)\n File \"E:\\pycharm\\my_project\\venv\\lib\\site-packages\\starlette\\routing.py\", line 259, in handle\n await self.app(scope, receive, send)\n File \"E:\\pycharm\\my_project\\venv\\lib\\site-packages\\starlette\\routing.py\", line 61, in app\n response = await func(request)\n File \"E:\\pycharm\\my_project\\venv\\lib\\site-packages\\fastapi\\routing.py\", line 226, in app\n raw_response = await run_endpoint_function(\n File \"E:\\pycharm\\my_project\\venv\\lib\\site-packages\\fastapi\\routing.py\", line 159, in run_endpoint_function\n return await dependant.call(**values)\n File \"E:\\pycharm\\my_project\\src\\backend\\app\\api\\api.py\", line 202, in subprocess_test\n parsed_json = await(probe_video_file(Path(r\"G:\\ffmpeg testing\\ffmpeg\\ffprobe.exe\"),\n File \"E:\\pycharm\\my_project\\src\\backend\\app\\ffmpeg\\ffprobe.py\", line 26, in probe_video_file\n proc = await asyncio.create_subprocess_exec(\n File \"C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310\\lib\\asyncio\\subprocess.py\", line 218, in create_subprocess_exec\n transport, protocol = await loop.subprocess_exec(\n File \"C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310\\lib\\asyncio\\base_events.py\", line 1652, in subprocess_exec\n transport = await self._make_subprocess_transport(\n File \"C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310\\lib\\asyncio\\base_events.py\", line 493, in _make_subprocess_transport\n raise NotImplementedError\nNotImplementedError\nINFO: 127.0.0.1:58576 - \"GET /test/subprocess HTTP/1.1\" 500 Internal Server Error\n```\n\nDoes anyone know how to resolve it? From what I understand this has to do with FastApi's default event loop not supporting this. But I don't know how to set or replace the default FastApi event loop with Asyncio's default event loop.\n\n### EDIT:\n\nI think it's important to point out that I'm using windows 10.\n\n========================================\n\nTop Answer:\nI had this same issue and noting the response from thisisalsomypassword, I removed the `--reload` argument from uvicorn, and instead installed `watchfiles` directly and wrapped the uvicorn command. For example in dev I use:\n\n```\nwatchfiles \"uvicorn mypackage.main:app\" mypackage\n```\n\nThis launches the `mypackage.main.app` watching in the `mypackage` folder for code changes.\n\nThis works on Windows because the watchfiles process is now seperate and uvicorn no longer overwrites the default loop because it doesn't have the `--reload` argument anymore.\n\nIn production it's not an issue because reloading is not required.\n\n========================================\n\nCode:\n```py\n@app.get(\"/test/subprocess\")\nasync def subprocess_test():\n parsed_json = await(probe_video_file(Path(r\"G:\\ffmpeg testing\\ffmpeg\\ffprobe.exe\"),\n Path(r\"G:\\ffmpeg testing\\input_file\\test_file.wmv\")))\n print(parsed_json)\n return parsed_json\n```\n\n```py\nasync def probe_video_file(ffprobe_path: Path, file_to_probe: Path) -> dict:\n \"\"\"\n Probes a video file with FFprobe.\n :param ffprobe_path: Path to ffprobe executable\n :param file_to_probe: Path to file to probe\n :returns Parsed JSON dict of the output\n \"\"\"\n args = [f'{str(ffprobe_path)}', f'{str(file_to_probe)}']\n args += [\"-hide_banner\", \"-loglevel\", \"fatal\", \"-show_error\", \"-show_format\", \"-show_streams\", \"-show_chapters\",\n \"-show_private_data\", \"-print_format\", \"json\"]\n\n #sub process is here, and here is where the exception happens.\n proc = await asyncio.create_subprocess_exec(\n *args,\n stdout=asyncio.subprocess.PIPE,\n stderr=asyncio.subprocess.PIPE)\n\n stdout, stderr = await proc.communicate()\n\n print(f'exited with {proc.returncode}]')\n if stdout:\n print(f'[stdout]\\n{stdout.decode()}')\n if stderr:\n print(f'[stderr]\\n{stderr.decode()}')\n raise Exception(f\"Failed to probe file {file_to_probe}\")\n\n return json.loads(stdout)\n```\n\n```py\nasync def main():\n json_output = await probe_video_file(Path(r\"G:\\ffmpeg testing\\ffmpeg\\ffprobe.exe\"),\n Path(r\"G:\\ffmpeg testing\\input_file\\test_file.wmv\"))\n print(json_output)\n\n\nif __name__ == '__main__':\n asyncio.run(main())\n```\n\n```json\n[['G:\\\\ffmpeg testing\\\\ffmpeg\\\\ffprobe.exe', 'G:\\\\ffmpeg testing\\\\input_file\\\\test_file.wmv', '-hide_banner', '-loglevel', 'fatal', '-show_error', '-show_format', '-show_streams', '-show_chapters', '-show_private_data', '-print_format', 'json'] exited with 0]\n[stdout]\n{\n \"streams\": [\n {\n \"index\": 0,\n \"codec_name\": \"wmav2\",\n \"codec_long_name\": \"Windows Media Audio 2\",\n \"codec_type\": \"audio\",\n \"codec_tag_string\": \"a[1][0][0]\",\n \"codec_tag\": \"0x0161\",\n \"sample_fmt\": \"fltp\",\n \"sample_rate\": \"48000\",\n \"channels\": 2,\n \"bits_per_sample\": 0,\n \"r_frame_rate\": \"0/0\",\n \"avg_frame_rate\": \"0/0\",\n \"time_base\": \"1/1000\",\n \"start_pts\": 0,\n \"start_time\": \"0.000000\",\n \"duration_ts\": 2155050,\n \"duration\": \"2155.050000\",\n \"bit_rate\": \"96000\",\n \"disposition\": {\n \"default\": 0,\n \"dub\": 0,\n \"original\": 0,\n \"comment\": 0,\n \"lyrics\": 0,\n \"karaoke\": 0,\n \"forced\": 0,\n \"hearing_impaired\": 0,\n \"visual_impaired\": 0,\n \"clean_effects\": 0,\n \"attached_pic\": 0,\n \"timed_thumbnails\": 0\n },\n \"tags\": {\n \"language\": \"eng\"\n }\n },\n {\n \"index\": 1,\n \"codec_name\": \"wmv3\",\n \"codec_long_name\": \"Windows Media Video 9\",\n \"profile\": \"Main\",\n \"codec_type\": \"video\",\n \"codec_tag_string\": \"WMV3\",\n \"codec_tag\": \"0x33564d57\",\n \"width\": 850,\n \"height\": 480,\n \"coded_width\": 850,\n \"coded_height\": 480,\n \"closed_captions\": 0,\n \"has_b_frames\": 0,\n \"pix_fmt\": \"yuv420p\",\n \"level\": -99,\n \"chroma_location\": \"left\",\n \"refs\": 1,\n \"r_frame_rate\": \"30000/1001\",\n \"avg_frame_rate\": \"30000/1001\",\n \"time_base\": \"1/1000\",\n \"start_pts\": 0,\n \"start_time\": \"0.000000\",\n \"duration_ts\": 2155050,\n \"duration\": \"2155.050000\",\n \"bit_rate\": \"2000000\",\n \"disposition\": {\n \"default\": 0,\n \"dub\": 0,\n \"original\": 0,\n \"comment\": 0,\n \"lyrics\": 0,\n \"karaoke\": 0,\n \"forced\": 0,\n \"hearing_impaired\": 0,\n \"visual_impaired\": 0,\n \"clean_effects\": 0,\n \"attached_pic\": 0,\n \"timed_thumbnails\": 0\n },\n \"tags\": {\n \"language\": \"eng\"\n }\n }\n ],\n \"chapters\": [\n\n ],\n \"format\": {\n \"filename\": \"G:\\\\ffmpeg testing\\\\input_file\\\\test_file.wmv\",\n \"nb_streams\": 2,\n \"nb_programs\": 0,\n \"format_name\": \"asf\",\n \"format_long_name\": \"ASF (Advanced / Active Streaming Format)\",\n \"start_time\": \"0.000000\",\n \"duration\": \"2155.050000\",\n \"size\": \"567194391\",\n \"bit_rate\": \"2105545\",\n \"probe_score\": 100,\n \"tags\": {\n \"WMFSDKNeeded\": \"0.0.0.0000\",\n \"DeviceConformanceTemplate\": \"MP@HL\",\n \"WMFSDKVersion\": \"11.0.5721.5265\",\n \"IsVBR\": \"0\"\n }\n }\n}\n\n{'streams': [{'index': 0, 'codec_name': 'wmav2', 'codec_long_name': 'Windows Media Audio 2', 'codec_type': 'audio', 'codec_tag_string': 'a[1][0][0]', 'codec_tag': '0x0161', 'sample_fmt': 'fltp', 'sample_rate': '48000', 'channels': 2, 'bits_per_sample': 0, 'r_frame_rate': '0/0', 'avg_frame_rate': '0/0', 'time_base': '1/1000', 'start_pts': 0, 'start_time': '0.000000', 'duration_ts': 2155050, 'duration': '2155.050000', 'bit_rate': '96000', 'disposition': {'default': 0, 'dub': 0, 'original': 0, 'comment': 0, 'lyrics': 0, 'karaoke': 0, 'forced': 0, 'hearing_impaired': 0, 'visual_impaired': 0, 'clean_effects': 0, 'attached_pic': 0, 'timed_thumbnails': 0}, 'tags': {'language': 'eng'}}, {'index': 1, 'codec_name': 'wmv3', 'codec_long_name': 'Windows Media Video 9', 'profile': 'Main', 'codec_type': 'video', 'codec_tag_string': 'WMV3', 'codec_tag': '0x33564d57', 'width': 850, 'height': 480, 'coded_width': 850, 'coded_height': 480, 'closed_captions': 0, 'has_b_frames': 0, 'pix_fmt': 'yuv420p', 'level': -99, 'chroma_location': 'left', 'refs': 1, 'r_frame_rate': '30000/1001', 'avg_frame_rate': '30000/1001', 'time_base': '1/1000', 'start_pts': 0, 'start_time': '0.000000', 'duration_ts': 2155050, 'duration': '2155.050000', 'bit_rate': '2000000', 'disposition': {'default': 0, 'dub': 0, 'original': 0, 'comment': 0, 'lyrics': 0, 'karaoke': 0, 'forced': 0, 'hearing_impaired': 0, 'visual_impaired': 0, 'clean_effects': 0, 'attached_pic': 0, 'timed_thumbnails': 0}, 'tags': {'language': 'eng'}}], 'chapters': [], 'format': {'filename': 'G:\\\\ffmpeg testing\\\\input_file\\\\test_file.wmv', 'nb_streams': 2, 'nb_programs': 0, 'format_name': 'asf', 'format_long_name': 'ASF (Advanced / Active Streaming Format)', 'start_time': '0.000000', 'duration': '2155.050000', 'size': '567194391', 'bit_rate': '2105545', 'probe_score': 100, 'tags': {'WMFSDKNeeded': '0.0.0.0000', 'DeviceConformanceTemplate': 'MP@HL', 'WMFSDKVersion': '11.0.5721.5265', 'IsVBR': '0'}}}\n\nProcess finished with exit code 0\n```\n\n```py\n@app.on_event(\"startup\")\nasync def startup_event():\n \"\"\"Code runs at startup...\"\"\"\n loop = asyncio.ProactorEventLoop()\n asyncio.set_event_loop(loop)\n```\n\n```text\nERROR: Exception in ASGI application\nTraceback (most recent call last):\n File \"E:\\pycharm\\my_project\\venv\\lib\\site-packages\\uvicorn\\protocols\\http\\httptools_impl.py\", line 375, in run_asgi\n result = await app(self.scope, self.receive, self.send)\n File \"E:\\pycharm\\my_project\\venv\\lib\\site-packages\\uvicorn\\middleware\\proxy_headers.py\", line 75, in __call__\n return await self.app(scope, receive, send)\n File \"E:\\pycharm\\my_project\\venv\\lib\\site-packages\\fastapi\\applications.py\", line 208, in __call__\n await super().__call__(scope, receive, send)\n File \"E:\\pycharm\\my_project\\venv\\lib\\site-packages\\starlette\\applications.py\", line 112, in __call__\n await self.middleware_stack(scope, receive, send)\n File \"E:\\pycharm\\my_project\\venv\\lib\\site-packages\\starlette\\middleware\\errors.py\", line 181, in __call__\n raise exc\n File \"E:\\pycharm\\my_project\\venv\\lib\\site-packages\\starlette\\middleware\\errors.py\", line 159, in __call__\n await self.app(scope, receive, _send)\n File \"E:\\pycharm\\my_project\\venv\\lib\\site-packages\\starlette\\middleware\\cors.py\", line 84, in __call__\n await self.app(scope, receive, send)\n File \"E:\\pycharm\\my_project\\venv\\lib\\site-packages\\starlette\\exceptions.py\", line 82, in __call__\n raise exc\n File \"E:\\pycharm\\my_project\\venv\\lib\\site-packages\\starlette\\exceptions.py\", line 71, in __call__\n await self.app(scope, receive, sender)\n File \"E:\\pycharm\\my_project\\venv\\lib\\site-packages\\starlette\\routing.py\", line 656, in __call__\n await route.handle(scope, receive, send)\n File \"E:\\pycharm\\my_project\\venv\\lib\\site-packages\\starlette\\routing.py\", line 259, in handle\n await self.app(scope, receive, send)\n File \"E:\\pycharm\\my_project\\venv\\lib\\site-packages\\starlette\\routing.py\", line 61, in app\n response = await func(request)\n File \"E:\\pycharm\\my_project\\venv\\lib\\site-packages\\fastapi\\routing.py\", line 226, in app\n raw_response = await run_endpoint_function(\n File \"E:\\pycharm\\my_project\\venv\\lib\\site-packages\\fastapi\\routing.py\", line 159, in run_endpoint_function\n return await dependant.call(**values)\n File \"E:\\pycharm\\my_project\\src\\backend\\app\\api\\api.py\", line 202, in subprocess_test\n parsed_json = await(probe_video_file(Path(r\"G:\\ffmpeg testing\\ffmpeg\\ffprobe.exe\"),\n File \"E:\\pycharm\\my_project\\src\\backend\\app\\ffmpeg\\ffprobe.py\", line 26, in probe_video_file\n proc = await asyncio.create_subprocess_exec(\n File \"C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310\\lib\\asyncio\\subprocess.py\", line 218, in create_subprocess_exec\n transport, protocol = await loop.subprocess_exec(\n File \"C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310\\lib\\asyncio\\base_events.py\", line 1652, in subprocess_exec\n transport = await self._make_subprocess_transport(\n File \"C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python310\\lib\\asyncio\\base_events.py\", line 493, in _make_subprocess_transport\n raise NotImplementedError\nNotImplementedError\nINFO: 127.0.0.1:58576 - \"GET /test/subprocess HTTP/1.1\" 500 Internal Server Error\n```\n\n```text\nNotImplementedError\n```\n\n```text\nprobe_video_file\n```\n\n```text\nprobe_video_file\n```\n\n```text\nProactorEventLoop\n```\n\n```py\nimport asyncio\nfrom asyncio.windows_events import ProactorEventLoop\n\nfrom fastapi import FastAPI\nfrom uvicorn import Config, Server\n\napp = FastAPI()\n\n\nclass ProactorServer(Server):\n def run(self, sockets=None):\n loop = ProactorEventLoop()\n asyncio.set_event_loop(loop) # since this is the default in Python 3.10, explicit selection can also be omitted\n asyncio.run(self.serve(sockets=sockets))\n\n\nconfig = Config(app=app, host=\"0.0.0.0\", port=8000, reload=True)\nserver = ProactorServer(config=config)\nserver.run()\n```\n\n```text\nreload=True\n```\n\n```text\nProactorEventLoop\n```\n\n```text\nSelectorEventLoop\n```\n\n```text\nreload=True\n```\n\n```text\nuvicorn.Server\n```\n\n```text\nasyncio.create_subprocess_exec()\n```\n\n```text\nwatchfiles \"uvicorn mypackage.main:app\" mypackage\n```\n\n```text\n--reload\n```\n\n```text\nwatchfiles\n```\n\n```text\nmypackage.main.app\n```\n\n```text\nmypackage\n```\n\n```text\n--reload\n```\n\n========================================\n\nComments:\n- github.com/tiangolo/fastapi/issues/825#issuecomment-56982674‌​3\n- @gold_cy Could you elaborate on that? I'm not sure what to do with that? Where does it go? It should be in FastAPI configuration or Uvicron configuration? A bit more clarity will help.\n- @gold_cy I've added it before `uvicorn.run(\"api.api:app\", host=\"0.0.0.0\", port=8000, reload=True)` in the main file. However `loop` keyword argument expects a string literal and not a loop instance and it errors out if I give it an instance. It expects one of the following: `[\"none\",\"auto\",\"asyncio\",\"uvloop\"]`\n- that’s my point I don’t think you can use any other loop other than the ones provided\n- Which python version are you using? With python 3.10 (maybe it started with an earlier version), `ProactorEventLoop` is the default event loop for Windows. Otherwise it's possible to use a custom event loop with uvicorn, e.g. by subclassing `uvicorn.Server`. I did this before it became the default and can look up the details if you need to do it.\n- @thisisalsomypassword I'm on 3.10 Python version\n- @gold_cy So it's impossible to run an async subprocess on FastApi?\n- Did you check which event loop is really running? What output do you get for `print(asyncio.get_running_loop())` inside your fastapi route function `subprocess_test()`?\n- @thisisalsomypassword It says `` It says this even if I say ` loop = asyncio.ProactorEventLoop()` and `asyncio.set_event_loop(loop)` before printing.\n- Thank you so much! Subclassing `Server` definitely worked, but omitting `reload=True` from the original code did not. Are there any downsides to using the `ProactorEventLoop` and this is why unicorn don't use it?\n- Not that I know of. I'm using the same setup in a project and didn't have any issues yet. I saw you postet an issue on the uvicorn github. Maybe that's the place to ask why they are doing it that way.\n- Sadly enough I posted an issue on the FastApi Github, not the Uvicron one :(\n- Thanks man, stuck in this for a considerate time, I just removed --reload","metadata":{"transformedAt":"2026-08-18T18:32:29.162Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":23,"totalLines":589,"estimatedTokens":6082}}766{"id":"stack-67580885","source":"stackoverflow","questionId":67580885,"title":"FastAPI query parameter using Pydantic model","tags":["python","fastapi","pydantic"],"text":"Title: FastAPI query parameter using Pydantic model\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI have a Pydantic model as below\n\n```\nclass Student(BaseModel):\n name:str\n age:int\n```\n\nWith this setup, I wish to get the OpenAPI schema as following,\n\nSo, how can I use the Pydantic model to get the from query parameter in FastAPI?\n\n========================================\n\nCode:\n```text\nclass Student(BaseModel):\n name:str\n age:int\n```\n\n```text\nfrom fastapi import FastAPI, Depends\n\nfrom pydantic import BaseModel\n\napp = FastAPI()\n\n\nclass Student(BaseModel):\n name: str\n age: int\n\n\n@app.get(\"/\")\ndef read_root(student: Student = Depends()):\n return {\"name\": student.name, \"age\": student.age}\n```\n\n```text\nfrom fastapi import FastAPI, Depends\nfrom typing import Optional\nfrom pydantic import BaseModel\n\napp = FastAPI()\n\n\nclass Student(BaseModel):\n name: str\n age: Optional[int]\n\n\n@app.get(\"/\")\ndef read_root(student: Student = Depends()):\n return {\"name\": student.name, \"age\": student.age}\n```\n\n```text\nOptional\n```\n\n========================================\n\nComments:\n- I have a question what if i don't specify `student: Student = Depends()` and just use `def read_root(student: Student):`? Why do we need to use `Depends` here?\n- IIRC, you won't get the schema representation *\"in this case\"*. Checkout more about `Depends(...)`\n- how to add a description to the name and age field?\n- question asked here stackoverflow.com/questions/75998227/…","metadata":{"transformedAt":"2026-08-18T18:32:29.162Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":73,"estimatedTokens":375}}767{"id":"stack-68805492","source":"stackoverflow","questionId":68805492,"title":"Grouping an array of objects by key in python","tags":["python","fastapi"],"text":"Title: Grouping an array of objects by key in python\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nSuppose I have an array of objects.\n\n```\narr = [\n {'grade': 'A', 'name': 'James'},\n {'grade': 'B', 'name': 'Tom'},\n {'grade': 'A', 'name': 'Zelda'}\n ]\n```\n\nI want this result\n\n```\n{\n 'A': [\n {'grade': 'A', 'name': 'James'},\n {'grade': 'A', 'name': 'Zelda'}\n ],\n 'B': [ {'grade': 'B', 'name': 'Tom'} ]\n}\n```\n\n========================================\n\nTop Answer:\nUsing `dict.setdefault` we can do this:\n\n```\nimport json\ngradeList = [\n {\"grade\": 'A', \"name\": 'James'},\n {\"grade\": 'B', \"name\": 'Tom'},\n {\"grade\": 'A', \"name\": 'Zelda'}\n]\ngradeDict = {}\nfor d in gradeList:\n gradeDict.setdefault(d[\"grade\"], []).append(d)\n\nprint(json.dumps(gradeDict, indent=4))\n```\n\nOutput:\n\n```\n{\n \"A\": [\n {\n \"grade\": \"A\",\n \"name\": \"James\"\n },\n {\n \"grade\": \"A\",\n \"name\": \"Zelda\"\n }\n ],\n \"B\": [\n {\n \"grade\": \"B\",\n \"name\": \"Tom\"\n }\n ]\n}\n```\n\n========================================\n\nCode:\n```text\narr = [\n {'grade': 'A', 'name': 'James'},\n {'grade': 'B', 'name': 'Tom'},\n {'grade': 'A', 'name': 'Zelda'}\n ]\n```\n\n```text\n{\n 'A': [\n {'grade': 'A', 'name': 'James'},\n {'grade': 'A', 'name': 'Zelda'}\n ],\n 'B': [ {'grade': 'B', 'name': 'Tom'} ]\n}\n```\n\n```text\narr2 = {}\nfor d in arr:\n t = arr2.setdefault(d['grade'], [])\n t.append(d)\n```\n\n```text\n>>> arr2\n{'A': [{'grade': 'A', 'name': 'James'}, {'grade': 'A', 'name': 'Zelda'}],\n 'B': [{'grade': 'B', 'name': 'Tom'}]}\n```\n\n```text\nsetdefault\n```\n\n```text\nimport json\ngradeList = [\n {\"grade\": 'A', \"name\": 'James'},\n {\"grade\": 'B', \"name\": 'Tom'},\n {\"grade\": 'A', \"name\": 'Zelda'}\n]\ngradeDict = {}\nfor d in gradeList:\n gradeDict.setdefault(d[\"grade\"], []).append(d)\n\nprint(json.dumps(gradeDict, indent=4))\n```\n\n```text\n{\n \"A\": [\n {\n \"grade\": \"A\",\n \"name\": \"James\"\n },\n {\n \"grade\": \"A\",\n \"name\": \"Zelda\"\n }\n ],\n \"B\": [\n {\n \"grade\": \"B\",\n \"name\": \"Tom\"\n }\n ]\n}\n```\n\n```text\ndict.setdefault\n```\n\n```text\nimport pandas as pd\ndf = pd.Dataframe(arr) \nfor index, group in df.groupby('grade'):\n print(group)\n```\n\n```py\narr = [{'grade': 'A', 'name': 'James'}, {'grade': 'B', 'name': 'Tom'}, {'grade': 'A', 'name': 'Zelda'}]\n\ngrouped_grades = {}\n\nfor item in arr:\n if item['grade'] not in grouped_grades:\n grouped_grades[item['grade']] = []\n \n grouped_grades[item['grade']].append(item)\n\nprint(grouped_grades)\n```\n\n```text\n{'A': [{'grade': 'A', 'name': 'James'}, {'grade': 'A', 'name': 'Zelda'}], 'B': [{'grade': 'B', 'name': 'Tom'}]}\n```\n\n```py\nfrom collections import defaultdict\noutput = defaultdict(lambda: [])\n\nfor item in arr:\n output[item['grade']].append(item)\n```\n\n```text\ndict(output)\n```\n\n```text\n>>> keyfunc = lambda item: item['grade']\n>>> {k:list(v) for k,v in itertools.groupby( sorted(arr,key=keyfunc) , keyfunc) }\n{'A': [{'grade': 'A', 'name': 'James'}, {'grade': 'A', 'name': 'Zelda'}], 'B': [{'grade': 'B', 'name': 'Tom'}]}\n```\n\n========================================\n\nComments:\n- Your dict is not valid. missing `' '` in keys.\n- In python your array is a list and your objects are dictionaries, and you need quotes around grade and name as well\n- @Corralien corrected.\n- the 2nd line has an extra ) at the end. Other than that, this is exactly the kind of problem that itertools.groupby solve","metadata":{"transformedAt":"2026-08-18T18:32:29.163Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":14,"totalLines":196,"estimatedTokens":866}}768{"id":"stack-71595635","source":"stackoverflow","questionId":71595635,"title":"Render NumPy array in FastAPI","tags":["python","numpy","image","fastapi","bytesio"],"text":"Title: Render NumPy array in FastAPI\nTags: python, numpy, image, fastapi, bytesio\nSource: Stack Overflow\n\nQuestion:\nI have found How to return a numpy array as an image using FastAPI?. However, I am still struggling to show the image on client side, which just appears as a white square.\n\nI read an array into `io.BytesIO` like so:\n\n```\ndef iterarray(array):\n output = io.BytesIO()\n np.savez(output, array)\n yield output.get_value()\n```\n\nIn my endpoint, I return `StreamingResponse(iterarray(), media_type='application/octet-stream')`.\n\nWhen I leave the `media_type` blank to be inferred a zipfile is downloaded.\n\nHow do I get the array to be displayed as an image?\n\n========================================\n\nCode:\n```text\ndef iterarray(array):\n output = io.BytesIO()\n np.savez(output, array)\n yield output.get_value()\n```\n\n```text\nio.BytesIO\n```\n\n```text\nStreamingResponse(iterarray(), media_type='application/octet-stream')\n```\n\n```text\nmedia_type\n```\n\n```py\n# Function to create a sample RGB image\ndef create_img():\n w, h = 512, 512\n arr = np.zeros((h, w, 3), dtype=np.uint8)\n arr[0:256, 0:256] = [255, 0, 0] # red patch in upper left\n return arr\n```\n\n```py\nfrom fastapi import Response\nfrom PIL import Image\nimport numpy as np\nimport io\n\n@app.get('/image', response_class=Response)\ndef get_image():\n # loading image from disk\n # im = Image.open('test.png')\n \n # using an in-memory image\n arr = create_img()\n im = Image.fromarray(arr)\n \n # save image to an in-memory bytes buffer\n with io.BytesIO() as buf:\n im.save(buf, format='PNG')\n im_bytes = buf.getvalue()\n \n headers = {'Content-Disposition': 'inline; filename=\"test.png\"'}\n return Response(im_bytes, headers=headers, media_type='image/png')\n```\n\n```py\nimport requests\nfrom PIL import Image\n\nurl = 'http://127.0.0.1:8000/image'\nr = requests.get(url=url)\n\n# write raw bytes to file\nwith open('test.png', 'wb') as f:\n f.write(r.content)\n\n# or, convert back to PIL Image\n# im = Image.open(io.BytesIO(r.content))\n# im.save('test.png')\n```\n\n```py\nimport cv2\n\n@app.get('/image', response_class=Response)\ndef get_image():\n # loading image from disk\n # arr = cv2.imread('test.png', cv2.IMREAD_UNCHANGED)\n \n # using an in-memory image\n arr = create_img()\n arr = cv2.cvtColor(arr, cv2.COLOR_RGB2BGR)\n # arr = cv2.cvtColor(arr, cv2.COLOR_RGBA2BGRA) # if dealing with 4-channel RGBA (transparent) image\n\n success, im = cv2.imencode('.png', arr)\n headers = {'Content-Disposition': 'inline; filename=\"test.png\"'}\n return Response(im.tobytes(), headers=headers, media_type='image/png')\n```\n\n```py\nurl = 'http://127.0.0.1:8000/image'\nr = requests.get(url=url) \n\n# write raw bytes to file\nwith open('test.png', 'wb') as f:\n f.write(r.content)\n\n# or, convert back to image format \n# arr = np.frombuffer(r.content, np.uint8)\n# img_np = cv2.imdecode(arr, cv2.IMREAD_UNCHANGED)\n# cv2.imwrite('test.png', img_np)\n```\n\n```none\nheaders = {'Content-Disposition': 'inline; filename=\"test.png\"'}\n```\n\n```none\nheaders = {'Content-Disposition': 'attachment; filename=\"test.png\"'}\n```\n\n```py\n@app.get('/image')\ndef get_image():\n def iterfile(): \n with open('test.png', mode='rb') as f: \n yield from f \n \n return StreamingResponse(iterfile(), media_type='image/png')\n```\n\n```py\nfrom fastapi import BackgroundTasks\n\n@app.get('/image')\ndef get_image(background_tasks: BackgroundTasks):\n # supposedly, the buffer already existed in memory\n arr = create_img()\n im = Image.fromarray(arr)\n buf = BytesIO()\n im.save(buf, format='PNG')\n\n # rewind the cursor to the start of the buffer\n buf.seek(0)\n # discard the buffer, after the response is returned\n background_tasks.add_task(buf.close)\n return StreamingResponse(buf, media_type='image/png')\n```\n\n```py\nfrom PIL import Image\nimport numpy as np\nimport json\n\n@app.get('/image')\ndef get_image():\n im = Image.open('test.png')\n # im = Image.open('test.png').convert('RGBA') # if dealing with 4-channel RGBA (transparent) image \n arr = np.asarray(im)\n return json.dumps(arr.tolist())\n```\n\n```py\nimport requests\nfrom PIL import Image\nimport numpy as np\nimport json\n\nurl = 'http://127.0.0.1:8000/image'\nr = requests.get(url=url) \narr = np.asarray(json.loads(r.json())).astype(np.uint8)\nim = Image.fromarray(arr)\nim.save('test_received.png')\n```\n\n```py\nimport cv2\nimport json\n\n@app.get('/image')\ndef get_image():\n arr = cv2.imread('test.png', cv2.IMREAD_UNCHANGED)\n return json.dumps(arr.tolist())\n```\n\n```py\nimport requests\nimport numpy as np\nimport cv2\nimport json\n\nurl = 'http://127.0.0.1:8000/image'\nr = requests.get(url=url) \narr = np.asarray(json.loads(r.json())).astype(np.uint8)\ncv2.imwrite('test_received.png', arr)\n```\n\n```text\nPIL\n```\n\n```text\nOpenCV\n```\n\n```text\nResponse\n```\n\n```text\nImage.open\n```\n\n```text\nImage.fromarray\n```\n\n```text\nstartup\n```\n\n```text\napp\n```\n\n```text\nBytesIO\n```\n\n```text\ngetvalue()\n```\n\n```text\nclose()\n```\n\n```text\nwith\n```\n\n```text\nImage\n```\n\n```text\ncv2.imread()\n```\n\n```text\nRGB\n```\n\n```text\nBGR\n```\n\n```text\ncv2.imencode()\n```\n\n```text\n.png\n```\n\n```text\n.jpg\n```\n\n```text\nnumpy.frombuffer()\n```\n\n```text\ncv2.imdecode()\n```\n\n```text\ncv2.imdecode()\n```\n\n```text\nFileResponse\n```\n\n```text\nResponse\n```\n\n```text\nStreamingResponse\n```\n\n```text\nHTTP\n```\n\n```text\nContent-Disposition\n```\n\n```text\nfilename\n```\n\n```text\nfilename\n```\n\n```text\nattachment\n```\n\n```text\ninline\n```\n\n```text\nStreamingResponse\n```\n\n```text\nStreamingResponse\n```\n\n```text\nStreamingResponse\n```\n\n```text\niter()\n```\n\n```text\nStreamingResponse\n```\n\n```text\nAsyncIterable\n```\n\n```text\niterate_in_threadpool()\n```\n\n```text\nContent-Length\n```\n\n```text\nStreamingResponse\n```\n\n```text\nStreamingResponse\n```\n\n```text\nResponse\n```\n\n```text\nContent-Length\n```\n\n```text\nStreamingResponse\n```\n\n```text\nResponse\n```\n\n```text\ntransfer-encoding: chunked\n```\n\n```text\nTransfer-Encoding: chunked\n```\n\n```text\nStreamingResponse\n```\n\n```text\nFileResponse\n```\n\n```text\nContent-Length\n```\n\n```text\nStreamingResponse(iterfile(), headers={'Content-Length': str(content_length)})\n```\n\n```text\ntransfer-encoding: chunked\n```\n\n```text\nopen()\n```\n\n```text\nStreamingResponse\n```\n\n```text\nyield from f\n```\n\n```text\nStreamingResponse\n```\n\n```text\nFileResponse\n```\n\n```text\nFileResponse\n```\n\n```text\nResponse\n```\n\n```text\nBytesIO\n```\n\n```text\nBytesIO\n```\n\n```text\nStreamingResponse\n```\n\n```text\nbuf.getvalue()\n```\n\n```text\nResponse\n```\n\n```text\nbuf.seek(0)\n```\n\n```text\nclose()\n```\n\n```text\nResponse\n```\n\n```text\ncontent\n```\n\n```text\nmedia_type\n```\n\n```text\nContent-Disposition\n```\n\n```text\nasarray()\n```\n\n```text\njson\n```\n\n========================================\n\nComments:\n- How are you reading the file after you download it?\n- @richardec I'm generating the array by finding the mean of a set of arrays (which come from grib files) so I'm not really downloading a file? Could you please clarify if I've misunderstood\n- Oh, I'm sorry. You have a `fastapi` server, right? and you're returning an array from it, so how are you getting that array on the other end?\n- oh i see, they are local files on my computer and I have just hardcoded paths to them within my code. They get read using the GDAL library to extract the array\n- So, if you're getting a white image, the arrays must be being loaded incorrectly. Can you peek in and see what the array is after loading it?\n- A large proportion of the array is 0 (image border) and the image itself is quite small compared to this so I guess i need to \"crop\" the array to remove the 0s from the outside\n- `application/octet-stream` isn't a valid image type - i.e. the response shouldn't be parsed or processed as an image. `npz` files which `savez` generates aren't valid image files that regular browsers can parse. You can usually use Pillow/PIL to convert a set of binary data to a valid image format.\n- thank you @MatsLindh , your suggestion fixed my problem. Happy to accept as correct if you wish to submit as an answer\n- @Chris Thanks for your very comprehensive answer!","metadata":{"transformedAt":"2026-08-18T18:32:29.163Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":88,"totalLines":505,"estimatedTokens":2018}}769{"id":"stack-64013678","source":"stackoverflow","questionId":64013678,"title":"Mapping issues from Sqlalchemy to Pydantic - from_orm failed","tags":["python","sqlalchemy","fastapi","pydantic"],"text":"Title: Mapping issues from Sqlalchemy to Pydantic - from_orm failed\nTags: python, sqlalchemy, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI'm trying to get my result dictonary from sqlalchemy automatically to the Pydantic output for Fastapi to maps using the from_orm method, but I always get a validation error.\n\nFile \"pydantic\\main.py\", line 508, in pydantic.main.BaseModel.from_orm\npydantic.error_wrappers.ValidationError: 2 validation errors for Category\nname\nfield required (type=value_error.missing)\nid\nfield required (type=value_error.missing)\n\nIf I create the objects with the Pydantic schema myself and add them to the list, the method works.\nWhat would I have to change for from_orm to work?\nDid I possibly miss something in the documentation?\nhttps://pydantic-docs.helpmanual.io/usage/models/#orm-mode-aka-arbitrary-class-instances\nhttps://fastapi.tiangolo.com/tutorial/sql-databases/#use-pydantics-orm_mode\n\nor is there another/better way to turn the ResultProxy into a Pydantic capable output?\n\nThe output I get from the database method is the following:\n\n```\n[{'id': 1, 'name': 'games', 'parentid': None}, {'id': 2, 'name': 'computer', 'parentid': None}, {'id': 3, 'name': 'household', 'parentid': None}, {'id': 10, 'name': 'test', 'parentid': None}]]\n```\n\n### Models.py\n\n```\nfrom sqlalchemy import BigInteger, Column, DateTime, ForeignKey, Integer, Numeric, String, Text, text, Table\nfrom sqlalchemy.orm import relationship, mapper\nfrom sqlalchemy.ext.declarative import declarative_base\n\nBase = declarative_base()\nmetadata = Base.metadata\n\ncategory = Table('category', metadata,\n Column('id', Integer, primary_key=True),\n Column('name', String(200)),\n Column('parentid', Integer),\n )\n\nclass Category(object):\n def __init__(self, cat_id, name, parentid):\n self.id = cat_id\n self.name = name\n self.parentid = parentid\n\nmapper(Category, category)\n```\n\n### Schemas.py\n\n```\nfrom pydantic import BaseModel, Field\n\nclass Category(BaseModel):\n name: str\n parentid: int = None\n id: int\n class Config:\n orm_mode = True\n```\n\n### main.py\n\n```\ndef result_proxy_to_Dict(results: ResultProxy):\n d, a = {}, []\n for rowproxy in results:\n # rowproxy.items() returns an array like [(key0, value0), (key1, value1)]\n for column, value in rowproxy.items():\n # build up the dictionary\n d = {**d, **{column: value}}\n a.append(d)\n return a\n\ndef crud_read_cat(db: Session) -> dict:\n # records = db.query(models.Category).all()\n #query = db.query(models.Category).filter(models.Category.parentid == None)\n s = select([models.Category]). \\\n where(models.Category.parentid == None)\n\n result = db.execute(s)\n #print(type(result))\n\n #print(result_proxy_to_Dict(result))\n #results = db.execute(query)\n # result_set = db.execute(\"SELECT id, name, parentid FROM public.category;\")\n\n # rint(type(result_set))\n # for r in result_set:\n # print(r)\n # return [{column: value for column, value in rowproxy.items()} for rowproxy in result_set]\n # return await databasehelper.database.fetch_all(query)\n return result_proxy_to_Dict(result)\n #return results\n\n@router.get(\"/category/\", response_model=List[schemas.Category], tags=[\"category\"])\nasync def read_all_category(db: Session = Depends(get_db)):\n categories = crud_read_cat(db)\n context = []\n print(categories)\n co_model = schemas.Category.from_orm(categories)\n # print(co_model)\n for row in categories:\n print(row)\n print(row.get(\"id\", None))\n print(row.get(\"name\", None))\n print(row.get(\"parentid\", None))\n tempcat = schemas.Category(id=row.get(\"id\", None), name=row.get(\"name\", None),\n parentid=row.get(\"parentid\", None))\n context.append(tempcat)\n #for dic in [dict(r) for r in categories]:\n # print(dic)\n # print(dic.get(\"category_id\", None))\n # print(dic.get(\"category_name\", None))\n # print(dic.get(\"category_parentid\", None))\n # tempcat = schemas.Category(id=dic.get(\"category_id\", None), name=dic.get(\"category_name\", None),\n # parentid=dic.get(\"category_parentid\", None))\n # context.append(tempcat)\n\n return context\n```\n\n========================================\n\nTop Answer:\nI just had the same problem. I think its related to pydantic nonethless. Please have a look at this link for more information https://github.com/samuelcolvin/pydantic/issues/506.\n\nBut having changed my model:\n\n```\nclass Student(BaseModel):\n id: Optional[int] --- changed to optional\n name: Optional [str]\n surname: Optional [str]\n email: Optional [str]\n```\n\nThe error validation goes away. Its a funny error - given that the entries in my database still updated with the values...I am new to fastAPI also so the workaround and the error does not really make sense for now....but yes it worked. Thank you\n\n========================================\n\nCode:\n```py\n[{'id': 1, 'name': 'games', 'parentid': None}, {'id': 2, 'name': 'computer', 'parentid': None}, {'id': 3, 'name': 'household', 'parentid': None}, {'id': 10, 'name': 'test', 'parentid': None}]]\n```\n\n```py\nfrom sqlalchemy import BigInteger, Column, DateTime, ForeignKey, Integer, Numeric, String, Text, text, Table\nfrom sqlalchemy.orm import relationship, mapper\nfrom sqlalchemy.ext.declarative import declarative_base\n\nBase = declarative_base()\nmetadata = Base.metadata\n\ncategory = Table('category', metadata,\n Column('id', Integer, primary_key=True),\n Column('name', String(200)),\n Column('parentid', Integer),\n )\n\n\nclass Category(object):\n def __init__(self, cat_id, name, parentid):\n self.id = cat_id\n self.name = name\n self.parentid = parentid\n\n\nmapper(Category, category)\n```\n\n```py\nfrom pydantic import BaseModel, Field\n\nclass Category(BaseModel):\n name: str\n parentid: int = None\n id: int\n class Config:\n orm_mode = True\n```\n\n```py\ndef result_proxy_to_Dict(results: ResultProxy):\n d, a = {}, []\n for rowproxy in results:\n # rowproxy.items() returns an array like [(key0, value0), (key1, value1)]\n for column, value in rowproxy.items():\n # build up the dictionary\n d = {**d, **{column: value}}\n a.append(d)\n return a\n\ndef crud_read_cat(db: Session) -> dict:\n # records = db.query(models.Category).all()\n #query = db.query(models.Category).filter(models.Category.parentid == None)\n s = select([models.Category]). \\\n where(models.Category.parentid == None)\n\n result = db.execute(s)\n #print(type(result))\n\n #print(result_proxy_to_Dict(result))\n #results = db.execute(query)\n # result_set = db.execute(\"SELECT id, name, parentid FROM public.category;\")\n\n # rint(type(result_set))\n # for r in result_set:\n # print(r)\n # return [{column: value for column, value in rowproxy.items()} for rowproxy in result_set]\n # return await databasehelper.database.fetch_all(query)\n return result_proxy_to_Dict(result)\n #return results\n\n\n@router.get(\"/category/\", response_model=List[schemas.Category], tags=[\"category\"])\nasync def read_all_category(db: Session = Depends(get_db)):\n categories = crud_read_cat(db)\n context = []\n print(categories)\n co_model = schemas.Category.from_orm(categories)\n # print(co_model)\n for row in categories:\n print(row)\n print(row.get(\"id\", None))\n print(row.get(\"name\", None))\n print(row.get(\"parentid\", None))\n tempcat = schemas.Category(id=row.get(\"id\", None), name=row.get(\"name\", None),\n parentid=row.get(\"parentid\", None))\n context.append(tempcat)\n #for dic in [dict(r) for r in categories]:\n # print(dic)\n # print(dic.get(\"category_id\", None))\n # print(dic.get(\"category_name\", None))\n # print(dic.get(\"category_parentid\", None))\n # tempcat = schemas.Category(id=dic.get(\"category_id\", None), name=dic.get(\"category_name\", None),\n # parentid=dic.get(\"category_parentid\", None))\n # context.append(tempcat)\n\n return context\n```\n\n```text\nclass Category(BaseModel):\n name: Optional[str]\n parentid: int = None\n id: Optional[int]\n\n class Config:\n orm_mode = True\n`\n```\n\n```text\n[\n {\n \"name\": \"games\",\n \"parentid\": null,\n \"id\": 1\n },\n {\n \"name\": \"computer\",\n \"parentid\": null,\n \"id\": 2\n },\n {\n \"name\": \"household\",\n \"parentid\": null,\n \"id\": 3\n },\n {\n \"name\": \"test\",\n \"parentid\": null,\n \"id\": 10\n }\n]\n```\n\n```text\nclass Student(BaseModel):\n id: Optional[int] --- changed to optional\n name: Optional [str]\n surname: Optional [str]\n email: Optional [str]\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.163Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":7,"totalLines":290,"estimatedTokens":2134}}770{"id":"stack-75590142","source":"stackoverflow","questionId":75590142,"title":"Decorators to configure Sentry error and trace rates?","tags":["python","fastapi","sentry"],"text":"Title: Decorators to configure Sentry error and trace rates?\nTags: python, fastapi, sentry\nSource: Stack Overflow\n\nQuestion:\nI am using Sentry and sentry_sdk to monitor errors and traces in my Python application. I want to configure the error and trace rates for different routes in my FastAPI API. To do this, I want to write two decorators called `sentry_error_rate` and `sentry_trace_rate` that will allow me to set the sample rates for errors and traces, respectively.\n\nThe `sentry_error_rate` decorator should take a single argument `errors_sample_rate` (a float between 0 and 1) and apply it to a specific route.\nThe `sentry_trace_rate` decorator should take a single argument `traces_sample_rate` (also a float between 0 and 1) and apply it to a specific route.\n\n```\ndef sentry_trace_rate(traces_sample_rate: float = 0.0) -> callable:\n \"\"\" Decorator to set the traces_sample_rate for a specific route.\n This is useful for routes that are called very frequently, but we\n want to sample them to reduce the amount of data we send to Sentry.\n\n Args:\n traces_sample_rate (float): The sample rate to use for this route.\n \"\"\"\n def decorator(func):\n @wraps(func)\n async def wrapper(*args, **kwargs):\n # Do something here ?\n return await func(*args, **kwargs)\n return wrapper\n return decorator\n\ndef sentry_error_rate(errors_sample_rate: float = 0.0) -> callable:\n \"\"\" Decorator to set the errors_sample_rate for a specific route.\n This is useful for routes that are called very frequently, but we\n want to sample them to reduce the amount of data we send to Sentry.\n\n Args:\n errors_sample_rate (float): The sample rate to use for this route.\n \"\"\"\n def decorator(func):\n @wraps(func)\n async def wrapper(*args, **kwargs):\n # Do something here ?\n return await func(*args, **kwargs)\n return wrapper\n return decorator\n```\n\nDoes someone have an idea if this is possible and how it could be done ?\n\n========================================\n\nCode:\n```py\ndef sentry_trace_rate(traces_sample_rate: float = 0.0) -> callable:\n \"\"\" Decorator to set the traces_sample_rate for a specific route.\n This is useful for routes that are called very frequently, but we\n want to sample them to reduce the amount of data we send to Sentry.\n\n Args:\n traces_sample_rate (float): The sample rate to use for this route.\n \"\"\"\n def decorator(func):\n @wraps(func)\n async def wrapper(*args, **kwargs):\n # Do something here ?\n return await func(*args, **kwargs)\n return wrapper\n return decorator\n\n\ndef sentry_error_rate(errors_sample_rate: float = 0.0) -> callable:\n \"\"\" Decorator to set the errors_sample_rate for a specific route.\n This is useful for routes that are called very frequently, but we\n want to sample them to reduce the amount of data we send to Sentry.\n\n Args:\n errors_sample_rate (float): The sample rate to use for this route.\n \"\"\"\n def decorator(func):\n @wraps(func)\n async def wrapper(*args, **kwargs):\n # Do something here ?\n return await func(*args, **kwargs)\n return wrapper\n return decorator\n```\n\n```text\nsentry_error_rate\n```\n\n```text\nsentry_trace_rate\n```\n\n```text\nsentry_error_rate\n```\n\n```text\nerrors_sample_rate\n```\n\n```text\nsentry_trace_rate\n```\n\n```text\ntraces_sample_rate\n```\n\n```py\nimport asyncio\nimport random\nfrom functools import wraps\nfrom typing import Callable, Union\n\nfrom fastapi import APIRouter\n\n\n_route_traces_entrypoints = {}\n_route_errors_entrypoints = {}\n_fn_traces_entrypoints = {}\n_fn_errors_entrypoints = {}\n_fn_to_route_entrypoints = {}\n\n\ndef sentry_trace_rate(trace_sample_rate: float = 0.0) -> Callable:\n \"\"\"Decorator to set the sentry trace rate for a specific endpoint.\n This is useful for endpoints that are called very frequently,\n and we don't want to report all traces.\n Args:\n trace_sample_rate (float): The rate to sample traces. 0.0 to disable traces.\n \"\"\"\n\n def decorator(fn: Callable) -> Callable:\n # Assert there is not twice function with the same nam\n if fn.__name__ in _fn_traces_entrypoints:\n raise ValueError(f\"Two function have the same name: {fn.__name__} | {fn.__file__}\")\n\n # Add fn entrypoint\n _fn_traces_entrypoints[fn.__name__] = trace_sample_rate\n\n # Check for coroutines and return the right wrapper\n if asyncio.iscoroutinefunction(fn):\n\n @wraps(fn)\n async def wrapper(*args, **kwargs) -> Callable:\n return await fn(*args, **kwargs)\n\n return wrapper\n else:\n\n @wraps(fn)\n def wrapper(*args, **kwargs) -> Callable:\n return fn(*args, **kwargs)\n\n return wrapper\n\n return decorator\n\n\ndef sentry_error_rate(error_sample_rate: float = 0.0) -> Callable:\n \"\"\"Decorator to set the sentry error rate for a specific endpoint.\n This is useful for endpoints that are called very frequently,\n and we don't want to report all errors.\n Args:\n error_sample_rate (float): The rate to sample errors. 0.0 to disable errors.\n \"\"\"\n\n def decorator(fn: Callable) -> Callable:\n # Assert there is not twice function with the same nam\n if fn.__name__ in _fn_errors_entrypoints:\n raise ValueError(f\"Two function have the same name: {fn.__name__} | {fn.__file__}\")\n\n # Add fn entrypoint\n _fn_errors_entrypoints[fn.__name__] = error_sample_rate\n\n # Check for coroutines and return the right wrapper\n if asyncio.iscoroutinefunction(fn):\n\n @wraps(fn)\n async def wrapper(*args, **kwargs) -> Callable:\n return await fn(*args, **kwargs)\n\n return wrapper\n else:\n\n @wraps(fn)\n def wrapper(*args, **kwargs) -> Callable:\n return fn(*args, **kwargs)\n\n return wrapper\n\n return decorator\n\n\ndef register_traces_disabler(router: APIRouter) -> None:\n \"\"\"Register all the entrypoints for the traces disabler\n Args:\n router (APIRouter): The router to register\n \"\"\"\n for route in router.routes:\n if route.name in _fn_traces_entrypoints:\n _route_traces_entrypoints[route.path] = _fn_traces_entrypoints[route.name]\n\n\ndef register_errors_disabler(router: APIRouter) -> None:\n \"\"\"Register all the entrypoints for the errors disabler\n Args:\n router (APIRouter): The router to register\n \"\"\"\n for route in router.routes:\n if route.name in _fn_errors_entrypoints:\n _route_errors_entrypoints[route.path] = _fn_errors_entrypoints[route.name]\n\n\nclass TracesSampler:\n \"\"\"Class to sample traces for sentry\n Args:\n default_traces_sample_rate (float, optional): The default sample rate for traces.\n Defaults to 1.0.\n \"\"\"\n\n def __init__(self, default_traces_sample_rate: float = 1.0) -> None:\n self.default_traces_sample_rate = default_traces_sample_rate\n\n def __call__(self, sampling_context) -> float:\n return _route_traces_entrypoints.get(sampling_context[\"asgi_scope\"][\"path\"], self.default_traces_sample_rate)\n\n\nclass BeforeSend:\n \"\"\"Class to sample event before sending them to sentry\n Args:\n default_errors_sample_rate (float, optional): The default sample rate for errors.\n Defaults to 1.0.\n \"\"\"\n\n def __init__(self, default_errors_sample_rate: float = 1.0) -> None:\n self.default_errors_sample_rate = default_errors_sample_rate\n\n def __call__(self, event: dict, hint: dict) -> Union[dict, None]:\n # Get the sample rate for this route, or use the default if it's not defined\n sample_rate = _route_errors_entrypoints.get(event[\"transaction\"], self.default_errors_sample_rate)\n\n # Generate a random number between 0 and 1, and discard the event if it's greater than the sample rate\n if random.random() > sample_rate:\n return None\n\n # Return the event if it should be captured\n return event\n```\n\n```py\n@router.get(\"/route\")\n@sentry_wrapper.sentry_trace_rate(trace_sample_rate=0.5) # limit traces to 50%\n@sentry_wrapper.sentry_error_rate(error_sample_rate=0.25) # limit error to 25%\ndef route_fn():\n pass\n```\n\n```py\nfrom app.services.sentry_wrapper import register_errors_disabler, register_traces_disabler\n\nregister_traces_disabler(router)\nregister_errors_disabler(router)\n```\n\n========================================\n\nComments:\n- If you're using `sentry_sdk` (which would be my assumption), it seems like the sampling can be controlled by a sampling function. Then you could probably set some context in your decorator, and use that to determine the sampling rate.\n- Yes indeed I use sentry_sdk, I'll take a look a the sampling function","metadata":{"transformedAt":"2026-08-18T18:32:29.164Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":10,"totalLines":270,"estimatedTokens":2188}}771{"id":"stack-75321439","source":"stackoverflow","questionId":75321439,"title":"Fastapi many to many relation with extra relationships","tags":["sqlalchemy","fastapi","pydantic"],"text":"Title: Fastapi many to many relation with extra relationships\nTags: sqlalchemy, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI am developing above database with many to many relationship and a additionally I need add in intermediate table a relationship many to one but I can't get this las relationship with others.\nWhat's a proper way to define many-to-many relationships in a pydantic model with extra data as relationship.\n\nmodels.py:\n\n```\nclass Devices(Base):\n __tablename__ = \"devices\"\n id = Column(Integer, primary_key=True, unique=True, index=True)\n name = Column(String(255))\n description = Column(String(255), nullable=True)\n status_id = Column(Integer, ForeignKey('status.id'))\n status = relationship(\"Status\", backref=\"devices\")\n protocols = relationship(\"Protocols\", secondary=\"device_protocols\", back_populates='device')\n\nclass Status(Base):\n __tablename__ = \"status\"\n id = Column(Integer, primary_key=True, unique=True, index=True)\n name = Column(String(255))\n description = Column(String(255), nullable=True)\n\nclass Protocols(Base):\n __tablename__ = \"protocols\"\n id = Column(Integer, primary_key=True, unique=True, index=True)\n name = Column(String(255))\n device = relationship(\"Devices\", secondary=\"device_protocols\", back_populates='protocols')\n\nclass DeviceProtocols(Base):\n __tablename__ = \"device_protocols\"\n device_id = Column(Integer, ForeignKey('devices.id'), primary_key=True)\n protocol_id = Column(Integer, ForeignKey('protocols.id'), primary_key=True)\n protocol_status_id = Column(Integer, ForeignKey('status.id'), nullable=True)\n protocol_status = relationship(\"Status\", backref=\"protocol_status\")\n```\n\nhttps://i.sstatic.net/2vuAS.png\n\nSchemas:\n\n```\nclass DeviceBase (BaseModel):\n name: str\n class Config:\n orm_mode = True\n\nclass DeviceRead (DeviceBase):\n id: str\n description: str | None = None\n status: StatusReadSimple | None = None\n protocols: list[ProtocolSimple]\n\nclass ProtocolBase (BaseModel):\n name: str\n class Config:\n orm_mode = True\n\nclass ProtocolSimple(ProtocolBase):\n id: str\n\nclass StatusBase (BaseModel):\n name: str\n description: str | None = None\n\n class Config:\n orm_mode = True\n\nclass StatusReadSimple(StatusBase):\n id: str\n```\n\nHow do I need to develop the schemas so that the device returns the intermediate table with the protocol and its status?\n\nActual response:\n\n```\n{\n \"name\": \"device1\",\n \"id\": \"3\",\n \"description\": \"my device\",\n \"status\": {\n \"name\": \"OK\",\n \"description\": \"Connection OK\",\n \"id\": \"1\"\n },\n \"protocols\": [\n {\n \"name\": \"ethernet\",\n \"id\": \"1\"\n },\n {\n \"name\": \"ethercat\",\n \"id\": \"2\"\n }\n ]\n}\n```\n\nExpected response or similar:\n\n```\n{\n \"name\": \"device1\",\n \"id\": \"3\",\n \"description\": \"my device\",\n \"status\": {\n \"name\": \"OK\",\n \"description\": \"Connection OK\",\n \"id\": \"1\"\n },\n \"protocols\": [\n {\n \"protocol:\"{\n \"name\": \"ethernet\",\n \"id\": \"1\"\n },\n \"protocol_status\":{\n \"id\":1,\n \"name\": \"OK\"\n }\n },\n {\n \"protocol:\"{\n \"name\": \"ethercat\",\n \"id\": \"2\"\n },\n \"protocol_status\":{\n \"id\":2,\n \"name\": \"NOK\"\n }\n }\n\n ]\n}\n```\n\n========================================\n\nCode:\n```text\nclass Devices(Base):\n __tablename__ = \"devices\"\n id = Column(Integer, primary_key=True, unique=True, index=True)\n name = Column(String(255))\n description = Column(String(255), nullable=True)\n status_id = Column(Integer, ForeignKey('status.id'))\n status = relationship(\"Status\", backref=\"devices\")\n protocols = relationship(\"Protocols\", secondary=\"device_protocols\", back_populates='device')\n\nclass Status(Base):\n __tablename__ = \"status\"\n id = Column(Integer, primary_key=True, unique=True, index=True)\n name = Column(String(255))\n description = Column(String(255), nullable=True)\n\nclass Protocols(Base):\n __tablename__ = \"protocols\"\n id = Column(Integer, primary_key=True, unique=True, index=True)\n name = Column(String(255))\n device = relationship(\"Devices\", secondary=\"device_protocols\", back_populates='protocols')\n\nclass DeviceProtocols(Base):\n __tablename__ = \"device_protocols\"\n device_id = Column(Integer, ForeignKey('devices.id'), primary_key=True)\n protocol_id = Column(Integer, ForeignKey('protocols.id'), primary_key=True)\n protocol_status_id = Column(Integer, ForeignKey('status.id'), nullable=True)\n protocol_status = relationship(\"Status\", backref=\"protocol_status\")\n```\n\n```text\nclass DeviceBase (BaseModel):\n name: str\n class Config:\n orm_mode = True\n\nclass DeviceRead (DeviceBase):\n id: str\n description: str | None = None\n status: StatusReadSimple | None = None\n protocols: list[ProtocolSimple]\n\nclass ProtocolBase (BaseModel):\n name: str\n class Config:\n orm_mode = True\n\nclass ProtocolSimple(ProtocolBase):\n id: str\n\nclass StatusBase (BaseModel):\n name: str\n description: str | None = None\n\n class Config:\n orm_mode = True\n\nclass StatusReadSimple(StatusBase):\n id: str\n```\n\n```text\n{\n \"name\": \"device1\",\n \"id\": \"3\",\n \"description\": \"my device\",\n \"status\": {\n \"name\": \"OK\",\n \"description\": \"Connection OK\",\n \"id\": \"1\"\n },\n \"protocols\": [\n {\n \"name\": \"ethernet\",\n \"id\": \"1\"\n },\n {\n \"name\": \"ethercat\",\n \"id\": \"2\"\n }\n ]\n}\n```\n\n```text\n{\n \"name\": \"device1\",\n \"id\": \"3\",\n \"description\": \"my device\",\n \"status\": {\n \"name\": \"OK\",\n \"description\": \"Connection OK\",\n \"id\": \"1\"\n },\n \"protocols\": [\n {\n \"protocol:\"{\n \"name\": \"ethernet\",\n \"id\": \"1\"\n },\n \"protocol_status\":{\n \"id\":1,\n \"name\": \"OK\"\n }\n },\n {\n \"protocol:\"{\n \"name\": \"ethercat\",\n \"id\": \"2\"\n },\n \"protocol_status\":{\n \"id\":2,\n \"name\": \"NOK\"\n }\n }\n\n ]\n}\n```\n\n```py\nfrom sqlalchemy import Column, ForeignKey, Integer, String\nfrom sqlalchemy.ext.associationproxy import association_proxy\nfrom sqlalchemy.orm import declarative_base, relationship\n\n\nBase = declarative_base()\n\n\nclass DeviceProtocolAssociation(Base):\n __tablename__ = \"device_protocol\"\n device_id = Column(Integer, ForeignKey(\"device.id\"), primary_key=True)\n device = relationship(\"Device\", back_populates=\"device_protocol_associations\")\n protocol_id = Column(Integer, ForeignKey(\"protocol.id\"), primary_key=True)\n protocol = relationship(\"Protocol\", back_populates=\"device_protocol_associations\")\n status_id = Column(Integer, ForeignKey(\"status.id\"), nullable=True)\n status = relationship(\"Status\", back_populates=\"device_protocol_associations\")\n\n\nclass Device(Base):\n __tablename__ = \"device\"\n id = Column(Integer, primary_key=True)\n name = Column(String(255))\n status_id = Column(Integer, ForeignKey(\"status.id\"))\n status = relationship(\"Status\", back_populates=\"devices\")\n device_protocol_associations = relationship(DeviceProtocolAssociation, back_populates=\"device\")\n protocols = association_proxy(\"device_protocol_associations\", \"protocol\")\n\n\nclass Protocol(Base):\n __tablename__ = \"protocol\"\n id = Column(Integer, primary_key=True)\n name = Column(String(255))\n device_protocol_associations = relationship(DeviceProtocolAssociation, back_populates=\"protocol\")\n devices = association_proxy(\"device_protocol_associations\", \"device\")\n\n\nclass Status(Base):\n __tablename__ = \"status\"\n id = Column(Integer, primary_key=True)\n name = Column(String(255))\n devices = relationship(\"Device\", back_populates=\"status\")\n device_protocol_associations = relationship(DeviceProtocolAssociation, back_populates=\"status\")\n```\n\n```py\ndef create_test_data() -> Device:\n status_ok = Status(id=1, name=\"OK\")\n device = Device(id=42, name=\"device1\", status=status_ok)\n device.device_protocol_associations.append(\n DeviceProtocolAssociation(\n protocol=Protocol(id=1, name=\"ethernet\"),\n status=status_ok,\n )\n )\n device.device_protocol_associations.append(\n DeviceProtocolAssociation(\n protocol=Protocol(id=2, name=\"ethercat\"),\n status=Status(id=69, name=\"Not OK\"),\n )\n )\n return device\n```\n\n```py\nfrom __future__ import annotations\nfrom pydantic import BaseModel as _BaseModel, Field\n\n\nclass BaseModel(_BaseModel):\n class Config:\n orm_mode = True\n\n\nclass ProtocolStatusModel(BaseModel):\n \"\"\"Corresponds to `DeviceProtocolAssociation`, but no need for `device`\"\"\"\n protocol: ProtocolModel\n status: StatusModel\n\n\nclass DeviceModel(BaseModel):\n id: int\n name: str\n status: StatusModel\n protocols: list[ProtocolStatusModel] = Field(alias=\"device_protocol_associations\")\n\n\nclass ProtocolModel(BaseModel):\n id: int\n name: str\n\n\nclass StatusModel(BaseModel):\n id: int\n name: str\n```\n\n```py\nProtocolStatusModel.update_forward_refs()\nDeviceModel.update_forward_refs()\n\n\ndef main() -> None:\n db_device = create_test_data()\n output_device = DeviceModel.from_orm(db_device)\n print(output_device.json(indent=4))\n\n\nif __name__ == \"__main__\":\n main()\n```\n\n```json\n{\n \"id\": 42,\n \"name\": \"device1\",\n \"status\": {\n \"id\": 1,\n \"name\": \"OK\"\n },\n \"protocols\": [\n {\n \"protocol\": {\n \"id\": 1,\n \"name\": \"ethernet\"\n },\n \"status\": {\n \"id\": 1,\n \"name\": \"OK\"\n }\n },\n {\n \"protocol\": {\n \"id\": 2,\n \"name\": \"ethercat\"\n },\n \"status\": {\n \"id\": 69,\n \"name\": \"Not OK\"\n }\n }\n ]\n}\n```\n\n```text\ndevice\n```\n\n```text\ndevice_protocol\n```\n\n```text\nprotocols\n```\n\n```text\ndevice_protocol\n```\n\n```text\nprotocol\n```\n\n```text\nstatus\n```\n\n```text\ndevice_protocol\n```\n\n```text\nDevice\n```\n\n```text\nDevices\n```\n\n```text\nstatus\n```\n\n```text\nprotocol_status\n```\n\n```text\nDeviceProtocols\n```\n\n```text\nDeviceProtocolAssociation\n```\n\n```text\nbackref\n```\n\n```text\nDevice\n```\n\n```text\nDeviceProtocolAssociation\n```\n\n```text\ndevice_protocol\n```\n\n```text\nsecondary\n```\n\n```text\nProtocol\n```\n\n```text\nprotocol\n```\n\n```text\nDevice\n```\n\n```text\nProtocol\n```\n\n```text\nStatus\n```\n\n```text\nDevice\n```\n\n```text\nProtocol\n```\n\n```text\nDeviceProtocolAssociation\n```\n\n```text\nDeviceProtocolAssociation\n```\n\n```text\nprotocol\n```\n\n```text\nProtocol\n```\n\n```text\nstatus\n```\n\n```text\nStatus\n```\n\n```text\nrelationship\n```\n\n```text\nDevice\n```\n\n```text\nDeviceProtocolAssociation\n```\n\n```text\ndevice_protocol_associations\n```\n\n```text\nDevice\n```\n\n```text\nDeviceProtocolAssociation\n```\n\n```text\nrelationship\n```\n\n```text\nDeviceProtocolAssociation\n```\n\n```text\nProtocol\n```\n\n```text\nprotocol\n```\n\n```text\nProtocol\n```\n\n```text\nassociation_proxy\n```\n\n```text\nDevice\n```\n\n```text\nDeviceProtocolAssociation.protocol\n```\n\n```text\nrelationship\n```\n\n```text\nDevice\n```\n\n```text\nProtocol\n```\n\n```text\nsecondary\n```\n\n```text\nprotocol\n```\n\n```text\nDeviceProtocolAssociation\n```\n\n```text\ndevice_protocol_associations\n```\n\n```text\nprotocols\n```\n\n```text\nProtocol\n```\n\n```text\nStatus\n```\n\n```text\nProtocol\n```\n\n```text\nDeviceProtocolAssociation\n```\n\n```text\ndevices\n```\n\n```text\nStatus\n```\n\n```text\nDeviceModel\n```\n\n```text\nprotocols\n```\n\n```text\ndevice_protocol_associations\n```\n\n```text\nDevice\n```\n\n```text\ndevice_protocol_associations\n```\n\n========================================\n\nComments:\n- It would help me (and maybe others) to put your desired relations into words: You have *devices*, *protocols* and *statuses*. Any *device* can have many *protocols* and any *protocol* can have many *devices*. (`n:n`) Any *device-protocol*-pair can have one *status* (`n:1`), thus any *status* can have many *device-protocol*-pairs. In addition to that, any *device* can itself have one *status* (`n:1`), thus any *status* can have many *devices*. Is that correct?\n- Your desired output model for a *device* should have a `status` field (data from the related *status* model). It should also have a `protocols` list field. Each object in `protocols` should have a `protocol` field, i.e. data from one related *protocol* and a `status` field, i.e. data from the *status* that is **related to that particular *device-protocol*-pair**. Is that correct?\n- @DaniilFajnberg that's exactly what I want, sorry for my explanation.\n- Thank you so much! Perfect and detailed solution. Good work.","metadata":{"transformedAt":"2026-08-18T18:32:29.164Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":73,"totalLines":671,"estimatedTokens":3088}}772{"id":"stack-74510774","source":"stackoverflow","questionId":74510774,"title":"RuntimeError: error checking inheritance of module 'datetime'","tags":["python","fastapi","python-datetime"],"text":"Title: RuntimeError: error checking inheritance of module 'datetime'\nTags: python, fastapi, python-datetime\nSource: Stack Overflow\n\nQuestion:\nI am getting following error when trying to run my python app:\n\nRuntimeError: error checking inheritance of (type: module)\n\nThis is my code:\n\n```\nimport datetime\nfrom pydantic.types import Optional\nfrom sqlmodel import SQLModel, Field\n\nclass BlogBase(SQLModel): \n title: str\n published_at: datetime\n # author:str = Field(default=None, foreign_key=\"author.id\")\n body: str\n updated_at: Optional[str]\n\nclass Blog(BlogBase, table=True): \n id: int = Field(default=True, primary_key=True)\n published_at: datetime = Field(default=datetime.utcnow(), nullable=False)\n\nclass BlogCreate(BlogBase): \n pass\n```\n\nCan someone help me in understanding the problem and how I can fix it?\n\n========================================\n\nCode:\n```py\nimport datetime\nfrom pydantic.types import Optional\nfrom sqlmodel import SQLModel, Field\n\nclass BlogBase(SQLModel): \n title: str\n published_at: datetime\n # author:str = Field(default=None, foreign_key=\"author.id\")\n body: str\n updated_at: Optional[str]\n\nclass Blog(BlogBase, table=True): \n id: int = Field(default=True, primary_key=True)\n published_at: datetime = Field(default=datetime.utcnow(), nullable=False)\n\n\nclass BlogCreate(BlogBase): \n pass\n```\n\n```py\nfrom datetime import datetime\n\nnow = datetime.utcnow()\n```\n\n```py\nfrom datetime import datetime\n```\n\n```py\nimport datetime\n\nnow = datetime.datetime.utcnow()\n```\n\n```text\ndatetime\n```\n\n```text\ndatetime.datetime\n```\n\n```text\ndatetime\n```\n\n```text\nutcnow()\n```\n\n```text\ndatetime\n```\n\n```text\ndatetime\n```\n\n```text\ndatetime\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.164Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":11,"totalLines":100,"estimatedTokens":419}}773{"id":"stack-75107329","source":"stackoverflow","questionId":75107329,"title":"How to return an object after insert with sqlalchemy?","tags":["python","sqlalchemy","fastapi"],"text":"Title: How to return an object after insert with sqlalchemy?\nTags: python, sqlalchemy, fastapi\nSource: Stack Overflow\n\nQuestion:\nI would like to retrieve the object after inserting it into the database, by object I mean the Base class.\nSome examples:\n\n```\nclass EdaToken(Base):\n\n __tablename__ = \"eda_token\"\n\n \"\"\"id, primary key\"\"\"\n id = Column(\n Integer(),\n primary_key=True\n )\n#... etc etc\n```\n\nthis works, return an EdaToken object:\n\n```\n@classmethod\n async def get_all(cls) -> List['EdaToken']:\n \"\"\"\n Get all records in database\n \"\"\"\n async with get_session() as conn:\n result = await conn.execute(\n select(EdaToken)\n )\n return result.scalars().all()\n```\n\nThe problem is in the insert:\n\n```\n#various tests\n @classmethod\n async def create_eda_token(\n cls,\n token: EdaTokenInputOnCreate\n ) -> 'EdaToken':\n \"\"\"\n Create a token and returning its new id\n \"\"\"\n async with get_session() as conn:\n result = await conn.execute(\n insert(EdaToken).values(label=token.label,token=token.token)\n )\n return result.scalars().unique().first() #??\n```\n\nWhat I'd like to return is the new database entry as an EdaToken object.\n\nError:\n\n```\n\n'CursorResult' object has no attribute 'id'\n```\n\nAnother test:\n\ndoesn't seem to work, though, it only allows me to enter a new token once, all new tokens are not entered and it always returns the previous token, the only one that is entered.\n\n```\n@classmethod\n async def create_eda_token(cls, token: EdaTokenInputOnCreate) -> 'EdaToken':\n \"\"\"\n Create a token and returning its new id\n \"\"\"\n async with get_session() as conn:\n result = await conn.execute(\n insert(EdaToken).values(label=token.label,token=token.token).returning(EdaToken)\n )\n await conn.flush()\n token_id = result.scalars().unique().first()\n result = await conn.execute(\n select(EdaToken).where(EdaToken.id == token_id)\n )\n return result.scalars().unique().first()\n```\n\n`psycopg2==2.9.3`\n`sqlalchemy==1.4.46`\n`asyncpg==0.27.0`\n\n========================================\n\nTop Answer:\nAnother working solution, adapted from @Plaoo (you don't need another query)\n\n```\n@classmethod\n async def create_eda_token(cls, token: EdaTokenInputOnCreate) -> 'EdaToken':\n \"\"\"\n Create a token and returning a new EdaToken instance\n \"\"\"\n async with engine.begin() as conn:\n result = await conn.execute(\n insert(EdaToken).values(\n label=token.label,\n token=token.token\n ).returning(EdaToken)\n )\n return result.scalar_one()\n```\n\nYou also don't need a commit because of the `with engine.begin()`\n\n========================================\n\nCode:\n```py\nclass EdaToken(Base):\n\n __tablename__ = \"eda_token\"\n\n \"\"\"id, primary key\"\"\"\n id = Column(\n Integer(),\n primary_key=True\n )\n#... etc etc\n```\n\n```py\n@classmethod\n async def get_all(cls) -> List['EdaToken']:\n \"\"\"\n Get all records in database\n \"\"\"\n async with get_session() as conn:\n result = await conn.execute(\n select(EdaToken)\n )\n return result.scalars().all()\n```\n\n```py\n#various tests\n @classmethod\n async def create_eda_token(\n cls,\n token: EdaTokenInputOnCreate\n ) -> 'EdaToken':\n \"\"\"\n Create a token and returning its new id\n \"\"\"\n async with get_session() as conn:\n result = await conn.execute(\n insert(EdaToken).values(label=token.label,token=token.token)\n )\n return result.scalars().unique().first() #??\n```\n\n```text\n<sqlalchemy.engine.cursor.CursorResult object at 0x7fedd7c24250>\n'CursorResult' object has no attribute 'id'\n```\n\n```py\n@classmethod\n async def create_eda_token(cls, token: EdaTokenInputOnCreate) -> 'EdaToken':\n \"\"\"\n Create a token and returning its new id\n \"\"\"\n async with get_session() as conn:\n result = await conn.execute(\n insert(EdaToken).values(label=token.label,token=token.token).returning(EdaToken)\n )\n await conn.flush()\n token_id = result.scalars().unique().first()\n result = await conn.execute(\n select(EdaToken).where(EdaToken.id == token_id)\n )\n return result.scalars().unique().first()\n```\n\n```text\npsycopg2==2.9.3\n```\n\n```text\nsqlalchemy==1.4.46\n```\n\n```text\nasyncpg==0.27.0\n```\n\n```py\n@classmethod\n async def create_eda_token(cls, token: EdaTokenInputOnCreate) -> 'EdaToken':\n \"\"\"\n Create a token and returning a new EdaToken instance\n \"\"\"\n async with engine.begin() as conn:\n result = await conn.execute(\n insert(EdaToken).values(label=token.label,token=token.token).returning(EdaToken)\n )\n await conn.commit()\n\n async with get_session() as conn:\n token_id = result.scalars().unique().first()\n result = await conn.execute(\n select(EdaToken).where(EdaToken.id == token_id)\n )\n return result.scalars().unique().first()\n```\n\n```py\n@classmethod\n async def create_eda_token(cls, token: EdaTokenInputOnCreate) -> 'EdaToken':\n \"\"\"\n Create a token and returning a new EdaToken instance <--\n \"\"\"\n\n async with get_session() as conn:\n new_token_id = EdaToken(label=token.label,token=token.token)\n conn.add(new_token_id)\n await conn.commit()\n\n return new_token_id\n```\n\n```py\n@classmethod\n async def create_eda_token(cls, token: EdaTokenInputOnCreate) -> 'EdaToken':\n \"\"\"\n Create a token and returning a new EdaToken instance\n \"\"\"\n async with engine.begin() as conn:\n result = await conn.execute(\n insert(EdaToken).values(\n label=token.label,\n token=token.token\n ).returning(EdaToken)\n )\n return result.scalar_one()\n```\n\n```text\nwith engine.begin()\n```\n\n========================================\n\nComments:\n- Have you tried selecting the object after inserting it? The `result` object should have a `.inserted_primary_key` property that you can use to get the generated id of the last insertion.\n- Hi @MatsLindh using scalar on result, I can retrieve the id, what I'm interested in is the return of the EdaToken object, is possible after an insert.\n- Yes, query the database for the object as you do with the select above.\n- @MatsLindh Can't I do it directly from the insert? Or does the insert only return me the id? I'll try it out and edit the answer.\n- No, an insert does not return the whole row that the insert resulted in for most RDBM-es (or their drivers - except for possibly doing an additional SELECT to retrieve the row based on the returned primary key) that I'm familiar with, only the primary key is usually returned by database drivers (implementations will vary)\n- Why aren't you using the typical ORM pattern? `new_token = EdaToken(…)`, then `session.add(new_token)`, followed by `session.flush()` or `session.commit()`. That will insert the row into the database and you still have the `new_token` object to work with.\n- Hi @GordThompson with get_session() or engine.begin()?\n- Not `engine.begin()` because that does not return a Session.\n- @GordThompson ``` async with get_session() as conn: new_token_id = EdaToken(label=token.label,token=token.token) result = await conn.add(new_token_id) await conn.flush() ``` ``` \"object NoneType can't be used in 'await' expression\"```\n- `.add()` and `.add_all()` do not need `await`. See the example here.\n- thank @GordThompson i have changed my answer!\n- is it possible also add joins to new object, and execute them on insert?","metadata":{"transformedAt":"2026-08-18T18:32:29.165Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":12,"totalLines":264,"estimatedTokens":1951}}774{"id":"stack-74549045","source":"stackoverflow","questionId":74549045,"title":"Why url_for generates URL with localhost as the hostname instead of the domain name?","tags":["python","jinja2","fastapi","templating","starlette"],"text":"Title: Why url_for generates URL with localhost as the hostname instead of the domain name?\nTags: python, jinja2, fastapi, templating, starlette\nSource: Stack Overflow\n\nQuestion:\nI have a FastAPI web application using Jinja2 templates, which is working fine on `localhost`, but **not** in production. The problem is that is not generating URLs for JavaScript and other `static` files correctly. I have deployed it on EC2 instance using `gunicorn` and `nginx`.\n\nI have this line of code in my HTML file:\n\n```\n\n```\n\nThe problem is that it is generating the URL like this:\n\n```\n\n```\n\nWhat I want is to generate something like this:\n\n```\n\n```\n\n========================================\n\nTop Answer:\nServe on `0.0.0.0` instead of `127.0.0.1`. If you're using `uvicorn` which is the default web server for FastAPI, you need to pass `--host 0.0.0.0` when starting the server. For other servers, look up the equivalent flag.\n\n========================================\n\nCode:\n```html\n<script src=\"{{ url_for('static', path='js/login_signup.js') }}\"></script>\n```\n\n```html\n<script src=\"http://127.0.0.1:8000/static/js/login_signup.js\"></script>\n```\n\n```html\n<script src=\"http://my_domain.com/static/js/login_signup.js\"></script>\n```\n\n```text\nlocalhost\n```\n\n```text\nstatic\n```\n\n```text\ngunicorn\n```\n\n```text\nnginx\n```\n\n```text\ngunicorn --bind 0.0.0.0:80\n```\n\n```text\nserver {\n server_name example.com\n location / {\n proxy_redirect off;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header X-Forwarded-Proto $scheme;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-Host $server_name;\n\n ...\n }\n\n\n listen 443 ssl;\n```\n\n```html\n<link href=\"static/styles.css'\" rel=\"stylesheet\">\n```\n\n```py\nfrom fastapi import FastAPI, Request\nfrom fastapi.staticfiles import StaticFiles\nfrom fastapi.templating import Jinja2Templates\nfrom typing import Any\nimport urllib\n\napp = FastAPI()\n\ndef my_url_for(request: Request, name: str, **path_params: Any) -> str:\n url = request.url_for(name, **path_params)\n parsed = list(urllib.parse.urlparse(url))\n #parsed[0] = 'https' # Change the scheme to 'https' (Optional)\n parsed[1] = 'my_domain.com' # Change the domain name\n return urllib.parse.urlunparse(parsed)\n \n\napp.mount('/static', StaticFiles(directory='static'), name='static')\ntemplates = Jinja2Templates(directory='templates')\ntemplates.env.globals['my_url_for'] = my_url_for\n```\n\n```html\n<link href=\"{{ my_url_for(request, 'static', path='/styles.css') }}\" rel=\"stylesheet\">\n```\n\n```text\ngunicorn\n```\n\n```text\n0.0.0.0\n```\n\n```text\n--proxy-headers\n```\n\n```text\nmy_url_for()\n```\n\n```text\nurl_for()\n```\n\n```text\n0.0.0.0\n```\n\n```text\n127.0.0.1\n```\n\n```text\nuvicorn\n```\n\n```text\n--host 0.0.0.0\n```\n\n========================================\n\nComments:\n- Probably because you're not serving on `0.0.0.0`, but you've given us no info. How are you starting your server?","metadata":{"transformedAt":"2026-08-18T18:32:29.165Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":21,"totalLines":153,"estimatedTokens":761}}775{"id":"stack-61239656","source":"stackoverflow","questionId":61239656,"title":"How to Implement Role Based Authentication with JWT in Python","tags":["vue.js","jwt","fastapi"],"text":"Title: How to Implement Role Based Authentication with JWT in Python\nTags: vue.js, jwt, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am looking to implement a role based authentication in a Vue/FastApi application. I come from a background of using Web Forms in asp.net and it was fairly simple to hide and show certain forms depending on if the user is an Admin, or a Manager, or Employee etc. Is there a way to do this with Vue/FastApi with JWT?","metadata":{"transformedAt":"2026-08-18T18:32:29.165Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":0,"totalLines":6,"estimatedTokens":112}}776{"id":"stack-60695759","source":"stackoverflow","questionId":60695759,"title":"Creating objects with ID and populating other fields","tags":["python","fastapi","pydantic"],"text":"Title: Creating objects with ID and populating other fields\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI want to construct a Pydantic object only with ID, and then populate other fields based on ID.\n\nI tried 2 different approaches, validator and also post init. Neither did work, so.\n\nCommon code:\n\n```\nfrom pydantic import BaseModel, validator\n\nobj_list = [\n {'id': 1, 'name': 'a', 'desc': 'desc1'},\n {'id': 2, 'name': 'b', 'desc': 'desc2'},\n {'id': 3, 'name': 'c', 'desc': 'desc3'}\n]\n```\n\nSolution 1: \n\n```\nclass Obj(BaseModel):\n id: int\n name: str = None\n desc: str = None\n\n @validator('id')\n def validate_exists(cls, v):\n items = [h for h in obj_list if h['id'] == v]\n if len(items) == 0:\n raise ValueError('id doesnt exist')\n return v\n\n def __post_init__(self):\n item = [h for h in obj_list if h['name'] == v][0]\n self.name = item['name']\n self.desc = item['desc']\n\nObj(id=1)\n# \n```\n\nSolution 2: \n\n```\nclass Obj(BaseModel):\n name: str = None\n desc: str = None\n id: int\n\n @validator('id')\n def validate_exists(cls, v, values):\n items = [h for h in obj_list if h['id'] == v]\n if len(items) == 0:\n raise ValueError('id doesnt exist')\n item = items[0]\n values['name'] = item['name']\n values['desc'] = item['desc']\n return v\n\nObj(id=1)\n# \n```\n\nI feel like it's doable. I read both Pydantic's and FastApi's documentation, but couldn't find anything relevant to this.\nSo, how can I construct objects using only IDs and then populate fields using DB or another object?\n\n========================================\n\nTop Answer:\n`__post_init__` doesn't exist, I think you got that confused with dataclasses.\n\nPydantic things validation should happen once, when you create the model object. Though you can work around this by using `Config.validate_assignment`.\n\nThere are two solutions to this:\n\n- Create each model with just `id` then use attribute assignment to set the other fields. This will be slower and I think is the wrong approach.\n\n- Don't create the models until you have all the data you need to create the model. I would suggest this is the best approach.\n\n========================================\n\nCode:\n```py\nfrom pydantic import BaseModel, validator\n\nobj_list = [\n {'id': 1, 'name': 'a', 'desc': 'desc1'},\n {'id': 2, 'name': 'b', 'desc': 'desc2'},\n {'id': 3, 'name': 'c', 'desc': 'desc3'}\n]\n```\n\n```py\nclass Obj(BaseModel):\n id: int\n name: str = None\n desc: str = None\n\n @validator('id')\n def validate_exists(cls, v):\n items = [h for h in obj_list if h['id'] == v]\n if len(items) == 0:\n raise ValueError('id doesnt exist')\n return v\n\n def __post_init__(self):\n item = [h for h in obj_list if h['name'] == v][0]\n self.name = item['name']\n self.desc = item['desc']\n\nObj(id=1)\n# <Obj id=1 name=None desc=None>\n```\n\n```py\nclass Obj(BaseModel):\n name: str = None\n desc: str = None\n id: int\n\n @validator('id')\n def validate_exists(cls, v, values):\n items = [h for h in obj_list if h['id'] == v]\n if len(items) == 0:\n raise ValueError('id doesnt exist')\n item = items[0]\n values['name'] = item['name']\n values['desc'] = item['desc']\n return v\n\nObj(id=1)\n# <Obj name=None desc=None id=1>\n```\n\n```text\nfrom pydantic import BaseModel, root_validator\n\nobj_list = [\n {'id': 1, 'name': 'a', 'desc': 'desc1'},\n {'id': 2, 'name': 'b', 'desc': 'desc2'},\n {'id': 3, 'name': 'c', 'desc': 'desc3'}\n]\nclass Obj(BaseModel):\n id: int\n name: str = None\n desc: str = None\n\n @root_validator(pre=True)\n def validate_exists(cls, values):\n if 'id' not in values:\n raise ValueError(\"id doesn't exist in the fields\")\n items = [h for h in obj_list if h['id'] == values['id']]\n if len(items) == 0:\n raise ValueError(f\"there is no obj with id {values['id']}\")\n return items[0]\n\nObj(id=1)\n```\n\n```text\nroot_validator\n```\n\n```text\n__post_init__\n```\n\n```text\nConfig.validate_assignment\n```\n\n```text\nid\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.165Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":8,"totalLines":178,"estimatedTokens":1006}}777{"id":"stack-78084157","source":"stackoverflow","questionId":78084157,"title":"FastAPI and Pydantic - ignore but warn when extra elements are provided to a router input Model","tags":["python","fastapi","pydantic","python-3.11"],"text":"Title: FastAPI and Pydantic - ignore but warn when extra elements are provided to a router input Model\nTags: python, fastapi, pydantic, python-3.11\nSource: Stack Overflow\n\nQuestion:\nThis is the code I wrote\n\n```\nfrom typing import Any\nfrom fastapi import APIRouter\nfrom pydantic import BaseModel, ConfigDict, ValidationError\n\nclass State(BaseModel):\n mode: str | None = None\n alarm: int = 0\n\nclass StateLoose(State):\n model_config = ConfigDict(extra='allow')\n\nclass StateExact(State):\n model_config = ConfigDict(extra='forbid')\n\ndef validated_state(state: dict) -> State:\n try:\n return StateExact(**state)\n except ValidationError as e:\n logger.warning(\"Sanitized input state that caused a validation error. Error: %s\", e)\n return State(**state)\n\n@router.put(\"/{client_id}\", response_model=State)\ndef update_state(client_id: str, state: StateLoose) -> Any:\n v_state = validated_state(state.dict()).dict()\n return update_resource(client_id=client_id, state=v_state)\n\n# Example State inputs\na = {\"mode\": \"MANUAL\", \"alarm\": 1}\nb = {\"mode\": \"MANUAL\", \"alarm\": 1, \"dog\": \"bau\"}\n\nnormal = State(**a)\nloose = StateLoose(**a)\nexact = StateExact(**a)\n```\n\nFrom my understanding/tests with/of pydantic\n\n- State \"adapts\" the input dict to fit the model and trows an exception only when something is very wrong (non-convertable type, missing required field). However, extra fields are lost.\n\n- StateLoose, accepts extra fields and shows them by default (or with **pydantic_extra**)\n\n- StateExact trows a ValidationError whenever something extra is provided\n\nWhat I wanted to achieve is:\n\n- Show the \"State scheme as input\" in the FastAPI generated Docs (this means having a State-like input in the \"put function\".\n\n- Accept States that have extra elements but ignoring the extra elements (this means using State to remove extra args)\n\n- Log a warning when extra elements are detected so that I can trace this since probably it means something went not as planned\n\nTo achieve this I was forced to create 3 different State classes and play with those. Since I plan to have lots of Models, I don't like the idea of having 3 versions of each and it feels like I am doing something quite wrong if it's so weird to accomplish.\n\n**Is there a less redundant way to:**\n\n- accept extra elements in a Model;\n\n- use the Model as an input to FastAPI router.put;\n\n- generate a warning;\n\n- ignore extra elements and continue with the right ones?\n\n========================================\n\nCode:\n```text\nfrom typing import Any\nfrom fastapi import APIRouter\nfrom pydantic import BaseModel, ConfigDict, ValidationError\n\n\n\nclass State(BaseModel):\n mode: str | None = None\n alarm: int = 0\n\n\nclass StateLoose(State):\n model_config = ConfigDict(extra='allow')\n\n\nclass StateExact(State):\n model_config = ConfigDict(extra='forbid')\n\n\ndef validated_state(state: dict) -> State:\n try:\n return StateExact(**state)\n except ValidationError as e:\n logger.warning(\"Sanitized input state that caused a validation error. Error: %s\", e)\n return State(**state)\n\n\n@router.put(\"/{client_id}\", response_model=State)\ndef update_state(client_id: str, state: StateLoose) -> Any:\n v_state = validated_state(state.dict()).dict()\n return update_resource(client_id=client_id, state=v_state)\n\n\n# Example State inputs\na = {\"mode\": \"MANUAL\", \"alarm\": 1}\nb = {\"mode\": \"MANUAL\", \"alarm\": 1, \"dog\": \"bau\"}\n\nnormal = State(**a)\nloose = StateLoose(**a)\nexact = StateExact(**a)\n```\n\n```py\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel, ConfigDict, model_validator\n\n\nclass WarnUnknownBase(BaseModel):\n model_config = ConfigDict(extra='ignore')\n\n @model_validator(mode='before')\n @classmethod\n def validate(cls, values):\n expected_fields = set(cls.model_fields.keys())\n submitted_fields = set(values.keys())\n unknown_fields = submitted_fields - expected_fields\n \n if unknown_fields:\n print(f\"Log these fields: {unknown_fields}\")\n\n return values\n \n \nclass Foo(WarnUnknownBase):\n foo: int\n \n \napp = FastAPI()\n\n@app.put('/')\ndef put_it(foo: Foo):\n return foo\n```\n\n```bash\nλ curl -H \"Content-Type: application/json\" -X PUT -d \"{\\\"foo\\\": 42}\" http://localhost:8008\n{\"foo\":42}\nλ curl -H \"Content-Type: application/json\" -X PUT -d \"{\\\"foo\\\": 42, \\\"bar\\\": 13}\" http://localhost:8008\n{\"foo\":42}\n```\n\n```bash\nINFO: 127.0.0.1:49458 - \"PUT / HTTP/1.1\" 200 OK\nLog these fields: {'bar'}\nINFO: 127.0.0.1:49462 - \"PUT / HTTP/1.1\" 200 OK\n```\n\n```text\nmodel_validator\n```\n\n```text\nmode=\"before\"\n```\n\n```text\nextra='ignore'\n```\n\n```text\nmodel_config\n```\n\n```text\nbar\n```\n\n```text\nLog these fields: {'bar'}\n```\n\n========================================\n\nComments:\n- You can use a `model_validator` with `before` to get access to the submitted values *before* validation happen, so you can log any fields that you didn't expect; you can then configure your model to use `ignore` for `extra` so anything that doesn't match a parameter gets dropped. docs.pydantic.dev/latest/api/base_model/… should give you the fields defined on the model.\n- I honestly tried but without any real success in understanding how it works. Would you be able to write an example of how the small code above would look like? In that case I could also accept your answer. Thanks.\n- Wow, just tried it out and works like a charm. Thanks, it was really a good way to solve this.","metadata":{"transformedAt":"2026-08-18T18:32:29.165Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":10,"totalLines":192,"estimatedTokens":1357}}778{"id":"stack-78425424","source":"stackoverflow","questionId":78425424,"title":"How can you specify python runtime version in vercel?","tags":["python","fastapi","vercel"],"text":"Title: How can you specify python runtime version in vercel?\nTags: python, fastapi, vercel\nSource: Stack Overflow\n\nQuestion:\nI am trying to deploy a simple FastAPI app to vercel for the first time.\nVercel.json is exactly below.\n\n```\n{\n \"devCommand\": \"uvicorn main:app --host 0.0.0.0 --port 3000\",\n \"builds\": [\n {\n \"src\": \"api/index.py\",\n \"use\": \"@vercel/python\",\n \"config\": {\n \"maxLambdaSize\": \"15mb\",\n \"runtime\": \"python3.9\"\n }\n }\n ],\n \"routes\": [\n {\n \"src\": \"/(.*)\",\n \"dest\": \"api/index.py\"\n }\n ]\n}\n```\n\nI have specified runtime as python3.9, but this doesn't reflect actual runtime which is still python3.12 (default).This ends up causing internal error.\n\nHow can I configure runtime version correctly?\n\nI also read the official docs which says `builds` property shouldn't be used. So I tried to rewrite like below.\n\n```\n{\n \"devCommand\": \"uvicorn main:app --host 0.0.0.0 --port 3000\",\n \"functions\": {\n \"api/index.py\":\n {\n \"runtime\": \"python@3.9\"\n }\n },\n \"routes\": [\n {\n \"src\": \"/(.*)\",\n \"dest\": \"api/index.py\"\n }\n ]\n}\n```\n\nThis didn't work as well.\nMaybe I shouldn't use vercel for python project?(little information in the internet)\n\n========================================\n\nCode:\n```json\n{\n \"devCommand\": \"uvicorn main:app --host 0.0.0.0 --port 3000\",\n \"builds\": [\n {\n \"src\": \"api/index.py\",\n \"use\": \"@vercel/python\",\n \"config\": {\n \"maxLambdaSize\": \"15mb\",\n \"runtime\": \"python3.9\"\n }\n }\n ],\n \"routes\": [\n {\n \"src\": \"/(.*)\",\n \"dest\": \"api/index.py\"\n }\n ]\n}\n```\n\n```json\n{\n \"devCommand\": \"uvicorn main:app --host 0.0.0.0 --port 3000\",\n \"functions\": {\n \"api/index.py\":\n {\n \"runtime\": \"python@3.9\"\n }\n },\n \"routes\": [\n {\n \"src\": \"/(.*)\",\n \"dest\": \"api/index.py\"\n }\n ]\n}\n```\n\n```text\nbuilds\n```\n\n```text\n## my_app.py\nfrom http.server import BaseHTTPRequestHandler, HTTPServer\nimport sys\n\nclass GETHandler(BaseHTTPRequestHandler):\n \n def do_GET(self):\n self.send_response(200)\n self.send_header('Content-type','text/plain')\n self.end_headers()\n self.wfile.write('Hello, world!\\n'.encode('utf-8'))\n python_version = f\"{sys.version_info[0]}.{sys.version_info[1]}.{sys.version_info[2]}\"\n self.wfile.write(f'Python version {python_version}'.encode('utf-8'))\n\n# variable required by Vercel\nhandler = GETHandler\n```\n\n```text\n## run in bash\npip install pipenv\npipenv install\n```\n\n```text\n## Pipfile\n[[source]]\nurl = \"https://pypi.org/simple\"\nverify_ssl = true\nname = \"pypi\"\n\n[packages]\npipenv = \"~=2023.12\"\n\n[dev-packages]\n\n[requires]\npython_version = \"3.9\"\n```\n\n```text\n## package.json\n{\n \"engines\": {\n \"node\": \"18.x\"\n }\n \n}\n```\n\n```text\n## vercel.json\n{\n\"builds\": [\n { \"src\": \"*.py\", \"use\": \"@vercel/python\" }\n ],\n \"redirects\": [\n { \"source\": \"/\", \"destination\": \"/my_app.py\" }\n ] \n\n}\n```\n\n```text\nbuilds\n```\n\n```text\nfunctions\n```\n\n```text\nVercel.json\n```\n\n```text\n@vercel/python\n```\n\n```text\nnode.js\n```\n\n```text\nPipfile\n```\n\n```text\nhandler\n```\n\n```text\napp\n```\n\n```text\npackage.json\n```\n\n```text\n/my_app.py\n```\n\n========================================\n\nComments:\n- Thank you for your solution! Pipfile didn't work for me unfortunately.\n- @agongji I was able to set up Python3.9 env on my vercel account. Thus updated my answer: 1. added links to several useful examples from vercel git; 2. step-by-step guide that worked on my computer.\n- Thank you for the step-by-step guide! It also worked to me!","metadata":{"transformedAt":"2026-08-18T18:32:29.165Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":18,"totalLines":214,"estimatedTokens":866}}779{"id":"stack-78513762","source":"stackoverflow","questionId":78513762,"title":"Validate Additional Info Using Pydantic Model","tags":["python","fastapi","pydantic"],"text":"Title: Validate Additional Info Using Pydantic Model\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI'm a new user of FastAPI. I'm writing a small web application and I'm wondering if it's good practice to validate additional information, which is not directly related to the object itself, using the Pydantic model itself? For example, checking if a user with such a name exists in the database.\nFor example:\n\n```\nclass CreateUser(BaseModel):\n model_config = ConfigDict(strict=True)\n username: str = Field(pattern=r\"[0-9a-zA-Z!@#$%&*_.-]{3,}\")\n password: str\n secret: str\n \n @field_validator(\"username\")\n def validate_username(cls, value: str):\n # check if user is exist in DB...\n # if no, return the username\n # if yes, raise error\n```\n\n========================================\n\nCode:\n```text\nclass CreateUser(BaseModel):\n model_config = ConfigDict(strict=True)\n username: str = Field(pattern=r\"[0-9a-zA-Z!@#$%&*_.-]{3,}\")\n password: str\n secret: str\n \n @field_validator(\"username\")\n def validate_username(cls, value: str):\n # check if user is exist in DB...\n # if no, return the username\n # if yes, raise error\n```\n\n========================================\n\nComments:\n- FastAPI may have some suggestions on what best practice is. In my experience, keeping the models fairly self contained leads to longer code, possibly more complicated code, but in the end easier to maintain code. YMMV.\n- Take a look at SQLModel which is from the same author as FastAPI\n- A model should only validate for a valid request (this also tangles up the error handling, since you won't reach the body of the function if the validation fails). Second, you probably want to make use of the dependency injection in FastAPI for the database session handling.\n- pydantic model is only here to validate the request and respone schema and type hints, nothing else. for you to keep username unique you need to add constraint in the db model username field ,that the unique=True that is all you need to do","metadata":{"transformedAt":"2026-08-18T18:32:29.165Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":1,"totalLines":46,"estimatedTokens":510}}780{"id":"stack-78525399","source":"stackoverflow","questionId":78525399,"title":"FastAPI OAuth2 with ForgeRock: SSL Certificate Verification Issue","tags":["ssl","oauth-2.0","fastapi","httpx","forgerock"],"text":"Title: FastAPI OAuth2 with ForgeRock: SSL Certificate Verification Issue\nTags: ssl, oauth-2.0, fastapi, httpx, forgerock\nSource: Stack Overflow\n\nQuestion:\nI'm working on implementing OAuth2 authentication in a FastAPI application using ForgeRock as the identity provider. This setup is within my company's internal environment, and I have the necessary certificates. However, I'm encountering an SSL certificate verification error when attempting to authenticate with ForgeRock (or calling /auth/login endpoint):\n\n[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self\nsigned certificate in certificate chain (_ssl.c:997)\n\nFastAPI is running in a container, here is my Dockerfile:\n\n```\nFROM xxx.com/xxx/python3.10.9-slim:1.0\nWORKDIR /app\nCOPY ./ /app\nCOPY ./certs /etc/ssl/certs/ca-certificates\nRUN chmod 644 /etc/ssl/certs/ca-certificates/*\nRUN apt-get update && apt-get install -y ca-certificates\nRUN update-ca-certificates\n...\n```\n\nThe certificates are moved properly to **/etc/ssl/certs/ca-certificates.crt**\n\nHere is my simplified FastAPI code:\n\n```\nCA_BUNDLE_PATH = '/etc/ssl/certs/ca-certificates.crt'\nos.environ['REQUESTS_CA_BUNDLE'] = CA_BUNDLE_PATH\n\nssl_context = ssl.create_default_context(cafile=CA_BUNDLE_PATH)\nlogging.debug(f\"SSL context CA certificates: {ssl_context.get_ca_certs()}\")\n\nclass CustomHttpxClient(httpx.AsyncClient):\n def __init__(self, *args, **kwargs):\n kwargs['verify'] = ssl_context\n super().__init__(*args, **kwargs)\n\noauth = OAuth()\noauth.register(\n name='forgerock',\n client_id='client-id',\n client_secret='secret',\n server_metadata_url='https://forgerock-login',\n client_kwargs={\n 'scope': 'openid profile email',\n 'httpx_client': CustomHttpxClient()\n }\n)\n\nasync def debug_session_state(request: Request):\n session = request.session\n state = session.get('state')\n logging.debug(f\"Session state: {state}\")\n\n@app.get('/auth/login')\nasync def login(request: Request):\n try:\n redirect_uri = request.url_for('auth_callback')\n response = await oauth.forgerock.authorize_redirect(request, redirect_uri)\n request.session['state'] = response.state\n logging.debug(f\"Stored state in session: {request.session['state']}\")\n return response\n except Exception as e:\n logging.error(f\"Error during authorization redirect: {e}\")\n raise HTTPException(status_code=500, detail=\"Internal Server Error\")\n\n@app.get('/auth/callback')\nasync def auth_callback(request: Request):\n await debug_session_state(request)\n try:\n state_in_session = request.session.get('state')\n state_in_request = request.query_params.get('state')\n logging.debug(f\"State in session: {state_in_session}, State in request: {state_in_request}\")\n \n if state_in_session != state_in_request:\n raise HTTPException(status_code=400, detail=\"CSRF Warning! State not equal in request and response.\")\n\n token = await oauth.forgerock.authorize_access_token(request)\n user = token.get('userinfo')\n return {'user': user}\n except Exception as e:\n logging.error(f\"Callback Error: {e}\")\n raise HTTPException(status_code=400, detail=\"Authentication Failed\")\n```\n\nSo I loaded CA certificates into a custom SSL context and used it with the httpx.AsyncClient.\nAnyway, I see this in debug logs:\n\n**DEBUG:httpx:load_verify_locations cafile='/usr/local/lib/python3.10/site-packages/certif/cacert.pem'**\n\nIt seems that SSL context is different than I specified. I tried different methods to pass SSL context, but with no result. Why I can't set my SSL context?\n\n========================================\n\nCode:\n```text\nFROM xxx.com/xxx/python3.10.9-slim:1.0\nWORKDIR /app\nCOPY ./ /app\nCOPY ./certs /etc/ssl/certs/ca-certificates\nRUN chmod 644 /etc/ssl/certs/ca-certificates/*\nRUN apt-get update && apt-get install -y ca-certificates\nRUN update-ca-certificates\n...\n```\n\n```text\nCA_BUNDLE_PATH = '/etc/ssl/certs/ca-certificates.crt'\nos.environ['REQUESTS_CA_BUNDLE'] = CA_BUNDLE_PATH\n\nssl_context = ssl.create_default_context(cafile=CA_BUNDLE_PATH)\nlogging.debug(f\"SSL context CA certificates: {ssl_context.get_ca_certs()}\")\n\nclass CustomHttpxClient(httpx.AsyncClient):\n def __init__(self, *args, **kwargs):\n kwargs['verify'] = ssl_context\n super().__init__(*args, **kwargs)\n\noauth = OAuth()\noauth.register(\n name='forgerock',\n client_id='client-id',\n client_secret='secret',\n server_metadata_url='https://forgerock-login',\n client_kwargs={\n 'scope': 'openid profile email',\n 'httpx_client': CustomHttpxClient()\n }\n)\n\nasync def debug_session_state(request: Request):\n session = request.session\n state = session.get('state')\n logging.debug(f\"Session state: {state}\")\n\n@app.get('/auth/login')\nasync def login(request: Request):\n try:\n redirect_uri = request.url_for('auth_callback')\n response = await oauth.forgerock.authorize_redirect(request, redirect_uri)\n request.session['state'] = response.state\n logging.debug(f\"Stored state in session: {request.session['state']}\")\n return response\n except Exception as e:\n logging.error(f\"Error during authorization redirect: {e}\")\n raise HTTPException(status_code=500, detail=\"Internal Server Error\")\n\n@app.get('/auth/callback')\nasync def auth_callback(request: Request):\n await debug_session_state(request)\n try:\n state_in_session = request.session.get('state')\n state_in_request = request.query_params.get('state')\n logging.debug(f\"State in session: {state_in_session}, State in request: {state_in_request}\")\n \n if state_in_session != state_in_request:\n raise HTTPException(status_code=400, detail=\"CSRF Warning! State not equal in request and response.\")\n\n token = await oauth.forgerock.authorize_access_token(request)\n user = token.get('userinfo')\n return {'user': user}\n except Exception as e:\n logging.error(f\"Callback Error: {e}\")\n raise HTTPException(status_code=400, detail=\"Authentication Failed\")\n```\n\n```text\nhttpx\n```\n\n```text\nrequests\n```\n\n```text\nhttpx\n```\n\n```text\ncertify\n```\n\n```text\nhttpx\n```\n\n```text\ncertifi\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.165Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":8,"totalLines":191,"estimatedTokens":1510}}781{"id":"stack-79202691","source":"stackoverflow","questionId":79202691,"title":"FastAPI inside docker stopped receiving any requests after a while","tags":["docker","fastapi"],"text":"Title: FastAPI inside docker stopped receiving any requests after a while\nTags: docker, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have a FastAPI app running inside docker which is deployed using portainer. Works fine after a few minutes but then suddenly it stops receiving any requests. I don't see any requests in the logs, instead when doing curl on the docker bridge port, it just simply forever hangs.\n\nThe portainer setup is basic, with only randomized port mappings.\n\n```\nFROM python:3.10-slim\n\nENV PYTHONDONTWRITEBYTECODE 1\nENV PYTHONUNBUFFERED 1\nENV POETRY_VERSION=1.8.2\n\nWORKDIR /app\n\nRUN apt-get update && apt-get install -y \\\n curl \\\n build-essential \\\n postgresql-client \\\n libpq-dev \\\n ca-certificates \\\n && rm -rf /var/lib/apt/lists/*\n\nRUN curl -sSL https://install.python-poetry.org | python3 -\n\nENV PATH=\"${PATH}:/root/.local/bin\"\n\nRUN mkdir -p $HOME/.postgresql\n\nRUN curl --create-dirs -o $HOME/.postgresql/root.crt 'https://cockroachlabs.cloud/clusters/.../cert'\n\nCOPY pyproject.toml poetry.lock* ./\n\nRUN poetry config virtualenvs.create false \\\n && poetry install --no-interaction --no-ansi\n\nCOPY . .\n\nEXPOSE 8121\n\nCMD [\"uvicorn\", \"main:app\", \"--host\", \"0.0.0.0\", \"--port\", \"8121\"]\n```\n\nThe project is also splinted into a module.\n\n**main**.py file looks like this\n\n```\nimport secrets\nfrom datetime import datetime\nfrom typing import List\n\nimport fastapi\nimport uvicorn\nfrom fastapi import Depends, HTTPException, Security\nfrom fastapi.security import APIKeyHeader\n\nfrom gpt_proxy.utils import mask_token\n\nfrom .config import ADMIN_KEY, log\nfrom .db import USERS, add_user, db_close, db_init, del_user\nfrom .firebase_manager import Firebase\nfrom .models import TokenCreate, TokenResponse, UserToken\nfrom .openai_forward import OpenAiForward\n\napp = fastapi.FastAPI()\nforwarder = OpenAiForward()\napi_key_header = APIKeyHeader(name=\"X-Admin-Key\", auto_error=True)\n\ndef verify_admin_key(api_key: str = Security(api_key_header)):\n if api_key != ADMIN_KEY:\n raise HTTPException(status_code=403, detail=\"Invalid admin key\")\n return api_key\n\n@app.on_event(\"startup\")\nasync def startup():\n log.info(\"Starting up OpenAI Forward application\")\n await db_init()\n log.info(\"Application startup complete\")\n\n@app.on_event(\"shutdown\")\nasync def shutdown():\n log.info(\"Shutting down OpenAI Forward application\")\n if forwarder.client:\n await forwarder.client.close()\n await db_close()\n log.info(\"Application shutdown complete\")\n\n@app.post(\"/tokens\", response_model=TokenResponse)\nasync def create_token(\n token_request: TokenCreate, api_key: str = Depends(verify_admin_key)\n):\n new_token = f\"mn-{secrets.token_urlsafe(32)}\"\n return await add_user(username=token_request.username, token=new_token)\n\n@app.delete(\"/tokens/{username}\")\nasync def delete_token(username: str, api_key: str = Depends(verify_admin_key)):\n await del_user(username)\n return {\"message\": f\"Token for user {username} has been deleted\"}\n\n@app.get(\"/tokens\", response_model=List[UserToken])\nasync def list_users(api_key: str = Depends(verify_admin_key)):\n users = []\n for user in USERS:\n user[\"token\"] = mask_token(user[\"token\"])\n users.append(user)\n return users\n\n@app.route(\n \"/{api_path:path}\",\n methods=[\"GET\", \"POST\", \"PUT\", \"DELETE\", \"OPTIONS\", \"HEAD\", \"PATCH\", \"TRACE\"],\n)\nasync def _handle_openai_request(request: fastapi.Request):\n return await forwarder.reverse_proxy(request)\n\nif __name__ == \"__main__\":\n log.info(\"Starting OpenAI Forward server\")\n uvicorn.run(app, host=\"0.0.0.0\", port=8010)\n```\n\nDatabase initialization:\n\n```\nimport time\n\nfrom tortoise import Tortoise\n\nfrom ..config import log\nfrom .models import FirebaseToken, User\n\nUSERS = []\n\nasync def _do_migration() -> None:\n old_users = {\n ....\n }\n\n for k, v in old_users.items():\n _ = await User.get_or_create(username=k, token=v, created_at=time.time())\n\nasync def _get_all_users() -> None:\n users = await User.all()\n if not users:\n await _do_migration()\n await _get_all_users()\n for user in users:\n USERS.append(dict(user))\n\nasync def db_init() -> None:\n await Tortoise.init(db_url=DB_URI, modules={\"models\": [\"gpt_proxy.db.models\"]})\n\n await Tortoise.generate_schemas()\n await _get_all_users()\n```\n\nOpenai forward class code. Not sure if this has any relevance since previous requests work just fine. So I'm thinking the blocking is somewhere else\n\n```\nimport asyncio\nimport time\nfrom functools import wraps\nfrom typing import Any, AsyncGenerator, Callable, Tuple, Type, TypeVar\n\nimport aiohttp\nimport anyio\nimport fastapi\nfrom fastapi import HTTPException\nfrom starlette.responses import BackgroundTask, StreamingResponse\n\nfrom .config import log\nfrom .firebase_manager import Firebase\nfrom .models import ClientConfig\nfrom .utils import get_token_user, header_cloudflare_safe, mask_token\n\nT = TypeVar(\"T\")\n\ndef async_retry(\n max_retries: int = 3,\n delay: float = 1.0,\n backoff: float = 2.0,\n exceptions: Tuple[Type[Exception], ...] = (Exception,),\n) -> Callable:\n def decorator(func: Callable[..., Any]) -> Callable[..., Any]:\n @wraps(func)\n async def wrapper(*args: Any, **kwargs: Any) -> T | None:\n current_delay = delay\n for attempt in range(max_retries + 1):\n try:\n if attempt > 0:\n log.info(\n f\"Retrying {func.__name__}, attempt {attempt}/{max_retries} \"\n f\"after {current_delay:.2f}s delay\"\n )\n await anyio.sleep(current_delay)\n current_delay *= backoff\n\n return await func(*args, **kwargs)\n\n except exceptions as e:\n log.warning(\n f\"Attempt {attempt + 1}/{max_retries + 1} failed for {func.__name__}: \"\n f\"{type(e).__name__}: {str(e)}\"\n )\n\n if attempt == max_retries:\n log.error(\n f\"All retry attempts failed for {func.__name__}. \"\n f\"Final exception: {type(e).__name__}: {str(e)}\"\n )\n raise\n\n return None\n\n return wrapper\n\n return decorator\n\nclass OpenAiForward:\n def __init__(self) -> None:\n log.info(\"Initializing OpenAI Forward\")\n self.base_url = \"https://api.openai.com/\"\n self.client: aiohttp.ClientSession | None = None\n self.firebase = Firebase()\n\n async def _init_client(self) -> None:\n if self.client is None:\n log.info(\"Initializing aiohttp client session\")\n tcp_connector = aiohttp.TCPConnector(\n limit=500, limit_per_host=0, force_close=False\n )\n self.client = aiohttp.ClientSession(connector=tcp_connector)\n log.info(\"aiohttp client session initialized\")\n\n async def _get_token(self, token: str):\n log.info(f\"Processing token {mask_token(token)}\")\n if token.startswith(\"mn-\"):\n username = await get_token_user(token)\n if not username:\n log.info(\"Using direct token\")\n return None, token\n fb_token = await self.firebase.get_token()\n return username, fb_token\n else:\n log.info(\"Using direct token\")\n return None, token\n\n async def iter_bytes(\n self, response: aiohttp.ClientResponse, request: fastapi.Request\n ) -> AsyncGenerator[bytes, Any]:\n log.info(f\"Streaming response for {request.url.path}\")\n async for chunk, _ in response.content.iter_chunks():\n yield chunk\n\n @async_retry(\n max_retries=3,\n delay=0.2,\n backoff=0.2,\n exceptions=(\n aiohttp.ServerTimeoutError,\n aiohttp.ServerConnectionError,\n aiohttp.ServerDisconnectedError,\n asyncio.TimeoutError,\n anyio.EndOfStream,\n RuntimeError,\n ),\n )\n async def send(\n self, client_config: ClientConfig, data: dict | None = None\n ) -> aiohttp.client.ClientRequest | Any | None:\n if not self.client:\n await self._init_client()\n\n log.info(f\"Sending {client_config.method} request to {client_config.url}\")\n if self.client:\n return await self.client.request(\n method=client_config.method,\n url=client_config.url,\n data=data,\n headers=client_config.headers,\n )\n return None\n\n async def prepare_config(self, request: fastapi.Request) -> ClientConfig:\n headers: dict = header_cloudflare_safe(request)\n original_bearer: str = headers.get(\n \"Authorization\", headers.get(\"authorization\")\n )\n\n if original_bearer:\n token: str = original_bearer.split()[-1].strip()\n user, replacement_token = await self._get_token(token)\n\n if replacement_token is None:\n raise HTTPException(status_code=401, detail=\"Invalid token\")\n\n auth_header = f\"Bearer {replacement_token}\"\n if \"Authorization\" in headers:\n headers[\"Authorization\"] = auth_header\n elif \"authorization\" in headers:\n headers[\"authorization\"] = auth_header\n\n log.info(\n f\"Token processing: User={user or 'direct'}, \"\n f\"Using={'Firebase' if user else 'direct'} token\"\n )\n\n url = f\"https://api.openai.com/{request.url.path}\"\n if request.url.query:\n url = f\"{url}?{request.url.query}\"\n\n return ClientConfig(\n headers=headers,\n method=request.method,\n url=url,\n )\n\n async def reverse_proxy(self, request: fastapi.Request) -> StreamingResponse:\n request_id = str(time.time())\n log.info(\n f\"[{request_id}] Incoming request: {request.method} {request.url.path}\"\n )\n\n config = await self.prepare_config(request)\n body = await request.body()\n data = body if body else None\n\n try:\n log.info(f\"[{request_id}] Forwarding request to OpenAI\")\n response = await self.send(config, data=data)\n log.info(f\"[{request_id}] OpenAI response received: {response.status}\")\n\n return StreamingResponse(\n self.iter_bytes(response, request),\n status_code=response.status,\n media_type=response.headers.get(\"content-type\"),\n background=BackgroundTask(response.release),\n )\n\n except aiohttp.ClientError as e:\n log.exception(f\"[{request_id}] Failed to forward request to OpenAI\")\n raise fastapi.HTTPException(\n status_code=fastapi.status.HTTP_502_BAD_GATEWAY,\n detail=f\"Failed to forward request: {str(e)}\",\n )\n except Exception as e:\n log.exception(f\"[{request_id}] Unexpected error during request forwarding\")\n raise fastapi.HTTPException(\n status_code=fastapi.status.HTTP_500_INTERNAL_SERVER_ERROR,\n detail=f\"Internal server error: {str(e)}\",\n )\n```\n\n========================================\n\nCode:\n```text\nFROM python:3.10-slim\n\nENV PYTHONDONTWRITEBYTECODE 1\nENV PYTHONUNBUFFERED 1\nENV POETRY_VERSION=1.8.2\n\nWORKDIR /app\n\nRUN apt-get update && apt-get install -y \\\n curl \\\n build-essential \\\n postgresql-client \\\n libpq-dev \\\n ca-certificates \\\n && rm -rf /var/lib/apt/lists/*\n\nRUN curl -sSL https://install.python-poetry.org | python3 -\n\nENV PATH=\"${PATH}:/root/.local/bin\"\n\nRUN mkdir -p $HOME/.postgresql\n\nRUN curl --create-dirs -o $HOME/.postgresql/root.crt 'https://cockroachlabs.cloud/clusters/.../cert'\n\nCOPY pyproject.toml poetry.lock* ./\n\nRUN poetry config virtualenvs.create false \\\n && poetry install --no-interaction --no-ansi\n\nCOPY . .\n\nEXPOSE 8121\n\nCMD [\"uvicorn\", \"main:app\", \"--host\", \"0.0.0.0\", \"--port\", \"8121\"]\n```\n\n```text\nimport secrets\nfrom datetime import datetime\nfrom typing import List\n\nimport fastapi\nimport uvicorn\nfrom fastapi import Depends, HTTPException, Security\nfrom fastapi.security import APIKeyHeader\n\nfrom gpt_proxy.utils import mask_token\n\nfrom .config import ADMIN_KEY, log\nfrom .db import USERS, add_user, db_close, db_init, del_user\nfrom .firebase_manager import Firebase\nfrom .models import TokenCreate, TokenResponse, UserToken\nfrom .openai_forward import OpenAiForward\n\napp = fastapi.FastAPI()\nforwarder = OpenAiForward()\napi_key_header = APIKeyHeader(name=\"X-Admin-Key\", auto_error=True)\n\n\ndef verify_admin_key(api_key: str = Security(api_key_header)):\n if api_key != ADMIN_KEY:\n raise HTTPException(status_code=403, detail=\"Invalid admin key\")\n return api_key\n\n\n@app.on_event(\"startup\")\nasync def startup():\n log.info(\"Starting up OpenAI Forward application\")\n await db_init()\n log.info(\"Application startup complete\")\n\n\n@app.on_event(\"shutdown\")\nasync def shutdown():\n log.info(\"Shutting down OpenAI Forward application\")\n if forwarder.client:\n await forwarder.client.close()\n await db_close()\n log.info(\"Application shutdown complete\")\n\n\n@app.post(\"/tokens\", response_model=TokenResponse)\nasync def create_token(\n token_request: TokenCreate, api_key: str = Depends(verify_admin_key)\n):\n new_token = f\"mn-{secrets.token_urlsafe(32)}\"\n return await add_user(username=token_request.username, token=new_token)\n\n\n@app.delete(\"/tokens/{username}\")\nasync def delete_token(username: str, api_key: str = Depends(verify_admin_key)):\n await del_user(username)\n return {\"message\": f\"Token for user {username} has been deleted\"}\n\n\n@app.get(\"/tokens\", response_model=List[UserToken])\nasync def list_users(api_key: str = Depends(verify_admin_key)):\n users = []\n for user in USERS:\n user[\"token\"] = mask_token(user[\"token\"])\n users.append(user)\n return users\n\n\n@app.route(\n \"/{api_path:path}\",\n methods=[\"GET\", \"POST\", \"PUT\", \"DELETE\", \"OPTIONS\", \"HEAD\", \"PATCH\", \"TRACE\"],\n)\nasync def _handle_openai_request(request: fastapi.Request):\n return await forwarder.reverse_proxy(request)\n\n\nif __name__ == \"__main__\":\n log.info(\"Starting OpenAI Forward server\")\n uvicorn.run(app, host=\"0.0.0.0\", port=8010)\n```\n\n```text\nimport time\n\nfrom tortoise import Tortoise\n\nfrom ..config import log\nfrom .models import FirebaseToken, User\n\nUSERS = []\n\n\nasync def _do_migration() -> None:\n old_users = {\n ....\n }\n\n for k, v in old_users.items():\n _ = await User.get_or_create(username=k, token=v, created_at=time.time())\n\n\nasync def _get_all_users() -> None:\n users = await User.all()\n if not users:\n await _do_migration()\n await _get_all_users()\n for user in users:\n USERS.append(dict(user))\n\n\nasync def db_init() -> None:\n await Tortoise.init(db_url=DB_URI, modules={\"models\": [\"gpt_proxy.db.models\"]})\n\n await Tortoise.generate_schemas()\n await _get_all_users()\n```\n\n```text\nimport asyncio\nimport time\nfrom functools import wraps\nfrom typing import Any, AsyncGenerator, Callable, Tuple, Type, TypeVar\n\nimport aiohttp\nimport anyio\nimport fastapi\nfrom fastapi import HTTPException\nfrom starlette.responses import BackgroundTask, StreamingResponse\n\nfrom .config import log\nfrom .firebase_manager import Firebase\nfrom .models import ClientConfig\nfrom .utils import get_token_user, header_cloudflare_safe, mask_token\n\nT = TypeVar(\"T\")\n\n\ndef async_retry(\n max_retries: int = 3,\n delay: float = 1.0,\n backoff: float = 2.0,\n exceptions: Tuple[Type[Exception], ...] = (Exception,),\n) -> Callable:\n def decorator(func: Callable[..., Any]) -> Callable[..., Any]:\n @wraps(func)\n async def wrapper(*args: Any, **kwargs: Any) -> T | None:\n current_delay = delay\n for attempt in range(max_retries + 1):\n try:\n if attempt > 0:\n log.info(\n f\"Retrying {func.__name__}, attempt {attempt}/{max_retries} \"\n f\"after {current_delay:.2f}s delay\"\n )\n await anyio.sleep(current_delay)\n current_delay *= backoff\n\n return await func(*args, **kwargs)\n\n except exceptions as e:\n log.warning(\n f\"Attempt {attempt + 1}/{max_retries + 1} failed for {func.__name__}: \"\n f\"{type(e).__name__}: {str(e)}\"\n )\n\n if attempt == max_retries:\n log.error(\n f\"All retry attempts failed for {func.__name__}. \"\n f\"Final exception: {type(e).__name__}: {str(e)}\"\n )\n raise\n\n return None\n\n return wrapper\n\n return decorator\n\n\nclass OpenAiForward:\n def __init__(self) -> None:\n log.info(\"Initializing OpenAI Forward\")\n self.base_url = \"https://api.openai.com/\"\n self.client: aiohttp.ClientSession | None = None\n self.firebase = Firebase()\n\n async def _init_client(self) -> None:\n if self.client is None:\n log.info(\"Initializing aiohttp client session\")\n tcp_connector = aiohttp.TCPConnector(\n limit=500, limit_per_host=0, force_close=False\n )\n self.client = aiohttp.ClientSession(connector=tcp_connector)\n log.info(\"aiohttp client session initialized\")\n\n async def _get_token(self, token: str):\n log.info(f\"Processing token {mask_token(token)}\")\n if token.startswith(\"mn-\"):\n username = await get_token_user(token)\n if not username:\n log.info(\"Using direct token\")\n return None, token\n fb_token = await self.firebase.get_token()\n return username, fb_token\n else:\n log.info(\"Using direct token\")\n return None, token\n\n async def iter_bytes(\n self, response: aiohttp.ClientResponse, request: fastapi.Request\n ) -> AsyncGenerator[bytes, Any]:\n log.info(f\"Streaming response for {request.url.path}\")\n async for chunk, _ in response.content.iter_chunks():\n yield chunk\n\n @async_retry(\n max_retries=3,\n delay=0.2,\n backoff=0.2,\n exceptions=(\n aiohttp.ServerTimeoutError,\n aiohttp.ServerConnectionError,\n aiohttp.ServerDisconnectedError,\n asyncio.TimeoutError,\n anyio.EndOfStream,\n RuntimeError,\n ),\n )\n async def send(\n self, client_config: ClientConfig, data: dict | None = None\n ) -> aiohttp.client.ClientRequest | Any | None:\n if not self.client:\n await self._init_client()\n\n log.info(f\"Sending {client_config.method} request to {client_config.url}\")\n if self.client:\n return await self.client.request(\n method=client_config.method,\n url=client_config.url,\n data=data,\n headers=client_config.headers,\n )\n return None\n\n async def prepare_config(self, request: fastapi.Request) -> ClientConfig:\n headers: dict = header_cloudflare_safe(request)\n original_bearer: str = headers.get(\n \"Authorization\", headers.get(\"authorization\")\n )\n\n if original_bearer:\n token: str = original_bearer.split()[-1].strip()\n user, replacement_token = await self._get_token(token)\n\n if replacement_token is None:\n raise HTTPException(status_code=401, detail=\"Invalid token\")\n\n auth_header = f\"Bearer {replacement_token}\"\n if \"Authorization\" in headers:\n headers[\"Authorization\"] = auth_header\n elif \"authorization\" in headers:\n headers[\"authorization\"] = auth_header\n\n log.info(\n f\"Token processing: User={user or 'direct'}, \"\n f\"Using={'Firebase' if user else 'direct'} token\"\n )\n\n url = f\"https://api.openai.com/{request.url.path}\"\n if request.url.query:\n url = f\"{url}?{request.url.query}\"\n\n return ClientConfig(\n headers=headers,\n method=request.method,\n url=url,\n )\n\n async def reverse_proxy(self, request: fastapi.Request) -> StreamingResponse:\n request_id = str(time.time())\n log.info(\n f\"[{request_id}] Incoming request: {request.method} {request.url.path}\"\n )\n\n config = await self.prepare_config(request)\n body = await request.body()\n data = body if body else None\n\n try:\n log.info(f\"[{request_id}] Forwarding request to OpenAI\")\n response = await self.send(config, data=data)\n log.info(f\"[{request_id}] OpenAI response received: {response.status}\")\n\n return StreamingResponse(\n self.iter_bytes(response, request),\n status_code=response.status,\n media_type=response.headers.get(\"content-type\"),\n background=BackgroundTask(response.release),\n )\n\n except aiohttp.ClientError as e:\n log.exception(f\"[{request_id}] Failed to forward request to OpenAI\")\n raise fastapi.HTTPException(\n status_code=fastapi.status.HTTP_502_BAD_GATEWAY,\n detail=f\"Failed to forward request: {str(e)}\",\n )\n except Exception as e:\n log.exception(f\"[{request_id}] Unexpected error during request forwarding\")\n raise fastapi.HTTPException(\n status_code=fastapi.status.HTTP_500_INTERNAL_SERVER_ERROR,\n detail=f\"Internal server error: {str(e)}\",\n )\n```\n\n```text\nFROM python:3.10-slim\n\nENV PYTHONDONTWRITEBYTECODE 1\nENV PYTHONUNBUFFERED 1\nENV POETRY_VERSION=1.8.2\n\nWORKDIR /app\n\nRUN apt-get update && apt-get install -y \\\n curl \\\n build-essential \\\n postgresql-client \\\n libpq-dev \\\n ca-certificates \\\n && rm -rf /var/lib/apt/lists/*\n\nRUN curl -sSL https://install.python-poetry.org | python3 -\n\nENV PATH=\"${PATH}:/root/.local/bin\"\n\nRUN mkdir -p $HOME/.postgresql\n\nRUN curl --create-dirs -o $HOME/.postgresql/root.crt 'https://cockroachlabs.cloud/clusters/1234/cert'\n\nCOPY pyproject.toml poetry.lock* ./\n\nRUN poetry config virtualenvs.create false \\\n && poetry install --no-interaction --no-ansi\n\nCOPY . .\n\nEXPOSE 8121\n\nCMD [\"fastapi\", \"run\", \"main\", \"--port\", \"8121\", \"--workers\", \"3\"]\n```\n\n========================================\n\nComments:\n- Please extract a minimal reproducible example, which should answer whether the PostgreSQL DB has any influence on that, for example.\n- @UlrichEckhardt right. I've included more details\n- Attaching some sort of debugger that allows you to see exactly what code the python interpreter is currently running could be helpful: stackoverflow.com/questions/25308847/… - I'd also advice having a few log statments on your happy path so that you can see when requests succeed - it might be helpful to discover where the deadlock happens.\n- @MatsLindh thanks for the hint. Anyway I've went through a refractory and the problem seems to be gone. No idea what fixed it. Either because I launched the web app with the built-in fastapi command or that I specified a count of 3 workers.\n- Consider marking the question as answered\n- @LukeWorth 2 hours left xD","metadata":{"transformedAt":"2026-08-18T18:32:29.165Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":755,"estimatedTokens":5489}}782{"id":"stack-77848941","source":"stackoverflow","questionId":77848941,"title":"How To use numpy.frombuffer to read a file sent using FastAPI?","tags":["python","numpy","fastapi"],"text":"Title: How To use numpy.frombuffer to read a file sent using FastAPI?\nTags: python, numpy, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm trying to read data from a text file sent to my API built using fastapi. The files template is always the same and consists of three columns of numbers as shown in the picture below:\n\nI tried solving the problem with the following code using numpy:\n\n```\n@app.post(\"/uploadfile/\")\nasync def create_upload_file(file: UploadFile):\n \n file_data = await file.read()\n \n print(len(file_data))\n print(file_data)\n \n deserialized_bytes = np.frombuffer(file_data,float)\n print(deserialized_bytes)\n```\n\nI got the following error:\n\nValueError: buffer size must be a multiple of element size\n\nWhen printing `file_data` I got the following:\n\n```\nb'0.01\\t1.008298628\\t-0.007582043\\n0.012589254\\t1.007411741\\t-0.008969602\\n0.015848932\\t1.00632129\\t-0.010491102\\n0.019952623\\t1.005019534\\t-0.012152029\\n0.025118864\\t1.00349648\\t-0.013967763\\n0.031622777\\t1.001734774\\t-0.015961535\\n0.039810717\\t0.999706432\\t-0.018160753\\n0.050118723\\t0.997371077\\t-0.020592808\\n0.063095734\\t0.994675168\\t-0.023280535\\n0.079432823\\t0.991552108\\t-0.026237042\\n0.1\\t0.987923699\\t-0.029459556\\n0.125892541\\t0.983703902\\t-0.032922359\\n0.158489319\\t0.978806153\\t-0.036569606\\n0.199526231\\t0.973155266\\t-0.040309894\\n0.251188643\\t0.96670398\\t-0.044015666\\n0.316227766\\t0.959452052\\t-0.047531126\\n0.398107171\\t0.95146288\\t-0.050691362\\n0.501187234\\t0.942870343\\t-0.05335184\\n0.630957344\\t0.933869168\\t-0.055422075\\n0.794328235\\t0.924687135\\t-0.056892752\\n1\\t0.915545303\\t-0.057845825\\n1.258925412\\t0.906618399\\t-0.058443323\\n1.584893192\\t0.898007292\\t-0.05889944\\n1.995262315\\t0.88972925\\t-0.05944639\\n2.511886432\\t0.88172395\\t-0.060304263\\n3.16227766\\t0.873868464\\t-0.06166047\\n3.981071706\\t0.865994233\\t-0.063658897\\n5.011872336\\t0.857901613\\t-0.066395558\\n6.309573445\\t0.849370763\\t-0.069916657\\n7.943282347\\t0.840170081\\t-0.074215864\\n10\\t0.830064778\\t-0.079229225\\n12.58925412\\t0.818828635\\t-0.084828018\\n15.84893192\\t0.80626166\\t-0.090811856\\n19.95262315\\t0.792215036\\t-0.09690624\\n25.11886432\\t0.776622119\\t-0.102770212\\n31.6227766\\t0.759530416\\t-0.10801952\\n39.81071706\\t0.741125379\\t-0.112267806\\n50.11872336\\t0.7217348\\t-0.115182125\\n63.09573445\\t0.701805205\\t-0.116541504\\n79.43282347\\t0.681849867\\t-0.116282042\\n100\\t0.662379027\\t-0.114513698\\n125.8925412\\t0.643830642\\t-0.111502997\\n158.4893192\\t0.626519742\\t-0.107628211\\n199.5262315\\t0.61061625\\t-0.103322294\\n251.1886432\\t0.596150187\\t-0.099019949\\n316.227766\\t0.583035191\\t-0.095119782\\n398.1071706\\t0.571098913\\t-0.091964781\\n501.1872336\\t0.560111017\\t-0.089838356\\n630.9573445\\t0.549803457\\t-0.08897027\\n794.3282347\\t0.539881289\\t-0.089546481\\n1000\\t0.530024653\\t-0.091717904\\n1258.925412\\t0.519883761\\t-0.095604233\\n1584.893192\\t0.509069473\\t-0.101289726\\n1995.262315\\t0.497142868\\t-0.10880829\\n2511.886432\\t0.48360875\\t-0.118115658\\n3162.27766\\t0.4679204\\t-0.12904786\\n3981.071706\\t0.449505702\\t-0.141268753\\n5011.872336\\t0.427826294\\t-0.154216509\\n6309.573445\\t0.402477916\\t-0.167069625\\n7943.282347\\t0.373326923\\t-0.17876369\\n10000\\t0.340652906\\t-0.188091157\\n12589.25412\\t0.305239137\\t-0.193894836\\n15848.93192\\t0.268343956\\t-0.195318306\\n19952.62315\\t0.231521442\\t-0.192025496\\n25118.86432\\t0.196333603\\t-0.184290646\\n31622.7766\\t0.164060493\\t-0.17291366\\n39810.71706\\t0.135516045\\t-0.15900294\\n50118.72336\\t0.111014755\\t-0.143723646\\n63095.73445\\t0.090459787\\t-0.128100619\\n79432.82347\\t0.073486071\\t-0.11291483\\n100000\\t0.059599333\\t-0.098684088\\n125892.5412\\t0.04827997\\t-0.085696257\\n158489.3192\\t0.03904605\\t-0.074063717\\n199526.2315\\t0.031483308\\t-0.063778419\\n251188.6432\\t0.025253597\\t-0.054757832\\n316227.766\\t0.020091636\\t-0.046879426\\n398107.1706\\t0.01579663\\t-0.040005154\\n501187.2336\\t0.012222187\\t-0.033998672\\n630957.3445\\t0.009265484\\t-0.028737822\\n794328.2347\\t0.006855045\\t-0.024123472\\n1000000\\t0.00493654\\t-0.020083713\\n'\n```\n\nand the length of `file_data` is 2897 which doesn't divide by 8 as it should.\n\nThinking that the problem originated from the Tab's and NewLine commands in the file, I tried removing the newLines, and replacing the tabs with spaces but I ended getting different numbers than the ones in the file.\n\nI don't quite understand how to convert `file_data` from bytes to a numpy array using the numpy library and not an entire function of my own which would be possible but much more complicated.\n\nWhat would be the right way to read the data into an array? If you can help me find a quick way to insert each column into a separate array automatically with no additional loop that would be great.\n\n========================================\n\nCode:\n```text\n@app.post(\"/uploadfile/\")\nasync def create_upload_file(file: UploadFile):\n \n file_data = await file.read()\n \n print(len(file_data))\n print(file_data)\n \n deserialized_bytes = np.frombuffer(file_data,float)\n print(deserialized_bytes)\n```\n\n```none\nb'0.01\\t1.008298628\\t-0.007582043\\n0.012589254\\t1.007411741\\t-0.008969602\\n0.015848932\\t1.00632129\\t-0.010491102\\n0.019952623\\t1.005019534\\t-0.012152029\\n0.025118864\\t1.00349648\\t-0.013967763\\n0.031622777\\t1.001734774\\t-0.015961535\\n0.039810717\\t0.999706432\\t-0.018160753\\n0.050118723\\t0.997371077\\t-0.020592808\\n0.063095734\\t0.994675168\\t-0.023280535\\n0.079432823\\t0.991552108\\t-0.026237042\\n0.1\\t0.987923699\\t-0.029459556\\n0.125892541\\t0.983703902\\t-0.032922359\\n0.158489319\\t0.978806153\\t-0.036569606\\n0.199526231\\t0.973155266\\t-0.040309894\\n0.251188643\\t0.96670398\\t-0.044015666\\n0.316227766\\t0.959452052\\t-0.047531126\\n0.398107171\\t0.95146288\\t-0.050691362\\n0.501187234\\t0.942870343\\t-0.05335184\\n0.630957344\\t0.933869168\\t-0.055422075\\n0.794328235\\t0.924687135\\t-0.056892752\\n1\\t0.915545303\\t-0.057845825\\n1.258925412\\t0.906618399\\t-0.058443323\\n1.584893192\\t0.898007292\\t-0.05889944\\n1.995262315\\t0.88972925\\t-0.05944639\\n2.511886432\\t0.88172395\\t-0.060304263\\n3.16227766\\t0.873868464\\t-0.06166047\\n3.981071706\\t0.865994233\\t-0.063658897\\n5.011872336\\t0.857901613\\t-0.066395558\\n6.309573445\\t0.849370763\\t-0.069916657\\n7.943282347\\t0.840170081\\t-0.074215864\\n10\\t0.830064778\\t-0.079229225\\n12.58925412\\t0.818828635\\t-0.084828018\\n15.84893192\\t0.80626166\\t-0.090811856\\n19.95262315\\t0.792215036\\t-0.09690624\\n25.11886432\\t0.776622119\\t-0.102770212\\n31.6227766\\t0.759530416\\t-0.10801952\\n39.81071706\\t0.741125379\\t-0.112267806\\n50.11872336\\t0.7217348\\t-0.115182125\\n63.09573445\\t0.701805205\\t-0.116541504\\n79.43282347\\t0.681849867\\t-0.116282042\\n100\\t0.662379027\\t-0.114513698\\n125.8925412\\t0.643830642\\t-0.111502997\\n158.4893192\\t0.626519742\\t-0.107628211\\n199.5262315\\t0.61061625\\t-0.103322294\\n251.1886432\\t0.596150187\\t-0.099019949\\n316.227766\\t0.583035191\\t-0.095119782\\n398.1071706\\t0.571098913\\t-0.091964781\\n501.1872336\\t0.560111017\\t-0.089838356\\n630.9573445\\t0.549803457\\t-0.08897027\\n794.3282347\\t0.539881289\\t-0.089546481\\n1000\\t0.530024653\\t-0.091717904\\n1258.925412\\t0.519883761\\t-0.095604233\\n1584.893192\\t0.509069473\\t-0.101289726\\n1995.262315\\t0.497142868\\t-0.10880829\\n2511.886432\\t0.48360875\\t-0.118115658\\n3162.27766\\t0.4679204\\t-0.12904786\\n3981.071706\\t0.449505702\\t-0.141268753\\n5011.872336\\t0.427826294\\t-0.154216509\\n6309.573445\\t0.402477916\\t-0.167069625\\n7943.282347\\t0.373326923\\t-0.17876369\\n10000\\t0.340652906\\t-0.188091157\\n12589.25412\\t0.305239137\\t-0.193894836\\n15848.93192\\t0.268343956\\t-0.195318306\\n19952.62315\\t0.231521442\\t-0.192025496\\n25118.86432\\t0.196333603\\t-0.184290646\\n31622.7766\\t0.164060493\\t-0.17291366\\n39810.71706\\t0.135516045\\t-0.15900294\\n50118.72336\\t0.111014755\\t-0.143723646\\n63095.73445\\t0.090459787\\t-0.128100619\\n79432.82347\\t0.073486071\\t-0.11291483\\n100000\\t0.059599333\\t-0.098684088\\n125892.5412\\t0.04827997\\t-0.085696257\\n158489.3192\\t0.03904605\\t-0.074063717\\n199526.2315\\t0.031483308\\t-0.063778419\\n251188.6432\\t0.025253597\\t-0.054757832\\n316227.766\\t0.020091636\\t-0.046879426\\n398107.1706\\t0.01579663\\t-0.040005154\\n501187.2336\\t0.012222187\\t-0.033998672\\n630957.3445\\t0.009265484\\t-0.028737822\\n794328.2347\\t0.006855045\\t-0.024123472\\n1000000\\t0.00493654\\t-0.020083713\\n'\n```\n\n```text\nfile_data\n```\n\n```text\nfile_data\n```\n\n```text\nfile_data\n```\n\n```text\nnp.frombuffer(b'\\x00\\x01\\x02\\x03', dtype=np.uint8)\n# → array([0,1,2,3], dtype=uint8)\n# because each byte is the representation of 1 uint8 integer\n\nnp.frombuffer(b'\\x00\\x01\\x02\\x03', dtype=np.uint16)\n# → array([256,770], dtype=uint16) on my machine\n# because each pairs of bytes make the 16 bits of a uint16 16 bits integer\n# 0 1, 00000000 00000001 in binary, with a little endian machine\n# is 00000001 00000000 in binary = 256 in decimal.\n# (on a big endian machine it would have been 1)\n# then 2=00000010 3=00000011. So on my little endian machine that is\n# 00000011 00000010 = 512+256+2 = 770\n# on a big endian machine, that would have been 00000010 00000011 = 512+2+1=515\n```\n\n```text\ndeserialized_bytes = np.loadtxt(file_data.split(b'\\n'))\n```\n\n```text\nfrombuffer\n```\n\n```text\nfrombuffer\n```\n\n```text\n.tobytes()\n```\n\n```text\nnp.array([256,770]).tobytes() = b'\\x00\\x01\\x02\\x03'\n```\n\n```text\nfwrite\n```\n\n```text\nfloat *\n```\n\n```text\nnp.float32\n```\n\n```text\n.frombuffer\n```\n\n```text\n.frombuffer\n```\n\n```text\nuint16\n```\n\n```text\nfloat64\n```\n\n```text\n\\t\n```\n\n```text\n\\n\n```\n\n```text\ntsv\n```\n\n```text\nnumpy.loadtxt\n```\n\n```text\nfile_data\n```\n\n```text\nb'\\n'\n```\n\n```text\nnp.loadtxt\n```\n\n========================================\n\nComments:\n- Have you tried a `csv` reader?\n- That doesn't look like bytes. It is multiline text with tab delimiter.\n- Hey hpaulj, I haven't because I'm trying to use fastapi's UploadFile that they recommend\n- I also thought it doesn't look like bytes, but it starts with the prefix b'.\n- that would be bytestring, one byte per character.\n- @swolfy Please have a look at this answer, as well as this answer and this answer","metadata":{"transformedAt":"2026-08-18T18:32:29.165Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":25,"totalLines":173,"estimatedTokens":2451}}783{"id":"stack-77854089","source":"stackoverflow","questionId":77854089,"title":"How to unify the response format in FastAPI while preserving Pydantic data models?","tags":["python","sqlalchemy","fastapi","swagger-ui","pydantic"],"text":"Title: How to unify the response format in FastAPI while preserving Pydantic data models?\nTags: python, sqlalchemy, fastapi, swagger-ui, pydantic\nSource: Stack Overflow\n\nQuestion:\nIn FastAPI, I am using SQLAlchemy and Pydantic to return data.\n\n```\n@router.get(\"/1\", response_model=User)\ndef read_user(db: Session = Depends(get_db)):\ndb_user = user_module.get_user(db, user_id=\"1\")\nif db_user is None:\nraise HTTPException(status_code=404, detail=\"User not found\")\nreturn db_user\n```\n\nThis approach helps me standardize the returned model, but I want to unify the response format for all APIs to `{\"code\": 0, \"msg\": \"success\", \"data\": {...}}`, so that the User model from the original return model is placed within the \"data\" field, making it easier for frontend management.\n\nI attempted to use FastAPI middleware for implementation, but it doesn't recognize the User return model in Swagger and other documentation. If I redefine a generic Pydantic return model with nested models, I cannot manipulate the SQLAlchemy returned data model into the desired User model.\n\nIs there any way to solve my requirement or are there any better solutions?\n\nTo unify the response format in FastAPI to`{\"code\": 0, \"msg\": \"success\", \"data\": {...}}`, while preserving Pydantic data models and ensuring proper recognition in Swagger and other documentation.\n\n========================================\n\nCode:\n```text\n@router.get(\"/1\", response_model=User)\ndef read_user(db: Session = Depends(get_db)):\ndb_user = user_module.get_user(db, user_id=\"1\")\nif db_user is None:\nraise HTTPException(status_code=404, detail=\"User not found\")\nreturn db_user\n```\n\n```text\n{\"code\": 0, \"msg\": \"success\", \"data\": {...}}\n```\n\n```text\n{\"code\": 0, \"msg\": \"success\", \"data\": {...}}\n```\n\n```text\nfrom pydantic import BaseModel, Field\nfrom typing import Generic, TypeVar, Type, Optional\nfrom fastapi import Depends, HTTPException, APIRouter\nfrom sqlalchemy.orm import Session\n\nT = TypeVar('T')\n\nclass GenericResponse(BaseModel, Generic[T]):\n code: int = Field(default=0, example=0)\n msg: str = Field(default=\"success\", example=\"success\")\n data: Optional[T]\n\nrouter = APIRouter()\n\n@router.get(\"/1\", response_model=GenericResponse[User])\ndef read_user(db: Session = Depends(get_db)):\n db_user = user_module.get_user(db, user_id=\"1\")\n if db_user is None:\n raise HTTPException(status_code=404, detail=\"User not found\")\n return GenericResponse(data=db_user)\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.165Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":66,"estimatedTokens":610}}784{"id":"stack-79422061","source":"stackoverflow","questionId":79422061,"title":"Problem with FastAPI, Pydantic, and kebab-case header fields","tags":["python","fastapi","openapi","swagger-ui","pydantic"],"text":"Title: Problem with FastAPI, Pydantic, and kebab-case header fields\nTags: python, fastapi, openapi, swagger-ui, pydantic\nSource: Stack Overflow\n\nQuestion:\nIn my FastAPI project, if I create a common header definition with Pydantic, I find that kebab-case header fields aren't behaving as expected. The \"magic\" conversion from kebab-case header fields in the request to their snake_case counterparts is not working, in addition to inconsistencies in the generated Swagger docs.\n\nWhat is the right way to specify this Pydantic header class so that the Swagger docs and behavior match?\n\nHere's a minimal reproduction of the problem:\n\n```\n### main.py\n\nfrom typing import Annotated\nfrom fastapi import FastAPI, Header\nfrom pydantic import BaseModel, Field\n\napp = FastAPI()\n\nclass CommonHeaders(BaseModel):\n simpleheader: str\n a_kebab_header: str | None = Field(\n default=None,\n title=\"a-kebab-header\",\n alias=\"a-kebab-header\",\n description=\"This is a header that should be specified as `a-kebab-header`\",\n )\n\n@app.get(\"/\")\ndef root_endpoint(\n headers: Annotated[CommonHeaders, Header()],\n):\n result = {\"headers received\": headers}\n return result\n```\n\nIf I run this and look at the Swagger docs at http://localhost:8000/docs I see this, which looks correct:\n\nhttps://i.sstatic.net/oTz6jFuA.png\n\nAnd if I \"try it out\" it will generate what I would expect as the correct request:\n\n```\ncurl -X 'GET' \\\n 'http://localhost:8000/' \\\n -H 'accept: application/json' \\\n -H 'simpleheader: foo' \\\n -H 'a-kebab-header: bar'\n```\n\nBut in the response, it becomes clear it did not correctly receive the kebab-case header:\n\n```\n{\n \"headers received\": {\n \"simpleheader\": \"foo\",\n \"a-kebab-header\": null\n }\n}\n```\n\nChanging the header name to snake_case \"a_kebab_header\" in the request does not work, either.\n\nUpdating the header definition to look like this doesn't work as expected, either. The Swagger docs and actual behavior are inconsistent.\n\n```\nclass CommonHeaders(BaseModel):\n simpleheader: str\n a_kebab_header: str | None = Field(\n default=None,\n description=\"This is a header that should be specified as `a-kebab-header`\",\n )\n```\n\nNotice this now results in the Swagger docs specifying it in snake_case:\n\nhttps://i.sstatic.net/bZyY08bU.png\n\nAnd using \"try it out\" results in the snake_case variant:\n\n```\ncurl -X 'GET' \\\n 'http://localhost:8000/' \\\n -H 'accept: application/json' \\\n -H 'simpleheader: foo' \\\n -H 'a_kebab_header: bar'\n```\n\nBut SURPRISINGLY this doesn't work! The response:\n\n```\n{\n \"headers received\": {\n \"simpleheader\": \"foo\",\n \"a_kebab_header\": null\n }\n}\n```\n\nBut in a SURPRISE ENDING, if I manually re-write the request in kebab-case:\n\n```\ncurl -X 'GET' \\\n 'http://localhost:8000/' \\\n -H 'accept: application/json' \\\n -H 'simpleheader: foo' \\\n -H 'a-kebab-header: bar'\n```\n\nit finally picks up that header value via the magic translation and I get the desired results back:\n\n```\n{\"headers received\":{\"simpleheader\":\"foo\",\"a_kebab_header\":\"bar\"}}\n```\n\n**What is the right way to specify this Pydantic header class so that the Swagger docs and behavior match?** If the docs are inconsistent with behavior I'm going to get hassled.\n\nAs a final thought: the following way works correctly in both the OpenAPI documentation and in the application (displaying and working as kebab-case), BUT it doesn't use Pydantic and so I lose the ability to define and use a common header structure easily across my project, and instead need to declare them individually for each endpoint:\n\n```\n\"\"\"Alternative version without Pydantic.\"\"\"\nfrom typing import Annotated\nfrom fastapi import FastAPI, Header\n\napp = FastAPI()\n\n@app.get(\"/\")\ndef root_endpoint(\n simpleheader: Annotated[str, Header()],\n a_kebab_header: Annotated[\n str | None,\n Header(\n title=\"a-kebab-header\",\n description=\"This is a header that should be specified as `a-kebab-header`\",\n ),\n ] = None,\n):\n result = {\n \"headers received\": {\n \"simpleheader\": simpleheader,\n \"a_kebab_header\": a_kebab_header,\n }\n }\n return result\n```\n\n========================================\n\nCode:\n```py\n### main.py\n\nfrom typing import Annotated\nfrom fastapi import FastAPI, Header\nfrom pydantic import BaseModel, Field\n\napp = FastAPI()\n\n\nclass CommonHeaders(BaseModel):\n simpleheader: str\n a_kebab_header: str | None = Field(\n default=None,\n title=\"a-kebab-header\",\n alias=\"a-kebab-header\",\n description=\"This is a header that should be specified as `a-kebab-header`\",\n )\n\n\n@app.get(\"/\")\ndef root_endpoint(\n headers: Annotated[CommonHeaders, Header()],\n):\n result = {\"headers received\": headers}\n return result\n```\n\n```bash\ncurl -X 'GET' \\\n 'http://localhost:8000/' \\\n -H 'accept: application/json' \\\n -H 'simpleheader: foo' \\\n -H 'a-kebab-header: bar'\n```\n\n```json\n{\n \"headers received\": {\n \"simpleheader\": \"foo\",\n \"a-kebab-header\": null\n }\n}\n```\n\n```py\nclass CommonHeaders(BaseModel):\n simpleheader: str\n a_kebab_header: str | None = Field(\n default=None,\n description=\"This is a header that should be specified as `a-kebab-header`\",\n )\n```\n\n```bash\ncurl -X 'GET' \\\n 'http://localhost:8000/' \\\n -H 'accept: application/json' \\\n -H 'simpleheader: foo' \\\n -H 'a_kebab_header: bar'\n```\n\n```json\n{\n \"headers received\": {\n \"simpleheader\": \"foo\",\n \"a_kebab_header\": null\n }\n}\n```\n\n```bash\ncurl -X 'GET' \\\n 'http://localhost:8000/' \\\n -H 'accept: application/json' \\\n -H 'simpleheader: foo' \\\n -H 'a-kebab-header: bar'\n```\n\n```json\n{\"headers received\":{\"simpleheader\":\"foo\",\"a_kebab_header\":\"bar\"}}\n```\n\n```py\n\"\"\"Alternative version without Pydantic.\"\"\"\nfrom typing import Annotated\nfrom fastapi import FastAPI, Header\n\napp = FastAPI()\n\n\n@app.get(\"/\")\ndef root_endpoint(\n simpleheader: Annotated[str, Header()],\n a_kebab_header: Annotated[\n str | None,\n Header(\n title=\"a-kebab-header\",\n description=\"This is a header that should be specified as `a-kebab-header`\",\n ),\n ] = None,\n):\n result = {\n \"headers received\": {\n \"simpleheader\": simpleheader,\n \"a_kebab_header\": a_kebab_header,\n }\n }\n return result\n```\n\n```text\nfrom typing import Annotated\nfrom fastapi import Depends, FastAPI, Header\nfrom pydantic import BaseModel\n\napp = FastAPI()\n\nclass CommonHeaders(BaseModel):\n simpleheader: str\n a_kebab_header: str | None\n\ndef get_common_headers(\n simpleheader: Annotated[str, Header()],\n a_kebab_header: str | None = Header(\n default=None,\n title=\"a-kebab-header\",\n alias=\"a-kebab-header\",\n description=\"This is a header that should be specified as `a-kebab-header`\",\n ),\n):\n return CommonHeaders(simpleheader=simpleheader, a_kebab_header=a_kebab_header)\n\n\n@app.get(\"/\")\ndef root_endpoint(\n headers: Annotated[CommonHeaders, Depends(get_common_headers)],\n):\n result = {\"headers received\": headers}\n return result\n\n\n@app.get(\"/another\")\ndef another_endpoint(\n headers: Annotated[CommonHeaders, Depends(get_common_headers)],\n):\n result = {\"headers received\": headers}\n return result\n```\n\n========================================\n\nComments:\n- Here is an explanation of why it doesn't work: github.com/fastapi/fastapi/issues/12402#issuecomment-2520205‌​504 . Pydantic uses field's alias to create signature of `__init__` method of model. But since alias contains hyphens it can't use this alias as a parameter name. So, it uses original name\n- Very nice. Retains the utility of the Pydantic models and the extra wrapping isn't too onerous. Easy to change back if/when the bug is fixed. Thanks!","metadata":{"transformedAt":"2026-08-18T18:32:29.166Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":10,"totalLines":305,"estimatedTokens":1895}}785{"id":"stack-77124844","source":"stackoverflow","questionId":77124844,"title":"FastAPI Automatically Rounds-off Decimal Values in Response","tags":["python","decimal","fastapi","pydantic"],"text":"Title: FastAPI Automatically Rounds-off Decimal Values in Response\nTags: python, decimal, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI am using Pydantic-based Response Model with a Decimal in FastAPI-based app. I want to return a response with precision up to 20 decimal values. But after serialization, it rounds off the decimal of 15 digits to 14 digits.\n\nFor example:\n\n```\nOriginal Decimal : 328.448267489936666\nDecimal in Response : 328.44826748993665\n```\n\nI have tried setting `getcontext.prec = 15`, but it has no effect on it.\n\nMinimal reproducible Example :\n\n```\nfrom decimal import getcontent, Decimal\nfrom fastapi import FastAPI\nfrom typing import Dict\n\napp = FastAPI()\n\n@app.get(\"/\")\ndef read_root()->Dict[str, Decimal]:\n getcontext().prec = 15 \n return {\"a\": Decimal(328.448267489936666)}\n```\n\nDependencies :\nfastapi==0.92.0\n\nuvicorn==0.20.0\n\npydantic==1.10.5\n\nPython 3.7\n\n========================================\n\nCode:\n```none\nOriginal Decimal : 328.448267489936666\nDecimal in Response : 328.44826748993665\n```\n\n```text\nfrom decimal import getcontent, Decimal\nfrom fastapi import FastAPI\nfrom typing import Dict\n\napp = FastAPI()\n\n\n@app.get(\"/\")\ndef read_root()->Dict[str, Decimal]:\n getcontext().prec = 15 \n return {\"a\": Decimal(328.448267489936666)}\n```\n\n```text\ngetcontext.prec = 15\n```\n\n```text\nimport decimal\nfrom fastapi import FastAPI\nfrom typing import Dict\n\napp = FastAPI()\n\n\n@app.get(\"/\")\ndef read_root() -> Dict[str, decimal.Decimal]:\n decimal.getcontext().prec = 15\n return {\"a\": decimal.Decimal(\"328.448267489936666\")}\n\n\nif __name__ == \"__main__\":\n import uvicorn\n\n uvicorn.run(app, port=11111)\n```\n\n```text\n~ $ curl http://localhost:11111\n{\"a\":\"328.448267489936666\"}\n```\n\n```text\nfrom fastapi import encoders\nencoders.ENCODERS_BY_TYPE[decimal.Decimal] = str\n```\n\n```text\nDecimal(328.448267489936666)\n```\n\n```text\nDecimal(\"328.448267489936666\")\n```\n\n```text\nDecimal\n```\n\n========================================\n\nComments:\n- Some precision loss happens with `Decimal(328.448267489936666)` since that's a float – try `Decimal(\"328.448267489936666\")` so you have a precise `Decimal` to begin with.\n- \"many JSON decoders just use floats for number content\" specifically double-precision floating-point numbers (colloquially \"doubles\"), which is also what's recommended by RFC 7159. Also relevant is that not all JSON APIs provide hooks which run during parsing, Python does (so you can ask for \"floats\" to be parsed as decimals), but browser-JS does not (the reviver runs on converted types, so even if you include decimal.js it's too late, you need to add a bespoke json parser as well)\n- @akx Even when we use string to initialize decimal.Decimal(\"328.448267489936666\"), there is still some precision loss. We get the response {\"a\":328.44826748993665}\n- @KeshavMishra Right, this seems to depend on the version of Pydantic you're using – 2.x defaults to strings for decimals. Augmented my answer.","metadata":{"transformedAt":"2026-08-18T18:32:29.166Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":115,"estimatedTokens":738}}786{"id":"stack-77505777","source":"stackoverflow","questionId":77505777,"title":"can't set cookie in custom local domain","tags":["cookies","localhost","fastapi"],"text":"Title: can't set cookie in custom local domain\nTags: cookies, localhost, fastapi\nSource: Stack Overflow\n\nQuestion:\nI setting cookie using FastApi\n\n```\nresponse.set_cookie(key=\"rf_t\", value=access_token, httponly=False, expires=120)\n```\n\nAnd its works perfect on \"localhost:\" local domain\n\nbut I need subdomains and cross subdomain cookies so I found out you can change hosts file at \\Windows\\System32\\Drivers\\etc\\hosts\n\nand created couple of domains with subdomains like so:\n\n```\n127.0.0.1 main.shop.localhost\n127.0.0.1 admin.shop.localhost\n127.0.0.1 store.shop.localhost\n\n127.0.0.1 shop.localhost\n```\n\nand cookie doesn't set for all of them, JSON responses come from server, but cookie doesn't set, it only sets when I'm\nusing basic localhost domain\n\nim using vue 3 vite on front, and setting dev domain and port in vite.config.js like so\n\n```\nserver: {\n port: 5000,\n host: \"shop.localhost\"\n },\n```\n\nI guess it has something to do with chrome policy, because its not https, but is there any way I can use local subdomains, and be able to set cross cookies (or any cookies) for them?\n\nThanks you a lot my fellow developers!\n\n========================================\n\nCode:\n```text\nresponse.set_cookie(key=\"rf_t\", value=access_token, httponly=False, expires=120)\n```\n\n```text\n127.0.0.1 main.shop.localhost\n127.0.0.1 admin.shop.localhost\n127.0.0.1 store.shop.localhost\n\n127.0.0.1 shop.localhost\n```\n\n```text\nserver: {\n port: 5000,\n host: \"shop.localhost\"\n },\n```\n\n```text\napi.shop.localhost\n```\n\n```text\napp.shop.localhost\n```\n\n========================================\n\nComments:\n- Please have a look at the following answers: this, as well as this and this","metadata":{"transformedAt":"2026-08-18T18:32:29.166Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":75,"estimatedTokens":416}}787{"id":"stack-75829870","source":"stackoverflow","questionId":75829870,"title":"Fast api override dependency as a class","tags":["python","pytest","backend","fastapi"],"text":"Title: Fast api override dependency as a class\nTags: python, pytest, backend, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to write test on some endpoint in fastAPI that has a auth dependency:\n\nrouter = APIRouter(dependencies=[Security(auth.AccountAuth())])\n\nIn the conftest.py. I have a class to override that dependency (I checked the formatted payload as well from jwt when calling the api):\n\n```\nclass AccountAuthTest:\n\ndef __init__(self):\n pass\n\nasync def __call__( \n self\n) -> FormattedPayload:\n return FormattedPayload(email=\"myemail\",\n accounts={},\n id=\"someid\",\n scopes=None,\n permissions=[],\n m2m=False)\n```\n\nI create a fixture like this one:\n\n```\n@pytest.fixture()\n def fastapi_authenticated_app(\n dbsession: AsyncSession,\n) -> FastAPI:\n\"\"\"\nFixture for creating FastAPI app.\n:return: fastapi app with mocked dependencies.\n\"\"\"\n\napplication, sub_app = get_app()\nsub_app.dependency_overrides[get_db_session] = lambda: dbsession\nsub_app.dependency_overrides[auth.AccountAuth()] = lambda: AccountAuthTest()\n\nreturn application\n```\n\nI expect the test will run correctly but it showed me 403. I don't know why this goes wrong here\n\n========================================\n\nCode:\n```text\nclass AccountAuthTest:\n\ndef __init__(self):\n pass\n\nasync def __call__( \n self\n) -> FormattedPayload:\n return FormattedPayload(email=\"myemail\",\n accounts={},\n id=\"someid\",\n scopes=None,\n permissions=[],\n m2m=False)\n```\n\n```text\n@pytest.fixture()\n def fastapi_authenticated_app(\n dbsession: AsyncSession,\n) -> FastAPI:\n\"\"\"\nFixture for creating FastAPI app.\n:return: fastapi app with mocked dependencies.\n\"\"\"\n\n\n\napplication, sub_app = get_app()\nsub_app.dependency_overrides[get_db_session] = lambda: dbsession\nsub_app.dependency_overrides[auth.AccountAuth()] = lambda: AccountAuthTest()\n\n\nreturn application\n```\n\n```text\nfrom dataclasses import dataclass\n\n\n@dataclass(frozen=True)\nclass AccountAuthTest:\n\n async def __call__(self) -> FormattedPayload:\n ...\n```\n\n========================================\n\nComments:\n- Wouldn't `auth.AccountAuth()` return a new function every time, so that when FastAPI checks whether the function given in `dependency_overrides` have been overridden, it hasn't been - since a new, different function was returned instead?\n- What should I do in this case ?\n- You'll have to use a different mechanism than `dependency_overrides` as far as I know, for example by mocking the `auth.AccountAuth` function with `mocker.patch` as shown in the discussion about this issue: github.com/tiangolo/fastapi/discussions/7952","metadata":{"transformedAt":"2026-08-18T18:32:29.166Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":3,"totalLines":106,"estimatedTokens":674}}788{"id":"stack-74184899","source":"stackoverflow","questionId":74184899,"title":"Is having a concurrent.futures.ThreadPoolExecutor call dangerous in a FastAPI endpoint?","tags":["python","python-3.x","fastapi","concurrent.futures","asgi"],"text":"Title: Is having a concurrent.futures.ThreadPoolExecutor call dangerous in a FastAPI endpoint?\nTags: python, python-3.x, fastapi, concurrent.futures, asgi\nSource: Stack Overflow\n\nQuestion:\nI have the following test code:\n\n```\nimport concurrent.futures\nimport urllib.request\n\nURLS = ['http://www.foxnews.com/',\n 'http://www.cnn.com/',\n 'http://europe.wsj.com/',\n 'http://www.bbc.co.uk/',\n 'http://some-made-up-domain.com/']\n\n# Retrieve a single page and report the URL and contents\ndef load_url(url, timeout):\n with urllib.request.urlopen(url, timeout=timeout) as conn:\n return conn.read()\n\n# We can use a with statement to ensure threads are cleaned up promptly\nwith concurrent.futures.ThreadPoolExecutor() as executor:\n # Start the load operations and mark each future with its URL\n future_to_url = {executor.submit(load_url, url, 60): url for url in URLS}\n for future in concurrent.futures.as_completed(future_to_url):\n url = future_to_url[future]\n try:\n data = future.result()\n except Exception as exc:\n print('%r generated an exception: %s' % (url, exc))\n else:\n print('%r page is %d bytes' % (url, len(data)))\n```\n\nI need to use the `concurrent.futures.ThreadPoolExecutor` part of the code in a FastAPI endpoint.\n\nMy concern is the impact of the number of API calls and the inclusion of threads. Concern about creating too many threads and its related consequences, starving the host, crashing the application and/or the host.\n\nAny thoughts or gotchas on this approach?\n\n========================================\n\nCode:\n```text\nimport concurrent.futures\nimport urllib.request\n\nURLS = ['http://www.foxnews.com/',\n 'http://www.cnn.com/',\n 'http://europe.wsj.com/',\n 'http://www.bbc.co.uk/',\n 'http://some-made-up-domain.com/']\n\n# Retrieve a single page and report the URL and contents\ndef load_url(url, timeout):\n with urllib.request.urlopen(url, timeout=timeout) as conn:\n return conn.read()\n\n# We can use a with statement to ensure threads are cleaned up promptly\nwith concurrent.futures.ThreadPoolExecutor() as executor:\n # Start the load operations and mark each future with its URL\n future_to_url = {executor.submit(load_url, url, 60): url for url in URLS}\n for future in concurrent.futures.as_completed(future_to_url):\n url = future_to_url[future]\n try:\n data = future.result()\n except Exception as exc:\n print('%r generated an exception: %s' % (url, exc))\n else:\n print('%r page is %d bytes' % (url, len(data)))\n```\n\n```text\nconcurrent.futures.ThreadPoolExecutor\n```\n\n```py\nlimits = httpx.Limits(max_keepalive_connections=5, max_connections=10)\nclient = httpx.AsyncClient(limits=limits)\n```\n\n```py\nfrom fastapi import FastAPI, Request\nfrom contextlib import asynccontextmanager\nimport httpx\nimport asyncio\n\n\nURLS = ['https://www.foxnews.com/',\n 'https://edition.cnn.com/',\n 'https://www.nbcnews.com/',\n 'https://www.bbc.co.uk/',\n 'https://www.reuters.com/']\n\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI):\n # customize settings\n limits = httpx.Limits(max_keepalive_connections=5, max_connections=10)\n timeout = httpx.Timeout(5.0, read=15.0) # 15s timeout on read. 5s timeout elsewhere.\n\n # Initialize the Client on startup and add it to the state\n async with httpx.AsyncClient(limits=limits, timeout=timeout) as client:\n yield {'client': client}\n # The Client closes on shutdown \n\n\napp = FastAPI(lifespan=lifespan)\n\n\nasync def send(url, client):\n return await client.get(url)\n\n\n@app.get('/')\nasync def main(request: Request):\n client = request.state.client\n tasks = [send(url, client) for url in URLS]\n responses = await asyncio.gather(*tasks)\n return [r.text[:50] for r in responses] # for demo purposes, only return the first 50 chars of each response\n```\n\n```py\nfrom fastapi import FastAPI, Request\nfrom fastapi.responses import StreamingResponse\nfrom contextlib import asynccontextmanager\nimport httpx\nimport asyncio\n\n\nURLS = ['https://www.foxnews.com/',\n 'https://edition.cnn.com/',\n 'https://www.nbcnews.com/',\n 'https://www.bbc.co.uk/',\n 'https://www.reuters.com/']\n\n\n@asynccontextmanager\nasync def lifespan(app: FastAPI):\n # customize settings\n limits = httpx.Limits(max_keepalive_connections=5, max_connections=10)\n timeout = httpx.Timeout(5.0, read=15.0) # 15s timeout on read. 5s timeout elsewhere.\n\n # Initialize the Client on startup and add it to the state\n async with httpx.AsyncClient(limits=limits, timeout=timeout) as client:\n yield {'client': client}\n # The Client closes on shutdown \n\n\napp = FastAPI(lifespan=lifespan)\n\n\nasync def send(url, client):\n req = client.build_request('GET', url)\n return await client.send(req, stream=True)\n\n\nasync def iter_content(responses):\n for r in responses:\n async for chunk in r.aiter_text():\n yield chunk[:50] # for demo purposes, return only the first 50 chars of each response and then break the loop\n yield '\\n\\n'\n break\n await r.aclose()\n\n\n@app.get('/')\nasync def main(request: Request):\n client = request.state.client\n tasks = [send(url, client) for url in URLS]\n responses = await asyncio.gather(*tasks)\n return StreamingResponse(iter_content(responses), media_type='text/event-stream')\n```\n\n```text\nHTTPX\n```\n\n```text\nasync\n```\n\n```text\nClient\n```\n\n```text\nHTTPX\n```\n\n```text\nAsyncClient\n```\n\n```text\nlimits\n```\n\n```text\nClient\n```\n\n```text\nhttpx.Limits\n```\n\n```text\nmax_keepalive_connections\n```\n\n```text\nNone\n```\n\n```text\nmax_connections\n```\n\n```text\nNone\n```\n\n```text\nkeepalive_expiry\n```\n\n```text\nNone\n```\n\n```text\ntimeout\n```\n\n```text\nClient\n```\n\n```text\nAsyncClient\n```\n\n```text\nTimeout\n```\n\n```text\nread\n```\n\n```text\nHTTPX\n```\n\n```text\nReadTimeout\n```\n\n```text\nNone\n```\n\n```text\ntimeout\n```\n\n```text\nread\n```\n\n```text\ntimeout\n```\n\n```text\nawait client.aclose()\n```\n\n```text\nAsyncClient\n```\n\n```text\nasyncio.gather()\n```\n\n```text\nasync\n```\n\n```text\ntasks\n```\n\n```text\nhttpx\n```\n\n```text\nStreamingResponse\n```\n\n========================================\n\nComments:\n- I your concerns about creating too many threads. If what you want to do is a lot of network requests, I would recommend looking into async (using e.g. httpx and `asyncio.gather()`.\n- Does this answer your question? What is the proper way to make downstream Https requests inside of Uvicorn/FastAPI?\n- Do you need to perform requests for all five URLs each time a user makes an API call?\n- @chris yes I do","metadata":{"transformedAt":"2026-08-18T18:32:29.166Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":37,"totalLines":311,"estimatedTokens":1642}}789{"id":"stack-74507306","source":"stackoverflow","questionId":74507306,"title":"FastAPI returns \"Error 422: Unprocessable entity\" when I send multipart form data with JavaScript Fetch API","tags":["javascript","python","fastapi","fetch-api","multipartform-data"],"text":"Title: FastAPI returns \"Error 422: Unprocessable entity\" when I send multipart form data with JavaScript Fetch API\nTags: javascript, python, fastapi, fetch-api, multipartform-data\nSource: Stack Overflow\n\nQuestion:\nI have some issue with using Fetch API JavaScript method when sending some simple `formData` like so:\n\n```\nfunction register() {\n var formData = new FormData();\n var textInputName = document.getElementById('textInputName');\n var sexButtonActive = document.querySelector('#buttonsMW > .btn.active');\n var imagesInput = document.getElementById('imagesInput');\n\n formData.append('name', textInputName.value);\n if (sexButtonActive != null){\n formData.append('sex', sexButtonActive.html())\n } else {\n formData.append('sex', \"\");\n }\n formData.append('images', imagesInput.files[0]);\n\n fetch('/user/register', {\n method: 'POST',\n data: formData,\n })\n .then(response => response.json());\n}\ndocument.querySelector(\"form\").addEventListener(\"submit\", register);\n```\n\nAnd on the server side (FastAPI):\n\n```\n@app.post(\"/user/register\", status_code=201)\ndef register_user(name: str = Form(...), sex: str = Form(...), images: List[UploadFile] = Form(...)):\ntry:\n print(name)\n print(sex)\n print(images)\n return \"OK\"\nexcept Exception as err:\n print(err)\n print(traceback.format_exc())\n return \"Error\"\n```\n\nAfter clicking on the submit button I get `Error 422: Unprocessable entity`. So, if I'm trying to add header `Content-Type: multipart/form-data`, it also doesn't help cause I get another `Error 400: Bad Request`. I want to understand what I am doing wrong, and how to process `formData` without such errors?\n\n========================================\n\nTop Answer:\nSo, I found that I has error in this part of code:\n\n```\nformData.append('images', imagesInput.files[0]);\n```\n\nRight way to upload multiple files is:\n\n```\nfor (const image of imagesInput.files) {\n formData.append('images', image);\n}\n```\n\nAlso, we should use **File** in FastAPI method arguments `images: List[UploadFile] = File(...)` (instead of *Form*) and change *data* to *body* in JS method. It's not an error, cause after method called, we get right type of data, for example:\n\n```\nName: Bob\nSex: Man\nImages: []\n```\n\n========================================\n\nCode:\n```text\nfunction register() {\n var formData = new FormData();\n var textInputName = document.getElementById('textInputName');\n var sexButtonActive = document.querySelector('#buttonsMW > .btn.active');\n var imagesInput = document.getElementById('imagesInput');\n\n formData.append('name', textInputName.value);\n if (sexButtonActive != null){\n formData.append('sex', sexButtonActive.html())\n } else {\n formData.append('sex', \"\");\n }\n formData.append('images', imagesInput.files[0]);\n\n fetch('/user/register', {\n method: 'POST',\n data: formData,\n })\n .then(response => response.json());\n}\ndocument.querySelector(\"form\").addEventListener(\"submit\", register);\n```\n\n```text\n@app.post(\"/user/register\", status_code=201)\ndef register_user(name: str = Form(...), sex: str = Form(...), images: List[UploadFile] = Form(...)):\ntry:\n print(name)\n print(sex)\n print(images)\n return \"OK\"\nexcept Exception as err:\n print(err)\n print(traceback.format_exc())\n return \"Error\"\n```\n\n```text\nformData\n```\n\n```text\nError 422: Unprocessable entity\n```\n\n```text\nContent-Type: multipart/form-data\n```\n\n```text\nError 400: Bad Request\n```\n\n```text\nformData\n```\n\n```py\nimages: List[UploadFile] = File(...)\n ^^^^\n```\n\n```py\nimages: List[UploadFile]\n```\n\n```py\n@app.post(\"/user/register\")\nasync def register_user(name: str = Form(...), images: List[UploadFile] = File(...)):\n pass\n```\n\n```js\nvar nameInput = document.getElementById('nameInput'); \nvar imagesInput = document.getElementById('imagesInput');\n\nvar formData = new FormData();\nformData.append('name', nameInput.value);\nfor (const file of imagesInput.files)\n formData.append('images', file);\n\nfetch('/user/register', {\n method: 'POST',\n body: formData,\n })\n .then(response => {\n console.log(response);\n })\n .catch(error => {\n console.error(error);\n });\n```\n\n```text\n422\n```\n\n```text\nimages\n```\n\n```text\nimages\n```\n\n```text\nList\n```\n\n```text\nFile\n```\n\n```text\nFile\n```\n\n```text\nForm\n```\n\n```text\nUploadFile\n```\n\n```text\nFile()\n```\n\n```text\nbody\n```\n\n```text\ndata\n```\n\n```text\nfetch()\n```\n\n```text\nFormData\n```\n\n```text\nfiles\n```\n\n```text\nform\n```\n\n```text\nContent-Type\n```\n\n```text\nmultipart/form-data\n```\n\n```text\nContent-Type\n```\n\n```text\nformData.append('images', imagesInput.files[0]);\n```\n\n```text\nfor (const image of imagesInput.files) {\n formData.append('images', image);\n}\n```\n\n```text\nName: Bob\nSex: Man\nImages: [<starlette.datastructures.UploadFile object at 0x7fe07abf04f0>]\n```\n\n```text\nimages: List[UploadFile] = File(...)\n```\n\n========================================\n\nComments:\n- Thank you for your answer, after reading your proof links I found the right solution (wrote below).\n- Thanks for the answer, I was having a similar problem and removed the header on my request where I manually added the Content-Type and it solved my 422 error (despite adding the same Content-Type header).","metadata":{"transformedAt":"2026-08-18T18:32:29.166Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":33,"totalLines":268,"estimatedTokens":1293}}790{"id":"stack-77095776","source":"stackoverflow","questionId":77095776,"title":"FastAPI pydantic data validation for put method if body only contains the updated data","tags":["python","fastapi","pydantic"],"text":"Title: FastAPI pydantic data validation for put method if body only contains the updated data\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI am learning FastAPI and understanding that its data validation using **pydantic** is one of its features. But after reading its put method example from its tutorial I have a question if I only want to let the put body contain the updated data(as the URL already has its id), how do I do that?\n\nUse the sample code from the tutorial as an example to what I mean,\n\n```\nfrom fastapi import FastAPI\nfrom fastapi.encoders import jsonable_encoder\nfrom pydantic import BaseModel\n\napp = FastAPI()\n\nclass Item(BaseModel):\n id: str\n description: str = \"default description\"\n price: Union[float, None] = None\n tax: float = 10.5\n tags: list[str] = []\n\n...\n\n@app.put(\"/items/{item_id}\")\n#async def update_item(item_id: str, item:Item):\nasync def update_item(item_id: str, item):\n pass\n```\n\nIf I code `async def update_item(item_id: str, item:Item)` then the body has to contain id property otherwise I will get `422 \"field required\"`. But I feel that is unnecessary because the URL `/items/{item_id}` already contains the `id` I just want body to contain the updated data.\n\nBut when I coded `async def update_item(item_id: str, item)`, to my surprise the item became the **required** QUERY PARAMETERS!\n\nAs its document shows:\n\nhttps://i.sstatic.net/ikQEI.png\n\nWhy does it become query parameters then? This is my second question.\n\nI feel that is wrong because I prefer to query parameters for GET only.\n\n**--- Update ---**\n\nI guess the 2 methods Chris provided are the way FastAPI solves my first question (whether `id` should be one of Item's properties is another question, e.g. check What to do when REST POST provides an ID?), but I come from nodejs background so I would like to provide Nestjs solution in comparison.\n\nUsing Nestjs sample code here https://docs.nestjs.com/controllers#full-resource-sample\n\n```\n@Controller('cats')\nexport class CatsController {\n @Post()\n create(@Body() createCatDto: CreateCatDto) {\n return 'This action adds a new cat';\n }\n\n...\n\n @Put(':id')\n update(@Param('id') id: string, @Body() updateCatDto: UpdateCatDto) {\n return `This action updates a #${id} cat`;\n }\n```\n\nAs https://docs.nestjs.com/techniques/validation#mapped-types explains \"The `PartialType()` function returns a type (class) with all the properties of the input type set to optional.\"\n\n```\nexport class CreateCatDto {\n name: string;\n age: number;\n breed: string;\n}\n\nexport class UpdateCatDto extends PartialType(CreateCatDto) {}\n```\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI\nfrom fastapi.encoders import jsonable_encoder\nfrom pydantic import BaseModel\n\napp = FastAPI()\n\n\nclass Item(BaseModel):\n id: str\n description: str = \"default description\"\n price: Union[float, None] = None\n tax: float = 10.5\n tags: list[str] = []\n\n...\n\n@app.put(\"/items/{item_id}\")\n#async def update_item(item_id: str, item:Item):\nasync def update_item(item_id: str, item):\n pass\n```\n\n```text\n@Controller('cats')\nexport class CatsController {\n @Post()\n create(@Body() createCatDto: CreateCatDto) {\n return 'This action adds a new cat';\n }\n\n...\n\n @Put(':id')\n update(@Param('id') id: string, @Body() updateCatDto: UpdateCatDto) {\n return `This action updates a #${id} cat`;\n }\n```\n\n```text\nexport class CreateCatDto {\n name: string;\n age: number;\n breed: string;\n}\n\nexport class UpdateCatDto extends PartialType(CreateCatDto) {}\n```\n\n```text\nasync def update_item(item_id: str, item:Item)\n```\n\n```text\n422 \"field required\"\n```\n\n```text\n/items/{item_id}\n```\n\n```text\nid\n```\n\n```text\nasync def update_item(item_id: str, item)\n```\n\n```text\nid\n```\n\n```text\nPartialType()\n```\n\n```py\nfrom fastapi import FastAPI\nfrom fastapi.encoders import jsonable_encoder\nfrom pydantic import BaseModel\nfrom typing import Union, List\n\napp = FastAPI()\n\n\nclass Item(BaseModel):\n description: str = \"default description\"\n price: Union[float, None] = None\n tax: float = 10.5\n tags: List[str] = []\n \n\nclass ItemCreate(Item):\n id: str\n\n\nitems = {\n \"foo\": {\"name\": \"Foo\", \"price\": 50.2},\n \"bar\": {\"name\": \"Bar\", \"description\": \"The bartenders\", \"price\": 62, \"tax\": 20.2},\n \"baz\": {\"name\": \"Baz\", \"description\": None, \"price\": 50.2, \"tax\": 10.5, \"tags\": []},\n}\n\n\n@app.get(\"/items/{item_id}\", response_model=Union[Item,str])\nasync def read_item(item_id: str):\n if item_id in items:\n return items[item_id]\n else:\n return 'Item not found'\n \n\n@app.put(\"/items/{item_id}\", response_model=Item)\nasync def update_item(item_id: str, item: Item):\n update_item_encoded = jsonable_encoder(item)\n items[item_id] = update_item_encoded\n return update_item_encoded\n \n\n@app.post(\"/items\")\nasync def create_item(item: ItemCreate):\n new_item_encoded = jsonable_encoder(item)\n items[item.id] = new_item_encoded\n return 'Success'\n```\n\n```py\nfrom fastapi import Body\n\n@app.post(\"/items\")\nasync def create_item(item: Item, id: str = Body(...)):\n new_item_encoded = jsonable_encoder(item)\n items[id] = new_item_encoded\n return 'Success'\n```\n\n```json\n{\n \"item\": {\n \"description\": \"default description\",\n \"price\": 0,\n \"tax\": 10.5,\n \"tags\": []\n },\n \"id\": \"string\"\n}\n```\n\n```py\nfrom fastapi import FastAPI, Body, HTTPException\nfrom fastapi.encoders import jsonable_encoder\nfrom pydantic import BaseModel\nfrom typing import Union, List\nfrom utils import optional\nimport random\nimport string\n\napp = FastAPI()\n\nitems = {\n \"foo\": {\"name\": \"Foo\", \"price\": 50.2},\n \"bar\": {\"name\": \"Bar\", \"description\": \"The bartenders\", \"price\": 62, \"tax\": 20.2},\n \"baz\": {\"name\": \"Baz\", \"description\": None, \"price\": 50.2, \"tax\": 10.5, \"tags\": []},\n}\n\n\nclass Item(BaseModel):\n description: str = \"default description\"\n price: Union[float, None] = None\n tax: float = 10.5\n tags: List[str] = []\n \n\n@optional\nclass ItemUpdate(Item):\n pass\n\n \ndef check_item_id(item_id):\n if item_id not in items:\n raise HTTPException(status_code=400, detail='Item not found')\n\n \n@app.get(\"/items/{item_id}\", response_model=Union[Item, str])\nasync def read_item(item_id: str):\n check_item_id(item_id)\n return items[item_id]\n\n \n@app.post(\"/items\")\nasync def create_item(item: Item):\n item_encoded = jsonable_encoder(item)\n item_id = ''.join(random.choices(string.ascii_letters + string.digits, k=5))\n items[item_id] = item_encoded\n return f\"Item '{item_id}' has been created\"\n \n\n@app.put(\"/items/{item_id}\", response_model=Union[Item, str])\nasync def update_item(item_id: str, item: ItemUpdate):\n check_item_id(item_id)\n old = items[item_id]\n new = jsonable_encoder(item)\n old.update((k,v) for k,v in new.items() if v is not None)\n return old\n```\n\n```py\nfrom pydantic import BaseModel\nfrom pydantic import create_model\nfrom typing import Optional\nimport inspect\n\ndef optional(*fields):\n def dec(cls):\n fields_dict = {}\n for field in fields:\n field_info = cls.__annotations__.get(field)\n if field_info is not None:\n fields_dict[field] = (Optional[field_info], None)\n OptionalModel = create_model(cls.__name__, **fields_dict)\n OptionalModel.__module__ = cls.__module__\n\n return OptionalModel\n\n if fields and inspect.isclass(fields[0]) and issubclass(fields[0], BaseModel):\n cls = fields[0]\n fields = cls.__annotations__\n return dec(cls)\n\n return dec\n```\n\n```text\nPOST\n```\n\n```text\nPUT\n```\n\n```text\nid\n```\n\n```text\nBaseModel\n```\n\n```text\nPOST\n```\n\n```text\nItem\n```\n\n```text\nPUT\n```\n\n```text\nPOST\n```\n\n```text\nid\n```\n\n```text\nBody\n```\n\n```text\ncreate_item\n```\n\n```text\nPOST\n```\n\n```text\nitem_id\n```\n\n```text\nItemUpdate\n```\n\n```text\nItem\n```\n\n```text\n@optional\n```\n\n```text\nutlis.py\n```\n\n```text\noptional\n```\n\n```text\npartial\n```\n\n```text\npydantic-partial\n```\n\n```text\nHTTP\n```\n\n```text\nPUT\n```\n\n```text\nPOST\n```\n\n```text\nitem_id\n```\n\n```text\nItem\n```\n\n```text\nstr\n```\n\n```text\nitem\n```\n\n```text\nItem\n```\n\n========================================\n\nComments:\n- You could define the `item` parameter as Optional - have a look at this answer.\n- I know that but I feel that is kind of defeats the purpose of defining the id property.\n- \"Why's that?\" because for post method I want id to be present. so I can code `async def create_item(item: Item)`\n- Please have a look at this answer and its references as well.\n- It is not an extra line of code that makes this over-complicated its the concept behind it, using a subclass to solve this makes me feel over-complicated. It is supposed to a simple question (at least to me).\n- If there is a situation that does require a subclass model, id still should be in the base class. Now we put it in the subclass just to solve a simple problem.\n- I feel this is over-complicated, I just need PUT with the body parameter containing the updated data while its id on path. How?\n- I am new to FastAPI as a matter of fact this is the **first** day I have started to learn it because we have a project using FastAPI. I accept your answer. Thanks for spending in in doing it. But I have to say this one only makes me realize I don't want to use FastAPI other than this project. I don't like it at all (compared with some other web frameworks I am familair with).\n- I would also suggest having a look at this answer, as well as this answer and this answer\n- I have checked all your answers. Thanks. I also updated my question to show how NestJS solves this.\n- Yes, @optional decorator you added is basically what `PartialType()` does in Next.js. I come to realize that my initial (and innocent) question, i.e. put method should better have optional body parameters has become a long discussion. Thanks.\n- This should be a separate topic but another reason when I said I don't want to FastAPI was because I saw Uvicorn only supports HTTP/1.1 while nodejs supports HTTP/2 since 8.6 (now is nodejs 20) so it was kind of what?! But anyway I should not jump to that conclusion.\n- Uvicorn is not the only ASGI server that can be used for development or production. In fact, there is Hypercorn and Daphne that support HTTP/2. You could also use HTTP/2 with a reverse proxy like NGINX or Traefik (see docs), and run Uvicorn (or Gunicorn with Uvicorn) behind it over HTTP/1.1. This would allow the proxy server to handle the performance intensive side (HTTPS, HTTP/2, etc.) and proxy the actual data to the server.","metadata":{"transformedAt":"2026-08-18T18:32:29.166Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":43,"totalLines":440,"estimatedTokens":2628}}791{"id":"stack-73678481","source":"stackoverflow","questionId":73678481,"title":"How to monitor the status of model training running on the server via fast-api","tags":["python","rest","machine-learning","fastapi"],"text":"Title: How to monitor the status of model training running on the server via fast-api\nTags: python, rest, machine-learning, fastapi\nSource: Stack Overflow\n\nQuestion:\nBy the following code, I want to get the status of training, just if it is started and when it is finished.\n\n```\napp = FastAPI()\n\n@app.post(\"/train\")\nasync def train_on_background():\n background_tasks.add_task(train, input_data, output_data)\n\ndef train(input_data, output_data):\n dataset = prepare_dataset(input_data, output_data)\n \n model = Trainer(dataset)\n model.auto_train()\n \n \n filename = \"Model\" \n filename = filename + \".pkl\"\n dump(model, open(filename, 'wb'))\n```\n\nThe `train()` function should train the model by doing several steps. `train_on_background()` should run the train function on the background.\n\nI want to add a separate command to check the training status. the command should respond started when the training starts (`train()` function is called), & finished when it `train()` function is ended.\n\n========================================\n\nCode:\n```py\napp = FastAPI()\n\n@app.post(\"/train\")\nasync def train_on_background():\n background_tasks.add_task(train, input_data, output_data)\n\n\n\n\ndef train(input_data, output_data):\n dataset = prepare_dataset(input_data, output_data)\n \n model = Trainer(dataset)\n model.auto_train()\n \n \n filename = \"Model\" \n filename = filename + \".pkl\"\n dump(model, open(filename, 'wb'))\n```\n\n```text\ntrain()\n```\n\n```text\ntrain_on_background()\n```\n\n```text\ntrain()\n```\n\n```text\ntrain()\n```\n\n```py\n@app.get(“/check”)\ndef check():\n filename = “Model”\n filename = filename + “.pkl”\n file_exists = os.path.exists(filename)\n if file_exists:\n return {“message”: “Model Already Exists”}\n elif (os.path.exists(f”temp_monitor.txt”)):\n return {“message”: “Training in progress...“}\ndef monitor_file(text):\n if text is None:\n os.remove(f”temp_monitor.txt”)\n else:\n with open(f’temp_monitor.txt’, ‘w’) as f:\n f.write(text)\n```\n\n```py\ndef train(input_data, output_data):4\n dataset = prepare_dataset(input_data, output_data)\n monitor_file(“started”)\n model = Trainer(dataset)\n model.auto_train()\n```\n\n```text\ntrain()\n```\n\n```text\ncheck\n```\n\n```text\ntraining in progress\n```\n\n```text\ntrain\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.166Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":11,"totalLines":112,"estimatedTokens":587}}792{"id":"stack-79109370","source":"stackoverflow","questionId":79109370,"title":"How to get the response.headers along with AsyncIterable content from async httpx.stream to a FastAPI StreamingResponse?","tags":["python","python-3.x","fastapi","httpx"],"text":"Title: How to get the response.headers along with AsyncIterable content from async httpx.stream to a FastAPI StreamingResponse?\nTags: python, python-3.x, fastapi, httpx\nSource: Stack Overflow\n\nQuestion:\nI am trying to use httpx in a FastAPI endpoint to download files from a server and return them as a `StreamingResponse`.\nFor some processing, I need to get the header information along with the data. I want to stream the file data so I came up with this attempt, boiled down to a MRE:\n\n```\nfrom typing import AsyncIterable\n\nimport httpx\nfrom fastapi import FastAPI\nfrom fastapi.responses import StreamingResponse\n\napp = FastAPI()\n\nclass FileStream:\n def __init__(self, headers: dict[str, str], stream: AsyncIterable[bytes]):\n self.headers = headers\n self.stream = stream\n\nasync def get_file_stream(url) -> FileStream:\n async with httpx.AsyncClient() as client:\n async with client.stream(\"GET\", url) as response:\n\n async def chunk_generator() -> AsyncIterable[bytes]:\n async for chunk in response.aiter_bytes():\n yield chunk\n\n return FileStream(response.headers, chunk_generator())\n\n@app.get(\"/download\")\nasync def download_file():\n file_stream = await get_file_stream(url=some_url)\n\n headers = {}\n media_type = \"application/octet-stream\"\n # some code setting headers and media_type based on file_stream.headers\n\n return StreamingResponse(file_stream.stream, media_type=media_type, headers=headers)\n\nif __name__ == \"__main__\":\n import uvicorn\n\n uvicorn.run(app, host=\"127.0.0.1\", port=8000, log_level=\"debug\")\n```\n\nThis leads to the Error `httpx.StreamClosed: Attempted to read or stream content, but the stream has been closed.`. To my understanding, this is because of the scoping of the context managers in `get_file_stream`, so I tried to solve it with a wrapping context manager:\n\n```\nfrom contextlib import asynccontextmanager\nfrom typing import AsyncIterable\n\nimport httpx\nfrom fastapi import FastAPI\nfrom fastapi.responses import StreamingResponse\n\napp = FastAPI()\n\nclass FileStream:\n def __init__(self, headers: dict[str, str], stream: AsyncIterable[bytes]):\n self.headers = headers\n self.stream = stream\n\n@asynccontextmanager\nasync def get_file_stream(url) -> FileStream:\n async with httpx.AsyncClient() as client:\n async with client.stream(\"GET\", url) as response:\n\n async def chunk_generator() -> AsyncIterable[bytes]:\n async for chunk in response.aiter_bytes():\n yield chunk\n\n yield FileStream(response.headers, chunk_generator())\n\n@app.get(\"/download\")\nasync def download_file():\n async with get_file_stream(url=some_url) as file_stream:\n\n headers = {}\n media_type = \"application/octet-stream\"\n # some code setting headers and media_type based on file_stream.headers\n\n return StreamingResponse(file_stream.stream, media_type=media_type, headers=headers)\n\nif __name__ == \"__main__\":\n import uvicorn\n uvicorn.run(app, host=\"127.0.0.1\", port=8000, log_level=\"debug\")\n```\n\nHowever, this leads to the same issue. It seems that I am missing some points here. Any hints on how to solve this?\n\n**Update**\nThe problem seems to be with how FastAPI handles `StreamingResponses`. It indeed closes the resources before starting the response streaming.\nI am trying to find a solid workaround.\n\nStill same for fastapi 0.116.1\n\n========================================\n\nCode:\n```py\nfrom typing import AsyncIterable\n\nimport httpx\nfrom fastapi import FastAPI\nfrom fastapi.responses import StreamingResponse\n\napp = FastAPI()\n\n\nclass FileStream:\n def __init__(self, headers: dict[str, str], stream: AsyncIterable[bytes]):\n self.headers = headers\n self.stream = stream\n\n\nasync def get_file_stream(url) -> FileStream:\n async with httpx.AsyncClient() as client:\n async with client.stream(\"GET\", url) as response:\n\n async def chunk_generator() -> AsyncIterable[bytes]:\n async for chunk in response.aiter_bytes():\n yield chunk\n\n return FileStream(response.headers, chunk_generator())\n\n\n@app.get(\"/download\")\nasync def download_file():\n file_stream = await get_file_stream(url=some_url)\n\n headers = {}\n media_type = \"application/octet-stream\"\n # some code setting headers and media_type based on file_stream.headers\n\n return StreamingResponse(file_stream.stream, media_type=media_type, headers=headers)\n\n\nif __name__ == \"__main__\":\n import uvicorn\n\n uvicorn.run(app, host=\"127.0.0.1\", port=8000, log_level=\"debug\")\n```\n\n```py\nfrom contextlib import asynccontextmanager\nfrom typing import AsyncIterable\n\nimport httpx\nfrom fastapi import FastAPI\nfrom fastapi.responses import StreamingResponse\n\napp = FastAPI()\n\n\nclass FileStream:\n def __init__(self, headers: dict[str, str], stream: AsyncIterable[bytes]):\n self.headers = headers\n self.stream = stream\n\n@asynccontextmanager\nasync def get_file_stream(url) -> FileStream:\n async with httpx.AsyncClient() as client:\n async with client.stream(\"GET\", url) as response:\n\n async def chunk_generator() -> AsyncIterable[bytes]:\n async for chunk in response.aiter_bytes():\n yield chunk\n\n yield FileStream(response.headers, chunk_generator())\n\n\n@app.get(\"/download\")\nasync def download_file():\n async with get_file_stream(url=some_url) as file_stream:\n\n headers = {}\n media_type = \"application/octet-stream\"\n # some code setting headers and media_type based on file_stream.headers\n\n return StreamingResponse(file_stream.stream, media_type=media_type, headers=headers)\n\nif __name__ == \"__main__\":\n import uvicorn\n uvicorn.run(app, host=\"127.0.0.1\", port=8000, log_level=\"debug\")\n```\n\n```text\nStreamingResponse\n```\n\n```text\nhttpx.StreamClosed: Attempted to read or stream content, but the stream has been closed.\n```\n\n```text\nget_file_stream\n```\n\n```text\nStreamingResponses\n```\n\n```text\nasync def get_file_stream(url: str) -> FileStream:\n async def chunk_generator() -> AsyncIterable[bytes]:\n async with httpx.AsyncClient() as client:\n async with client.stream(\"GET\", url) as response:\n async for chunk in response.aiter_bytes():\n yield chunk\n return FileStream({}, chunk_generator())\n\n\n@app.get(\"/download\")\nasync def download_file():\n\n file_stream = await get_file_stream(some_url)\n\n headers = {}\n media_type = \"application/octet-stream\"\n\n return StreamingResponse(\n file_stream.stream,\n media_type=media_type,\n headers=headers,\n )\n```\n\n========================================\n\nComments:\n- Don’t use async with client.stream(...) inside your endpoint. That guarantees the stream will close too early. Instead, create the httpx client and response, then hand over a generator (gen) that: yields chunks, and in a finally: block closes the response and client when iteration is done","metadata":{"transformedAt":"2026-08-18T18:32:29.166Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":7,"totalLines":234,"estimatedTokens":1707}}793{"id":"stack-77566386","source":"stackoverflow","questionId":77566386,"title":"How can I use dynamically defined enums in FastAPI/Pydantic models run on Uvicorn?","tags":["python","dynamic","fastapi","pydantic","uvicorn"],"text":"Title: How can I use dynamically defined enums in FastAPI/Pydantic models run on Uvicorn?\nTags: python, dynamic, fastapi, pydantic, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI have a FastAPI application that has some Pydantic models defined. Some of the fields in these models should only allow values that are defined by enums that are loaded from a database and created at runtime.\n\nThe setup I have currently works fine when either debugging or running via the python command line however when I run with Uvicorn using `uvicorn main:app` I can see that the enums get loaded successfully but it seems the models get loaded before the enums and as such the app fails to start up successfully with an `ImportError`.\n\nI have a minimal example that shows the issue on github.\n\nI've tried changing it so instead of using an import statement I get the enum definition from the `enum_definitions` singleton declared on line 139 of `models/enums.py`, i.e.\n\n```\nEnum1 = enum_definitions.get_enum_definition(\"Enum1\")\n```\n\nwhich triggered the exception on line 104 of `models/enums.py`. I've tried changing it so the enums are loaded both in `main.py` before the FastAPI object is instantiated and in `models/model1.py` before the model class is declared, however all these approaches result in the model not being able to see the enum.\n\nHow can I get the model to use these dynamic enums?\n\nMany thanks in advance.\n\n========================================\n\nCode:\n```text\nEnum1 = enum_definitions.get_enum_definition(\"Enum1\")\n```\n\n```text\nuvicorn main:app\n```\n\n```text\nImportError\n```\n\n```text\nenum_definitions\n```\n\n```text\nmodels/enums.py\n```\n\n```text\nmodels/enums.py\n```\n\n```text\nmain.py\n```\n\n```text\nmodels/model1.py\n```\n\n```py\nfrom pydantic import BaseModel, validator\n from models.enums import enum_definitions\n \n class Model(BaseModel):\n enum_field_name: str\n \n @validator('enum_field_name', pre=True, always=True)\n def validate_enum_field(cls, v):\n Enum1 = enum_definitions.get_enum_definition(\"Enum1\")\n if v not in Enum1.__members__:\n raise ValueError(f\"{v} is not a valid value for \n\nEnum1\")\n return v\n```\n\n```py\n@app.on_event(\"startup\")\n async def load_enums():\n await enum_definitions.load_definitions(global_import=True)\n```\n\n========================================\n\nComments:\n- Any reason why you can't load the enum definitions synchronously at startup instead of using the lifetime manager/async loop? That way you can be sure that the code runs before your models get imported.\n- @MatsLindh as the database connection in my main project is asynchronous, and I need to retrieve the enum definitions from that database, the enum construction needs to happen in an async context.\n- But since this is on startup and you need the content before you can actually start your application; what's the need for actually running it async? Why not await the query as soon as possible and retrieve the data before proceeding with launching the application?\n- Could you explain how I might go about doing that in the context of the example application?\n- Several comprehensive solutions to dynamic enums with Pydantic here: stackoverflow.com/questions/75587442/…\n- I like the approach of using a validator, I will try this in my main project and get back to you. Thanks\n- Ended up going with this solution. Thank you!\n- This is kinda the worst of every world. \"enum_field_name\" looks like it takes in any \"str\" but it actually won't. And nowhere in any documentation will this approach work (for example look at any generated openapi spec that uses this Model). You probably want a solution where \"enum_field_name\" is of type Enum1 (or some annotation with valid valued).","metadata":{"transformedAt":"2026-08-18T18:32:29.166Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":10,"totalLines":92,"estimatedTokens":941}}794{"id":"stack-77285773","source":"stackoverflow","questionId":77285773,"title":"\"RuntimeWarning: coroutine was never awaited\" in python tests","tags":["python-3.x","debugging","pytest","python-asyncio","fastapi"],"text":"Title: \"RuntimeWarning: coroutine was never awaited\" in python tests\nTags: python-3.x, debugging, pytest, python-asyncio, fastapi\nSource: Stack Overflow\n\nQuestion:\nI run my python tests with pytest and it shows a warning:\n\n```\nRuntimeWarning: coroutine 'AsyncMockMixin._execute_mock_call' was never awaited\n```\n\nIn the first glance I didn't see problems with my code. All coroutines were awaited as far as I can see. But obviously there is some problem in tests.\n\nHow my test looks like. I deleted some info to hide business logic.\n\n```\n@pytest.mark.asyncio()\nasync def test1(\n client: httpx.AsyncClient,\n mock1: MagicMock, ...\n) -> None:\n ...\n await client.post(url=\"url\", json=jsonable_encoder(body.dict(), by_alias=True))\n mock1.func.assert_awaited_once_with(...)\n```\n\nAs docs recommends, I've enabled `tracemalloc`. But it only shows this info:\n\n```\n.../lib/python3.11/site-packages/fastapi/routing.py:144: RuntimeWarning: coroutine 'AsyncMockMixin._execute_mock_call' was never awaited\n value, errors_ = field.validate(response_content, {}, loc=(\"response\",))\n \n Object allocated at:\n File \".../lib/python3.11/site-packages/pluggy/_callers.py\", line 77\n res = hook_impl.function(*args)\n File \".../lib/python3.11/site-packages/_pytest/runner.py\", line 169\n item.runtest()\n File \".../lib/python3.11/site-packages/_pytest/python.py\", line 1792\n self.ihook.pytest_pyfunc_call(pyfuncitem=self)\n File \".../lib/python3.11/site-packages/pluggy/_hooks.py\", line 493\n return self._hookexec(self.name, self._hookimpls, kwargs, firstresult)\n File \".../lib/python3.11/site-packages/pluggy/_manager.py\", line 115\n return self._inner_hookexec(hook_name, methods, kwargs, firstresult)\n File \".../lib/python3.11/site-packages/pluggy/_callers.py\", line 77\n res = hook_impl.function(*args)\n File \".../lib/python3.11/site-packages/_pytest/python.py\", line 194\n result = testfunction(**testargs)\n File \".../lib/python3.11/site-packages/pytest_asyncio/plugin.py\", line 532\n _loop.run_until_complete(task)\n File \"/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/base_events.py\", line 640\n self.run_forever()\n File \"/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/base_events.py\", line 607\n self._run_once()\n File \"/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/base_events.py\", line 1922\n handle._run()\n File \"/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/events.py\", line 80\n self._context.run(self._callback, *self._args)\n File \".../lib/python3.11/site-packages/starlette/middleware/base.py\", line 70\n await self.app(scope, receive_or_disconnect, send_no_error)\n File \".../lib/python3.11/site-packages/starlette/middleware/exceptions.py\", line 68\n await self.app(scope, receive, sender)\n File \".../lib/python3.11/site-packages/fastapi/middleware/asyncexitstack.py\", line 17\n await self.app(scope, receive, send)\n File \".../python3.11/site-packages/starlette/routing.py\", line 718\n await route.handle(scope, receive, send)\n File \".../lib/python3.11/site-packages/starlette/routing.py\", line 276\n await self.app(scope, receive, send)\n File \".../lib/python3.11/site-packages/starlette/routing.py\", line 66\n response = await func(request)\n File \".../lib/python3.11/site-packages/fastapi/routing.py\", line 291\n content = await serialize_response(\n File \".../lib/python3.11/site-packages/fastapi/routing.py\", line 144\n value, errors_ = field.validate(response_content, {}, loc=(\"response\",))\n```\n\nBut it's `fastapi` package. I don't think, that the problem is there\n\nWhat my possible next steps to catch where exactly not awaited coroutine created in my code?\nPlease, recommend some tools or commands.\n\n========================================\n\nCode:\n```text\nRuntimeWarning: coroutine 'AsyncMockMixin._execute_mock_call' was never awaited\n```\n\n```py\n@pytest.mark.asyncio()\nasync def test1(\n client: httpx.AsyncClient,\n mock1: MagicMock, ...\n) -> None:\n ...\n await client.post(url=\"url\", json=jsonable_encoder(body.dict(), by_alias=True))\n mock1.func.assert_awaited_once_with(...)\n```\n\n```text\n.../lib/python3.11/site-packages/fastapi/routing.py:144: RuntimeWarning: coroutine 'AsyncMockMixin._execute_mock_call' was never awaited\n value, errors_ = field.validate(response_content, {}, loc=(\"response\",))\n \n Object allocated at:\n File \".../lib/python3.11/site-packages/pluggy/_callers.py\", line 77\n res = hook_impl.function(*args)\n File \".../lib/python3.11/site-packages/_pytest/runner.py\", line 169\n item.runtest()\n File \".../lib/python3.11/site-packages/_pytest/python.py\", line 1792\n self.ihook.pytest_pyfunc_call(pyfuncitem=self)\n File \".../lib/python3.11/site-packages/pluggy/_hooks.py\", line 493\n return self._hookexec(self.name, self._hookimpls, kwargs, firstresult)\n File \".../lib/python3.11/site-packages/pluggy/_manager.py\", line 115\n return self._inner_hookexec(hook_name, methods, kwargs, firstresult)\n File \".../lib/python3.11/site-packages/pluggy/_callers.py\", line 77\n res = hook_impl.function(*args)\n File \".../lib/python3.11/site-packages/_pytest/python.py\", line 194\n result = testfunction(**testargs)\n File \".../lib/python3.11/site-packages/pytest_asyncio/plugin.py\", line 532\n _loop.run_until_complete(task)\n File \"/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/base_events.py\", line 640\n self.run_forever()\n File \"/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/base_events.py\", line 607\n self._run_once()\n File \"/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/base_events.py\", line 1922\n handle._run()\n File \"/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/asyncio/events.py\", line 80\n self._context.run(self._callback, *self._args)\n File \".../lib/python3.11/site-packages/starlette/middleware/base.py\", line 70\n await self.app(scope, receive_or_disconnect, send_no_error)\n File \".../lib/python3.11/site-packages/starlette/middleware/exceptions.py\", line 68\n await self.app(scope, receive, sender)\n File \".../lib/python3.11/site-packages/fastapi/middleware/asyncexitstack.py\", line 17\n await self.app(scope, receive, send)\n File \".../python3.11/site-packages/starlette/routing.py\", line 718\n await route.handle(scope, receive, send)\n File \".../lib/python3.11/site-packages/starlette/routing.py\", line 276\n await self.app(scope, receive, send)\n File \".../lib/python3.11/site-packages/starlette/routing.py\", line 66\n response = await func(request)\n File \".../lib/python3.11/site-packages/fastapi/routing.py\", line 291\n content = await serialize_response(\n File \".../lib/python3.11/site-packages/fastapi/routing.py\", line 144\n value, errors_ = field.validate(response_content, {}, loc=(\"response\",))\n```\n\n```text\ntracemalloc\n```\n\n```text\nfastapi\n```\n\n```py\n@pytest.mark.asyncio()\nasync def test1(\n client: httpx.AsyncClient,\n mock1: MagicMock, ...\n) -> None:\n ...\n resp = await client.post(url=\"url\", json=jsonable_encoder(body.dict(), by_alias=True))\n assert resp.status_code == 200\n mock1.func.assert_awaited_once_with(...)\n```\n\n```text\nclient.post\n```\n\n========================================\n\nComments:\n- What does your tests look like? i.e. have you marked your tests with asyncio? Are you using `pytest-asyncio`?\n- @MatsLindh I added test example to question. Yes, I'm using `pytest-asyncio`\n- I am getting this error in the case of using `with pytest.raises()` where if the coroutine raises combined with this context manager, it makes asyncio think the coroutine was never awaited.","metadata":{"transformedAt":"2026-08-18T18:32:29.166Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":7,"totalLines":175,"estimatedTokens":1922}}795{"id":"stack-78574363","source":"stackoverflow","questionId":78574363,"title":"Why FastAPI isn't validating POST body?","tags":["python","fastapi","sqlmodel"],"text":"Title: Why FastAPI isn't validating POST body?\nTags: python, fastapi, sqlmodel\nSource: Stack Overflow\n\nQuestion:\nI'm working on a webserver built with FastAPI version 0.111.0 and SQLModel version 0.0.18.\n\nWhen I'm calling the POST endpoint with partial data or with keys I don't specify in my class, it doesn't trigger the unprocessable entity or bad request error. I'm using the method POST only for inserting data and not updating it. For update an entity, I use a separate PUT request.\n\nHere's my model:\n\n```\nfrom sqlmodel import SQLModel, Field\n\nclass Job(SQLModel, table=True):\n job_id: int = Field(primary_key=True)\n title: str\n start_time: str\n end_time: str | None = None\n pipeline_id: int = Field(foreign_key=\"pipeline.pipeline_id\")\n prj_path: str\n branch_tag: str\n user: str\n status: str\n log: str = \"\"\n result: str = \"\"\n```\n\nand here's the controller:\n\n```\nfrom fastapi import APIRouter\nfrom models.job import Job\n\njob_router = APIRouter(prefix=\"/job\", tags=[\"Jobs\"])\n\n@job_router.post(\"/\", status_code=201, response_model=Job)\nasync def add_job(job: Job):\n job = await c.insert_job(job)\n return job\n```\n\nThe `c.insert_job(job)` is where I'm saving the object in the database and the `job_router` is importend in the main file with the FastAPI app:\n\n```\nfrom fastapi import FastAPI\nfrom routers.job import job_router\n\napp = FastAPI()\n\napp.include_router(job_router)\n```\n\nEven if the auto-created documentation tells me that there are some required fields as shown here: \n\njob class in swagger \n\nif I'm sending a request with a body like `{ \"job_id\": 0 }` or even `{ \"job_id\": 0, \"test\": \"test\" }`, it passes without triggering anything like shown in the next image (here I return the partial object I get instead of adding it to the database because it would throw an error on fields without the default value): \n\nreturned object\n\n========================================\n\nCode:\n```text\nfrom sqlmodel import SQLModel, Field\n\nclass Job(SQLModel, table=True):\n job_id: int = Field(primary_key=True)\n title: str\n start_time: str\n end_time: str | None = None\n pipeline_id: int = Field(foreign_key=\"pipeline.pipeline_id\")\n prj_path: str\n branch_tag: str\n user: str\n status: str\n log: str = \"\"\n result: str = \"\"\n```\n\n```text\nfrom fastapi import APIRouter\nfrom models.job import Job\n\n\njob_router = APIRouter(prefix=\"/job\", tags=[\"Jobs\"])\n\n@job_router.post(\"/\", status_code=201, response_model=Job)\nasync def add_job(job: Job):\n job = await c.insert_job(job)\n return job\n```\n\n```text\nfrom fastapi import FastAPI\nfrom routers.job import job_router\n\napp = FastAPI()\n\napp.include_router(job_router)\n```\n\n```text\nc.insert_job(job)\n```\n\n```text\njob_router\n```\n\n```text\n{ \"job_id\": 0 }\n```\n\n```text\n{ \"job_id\": 0, \"test\": \"test\" }\n```\n\n```text\nfrom pydantic import BaseModel\n from typing import Optional\n class JobRead(BaseModel):\n job_id: int\n title: str\n start_time: str\n end_time: Optional[str] = Field(default=None)\n pipeline_id: int\n prj_path: str\n branch_tag: str\n user: str\n status: str\n log: Optional[str] = Field(default=\"\")\n result: Optional[str] = Field(default=\"\")\n```\n\n```text\nfrom fastapi import APIRouter\nfrom models.job import Job\n\n\njob_router = APIRouter(prefix=\"/job\", tags=[\"Jobs\"])\n\n@job_router.post(\"/\", status_code=201, response_model=Job)\nasync def add_job(job: Job = Depends()):\n job = await c.insert_job(job)\n return job\n```\n\n========================================\n\nComments:\n- I think I'm seeing the same behavior and it's really baffling. I am also using SQLModel and I'm even more surprised because SQLModel and FastAPI are from the same author so I'd expect them to work together seamlessly.\n- It seems this was a known issue in SQLModel and the suggestion is to create a normal Pydantic model but then inherit from that to create a separate SQLModel for database interactions github.com/fastapi/sqlmodel/issues/52 That seems to defeat the purpose of SQLModel to me.\n- Thanks, it worked! But I don't understand why using a class extending the BaseModel doesn't work and using BaseModel directly works...\n- Your code is not working because you use sqlmodel class. BaseModel it's pydantic's class which have validation. Excuse me for my English pls)\n- You need write classes for sql and for validate etc.\n- SQLModel is from the same author as FastAPI and the docs claim, \"And at the same time, ✨ it is also a Pydantic model ✨. You can use inheritance with it to define all your data models while avoiding code duplication. That makes it very easy to use with FastAPI.\" sqlmodel.tiangolo.com/#sqlalchemy-and-pydantic","metadata":{"transformedAt":"2026-08-18T18:32:29.166Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":158,"estimatedTokens":1168}}796{"id":"stack-78110110","source":"stackoverflow","questionId":78110110,"title":"Keycloak fastapi user registry","tags":["fastapi"],"text":"Title: Keycloak fastapi user registry\nTags: fastapi\nSource: Stack Overflow\n\nQuestion:\nSo I was testing a way to add more users to keycloak and I found this way:\n\n```\nkeycloak_connection = KeycloakOpenIDConnection(\n server_url=\"http://localhost:8080/*\",\n username='test',\n password='1234',\n realm_name=\"test_admin\",\n client_id=\"test_admin_user\",\n client_secret_key=\"1111111111111\",\n verify=True)\n\nkeycloak_admin = KeycloakAdmin(connection=keycloak_connection)\n\n# Add user\nnew_user = keycloak_admin.create_user({\"email\": \"test_email\",\n \"username\": \"alias\",\n \"enabled\": True,\n \"firstName\": \"top\",\n \"lastName\": \"top1\"})\n```\n\nBut then when I try this with keycloak I see this error:\n\n```\nkeycloak.exceptions.KeycloakPostError: 403: b'{\"error\":\"unknown_error\",\"error_description\":\"For more on this error consult the server log at the debug level.\"}'\n```\n\n========================================\n\nCode:\n```text\nkeycloak_connection = KeycloakOpenIDConnection(\n server_url=\"http://localhost:8080/*\",\n username='test',\n password='1234',\n realm_name=\"test_admin\",\n client_id=\"test_admin_user\",\n client_secret_key=\"1111111111111\",\n verify=True)\n\nkeycloak_admin = KeycloakAdmin(connection=keycloak_connection)\n\n# Add user\nnew_user = keycloak_admin.create_user({\"email\": \"test_email\",\n \"username\": \"alias\",\n \"enabled\": True,\n \"firstName\": \"top\",\n \"lastName\": \"top1\"})\n```\n\n```text\nkeycloak.exceptions.KeycloakPostError: 403: b'{\"error\":\"unknown_error\",\"error_description\":\"For more on this error consult the server log at the debug level.\"}'\n```\n\n```py\nfrom keycloak import KeycloakOpenIDConnection, KeycloakAdmin\n\nkeycloak_connection = KeycloakOpenIDConnection(\n server_url=\"http://localhost:8180\",\n username='test',\n password='1234',\n realm_name=\"test_admin\",\n user_realm_name=\"test_admin\",\n client_id=\"admin-cli\",\n verify=True\n)\nkeycloak_admin = KeycloakAdmin(connection=keycloak_connection)\n\n# Add user\nusers = keycloak_admin.get_users()\n\nisAlias = False\nfor user in users:\n print(\"user:\", user['username'])\n if (user['username'] == \"alias\"):\n isAlias = True\n\nif (not isAlias):\n new_user = keycloak_admin.create_user({\n \"email\": \"test_email@test.com\",\n \"username\": \"alias\",\n \"enabled\": True,\n \"emailVerified\": True,\n \"firstName\": \"top\",\n \"lastName\": \"top1\"\n })\n print(\"alias registered\")\n```\n\n```text\nrealm-management\n```\n\n```text\ncreate-user.py\n```\n\n========================================\n\nComments:\n- thank you for the help, can you please send me the documentation where this is?\n- @rainbow12, I referenced two documentation. One is Python Keycloak other is my other answer, Can you accept and up-vote for my answer?\n- I need to set up a session key from the js to store the refresh token. Do you have any topics that can point me to and help?\n- I handled access token before in here and here, you can find refresh token. If not success make a new question, I can help you.\n- thank you, I just did this question:stackoverflow.com/questions/78156424/…\n- OK, I will try it when I return home.\n- @rainbow12, I wonder for your tag. Why you add a tag `fastapi`, I think your question just `python`, `keycloak` and `python-keycloak`, I cant find ho to related with `fastapi`?\n- Sorry but are you referring to the question i posted?\n- OK, I got it this question no API decorator but your new question has `@app.post`, So that makes sense.","metadata":{"transformedAt":"2026-08-18T18:32:29.167Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":115,"estimatedTokens":967}}797{"id":"stack-72749927","source":"stackoverflow","questionId":72749927,"title":"Does FastAPI websocket example deadlock the process?","tags":["python","websocket","fastapi"],"text":"Title: Does FastAPI websocket example deadlock the process?\nTags: python, websocket, fastapi\nSource: Stack Overflow\n\nQuestion:\nThe code in the docs has a `while True:` block and I am curious if something like that would deadlock the process. If I get two requests, would the second one just not go through? why or why not?\n\nSource: https://fastapi.tiangolo.com/advanced/websockets/\n\n```\n@app.websocket(\"/ws\")\nasync def websocket_endpoint(websocket: WebSocket):\n await websocket.accept()\n while True:\n data = await websocket.receive_text()\n await websocket.send_text(f\"Message text was: {data}\")\n```\n\n========================================\n\nCode:\n```text\n@app.websocket(\"/ws\")\nasync def websocket_endpoint(websocket: WebSocket):\n await websocket.accept()\n while True:\n data = await websocket.receive_text()\n await websocket.send_text(f\"Message text was: {data}\")\n```\n\n```text\nwhile True:\n```\n\n```text\nwhile True\n```\n\n```text\nasync def\n```\n\n```text\nwhile True\n```\n\n```text\nawait\n```\n\n```text\nevent loop\n```\n\n```text\nawait websocket.receive_text()\n```\n\n```text\nawait websocket.send_text()\n```\n\n```text\nrequests\n```\n\n```text\nevent loop\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.167Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":11,"totalLines":69,"estimatedTokens":290}}798{"id":"stack-71211163","source":"stackoverflow","questionId":71211163,"title":"How to log the return value of a POST method after returning the response?","tags":["python","logging","fastapi","background-task"],"text":"Title: How to log the return value of a POST method after returning the response?\nTags: python, logging, fastapi, background-task\nSource: Stack Overflow\n\nQuestion:\nI'm working on my first ever REST API, so apologies in advance if I've missed something basic. I have a function that takes a JSON request from another server, processes it (makes a prediction based on the data), and returns another JSON with the results. I'd like to keep a log on the server's local disk of all requests to this endpoint along with their results, for evaluation purposes and for retraining the model. However, for the purposes of minimising the latency of returning the result to the user, I'd like to return the response data first, and then write it to the local disk. It's not obvious to me how to do this properly, as the FastAPI paradigm necessitates that the result of a POST method is the return value of the decorated function, so anything I want to do with the data has to be done *before* it is returned.\n\nBelow is a minimal working example of what I think is my closest attempt at getting it right so far, using a custom object with a `log` decorator - my idea was just to assign the result to the log object as a class attribute, then use another method to write it to disk, but I can't figure out how to make sure that that function gets called *after* `get_data` every time.\n\n```\nimport json\nimport uvicorn\nfrom fastapi import FastAPI, Request\nfrom functools import wraps\nfrom pydantic import BaseModel\n\nclass Blob(BaseModel):\n id: int\n x: float\n\ndef crunch_numbers(data: Blob) -> dict:\n # does some stuff\n return {'foo': 'bar'}\n\nclass PostResponseLogger:\n\n def __init__(self) -> None:\n self.post_result = None\n\n def log(self, func, *args, **kwargs):\n @wraps(func)\n def func_to_log(*args, **kwargs):\n post_result = func(*args, **kwargs)\n self.post_result = post_result\n\n # how can this be done outside of this function ???\n self.write_data()\n\n return post_result\n return func_to_log\n\n def write_data(self):\n if self.post_result:\n with open('output.json', 'w') as f:\n json.dump(self.post_result, f)\n\ndef main():\n app = FastAPI()\n logger = PostResponseLogger()\n\n @app.post('/get_data/')\n @logger.log\n def get_data(input_json: dict, request: Request):\n result = crunch_numbers(input_json)\n return result\n\n uvicorn.run(app=app)\n\nif __name__ == '__main__':\n main()\n```\n\nBasically, my question boils down to: \"is there a way, in the `PostResponseLogger` class, to automatically call `self.write_data` after every call to `self.log`?\", but if I'm using the wrong approach altogether, any other suggestions are also welcome.\n\n========================================\n\nCode:\n```text\nimport json\nimport uvicorn\nfrom fastapi import FastAPI, Request\nfrom functools import wraps\nfrom pydantic import BaseModel\n\nclass Blob(BaseModel):\n id: int\n x: float\n\ndef crunch_numbers(data: Blob) -> dict:\n # does some stuff\n return {'foo': 'bar'}\n\nclass PostResponseLogger:\n\n def __init__(self) -> None:\n self.post_result = None\n\n def log(self, func, *args, **kwargs):\n @wraps(func)\n def func_to_log(*args, **kwargs):\n post_result = func(*args, **kwargs)\n self.post_result = post_result\n\n # how can this be done outside of this function ???\n self.write_data()\n\n return post_result\n return func_to_log\n\n def write_data(self):\n if self.post_result:\n with open('output.json', 'w') as f:\n json.dump(self.post_result, f)\n\ndef main():\n app = FastAPI()\n logger = PostResponseLogger()\n\n @app.post('/get_data/')\n @logger.log\n def get_data(input_json: dict, request: Request):\n result = crunch_numbers(input_json)\n return result\n\n uvicorn.run(app=app)\n\nif __name__ == '__main__':\n main()\n```\n\n```text\nlog\n```\n\n```text\nget_data\n```\n\n```text\nPostResponseLogger\n```\n\n```text\nself.write_data\n```\n\n```text\nself.log\n```\n\n```text\ndef write_log_data():\n logger.write_data()\n```\n\n```text\nfrom fastapi import BackgroundTasks\n\n@app.post('/get_data/')\ndef get_data(input_json: dict, request: Request, background_tasks: BackgroundTasks):\n result = crunch_numbers(input_json)\n background_tasks.add_task(write_log_data)\n return result\n```\n\n```text\nBackground Task\n```\n\n```text\nBackgroundTasks\n```\n\n```text\nBackgroundTasks\n```\n\n```text\nwrite_log_data\n```\n\n```text\nbackground_tasks\n```\n\n```text\n.add_task()\n```\n\n```text\nBackgroundTasks\n```\n\n```text\nAPIRoute\n```\n\n```text\nasync/await\n```\n\n```text\nevent loop\n```\n\n```text\nasync def\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\nevent loop\n```\n\n```text\ndef\n```\n\n```text\nawait\n```\n\n========================================\n\nComments:\n- You may want to have a look at this answer.\n- I may be missing something, but i don't think there's anything there that solves my issue - as far as I can tell, FastAPI middleware can still only process a response *before* returning it\n- Ah cool, wasn't aware of this. Thank you!","metadata":{"transformedAt":"2026-08-18T18:32:29.167Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":24,"totalLines":225,"estimatedTokens":1250}}799{"id":"stack-71858816","source":"stackoverflow","questionId":71858816,"title":"Error uploading file to google cloud storage","tags":["python","google-cloud-platform","google-cloud-storage","fastapi"],"text":"Title: Error uploading file to google cloud storage\nTags: python, google-cloud-platform, google-cloud-storage, fastapi\nSource: Stack Overflow\n\nQuestion:\nHow should the files on my server be uploaded to google cloud storage?\n\nthe code I have tried is given below, however, it throws a type error, saying, the expected type is not byte for:\n\n```\nthe expected type is not byte for:\nblob.upload_from_file(file.file.read()).\n```\n\nAlthough upload_from_file requires a binary type.\n\n```\n@app.post(\"/file/\")\nasync def create_upload_file(files: List[UploadFile] = File(...)):\n storage_client = storage.Client.from_service_account_json(path.json)\n bucket_name = 'data'\n try:\n bucket = storage_client.create_bucket(bucket_name)\n except Exception:\n bucket = storage_client.get_bucket(bucket_name)\n for file in files: \n destination_file_name = f'{file.filename}'\n new_data = models.Data(\n path=destination_file_name\n )\n try:\n blob = bucket.blob(destination_file_name)\n blob.upload_from_file(file.file.read())\n except Exception:\n raise HTTPException(\n status_code=500,\n detail=\"File upload failed\"\n )\n```\n\n========================================\n\nCode:\n```text\nthe expected type is not byte for:\nblob.upload_from_file(file.file.read()).\n```\n\n```text\n@app.post(\"/file/\")\nasync def create_upload_file(files: List[UploadFile] = File(...)):\n storage_client = storage.Client.from_service_account_json(path.json)\n bucket_name = 'data'\n try:\n bucket = storage_client.create_bucket(bucket_name)\n except Exception:\n bucket = storage_client.get_bucket(bucket_name)\n for file in files: \n destination_file_name = f'{file.filename}'\n new_data = models.Data(\n path=destination_file_name\n )\n try:\n blob = bucket.blob(destination_file_name)\n blob.upload_from_file(file.file.read())\n except Exception:\n raise HTTPException(\n status_code=500,\n detail=\"File upload failed\"\n )\n```\n\n```py\n# Rewind the stream to the beginning. This step can be omitted if the \n# input stream is at a correct position.\nfile.seek(0)\n\n# Upload data from the stream to your bucket\nblob.upload_from_file(file.file)\n```\n\n```py\nblob.upload_from_string(file.file.read())\n```\n\n```py\ncontents = await file.read()\nblob.upload_from_string(contents)\n```\n\n```py\nfrom tempfile import NamedTemporaryFile\nimport os\n\ncontents = file.file.read()\ntemp = NamedTemporaryFile(delete=False)\ntry:\n with temp as f:\n f.write(contents);\n blob.upload_from_filename(temp.name)\nexcept Exception:\n return {\"message\": \"There was an error uploading the file\"}\nfinally:\n #temp.close() # the `with` statement above takes care of closing the file\n os.remove(temp.name)\n```\n\n```py\nawait run_in_threadpool(blob.upload_from_file, file.file)\n```\n\n```py\nasync with aiofiles.tempfile.NamedTemporaryFile(\"wb\", delete=False) as temp:\n contents = await file.read()\n await temp.write(contents)\n #...\n```\n\n```py\nawait run_in_threadpool(blob.upload_from_filename, temp.name)\n```\n\n```text\nupload_from_file()\n```\n\n```text\n.file\n```\n\n```text\nUploadFile\n```\n\n```text\nSpooledTemporaryFile\n```\n\n```text\nread()\n```\n\n```text\nfile.read()\n```\n\n```text\nseek()\n```\n\n```text\nfile.seek(0)\n```\n\n```text\nfile\n```\n\n```text\nupload_from_string()\n```\n\n```text\ndata\n```\n\n```text\nbytes\n```\n\n```text\nstring\n```\n\n```text\nasync def\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\nupload_from_filename()\n```\n\n```text\nfilename\n```\n\n```text\nfile\n```\n\n```text\nNo such file or directory\n```\n\n```text\nfile.filename\n```\n\n```text\nfile\n```\n\n```text\nNamedTemporaryFile\n```\n\n```text\npython-storage\n```\n\n```text\ntimeout\n```\n\n```text\ntimeout\n```\n\n```text\nupload_from_file()\n```\n\n```text\ntimeout=60\n```\n\n```text\nblob.upload_from_file(file.file, timeout=180)\n```\n\n```text\ntimeout=None\n```\n\n```text\npython-storage\n```\n\n```text\ncreate_upload_file\n```\n\n```text\nasync def\n```\n\n```text\ndef\n```\n\n```text\ndef\n```\n\n```text\nasync def\n```\n\n```text\nrun_in_threadpool()\n```\n\n```text\nasyncio\n```\n\n```text\nloop.run_in_executor()\n```\n\n```text\npython-storage\n```\n\n```text\nNamedTemporaryFile\n```\n\n```text\naiofiles\n```\n\n```text\ntry-except-finally\n```\n\n```text\nUploadFile\n```\n\n```text\nUploadFile\n```\n\n```text\nSpooledTemporaryFile\n```\n\n```text\nmax_size\n```\n\n```text\ntemp\n```\n\n```text\n.close()\n```\n\n========================================\n\nComments:\n- Use **blob.upload_from_filename(file.filename)**\n- @JohnHanley Thank you, however when I do that, it says given file name is not found, what could be the reason?\n- What is the filename? Does it exist?\n- it is what is taken from fastapi UploadFile: file = File(...). file.filename exists. but when passed to blob.upload_from_filename(file.filename), it throws error that \"No such file or directory\".\n- Thank you very much for the all mentioned options, and for your time. However, there is still an \"Internal server error\" when I try to upload large files (up to 1 GB) with provided solutions, do you think I should send them as chunks? or the reason is something else?\n- It was related to the default timeout limit of upload_from_file(). initializing it to None solved the problem. Thank you very much for your response again.","metadata":{"transformedAt":"2026-08-18T18:32:29.167Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":58,"totalLines":327,"estimatedTokens":1302}}800{"id":"stack-73653352","source":"stackoverflow","questionId":73653352,"title":"Strawberry+FastAPI: How to get request-info in a dependency?","tags":["python","fastapi","strawberry-graphql"],"text":"Title: Strawberry+FastAPI: How to get request-info in a dependency?\nTags: python, fastapi, strawberry-graphql\nSource: Stack Overflow\n\nQuestion:\nConsider this code:\n\n```\nimport strawberry\n\nfrom fastapi import FastAPI, Depends, Request, WebSocket, BackgroundTasks\nfrom strawberry.types import Info\nfrom strawberry.fastapi import GraphQLRouter\n\ndef custom_context_dependency() -> str:\n # ===> need to get request here, to get request header\n return \"John\"\n\ndef has_root_access() -> bool:\n # ===> need to get request and header to get user info\n # and user permissions\n return False\n\nasync def get_context(\n custom_value=Depends(custom_context_dependency),\n has_root_access=Depends(has_root_access),\n):\n return {\n \"custom_value\": custom_value,\n \"has_root_access\": has_root_access,\n }\n\n@strawberry.type\nclass Query:\n @strawberry.field\n def example(self, info: Info) -> str:\n return f\"Hello {info.context['custom_value']}\"\n\nschema = strawberry.Schema(Query)\ngraphql_app = GraphQLRouter(\n schema,\n context_getter=get_context,\n)\n\napp = FastAPI()\napp.include_router(graphql_app, prefix=\"/graphql\")\n```\n\nHow do I get the request info in the dependencies `custom_context_dependency` and `has_root_access`?\n\n========================================\n\nCode:\n```py\nimport strawberry\n\nfrom fastapi import FastAPI, Depends, Request, WebSocket, BackgroundTasks\nfrom strawberry.types import Info\nfrom strawberry.fastapi import GraphQLRouter\n\n\ndef custom_context_dependency() -> str:\n # ===> need to get request here, to get request header\n return \"John\"\n\ndef has_root_access() -> bool:\n # ===> need to get request and header to get user info\n # and user permissions\n return False\n\nasync def get_context(\n custom_value=Depends(custom_context_dependency),\n has_root_access=Depends(has_root_access),\n):\n return {\n \"custom_value\": custom_value,\n \"has_root_access\": has_root_access,\n }\n\n\n@strawberry.type\nclass Query:\n @strawberry.field\n def example(self, info: Info) -> str:\n return f\"Hello {info.context['custom_value']}\"\n\nschema = strawberry.Schema(Query)\ngraphql_app = GraphQLRouter(\n schema,\n context_getter=get_context,\n)\n\napp = FastAPI()\napp.include_router(graphql_app, prefix=\"/graphql\")\n```\n\n```text\ncustom_context_dependency\n```\n\n```text\nhas_root_access\n```\n\n```py\ndef custom_context_dependency(\n request: Request = None,\n websocket: WebSocket = None,\n) -> str:\n item = request or websocket\n ...\n return \"John\"\n```\n\n```py\ndef custom_context_dependency(\n Authorization: str = Header(None)\n) -> str:\n ...\n```\n\n```text\nRequest\n```\n\n```text\nHeader\n```\n\n========================================\n\nComments:\n- In plain FastAPI you can add a parameter typed as `Request` to your dependency and it'll automagically be filled. Since it seems strawberry can use the same Dependency system (with Depends being filled) through FastAPI, I'm guessing you can just add the parameter: `def custom_context_dependency(request: Request) -> str:`\n- It works! But request is not always supplied. I'll add an answer","metadata":{"transformedAt":"2026-08-18T18:32:29.167Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":7,"totalLines":134,"estimatedTokens":765}}801{"id":"stack-70665879","source":"stackoverflow","questionId":70665879,"title":"Use trio nursery as a generator for Sever Sent Events with FastAPI?","tags":["python","async-await","fastapi","server-sent-events","python-trio"],"text":"Title: Use trio nursery as a generator for Sever Sent Events with FastAPI?\nTags: python, async-await, fastapi, server-sent-events, python-trio\nSource: Stack Overflow\n\nQuestion:\nI'm trying to build a Server-Sent Events endpoint with FastAPI but I'm unsure if what I'm trying to accomplish is possible or how I would go about doing it.\n\n### Introduction to the problem\n\nBasically let's say I have a `run_task(limit, task)` async function that sends an async request, makes a transaction, or something similar. Let's say that for each task `run_task` can return some JSON data.\n\nI'd like to run multiple tasks (multiple `run_task(limit, task)`) asynchronously, to do so I'm using trio and nurseries like so:\n\n```\nasync with trio.open_nursery() as nursery:\n limit = trio.CapacityLimiter(10)\n for task in tasks:\n nursery.start_soon(run_task, limit, task)\n```\n\nAnd finally, I want to return the results of each task via a FastAPI endpoint\n\nAt first, I simply created an object containing a list, and passed that object (by reference) to each `run_task`, when a task was finished I'd push the JSON data as a dictionary, and return the whole object via the endpoint once all the tasks were finished.\n\nThis works, but I find it inefficient, the client sending the request needs to wait for all the tasks to finish before it can display the data, however, some tasks can be quite slow, meaning the data fetched from other tasks just ends up stagnating.\n\n### What I would like to accomplish\n\nWhenever a task is finished, I'd want the API to directly return the data of said task (that I would've previously added to the object) so that the client can display said data in real-time.\n\nThat's when I discovered what Server-Sent Events and Web-sockets were. Server sent events seemed like the appropriate solution to my problem, as I don't need bidirectional communication.\n\nSince FastAPI is built on Starlette, I decided to use sse-Starlette to build an endpoint with server-sent events, to do so I need to build an endpoint like so\n\n```\n@router.get('/stream')\nasync def runTasks(\n param1: str,\n request: Request\n):\n event_generator = status_event_generator(request, param1)\n return EventSourceResponse(event_generator)\n```\n\n### The actual problem\n\nAs the name `status_event_generator` implies, sse-starlette needs to return an event generator, and that's where I'm kind of stuck. I'd want the generator to yield the data of a task when it finishes (so that the client can receive the data of each task in real-time), however, the tasks are within the async trio nursery so I'm unsure how to proceed\n\nAs per Is yielding from inside a nursery in an asynchronous generator function bad?, it seems (if I understand correctly) that I can't just put a yield in `run_task(limit, task)` and expect it to work\n\n========================================\n\nCode:\n```py\nasync with trio.open_nursery() as nursery:\n limit = trio.CapacityLimiter(10)\n for task in tasks:\n nursery.start_soon(run_task, limit, task)\n```\n\n```py\n@router.get('/stream')\nasync def runTasks(\n param1: str,\n request: Request\n):\n event_generator = status_event_generator(request, param1)\n return EventSourceResponse(event_generator)\n```\n\n```text\nrun_task(limit, task)\n```\n\n```text\nrun_task\n```\n\n```text\nrun_task(limit, task)\n```\n\n```text\nrun_task\n```\n\n```text\nstatus_event_generator\n```\n\n```text\nrun_task(limit, task)\n```\n\n```py\n@router.websocket('/stream')\nasync def runTasks(\n websocket: WebSocket\n):\n # Initialise websocket\n await websocket.accept()\n\n # Receive data\n tasks = await websocket.receive_json()\n\n async with trio.open_nursery() as nursery:\n limit = trio.CapacityLimiter(10)\n for task in tasks:\n nursery.start_soon(run_task, limit, task, websocket)\n```\n\n```text\nawait websocket.send_json()\n```\n\n```text\nrun_task\n```\n\n========================================\n\nComments:\n- Since yielding is only a problem across a nursery boundary, would an ambient nursery work?\n- @user3840170 possibly? I must admit I don't quite know what am ambient nursery is, or how I'd implement it\n- It's a term I made up. Basically, open a nursery somewhere in a wider scope that will contain the loop that goes over the generator, and use that nursery in the generator itself to spawn background tasks.\n- Ah right, but if the stackoverflow question I had linked is correct, I unfortunately believe that the yield operator isn't accessible anywhere in the nursery, neither in the tasks nor the nursery itself, meaning opening a nursery in a wider scope and putting the generator in it wouldn't work either\n- : *We don’t actually want to forbid every `yield` that happens *inside* our `with` block; we only want to forbid `yield`s that *temporarily exit the with block*. It’s fine if the code inside the `with` block iterates over a generator that has some internal `yield`.* Written by the same person who wrote the answer under that question, who is also the author of the trio library. I’ll give him the benefit of the doubt that he knows what he is talking about.\n- That's really interesting, I'll have to try and experiment. Do you believe if I use `for task in tasks` as the generator loop, and add a yield within the `run_task`, it might work?","metadata":{"transformedAt":"2026-08-18T18:32:29.167Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":11,"totalLines":128,"estimatedTokens":1316}}802{"id":"stack-75931697","source":"stackoverflow","questionId":75931697,"title":"Sentry traces_sampler(sampling_context) how to use with FastAPI","tags":["python","fastapi","sentry"],"text":"Title: Sentry traces_sampler(sampling_context) how to use with FastAPI\nTags: python, fastapi, sentry\nSource: Stack Overflow\n\nQuestion:\nIn sentry docs there is example\n\nhttps://docs.sentry.io/platforms/python/configuration/sampling/\n\n```\ndef traces_sampler(sampling_context):\n # Examine provided context data (including parent decision, if any)\n # along with anything in the global namespace to compute the sample rate\n # or sampling decision for this transaction\n\n if \"...\":\n # These are important - take a big sample\n return 0.5\n else:\n # Default sample rate\n return 0.1\n\nsentry_sdk.init(\n # ...\n\n traces_sampler=traces_sampler,\n)\n```\n\nbut there are no typing for `sampling_context` variable, I have no idea how to filter specific http route in case of FastAPI integration.\n\nPls advice how to set different sample rate for specific route ?\n\n========================================\n\nCode:\n```text\ndef traces_sampler(sampling_context):\n # Examine provided context data (including parent decision, if any)\n # along with anything in the global namespace to compute the sample rate\n # or sampling decision for this transaction\n\n if \"...\":\n # These are important - take a big sample\n return 0.5\n else:\n # Default sample rate\n return 0.1\n\nsentry_sdk.init(\n # ...\n\n traces_sampler=traces_sampler,\n)\n```\n\n```text\nsampling_context\n```\n\n```text\n{\n 'type': 'http',\n 'asgi': {\n 'version': '3.0',\n 'spec_version': '2.3'\n },\n 'http_version': '1.0',\n 'server': ('127.0.0.1', 8000),\n 'client': ('127.0.0.1', 37458),\n 'scheme': 'http',\n 'method': 'GET',\n 'root_path': '',\n 'path': '/',\n 'raw_path': b'/',\n 'query_string': b'',\n 'headers': [...],\n 'state': {},\n}\n```\n\n```text\nsampling_context\n```\n\n```text\nasgi_scope\n```\n\n```text\nasgi_scope\n```\n\n```text\npath\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.167Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":7,"totalLines":96,"estimatedTokens":451}}803{"id":"stack-70366407","source":"stackoverflow","questionId":70366407,"title":"how to run a script on server using fastApi","tags":["python","fastapi"],"text":"Title: how to run a script on server using fastApi\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\ni'm new to fastAPI\nimported a script into the main.py in my fastAPI based api\n\n```\nimport example\n```\n\nhow to run the script when calling the url with value in the script\n\nlike http://127.0.0.1:8000/url=https://google.com\n\nto make the script waiting for the value after \"url=\"\n\n========================================\n\nCode:\n```text\nimport example\n```\n\n```text\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/{param}\")\nasync def read_user_item(param: str, url: str):\n item = {\"param\": param, \"url\": url}\n return item\n```\n\n========================================\n\nComments:\n- Possible `?` symbol missing in query.","metadata":{"transformedAt":"2026-08-18T18:32:29.167Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":2,"totalLines":40,"estimatedTokens":184}}804{"id":"stack-72576972","source":"stackoverflow","questionId":72576972,"title":"Returning response in FastAPI takes a long time and blocks everything","tags":["python","fastapi"],"text":"Title: Returning response in FastAPI takes a long time and blocks everything\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI got problem with my api FastAPI, I got a big request that return me 700k rows. This request take 50 sec to be treat. But, the return response take 2mins and completely block the server who can't handle other request during those 2 mins.\n\nAnd I don't Know how to handle this ... Here is my code :\n\n```\n@app.get(\"/request\")\nasync def request_db(data):\n dict_of_result = await run_in_threadpool(get_data_from_pgsql, data)\n # After 50 sec the code above is done with even others requests coming working\n\n # But this return below block the server for 2min !\n return dict_of_result\n```\n\nI can't add limit or pagination system that request is for specefic purpose. Thank you for help\n\n========================================\n\nTop Answer:\nYou should not make a 700k row database request from FastAPI or any other web server.\n\nI would update this application logic / query to offload the processing to the database or to an external worker and only make a query for the result.\n\nAsyncIO prevents the application from blocking while *waiting* for IO, not processing what must be a huge amount of IO. This is especially worse in Python where you are single process bound by the GIL (Global Interpreter Lock).\n\n========================================\n\nCode:\n```text\n@app.get(\"/request\")\nasync def request_db(data):\n dict_of_result = await run_in_threadpool(get_data_from_pgsql, data)\n # After 50 sec the code above is done with even others requests coming working\n\n # But this return below block the server for 2min !\n return dict_of_result\n```\n\n```py\n@app.get(\"/request\")\nasync def request_db(data):\n dict_of_result = await run_in_threadpool(get_data_from_pgsql, data)\n # After 50 sec the code above is done with even others requests coming working\n def chunk_emitter():\n # How to split() will depend on the data since this is a dict\n for chunk in split(dict_of_result, CHUNK_SIZE):\n yield chunk\n\n headers = {'Content-Disposition': 'attachment'}\n return StreamingResponse(chunk_emitter(), headers=headers, media_type='application/json')\n```\n\n========================================\n\nComments:\n- Run multiple workers with your webserver (`-w` usually), and depending on how `get_data_from_pgsql` is implemented, make sure that it handles its IO async as well.\n- Have a look at related answers here and here as well.","metadata":{"transformedAt":"2026-08-18T18:32:29.167Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":2,"totalLines":62,"estimatedTokens":624}}805{"id":"stack-73062925","source":"stackoverflow","questionId":73062925,"title":"How to send JSON data from Nuxt Axios to a FastAPI backend through a POST request?","tags":["vue.js","axios","nuxt.js","fastapi"],"text":"Title: How to send JSON data from Nuxt Axios to a FastAPI backend through a POST request?\nTags: vue.js, axios, nuxt.js, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm trying to send user data from Nuxt.js using Axios via a `POST` request. The data is already provided via a Javascript cdn function that returns an object with `user` parameters, so I wouldn't want to use a `form` since I'm forwarding the `user` data I received as `JSON`.\n\nI wanted to know if the method I'm using is the right way of doing this? I need to send the `user` information in order to send a query in the backend to an external API (requiring a token from both the front and the back end, e.g., user token and app token).\n\nHere is my current iteration:\n\n```\n\nexport default {\n head (){\n return {\n __dangerouslyDisableSanitizers: ['script'],\n script: [\n {\n hid: 'platform-api',\n src: \"https://cdn-sample.app.com/api\",\n type: 'text/javascript',\n defer: true\n },\n ]\n }\n },\n computed: {\n // Change user token parameter according to docs\n // Add Neccessary parameters\n auth_token: {\n get(){\n let userdata = getPlatformContext();\n this.$store.state.user.auth_token = userdata.auth_token;\n return this.$store.state.user.auth_token;\n },\n set(value){\n this.$store.commit(\"item/storeAuthToken\", value)\n }\n },\n // Additional parameters omitted as they extract each parameter in the same way\n // as above.\n methods: {\n // I tried to test it by sending just the user token by clicking a button\n async sendUserToken(auth_token) {\n await this.$axios.post(this.$config.baseURL, user.auth_token);\n },\n // Then i wanted instead to try and send the whole json dict of user data to \n // backend and sort the data over in fastapi according to what i need.\n async sendUserData(user) {\n await this.$axios.post(this.$config.baseURL, user);\n }\n \n },\n \n}\n\n```\n\nSo, if I wanted to send the user data as a `POST` request in `JSON` format, not as a `form`, what would be the best way to do this?\n\n========================================\n\nCode:\n```js\n<script>\nexport default {\n head (){\n return {\n __dangerouslyDisableSanitizers: ['script'],\n script: [\n {\n hid: 'platform-api',\n src: \"https://cdn-sample.app.com/api\",\n type: 'text/javascript',\n defer: true\n },\n ]\n }\n },\n computed: {\n // Change user token parameter according to docs\n // Add Neccessary parameters\n auth_token: {\n get(){\n let userdata = getPlatformContext();\n this.$store.state.user.auth_token = userdata.auth_token;\n return this.$store.state.user.auth_token;\n },\n set(value){\n this.$store.commit(\"item/storeAuthToken\", value)\n }\n },\n // Additional parameters omitted as they extract each parameter in the same way\n // as above.\n methods: {\n // I tried to test it by sending just the user token by clicking a button\n async sendUserToken(auth_token) {\n await this.$axios.post(this.$config.baseURL, user.auth_token);\n },\n // Then i wanted instead to try and send the whole json dict of user data to \n // backend and sort the data over in fastapi according to what i need.\n async sendUserData(user) {\n await this.$axios.post(this.$config.baseURL, user);\n }\n \n },\n \n}\n\n</script>\n```\n\n```text\nPOST\n```\n\n```text\nuser\n```\n\n```text\nform\n```\n\n```text\nuser\n```\n\n```text\nJSON\n```\n\n```text\nuser\n```\n\n```text\nPOST\n```\n\n```text\nJSON\n```\n\n```text\nform\n```\n\n```py\nfrom fastapi import FastAPI, Request, Body\nfrom fastapi.templating import Jinja2Templates\nfrom pydantic import BaseModel\n\napp = FastAPI()\ntemplates = Jinja2Templates(directory=\"templates\")\n\nclass User(BaseModel):\n username: str\n address: str\n \n@app.get(\"/\")\ndef main(request: Request):\n return templates.TemplateResponse(\"index.html\", {\"request\": request})\n \n@app.post(\"/submit\")\ndef main(user: User):\n return user\n```\n\n```html\n<script type=\"text/javascript\" src=\"https://cdnjs.cloudflare.com/ajax/libs/axios/0.27.2/axios.min.js\"></script>\n<script type=\"text/javascript\">\nfunction uploadJSONdata() {\n axios({\n method: 'post',\n url: '/submit',\n data: JSON.stringify({\"username\": \"some name\", \"address\": \"some address\"}),\n headers: {\n 'Accept': 'application/json',\n 'Content-Type': 'application/json'\n },\n })\n .then(response => {\n console.log(response);\n document.getElementById(\"p1\").innerHTML = JSON.stringify(response.data);\n })\n .catch(error => {\n console.error(error);\n });\n}\n</script>\n<p id=\"p1\"></p>\n<input type=\"button\" value=\"submit\" onclick=\"uploadJSONdata()\">\n```\n\n```js\nthis.$axios.post('/submit', {\n username: 'some name',\n address: 'some address'\n })\n .then(function (response) {\n console.log(response);\n })\n .catch(function (error) {\n console.log(error);\n });\n```\n\n```text\nJSON\n```\n\n```text\nJSON\n```\n\n```text\nJSON.stringify()\n```\n\n```text\nBody\n```\n\n```text\nBody\n```\n\n```text\nBody\n```\n\n========================================\n\nComments:\n- Thank you, this helped me figure out how to implement this. I've decided to store state of a function with the required info and then post the user info to backend.","metadata":{"transformedAt":"2026-08-18T18:32:29.167Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":19,"totalLines":237,"estimatedTokens":1367}}806{"id":"stack-67154839","source":"stackoverflow","questionId":67154839,"title":"FastAPI - Best way to run continuous GET requests in the background","tags":["python","celery","fastapi"],"text":"Title: FastAPI - Best way to run continuous GET requests in the background\nTags: python, celery, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to create a program which does periodic GET requests from around 10 websites and updates the information in a DB locally. Now when a user wants information, I will display the locally stored aggregate info.\n\nI am trying to figure out the best way to run these periodic GET requests in FastAPI. I am new to FastAPI and am still trying to figure things out.\n\nAfter some research I can think of two options:\n\n- Using a background task endpoint which runs periodically and does the GET requests one by one from each website.\n\n- Using Celery to do these GET requests\n\nIf anyone has any experience of doing something similar I am trying to figure out the best way to do this, or how would I go about finding out the best way to do this?\n\n========================================\n\nCode:\n```text\nTIME_INTERVAL_IN_SEC = 60\n\n\nasync def crawl_websites():\n while True:\n # async GET requests\n # async update DB\n await asyncio.sleep(TIME_INTERVAL_IN_SEC)\n\n\nloop = asyncio.get_event_loop()\ntask = loop.create_task(crawl_websites())\nloop.run_until_complete(task)\n```\n\n```text\nasyncio\n```\n\n========================================\n\nComments:\n- Just checking. FastAPI is used to build web sites. If this is a background task that is independent of incoming requests, then it doesn't need FastAPI. It can just be a periodic `cron` job that does a series of requests using the `requests` module. Right?\n- Yeah that makes sense as well thanks. Since I am using FastAPI for the website itself, I thought that using fastAPI for this particular purpose makes sense since it already has DB connectivity in the app and things like that. But I will consider using this as well. Thank you\n- Future readers might benefit from the following answers: here and here, as well as here, here and here\n- Thank you for your reply. I will try this approach. The way I understand it, if I run this block within fastAPI, it will run in the same event loop as the rest of the backend functionality. So you would suggest that I run this from a script outside of fastAPI or it would not make any difference if I run it from within fastAPI?\n- You can run within fast API, there is also a discussion about that here: github.com/tiangolo/fastapi/issues/543","metadata":{"transformedAt":"2026-08-18T18:32:29.167Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":2,"totalLines":48,"estimatedTokens":597}}807{"id":"stack-65998660","source":"stackoverflow","questionId":65998660,"title":"Change default naming-behavior for operation_id","tags":["fastapi","openapi","openapi-generator"],"text":"Title: Change default naming-behavior for operation_id\nTags: fastapi, openapi, openapi-generator\nSource: Stack Overflow\n\nQuestion:\nIf I generate a Java client based on the following endpoint:\n\n```\napi_users = APIRouter(prefix='/api/users', tags=['users'])\n\nclass User(BaseModel):\n name: str\n\n@api_users.get(\n path='',\n response_model=List[User],\n)\nasync def get_users():\n return [User(name='test')]\n```\n\nThe method name inside the `UserApi.java` file for it will be `getUsersApiUsersGet()` instead of `getUsers()`. I have to set the `operation_id` to something like `get_users` as in\n\n```\n@api_users.get(\n path='',\n response_model=List[User],\n operation_id='get_users'\n)\n```\n\nbut this is tedious. Why isn't it just grabbing the method name itself, and uses this as default value instead?\n\nSo, is there a way I can change that behavior?\n\n========================================\n\nCode:\n```py\napi_users = APIRouter(prefix='/api/users', tags=['users'])\n\n\nclass User(BaseModel):\n name: str\n\n\n@api_users.get(\n path='',\n response_model=List[User],\n)\nasync def get_users():\n return [User(name='test')]\n```\n\n```py\n@api_users.get(\n path='',\n response_model=List[User],\n operation_id='get_users'\n)\n```\n\n```text\nUserApi.java\n```\n\n```text\ngetUsersApiUsersGet()\n```\n\n```text\ngetUsers()\n```\n\n```text\noperation_id\n```\n\n```text\nget_users\n```\n\n```py\ndef use_route_names_as_operation_ids(application: FastAPI) -> None:\n \"\"\"\n Simplify operation IDs so that generated API clients have simpler function\n names.\n\n Should be called only after all routes have been added.\n \"\"\"\n for route in application.routes:\n if isinstance(route, APIRoute):\n route: APIRoute = route\n route.operation_id = route.name\n\n\napp = FastAPI()\ncontroller.initialize(app)\nuse_route_names_as_operation_ids(app) # Call after controller were initialized\n```\n\n========================================\n\nComments:\n- I do not understand your question. Are you trying to call python code from `java`?\n- @lsabi Already figured it out. But thanks :)","metadata":{"transformedAt":"2026-08-18T18:32:29.167Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":8,"totalLines":106,"estimatedTokens":515}}808{"id":"stack-67797373","source":"stackoverflow","questionId":67797373,"title":"Download image on heroku","tags":["python","heroku","fastapi"],"text":"Title: Download image on heroku\nTags: python, heroku, fastapi\nSource: Stack Overflow\n\nQuestion:\ni have a simple function in fastapi python\n\n```\nurl=\"some_random_video_url_here\"\nre = requests.get(url)\nwith open(\"download/hello.png\", 'wb') as file: #save hello.png to download folder\n file.write(re.content)\n file.close()\n```\n\nthis function work locally fine and download image and any files bot when upload on heroku not download image and save in staticsFiles folder\n\nplease help\n\n========================================\n\nCode:\n```text\nurl=\"some_random_video_url_here\"\nre = requests.get(url)\nwith open(\"download/hello.png\", 'wb') as file: #save hello.png to download folder\n file.write(re.content)\n file.close()\n```\n\n========================================\n\nComments:\n- first you should check if you get any error message in logs. Second you should check in documentation if heroku doesn't block access to external servers - to stop spamers/hackers/bots.","metadata":{"transformedAt":"2026-08-18T18:32:29.167Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":1,"totalLines":34,"estimatedTokens":241}}809{"id":"stack-70066194","source":"stackoverflow","questionId":70066194,"title":"Run Scrapy from a script when it gets a request","tags":["python","scrapy","fastapi"],"text":"Title: Run Scrapy from a script when it gets a request\nTags: python, scrapy, fastapi\nSource: Stack Overflow\n\nQuestion:\nI have a **FastAPI** server that is listening to an endpoint, after receiving any post request, it will use **Scrapy** to grab some data depending on that data it's gotten from post request.\n\n```\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\nfrom typing import List\nfrom scrapy.crawler import CrawlerProcess\nfrom scrapy.utils.project import get_project_settings\n\nclass Request(BaseModel):\n someIDs: List[str]\n\nprocess = CrawlerProcess(get_project_settings())\n\napp = FastAPI()\n\n@app.post(\"/\")\ndef home(request: Request):\n process.crawl('rt_criteria', ids=request.someIDs)\n process.start() # the script will block here until the crawling is finished\n return {\"crawled\": True}\n\n# uvicorn main:app --reload\n```\n\nThis code will run for the first time as I expect, but for the second time, I will get\n\n```\ntwisted.internet.error.ReactorNotRestartable\n```\n\nerror on:\n\n```\nprocess.start()\n```\n\nWhere should I write this and How can I fix the error?\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\nfrom typing import List\nfrom scrapy.crawler import CrawlerProcess\nfrom scrapy.utils.project import get_project_settings\n\n\nclass Request(BaseModel):\n someIDs: List[str]\n\n\nprocess = CrawlerProcess(get_project_settings())\n\napp = FastAPI()\n\n\n@app.post(\"/\")\ndef home(request: Request):\n process.crawl('rt_criteria', ids=request.someIDs)\n process.start() # the script will block here until the crawling is finished\n return {\"crawled\": True}\n\n# uvicorn main:app --reload\n```\n\n```text\ntwisted.internet.error.ReactorNotRestartable\n```\n\n```text\nprocess.start()\n```\n\n```py\nfrom fastapi import FastAPI, BackgroundTasks\n\n# *** Not changed codes ***\n\n@app.post(\"/\")\nasync def home(request: Request, bt: BackgroundTasks):\n process.crawl('rt_criteria', mid=request.movieIDs)\n # Changed line below using Background tasks\n bt.add_task(process.start, stop_after_crawl=False)\n return {\"crawled\": True}\n\n# uvicorn main:app --reload\n```\n\n========================================\n\nComments:\n- Please note that background tasks run in the event loop; hence, if you performed any blocking operations inside a background task, it would block the event loop (and hence, the entire server), unless you defined the background task function with normal `def`, which, in that case, would be run in an external threadpool and then `await`ed. Please have a look at this answer for more details.","metadata":{"transformedAt":"2026-08-18T18:32:29.167Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":100,"estimatedTokens":644}}810{"id":"stack-69791631","source":"stackoverflow","questionId":69791631,"title":"Which port to expose on Docker for AWS Lambda?","tags":["docker","aws-lambda","serverless","fastapi"],"text":"Title: Which port to expose on Docker for AWS Lambda?\nTags: docker, aws-lambda, serverless, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to host a very simple (Hello World) FastAPI on AWS Lambda using Docker image. The image is working fine locally but when I am running it on Lambda it shows me the port binding error. Below are the error details that I am getting when I am trying to test the Lambda function with this image.\n\n```\nSTART RequestId: ae27e3b1-596d-41f3-a153-51cb9facc7a7 Version: $LATEST\nINFO: Started server process [8]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\nERROR: [Errno 13] error while attempting to bind on address ('0.0.0.0', 80): permission denied\nINFO: Waiting for application shutdown.\nINFO: Application shutdown complete.\nEND RequestId: ae27e3b1-596d-41f3-a153-51cb9facc7a7\nREPORT RequestId: ae27e3b1-596d-41f3-a153-51cb9facc7a7 Duration: 3034.14 ms Billed Duration: 3000 ms Memory Size: 128 MB Max Memory Used: 20 MB \n2021-11-01T00:23:59.807Z ae27e3b1-596d-41f3-a153-51cb9facc7a7 Task timed out after 3.03 seconds\n```\n\nThis says that I cant bind port 80 on 0.0.0.0, so any idea what port and host should I use in the Dockerfile to make it work on AWS Lambda? Thanks (Below is the Dockerfile which I am using)\n\n```\nFROM python:3.9\n\nWORKDIR /code\n\nCOPY ./requirements.txt /code/requirements.txt\n\nRUN pip install -r /code/requirements.txt\n\nCOPY . /code\n\nCMD [\"uvicorn\", \"main:app\", \"--host\", \"0.0.0.0\", \"--port\", \"80\"]\n```\n\n========================================\n\nCode:\n```text\nSTART RequestId: ae27e3b1-596d-41f3-a153-51cb9facc7a7 Version: $LATEST\nINFO: Started server process [8]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\nERROR: [Errno 13] error while attempting to bind on address ('0.0.0.0', 80): permission denied\nINFO: Waiting for application shutdown.\nINFO: Application shutdown complete.\nEND RequestId: ae27e3b1-596d-41f3-a153-51cb9facc7a7\nREPORT RequestId: ae27e3b1-596d-41f3-a153-51cb9facc7a7 Duration: 3034.14 ms Billed Duration: 3000 ms Memory Size: 128 MB Max Memory Used: 20 MB \n2021-11-01T00:23:59.807Z ae27e3b1-596d-41f3-a153-51cb9facc7a7 Task timed out after 3.03 seconds\n```\n\n```text\nFROM python:3.9\n\n\nWORKDIR /code\n\n\nCOPY ./requirements.txt /code/requirements.txt\n\n\nRUN pip install -r /code/requirements.txt\n\n\nCOPY . /code\n\n\nCMD [\"uvicorn\", \"main:app\", \"--host\", \"0.0.0.0\", \"--port\", \"80\"]\n```\n\n```text\nif __name__ == \"__main__\":\n uvicorn.run(\"myapp:app\")\nelse:\n handler = Mangum(app)\n```\n\n```text\nENTRYPOINT [ \"/usr/local/bin/python\", \"-m\", \"awslambdaric\" ]\nCMD [ \"myapp.handler\" ]\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.167Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":82,"estimatedTokens":662}}811{"id":"stack-75431522","source":"stackoverflow","questionId":75431522,"title":"How to create the first user in an python web application with JWT tokens and encrypted passwords?","tags":["python","fastapi","password-encryption"],"text":"Title: How to create the first user in an python web application with JWT tokens and encrypted passwords?\nTags: python, fastapi, password-encryption\nSource: Stack Overflow\n\nQuestion:\nI have created a FastAPI application which has a database with postgresql. The application uses docker, a container for the app and another for the database. Furthermore, it implements authentication with JWT tokens and encrypts passwords with bcrypt. My problem is that logically the endpoint to create new users requires authentication. How do I create the first user? That is, temporarily remove authentication from the endpoint and create the user, but I must write the step by step for project delivery and I do not consider pertinent to give that solution.\nI tried to build the containers and write the steps to insert a user from the database container terminal. However the record is saved in the database but with the password unencrypted, so when I try to authenticate it doesn't work.\nIn summary, how to create that first user?\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI, Request\nfrom domain import *\n\napp = FastAPI()\n\nusers = {}\n\n@app.on_event('startup')\nasync def populate_admin():\n if \"admin\" not in users:\n users['admin'] = {\n 'username': 'admin_user',\n 'password': hash('totally_secret_password')\n }\n```\n\n========================================\n\nComments:\n- Create a utility script that can be run in the container to setup the initial user. There is no particular reason why the initial user shouldn't have their password properly hashed, so that would depend on the code you've written and how you're creating the user. Having a `UserService` class with `.create_user` would be a common way to do it, so that you're always calling the same piece of code, regardless of whether you're creating the user from the CLI or from a controller in your app.\n- Thanks, that's just what I needed to read.","metadata":{"transformedAt":"2026-08-18T18:32:29.167Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":1,"totalLines":34,"estimatedTokens":494}}812{"id":"stack-64302904","source":"stackoverflow","questionId":64302904,"title":"Trouble connecting to localhost from browser using WSL","tags":["python","python-3.x","fastapi","windows-subsystem-for-linux"],"text":"Title: Trouble connecting to localhost from browser using WSL\nTags: python, python-3.x, fastapi, windows-subsystem-for-linux\nSource: Stack Overflow\n\nQuestion:\nI am trying to develop a Python FastAPI endpoint on Windows in a Ubuntu WSL environment but seem to be unable to view/access this from my browser. The weird thing is that I tried this a few days ago and it seemed to work fine but hasn't worked since as I seem to get this error from using curl in my powershell:\n\n```\ncurl : Unable to connect to the remote server\nAt line:1 char:1\n+ curl http://127.0.0.1:8000/\n+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~\n + CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException\n + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand\n```\n\nAnd in any browser I get an error where it can't find that server.\n\nHere's some example code:\n\n```\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\"/\")\nasync def root():\n return {\n \"message\": \"Hello World\"\n }\n```\n\nand then I run `uvicorn main:app --reload` to start the app and try to access the endpoint provided.\n\nMy OS build version is 19041.508 if that matters.\n\nDoes anyone know how I can get this working again? I have no idea what could be going wrong here.\n\nThanks\n\n========================================\n\nTop Answer:\nRestarting the computer can sometimes fix odd connection issues. I'm not sure why. I was having trouble with a fastapi server refusing a secure connection, which previously worked and worked with curl but not in the browser, despite all sorts of measures. It mysteriously would refuse any connection from a browser. Restarted the computer and updated VS Code and everything seems to be working fine now. Maybe it was the VS Code update.\n\n========================================\n\nCode:\n```text\ncurl : Unable to connect to the remote server\nAt line:1 char:1\n+ curl http://127.0.0.1:8000/\n+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~\n + CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException\n + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand\n```\n\n```text\nfrom fastapi import FastAPI\n\napp = FastAPI()\n\n\n@app.get(\"/\")\nasync def root():\n return {\n \"message\": \"Hello World\"\n }\n```\n\n```text\nuvicorn main:app --reload\n```\n\n========================================\n\nComments:\n- To note, if I run curl within wsl for that endpoint, I get the expected response. Secondly, I've also tried to access from the browser using the IP address for the wsl virtualmachine which also gave the same error\n- Have you tried running the app via uvicorn --host 0.0.0.0 main:app --reload ?\n- Yes, I tried this and get the same error. Firefox says \"Firefox can't establish a connection to the server at 0.0.0.0:8000\" and curl from outside the wsl still gives the same error too\n- Sorry for the late response, unfortunately couldn't get it working on the existing pipenv. Ended up just deleting the existing pipenv and creating and new one which seems to be working now. Thanks for trying to help.\n- exactly this solution worked for me, the good 'ol restart.\n- Running `wsl --shutdown` seems to be fixing this issue for me.","metadata":{"transformedAt":"2026-08-18T18:32:29.167Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":3,"totalLines":83,"estimatedTokens":822}}813{"id":"stack-67161500","source":"stackoverflow","questionId":67161500,"title":"async http call taking twice as long as it should","tags":["python","python-asyncio","fastapi"],"text":"Title: async http call taking twice as long as it should\nTags: python, python-asyncio, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am learning async and semaphore, I have made an endpoint using fastapi to test against. The fastapi end point is just a simple server side that takes a request with a sleep time in it and will sleep that long before returning the response. I run the fastapi via uvicorn for testing purpose but with 5 workers. this is for testing only, i understand fro production i should use gunicorn and nginx, but for the purposes of learning i am just using uvicorn\n\n`uvicorn api_example:app --port 8008 --host cdsre.co.uk --workers 5`\n\n**api_example.py**\n\n```\nfrom time import sleep, time\nimport json\nfrom fastapi import FastAPI, Response, Request\n\napp = FastAPI()\n\n@app.post(\"/sleeper\")\nasync def sleeper(request: Request):\n request_data = await request.json()\n sleep_time = request_data['sleep_time']\n start = time()\n sleep(sleep_time)\n end = time()\n return Response(content=json.dumps({\"slept for\": end - start}))\n```\n\nclient code on my local machine is trying to utilise async and semaphore to call 3 post requests in parallel. I have 6 requests, and sleep timer of 5 seconds. So expectation here is that it should take 10 seconds approx to process the 6 requests.\n\n**async_example.py**\n\n```\nimport aiohttp\nimport asyncio\nimport time\n\nasync def get_http_response(session, url):\n async with semaphore:\n print(\"firing request...\")\n start = time.time()\n async with session.post(url, json={\"sleep_time\": 5}) as resp:\n response = await resp.text()\n end = time.time()\n print(f\"Client time: {end - start}, server time: {response}\")\n return response\n\nasync def main():\n async with aiohttp.ClientSession() as session:\n tasks = []\n for number in range(6):\n url = f'http://cdsre.co.uk:8008/sleeper'\n tasks.append(asyncio.ensure_future(get_http_response(session, url)))\n responses = await asyncio.gather(*tasks)\n for response in responses:\n pass\n # print(response)\n\nsemaphore = asyncio.Semaphore(3)\nstart_time = time.time()\nasyncio.get_event_loop().run_until_complete(main())\nprint(\"--- %s seconds ---\" % (time.time() - start_time))\n```\n\nHowever frequently the post request takes twice as long as it should. In this case with a sleep timer of 5 seconds some requests take 10 seconds.\n\n```\nfiring request...\nfiring request...\nfiring request...\nClient time: 5.137275695800781, server time: {\"slept for\": 5.005105018615723}\nfiring request...\nClient time: 10.158655643463135, server time: {\"slept for\": 5.0042970180511475}\nClient time: 10.158655643463135, server time: {\"slept for\": 5.001959800720215}\nfiring request...\nfiring request...\nClient time: 5.055504560470581, server time: {\"slept for\": 5.005110025405884}\nClient time: 5.056135654449463, server time: {\"slept for\": 5.005115509033203}\nClient time: 5.107320070266724, server time: {\"slept for\": 5.005107402801514}\n--- 15.271023750305176 seconds ---\n```\n\nsometimes its 3 times as slow, its always by a factor of my sleep time, which makes me think there is some sort of queuing happening or some sort of race condition I am missing,however i thought the whole purpose of the semaphore pattern was to avoid these race conditions such that my limiting to 3 requests at any one time is always going to be less than the works available on the server side (5 workers) so there should always be a working available server side to process it.\n\nI also dont start time timing until inside the semaphore so I am not starting it early so it should only start the timer when its sending the request. Hopefully i am just missing something obvious. I have left the end point url up if anyone wants to try it. I would appreciate any help in solving this. Essentially i need to be able to write an async client that can send request in parallel up to a limit and be consistent in measureing the response time.\n\n**Exmaple of some taking 3 times as long**\n\n```\nfiring request...\nfiring request...\nfiring request...\nClient time: 15.127191305160522, server time: {\"slept for\": 5.001192808151245}\nfiring request...\nClient time: 15.127155303955078, server time: {\"slept for\": 5.005094766616821}\nClient time: 15.127155303955078, server time: {\"slept for\": 5.005074977874756}\nfiring request...\nfiring request...\nClient time: 5.053789854049683, server time: {\"slept for\": 5.005076169967651}\nClient time: 5.100871801376343, server time: {\"slept for\": 5.005076885223389}\nClient time: 10.107984781265259, server time: {\"slept for\": 5.005110502243042}\n--- 25.236175775527954 seconds ---\n```\n\n========================================\n\nCode:\n```py\nfrom time import sleep, time\nimport json\nfrom fastapi import FastAPI, Response, Request\n\n\napp = FastAPI()\n\n\n@app.post(\"/sleeper\")\nasync def sleeper(request: Request):\n request_data = await request.json()\n sleep_time = request_data['sleep_time']\n start = time()\n sleep(sleep_time)\n end = time()\n return Response(content=json.dumps({\"slept for\": end - start}))\n```\n\n```py\nimport aiohttp\nimport asyncio\nimport time\n\n\nasync def get_http_response(session, url):\n async with semaphore:\n print(\"firing request...\")\n start = time.time()\n async with session.post(url, json={\"sleep_time\": 5}) as resp:\n response = await resp.text()\n end = time.time()\n print(f\"Client time: {end - start}, server time: {response}\")\n return response\n\n\nasync def main():\n async with aiohttp.ClientSession() as session:\n tasks = []\n for number in range(6):\n url = f'http://cdsre.co.uk:8008/sleeper'\n tasks.append(asyncio.ensure_future(get_http_response(session, url)))\n responses = await asyncio.gather(*tasks)\n for response in responses:\n pass\n # print(response)\n\n\nsemaphore = asyncio.Semaphore(3)\nstart_time = time.time()\nasyncio.get_event_loop().run_until_complete(main())\nprint(\"--- %s seconds ---\" % (time.time() - start_time))\n```\n\n```none\nfiring request...\nfiring request...\nfiring request...\nClient time: 5.137275695800781, server time: {\"slept for\": 5.005105018615723}\nfiring request...\nClient time: 10.158655643463135, server time: {\"slept for\": 5.0042970180511475}\nClient time: 10.158655643463135, server time: {\"slept for\": 5.001959800720215}\nfiring request...\nfiring request...\nClient time: 5.055504560470581, server time: {\"slept for\": 5.005110025405884}\nClient time: 5.056135654449463, server time: {\"slept for\": 5.005115509033203}\nClient time: 5.107320070266724, server time: {\"slept for\": 5.005107402801514}\n--- 15.271023750305176 seconds ---\n```\n\n```none\nfiring request...\nfiring request...\nfiring request...\nClient time: 15.127191305160522, server time: {\"slept for\": 5.001192808151245}\nfiring request...\nClient time: 15.127155303955078, server time: {\"slept for\": 5.005094766616821}\nClient time: 15.127155303955078, server time: {\"slept for\": 5.005074977874756}\nfiring request...\nfiring request...\nClient time: 5.053789854049683, server time: {\"slept for\": 5.005076169967651}\nClient time: 5.100871801376343, server time: {\"slept for\": 5.005076885223389}\nClient time: 10.107984781265259, server time: {\"slept for\": 5.005110502243042}\n--- 25.236175775527954 seconds ---\n```\n\n```text\nuvicorn api_example:app --port 8008 --host cdsre.co.uk --workers 5\n```\n\n```text\nasync\n```\n\n```text\nsleep\n```\n\n```text\nloop.run_in_executor\n```\n\n```text\nsleep\n```\n\n```text\nasyncio.sleep\n```\n\n```text\nawait loop.run_in_executor(None, time.sleep, 5)\n```\n\n========================================\n\nComments:\n- You’re using `time.sleep`. This will block the thread. You want to use `await asyncio.sleep(sleep_time)`.\n- yeah but i want the thread to block on the server end to simulate the app taking some time do something. What I dont get is that I have 5 workers available on the server side and only ever send at most 3 requests at the same time. So there should always be a worker free to pick up the request, sleep for that time then return the response. But sometimes that response time on the client side it 2 or 3 times slower, and its always by a factor of the sleep time, I.E if the sleep time is 5, its always 5, or 10 or 15, its never 7 or 12 etc. So i figure there must be something in the client side.\n- However, having taken your comment and applied it in my code the results are a lot more consistent . So what is the difference between time.sleep in a worker and await asyncio.sleep.......I was thinking that each worker would get a seperate request, so a sleep blocking that thread wouldnt affect the others.\n- Feel free to post that as an answer as its 100% solved my issue. any further explanation about why it fixes it or why sleep was causing the issue would greatly be appreciated.","metadata":{"transformedAt":"2026-08-18T18:32:29.167Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":11,"totalLines":228,"estimatedTokens":2178}}814{"id":"stack-68623238","source":"stackoverflow","questionId":68623238,"title":"How to identify and save the right \"user\" when we use Django (Existing proj) for authentication and FastAPI (new feature) for API's?","tags":["python-3.x","django","django-models","django-rest-framework","fastapi"],"text":"Title: How to identify and save the right \"user\" when we use Django (Existing proj) for authentication and FastAPI (new feature) for API's?\nTags: python-3.x, django, django-models, django-rest-framework, fastapi\nSource: Stack Overflow\n\nQuestion:\nHello guys I have an existing Django project which has certain features and also has user data. For certain features, users use the API served through Django (also the authentication), but since there is a need for new feature which needs to be implemented through FastAPI, I need to have the same users authenticate or (better to say) to be recognized by FastAPI (as the same user in Django) to save or retrieve an action corresponding to user in the db (through FastAPI).\n\nHow to achieve that? How do I store the user data, like `user_id` and `username` for each user safely? How to properly design the database table?\n\nPlease do let me know, how to start.\n\nThank you.\n\n========================================\n\nTop Answer:\nThis is mostly a software architecture design problem, In your old login endpoint put every required data by the new FastAPI project in the JWT token payload(such as user_id, user_name and etc), sign it and give it to the user:\n\n```\n# using PyJWT\nimport jwt\nuser_token = jwt.encode(\n {\"user_id\": \"1222\", \"user_name\": \"yosef\", },\n \"YOUR_SECRET_KEY\",\n algorithm=\"HS256\",\n headers={},\n)\n```\n\nAfterwards in new FastAPI project endpoint, validate JWT token in request header with the key you have signed it in Django login endpoint:\n\n```\n# using PyJWT\nimport jwt\n\ntry:\n data = jwt.decode(JWT_STRING_VAR, \"YOUR_SECRET_KEY\", algorithms=[\"HS256\"])\nexcept jwt.ExpiredSignatureError:\n # reject\n ...\n```\n\nIf the token is valid you accept the request and use the payload as confirmed data to do your usual endpoint functionality and if sign is not valid reject request.\n\nThis way you are not required to change your old endpoints at all.\n\n*note: instead of PyJWT you can use SimpleJWT or any other package for Django and a suitable JWT package for FastAPI\n\n**note: this scenario may go crazy complex when your JWT payload may get changed before the JWT expires, like when user_name changes but you can not change that in JWT and user can use it in your other service with old data, there are more solutions on this, like removing the properties that may change from payload and get them directly from database, meaning you query Django populated table from FastAPI, you can achieve this by import dynamic tables in SQLAlchemy\n***note: system design schema image\nhttps://i.sstatic.net/6KOLo.png\n\n========================================\n\nCode:\n```text\nuser_id\n```\n\n```text\nusername\n```\n\n```text\nAbstractUser\n```\n\n```text\nDannyUser\n```\n\n```text\nJSONField\n```\n\n```text\nDannyUser\n```\n\n```text\nmy_danny_instance.fastapi_account.auth_token\n```\n\n```text\n# using PyJWT\nimport jwt\nuser_token = jwt.encode(\n {\"user_id\": \"1222\", \"user_name\": \"yosef\", },\n \"YOUR_SECRET_KEY\",\n algorithm=\"HS256\",\n headers={},\n)\n```\n\n```text\n# using PyJWT\nimport jwt\n\ntry:\n data = jwt.decode(JWT_STRING_VAR, \"YOUR_SECRET_KEY\", algorithms=[\"HS256\"])\nexcept jwt.ExpiredSignatureError:\n # reject\n ...\n```\n\n========================================\n\nComments:\n- Maybe authentication via Json web tokens will be enough for you?\n- Thank you for the response. I haven't worked with multiple frameworks before, so I am a bit confused on how I should save the data in db? like with user_id? how to validate the jwt token for each request? or is there another way? If you could tell more, it would be great.\n- How are you authenticating currently?\n- Using JWT tokens\n- Thanks for the response. I am having a custom user model and currently using JWT tokens for authentication. Do you mean to create a separate model to the the user's token details and validate for each request?\n- Either a separate model or even a simple field like `user_jwt_token` for each `User` model instance that needs to store it; adding a new model and linking with M2M FKs offers greater flexibility in the future, though\n- Oh..Thank you for the response, I will try that out.\n- Oh..great, the last section seems promising even though its a bit complex, and looks a bit expensive too. Let me try that. Thank you","metadata":{"transformedAt":"2026-08-18T18:32:29.168Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":9,"totalLines":116,"estimatedTokens":1058}}815{"id":"stack-65866200","source":"stackoverflow","questionId":65866200,"title":"How can I use motor's open_download_stream work with FastAPI's StreamingResponse?","tags":["mongodb","fastapi","mongodb-motor"],"text":"Title: How can I use motor's open_download_stream work with FastAPI's StreamingResponse?\nTags: mongodb, fastapi, mongodb-motor\nSource: Stack Overflow\n\nQuestion:\nI'm building a FastAPI endpoint where web client user can essentially download files which are stored in MongoDB as GridFS chunks. However, FastAPI's StreamingResponse doesn't take the supposedly file-like AsyncIOMotorGridOut object returned by motor's open_download_stream method.\n\nI already have an endpoint which can take files in a form and cause them to be uploaded to MongoDB. I would expect a similar download helper function to be as simple as this:\n\n```\nasync def upload_file(db, file: UploadFile):\n \"\"\" Uploads file to MongoDB GridFS file system and returns ID to be stored with collection document \"\"\"\n fs = AsyncIOMotorGridFSBucket(db)\n file_id = await fs.upload_from_stream(\n file.filename,\n file.file,\n # chunk_size_bytes=255*1024*1024, #default 255kB\n metadata={\"contentType\": file.content_type})\n return file_id\n```\n\nMy first attempt is to use a helper like this:\n\n```\nasync def download_file(db, file_id):\n \"\"\"Returns AsyncIOMotorGridOut (non-iterable file-like object)\"\"\"\n fs = AsyncIOMotorGridFSBucket(db)\n stream = await fs.open_download_stream(file_id)\n # return download_streamer(stream)\n return stream\n```\n\nMy FastAPI endpoint looks like this:\n\n```\napp.get(\"/file/{file_id}\")\nasync def get_file(file_id):\n file = await download_file(db, file_id)\n return StreamingResponse(file, media_type=file.content_type)\n```\n\nWhen trying to download a file with a valid `file_id`, I get this error: `TypeError: 'AsyncIOMotorGridOut' object is not an iterator`\n\nMy 2nd attempt has been to make a generator to iterate over chunks of the file:\n\n```\nasync def download_streamer(file: AsyncIOMotorGridOut):\n \"\"\" Returns generator file-like object to be served by StreamingResponse\n https://fastapi.tiangolo.com/advanced/custom-response/#streamingresponse\n \"\"\"\n chunk_size = 255*1024*1024\n for chunk in await file.readchunk():\n print(f\"chunk: {chunk}\")\n yield chunk\n```\n\nI then use the commented `return download_streamer(stream)` in my `download_file` helper, but for some reason, every chunk is just an integer of `255`.\n\nWhat's the best way to get a file out of MongoDB using motor and streaming it as a FastAPI web response without using a temporary file? (I don't have access to hard drive, and I don't want to store the whole file in memory - I just want to stream files from MongoDB through FastAPI directly to client a chunk at a time).\n\n========================================\n\nCode:\n```text\nasync def upload_file(db, file: UploadFile):\n \"\"\" Uploads file to MongoDB GridFS file system and returns ID to be stored with collection document \"\"\"\n fs = AsyncIOMotorGridFSBucket(db)\n file_id = await fs.upload_from_stream(\n file.filename,\n file.file,\n # chunk_size_bytes=255*1024*1024, #default 255kB\n metadata={\"contentType\": file.content_type})\n return file_id\n```\n\n```text\nasync def download_file(db, file_id):\n \"\"\"Returns AsyncIOMotorGridOut (non-iterable file-like object)\"\"\"\n fs = AsyncIOMotorGridFSBucket(db)\n stream = await fs.open_download_stream(file_id)\n # return download_streamer(stream)\n return stream\n```\n\n```text\napp.get(\"/file/{file_id}\")\nasync def get_file(file_id):\n file = await download_file(db, file_id)\n return StreamingResponse(file, media_type=file.content_type)\n```\n\n```text\nasync def download_streamer(file: AsyncIOMotorGridOut):\n \"\"\" Returns generator file-like object to be served by StreamingResponse\n https://fastapi.tiangolo.com/advanced/custom-response/#streamingresponse\n \"\"\"\n chunk_size = 255*1024*1024\n for chunk in await file.readchunk():\n print(f\"chunk: {chunk}\")\n yield chunk\n```\n\n```text\nfile_id\n```\n\n```text\nTypeError: 'AsyncIOMotorGridOut' object is not an iterator\n```\n\n```text\nreturn download_streamer(stream)\n```\n\n```text\ndownload_file\n```\n\n```text\n255\n```\n\n```text\nasync def chunk_generator(grid_out):\n while True:\n # chunk = await grid_out.read(1024)\n chunk = await grid_out.readchunk()\n if not chunk:\n break\n yield chunk\n\n\nasync def download_file(db, file_id):\n \"\"\"Returns iterator over AsyncIOMotorGridOut object\"\"\"\n fs = AsyncIOMotorGridFSBucket(db)\n grid_out = await fs.open_download_stream(file_id)\n return chunk_generator(grid_out)\n```\n\n```text\nreadchunk()\n```\n\n```text\nupload_from_stream()\n```\n\n```text\n.read(n)\n```\n\n```text\nn\n```\n\n```text\nreadchunk()\n```\n\n```text\ndownload_file()\n```\n\n```text\nContentType\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.168Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":17,"totalLines":166,"estimatedTokens":1145}}816{"id":"stack-75057759","source":"stackoverflow","questionId":75057759,"title":"FastApi with gunicorn/uvicorn stops responding","tags":["python","docker","fastapi","gunicorn","uvicorn"],"text":"Title: FastApi with gunicorn/uvicorn stops responding\nTags: python, docker, fastapi, gunicorn, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI'm currently using **FastApi** with **Gunicorn**/**Uvicorn** as my server engine.\n\nI'm using the following config for **Gunicorn**:\n\n```\nTIMEOUT 0\nGRACEFUL_TIMEOUT 120\nKEEP_ALIVE 5\nWORKERS 10\n```\n\n**Uvicorn** has all default settings, and is started in docker container casually:\n\n```\nCMD [\"uvicorn\", \"app.main:app\", \"--host\", \"0.0.0.0\", \"--port\", \"8000\"]\n```\n\nEverything is packed in docker container.\n\n**The problem is the following:**\n\nAfter some time (somewhere between 1 day and 1 week, depending on load) my app stops responding (even simple `curl http://0.0.0.0:8000` command hangs forever). Docker container keeps working, there are no application errors in logs, and there are no connection issues, but none of my workers are getting the request (and so I'm never getting my response). It seems like my request is lost somewhere between server engine and my application. Any ideas how to fix it?\n\n**UPDATE**: I've managed to reproduce this behaviour with custom **locust** load profile:https://i.sstatic.net/FcuYJ.png\nThe scenario was the following:\n\n- In first 15 minutes ramp up to 50 users (30 of them will send requests requiring GPU at 1 rps, and 20 will send requests that do not require GPU at 10 rps)\nWork for another 4 hours\nAs the plot shows, in about 30 minutes API stops responding. (And still, there are no error messages/warnings in output)\n\n**UPDATE 2**:\nCan there be any hidden memory leak or deadlock due to incorrect **Gunicorn** setup or bug (such as https://github.com/tiangolo/fastapi/issues/596)?\n\n**UPDATE 4**:\nI've got inside my container and executed `ps` command. It shows:\n\n```\nPID TTY TIME CMD\n 120 pts/0 00:00:00 bash\n 134 pts/0 00:00:00 ps\n```\n\nWhich means my **Gunicorn** server app just silently turned off. And also there is binary file named `core` in the app directory, which obviously mens that something has crashed\n\n========================================\n\nCode:\n```text\nTIMEOUT 0\nGRACEFUL_TIMEOUT 120\nKEEP_ALIVE 5\nWORKERS 10\n```\n\n```text\nCMD [\"uvicorn\", \"app.main:app\", \"--host\", \"0.0.0.0\", \"--port\", \"8000\"]\n```\n\n```text\nPID TTY TIME CMD\n 120 pts/0 00:00:00 bash\n 134 pts/0 00:00:00 ps\n```\n\n```text\ncurl http://0.0.0.0:8000\n```\n\n```text\nps\n```\n\n```text\ncore\n```\n\n```text\nelastic apm\n```\n\n========================================\n\nComments:\n- @Chris no it's not. I'm getting this error no matter if I face CUDA memory overflow or not.\n- @Chris P.S. I've moved away all ML models to a separate container, but API keeps failing.\n- Without looking at your application source code it's hard to help, but the first thing I'd double check is that you are handling database connections correctly. When your application gets to \"hanging forever state\", query your database and check for open connections.\n- how did you figure out what caused this and how did you confirm it was an OOM issue, I'm facing a similar issue\n- @Ebdulmomen1 Just got `docker stats` and watched my container memory to flow away. When I removed middleware it stopped","metadata":{"transformedAt":"2026-08-18T18:32:29.168Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":7,"totalLines":93,"estimatedTokens":785}}817{"id":"stack-74958699","source":"stackoverflow","questionId":74958699,"title":"How to create multilingual web pages with fastapi-babel?","tags":["python","fastapi","gettext"],"text":"Title: How to create multilingual web pages with fastapi-babel?\nTags: python, fastapi, gettext\nSource: Stack Overflow\n\nQuestion:\nI'm thinking of creating a multilingual web page with fastapi-babel.\n\nI have configured according to the documentation.\nThe translation from English to French was successful.\nHowever, I created a .po file for another language, translated it, compiled it, but the translated text does not apply.\n\n```\nfrom fastapi_babel import _\nfrom fastapi_babel.middleware import InternationalizationMiddleware as I18nMiddleware\nfrom fastapi_babel import Babel\nfrom fastapi_babel import BabelConfigs\n\nconfigs = BabelConfigs(\n ROOT_DIR=__file__,\n BABEL_DEFAULT_LOCALE=\"en\",\n BABEL_TRANSLATION_DIRECTORY=\"lang\",\n)\nlogger.info(f\"configs: {configs.__dict__}\")\nbabel = babel(configs)\nbabel.install_jinja(templates)\n\napp.add_middleware(I18nMiddleware, babel=babel)\n\n@app.get(\"/items/{id}\", response_class=HTMLResponse)\nasync def read_item(request: Request, id: str):\n babel.locale = \"en\"\n logger.info(_(\"Hello World\"))\n babel. locale = \"fa\"\n logger.info(_(\"Hello World\"))\n babel.locale = \"ja\"\n logger.info(_(\"Hello World\"))\n return templates.TemplateResponse('item.html', {'request': request, 'id': id})\n```\n\nAbove, the result will be:\n\n```\nINFO: Hello World\nINFO: Bonjour le monde\nINFO: Hello World\n```\n\nHow can the translation be applied to languages other than French?\n\nhttps://i.sstatic.net/QJDkC.png\n\n========================================\n\nCode:\n```text\nfrom fastapi_babel import _\nfrom fastapi_babel.middleware import InternationalizationMiddleware as I18nMiddleware\nfrom fastapi_babel import Babel\nfrom fastapi_babel import BabelConfigs\n\nconfigs = BabelConfigs(\n ROOT_DIR=__file__,\n BABEL_DEFAULT_LOCALE=\"en\",\n BABEL_TRANSLATION_DIRECTORY=\"lang\",\n)\nlogger.info(f\"configs: {configs.__dict__}\")\nbabel = babel(configs)\nbabel.install_jinja(templates)\n\napp.add_middleware(I18nMiddleware, babel=babel)\n\n\n@app.get(\"/items/{id}\", response_class=HTMLResponse)\nasync def read_item(request: Request, id: str):\n babel.locale = \"en\"\n logger.info(_(\"Hello World\"))\n babel. locale = \"fa\"\n logger.info(_(\"Hello World\"))\n babel.locale = \"ja\"\n logger.info(_(\"Hello World\"))\n return templates.TemplateResponse('item.html', {'request': request, 'id': id})\n```\n\n```text\nINFO: Hello World\nINFO: Bonjour le monde\nINFO: Hello World\n```\n\n```text\npip install fastapi-babel==0.0.8\n```\n\n```text\nbabel = Babel(\n configs=BabelConfigs(\n ROOT_DIR=__file__,\n BABEL_DEFAULT_LOCALE=\"en\",\n BABEL_TRANSLATION_DIRECTORY=\"lang\",\n )\n)\n```\n\n```text\nbabel.locale = \"en\"\n```\n\n```text\n0.0.3\n```\n\n```text\n0.0.8\n```\n\n```text\npybabel compile -d lang\n```\n\n```text\nBABEL_DEFAULT_LOCALE\n```\n\n```text\nbabel.locale\n```\n\n```text\npybabel extract -F babel.cfg -o messages.pot .\n```\n\n```text\npybabel compile -d lang\n```\n\n```text\npybabel init -i messages.pot -d lang -l fa\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.168Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":13,"totalLines":138,"estimatedTokens":726}}818{"id":"stack-74895753","source":"stackoverflow","questionId":74895753,"title":"How to return data on WebSocket when new database entry is made FastAPI","tags":["python-3.x","websocket","sqlalchemy","python-asyncio","fastapi"],"text":"Title: How to return data on WebSocket when new database entry is made FastAPI\nTags: python-3.x, websocket, sqlalchemy, python-asyncio, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to write a simple API that collects measurements, and then streams them live to clients over a websocket with FastAPI. There are plenty of tutorials on how to send messages when triggered by the websocket manager, but I'm having a hard time getting the database trigger to send the message. Below is what I have so far:\n\nmain.py:\n\n```\nfrom fastapi import FastAPI, Depends, WebSocket, WebSocketDisconnect\nfrom sql_app.database import engine, Session\nfrom sql_app import models\nfrom fastapi.encoders import jsonable_encoder\nimport sql_app.schemas as schemas\nfrom sql_app.database import Base, get_db\nimport datetime\nimport uvicorn\n\ndef create_tables():\n print(\"Creating Tables..\")\n Base.metadata.create_all(bind=engine)\n\napp = FastAPI()\n\n@app.post(\"/measurement/\")\nasync def create_measurement(measurement: schemas.MeasurementCreate, db: Session = Depends(get_db)):\n # new_measurement = schemas.MeasurementCreate(**measurement.dict(), session=db)\n new_measurement = models.Measurement(**measurement.dict())\n db.add(new_measurement)\n db.commit()\n db.refresh(new_measurement)\n return new_measurement\n\n@app.post(\"/create_device/\")\nasync def create_device(device: schemas.DeviceCreate, db: Session = Depends(get_db)):\n new_device = models.Device(device_key=device.device_key,\n name=device.name,\n hardware=device.hardware,\n firmware=device.firmware,\n software=device.software\n )\n db.add(new_device)\n db.commit()\n return db.refresh(new_device)\n\n@app.get(\"/measurement/\")\nasync def get_measurements(db: Session = Depends(get_db)):\n return db.query(models.Measurement).filter(\n models.Measurement.timestamp >= datetime.datetime.now() - datetime.timedelta(days=30)\n ).all()\n\n@app.websocket(\"/ws\")\nasync def dashboard_data(websocket: WebSocket, db: Session = Depends(get_db)):\n await websocket.accept()\n await websocket.send_json(\n jsonable_encoder(\n db.query(models.Measurement).filter(\n models.Measurement.timestamp >= datetime.datetime.now() - datetime.timedelta(days=30)).all()))\n while True:\n try:\n data = await models.measurement_stream(Depends(get_db))\n await websocket.send_text(data)\n except WebSocketDisconnect:\n return None\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"localhost\", port=8000)\n```\n\nModels.py:\n\n```\nfrom sqlalchemy import Boolean, Column, ForeignKey, Integer, String, Float, DateTime, event\nfrom sqlalchemy.schema import UniqueConstraint\nfrom sqlalchemy.orm import relationship\nfrom fastapi import Depends\nfrom .database import Base, get_db\nimport datetime\nfrom pytz import timezone\nfrom sql_app.database import Session\n\nclass Measurement(Base):\n __tablename__ = \"measurements\"\n\n id = Column(Integer, primary_key=True, index=True)\n device_key = Column(String(length=40), ForeignKey(\"devices.device_key\"))\n inside_temp = Column(Float)\n outside_temp = Column(Float)\n inside_humidity = Column(Float)\n outside_humidity = Column(Float)\n current_capacity = Column(Float)\n timestamp = Column(DateTime, default=lambda: datetime.datetime.now(tz=timezone('America/Los_Angeles')))\n\n device = relationship(\"Device\", back_populates=\"measurements\")\n\n def _as_dict(self):\n return {c.name: getattr(self, c.name) for c in self.__table__.columns}\n\n@event.listens_for(Measurement, \"after_insert\")\nasync def measurement_stream(db: Session):\n return \"test\" #db.query(Measurement).filter(Measurement.timestamp >= datetime.datetime.now() - datetime.timedelta(days=30)).all()\n\nclass Device(Base):\n __tablename__ = \"devices\"\n device_key = Column(String(length=40), unique=True, primary_key=True)\n name = Column(String)\n hardware = Column(String)\n firmware = Column(String)\n software = Column(String)\n\n measurements = relationship(\"Measurement\", back_populates=\"device\")\n```\n\nIf I execute this now it just returns \"test\" as quickly as the loop runs. How can I make the message only send when there is an update to the database? Note: I am not even sure if my event listener for the measurement ORM class is correct.\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI, Depends, WebSocket, WebSocketDisconnect\nfrom sql_app.database import engine, Session\nfrom sql_app import models\nfrom fastapi.encoders import jsonable_encoder\nimport sql_app.schemas as schemas\nfrom sql_app.database import Base, get_db\nimport datetime\nimport uvicorn\n\n\ndef create_tables():\n print(\"Creating Tables..\")\n Base.metadata.create_all(bind=engine)\n\napp = FastAPI()\n\n\n\n@app.post(\"/measurement/\")\nasync def create_measurement(measurement: schemas.MeasurementCreate, db: Session = Depends(get_db)):\n # new_measurement = schemas.MeasurementCreate(**measurement.dict(), session=db)\n new_measurement = models.Measurement(**measurement.dict())\n db.add(new_measurement)\n db.commit()\n db.refresh(new_measurement)\n return new_measurement\n\n\n@app.post(\"/create_device/\")\nasync def create_device(device: schemas.DeviceCreate, db: Session = Depends(get_db)):\n new_device = models.Device(device_key=device.device_key,\n name=device.name,\n hardware=device.hardware,\n firmware=device.firmware,\n software=device.software\n )\n db.add(new_device)\n db.commit()\n return db.refresh(new_device)\n\n@app.get(\"/measurement/\")\nasync def get_measurements(db: Session = Depends(get_db)):\n return db.query(models.Measurement).filter(\n models.Measurement.timestamp >= datetime.datetime.now() - datetime.timedelta(days=30)\n ).all()\n\n\n\n\n@app.websocket(\"/ws\")\nasync def dashboard_data(websocket: WebSocket, db: Session = Depends(get_db)):\n await websocket.accept()\n await websocket.send_json(\n jsonable_encoder(\n db.query(models.Measurement).filter(\n models.Measurement.timestamp >= datetime.datetime.now() - datetime.timedelta(days=30)).all()))\n while True:\n try:\n data = await models.measurement_stream(Depends(get_db))\n await websocket.send_text(data)\n except WebSocketDisconnect:\n return None\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"localhost\", port=8000)\n```\n\n```text\nfrom sqlalchemy import Boolean, Column, ForeignKey, Integer, String, Float, DateTime, event\nfrom sqlalchemy.schema import UniqueConstraint\nfrom sqlalchemy.orm import relationship\nfrom fastapi import Depends\nfrom .database import Base, get_db\nimport datetime\nfrom pytz import timezone\nfrom sql_app.database import Session\n\n\nclass Measurement(Base):\n __tablename__ = \"measurements\"\n\n id = Column(Integer, primary_key=True, index=True)\n device_key = Column(String(length=40), ForeignKey(\"devices.device_key\"))\n inside_temp = Column(Float)\n outside_temp = Column(Float)\n inside_humidity = Column(Float)\n outside_humidity = Column(Float)\n current_capacity = Column(Float)\n timestamp = Column(DateTime, default=lambda: datetime.datetime.now(tz=timezone('America/Los_Angeles')))\n\n device = relationship(\"Device\", back_populates=\"measurements\")\n\n def _as_dict(self):\n return {c.name: getattr(self, c.name) for c in self.__table__.columns}\n\n\n@event.listens_for(Measurement, \"after_insert\")\nasync def measurement_stream(db: Session):\n return \"test\" #db.query(Measurement).filter(Measurement.timestamp >= datetime.datetime.now() - datetime.timedelta(days=30)).all()\n\n\n\nclass Device(Base):\n __tablename__ = \"devices\"\n device_key = Column(String(length=40), unique=True, primary_key=True)\n name = Column(String)\n hardware = Column(String)\n firmware = Column(String)\n software = Column(String)\n\n measurements = relationship(\"Measurement\", back_populates=\"device\")\n```\n\n```text\n@app.websocket(\"/ws\")\nasync def dashboard_data(websocket: WebSocket, db: Session = Depends(get_db)):\n flag = asyncio.Event()\n @event.listens_for(models.Measurement, \"after_insert\")\n def measurement_stream(*args, **kwargs):\n flag.set()\n print(\"event set\")\n await websocket.accept()\n await websocket.send_json(\n jsonable_encoder(\n db.query(models.Measurement).filter(\n models.Measurement.timestamp >= datetime.datetime.now() - datetime.timedelta(days=30)).all()))\n while True:\n try:\n await flag.wait()\n await websocket.send_json(jsonable_encoder(\n db.query(models.Measurement).filter(\n models.Measurement.timestamp >= datetime.datetime.now() - datetime.timedelta(days=30)).all()))\n flag.clear()\n except WebSocketDisconnect:\n return None\n```\n\n========================================\n\nComments:\n- What happens when your server application is idle with the `flag.wait()` function and the client application close the connection? It looks like the server app won't close the connection right away.","metadata":{"transformedAt":"2026-08-18T18:32:29.168Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":3,"totalLines":261,"estimatedTokens":2250}}819{"id":"stack-75329557","source":"stackoverflow","questionId":75329557,"title":"How is passing a generator to Depends make the generator act like a contextmanager?","tags":["python","python-3.x","fastapi"],"text":"Title: How is passing a generator to Depends make the generator act like a contextmanager?\nTags: python, python-3.x, fastapi\nSource: Stack Overflow\n\nQuestion:\nI was going through a tutorial on fast api and I came across something like below\n\n```\ndef get_db():\n try:\n db = SessionLocal()\n yield db\n finally:\n print(\"from finally block\")\n db.close()\n```\n\n```\n@app.get(\"/\")\nasync def read_all(db: Session = Depends(get_db)):\n res = db.query(models.Todos).all()\n print(\"from endpoint\")\n return res\n```\n\nresult\n\n```\nINFO: 127.0.0.1:39088 - \"GET /openapi.json HTTP/1.1\" 200 OK\nfrom endpoint\nINFO: 127.0.0.1:39088 - \"GET / HTTP/1.1\" 200 OK\nfrom finally block\n```\n\nwhy does Depends(get_db) seem to act like somekind of contextmanager?.\nthe `\"from finally block\"` print statement does not get executed until the end of the `read_all` method\n\ndoing something like\n\n```\nclass SomeDependency:\n def __enter__(self):\n print(\"entering\")\n def __exit__(self, exc_type, exc_val, exc_tb):\n print(\"exited\")\n\ndef hello():\n try:\n yield SomeDependency()\n finally:\n print(\"yolo\")\n\nif __name__ == \"__main__\":\n next(hello())\n```\n\nthe `finally` block gets executed immediately after the call to `next`.\n\nwhat why does the `finally` block of the `get_db` not execute immediately when passed to `Depends`?\n\n========================================\n\nTop Answer:\nThe behavior you are seeing is correct, but it's not because `next()` is behaving differently. It's happening because of **Python's garbage collection**.\n\nLet's break down the line `next(hello())` step-by-step:\n\n- **`hello()` is called:** This does **not** run the code inside `hello`. It creates and returns a new generator object. Let's call this object `gen_obj_A`.\n**`next(gen_obj_A)` is called:**\n\n- The `hello` generator starts executing.\n\n- It enters the `try` block.\n\n- It hits `yield SomeDependency()`. It yields a new `SomeDependency` object and **pauses**.\n\n- **The line finishes:** The `next()` function has done its job—it produced one value. The Python interpreter is now done with this line of code.\n\nHere is the crucial part: **What happens to the generator object `gen_obj_A`?**\n\nNothing. It was never assigned to a variable. There are no more references to it anywhere in your program. It's now \"unreachable.\"\n\nWhen an object becomes unreachable, Python's **Garbage Collector** is free to destroy it to reclaim its memory.\n\n### The Role of `generator.close()` and `finally`\n\nAs part of the process of destroying a generator, the garbage collector calls the generator's `.close()` method. The `.close()` method does one specific thing: it raises a special `GeneratorExit` exception inside the generator at the point where it was paused.\n\nSo, the full sequence is:\n\n- `next(hello())` creates a generator, runs it to the `yield`, and the generator pauses.\n\n- The line finishes. The generator object is now unreferenced.\n\n- The Garbage Collector sees the unreferenced generator and calls `.close()` on it.\n\n- The `.close()` method injects a `GeneratorExit` exception into the generator right after the `yield` statement.\n\n- The `try...finally` block immediately catches this exit signal. Before the generator can be destroyed, the `finally` block **must** be executed.\n\n- `print(\"yolo\")` runs.\n\n- The generator is then closed and garbage collected.\n\nThis is a vital feature of Python that ensures resources are cleaned up. It guarantees that a generator's `finally` block will run even if the code using the generator \"forgets\" about it or doesn't finish iterating over it.\n\n### How to Get the Behavior You Expected\n\nTo get the behavior you were expecting (where the `finally` block doesn't run immediately), you need to keep a reference to the generator, preventing it from being garbage collected.\n\nWatch the difference here:\n\n```\nclass SomeDependency:\n def __enter__(self):\n print(\"entering\")\n def __exit__(self, exc_type, exc_val, exc_tb):\n print(\"exited\")\n\ndef hello():\n try:\n print(\"Generator starting...\")\n yield SomeDependency()\n print(\"Generator resumed after yield, but this part is never reached in this script.\")\n finally:\n print(\"FINALLY block executed!\")\n\nif __name__ == \"__main__\":\n print(\"Creating the generator and assigning it to a variable.\")\n # Keep a reference to the generator\n gen = hello() \n print(\"Generator created. FINALLY has not run yet.\")\n\n print(\"\\nCalling next(gen)...\")\n # The next() call runs the generator until the yield\n value = next(gen) \n print(f\"Received value from next(): {value}\")\n\n print(\"\\nScript is still running. The 'gen' variable is alive.\")\n print(\"The generator is paused and FINALLY has still not run.\")\n\n # The finally block will run when the 'gen' object is closed or\n # garbage collected at the end of the script.\n # Or we can close it explicitly:\n print(\"\\nExplicitly closing the generator...\")\n gen.close()\n```\n\n**Output of this code:**\n\n```\nCreating the generator and assigning it to a variable.\nGenerator created. FINALLY has not run yet.\n\nCalling next(gen)...\nGenerator starting...\nReceived value from next(): \n\nScript is still running. The 'gen' variable is alive.\nThe generator is paused and FINALLY has still not run.\n\nExplicitly closing the generator...\nFINALLY block executed!\n```\n\nThis demonstrates that by holding a reference (`gen = hello()`), you prevent immediate garbage collection, and the `finally` block only executes when the generator is explicitly closed or the program ends. This is exactly how FastAPI works: it holds onto the generator for the entire request, only resuming/closing it after the endpoint is done.\n\n========================================\n\nCode:\n```text\ndef get_db():\n try:\n db = SessionLocal()\n yield db\n finally:\n print(\"from finally block\")\n db.close()\n```\n\n```text\n@app.get(\"/\")\nasync def read_all(db: Session = Depends(get_db)):\n res = db.query(models.Todos).all()\n print(\"from endpoint\")\n return res\n```\n\n```text\nINFO: 127.0.0.1:39088 - \"GET /openapi.json HTTP/1.1\" 200 OK\nfrom endpoint\nINFO: 127.0.0.1:39088 - \"GET / HTTP/1.1\" 200 OK\nfrom finally block\n```\n\n```text\nclass SomeDependency:\n def __enter__(self):\n print(\"entering\")\n def __exit__(self, exc_type, exc_val, exc_tb):\n print(\"exited\")\n\ndef hello():\n try:\n yield SomeDependency()\n finally:\n print(\"yolo\")\n\nif __name__ == \"__main__\":\n next(hello())\n```\n\n```text\n\"from finally block\"\n```\n\n```text\nread_all\n```\n\n```text\nfinally\n```\n\n```text\nnext\n```\n\n```text\nfinally\n```\n\n```text\nget_db\n```\n\n```text\nDepends\n```\n\n```text\nfrom contextlib import contextmanager\n\n@contextmanager\ndef managed_resource(...):\n resource = acquire_resource(...)\n try:\n yield resource\n finally:\n release_resource(resource)\n\nwith managed_resource(...) as resource:\n ...\n```\n\n```text\nwith\n```\n\n```text\ntry/finally\n```\n\n```text\nwith\n```\n\n```text\nfinally\n```\n\n```text\nhello()\n```\n\n```text\nDepends\n```\n\n```py\nclass SomeDependency:\n def __enter__(self):\n print(\"entering\")\n def __exit__(self, exc_type, exc_val, exc_tb):\n print(\"exited\")\n\ndef hello():\n try:\n print(\"Generator starting...\")\n yield SomeDependency()\n print(\"Generator resumed after yield, but this part is never reached in this script.\")\n finally:\n print(\"FINALLY block executed!\")\n\nif __name__ == \"__main__\":\n print(\"Creating the generator and assigning it to a variable.\")\n # Keep a reference to the generator\n gen = hello() \n print(\"Generator created. FINALLY has not run yet.\")\n\n print(\"\\nCalling next(gen)...\")\n # The next() call runs the generator until the yield\n value = next(gen) \n print(f\"Received value from next(): {value}\")\n\n print(\"\\nScript is still running. The 'gen' variable is alive.\")\n print(\"The generator is paused and FINALLY has still not run.\")\n\n # The finally block will run when the 'gen' object is closed or\n # garbage collected at the end of the script.\n # Or we can close it explicitly:\n print(\"\\nExplicitly closing the generator...\")\n gen.close()\n```\n\n```text\nCreating the generator and assigning it to a variable.\nGenerator created. FINALLY has not run yet.\n\nCalling next(gen)...\nGenerator starting...\nReceived value from next(): <__main__.SomeDependency object at 0x...>\n\nScript is still running. The 'gen' variable is alive.\nThe generator is paused and FINALLY has still not run.\n\nExplicitly closing the generator...\nFINALLY block executed!\n```\n\n```text\nnext()\n```\n\n```text\nnext(hello())\n```\n\n```text\nhello()\n```\n\n```text\nhello\n```\n\n```text\ngen_obj_A\n```\n\n```text\nnext(gen_obj_A)\n```\n\n```text\nhello\n```\n\n```text\ntry\n```\n\n```text\nyield SomeDependency()\n```\n\n```text\nSomeDependency\n```\n\n```text\nnext()\n```\n\n```text\ngen_obj_A\n```\n\n```text\ngenerator.close()\n```\n\n```text\nfinally\n```\n\n```text\n.close()\n```\n\n```text\n.close()\n```\n\n```text\nGeneratorExit\n```\n\n```text\nnext(hello())\n```\n\n```text\nyield\n```\n\n```text\n.close()\n```\n\n```text\n.close()\n```\n\n```text\nGeneratorExit\n```\n\n```text\nyield\n```\n\n```text\ntry...finally\n```\n\n```text\nfinally\n```\n\n```text\nprint(\"yolo\")\n```\n\n```text\nfinally\n```\n\n```text\nfinally\n```\n\n```text\ngen = hello()\n```\n\n```text\nfinally\n```\n\n========================================\n\nComments:\n- Dependencies in FastAPI is cached across the whole request (if you're using `get_db` in multiple places in the dependency hierarchy, it does only get resolved once; thus, I'm guessing it also only gets collected after the dependency cache gets removed. You're not looking at a direct function call as in your own example, the actual call happens far further down the stack.\n- @MatsLindh what I do not understand. even if the function call happens further down. the second `hello` yields it value, it immediately calls the `finally block`. but not when fastapi makes the `get_db` yield its value. its acting like a context manager. how is it able to get you the actual value from your generator but not make it exit immediately?\n- @MatsLindh, FYI, it's done explicitly via the `with` statement. See the implementation if you are interested.\n- I do understand how a context manager and generator works otherwise how was I able to infer that it s actually what FastAPI was doing?. I mean that should implicitly tell you I do know?smh. and also my bad. the example with `__enter__` was wrong i didn't use that as a context manager in that example Anyway thank you for your explanation and links they are very helpful. It answers my question\n- You are right. I thought that because you mixed a context manager and a generator unsensibly. Anyway it's good to hear it was helpful.\n- Can you verify that your answer is not generated by AI?","metadata":{"transformedAt":"2026-08-18T18:32:29.168Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":50,"totalLines":459,"estimatedTokens":2656}}820{"id":"stack-73813029","source":"stackoverflow","questionId":73813029,"title":"How to compress image and then upload it to AWS S3 bucket using FastAPI?","tags":["python","amazon-web-services","amazon-s3","boto3","fastapi"],"text":"Title: How to compress image and then upload it to AWS S3 bucket using FastAPI?\nTags: python, amazon-web-services, amazon-s3, boto3, fastapi\nSource: Stack Overflow\n\nQuestion:\nHere is my code for uploading the image to AWS S3:\n\n```\n@app.post(\"/post_ads\")\nasync def create_upload_files(files: list[UploadFile] = File(description=\"Multiple files as UploadFile\")):\n main_image_list = []\n for file in files:\n s3 = boto3.resource(\n 's3',\n aws_access_key_id = aws_access_key_id,\n aws_secret_access_key = aws_secret_access_key\n )\n bucket = s3.Bucket(aws_bucket_name)\n bucket.upload_fileobj(file.file,file.filename,ExtraArgs={\"ACL\":\"public-read\"})\n```\n\nIs there any way to **compress the image size** and upload the image to a **specific folder** using `boto3`? I have this function for compressing the image, but I don't know how to integrate it into boto3.\n\n```\nfor file in files:\n im = Image.open(file.file)\n im = im.convert(\"RGB\")\n im_io = BytesIO()\n im = im.save(im_io, 'JPEG', quality=50) \n \n s3 = boto3.resource(\n 's3',\n aws_access_key_id = aws_access_key_id,\n aws_secret_access_key = aws_secret_access_key\n )\n bucket = s3.Bucket(aws_bucket_name)\n bucket.upload_fileobj(file.file,file.filename,ExtraArgs={\"ACL\":\"public-read\"})\n```\n\n**Update #1**\n\nAfter following Chris's recommendation, my problem has been resolved:\n\nHere is **Chris's solution**:\n\n```\nim_io.seek(0)\nbucket.upload_fileobj(im_io,file.filename,ExtraArgs={\"ACL\":\"public-read\"})\n```\n\n========================================\n\nTop Answer:\naws s3 sync s3://your-pics. for file in \"$ (find. -name \"*.jpg\")\"; do gzip \"$file\"; echo \"$file\"; done aws s3 sync. s3://your-pics --content-encoding gzip --dryrun This will download all files in s3 bucket to the machine (or ec2 instance), compresses the image files and upload them back to s3 bucket.\n\nThis should help you.\n\n========================================\n\nCode:\n```text\n@app.post(\"/post_ads\")\nasync def create_upload_files(files: list[UploadFile] = File(description=\"Multiple files as UploadFile\")):\n main_image_list = []\n for file in files:\n s3 = boto3.resource(\n 's3',\n aws_access_key_id = aws_access_key_id,\n aws_secret_access_key = aws_secret_access_key\n )\n bucket = s3.Bucket(aws_bucket_name)\n bucket.upload_fileobj(file.file,file.filename,ExtraArgs={\"ACL\":\"public-read\"})\n```\n\n```text\nfor file in files:\n im = Image.open(file.file)\n im = im.convert(\"RGB\")\n im_io = BytesIO()\n im = im.save(im_io, 'JPEG', quality=50) \n \n s3 = boto3.resource(\n 's3',\n aws_access_key_id = aws_access_key_id,\n aws_secret_access_key = aws_secret_access_key\n )\n bucket = s3.Bucket(aws_bucket_name)\n bucket.upload_fileobj(file.file,file.filename,ExtraArgs={\"ACL\":\"public-read\"})\n```\n\n```text\nim_io.seek(0)\nbucket.upload_fileobj(im_io,file.filename,ExtraArgs={\"ACL\":\"public-read\"})\n```\n\n```text\nboto3\n```\n\n```py\nbucket.upload_fileobj(file.file, file.filename, ExtraArgs={\"ACL\":\"public-read\"})\n```\n\n```py\nfrom fastapi import HTTPException\nfrom PIL import Image\nimport io\n\n# ...\n\ntry: \n im = Image.open(file.file)\n if im.mode in (\"RGBA\", \"P\"): \n im = im.convert(\"RGB\") \n buf = io.BytesIO()\n im.save(buf, 'JPEG', quality=50)\n buf.seek(0)\n bucket.upload_fileobj(buf, 'out.jpg', ExtraArgs={\"ACL\":\"public-read\"})\nexcept Exception:\n raise HTTPException(status_code=500, detail='Something went wrong')\nfinally:\n file.file.close()\n buf.close()\n im.close()\n```\n\n```text\nBytesIO\n```\n\n```text\nBytesIO\n```\n\n```text\nupload_fileobj()\n```\n\n```text\n.seek(0)\n```\n\n```text\n.seek(0)\n```\n\n```text\nim.save()\n```\n\n```text\nfile.file.seek(0)\n```\n\n```text\nfile\n```\n\n```text\nBytesIO\n```\n\n```text\nclose\n```\n\n```text\nUploadFile\n```\n\n```text\nImage\n```\n\n```text\nBytesIO\n```\n\n```text\nExtraArgs={\"ACL\":\"public-read\"}\n```\n\n========================================\n\nComments:\n- @Chris can you please explain `bucket.upload_fileobj(im_io,...`? is it `bucket.upload_fileobj(im,...`?\n- Chris I tried `bucket.upload_fileobj(im_io,..` but my image getting corrupted after uploading. I faced the similar issue before. If I remove my image compressing code then my original image uploaded without any issue\n- @Chris yes exactly it's zero. please see the full line `bucket.upload_fileobj(im_io,file.filename,ExtraArgs={\"ACL\":\"‌​public-read\", })`\n- @ Chris now image is uploading also compressing but can't view image from url. see the screenshot drive.google.com/file/d/1yNNSWrBsYUALjaeamfFEjsmUYaplUVux/…","metadata":{"transformedAt":"2026-08-18T18:32:29.168Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":20,"totalLines":189,"estimatedTokens":1191}}821{"id":"stack-71608877","source":"stackoverflow","questionId":71608877,"title":"POST to external url with FastAPI","tags":["python","json","post","fastapi"],"text":"Title: POST to external url with FastAPI\nTags: python, json, post, fastapi\nSource: Stack Overflow\n\nQuestion:\nI've been trying to figure out how to properly do a POST with FastAPI.\n\nI'm currently doing a POST with python's \"requests module\" and passing some json data as shown below:\n\n```\nimport requests\nfrom fastapi import FastAPI\n\njson_data = {\"user\" : MrMinty, \"pass\" : \"password\"} #json data\nendpoint = \"https://www.testsite.com/api/account_name/?access_token=1234567890\" #endpoint\nprint(requests.post(endpoint, json=json_data). content)\n```\n\nI don't understand how to do the same POST using just FastAPI's functions, and reading the response.\n\n========================================\n\nCode:\n```text\nimport requests\nfrom fastapi import FastAPI\n\njson_data = {\"user\" : MrMinty, \"pass\" : \"password\"} #json data\nendpoint = \"https://www.testsite.com/api/account_name/?access_token=1234567890\" #endpoint\nprint(requests.post(endpoint, json=json_data). content)\n```\n\n```text\nimport requests\nsome_info = {'info':'some_info'}\nhead = 'http://192.168.0.8:8000' #IP and port of your server \n# maybe in your case the ip is the localhost \nrequests.post(f'{head}/send_some_info', data=json.dumps(tablea))\n# \"send_some_info\" is the address of your function in fast api\n```\n\n```text\nfrom fastapi import FastAPI\napp = FastAPI()\n\n@app.post(\"/send_some_info\")\nasync def test_function(dict: dict[str, str]):\n # do something\n return 'Success'\n```\n\n========================================\n\nComments:\n- What do you mean by \"do the same POST using just FastAPI's functions? FastAPI is not an API client, is an API server - it does not do outgoing requests. Use `requests`, `httpx` or `urllib3` for that.\n- You might find this answer useful stackoverflow.com/questions/63872924/…\n- I just wanted to make sure that there wasn't a way to make outgoing requests --as I was over the FastAPI's callback documentation fastapi.tiangolo.com/advanced/openapi-callbacks","metadata":{"transformedAt":"2026-08-18T18:32:29.168Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":3,"totalLines":57,"estimatedTokens":488}}822{"id":"stack-69042316","source":"stackoverflow","questionId":69042316,"title":"Defining Fastapi Pydantic many to Many relationships","tags":["python","sqlalchemy","fastapi","pydantic"],"text":"Title: Defining Fastapi Pydantic many to Many relationships\nTags: python, sqlalchemy, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nWhat's a proper way to define many-to-many relationships in a pydantic model without getting circular import error.\nI have two files `supplier_schema.py` and `category_schema.py`.\n\n**supplier_schema.py**\n\n```\nfrom pydantic import BaseModel, HttpUrl, EmailStr\nfrom typing import Optional, List\nfrom datetime import datetime\nfrom schemas.category_schema import Category\nfrom schemas.membership_schema import Membership\n\nclass SupplierBase(BaseModel):\n contact_person: str\n email_address: EmailStr\n company_name: str\n company_email: str\n company_logo: str\n country: str\n state_province: str\n city_area: Optional[str] = None\n location: str\n phone: str\n fax: Optional[str] = None\n tagline: str\n company_bio: Optional[str]\n year_established: int\n employees_count: str\n certificates: Optional[List[str]] = None\n cover_image: Optional[HttpUrl] = None\n gallery: Optional[List[HttpUrl]] = None\n company_license: Optional[HttpUrl] = None\n company_website: Optional[HttpUrl] = None\n whatsapp_number: Optional[str] = None\n facebook_url: Optional[HttpUrl] = None\n twitter_url: Optional[HttpUrl] = None\n linkedin_url: Optional[HttpUrl] = None\n pinterest_url: Optional[HttpUrl] = None\n instagram_url: Optional[HttpUrl] = None\n youtube_url: Optional[HttpUrl] = None\n annual_revenue: Optional[str] = None\n challenges: List[str]\n status: str = None\n\n class Config:\n orm_mode = True\n\nclass SupplierCreate(SupplierBase):\n password: str\n membership_id: int\n categories_id: Optional[List[int]] = []\n\nclass Supplier(SupplierBase):\n id: int\n created_at: datetime\n updated_at: datetime\n membership: Membership\n categories: List[Category]\n```\n\n**category_schema.py**\n\n```\nfrom pydantic import BaseModel, HttpUrl, EmailStr\nfrom typing import Optional, List\nfrom datetime import datetime\nfrom schemas.category_schema import Category\nfrom schemas.membership_schema import Membership\n\nclass SupplierBase(BaseModel):\n contact_person: str\n email_address: EmailStr\n company_name: str\n company_email: str\n company_logo: str\n country: str\n state_province: str\n city_area: Optional[str] = None\n location: str\n phone: str\n fax: Optional[str] = None\n tagline: str\n company_bio: Optional[str]\n year_established: int\n employees_count: str\n certificates: Optional[List[str]] = None\n cover_image: Optional[HttpUrl] = None\n gallery: Optional[List[HttpUrl]] = None\n company_license: Optional[HttpUrl] = None\n company_website: Optional[HttpUrl] = None\n whatsapp_number: Optional[str] = None\n facebook_url: Optional[HttpUrl] = None\n twitter_url: Optional[HttpUrl] = None\n linkedin_url: Optional[HttpUrl] = None\n pinterest_url: Optional[HttpUrl] = None\n instagram_url: Optional[HttpUrl] = None\n youtube_url: Optional[HttpUrl] = None\n annual_revenue: Optional[str] = None\n challenges: List[str]\n status: str = None\n\n class Config:\n orm_mode = True\n\nclass SupplierCreate(SupplierBase):\n password: str\n membership_id: int\n categories_id: Optional[List[int]] = []\n\nclass Supplier(SupplierBase):\n id: int\n created_at: datetime\n updated_at: datetime\n membership: Membership\n categories: List[Category]\n```\n\nBut I get this error\n\n```\nTraceback (most recent call last):\n File \"/usr/lib/python3.9/multiprocessing/process.py\", line 315, in _bootstrap\n self.run()\n File \"/usr/lib/python3.9/multiprocessing/process.py\", line 108, in run\n self._target(*self._args, **self._kwargs)\n File \"/home/phat/projects/crdle2-api/venv/lib/python3.9/site-packages/uvicorn/subprocess.py\", line 61, in subprocess_started\n target(sockets=sockets)\n File \"/home/phat/projects/crdle2-api/venv/lib/python3.9/site-packages/uvicorn/server.py\", line 49, in run\n loop.run_until_complete(self.serve(sockets=sockets))\n File \"uvloop/loop.pyx\", line 1501, in uvloop.loop.Loop.run_until_complete\n File \"/home/phat/projects/crdle2-api/venv/lib/python3.9/site-packages/uvicorn/server.py\", line 56, in serve\n config.load()\n File \"/home/phat/projects/crdle2-api/venv/lib/python3.9/site-packages/uvicorn/config.py\", line 308, in load\n self.loaded_app = import_from_string(self.app)\n File \"/home/phat/projects/crdle2-api/venv/lib/python3.9/site-packages/uvicorn/importer.py\", line 23, in import_from_string\n raise exc from None\n File \"/home/phat/projects/crdle2-api/venv/lib/python3.9/site-packages/uvicorn/importer.py\", line 20, in import_from_string\n module = importlib.import_module(module_str)\n File \"/usr/lib/python3.9/importlib/__init__.py\", line 127, in import_module\n return _bootstrap._gcd_import(name[level:], package, level)\n File \"\", line 1030, in _gcd_import\n File \"\", line 1007, in _find_and_load\n File \"\", line 986, in _find_and_load_unlocked\n File \"\", line 680, in _load_unlocked\n File \"\", line 850, in exec_module\n File \"\", line 228, in _call_with_frames_removed\n File \"/home/phat/projects/crdle2-api/./main.py\", line 3, in \n from routers import supplier_router, membership_router, category_router\n File \"/home/phat/projects/crdle2-api/./routers/supplier_router.py\", line 4, in \n from schemas.supplier_schema import Supplier, SupplierCreate\n File \"/home/phat/projects/crdle2-api/./schemas/supplier_schema.py\", line 4, in \n from schemas.category_schema import Category\n File \"/home/phat/projects/crdle2-api/./schemas/category_schema.py\", line 4, in \n from schemas.supplier_schema import Supplier\nImportError: cannot import name 'Supplier' from partially initialized module 'schemas.supplier_schema' (most likely due to a circular import) (/home/phat/projects/crdle2-api/./schemas/supplier_schema.py)\n```\n\nWhat am I doing wrong? How can I fix this?\n\n========================================\n\nTop Answer:\nThis import error is owing to the following process:\n\n- `supplier_schema.py` is defined\n\n- `supplier_schema` module imports `Category` from `schemas.category_schema`\n\n- Since `schemas.category_schema` hasn't yet been defined, it is now executed.\n\n- But wait! `category_schema` requires importing `Supplier` from `supplier_schema`.\n\n- `supplier_schema` cannot proceed execution without importing from `category_schema` and vice versa.\n\n- This is known as a circular import.\n\n### How can you solve circular imports?\n\n*I'll be addressing this specific case.*\n\n*For more general use cases, read: Circular import dependency in Python*\n\n**Option 1:**\nCombine everything into one module.\n\n- This is the fastest and simplest solution.\n\n- Can get pretty out of hand once your ORM code increases to many models.\n\n**Option 2:**\nImport models in the initialization of the root module and change import language:\n\n- Robust solution\n\n- Requires more careful planning and architecting of your project\n\n- Requires testing (additional imports create opportunity for breakage)\n\n**Here's how to execute this:**\n\nEnsure your `schemas` module contains an `init` file:\n\n```\n-- schemas\n|-- __init__.py\n|-- category_schema.py\n|-- membership_schema.py\n```\n\nYour `__init__.py` file should contain the following:\n\n```\nfrom . import category_schema\nfrom . import membership_schema\n```\n\nNow, your imports should be revised to the following:\n\n```\n# Old way: ⬇\n# from schemas.category_schema import Category\n\n# New way: ⬇\nimport schemas\n\n...\n\nclass Supplier(SupplierBase): \n categories: List[schemas.category_schema.Category]\n...\n```\n\nRepeat for other submodules and imports.\n\n### A word of advice on choosing a solution:\n\nCircular imports are very common errors when working with ORMs. Encountering one means you've greatly extended the properties of your application – congratulations! Choosing the best solution for your project depends on your goals.\n\n- If your code is a proof of concept and you need to move quickly, I'd recommend choosing option 1. *(Move fast and break things.)*\n\n- If your code is part of a more robust project, even if you're in the early stages, definitely choose option 2. *(Solve tomorrow's problems today.)*\n\n========================================\n\nCode:\n```text\nfrom pydantic import BaseModel, HttpUrl, EmailStr\nfrom typing import Optional, List\nfrom datetime import datetime\nfrom schemas.category_schema import Category\nfrom schemas.membership_schema import Membership\n\n\nclass SupplierBase(BaseModel):\n contact_person: str\n email_address: EmailStr\n company_name: str\n company_email: str\n company_logo: str\n country: str\n state_province: str\n city_area: Optional[str] = None\n location: str\n phone: str\n fax: Optional[str] = None\n tagline: str\n company_bio: Optional[str]\n year_established: int\n employees_count: str\n certificates: Optional[List[str]] = None\n cover_image: Optional[HttpUrl] = None\n gallery: Optional[List[HttpUrl]] = None\n company_license: Optional[HttpUrl] = None\n company_website: Optional[HttpUrl] = None\n whatsapp_number: Optional[str] = None\n facebook_url: Optional[HttpUrl] = None\n twitter_url: Optional[HttpUrl] = None\n linkedin_url: Optional[HttpUrl] = None\n pinterest_url: Optional[HttpUrl] = None\n instagram_url: Optional[HttpUrl] = None\n youtube_url: Optional[HttpUrl] = None\n annual_revenue: Optional[str] = None\n challenges: List[str]\n status: str = None\n\n class Config:\n orm_mode = True\n\n\nclass SupplierCreate(SupplierBase):\n password: str\n membership_id: int\n categories_id: Optional[List[int]] = []\n\n\nclass Supplier(SupplierBase):\n id: int\n created_at: datetime\n updated_at: datetime\n membership: Membership\n categories: List[Category]\n```\n\n```text\nfrom pydantic import BaseModel, HttpUrl, EmailStr\nfrom typing import Optional, List\nfrom datetime import datetime\nfrom schemas.category_schema import Category\nfrom schemas.membership_schema import Membership\n\n\nclass SupplierBase(BaseModel):\n contact_person: str\n email_address: EmailStr\n company_name: str\n company_email: str\n company_logo: str\n country: str\n state_province: str\n city_area: Optional[str] = None\n location: str\n phone: str\n fax: Optional[str] = None\n tagline: str\n company_bio: Optional[str]\n year_established: int\n employees_count: str\n certificates: Optional[List[str]] = None\n cover_image: Optional[HttpUrl] = None\n gallery: Optional[List[HttpUrl]] = None\n company_license: Optional[HttpUrl] = None\n company_website: Optional[HttpUrl] = None\n whatsapp_number: Optional[str] = None\n facebook_url: Optional[HttpUrl] = None\n twitter_url: Optional[HttpUrl] = None\n linkedin_url: Optional[HttpUrl] = None\n pinterest_url: Optional[HttpUrl] = None\n instagram_url: Optional[HttpUrl] = None\n youtube_url: Optional[HttpUrl] = None\n annual_revenue: Optional[str] = None\n challenges: List[str]\n status: str = None\n\n class Config:\n orm_mode = True\n\n\nclass SupplierCreate(SupplierBase):\n password: str\n membership_id: int\n categories_id: Optional[List[int]] = []\n\n\nclass Supplier(SupplierBase):\n id: int\n created_at: datetime\n updated_at: datetime\n membership: Membership\n categories: List[Category]\n```\n\n```text\nTraceback (most recent call last):\n File \"/usr/lib/python3.9/multiprocessing/process.py\", line 315, in _bootstrap\n self.run()\n File \"/usr/lib/python3.9/multiprocessing/process.py\", line 108, in run\n self._target(*self._args, **self._kwargs)\n File \"/home/phat/projects/crdle2-api/venv/lib/python3.9/site-packages/uvicorn/subprocess.py\", line 61, in subprocess_started\n target(sockets=sockets)\n File \"/home/phat/projects/crdle2-api/venv/lib/python3.9/site-packages/uvicorn/server.py\", line 49, in run\n loop.run_until_complete(self.serve(sockets=sockets))\n File \"uvloop/loop.pyx\", line 1501, in uvloop.loop.Loop.run_until_complete\n File \"/home/phat/projects/crdle2-api/venv/lib/python3.9/site-packages/uvicorn/server.py\", line 56, in serve\n config.load()\n File \"/home/phat/projects/crdle2-api/venv/lib/python3.9/site-packages/uvicorn/config.py\", line 308, in load\n self.loaded_app = import_from_string(self.app)\n File \"/home/phat/projects/crdle2-api/venv/lib/python3.9/site-packages/uvicorn/importer.py\", line 23, in import_from_string\n raise exc from None\n File \"/home/phat/projects/crdle2-api/venv/lib/python3.9/site-packages/uvicorn/importer.py\", line 20, in import_from_string\n module = importlib.import_module(module_str)\n File \"/usr/lib/python3.9/importlib/__init__.py\", line 127, in import_module\n return _bootstrap._gcd_import(name[level:], package, level)\n File \"<frozen importlib._bootstrap>\", line 1030, in _gcd_import\n File \"<frozen importlib._bootstrap>\", line 1007, in _find_and_load\n File \"<frozen importlib._bootstrap>\", line 986, in _find_and_load_unlocked\n File \"<frozen importlib._bootstrap>\", line 680, in _load_unlocked\n File \"<frozen importlib._bootstrap_external>\", line 850, in exec_module\n File \"<frozen importlib._bootstrap>\", line 228, in _call_with_frames_removed\n File \"/home/phat/projects/crdle2-api/./main.py\", line 3, in <module>\n from routers import supplier_router, membership_router, category_router\n File \"/home/phat/projects/crdle2-api/./routers/supplier_router.py\", line 4, in <module>\n from schemas.supplier_schema import Supplier, SupplierCreate\n File \"/home/phat/projects/crdle2-api/./schemas/supplier_schema.py\", line 4, in <module>\n from schemas.category_schema import Category\n File \"/home/phat/projects/crdle2-api/./schemas/category_schema.py\", line 4, in <module>\n from schemas.supplier_schema import Supplier\nImportError: cannot import name 'Supplier' from partially initialized module 'schemas.supplier_schema' (most likely due to a circular import) (/home/phat/projects/crdle2-api/./schemas/supplier_schema.py)\n```\n\n```text\nsupplier_schema.py\n```\n\n```text\ncategory_schema.py\n```\n\n```text\nfrom __future__ import annotations\nfrom pydantic import BaseModel\nfrom typing import Optional, List\nfrom datetime import datetime\n# import schemas\n\n\nclass SupplierBase(BaseModel):\n company_email: Optional[str] = None\n logo: Optional[str] = None\n state_province: str = None\n city_area: Optional[str] = None\n location: Optional[str] = None\n company_phone: str = None\n fax: Optional[str] = None\n tagline: Optional[str] = None\n company_bio: Optional[str] = None\n postal_code: Optional[str] = None\n year_established: str = None\n employees_count: Optional[str] = None\n certificates: Optional[List[dict]] = []\n cover_image: Optional[str] = None\n gallery: Optional[List[dict]] = None\n license: Optional[str] = None\n website: Optional[str] = None\n whatsapp_number: Optional[str] = None\n facebook_url: Optional[str] = None\n twitter_url: Optional[str] = None\n linkedin_url: Optional[str] = None\n pinterest_url: Optional[str] = None\n instagram_url: Optional[str] = None\n youtube_url: Optional[str] = None\n annual_revenue: Optional[str] = None\n payment_methods: Optional[List[dict]] = None\n challenges: Optional[List[str]] = []\n status: str = None\n user_id: int\n\n class Config:\n orm_mode = True\n\n\nclass SupplierCreate(SupplierBase):\n pass\n\n\nclass Supplier(SupplierBase):\n id: int\n categories: Optional[List[Category]] = []\n created_at: datetime\n updated_at: datetime\n\n\nfrom .category_schema import Category # nopep8\nCategory.update_forward_refs()\n```\n\n```text\nfrom __future__ import annotations\nfrom typing import List\nfrom pydantic import BaseModel\nfrom datetime import datetime\n\n\nclass CategoryBase(BaseModel):\n label: str\n\n class Config:\n orm_mode = True\n\n\nclass CategoryCreate(CategoryBase):\n pass\n\n\nclass Category(CategoryBase):\n id: int\n created_at: datetime\n updated_at: datetime\n suppliers: List[Supplier]\n\n\nfrom .supplier_schema import Supplier # nopep8\nCategory.update_forward_refs()\n\n\nclass CategorySkeleton(CategoryBase):\n pass\n\n\nclass CategoryPatch(CategoryBase):\n pass\n```\n\n```text\nfrom __future__ import annotations\n```\n\n```text\n-- schemas\n|-- __init__.py\n|-- category_schema.py\n|-- membership_schema.py\n```\n\n```text\nfrom . import category_schema\nfrom . import membership_schema\n```\n\n```text\n# Old way: ⬇\n# from schemas.category_schema import Category\n\n# New way: ⬇\nimport schemas\n\n...\n\nclass Supplier(SupplierBase): \n categories: List[schemas.category_schema.Category]\n...\n```\n\n```text\nsupplier_schema.py\n```\n\n```text\nsupplier_schema\n```\n\n```text\nCategory\n```\n\n```text\nschemas.category_schema\n```\n\n```text\nschemas.category_schema\n```\n\n```text\ncategory_schema\n```\n\n```text\nSupplier\n```\n\n```text\nsupplier_schema\n```\n\n```text\nsupplier_schema\n```\n\n```text\ncategory_schema\n```\n\n```text\nschemas\n```\n\n```text\ninit\n```\n\n```text\n__init__.py\n```\n\n========================================\n\nComments:\n- So, I revised all of my imports to the second option. But now I get: AttributeError: partially initialized module 'schemas' has no attribute 'supplier_schema' (most likely due to a circular import). Any ideas?\n- I would be thankful if you could help me out once more\n- Is it possible your code references these models elsewhere (and is loading them in different order?) @phatnael\n- This one worked for me.\n- Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.","metadata":{"transformedAt":"2026-08-18T18:32:29.168Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":24,"totalLines":597,"estimatedTokens":4335}}823{"id":"stack-62529877","source":"stackoverflow","questionId":62529877,"title":"Pydantic: Validate discriminated union with literals","tags":["python","discriminated-union","fastapi","pydantic"],"text":"Title: Pydantic: Validate discriminated union with literals\nTags: python, discriminated-union, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI am trying to use `Literal` to create a discriminated union with Pydantic.\nThere are events about a Job resource, and I want to distinguish them by `event_name`. For `JobPublishedEvents` I want to ensure, that some `extra_field` is present.\n\n```\nclass GenericJobEvent(BaseModel):\n event_name: str\n id: int\n\nclass JobPublishedEvent(GenericJobEvent):\n event_name: Literal['job.published']\n extra_field: str\n\nclass Wrapper(BaseModel):\n wrapped: Union[JobPublishedEvent, GenericJobEvent]\n\nprint(type(Wrapper(wrapped={'event_name': 'some.event', 'id': 1}).wrapped)) # GenericJobEvent\nprint(type(Wrapper(wrapped={'event_name': 'job.published', 'id': 1, 'extra_field': 'extra'}).wrapped)) # JobPublishedEvent\nprint(type(Wrapper(wrapped={'event_name': 'job.published', 'id': 1}).wrapped)) # GenericJobEvent\n```\n\nThe first 2 cases behave as expected, for the third I would like a validation error since the literal matches, but the schema is not fulfilled. I get why the fallback to the GenericJobEvent is valid, though.\n\nDoes anybody have an idea on how to achieve this?\n\n========================================\n\nCode:\n```py\nclass GenericJobEvent(BaseModel):\n event_name: str\n id: int\n\n\nclass JobPublishedEvent(GenericJobEvent):\n event_name: Literal['job.published']\n extra_field: str\n\n\nclass Wrapper(BaseModel):\n wrapped: Union[JobPublishedEvent, GenericJobEvent]\n\nprint(type(Wrapper(wrapped={'event_name': 'some.event', 'id': 1}).wrapped)) # GenericJobEvent\nprint(type(Wrapper(wrapped={'event_name': 'job.published', 'id': 1, 'extra_field': 'extra'}).wrapped)) # JobPublishedEvent\nprint(type(Wrapper(wrapped={'event_name': 'job.published', 'id': 1}).wrapped)) # GenericJobEvent\n```\n\n```text\nLiteral\n```\n\n```text\nevent_name\n```\n\n```text\nJobPublishedEvents\n```\n\n```text\nextra_field\n```\n\n```text\n@validator('event_name')\n def event_name_filter(cls, v):\n if 'job.published' == v:\n raise ValueError('GenericJobEvent cannot have event_name equal to job.published')\n return v.title()\n```\n\n```text\nJobPublishedEvent\n```\n\n```text\nGenericJobEvent\n```\n\n```text\nevent_name\n```\n\n```text\nid\n```\n\n```text\nevent_name\n```\n\n```text\nGenericJobEvent\n```\n\n```text\njob.published\n```\n\n========================================\n\nComments:\n- Yeah, that's what I meant with \"I get why the fallback to the GenericJobEvent is valid\". What I would need is for the GenericEvent to accept all strings except the ones defined in subclasses... Thank you for your solution!\n- Sorry, too much multitasking led to distracting me. Glad I've helped","metadata":{"transformedAt":"2026-08-18T18:32:29.168Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":13,"totalLines":108,"estimatedTokens":675}}824{"id":"stack-74267757","source":"stackoverflow","questionId":74267757,"title":"How to authorize OpenAPI/Swagger UI page in FastAPI?","tags":["python","oauth-2.0","fastapi","swagger-ui","openapi"],"text":"Title: How to authorize OpenAPI/Swagger UI page in FastAPI?\nTags: python, oauth-2.0, fastapi, swagger-ui, openapi\nSource: Stack Overflow\n\nQuestion:\nI'm building a FastAPI application with OAuth2 and JWT authentication. I've got two endpoints that create the JWT token. The first is hidden from the OpenAPI page but is used by the page `Authorize` button. The second does the same functionality but is available to the users as an API endpoint.\n\nIf the user uses the page `Authorize` button and successfully gets authenticated, the rest of the API endpoints on the OpenAPI page become accessible.\n\nIf the user uses the API `get_token` endpoint only, they get a valid JWT token, which can be used with the protected API's, but the OpenAPI page isn't authenticated.\n\nHow can I use the token returned by the public `get_token` API endpoint to authenticate the OpenAPI page as if the user went through OpenAPI provided `Authorize` functionality?\n\n========================================\n\nCode:\n```text\nAuthorize\n```\n\n```text\nAuthorize\n```\n\n```text\nget_token\n```\n\n```text\nget_token\n```\n\n```text\nAuthorize\n```\n\n```text\nAuthorize\n```\n\n```text\nAuthorization\n```\n\n```text\nget_token\n```\n\n```text\nAuthorization\n```\n\n```text\nHeader\n```\n\n```text\ntoken\n```\n\n```text\ntoken\n```\n\n```text\nAuthorize\n```\n\n```text\nhttponly\n```\n\n```text\nSet-Cookie\n```\n\n```text\nget_token\n```\n\n```text\nResponse\n```\n\n```text\nCookie\n```\n\n```text\nRequest\n```\n\n```text\nrequest.cookies.get('token')\n```\n\n========================================\n\nComments:\n- Thanks Chris, this all makes sense. I'll need to dig into this to balance the use case between the OpenAPI page, or users using something like PostMan, where they would have to add the Bearer token to the Authorization header.","metadata":{"transformedAt":"2026-08-18T18:32:29.168Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":20,"totalLines":100,"estimatedTokens":435}}825{"id":"stack-74925057","source":"stackoverflow","questionId":74925057,"title":"How to redirect the user to another webpage without using JavaScript in a Jinja2 HTML template?","tags":["python","html","http-redirect","jinja2","fastapi"],"text":"Title: How to redirect the user to another webpage without using JavaScript in a Jinja2 HTML template?\nTags: python, html, http-redirect, jinja2, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm using a Jinja2 Template with FastAPI. All I want to know is how to implement a `redirect` action in Jinja2 template **without using JavaScrpit**?\n\nIf the variable I set exists, I would like to force a page redirection.\n\n```\n{% if my_var %}\n // What value should I enter here?\n{% endif %}\n```\n\nCase in my titles with java :\n\n```\n \n \n\n```\n\nCase in my PHP :\n\n```\nif(!empty($my_var) ){\n header('Location:/new/url');\n exit; \n}\n```\n\nIf there is no way, I have to use JavaScript, but I don't want to use this method at all, as some of people deactivate JavaScript in their browsers.\n\n========================================\n\nCode:\n```text\n{% if my_var %}\n // What value should I enter here?\n{% endif %}\n```\n\n```text\n<c:if test=\"${!emtpy(my_var)}\"> \n <% response.sendRedirect(\"/new/url\"); %>\n</c:if>\n```\n\n```text\nif(!empty($my_var) ){\n header('Location:/new/url');\n exit; \n}\n```\n\n```text\nredirect\n```\n\n```html\n<head>\n {% if my_var %}\n <meta http-equiv=\"refresh\" content=\"0; url='https://stackoverflow.com'\" />\n {% endif %}\n</head>\n```\n\n```text\n<meta>\n```\n\n```text\nhttp-equiv\n```\n\n```text\nrefresh\n```\n\n```text\ncontent\n```\n\n```text\n';url='\n```\n\n```text\ncontent\n```\n\n```text\n0\n```\n\n```text\n<meta>\n```\n\n```text\n<head>\n```\n\n```text\n<meta>\n```\n\n```text\n<body>\n```\n\n```text\nitemprop\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.168Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":17,"totalLines":115,"estimatedTokens":374}}826{"id":"stack-73430447","source":"stackoverflow","questionId":73430447,"title":"Python API Patch updates all fields instead of just the given","tags":["python","fastapi","pydantic"],"text":"Title: Python API Patch updates all fields instead of just the given\nTags: python, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nSo my issue is when creating a patch request to `post` which will update `title` and `content` but when sending, the patch request updates all optional fields to the defaults:\n\n`post`- it's class:\n\n```\nclass Post(BaseModel):\n title: str\n content: str\n published: bool = True\n rating: Optional[bool] = None\n```\n\n`post` stored in memory:\n\n```\n[{\"title\": \"title\",\n \"content\": \"stuff\", \n \"published\": False,\n \"rating\": True,\n \"id\": 1}]\n```\n\njson sent:\n\n```\n{\n\"title\": \"updated title\",\n\"content\": \"stuffyy\"\n}\n```\n\n`post` received:\n\n```\n{\n\"data\": {\n \"title\": \"updated title\",\n \"content\": \"stuffyy\",\n \"published\": true,\n \"rating\": null,\n \"id\": 1\n }\n}\n```\n\nand the python code:\n\n```\n@app.patch(\"/posts/{id}\")\ndef update_post(id: int, post: Post):\n index = find_index_post(id)\n if index == None:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f\"post with id: '{id}' does not exist, hence cannot be updated\")\n post_dict = post.dict()\n post_dict['id'] = id\n my_posts[index] = post_dict\n return {\"data\": post_dict}\n```\n\nprobably out of my depth here\n\n========================================\n\nTop Answer:\nYou want `PATCH`, not `POST` to only update the fields explicitly included. `POST` creates a whole new object and overwrites with that.\n\n========================================\n\nCode:\n```text\nclass Post(BaseModel):\n title: str\n content: str\n published: bool = True\n rating: Optional[bool] = None\n```\n\n```text\n[{\"title\": \"title\",\n \"content\": \"stuff\", \n \"published\": False,\n \"rating\": True,\n \"id\": 1}]\n```\n\n```text\n{\n\"title\": \"updated title\",\n\"content\": \"stuffyy\"\n}\n```\n\n```text\n{\n\"data\": {\n \"title\": \"updated title\",\n \"content\": \"stuffyy\",\n \"published\": true,\n \"rating\": null,\n \"id\": 1\n }\n}\n```\n\n```text\n@app.patch(\"/posts/{id}\")\ndef update_post(id: int, post: Post):\n index = find_index_post(id)\n if index == None:\n raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f\"post with id: '{id}' does not exist, hence cannot be updated\")\n post_dict = post.dict()\n post_dict['id'] = id\n my_posts[index] = post_dict\n return {\"data\": post_dict}\n```\n\n```text\npost\n```\n\n```text\ntitle\n```\n\n```text\ncontent\n```\n\n```text\npost\n```\n\n```text\npost\n```\n\n```text\npost\n```\n\n```text\nclass Post(BaseModel):\n title: str\n content: str\n published: bool = True # <--------default to true\n rating: Optional[bool] = None # <--------default to null\n```\n\n```text\npost_dict = post.dict(exclude_unset=True)\n```\n\n```text\npost_dict = post.dict(exclude={'published', 'rating'})\n```\n\n```text\nPost\n```\n\n```text\npublished\n```\n\n```text\nrating\n```\n\n```text\nTrue(true)\n```\n\n```text\nNone(null)\n```\n\n```text\ndef update_post(id: int, post: Post):\n```\n\n```text\nexclude\n```\n\n```text\nPATCH\n```\n\n```text\nPOST\n```\n\n```text\nPOST\n```\n\n```text\nfrom pydantic import BaseModel\nclass PatchModelForPost(BaseModel):\n title: str\n content: str\n\n@app.patch(\"/posts/{id}\")\ndef update_post(id: int, post: PatchModelForPost):\n```\n\n========================================\n\nComments:\n- You would need to use Pydantic's `exclude_unset=True`, e.g., `post_dict = post.dict(exclude_unset=True)`. Please have a look at **this answer** for more details.\n- this does work in not updating the fields excluded, but it does this by deleting the fields not given - any work around?","metadata":{"transformedAt":"2026-08-18T18:32:29.169Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":25,"totalLines":216,"estimatedTokens":859}}827{"id":"stack-67571477","source":"stackoverflow","questionId":67571477,"title":"Python FastAPI: Returned gif image is not animating","tags":["javascript","python","html","fastapi"],"text":"Title: Python FastAPI: Returned gif image is not animating\nTags: javascript, python, html, fastapi\nSource: Stack Overflow\n\nQuestion:\nBelow is my Python FastAPI route and HTML page:\n\n**Python:**\n\n```\n@app.get('/', status_code=200)\nasync def upload_file(file: UploadFile = File(...)):\n error_img = Image.open('templates/crying.gif')\n byte_io = BytesIO()\n error_img.save(byte_io, 'png')\n byte_io.seek(0)\n return StreamingResponse(byte_io, media_type='image/gif')\n```\n\n**HTML:**\n\n```\n\nfunction goBuster(file) {\n\n fetch('/', {\n method: 'GET',\n body: data\n })\n .then(response => response.blob())\n .then(image => {\n var outside = URL.createObjectURL(image);\n var mazeimg = document.getElementById(\"img-maze\");\n mazeimg.onload = () => {\n URL.revokeObjectURL(mazeimg.src);\n }\n mazeimg.setAttribute('src', outside);\n mazeimg.setAttribute('style', 'display:inline-block');\n\n })\n}\n```\n\nThe image is not animating, I checked the generated HTML and found:\n\n```\n\n```\n\nSo the image's `src` attribute is using blob, I guess this is the reason why the gif is not animating, but I have no idea how to fix it.\n\n### Update 1\n\nNow I have updated my code to:\n\n```\nwith open('templates/crying.gif', 'rb') as f:\n img_raw = f.read()\n byte_io = BytesIO()\n byte_io.write(img_raw)\n byte_io.seek(0)\n return StreamingResponse(byte_io, media_type='image/gif')\n```\n\nThe generated HTML looks same:\n\n```\n\n```\n\nbut it gets worse, the image is not even showing up.\n\n========================================\n\nTop Answer:\n```\nerror_img.save(byte_io, 'png')\n```\n\nYou're converting this image to png. PNG doesn't support animation.\n\nI think you can use:\n\n```\n@app.get('/', status_code=200)\nasync def upload_file(file: UploadFile = File(...)):\n with open('templates/crying.gif', 'rb') as f:\n img_raw = f.read()\n byte_io = BytesIO(img_raw)\n return StreamingResponse(byte_io, media_type='image/gif')\n```\n\n========================================\n\nCode:\n```text\n@app.get('/', status_code=200)\nasync def upload_file(file: UploadFile = File(...)):\n error_img = Image.open('templates/crying.gif')\n byte_io = BytesIO()\n error_img.save(byte_io, 'png')\n byte_io.seek(0)\n return StreamingResponse(byte_io, media_type='image/gif')\n```\n\n```text\n<img src=\"\" id=\"img-maze\" alt=\"this is photo\" style=\"display: none;\" />\n\nfunction goBuster(file) {\n\n fetch('/', {\n method: 'GET',\n body: data\n })\n .then(response => response.blob())\n .then(image => {\n var outside = URL.createObjectURL(image);\n var mazeimg = document.getElementById(\"img-maze\");\n mazeimg.onload = () => {\n URL.revokeObjectURL(mazeimg.src);\n }\n mazeimg.setAttribute('src', outside);\n mazeimg.setAttribute('style', 'display:inline-block');\n\n })\n}\n```\n\n```text\n<img src=\"blob:http://127.0.0.1:8000/ee2bda53-92ac-466f-afa5-e6e34fa3d341\" id=\"img-maze\" alt=\"this is photo\" style=\"display:inline-block\">\n```\n\n```text\nwith open('templates/crying.gif', 'rb') as f:\n img_raw = f.read()\n byte_io = BytesIO()\n byte_io.write(img_raw)\n byte_io.seek(0)\n return StreamingResponse(byte_io, media_type='image/gif')\n```\n\n```text\n<img src=\"blob:http://127.0.0.1:8000/c3ad0683-3971-4444-bf20-2c9cd5eedc3d\" id=\"img-maze\" alt=\"this is maze photo\" style=\"display:inline-block\">\n```\n\n```text\nsrc\n```\n\n```text\nwb\n```\n\n```text\nrb\n```\n\n```text\nwb\n```\n\n```text\nrb\n```\n\n```py\nerror_img.save(byte_io, 'png')\n```\n\n```py\n@app.get('/', status_code=200)\nasync def upload_file(file: UploadFile = File(...)):\n with open('templates/crying.gif', 'rb') as f:\n img_raw = f.read()\n byte_io = BytesIO(img_raw)\n return StreamingResponse(byte_io, media_type='image/gif')\n```\n\n========================================\n\nComments:\n- Hi Vad, thanks for your answer. It throws an error: ` img_raw = f.read() io.UnsupportedOperation: read`\n- I found the reason, change `wb` to `rb` solved the UnsupportedOperation read`. However, the issue is still there and gets worse, the image does now show up any more.\n- hi @vadsim, I will set your post as the answer, could you please update `wb` to `rb`? thanks :)","metadata":{"transformedAt":"2026-08-18T18:32:29.169Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":12,"totalLines":184,"estimatedTokens":1040}}828{"id":"stack-73041248","source":"stackoverflow","questionId":73041248,"title":"Return the same response model on two different endpoints on FastAPI","tags":["python","fastapi"],"text":"Title: Return the same response model on two different endpoints on FastAPI\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am using FastAPI and I cannot view the documentation on the /docs endpoint when I have the same response model for two endpoints.\n\nThis is the code I use\n\n```\nimport dataclasses\n\nimport fastapi\nimport uvicorn\n\napp = fastapi.FastAPI()\n\n@dataclasses.dataclass\nclass Response:\n yo: str\n\n@app.post('/one', response_model=Response)\ndef get_responses():\n pass\n\n@app.post('/two', response_model=Response) # When I remove this \"Response\", or I create a second class it works.\ndef send_responses():\n pass\n\nif __name__ == '__main__':\n uvicorn.run(app, host='127.0.0.1')\n```\n\nThis is the error it shows in the browser\nhttps://i.sstatic.net/tCZT6.png\n\nThis is the error it shows in the code\n\n```\n...\nresponse = await func(request)\n File \"E:\\Code\\venvs\\lib\\site-packages\\fastapi\\applications.py\", line 224, in openapi\n return JSONResponse(self.openapi())\n File \"E:\\Code\\venvs\\lib\\site-packages\\fastapi\\applications.py\", line 199, in openapi\n self.openapi_schema = get_openapi(\n File \"E:\\Code\\venvs\\lib\\site-packages\\fastapi\\openapi\\utils.py\", line 418, in get_openapi\n definitions = get_model_definitions(\n File \"E:\\Code\\venvs\\lib\\site-packages\\fastapi\\utils.py\", line 32, in get_model_definitions\n model_name = model_name_map[model]\nKeyError: \n```\n\nWhat am I doing wrong?\n\n========================================\n\nTop Answer:\nYou can also get this error if you use a function to generate endpoints and define a Pydantic model inside that function, causing it to be defined multiple times. The error will look like\n\n```\nFile \"/usr/local/lib/python3.10/site-packages/fastapi/utils.py\", line 39, in get_model_definitions\n model_name = model_name_map[model]\nKeyError: .MyModel'>\n```\n\nIn this case move the Pydantic definition outside the function.\n\n========================================\n\nCode:\n```text\nimport dataclasses\n\nimport fastapi\nimport uvicorn\n\napp = fastapi.FastAPI()\n\n\n\n@dataclasses.dataclass\nclass Response:\n yo: str\n\n\n@app.post('/one', response_model=Response)\ndef get_responses():\n pass\n\n\n@app.post('/two', response_model=Response) # When I remove this \"Response\", or I create a second class it works.\ndef send_responses():\n pass\n\n\nif __name__ == '__main__':\n uvicorn.run(app, host='127.0.0.1')\n```\n\n```text\n...\nresponse = await func(request)\n File \"E:\\Code\\venvs\\lib\\site-packages\\fastapi\\applications.py\", line 224, in openapi\n return JSONResponse(self.openapi())\n File \"E:\\Code\\venvs\\lib\\site-packages\\fastapi\\applications.py\", line 199, in openapi\n self.openapi_schema = get_openapi(\n File \"E:\\Code\\venvs\\lib\\site-packages\\fastapi\\openapi\\utils.py\", line 418, in get_openapi\n definitions = get_model_definitions(\n File \"E:\\Code\\venvs\\lib\\site-packages\\fastapi\\utils.py\", line 32, in get_model_definitions\n model_name = model_name_map[model]\nKeyError: <class 'pydantic.dataclasses.Response'>\n```\n\n```text\nimport dataclasses\n\nimport fastapi\nimport uvicorn\nimport pydantic\n\n\napp = fastapi.FastAPI()\n\n\nclass Response(pydantic.BaseModel):\n yo: str\n\n\n@app.post('/one', response_model=Response)\ndef get_responses():\n pass\n\n\n@app.post('/two', response_model=Response)\ndef send_responses():\n pass\n\n\nif __name__ == '__main__':\n uvicorn.run(app, host='127.0.0.1')\n```\n\n```text\nFile \"/usr/local/lib/python3.10/site-packages/fastapi/utils.py\", line 39, in get_model_definitions\n model_name = model_name_map[model]\nKeyError: <class 'app.routes.my_generate_routes.<locals>.MyModel'>\n```\n\n========================================\n\nComments:\n- There is something weird going on with dataclasses in FastAPI. I haven't been able to put my finger on it, but there are others with the same problem, for example github.com/tiangolo/fastapi/issues/5138\n- Thank you for the quick response, I'll observe that topic in the link you mentioned. I assume the issue could be solved by using pydantics BaseModel instead of the dataclasses. I'll try that tomorrow\n- Yes definitely, it is a specific issue to dataclasses. Base model works as expected!\n- If you use fastapi there is no point using basic dataclasses, you should use pydantic models as it is shipped with the framework\n- With BaseModel it does work indeed. @BastienB I usually prefer dataclasses due to better IDE support","metadata":{"transformedAt":"2026-08-18T18:32:29.169Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":4,"totalLines":156,"estimatedTokens":1084}}829{"id":"stack-72702693","source":"stackoverflow","questionId":72702693,"title":"How to get separately column from sqlalchemy relationship using pydantic schema","tags":["python","sqlalchemy","fastapi","pydantic"],"text":"Title: How to get separately column from sqlalchemy relationship using pydantic schema\nTags: python, sqlalchemy, fastapi, pydantic\nSource: Stack Overflow\n\nQuestion:\nI have 4 tables: `Hardware`, `SoftwareName`, `SoftwareVersion`, and `Software`.\n\nThe `Software` table has an `one-to-many` relationship with `SoftwareName` table and `SoftwareVersion` table. Finally, the `Hardware` model has an `one-to-many` relationship with `Software` table.\n\nI'm trying to get just a specific column from a model relationship using `Pydantic Schema`.\n\nNow I'm getting this output:\n\n```\n[\n {\n \"id\": 1,\n \"hostname\": \"hostname2\",\n \"softwares\": [\n {\n \"id\": 1,\n \"software_name\": {\n \"id\": 1,\n \"name\": \"nginx\"\n },\n \"software_version\": {\n \"id\": 1,\n \"version\": \"2.9\"\n }\n },\n {\n \"id\": 2,\n \"software_name\": {\n \"id\": 2,\n \"name\": \"vim\"\n },\n \"software_version\": {\n \"id\": 2,\n \"version\": \"0.3\"\n }\n },\n {\n \"id\": 3,\n \"software_name\": {\n \"id\": 3,\n \"name\": \"apache\"\n },\n \"software_version\": {\n \"id\": 3,\n \"version\": \"1.0\"\n }\n }\n ]\n }\n]\n```\n\nBut what I expect is this output:\n\n```\n[\n {\n \"id\": 1,\n \"hostname\": \"hostname2\",\n \"softwares\": [\n {\n \"id\": 1,\n \"name\": \"nginx\",\n \"version\": \"2.9\"\n },\n {\n \"id\": 2,\n \"name\": \"vim\",\n \"version\": \"0.3\"\n },\n {\n \"id\": 3,\n \"name\": \"apache\",\n \"version\": \"1.0\"\n }\n ]\n }\n]\n```\n\nI have the file `main.py`:\n\n```\nimport uvicorn\nfrom typing import Any, Iterator, List, Optional\nfrom faker import Faker\nfrom fastapi import Depends, FastAPI\nfrom pydantic import BaseModel\nfrom sqlalchemy import Column, ForeignKey, Integer, String, create_engine\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import Session, sessionmaker, relationship\nfrom faker.providers import DynamicProvider\n\nsoftware_name = DynamicProvider(\n provider_name=\"software_name\",\n elements=[\"bash\", \"vim\", \"vscode\", \"nginx\", \"apache\"],\n)\n\nsoftware_version = DynamicProvider(\n provider_name=\"software_version\",\n elements=[\"1.0\", \"2.9\", \"1.1\", \"0.3\", \"2.0\"],\n)\n\nhardware = DynamicProvider(\n provider_name=\"hardware\",\n elements=[\"hostname1\", \"hostname2\", \"hostname3\", \"hostname4\", \"hostname5\"],\n)\n\nfake = Faker()\n\n# then add new provider to faker instance\nfake.add_provider(software_name)\nfake.add_provider(software_version)\nfake.add_provider(hardware)\n\nengine = create_engine(\"sqlite:///.db\", connect_args={\"check_same_thread\": False})\nSessionLocal = sessionmaker(autocommit=True, autoflush=True, bind=engine)\n\nBase = declarative_base(bind=engine)\n\nclass Software(Base):\n __tablename__ = 'software'\n\n id = Column(Integer, primary_key=True)\n hardware_id = Column(Integer, ForeignKey('hardware.id'))\n name_id = Column(Integer, ForeignKey('software_name.id'))\n version_id = Column(Integer, ForeignKey('software_version.id'))\n\n software_name = relationship('SoftwareName', backref='software_name')\n software_version = relationship('SoftwareVersion',\n backref='software_version')\n\nclass SoftwareName(Base):\n __tablename__ = 'software_name'\n\n id = Column(Integer, primary_key=True)\n name = Column(String)\n\nclass SoftwareVersion(Base):\n __tablename__ = 'software_version'\n\n id = Column(Integer, primary_key=True)\n version = Column(String)\n\nclass Hardware(Base):\n __tablename__ = \"hardware\"\n\n id = Column(Integer, primary_key=True, autoincrement=True)\n hostname = Column(String, nullable=False)\n\n softwares = relationship(Software)\n\nBase.metadata.drop_all()\nBase.metadata.create_all()\n\nclass BaseSchema(BaseModel):\n id: int\n\n class Config:\n orm_mode = True\n\nclass SoftwareNameSchema(BaseSchema):\n name: str\n\nclass SoftwareVersionSchema(BaseSchema):\n version: str\n\nclass SoftwareSchema(BaseSchema):\n software_name: SoftwareNameSchema\n software_version: SoftwareVersionSchema\n\nclass HardwareOut(BaseSchema):\n hostname: str\n softwares: List[SoftwareSchema]\n\napp = FastAPI()\n\n@app.on_event(\"startup\")\ndef on_startup() -> None:\n session = SessionLocal()\n\n for _ in range(10):\n software_list = []\n for _ in range(3):\n sn = SoftwareName(name=fake.software_name())\n sv = SoftwareVersion(version=fake.software_version())\n s = Software(software_name=sn, software_version=sv)\n software_list.append(s)\n\n h = Hardware(hostname=fake.hardware(), softwares=software_list)\n session.add(h)\n session.flush()\n\n session.close()\n\ndef get_db() -> Iterator[Session]:\n db = SessionLocal()\n try:\n yield db\n finally:\n db.close()\n\n@app.get(\"/hardwares\", response_model=List[HardwareOut])\ndef get_hardwares(db: Session = Depends(get_db)) -> Any:\n return [HardwareOut.from_orm(hardware) for hardware in db.query(Hardware).all()]\n```\n\nHow can I change the `HardwareOut` Schema to return what I expect?\n\n========================================\n\nCode:\n```json\n[\n {\n \"id\": 1,\n \"hostname\": \"hostname2\",\n \"softwares\": [\n {\n \"id\": 1,\n \"software_name\": {\n \"id\": 1,\n \"name\": \"nginx\"\n },\n \"software_version\": {\n \"id\": 1,\n \"version\": \"2.9\"\n }\n },\n {\n \"id\": 2,\n \"software_name\": {\n \"id\": 2,\n \"name\": \"vim\"\n },\n \"software_version\": {\n \"id\": 2,\n \"version\": \"0.3\"\n }\n },\n {\n \"id\": 3,\n \"software_name\": {\n \"id\": 3,\n \"name\": \"apache\"\n },\n \"software_version\": {\n \"id\": 3,\n \"version\": \"1.0\"\n }\n }\n ]\n }\n]\n```\n\n```json\n[\n {\n \"id\": 1,\n \"hostname\": \"hostname2\",\n \"softwares\": [\n {\n \"id\": 1,\n \"name\": \"nginx\",\n \"version\": \"2.9\"\n },\n {\n \"id\": 2,\n \"name\": \"vim\",\n \"version\": \"0.3\"\n },\n {\n \"id\": 3,\n \"name\": \"apache\",\n \"version\": \"1.0\"\n }\n ]\n }\n]\n```\n\n```python\nimport uvicorn\nfrom typing import Any, Iterator, List, Optional\nfrom faker import Faker\nfrom fastapi import Depends, FastAPI\nfrom pydantic import BaseModel\nfrom sqlalchemy import Column, ForeignKey, Integer, String, create_engine\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import Session, sessionmaker, relationship\nfrom faker.providers import DynamicProvider\n\nsoftware_name = DynamicProvider(\n provider_name=\"software_name\",\n elements=[\"bash\", \"vim\", \"vscode\", \"nginx\", \"apache\"],\n)\n\n\nsoftware_version = DynamicProvider(\n provider_name=\"software_version\",\n elements=[\"1.0\", \"2.9\", \"1.1\", \"0.3\", \"2.0\"],\n)\n\n\nhardware = DynamicProvider(\n provider_name=\"hardware\",\n elements=[\"hostname1\", \"hostname2\", \"hostname3\", \"hostname4\", \"hostname5\"],\n)\n\nfake = Faker()\n\n# then add new provider to faker instance\nfake.add_provider(software_name)\nfake.add_provider(software_version)\nfake.add_provider(hardware)\n\n\nengine = create_engine(\"sqlite:///.db\", connect_args={\"check_same_thread\": False})\nSessionLocal = sessionmaker(autocommit=True, autoflush=True, bind=engine)\n\nBase = declarative_base(bind=engine)\n\n\nclass Software(Base):\n __tablename__ = 'software'\n\n id = Column(Integer, primary_key=True)\n hardware_id = Column(Integer, ForeignKey('hardware.id'))\n name_id = Column(Integer, ForeignKey('software_name.id'))\n version_id = Column(Integer, ForeignKey('software_version.id'))\n\n software_name = relationship('SoftwareName', backref='software_name')\n software_version = relationship('SoftwareVersion',\n backref='software_version')\n\n\nclass SoftwareName(Base):\n __tablename__ = 'software_name'\n\n id = Column(Integer, primary_key=True)\n name = Column(String)\n\n\nclass SoftwareVersion(Base):\n __tablename__ = 'software_version'\n\n id = Column(Integer, primary_key=True)\n version = Column(String)\n\n\nclass Hardware(Base):\n __tablename__ = \"hardware\"\n\n id = Column(Integer, primary_key=True, autoincrement=True)\n hostname = Column(String, nullable=False)\n\n softwares = relationship(Software)\n\n\nBase.metadata.drop_all()\nBase.metadata.create_all()\n\nclass BaseSchema(BaseModel):\n id: int\n\n class Config:\n orm_mode = True\n\n\nclass SoftwareNameSchema(BaseSchema):\n name: str\n\n\nclass SoftwareVersionSchema(BaseSchema):\n version: str\n\n\nclass SoftwareSchema(BaseSchema):\n software_name: SoftwareNameSchema\n software_version: SoftwareVersionSchema\n\n\nclass HardwareOut(BaseSchema):\n hostname: str\n softwares: List[SoftwareSchema]\n\n\napp = FastAPI()\n\n\n@app.on_event(\"startup\")\ndef on_startup() -> None:\n session = SessionLocal()\n\n for _ in range(10):\n software_list = []\n for _ in range(3):\n sn = SoftwareName(name=fake.software_name())\n sv = SoftwareVersion(version=fake.software_version())\n s = Software(software_name=sn, software_version=sv)\n software_list.append(s)\n\n h = Hardware(hostname=fake.hardware(), softwares=software_list)\n session.add(h)\n session.flush()\n\n session.close()\n\n\ndef get_db() -> Iterator[Session]:\n db = SessionLocal()\n try:\n yield db\n finally:\n db.close()\n\n\n@app.get(\"/hardwares\", response_model=List[HardwareOut])\ndef get_hardwares(db: Session = Depends(get_db)) -> Any:\n return [HardwareOut.from_orm(hardware) for hardware in db.query(Hardware).all()]\n```\n\n```text\nHardware\n```\n\n```text\nSoftwareName\n```\n\n```text\nSoftwareVersion\n```\n\n```text\nSoftware\n```\n\n```text\nSoftware\n```\n\n```text\none-to-many\n```\n\n```text\nSoftwareName\n```\n\n```text\nSoftwareVersion\n```\n\n```text\nHardware\n```\n\n```text\none-to-many\n```\n\n```text\nSoftware\n```\n\n```text\nPydantic Schema\n```\n\n```text\nmain.py\n```\n\n```text\nHardwareOut\n```\n\n```python\nfrom typing import Union\nfrom pydantic import validator\n\n...\n\nclass SoftwareSchema(BaseSchema):\n software_name: Union[str, SoftwareNameSchema]\n software_version: Union[str, SoftwareVersionSchema]\n\n @validator('software_name')\n def name_to_str(cls, v, values, **kwargs):\n return v.name if not isinstance(v, str) else v\n\n @validator('software_version')\n def version_to_str(cls, v, values, **kwargs):\n return v.version if not isinstance(v, str) else v\n\n...\n```\n\n```json\n[\n {\n \"id\": 1,\n \"hostname\": \"hostname2\",\n \"softwares\": [\n {\n \"id\": 1,\n \"software_name\": \"nginx\",\n \"software_version\": \"2.9\"\n },\n {\n \"id\": 2,\n \"software_name\": \"vim\",\n \"software_version\": \"0.3\"\n },\n {\n \"id\": 3,\n \"software_name\": \"apache\",\n \"software_version\": \"1.0\"\n }\n ]\n }\n]\n```\n\n```python\nfrom typing import Union\nfrom pydantic import validator\n\n...\n\nclass SoftwareSchema(BaseSchema):\n software_name: Union[str, SoftwareNameSchema] = Field(None, alias=\"name\")\n software_version: Union[str, SoftwareVersionSchema] = Field(None, alias=\"version\")\n\n @validator('software_name')\n def name_to_str(cls, v, values, **kwargs):\n return v.name if not isinstance(v, str) else v\n\n @validator('software_version')\n def version_to_str(cls, v, values, **kwargs):\n return v.version if not isinstance(v, str) else v\n\n...\n```\n\n```text\nUnion\n```\n\n```text\ntyping\n```\n\n```text\nsoftware_name\n```\n\n```text\nsoftware_version\n```\n\n```text\nvalidator\n```\n\n```text\nsoftware_name\n```\n\n```text\nname\n```\n\n```text\nsoftware_version\n```\n\n```text\nversion\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.169Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":29,"totalLines":587,"estimatedTokens":2777}}830{"id":"stack-69262116","source":"stackoverflow","questionId":69262116,"title":"Error in Angular with HTTPparams 422 (Unprocessable Entity) and FastAPI","tags":["angular","rest","fastapi","http-status-code-422","http-parameters"],"text":"Title: Error in Angular with HTTPparams 422 (Unprocessable Entity) and FastAPI\nTags: angular, rest, fastapi, http-status-code-422, http-parameters\nSource: Stack Overflow\n\nQuestion:\nI have this url in backend and need pass c1 like a parameter, c1 is only an example,\nthis method enable or disable an user and give back an \"ok\"\n\nhttp://127.0.0.1:8000/admin/enable_disable_account?name=c1\n\nthe value is taken from a button\n\n```\n\n \n \n- username -> {{userInfo[\"username\"]}}\n \n- email -> {{userInfo[\"email\"]}}\n \n- enable/disable -> {{userInfo[\"enable\"]}}\n \n Enable/Disable \n\n```\n\nThe method of the component to managment that click event\n\n```\nsetValor(username): void {\n console.log(\"click\")\n this.adminServ.updateStateUser(username)\n .subscribe(data => {\n \n console.log(data)\n },\n err => {\n console.log(\"error\")\n console.error(err)\n })\n }\n```\n\nAnd the method in the service\n\n```\npublic updateStateUser(username): Observable {\n let params = new HttpParams()\n .append('name', username) \n return this.http.post('http://127.0.0.1:8000/admin/enable_disable_account', params)\n }\n```\n\nand i have this error, what is the problem?\nhttps://i.sstatic.net/cHAWS.png\n\nI copy here the method of the backend, i dont know if it's important to find the problem,\nit's done with FastAPI\n\n```\n@router.post(\"/enable_disable_account\")\nasync def enable_disable_account(name: str, current_user: User = Security(get_current_user, scopes=[\"admin\"])): \n result = await admin_db.enable_disable_account(name)\n if result:\n return JSONResponse(status_code=status.HTTP_200_OK,\n content='ok')\n```\n\n========================================\n\nCode:\n```html\n<div *ngFor='let userInfo of users'>\n <ul class=\"list-group\">\n <li class=\"list-group-item\">username -> {{userInfo[\"username\"]}}</li>\n <li class=\"list-group-item\">email -> {{userInfo[\"email\"]}}</li>\n <li class=\"list-group-item\">enable/disable -> {{userInfo[\"enable\"]}}</li>\n </ul>\n <button class=\"btn btn-primary\" (click)=\"setValor(userInfo['username'])\">Enable/Disable</button> \n</div>\n```\n\n```js\nsetValor(username): void {\n console.log(\"click\")\n this.adminServ.updateStateUser(username)\n .subscribe(data => {\n \n console.log(data)\n },\n err => {\n console.log(\"error\")\n console.error(err)\n })\n }\n```\n\n```js\npublic updateStateUser(username): Observable<any> {\n let params = new HttpParams()\n .append('name', username) \n return this.http.post('http://127.0.0.1:8000/admin/enable_disable_account', params)\n }\n```\n\n```py\n@router.post(\"/enable_disable_account\")\nasync def enable_disable_account(name: str, current_user: User = Security(get_current_user, scopes=[\"admin\"])): \n result = await admin_db.enable_disable_account(name)\n if result:\n return JSONResponse(status_code=status.HTTP_200_OK,\n content='ok')\n```\n\n```js\nthis.http.post('http://127.0.0.1:8000/admin/enable_disable_account', params)\n```\n\n```js\nthis.http.post('http://127.0.0.1:8000/admin/enable_disable_account',null ,{\nparams: params\n})\n```\n\n```text\nAngular\n```\n\n```text\npost\n```\n\n```text\nbody\n```\n\n```text\noptions\n```\n\n```text\nquery\n```\n\n```text\nparams\n```\n\n```text\nHttpParams\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.169Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":13,"totalLines":151,"estimatedTokens":791}}831{"id":"stack-66472298","source":"stackoverflow","questionId":66472298,"title":"How can I see the domain name or ip of the PC accessing my API method?","tags":["python","python-3.x","fastapi","uvicorn"],"text":"Title: How can I see the domain name or ip of the PC accessing my API method?\nTags: python, python-3.x, fastapi, uvicorn\nSource: Stack Overflow\n\nQuestion:\nI have an API method deploy on my local server,\n\n```\n@app.post(\"/test/api\")\nasync def method():\n if incoming.request.url or domain == \"this\":\n do some operation\n else:\n skip it\n .....\n return something\n```\n\nNow, Few people are using my API method, but is there any way I could track who is calling my api method and do specific extra operations to the once I specified who is calling my api.\n\nHow can I track the incoming domain name or ip or url of the people who are using my api method?\n\nNote: Need a basic example on how to acheive it if you familiar with it\n\nIs it something possible?\n\n========================================\n\nTop Answer:\nIf you can access incoming request headers, then check if X-Forwarded-For has IP address of client. If not it is possible that changing configuration of your setup will make it works as intended, however I have not experience with neither `fastapi` or `uvicorn`, so I am unable to write anything more precise.\n\n========================================\n\nCode:\n```text\n@app.post(\"/test/api\")\nasync def method():\n if incoming.request.url or domain == \"this\":\n do some operation\n else:\n skip it\n .....\n return something\n```\n\n```text\nfrom flask import FLASK, request\n@app.route('/test/api', methods=['POST']):\ndef method():\n visitor_ip = request.remote_addr\n```\n\n```text\nremote_addr\n```\n\n```text\nrequest.client.host\n```\n\n```text\nfastapi\n```\n\n```text\nuvicorn\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.169Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":6,"totalLines":67,"estimatedTokens":398}}832{"id":"stack-62418392","source":"stackoverflow","questionId":62418392,"title":"Size of PDF breaks FastAPI using python-multipart?","tags":["pdf","multipartform-data","fastapi"],"text":"Title: Size of PDF breaks FastAPI using python-multipart?\nTags: pdf, multipartform-data, fastapi\nSource: Stack Overflow\n\nQuestion:\nI am trying to upload a **PDF to FastAPI**. After turning the PDF into a base64-blob and storing it in a txt-file, I POST this file to FastAPI using Postman.\n\nThis is my server-side code:\n\n```\nfrom fastapi import FastAPI, File, UploadFile\nimport base64\n\napp = FastAPI()\n\n@app.post(\"/uploadfile/\")\nasync def create_upload_file(file: UploadFile = File(...)):\n contents = await file.read()\n blob = base64.b64decode(contents)\n pdf = open('result.pdf','wb')\n pdf.write(blob)\n pdf.close()\n return {\"filename\": file.filename}\n```\n\nThis procedure works fine for a single-page PDF document of size 279KB (blob-size: 372KB), but it doesn't for a multi-page document of size 1.8MB (blob-size: 2.4MB).\n\nWhen I try, I get the following WARNING and a 400 bad request response (along with the reseponse \"detail\": \"There was an error parsing the body\"):\n\"Did not find boundary character 55 at index 2\"\n\nI'm sure there must be an explanation for this behavior? Maybe it has something to do with async?\n\n========================================\n\nCode:\n```text\nfrom fastapi import FastAPI, File, UploadFile\nimport base64\n\napp = FastAPI()\n\n@app.post(\"/uploadfile/\")\nasync def create_upload_file(file: UploadFile = File(...)):\n contents = await file.read()\n blob = base64.b64decode(contents)\n pdf = open('result.pdf','wb')\n pdf.write(blob)\n pdf.close()\n return {\"filename\": file.filename}\n```\n\n```text\nwith open('failed.pdf', 'wb') as outfile:\n outfile.write(blob)\n```\n\n```text\nopen()\n```\n\n```text\npdf.close()\n```\n\n```text\npdf.write()\n```\n\n```text\nwith\n```\n\n```text\nwith\n```\n\n```text\nclose()\n```\n\n```text\nwith\n```\n\n========================================\n\nComments:\n- Does this answer your question? How to Upload File using FastAPI?\n- any reason .close() would execute before .write() has finished saving all the contents? because .write() seems to be sync call. isn't it supposed to finish its job before executing the next line?","metadata":{"transformedAt":"2026-08-18T18:32:29.169Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":89,"estimatedTokens":516}}833{"id":"stack-77918536","source":"stackoverflow","questionId":77918536,"title":"FastAPI: How to generate a readable scheme from IntEnum in openapi.json with the correct keys, not digital ones?","tags":["enums","fastapi","openapi","pydantic","openapi-generator"],"text":"Title: FastAPI: How to generate a readable scheme from IntEnum in openapi.json with the correct keys, not digital ones?\nTags: enums, fastapi, openapi, pydantic, openapi-generator\nSource: Stack Overflow\n\nQuestion:\nMy IntEnum class:\n\n```\nclass Role(IntEnum):\n client = 1\n manager = 2\n admin = 3\n```\n\nWhat I got in generated openapi.json:\n\n```\n{\n enum: [1, 2, 3],\n title: \"Role\",\n type: \"integer\"\n}\n```\n\nWhat I need:\n\n```\n{\n enum: {\n client: 1,\n manager: 2,\n admin: 3\n },\n title: \"Role\",\n type: \"integer\"\n}\n```\n\nIs it possible?🙏🏼\n\n========================================\n\nTop Answer:\nYou can make use of docstring on Enum Class. Fastapi will generate json schema included automatically\n\n```\nclass Role(IntEnum):\n \"\"\"\n 1: client \n 2: manager\n 3: admin\n \"\"\"\n client = 1\n manager = 2\n admin = 3\n```\n\nThis will generate, on openapi.json\n\n```\n{\n...\n\"type\":\"object\",\n\"description\": \n\"\"\" 1: client \n 2: manager\n 3: admin\n\"\"\"\n}\n```\n\n========================================\n\nCode:\n```py\nclass Role(IntEnum):\n client = 1\n manager = 2\n admin = 3\n```\n\n```json\n{\n enum: [1, 2, 3],\n title: \"Role\",\n type: \"integer\"\n}\n```\n\n```json\n{\n enum: {\n client: 1,\n manager: 2,\n admin: 3\n },\n title: \"Role\",\n type: \"integer\"\n}\n```\n\n```text\n__get_pydantic_json_schema__\n```\n\n```py\nclass Role(IntEnum):\n \"\"\"\n 1: client \n 2: manager\n 3: admin\n \"\"\"\n client = 1\n manager = 2\n admin = 3\n```\n\n```text\n{\n...\n\"type\":\"object\",\n\"description\": \n\"\"\" 1: client \n 2: manager\n 3: admin\n\"\"\"\n}\n```\n\n========================================\n\nComments:\n- The names in an `IntEnum` are only used internally. Any reason you can't use a `StrEnum`?\n- I use this IntEnum as type for field in db and I wouldn't store roles and statuses as strings","metadata":{"transformedAt":"2026-08-18T18:32:29.169Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":6,"totalLines":134,"estimatedTokens":438}}834{"id":"stack-67232079","source":"stackoverflow","questionId":67232079,"title":"Tests in FastAPI doesn't work with relative static path file","tags":["python","json","path","pytest","fastapi"],"text":"Title: Tests in FastAPI doesn't work with relative static path file\nTags: python, json, path, pytest, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm trying to run tests in my FastAPI application and I'm using a static file that contains a JSON with colors.\nOnce I'm running the command **'pytest {path of my test file}'** I'm getting the error - No such file or directory.\n\nAt first I was running the below line in the main page of the backend side - \n\n```\napp.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")\n```\n\nThe application works fine, but the test doesn't.\n\nThe main reason is this function:\n\n```\nwith open(\"static/def_Sys/colors.json\") as f:\n li = json.load(f)\n colors = [x['color'] for x in li]\n names = [x['label'] for x in li]\nfor (x, col) in zip(names, colors):\n colors_dict[x.upper()] = col # save systems (key) and color(value) in dictionary and return it\n\nreturn colors_dict\n```\n\nAfter that, I tried to do two more actions in order to solve it -\n\nDeleted the mount line, and added this path in the function instead:\n\nwith open(\"../../../static/def_Sys/colors.json\") as f:\n\n**but the application could not run (this is the relative path from the current script)**\n\nDeleted the mount line, and changed to this line -\n\nwith open(os.path.abspath(\"static\\def_Sys\\colors.json\"),'r') as f:\n\n**The application run, but the tests can't find the path to this static file.**\n\nMoreover I noticed the tests are not using the same path like the application.\n\nFor example:\nWhen we run in pytest:\n\n\"C:\\Users\\user\\PycharmProjects\\application\\static\\def_Sys\\colors.json\"\n\nWhen we run the application:\n\n\"C:\\Users\\user\\PycharmProjects\\application\\app\\static\\def_Sys\\colors.json\"\n\nI'm trying to find a solution that will let me run the tests and my application without changing the code between each run.\n\n========================================\n\nCode:\n```text\napp.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")\n```\n\n```text\nwith open(\"static/def_Sys/colors.json\") as f:\n li = json.load(f)\n colors = [x['color'] for x in li]\n names = [x['label'] for x in li]\nfor (x, col) in zip(names, colors):\n colors_dict[x.upper()] = col # save systems (key) and color(value) in dictionary and return it\n\nreturn colors_dict\n```\n\n```py\napp.mount('/static', StaticFiles(directory=realpath(f'{realpath(__file__)}/../static')), name='static')\n```\n\n```text\ntemplates\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.169Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":81,"estimatedTokens":599}}835{"id":"stack-71540505","source":"stackoverflow","questionId":71540505,"title":"Python Script Returns 403 but returns 200 in Postman & Browser","tags":["python","python-requests","fastapi"],"text":"Title: Python Script Returns 403 but returns 200 in Postman & Browser\nTags: python, python-requests, fastapi\nSource: Stack Overflow\n\nQuestion:\nWhen I run the below code in a python script, I'm getting the error message \n\nBut when I send a get request via postman or open up the address in my browser, I'm not getting an error message and it's showing a response status of \n\nI've copied all the headers that are showing up in the network console of Google Chrome to see if perhaps the issue was tied to me not importing all the proper headers, but the issue persists even if after copying every single header.\n\n### The code that runs my API\n\n```\napp = FastAPI()\n\n@app.get(\"/test\")\ndef pass_parameters(parameters: Optional[str] = Query(None)):\n \n file_name = \"hey.txt\"\n with open(file_name, 'w') as f:\n api_token = \"shdsajkhdjkasjdkasjh3242341jh\" \n parameters= {\"phrase\": parameters}\n print(parameters)\n response = requests.get(f\"https://api.state.taxes\", headers={ \"Accept\": \"application/json\", \"Authorization\": f\"Bearer {api_token}\"}, params=parameters)\n \n f.write(json.dumps(response.json(), indent=4))\n response = response.json()\n \n\n \n return JSONResponse(content=response, media_type=\"text/json\")\n \nif __name__ == '__main__':\n uvicorn.run(app, port=8080, host='127.0.0.1')\n```\n\n### **The code to get stuff from my API**\n\n```\nimport requests\n\nurl = \"http://127.0.0.1:8080/test\"\n\nheaders = {\n \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\",\n \"Accept-Encoding\": \"gzip, deflate, br\",\n \"Accept-Language\": \"en-US,en;q=0.9\",\n \"Connection\": \"keep-alive\",\n \"Cookie\": \"AMCV_1B3AA45570643167F000101%40AdobeOrg=-%7CMCIDTS%7C18944%7CMCMID%%7CMCOPTOUT-1636735667s%7CNONE%7CvVersion%7C5.1.1\",\n \"Host\": \"127.0.0.1:8080\",\n \"If-Modified-Since\": \"Sat, 19 Mar 2022 15:13:13 GMT\",\n \"If-None-Match\": \"e6ead9f56bc933ab83465\",\n \"sec-ch-ua-mobile\": \"?0\",\n \"sec-ch-ua-platform\": \"Windows\",\n \"Sec-Fetch-Dest\": \"document\",\n \"Sec-Fetch-Mode\": \"navigate\",\n \"Sec-Fetch-Site\": \"none\",\n \"Sec-Fetch-User\": \"?1\",\n \"Upgrade-Insecure-Requests\": \"1\",\n \"User-Agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.74 Safari/537.36\"\n}\n\nresponse = requests.get(url, headers=headers)\n\nprint(response) --> returns \n```\n\nBut when I open my browser, the webpage opens up fine with a 200 response in the network console of the developer tools as well as within Postman. I exported the Postman call to Python and getting the same error. I saw several Stackoverflow posts were they were able to fix the issue by applying the correct header and disabling proxy in Postman, I've done both and issue persists. I'm not sure if perhaps there's a header that I'm missing?\n\n========================================\n\nCode:\n```text\napp = FastAPI()\n\n@app.get(\"/test\")\ndef pass_parameters(parameters: Optional[str] = Query(None)):\n \n file_name = \"hey.txt\"\n with open(file_name, 'w') as f:\n api_token = \"shdsajkhdjkasjdkasjh3242341jh\" \n parameters= {\"phrase\": parameters}\n print(parameters)\n response = requests.get(f\"https://api.state.taxes\", headers={ \"Accept\": \"application/json\", \"Authorization\": f\"Bearer {api_token}\"}, params=parameters)\n \n f.write(json.dumps(response.json(), indent=4))\n response = response.json()\n \n\n \n return JSONResponse(content=response, media_type=\"text/json\")\n \nif __name__ == '__main__':\n uvicorn.run(app, port=8080, host='127.0.0.1')\n```\n\n```text\nimport requests\n\nurl = \"http://127.0.0.1:8080/test\"\n\nheaders = {\n \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\",\n \"Accept-Encoding\": \"gzip, deflate, br\",\n \"Accept-Language\": \"en-US,en;q=0.9\",\n \"Connection\": \"keep-alive\",\n \"Cookie\": \"AMCV_1B3AA45570643167F000101%40AdobeOrg=-%7CMCIDTS%7C18944%7CMCMID%%7CMCOPTOUT-1636735667s%7CNONE%7CvVersion%7C5.1.1\",\n \"Host\": \"127.0.0.1:8080\",\n \"If-Modified-Since\": \"Sat, 19 Mar 2022 15:13:13 GMT\",\n \"If-None-Match\": \"e6ead9f56bc933ab83465\",\n \"sec-ch-ua-mobile\": \"?0\",\n \"sec-ch-ua-platform\": \"Windows\",\n \"Sec-Fetch-Dest\": \"document\",\n \"Sec-Fetch-Mode\": \"navigate\",\n \"Sec-Fetch-Site\": \"none\",\n \"Sec-Fetch-User\": \"?1\",\n \"Upgrade-Insecure-Requests\": \"1\",\n \"User-Agent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.74 Safari/537.36\"\n}\n\nresponse = requests.get(url, headers=headers)\n\nprint(response) --> returns <Response [403]>\n```\n\n========================================\n\nComments:\n- What do you see if you print `response.content` and `response.text`?\n- Have you looked at stackoverflow.com/a/8287752/8593689? This answer provides details how to use requests with a proxy.\n- Thank you so much for sharing that with me! I'll take a look at that now!\n- @ShaneBishop So I copied all the proxy settings from my local computer and passed it in through my API call but I'm still getting the same error. I'm confused as to why it works in my browser and in Postman, but not in visual studio code. It's working in Powershell as well. Is it because the requests package in python functions differently? I'm looking at Postman and there isn't any cookies generated. In the browser however, there's cookies that are generated and I copied/pasted those into my headers. Issue persists.","metadata":{"transformedAt":"2026-08-18T18:32:29.169Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":2,"totalLines":133,"estimatedTokens":1369}}836{"id":"stack-75687525","source":"stackoverflow","questionId":75687525,"title":"Google OAuth2.0 - Unintended redirecting to http","tags":["oauth-2.0","google-oauth","fastapi","google-api-python-client"],"text":"Title: Google OAuth2.0 - Unintended redirecting to http\nTags: oauth-2.0, google-oauth, fastapi, google-api-python-client\nSource: Stack Overflow\n\nQuestion:\nI'm trying to setup a Google OAuth for my FARM stack app.\n\nMy problem is:\nMy flow and code is working when I'm running the app in my local.\nBut It's not working in production. (Because Google doesn't allow me to enter a redirect url in \"http\" scheme if my OAuth app is set to Production mode.)\nI have all the requirements satisfied, e.g ClientID, Redirect URI's.\n\nHere's the steps I :\n\n1- Created ClientId for Web Application.\n2- Added the required redirect URIs.\n3- In FastAPI I have this code:\n\n```\n# config[\"CLIENT_URL\"] equals to my React App's url.\n@router.get('/google_cb') # 1\nasync def login(request: Request):\n redirect_uri = request.url_for('google')\n return await oauth.google.authorize_redirect(request, redirect_uri)\n\n@router.get(\"/google\", name=\"google\") # 2\nasync def google_oauth(request: Request):\n try:\n access_token = await oauth.google.authorize_access_token(request)\n user = user_service.find_one(\n {\"email\": access_token['userinfo']['email'], \"authentication_method\": AuthenticationMethod.GOOGLE})\n if user:\n access_token_expires = timedelta(minutes=config[\"Auth\"][\"token_expiry\"])\n access_token = create_access_token(\n data={\"sub\": user.id, \"scopes\": []},\n expires_delta=access_token_expires,\n )\n return RedirectResponse(url=f'{config[\"CLIENT_URL\"]}/oauthcb/' + access_token)\n invite = invites_repository.find_one({\"email\": access_token['userinfo']['email'], \"status\": \"Pending\"})\n if not invite:\n raise HTTPException(status_code=404, detail=\"Invite not found\")\n created_user = user_service.create_user(\n {\"email\": invite[\"email\"], \"hashed_password\": \"google_auth\",\n \"tenant_id\": invite[\"tenant_id\"], \"disabled\": False, \"first_name\": access_token['userinfo']['given_name'],\n \"last_name\": access_token['userinfo']['family_name'], \"is_admin\": False, \"fireflies_id\": None,\n \"authentication_method\": \"Google\", \"external_auth_data\": access_token})\n access_token_expires = timedelta(minutes=config[\"Auth\"][\"token_expiry\"])\n access_token = create_access_token(\n data={\"sub\": str(created_user.inserted_id), \"scopes\": []},\n expires_delta=access_token_expires,\n )\n invites_repository.delete({\"_id\": invite[\"_id\"]})\n return RedirectResponse(url=f'{config[\"CLIENT_URL\"]}/oauthcb/' + access_token)\n except OAuthError as e:\n print(e)\n return RedirectResponse(url=f'{config[\"CLIENT_URL\"]}')\n```\n\n4- In React I have this code:\n\n```\nprocess.env.REACT_APP_API_URL is set to https://my.api.url\n```\n\n```\n}\n onClick={() => {\n window.location.replace(\n `${process.env.REACT_APP_API_URL}/oauth/google_cb`\n );\n }}\n >\n Login with Google\n \n```\n\n5- Flow: User presses Login With Google button in React App, user hits the **https**://my.api.url/google_cb endpoint in the backend. The backend redirects the user to the page that google provides to enter their email and password. After they log in, google should redirect the user to **https://my.api.url**/google endpoint and I do my process here.\n\nProblem is: Although I'm redirecting the user from React to the **https:**//my.api.endpoint/google_cb\nI'm getting an error \"redirect_url_mismatch\", and in the error it says \"redirect_url=**http:**//my.api.endpoint/google_cb\"\nAnd this causes my problem. I'm sure about this because I swithced the mode for my OAuth App from Google Console to \"Test\" from \"Production\" and It worked.\n\nIn production mode Google doesn't allow me to enter http url. They just allow me to enter https.\n\nBut I'm pretty pretty sure that I'm redirecting the user to https instead of http.\n\nI wonder if anyone faced with the same issue before.\n\n========================================\n\nCode:\n```text\n# config[\"CLIENT_URL\"] equals to my React App's url.\n@router.get('/google_cb') # 1\nasync def login(request: Request):\n redirect_uri = request.url_for('google')\n return await oauth.google.authorize_redirect(request, redirect_uri)\n\n\n@router.get(\"/google\", name=\"google\") # 2\nasync def google_oauth(request: Request):\n try:\n access_token = await oauth.google.authorize_access_token(request)\n user = user_service.find_one(\n {\"email\": access_token['userinfo']['email'], \"authentication_method\": AuthenticationMethod.GOOGLE})\n if user:\n access_token_expires = timedelta(minutes=config[\"Auth\"][\"token_expiry\"])\n access_token = create_access_token(\n data={\"sub\": user.id, \"scopes\": []},\n expires_delta=access_token_expires,\n )\n return RedirectResponse(url=f'{config[\"CLIENT_URL\"]}/oauthcb/' + access_token)\n invite = invites_repository.find_one({\"email\": access_token['userinfo']['email'], \"status\": \"Pending\"})\n if not invite:\n raise HTTPException(status_code=404, detail=\"Invite not found\")\n created_user = user_service.create_user(\n {\"email\": invite[\"email\"], \"hashed_password\": \"google_auth\",\n \"tenant_id\": invite[\"tenant_id\"], \"disabled\": False, \"first_name\": access_token['userinfo']['given_name'],\n \"last_name\": access_token['userinfo']['family_name'], \"is_admin\": False, \"fireflies_id\": None,\n \"authentication_method\": \"Google\", \"external_auth_data\": access_token})\n access_token_expires = timedelta(minutes=config[\"Auth\"][\"token_expiry\"])\n access_token = create_access_token(\n data={\"sub\": str(created_user.inserted_id), \"scopes\": []},\n expires_delta=access_token_expires,\n )\n invites_repository.delete({\"_id\": invite[\"_id\"]})\n return RedirectResponse(url=f'{config[\"CLIENT_URL\"]}/oauthcb/' + access_token)\n except OAuthError as e:\n print(e)\n return RedirectResponse(url=f'{config[\"CLIENT_URL\"]}')\n```\n\n```text\nprocess.env.REACT_APP_API_URL is set to https://my.api.url\n```\n\n```text\n<Button\n icon={<GoogleOutlined />}\n onClick={() => {\n window.location.replace(\n `${process.env.REACT_APP_API_URL}/oauth/google_cb`\n );\n }}\n >\n Login with Google\n </Button>\n```\n\n```text\nasync def login(request: Request):\n redirect_uri = request.url_for('google')\n if request.base_url.hostname == 'localhost': \n# I consider about localhost for testing purposes, you may not have this.\n redirect_uri = redirect_uri.replace('https', 'http')\n else:\n redirect_uri = redirect_uri.replace('http', 'https')\n return await oauth.google.authorize_redirect(request, redirect_uri)\n```","metadata":{"transformedAt":"2026-08-18T18:32:29.169Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":159,"estimatedTokens":1644}}837{"id":"stack-77869420","source":"stackoverflow","questionId":77869420,"title":"How to connect FastAPI, Jinja2 and Keycloak?","tags":["python","jinja2","keycloak","fastapi"],"text":"Title: How to connect FastAPI, Jinja2 and Keycloak?\nTags: python, jinja2, keycloak, fastapi\nSource: Stack Overflow\n\nQuestion:\nI work for a company and I have a Python FastAPI project. This is something like a multi-page website, where each endpoint is a page of the site. This was done using Jinja2 - TemplateResponse(). I know that this is not the best solution for similar projects, such as Flask or Django, but there is no way to change it.\n\nI need to hide content using Keycloak authentication. I took the solution here: https://stackoverflow.com/a/77186511/21439459\n\nMade same endpoint:\n\n```\n@app.get(\"/secure\")\nasync def root(user: User = Depends(get_user_info)):\n return {\"message\": f\"Hello {user.username} you have the following service: {user.realm_roles}\"}\n```\n\nWhen I run the page I get (Not authenticated):\n\nI don't understand how a user can authenticate. I expected a redirect to the Keycloak page like in other frameworks.\nInteresting point when running /docs\n\nHere, after entering the data, a correct redirect to Keycloak occurs and after entering the login/password, I can receive a response from the secure endpoint.\n\nI need help with a redirect when opening my website. I don't understand how to repeat authentication from the documentation.\n\nI tried the fastapi_keycloak library, but as I understand it, it does not work with the company's version of keycloak.\n\nI tried fastapi-keycloak-middleware, but I also received a 401 error and did not understand how to authenticate users.\n\n========================================\n\nCode:\n```text\n@app.get(\"/secure\")\nasync def root(user: User = Depends(get_user_info)):\n return {\"message\": f\"Hello {user.username} you have the following service: {user.realm_roles}\"}\n```\n\n```text\nimport jwt\nimport time\nimport json\nimport uvicorn\nimport requests\nfrom fastapi import FastAPI, Request\nfrom fastapi.responses import RedirectResponse\nfrom fastapi.middleware.cors import CORSMiddleware\nfrom fastapi.templating import Jinja2Templates\nfrom fastapi.security.utils import get_authorization_scheme_param\n\n\nAUTH_URL = \"... KeyCloak Auth URL...\" # with \"...&redirect_uri=http://127.0.0.1:8080/auth\"\nTOKEN_URL = \"...KeyCloak Token URL...\"\n\ntemplates = Jinja2Templates(directory=\"templates\") # paste your directory\n\napp = FastAPI()\n\napp.add_middleware(\n CORSMiddleware,\n allow_credentials=True,\n allow_methods=[\"*\"],\n allow_headers=[\"*\"]\n)\n\n\n@app.get(\"/secure_method\")\ndef func(request: Request):\n authorization: str = request.cookies.get(\"Authorization\")\n if not authorization:\n # You can add \"&state=secure_method\" to AUTH_URL for correct redirection after authentication\n return RedirectResponse(url=AUTH_URL)\n scheme, credentials = get_authorization_scheme_param(authorization)\n try:\n decoded = jwt.decode(jwt=credentials, options={'verify_signature': False}) \n except Exception as e\n return 0 # I send special error template\n # check expiration time\n if decoded['exp'] + 3600*24 < datetime.utcnow().timestamp():\n return RedirectResponse(url=AUTH_URL)\n\n # generate data or make something\n \n return templates.TemplateResponse('secure.html', {\"request\": request})\n \n\napp.get(\"/auth\")\ndef auth(code: str, state: str = \"\") -> RedirectResponse:\n payload = {\n 'grant_type': 'authorization_code',\n 'client_id': '...some client ID...',\n 'code': code,\n 'redirect_uri': 'http://127.0.0.1:8080/auth'\n }\n headers = {\"Content-Type\": \"application/x-www-form-urlencoded\"}\n token_response = requests.request(\"POST\", TOKEN_URL, data=payload, headers=headers)\n token_body = json.loads(token_response.content)\n access_token = token_body.get(\"access_token\")\n if not access_token:\n return {\"ERROR\": \"access_token\"}\n response = RedirectResponse(url=\"/\" + state)\n response.set_cookie(\"Authorization\", value=f\"Bearer {access_token}\")\n return response\n\n\nif __name__ == \"__main__\":\n uvicorn.run(app, host=\"127.0.0.1\", port=8080)\n```\n\n========================================\n\nComments:\n- In your `get_user_info` function - if there isn't a user available, you can issue a redirect to keycloak as you find necessary (call `RedirectResponse(url='https://keycloakinstance/path'`)\n- @MatsLindh I think I need something from python-keycloak library ( pypi.org/project/python-keycloak ) like keycloak_openid.auth_url() but I don't understand how to add it to project","metadata":{"transformedAt":"2026-08-18T18:32:29.169Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":2,"totalLines":115,"estimatedTokens":1113}}838{"id":"stack-75811288","source":"stackoverflow","questionId":75811288,"title":"CORS error with Nextjs application using API gateway, only on client side","tags":["javascript","next.js","axios","cors","fastapi"],"text":"Title: CORS error with Nextjs application using API gateway, only on client side\nTags: javascript, next.js, axios, cors, fastapi\nSource: Stack Overflow\n\nQuestion:\nI'm not sure how to describe the problem to its fullest, I'm already a week in playing with this and can't get it to work...\n\nI have a FastAPI server running as Lambda connected to API Gateway\n\nhttps://i.sstatic.net/S5Zx9.png\n\nCORS is enabled in both FastAPI and API Gateway.\n\nI have NextJS running on Amplify, the requests that NextJS is performing are working, but the requests on my client side do not and have a CORS error.\n\nmy API is `api.example.com/api` while App is `example.com`\n\n**What Iv'e tried:**\n\n- Adding the following headers to each request `\"Access-Control-Allow-Origin\": '*', \"Access-Control-Allow-Headers\": \"X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version\", \"Access-Control-Allow-Methods\": 'GET, POST, PUT, DELETE, OPTIONS'`\n\n- Adding re-writes to make sort of a proxy\n\n- Using CORS chrome extension, still does not work\n\n**Signup route which is done by next and not the client works**\n\nhttps://i.sstatic.net/dErCf.png\n\n**yet request done by client**\n\nhttps://i.sstatic.net/aqkav.png\n\nI've prob tried many more things in between, I'm just clueless\n\nThis is my code for creating Axios Instance (Removed the headers but it did not work with them also)\n\n```\nimport axios from 'axios';\n\nexport const api = (session: any): any => {\n const headers: { [key: string]: string | number } = {\n \"Accept\": 'application/json',\n }\n\n if (session?.user) {\n headers.Authorization = session.user.token;\n }\n\n const api = axios.create({\n baseURL: process.env.NEXT_PUBLIC_API_DOMAIN,\n withCredentials: true,\n headers\n });\n\n return api;\n};\n```\n\nAny help is very very much appreciated\n\n***EDIT:***\n\n**ERROR itself**\n\nhttps://i.sstatic.net/zZ394.png\n\nThe lambda does not seems to even get the requests that done by my client, only the ones from Nextjs backend.\n\nIt makes me think it's the API Gateway configuration or my client request headers configuration.\n\nAlso tried:\n\n- Adding `Access-Control-Allow-Credentials` header as true, on client, and API gateway.\n\n- Added for my FastAPI CORS middleware-specific **set of origins** with my `https://example.com`\n\n========================================\n\nCode:\n```text\nimport axios from 'axios';\n\n\nexport const api = (session: any): any => {\n const headers: { [key: string]: string | number } = {\n \"Accept\": 'application/json',\n }\n\n if (session?.user) {\n headers.Authorization = session.user.token;\n }\n\n const api = axios.create({\n baseURL: process.env.NEXT_PUBLIC_API_DOMAIN,\n withCredentials: true,\n headers\n });\n\n\n return api;\n};\n```\n\n```text\napi.example.com/api\n```\n\n```text\nexample.com\n```\n\n```text\n\"Access-Control-Allow-Origin\": '*', \"Access-Control-Allow-Headers\": \"X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version\", \"Access-Control-Allow-Methods\": 'GET, POST, PUT, DELETE, OPTIONS'\n```\n\n```text\nAccess-Control-Allow-Credentials\n```\n\n```text\nhttps://example.com\n```\n\n```text\ntype Mock\n```\n\n========================================\n\nComments:\n- Also tried to delete cache, remove cache in dev tools etc...\n- Does this answer your question? FastAPI is not returning cookies to React frontend\n- No, I tried to set up credentials as true and allow specific origins, both in the API gateway and in my FastAPI code..\n- @Chris I've added more information :D thanks!\n- Before a POST a browser wil do an OPTION request (preflight request). Check if the CORS headers are included for OPTION requests with a tool like postman\n- None of this is related to the client-side (and you definitely should not add any `Access-Control-*` headers to your requests). The error is literally telling you what the problem is; the response to the preflight request does not have `Access-Control-Allow-Credentials: true`\n- @Phil I do have it set up in API gateway, is there a special setup also in FastAPI that should be done? in the FastAPI console I don't see any response to the preflight request hence I think it get stopped in API gateway, and there in the settings I enabled CORS with credetials: true for my {proxy+} resource\n- @n9iels can you point out what exact headers to verify, I do see CORS headers given in the response.\n- methods to debug: try making the same request by postman via copying curl and importing it in postman see if you are able to make that request, if yes then please your cors policy at server like allowed headers, origin, methods, credentials. check if you have option method added to your allowed methods.\n- @DanishHasan here are the headers - prnt.sc/Ct5-N5Oojf1- it seems the API Gateway does return the CORS\n- Also seem like options should return the Credentials header as configured in API Gateway prnt.sc/N9JsadV3O0UA I'm confused why it does not work.","metadata":{"transformedAt":"2026-08-18T18:32:29.169Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":7,"totalLines":142,"estimatedTokens":1244}}839{"id":"stack-66570680","source":"stackoverflow","questionId":66570680,"title":"How to authenticate static routes in FastAPI","tags":["fastapi","starlette"],"text":"Title: How to authenticate static routes in FastAPI\nTags: fastapi, starlette\nSource: Stack Overflow\n\nQuestion:\nI am statically serving a folder via FastAPI following the documentation:\n\n```\nfrom fastapi import FastAPI\nfrom fastapi.staticfiles import StaticFiles\n\napp = FastAPI()\n\napp.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")\n```\n\nHow can I add basic authentication (user, password) to this route `/static`?\n\n========================================\n\nTop Answer:\nIm not sure you can add basic authentication to the route itself I add it directly to the endpoint. But here's a link with the best auth modules for fastapi. Hope it helps. I like FastAPI Login.\n\nFastAPI Auth\n\n========================================\n\nCode:\n```py\nfrom fastapi import FastAPI\nfrom fastapi.staticfiles import StaticFiles\n\napp = FastAPI()\n\napp.mount(\"/static\", StaticFiles(directory=\"static\"), name=\"static\")\n```\n\n```text\n/static\n```\n\n```py\nimport secrets\n\nfrom fastapi import Depends, FastAPI, HTTPException, status\nfrom fastapi.security import HTTPBasic, HTTPBasicCredentials\n\napp = FastAPI()\n\nsecurity = HTTPBasic()\n\n\ndef get_current_username(credentials: HTTPBasicCredentials = Depends(security)):\n correct_username = secrets.compare_digest(credentials.username, \"stanleyjobson\")\n correct_password = secrets.compare_digest(credentials.password, \"swordfish\")\n if not (correct_username and correct_password):\n raise HTTPException(\n status_code=status.HTTP_401_UNAUTHORIZED,\n detail=\"Incorrect email or password\",\n headers={\"WWW-Authenticate\": \"Basic\"},\n )\n return credentials.username\n\n\n@app.get(\"/users/me\")\ndef read_current_user(username: str = Depends(get_current_username)):\n return {\"username\": username}\n```\n\n========================================\n\nComments:\n- The part I still had to figure out is how to serve my static files without using the `StaticFiles` class. I ended up using the Template functionality provided by fastapi to serve a website: fastapi.tiangolo.com/advanced/templates\n- This doesn't answer the OPs question\n- This doesn't provide a solution to the question. Here there is a workaround github.com/tiangolo/fastapi/issues/858#issuecomment-87656402‌​0","metadata":{"transformedAt":"2026-08-18T18:32:29.169Z","totalAnswersIncluded":1,"totalCodeBlocksIncluded":3,"totalLines":75,"estimatedTokens":564}}840{"id":"stack-78839103","source":"stackoverflow","questionId":78839103,"title":"How to return plain text or JSON depending on condition?","tags":["python","fastapi"],"text":"Title: How to return plain text or JSON depending on condition?\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nIs there a way to do something like this using FastAPI:\n\n```\n@app.post(\"/instance/new\", tags=[\"instance\"])\nasync def MyFunction(condition):\n if condition:\n response = {\"key\": \"value\"}\n return response\n else:\n return some_big_plain_text\n```\n\nThe way it is coded now, the JSON is returned fine, but `some_big_plain_text` is not human friendly. If I do: `@app.post(\"/instance/new\", tags=[\"instance\"], PlainTextResponse)` I get an error when returning a JSON response.\n\n========================================\n\nCode:\n```py\n@app.post(\"/instance/new\", tags=[\"instance\"])\nasync def MyFunction(condition):\n if condition:\n response = {\"key\": \"value\"}\n return response\n else:\n return some_big_plain_text\n```\n\n```text\nsome_big_plain_text\n```\n\n```text\n@app.post(\"/instance/new\", tags=[\"instance\"], PlainTextResponse)\n```\n\n```text\nfrom fastapi import FastAPI, Response\n\n@app.post(\"/instance/new\", tags=[\"instance\"])\nasync def MyFunction(condition):\n if condition:\n response = {\"key\": \"value\"}\n return response\n else:\n return Response(content=some_big_plain_text, media_type=\"text/plain\")\n```\n\n```text\nFastAPI\n```\n\n```text\nResponse\n```\n\n========================================\n\nComments:\n- why not wrap the plain text into a json? `{\"response\" : some_big_plein_text}`\n- Have a look at this answer (along with this), in order to better understand what takes place behind the scenes, when returning a response from a FastAPI endpoint, as well as how to return a custom `Response` directly.","metadata":{"transformedAt":"2026-08-18T18:32:29.169Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":6,"totalLines":65,"estimatedTokens":413}}841{"id":"stack-61112808","source":"stackoverflow","questionId":61112808,"title":"Correct nginx.conf loadbalancing to uvicorn FastAPI with docker-compose","tags":["nginx","docker-compose","load-balancing","reverse-proxy","fastapi"],"text":"Title: Correct nginx.conf loadbalancing to uvicorn FastAPI with docker-compose\nTags: nginx, docker-compose, load-balancing, reverse-proxy, fastapi\nSource: Stack Overflow\n\nQuestion:\nI want to use nginx as load balancer to my FastAPI replicas but i cannot get it to work. I read that uvicorn can also do it, but nginx would handle load balancing nicely. forum post.\n\nI get an error\n\n```\nhost not found in upstream \"inconnect1:5001\"\n```\n\ndocker-compose.yml\n\n```\nversion: \"3\"\n\nnetworks:\n proxy-tier:\n external:\n name: nginx-proxy\n\nservices:\n\n inconnect1: \n image: inconnect:0.1\n container_name: inconnect1\n environment:\n - PORT=5001\n volumes:\n - ./inconnect/app:/app\n ports:\n - 5001:5001\n\n nginx: \n image: jwilder/nginx-proxy\n container_name: nginx\n ports:\n - 80:80\n - 443:443\n volumes:\n - /var/run/docker.sock:/tmp/docker.sock:ro\n - ./letsencrypt/certs:/etc/nginx/certs:ro\n - ./nginx/nginx.conf:/etc/nginx/nginx.conf\n networks:\n - proxy-tier\n restart: always\n deploy:\n mode: replicated\n replicas: 1\n```\n\nnginx.conf\n\n```\nworker_processes 1;\n\nevents { worker_connections 1024; }\n\nhttp {\n\nsendfile on;\n\nupstream restapis {\nserver inconnect:5001;\n}\n\nserver {\nlisten 80;\n\nlocation / {\n proxy_set_header Host $http_host;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header X-Forwarded-Proto $scheme;\n proxy_redirect off;\n proxy_buffering off;\n proxy_pass http://restapis;\n}\n\nlocation /static {\n # path for static files\n root /path/to/app/static;\n}\n}\n }\n```\n\n========================================\n\nCode:\n```text\nhost not found in upstream \"inconnect1:5001\"\n```\n\n```text\nversion: \"3\"\n\nnetworks:\n proxy-tier:\n external:\n name: nginx-proxy\n\nservices:\n\n inconnect1: \n image: inconnect:0.1\n container_name: inconnect1\n environment:\n - PORT=5001\n volumes:\n - ./inconnect/app:/app\n ports:\n - 5001:5001\n\n nginx: \n image: jwilder/nginx-proxy\n container_name: nginx\n ports:\n - 80:80\n - 443:443\n volumes:\n - /var/run/docker.sock:/tmp/docker.sock:ro\n - ./letsencrypt/certs:/etc/nginx/certs:ro\n - ./nginx/nginx.conf:/etc/nginx/nginx.conf\n networks:\n - proxy-tier\n restart: always\n deploy:\n mode: replicated\n replicas: 1\n```\n\n```text\nworker_processes 1;\n\nevents { worker_connections 1024; }\n\nhttp {\n\nsendfile on;\n\nupstream restapis {\nserver inconnect:5001;\n}\n\nserver {\nlisten 80;\n\nlocation / {\n proxy_set_header Host $http_host;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header X-Forwarded-Proto $scheme;\n proxy_redirect off;\n proxy_buffering off;\n proxy_pass http://restapis;\n}\n\nlocation /static {\n # path for static files\n root /path/to/app/static;\n}\n}\n }\n```\n\n```text\nimage: jwilder/nginx-proxy\n container_name: nginx\n ports:\n - 80:80\n - 443:443\n volumes:\n - /var/run/docker.sock:/tmp/docker.sock:ro\n - ./letsencrypt/certs:/etc/nginx/certs:ro\n - ./nginx/nginx.conf:/etc/nginx/nginx.conf\n links:\n - \"inconnect1:inconnect1\"\n restart: always\n deploy:\n mode: replicated\n replicas: 1\n```\n\n```text\nnetworks:\n proxy-tier:\n driver: bridge\n\nservices:\n\n inconnect1: \n image: inconnect:0.1\n container_name: inconnect1\n environment:\n - PORT=5001\n volumes:\n - ./inconnect/app:/app\n ports:\n - 5001:5001\n networks:\n - proxy-tier\n\n nginx: \n image: jwilder/nginx-proxy\n container_name: nginx\n ports:\n - 80:80\n - 443:443\n volumes:\n - /var/run/docker.sock:/tmp/docker.sock:ro\n - ./letsencrypt/certs:/etc/nginx/certs:ro\n - ./nginx/nginx.conf:/etc/nginx/nginx.conf\n networks:\n - proxy-tier\n restart: always\n deploy:\n mode: replicated\n replicas: 1\n```\n\n```text\nserver inconnect:5001;\n```\n\n```text\nserver inconnect1:5001;\n```\n\n```text\nlink\n```\n\n```text\ninconnect1\n```\n\n========================================\n\nComments:\n- thanks. however, the nginx.conf does not work for SSL yet, can it be modified?","metadata":{"transformedAt":"2026-08-18T18:32:29.170Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":241,"estimatedTokens":998}}842{"id":"stack-75055890","source":"stackoverflow","questionId":75055890,"title":"FastAPI - Cannot use `Response` as a return type when `status_code` is set to 204","tags":["python","fastapi"],"text":"Title: FastAPI - Cannot use `Response` as a return type when `status_code` is set to 204\nTags: python, fastapi\nSource: Stack Overflow\n\nQuestion:\nI've been using the following code for my `/healthz`:\n\n```\n@router.get(\"/healthz\", status_code=status.HTTP_204_NO_CONTENT, tags=[\"healthz\"],\n summary=\"Service for 'Health Check'\",\n description=\"This entrypoint is used to check if the service is alive or dead.\",\n # include_in_schema=False\n )\ndef get_healthz() -> Response:\n return Response(status_code=status.HTTP_204_NO_CONTENT)\n```\n\nThis has been working since some years ago.\n\nToday I updated FastAPI from 0.88.0 to 0.89.0 and now I get `AssertionError: Status code 204 must not have a response body`. The full tracebakc can be seen below:\n\n```\nTraceback (most recent call last):\n File \"\", line 1234, in _handle_fromlist\n File \"\", line 241, in _call_with_frames_removed\n File \"......../src/routers/healthz.py\", line 20, in \n @router.get(\"/healthz\", status_code=status.HTTP_204_NO_CONTENT, tags=[\"healthz\"],\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/Users/..../.local//virtualenvs/........../lib/python3.11/site-packages/fastapi/routing.py\", line 633, in decorator\n self.add_api_route(\n File \"/Users/..../.local//virtualenvs/......../lib/python3.11/site-packages/fastapi/routing.py\", line 572, in add_api_route\n route = route_class(\n ^^^^^^^^^^^^\n File \"/Users/...../.local//virtualenvs/....../lib/python3.11/site-packages/fastapi/routing.py\", line 396, in __init__\n assert is_body_allowed_for_status_code(\nAssertionError: Status code 204 must not have a response body\npython-BaseException\n```\n\nHere:\nhttps://i.sstatic.net/UFgSE.png\n\nMy question is:\n\nIs this a bug from the version 0.89.0 , or should I write the `/heathz` In a different way?\n\nEven with `return Response(status_code=status.HTTP_204_NO_CONTENT, content=None)` is failling.\n\nChangelog of 0.89.0:\nhttps://i.sstatic.net/DripA.png\n\nThanks\n\n========================================\n\nCode:\n```py\n@router.get(\"/healthz\", status_code=status.HTTP_204_NO_CONTENT, tags=[\"healthz\"],\n summary=\"Service for 'Health Check'\",\n description=\"This entrypoint is used to check if the service is alive or dead.\",\n # include_in_schema=False\n )\ndef get_healthz() -> Response:\n return Response(status_code=status.HTTP_204_NO_CONTENT)\n```\n\n```text\nTraceback (most recent call last):\n File \"<frozen importlib._bootstrap>\", line 1234, in _handle_fromlist\n File \"<frozen importlib._bootstrap>\", line 241, in _call_with_frames_removed\n File \"......../src/routers/healthz.py\", line 20, in <module>\n @router.get(\"/healthz\", status_code=status.HTTP_204_NO_CONTENT, tags=[\"healthz\"],\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"/Users/..../.local/share/virtualenvs/........../lib/python3.11/site-packages/fastapi/routing.py\", line 633, in decorator\n self.add_api_route(\n File \"/Users/..../.local/share/virtualenvs/......../lib/python3.11/site-packages/fastapi/routing.py\", line 572, in add_api_route\n route = route_class(\n ^^^^^^^^^^^^\n File \"/Users/...../.local/share/virtualenvs/....../lib/python3.11/site-packages/fastapi/routing.py\", line 396, in __init__\n assert is_body_allowed_for_status_code(\nAssertionError: Status code 204 must not have a response body\npython-BaseException\n```\n\n```text\n/healthz\n```\n\n```text\nAssertionError: Status code 204 must not have a response body\n```\n\n```text\n/heathz\n```\n\n```text\nreturn Response(status_code=status.HTTP_204_NO_CONTENT, content=None)\n```\n\n========================================\n\nComments:\n- I think that you are not following the instructions. The FastAPI constructs the response automatically, the user is not supposed to do it explicitly. In your particular case FastAPI treats the Response you return as an object, and adds this object into automatically constructed response body. :)\n- I just saw this fix opened 1h after my question, I'll wait to the merge and test again: github.com/tiangolo/fastapi/pull/5860 . If the problem won't be fixed, then I'll put here more details about my implementation. FYI: @Chris alv2017","metadata":{"transformedAt":"2026-08-18T18:32:29.170Z","totalAnswersIncluded":0,"totalCodeBlocksIncluded":6,"totalLines":105,"estimatedTokens":1046}}843 