I have a simple Python web service built around FastAPI that looks like this
project/
app/
__init__.py
main.py
config.py
tests/
run_tests.py
main.py
needs to import from config.py
some items, it looks like this
from app.config import Settings
app = FastAPI()
and I need to run it like this to run the webservice
$ cd project/app
$ python main.py
$ # Or I can do this
$ uvicorn main:app --reload
run_tests.py
has this code
from app.main import app
from app.config import settings
and I run the tests like this
$ cd project/app/tests
$ pytest
However, this doesn't work. I can only ever get either the tests to work or I can get the webserver to work.
- If I leave the code as it is above the unit tests run fine but I can't run the webservice
$ cd project/app
$ python main.py
Traceback (most recent call last):
File "main.py", line 19, in <module>
from app.config import settings
ModuleNotFoundError: No module named 'app'
$ cd ../../project
$ # I'm only in '/project' now not 'project/app'
$ python app/main.py
Traceback (most recent call last):
File "app/main.py", line 19, in <module>
from app.config import settings
ModuleNotFoundError: No module named 'app'
If I try to change it a relative import
main.py
from .config import Settings
I get this error
$ cd project/app
$ python main.py
Traceback (most recent call last):
File "main.py", line 19, in <module>
from .config import settings
ModuleNotFoundError: No module named '__main__.config'; '__main__' is not a package
It only works if I change it as follows
main.py
from config import Settings
$ cd project/app
$ python main.py
$ python main.py
INFO: Started server process [8325]
INFO:uvicorn.error:Started server process [8325]
INFO: Waiting for application startup.
However - this breaks the running of the unit tests
main.py
from config import Settings
$ cd project/app/tests
$ pytest
test_api.py:7: in <module>
from app.main import app
../main.py:19: in <module>
from config import settings
E ModuleNotFoundError: No module named 'config'
I don't understand what is going on? I have an __init__.py
inside of my project/app
folder so why isn't that considered a package?