Search code examples
flaskuwsgipythoninterpreter

Running a uWSGI app that uses uwsgidecorators from shell python directly


As you may know, uwsgidecorators are only working if your app is running in the context of uwsgi, which is not exactly clear from the documentation: https://uwsgi-docs.readthedocs.io/en/latest/PythonDecorators.html

My code is using these decorators, for example for locking:

@uwsgidecorators.lock
def critical_func():
  ...

And this works just fine when I deploy my app with uwsgi, however, when starting it directly from Python shell, I'm getting an expected error:

File ".../venv/lib/python3.6/site-packages/uwsgidecorators.py", line 10, in <module>
  import uwsgi
ModuleNotFoundError: No module named 'uwsgi'

Is there any known solution to run my app in both modes? obviously I don't need the synchronization and other capabilities to work when using simple interpreter, but doing some try-except importing seems like really bad coding.


Solution

  • For the meantime I did the following implementation, would be happy to know there's something simpler:

    class _dummy_lock():
        """Implement the uwsgi lock decorator without actually doing any locking"""
        def __init__(self, f):
            self.f = f
    
        def __call__(self, *args, **kwargs):
            return self.f(*args, **kwargs)
    
    
    class uwsgi_lock():
        """
        This is a lock decorator that wraps the uwsgi decorator to allow it to work outside of a uwsgi environment as well.
        ONLY STATIC METHODS can be locked using this functionality
        """
        def __init__(self, f):
            try:
                import uwsgidecorators
                self.lock = uwsgidecorators.lock(f)  # the real uwsgi lock class
            except ModuleNotFoundError:
                self.lock = _dummy_lock(f)
    
        def __call__(self, *args, **kwargs):
            return self.lock(*args, **kwargs)
    
    @staticmethod
    @uwsgi_lock
    def critical_func():
      ...