django-constance icon indicating copy to clipboard operation
django-constance copied to clipboard

Needs `sync_to_async` in async context

Open HosseyNJF opened this issue 4 years ago • 8 comments

Describe the problem

When used in an async view, you need to access the object with a sync_to_async wrapper or this error will get raised:

SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async

Steps to reproduce

Create an async view in Django 3.1 and try to access an attribute of the config object.

System configuration

  • Django version: 3.1
  • Python version: 3.9
  • Django-Constance version: 2.8.0

HosseyNJF avatar Dec 07 '20 19:12 HosseyNJF

I came here to report something similar. This error also occurs if trying to use constance settings in views.py or urls.py (anything that gets called when Django starts up) when using the latest django-channels and deploying the app with asgi. An example would be using a constance config as a constant in a caching decorator.

benwhalley avatar May 05 '21 07:05 benwhalley

Same - django 3.1, python 3.7, latest constance

lmeyerov avatar May 06 '21 21:05 lmeyerov

Any thoughts?

More details:

  • py 3.7, django 3.1, daphne 3.0.1, asgref 3.2.10, constance 2.8.0 (latest), no channels
  • constance via postgres/redis
  • triggering scenario is urls.py calls config.XYZ as part of import

lmeyerov avatar Jun 07 '21 18:06 lmeyerov

More complete workaround:

from asgiref.sync import sync_to_async
from constance import config

@sync_to_async
def safe_constance_get(fld: str):
    return getattr(config, fld)

z = safe_constance_get('Z')

lmeyerov avatar Jun 08 '21 08:06 lmeyerov

mea culpa, not always the right fix: can get you a <coroutine obj> that'll need to be run

This is a common use case so not sure

lmeyerov avatar Sep 03 '21 02:09 lmeyerov

https://channels.readthedocs.io/en/stable/topics/databases.html#database-sync-to-async is recommended way to wrap. What changes do you expect in django-constance?

sergei-iurchenko avatar Mar 16 '23 00:03 sergei-iurchenko

@sergei-iurchenko Hi! Thanks for answering. Considering that the Constance API is as simple as Django's Settings API, It would've been better if the library handled the synchronous context to reduce the confusion for a beginner user. Doing this would also prevent the code from being coupled to the storage backend (Because you won't need to use sync_to_async when using a Redis backend).

HosseyNJF avatar Mar 18 '23 10:03 HosseyNJF

I see your point. How do you see expected changed to support this feature? I just do not see any obvious way to implement this.

sergei-iurchenko avatar Mar 25 '23 22:03 sergei-iurchenko