0

I am trying to run a flask scheduler from app.py that executes a function that talks directly to sqlalchemy.

I defined the app context but it still can't seem to detect it.

The error message I get is:

Job "Sync LDAP Users (trigger: interval[0:01:00], next run at: 2021-07-13 11:11:56 CEST)" raised an exception
Traceback (most recent call last):
  File "/Users/omar/code/venv/lib/python3.7/site-packages/apscheduler/executors/base.py", line 125, in run_job
    retval = job.func(*job.args, **job.kwargs)
  File "/Users/omar/code/app/iprotect_api/resources/users.py", line 229, in get_users_from_ldap
    cards = get_lastkeyusage()
 
  File "/Users/omar/code/venv/lib/python3.7/site-packages/werkzeug/local.py", line 347, in __getattr__
    return getattr(self._get_current_object(), name)
  File "/Users/omar/code/venv/lib/python3.7/site-packages/werkzeug/local.py", line 306, in _get_current_object
    return self.__local()
  File "/Users/omar/code/venv/lib/python3.7/site-packages/flask/globals.py", line 51, in _find_app
    raise RuntimeError(_app_ctx_err_msg)
RuntimeError: Working outside of application context.

This typically means that you attempted to use functionality that needed
to interface with the current application object in some way. To solve
this, set up an application context with app.app_context().  See the
documentation for more information.

This is where I run the scheduler:

from app import app
from flask_apscheduler import APScheduler
from app.users import get_users_from_ldap

scheduler = APScheduler()
scheduler.init_app(app)


if __name__ == "__main__":
    with app.app_context():
        scheduler.add_job(id = 'Sync LDAP Users', func=get_users_from_ldap, trigger="interval", minutes=1)
        scheduler.start()
    app.run(host='127.0.0.1', port=5000, debug=True, threaded=True)

This is the function it calls: get_users_from_ldap

def get_users_from_ldap(username=None):
    search_filter = ldap_search_filter
    if username:
        search_filter = "(&(uid=%s)%s)" % (username, ldap_search_filter)

    server = ldap3.Server(ldap_server_uri)
    with ldap3.Connection(server, auto_bind=True, user=ldap_user, password=ldap_password) as conn:
        conn.search(ldap_search_base, search_filter, attributes=ldap3.ALL_ATTRIBUTES)

    if username and len(conn.entries) == 0:
        abort(404, error="User %s not found." % username)

    cards = get_lastkeyusage()
    output = []
    for entry in conn.entries:

        user = {'NAME': entry['uid'][0], 'FULLNAME': entry['cn'][0], 'LOCATION': entry['l'][0]}
        local_user = models.s.query(models.User).filter(models.User.username == user['NAME']).first()
        if not local_user or local_user is None:
            local_user = models.User(username=user['NAME'], fullname=user['FULLNAME'], location=user['LOCATION'])
            models.s.add(local_user)
            models.s.commit()
            local_user = models.s.query(models.User).filter(models.User.username == user['NAME']).first()
            
        output.append(user)

        models.s.commit()
    return output[0] if len(output) == 1 else output

Am I missing something here?

Omar Abdelrazik
  • 683
  • 2
  • 9
  • 30

0 Answers0