Reputation: 549
I have a python service that uses fastapi as a web interface. I need to make an executable file and hence I am using PyInstaller.
I keep getting the following error:
File "..../miniconda3/lib/python3.7/site-packages/PyInstaller/lib/modulegraph/modulegraph.py", line 2912, in _load_package
self._load_module(fqname, fp, buf, stuff)
File "..../miniconda3/lib/python3.7/site-packages/PyInstaller/lib/modulegraph/modulegraph.py", line 2093, in _load_module
m = self._load_package(fqname, pathname, packagepath)
RecursionError: maximum recursion depth exceeded while calling a Python object
I added import sys; sys.setrecursionlimit(50000)
to the original python file as well as in the spec but still getting the same problem.
The interesting thing is that I don't get that error if I don't use fastapi (It works with Flask for example). Looks like PyInstaller has some issue with fastapi.
Does anybody have any idea how to solve this issue?
This is the code in my main python function:
from fastapi import FastAPI
import uvicorn
app = FastAPI()
if __name__ == "__main__":
uvicorn.run("main:app", host="0.0.0.0", workers=1, port=5000)
Upvotes: 5
Views: 8010
Reputation: 10016
Using @UFO answer I then also updated the PyInstaller to include the hidden modules
pydantic
and install from source. Hopefully this will update in the registry soon.pip uninstall pydantic
pip install git+git://github.com/samuelcolvin/pydantic@master#egg=pydantic
# or with extras
pip install git+git://github.com/samuelcolvin/pydantic@master#egg=pydantic[email,typing_extensions]
Run pyinstaller main.py
Add these hidden imports to .spec
file generated by pyinstaller
hiddenimports=[
'uvicorn.logging',
'uvicorn.loops',
'uvicorn.loops.auto',
'uvicorn.protocols',
'uvicorn.protocols.http',
'uvicorn.protocols.http.auto',
'uvicorn.protocols.websockets',
'uvicorn.protocols.websockets.auto',
'uvicorn.lifespan',
'uvicorn.lifespan.on',
]
pyinstaller main.spec
Ref:
main.py
import uvicorn
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def root():
return {"hello": "world"}
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)
Upvotes: 5
Reputation: 71
I also encountered the same problem today, and I found that the problem was in the Pydantic module.
I reinstalled it directly from the repository:
pip uninstall pydantic
pip install git+git://github.com/samuelcolvin/pydantic@master#egg=pydantic
# or with extras
pip install git+git://github.com/samuelcolvin/pydantic@master#egg=pydantic[email,typing_extensions]
This will solve the maximum recursion depth problem, but will encounter another problem in Uvicorn:
Traceback (most recent call last):
File "logging/config.py", line 388, in resolve
AttributeError: module 'uvicorn' has no attribute 'logging'
And I replaced Uvicorn with Hypercorn + Uvloop and it works very well now.
Here is my final code:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
if __name__ == "__main__":
import asyncio
import uvloop
from hypercorn.asyncio import serve
from hypercorn.config import Config
config = Config()
config.bind = ["0.0.0.0:8000"]
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(serve(app, config))
Upvotes: 7