request_ctx error

59 views
Skip to first unread message

mauri...@gmail.com

unread,
Aug 21, 2022, 3:06:43 PM8/21/22
to py4web
I normally get this error if not connected to internet when using this app locally.
I just ported from web2py to py4web on pythonanywhere an got his error again:

[2022-08-21T17:42:32.169465]: Traceback (most recent call last):
  File "/home/www_hest/py4web/py4web/core.py", line 1317, in import_app
    module = importlib.machinery.SourceFileLoader(
  File "<frozen importlib._bootstrap_external>", line 529, in _check_name_wrapper
  File "<frozen importlib._bootstrap_external>", line 1034, in load_module
  File "<frozen importlib._bootstrap_external>", line 859, in load_module
  File "<frozen importlib._bootstrap>", line 274, in _load_module_shim
  File "<frozen importlib._bootstrap>", line 711, in _load
  File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 855, in exec_module
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "/home/www_hest/py4web/apps/hest/__init__.py", line 7, in <module>
    from .models import db
  File "/home/www_hest/py4web/apps/hest/models.py", line 147, in <module>
    Field('author', 'reference auth_user', default=get_user(), writable=False, readable=False),
  File "/home/www_hest/py4web/apps/hest/models.py", line 128, in get_user
    return auth.current_user.get('id') if auth.current_user else None
  File "/home/www_hest/py4web/py4web/utils/auth.py", line 493, in current_user
    return self.get_user()
  File "/home/www_hest/py4web/py4web/utils/auth.py", line 461, in get_user
    if not self.session.is_valid():
  File "/home/www_hest/py4web/py4web/core.py", line 345, in is_valid
    ctx = self.__request_master_ctx__.request_ctx
AttributeError: '_thread._local' object has no attribute 'request_ctx'
[FAILED] loading hest ('_thread._local' object has no attribute 'request_ctx')

In my models.py, I have this function:

def get_user():
    return auth.current_user.get('id') if auth.current_user else None

Jim Steil

unread,
Aug 22, 2022, 8:52:26 AM8/22/22
to py4web
The manual has this method for retrieving the user_id

@action("index")
@action.uses(auth.user)
def index():
    user_id = auth.user_id
    user_email = auth.get_user().get('email')
    return locals()

You should use auth.get_user() inside a controller method (that has auth.user included in your @action.uses()).

Since auth is loaded only once in py4web (vs every request in web2py) you need to access your current user through auth only when your @action.uses() includes auth.user.

Does that help?

-Jim

Maurice Waka

unread,
Aug 24, 2022, 12:31:22 PM8/24/22
to Jim Steil, py4web
Thanks @Jim Steil 
I noted this error from the modules.py file

I had:
from .common import db, Field, DAL, session, auth
from py4web.utils.auth import Auth
def get_user():
    return auth.current_user.get('id') if auth.current_user else None

Using the 'Auth' from the utils.py solved the problem for me. There is 'auth' from common.py and another 'Auth' from py4web.utils.auth.

Kind regards

--
You received this message because you are subscribed to a topic in the Google Groups "py4web" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/py4web/4Mv0MgWco8Y/unsubscribe.
To unsubscribe from this group and all its topics, send an email to py4web+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/py4web/83d2ac2f-9a8f-4c28-8d02-55a63e45e9a0n%40googlegroups.com.

Jim Steil

unread,
Aug 24, 2022, 12:42:54 PM8/24/22
to py4web
With that solution I think you could run into concurrency issues once you get in a multi-user environment.

In controllers that need access to the current user I always use the code I posted earlier.

-Jim

Maurice Waka

unread,
Aug 24, 2022, 12:57:20 PM8/24/22
to Jim Steil, py4web
Question...
This is my controller code using the models.py code earlier posted:
@authenticated()
def tasks():
    a = request.forms.get('jsObject')
    user = auth.get_user()

    if a:        
        db.tasks.insert(messages=a,author=auth.user_id)        
    db.commit()        
    return dict()

@authenticated()
def my_result():
    rows = db(db.tasks.author).select(db.tasks.ALL, orderby=db.tasks.created_on)
    ....code...
    return dict()

Any advice/critic?
regards

Jim Steil

unread,
Aug 24, 2022, 3:10:24 PM8/24/22
to py4web
I would use 

@authenticated

instead of

@authenticated()


Otherwise this should work.  But, the line user = auth.get_user() doesn't really do anything, you don't use the user variable again in that method.

-Jim

Maurice Waka

unread,
Aug 24, 2022, 10:06:23 PM8/24/22
to Jim Steil, py4web
Reply all
Reply to author
Forward
0 new messages