Support for Python 3.12
Describe the bug
Importing fastapi_users fails with Python 3.12.
To Reproduce
Steps to reproduce the behavior:
- Install
fastapi-usersv12.1.2 and run Python 3.12. - Execute
import fastapi_users. - See error
ModuleNotFoundError: No module named 'pkg_resources'.
Expected behavior
Fastapi-users should work on Python 3.12.
Configuration
- Python version : 3.12
- FastAPI version : 0.103.2
- FastAPI Users version : 12.1.2
Additional context
It seems that passlib still uses pkg_resources, which is deprecated. On Python <3.10, importlib_metadata should be used, and importlib.metadata should be used on Python >=3.10.
Thanks for raising this @davidbrochart 👍
Unfortunately, passlib seems to be unmaintained those days: https://foss.heptapod.net/python-libs/passlib
It's really unfortunate, because passlib is the de-facto standard for password hashing. I'm not aware of alternatives 🤔
Maybe fork it?
Probably, but not me. I know nothing about cryptography algorithms, so I wouldn't risk to support a library that critical 😅
An alternative is to install setuptools, but there is a deprecation warning when importing:
Python 3.12.0 | packaged by conda-forge | (main, Oct 3 2023, 08:43:22) [GCC 12.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pkg_resources
<stdin>:1: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
Not sure if its related, but just started seeing this:
Python: 3.12.0
FastAPI: 0.104.1
FastAPI-Users: 12.1.2
INFO: 172.21.0.1:47400 - "GET /auth/google/authorize HTTP/1.1" 200 OK
(trapped) error reading bcrypt version
Traceback (most recent call last):
File "/usr/local/lib/python3.12/site-packages/fastapi_users/manager.py", line 201, in oauth_callback
user = await self.get_by_oauth_account(oauth_name, account_id)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/fastapi_users/manager.py", line 106, in get_by_oauth_account
raise exceptions.UserNotExists()
fastapi_users.exceptions.UserNotExists
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.12/site-packages/fastapi_users/manager.py", line 205, in oauth_callback
user = await self.get_by_email(account_email)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/fastapi_users/manager.py", line 90, in get_by_email
raise exceptions.UserNotExists()
fastapi_users.exceptions.UserNotExists
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.12/site-packages/passlib/handlers/bcrypt.py", line 620, in _load_backend_mixin
version = _bcrypt.__about__.__version__
^^^^^^^^^^^^^^^^^
AttributeError: module 'bcrypt' has no attribute '__about__'
User 4bdb7054-ddd9-433c-8bbb-a7204a296ae8 has registered.
This happens when registering a new user, it works perfectly and have not noticed any problems...
bert
I think that the warning in the previous comment (by @bert2002) is unrelated to python 3.12; it's rather a passlib issue with recent bcrypt versions (see https://foss.heptapod.net/python-libs/passlib/-/issues/190).
Unfortunately, passlib seems to be unmaintained those days: https://foss.heptapod.net/python-libs/passlib
It's really unfortunate, because passlib is the de-facto standard for password hashing. I'm not aware of alternatives 🤔
For the record, there seems to be a renewed effort towards passlib maintenance, see https://foss.heptapod.net/python-libs/passlib/-/issues/187.
The only dependency to passlib seems to be in password.py. https://argon2-cffi.readthedocs.io/en/stable/argon2.html could replace passlib as the package defines a PasswordHasher with close protocol. We just have to define a new CryptContext protocol.
The only dependency to passlib seems to be in password.py. https://argon2-cffi.readthedocs.io/en/stable/argon2.html could replace passlib as the package defines a PasswordHasher with close protocol. We just have to define a new
CryptContextprotocol.
Passlib supports several hashing algorithms, not only argon2, and has convenient features like hash upgrades. Plus, I believe most FastAPI Users installations use bcrypt right now.
Hi @frankie567 could this option to unblock the library for python 3.12 be considered as a short term solution? https://github.com/fastapi-users/fastapi-users/pull/1345
A passlib maintainer responded so it sounds like there may be a fix coming soon.
Fixed as of v13.0.0