What is Python idiom in uwsgi for
if __name__ == '__main__':
main()
I found here a long string in uwsgi instead of __main__
What __name__ string does uwsgi use?. But it looks like a workaround. Is there better way to call function once, when uwsgi starts my python script?
It depends what you are trying to guard against. There are three use cases I can think of:
The uwsgi
binary provides a module called uwsgi
that is otherwise not importable. This is best used for detecting if you are running unit tests or not. See Unit testing Flask app running under uwsgi
try:
import uwsgi
except ImportError:
UWSGI_SERVER = False
else:
UWSGI_SERVER = True
if UWSGI_SERVER:
do_something()
else:
import test_utils
test_utils.mock_do_somethng()
This implies the above, that if your main module has a uwsgi_file_*
module name, then you are running a uwsgi
server. It also lets you know which file was run as the main module. That is, the one that contains your application. Maybe you are running a handful of micro-services that all use the same core, but need to be configured slightly differently depending on which service is running.
File: myapp.py
import sys
if __name__ == 'uwsgi_file_myapp':
assert 'uwsgi_file_myapp' in sys.modules, (
'other modules can also see what the main module is'
)
connect_to_redis()
See What __name__ string does uwsgi use? for more details.
Useful for doing one-time initialisations per worker process. Such as connecting to a database.
try:
import uwsgi
except ImportError:
def postfork(func):
"""Dummy decorator for unit tests"""
return func
else:
from uwsgidecorators import postfork
DB = None
@postfork
def init_db():
global DB
from datetime import datetime
DB = f'some-database connection, set @ {datetime.now().isoformat()}'
def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html')])
return [f'{DB=!r}'.encode()]
This program will need to be run with the --master
option. eg.
uwsgi --http :8080 --master --wsgi-file myapp.py