Today, I upgrade fastapi_login to the latest version: 1.7.0. When I login, it raises error.
2021-09-23 14:58:04 | TypeError: the first argument must be callable
-- | --
| | 2021-09-23 14:58:04 | self._user_callback = ordered_partial(callback, *args, **kwargs)
| | 2021-09-23 14:58:04 | File "/usr/local/lib/python3.8/site-packages/fastapi_login/fastapi_login.py", line 147, in decorator
| | 2021-09-23 14:58:04 | user = load_user(name)
The function user_loader
in fastapi_login.py
of version 1.6.2 is:
def user_loader(self, callback: Union[Callable, Awaitable]) -> Union[Callable, Awaitable]:
self._user_callback = callback
return callback
However, In the latest version, it becomes to:
def user_loader(self, *args, **kwargs) -> Union[Callable, Awaitable]:
def decorator(callback: Union[Callable, Awaitable]):
The actual setter of the load_user callback
Args:
callback (Callable or Awaitable): The callback which returns the user
Returns:
Partial of the callback with given args and keyword arguments already set
self._user_callback = ordered_partial(callback, *args, **kwargs)
return decorator
You add the function ordered_partial
here cause my problem. But When I refer to the release note, I did not find any notice for this change, only find a pull request note in #56 . It seems that your code is not backwards compatible. @MushroomMaula
You are correct, I am sorry this happend. My tests didn't catch it because I didn't use the decorator syntax.
For a quick fix you can just add parantheses behind the decorator like this:
@manager.user_loader()
def user_loader(email: str):
Im working on fixing this.
from config import DEFAULT_SETTINGS
from beanie import init_beanie
from models.user import User
from icecream import ic
import asyncio
from security import manager
async def setup():
# CREATE MOTOR CLIENT
client = motor.motor_asyncio.AsyncIOMotorClient(
DEFAULT_SETTINGS.mongo_dsn
# INIT BEANIE
await init_beanie(client.automatik_default, document_models=[User])
@manager.user_loader
async def get_user(email: str) -> User:
user = await User.find_one(User.email == email)
ic(user)
# if user is None:
# # raise HTTPException(status_code=404, detail="User not found")
# return None
# return user
return user
async def main():
await setup()
email = 'user@example.com'
user_exists = await get_user(email)
ic(user_exists)
user = await User.find_one(User.email == email)
ic(user)
if __name__ == '__main__':
asyncio.run(main())
Code above doesn't work with v1.7.1
It works with v1.6.3
Sorry forgot to paste the error..
/home/okazdal/.cache/pypoetry/virtualenvs/sekuritim-auto-selfhosted-Hg4E5aVa-py3.9/lib/python3.9/site-packages/fastapi_login/fastapi_login.py:158: SyntaxWarning: As of version 1.7.0 decorating your callback like this is not recommended anymore.
Please add empty parentheses like this @manager.user_loader() if you don'twhich to pass additional arguments to your callback.
warnings.warn(SyntaxWarning(
Traceback (most recent call last):
File "/home/okazdal/PycharmProjects/sekuritim-auto-selfhosted/misc/selfhosted/create_user.py", line 41, in <module>
asyncio.run(main())
File "/home/okazdal/py3.9/lib/python3.9/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "/home/okazdal/py3.9/lib/python3.9/asyncio/base_events.py", line 642, in run_until_complete
return future.result()
File "/home/okazdal/PycharmProjects/sekuritim-auto-selfhosted/misc/selfhosted/create_user.py", line 34, in main
user_exists = await get_user(email)
TypeError: 'NoneType' object is not callable
Error after adding recommended parentheses
Traceback (most recent call last):
File "/home/okazdal/PycharmProjects/sekuritim-auto-selfhosted/misc/selfhosted/create_user.py", line 41, in <module>
asyncio.run(main())
File "/home/okazdal/py3.9/lib/python3.9/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "/home/okazdal/py3.9/lib/python3.9/asyncio/base_events.py", line 642, in run_until_complete
return future.result()
File "/home/okazdal/PycharmProjects/sekuritim-auto-selfhosted/misc/selfhosted/create_user.py", line 34, in main
user_exists = await get_user(email)
TypeError: 'NoneType' object is not callable