Asyncifying django.contrib.auth? (and signals, and maybe sessions)

That’s awesome! @HappyDingning have you been working on prototyping a version of this? If not, maybe we could build off of @Andrew-Chen-Wang’s work as a starting point

A few thoughts/clarifying pointers after reading through this thread:

  1. This was on a FastAPI backend, so context switching has not been tested. My initial thoughts on the session store implementation above is that, under a single class, other modules don’t need to access two different session store objects. With two classes, there would be potential for race conditions with the save method unless you shared a storage method such as contextvars. General thoughts on the implementation is that it’s safe.
  2. The methods don’t try to touch any Python magic methods which is the typical case for most asyncio implementations I’ve added over the past year (especially __getitem__, __del__, etc.). I warn against those because you never know when an async only call is needed that can mess those up. Best be explicit. In the redis-py implementation, this is also discouraged and simply not allowed (including in the sans-io rewrite).
  3. Separate classes topic:

tl;dr use a single class in this case per point 1

I’m open to the separate class idea too, code wins arguments.

Generally, this should definitely be allowed in certain contexts. Even in Django, the test Client class has an AsyncClient counterpart, or ASGIRequest vs. WSGIRequest. Additionally, in the db driver, my (albeit long-idle draft) PR has a separate async class from its sync counterparts (even if it uses the same package like psycopg’s compatibility for both sync+async).

The case to use two separate classes for sync/async is not obvious in Django given precedence. In my opinion, when you’re stuck in a certain context (like async testing only with AsyncClient), it’s best to have two different classes for sync and async to optimize for the specific environment; furthermore, if a local storage is unneeded, separate classes can provide efficiency while still following DRY. But there are a lot of nuances (such as the implementation of LocMem cache + Redis cache backends, but I digress for a different thread).

Good spot to see the context-separate-class philosophy is in redis-py’s or elasticsearch-py’s asyncio module, but they’re following DRY principle + bound by low-level I/O connections.

Feel free to ping/email me with questions or if more code is needed; unlikely to have time to visit implementation.

Andrew

1 Like

I’ve opened #34901 (Add async interface to contrib.sessions) – Django which will track work to merge @Andrew-Chen-Wang 's prototype into main (which would be released in 5.1).

Just as a summary of where this lands in the work I outlined in the original post:

  1. DONE
  2. DONE
  3. The just-filed ticket (#34901 (Add async interface to contrib.sessions) – Django)
  4. Blocked by (3)
  5. DONE
  6. Blocked by (4)
1 Like

I traced a problem we encountered with upgrading Django to v5.0 in buildroot to Refs #31949 -- Made @sensitive_variables/sensitive_post_parameters decorators to work with async functions. by bigfootjon · Pull Request #16831 · django/django · GitHub.

Maybe someone here has an idea how to resolve this?

CC @bigfootjon who wrote the PR above. Thanks for your help! :slight_smile:

Just to close the loop here, #35187 (@sensitive_variables/sensitive_post_parameters decorators crash with .pyc-only builds.) – Django has been solved via Fixed #35187 -- Fixed @sensitive_variables/sensitive_post_parameters decorators crash with .pyc-only builds. by felixxm · Pull Request #17860 · django/django · GitHub and has been cherry-picked back to the 5.0.x branch for release with the next bugfix release of Django.

2 Likes