Marcucus _
Marcucus _

Reputation: 98

FastAPI or sqlachemy error encoding in python

I've made a website with sqlachemy, fastAPI and postgresql in python.

The error is raised when I try to login as a user.

For information, I get the password and the email from an HTML/JS form and my database is encoded in UTF-8

I have tested:

This is the error I get:

INFO:     127.0.0.1:54829 - "POST /login HTTP/1.1" 500 Internal Server Error
ERROR:    Exception in ASGI application
  + Exception Group Traceback (most recent call last):
  |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\_utils.py", line 76, in collapse_excgroups
  |     yield
  |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\middleware\base.py", line 178, in __call__
  |     async with anyio.create_task_group() as task_group:
  |                ~~~~~~~~~~~~~~~~~~~~~~~^^
  |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\anyio\_backends\_asyncio.py", line 767, in __aexit__
  |     raise BaseExceptionGroup(
  |         "unhandled errors in a TaskGroup", self._exceptions
  |     )
  | ExceptionGroup: unhandled errors in a TaskGroup (1 sub-exception)
  +-+---------------- 1 ----------------
    | Traceback (most recent call last):
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\uvicorn\protocols\http\httptools_impl.py", line 409, in run_asgi
    |     result = await app(  # type: ignore[func-returns-value]
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |         self.scope, self.receive, self.send
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |     )
    |     ^
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\uvicorn\middleware\proxy_headers.py", line 60, in __call__
    |     return await self.app(scope, receive, send)
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\fastapi\applications.py", line 1054, in __call__
    |     await super().__call__(scope, receive, send)
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\applications.py", line 112, in __call__
    |     await self.middleware_stack(scope, receive, send)
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\middleware\errors.py", line 187, in __call__
    |     raise exc
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\middleware\errors.py", line 165, in __call__
    |     await self.app(scope, receive, _send)
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\middleware\base.py", line 177, in __call__
    |     with recv_stream, send_stream, collapse_excgroups():
    |                                    ~~~~~~~~~~~~~~~~~~^^
    |   File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.13_3.13.752.0_x64__qbz5n2kfra8p0\Lib\contextlib.py", line 162, in __exit__
    |     self.gen.throw(value)
    |     ~~~~~~~~~~~~~~^^^^^^^
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\_utils.py", line 82, in collapse_excgroups
    |     raise exc
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\middleware\base.py", line 179, in __call__
    |     response = await self.dispatch_func(request, call_next)
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\slowapi\middleware.py", line 136, in dispatch
    |     response = await call_next(request)
    |                ^^^^^^^^^^^^^^^^^^^^^^^^
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\middleware\base.py", line 154, in call_next
    |     raise app_exc
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\middleware\base.py", line 141, in coro
    |     await self.app(scope, receive_or_disconnect, send_no_error)
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\middleware\exceptions.py", line 62, in __call__
    |     await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
    |     raise exc
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app
    |     await app(scope, receive, sender)
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\routing.py", line 715, in __call__
    |     await self.middleware_stack(scope, receive, send)
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\routing.py", line 735, in app
    |     await route.handle(scope, receive, send)
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\routing.py", line 288, in handle
    |     await self.app(scope, receive, send)
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\routing.py", line 76, in app
    |     await wrap_app_handling_exceptions(app, request)(scope, receive, send)
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
    |     raise exc
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app
    |     await app(scope, receive, sender)
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\routing.py", line 73, in app
    |     response = await f(request)
    |                ^^^^^^^^^^^^^^^^
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\fastapi\routing.py", line 301, in app
    |     raw_response = await run_endpoint_function(
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |     ...<3 lines>...
    |     )
    |     ^
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\fastapi\routing.py", line 212, in run_endpoint_function
    |     return await dependant.call(**values)
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\main.py", line 79, in login
    |     token = loginUser(email, password)
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\db.py", line 98, in loginUser
    |     user = db.query(User).filter(User.email == email, User.password == password).first()
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\orm\query.py", line 2754, in first
    |     return self.limit(1)._iter().first()  # type: ignore
    |            ~~~~~~~~~~~~~~~~~~~^^
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\orm\query.py", line 2853, in _iter
    |     result: Union[ScalarResult[_T], Result[_T]] = self.session.execute(
    |                                                   ~~~~~~~~~~~~~~~~~~~~^
    |         statement,
    |         ^^^^^^^^^^
    |         params,
    |         ^^^^^^^
    |         execution_options={"_sa_orm_load_options": self.load_options},
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |     )
    |     ^
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\orm\session.py", line 2365, in execute
    |     return self._execute_internal(
    |            ~~~~~~~~~~~~~~~~~~~~~~^
    |         statement,
    |         ^^^^^^^^^^
    |     ...<4 lines>...
    |         _add_event=_add_event,
    |         ^^^^^^^^^^^^^^^^^^^^^^
    |     )
    |     ^
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\orm\session.py", line 2241, in _execute_internal
    |     conn = self._connection_for_bind(bind)
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\orm\session.py", line 2110, in _connection_for_bind
    |     return trans._connection_for_bind(engine, execution_options)
    |            ~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |   File "<string>", line 2, in _connection_for_bind
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\orm\state_changes.py", line 139, in _go
    |     ret_value = fn(self, *arg, **kw)
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\orm\session.py", line 1189, in _connection_for_bind
    |     conn = bind.connect()
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\engine\base.py", line 3274, in connect
    |     return self._connection_cls(self)
    |            ~~~~~~~~~~~~~~~~~~~~^^^^^^
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\engine\base.py", line 146, in __init__
    |     self._dbapi_connection = engine.raw_connection()
    |                              ~~~~~~~~~~~~~~~~~~~~~^^
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\engine\base.py", line 3298, in raw_connection
    |     return self.pool.connect()
    |            ~~~~~~~~~~~~~~~~~^^
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\pool\base.py", line 449, in connect
    |     return _ConnectionFairy._checkout(self)
    |            ~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\pool\base.py", line 1263, in _checkout
    |     fairy = _ConnectionRecord.checkout(pool)
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\pool\base.py", line 712, in checkout
    |     rec = pool._do_get()
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\pool\impl.py", line 179, in _do_get
    |     with util.safe_reraise():
    |          ~~~~~~~~~~~~~~~~~^^
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 146, in __exit__
    |     raise exc_value.with_traceback(exc_tb)
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\pool\impl.py", line 177, in _do_get
    |     return self._create_connection()
    |            ~~~~~~~~~~~~~~~~~~~~~~~^^
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\pool\base.py", line 390, in _create_connection
    |     return _ConnectionRecord(self)
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\pool\base.py", line 674, in __init__
    |     self.__connect()
    |     ~~~~~~~~~~~~~~^^
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\pool\base.py", line 900, in __connect
    |     with util.safe_reraise():
    |          ~~~~~~~~~~~~~~~~~^^
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 146, in __exit__
    |     raise exc_value.with_traceback(exc_tb)
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\pool\base.py", line 896, in __connect
    |     self.dbapi_connection = connection = pool._invoke_creator(self)
    |                                          ~~~~~~~~~~~~~~~~~~~~^^^^^^
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\engine\create.py", line 646, in connect
    |     return dialect.connect(*cargs, **cparams)
    |            ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\engine\default.py", line 622, in connect
    |     return self.loaded_dbapi.connect(*cargs, **cparams)
    |            ~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^
    |   File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\psycopg2\__init__.py", line 135, in connect
    |     conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
    | UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe9 in position 103: invalid continuation byte
    +------------------------------------

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\uvicorn\protocols\http\httptools_impl.py", line 409, in run_asgi
    result = await app(  # type: ignore[func-returns-value]
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        self.scope, self.receive, self.send
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\uvicorn\middleware\proxy_headers.py", line 60, in __call__
    return await self.app(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\fastapi\applications.py", line 1054, in __call__
    await super().__call__(scope, receive, send)
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\applications.py", line 112, in __call__
    await self.middleware_stack(scope, receive, send)
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\middleware\errors.py", line 187, in __call__
    raise exc
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\middleware\errors.py", line 165, in __call__
    await self.app(scope, receive, _send)
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\middleware\base.py", line 177, in __call__
    with recv_stream, send_stream, collapse_excgroups():
                                   ~~~~~~~~~~~~~~~~~~^^
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.13_3.13.752.0_x64__qbz5n2kfra8p0\Lib\contextlib.py", line 162, in __exit__
    self.gen.throw(value)
    ~~~~~~~~~~~~~~^^^^^^^
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\_utils.py", line 82, in collapse_excgroups
    raise exc
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\middleware\base.py", line 179, in __call__
    response = await self.dispatch_func(request, call_next)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\slowapi\middleware.py", line 136, in dispatch
    response = await call_next(request)
               ^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\middleware\base.py", line 154, in call_next
    raise app_exc
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\middleware\base.py", line 141, in coro
    await self.app(scope, receive_or_disconnect, send_no_error)
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\middleware\exceptions.py", line 62, in __call__
    await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
    raise exc
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app
    await app(scope, receive, sender)
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\routing.py", line 715, in __call__
    await self.middleware_stack(scope, receive, send)
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\routing.py", line 735, in app
    await route.handle(scope, receive, send)
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\routing.py", line 288, in handle
    await self.app(scope, receive, send)
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\routing.py", line 76, in app
    await wrap_app_handling_exceptions(app, request)(scope, receive, send)
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
    raise exc
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app
    await app(scope, receive, sender)
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\starlette\routing.py", line 73, in app
    response = await f(request)
               ^^^^^^^^^^^^^^^^
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\fastapi\routing.py", line 301, in app
    raw_response = await run_endpoint_function(
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ...<3 lines>...
    )
    ^
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\fastapi\routing.py", line 212, in run_endpoint_function
    return await dependant.call(**values)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Marcus\noCodeProj\testFastApi\main.py", line 79, in login
    token = loginUser(email, password)
  File "C:\Users\Marcus\noCodeProj\testFastApi\db.py", line 98, in loginUser
    user = db.query(User).filter(User.email == email, User.password == password).first()
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\orm\query.py", line 2754, in first
    return self.limit(1)._iter().first()  # type: ignore
           ~~~~~~~~~~~~~~~~~~~^^
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\orm\query.py", line 2853, in _iter
    result: Union[ScalarResult[_T], Result[_T]] = self.session.execute(
                                                  ~~~~~~~~~~~~~~~~~~~~^
        statement,
        ^^^^^^^^^^
        params,
        ^^^^^^^
        execution_options={"_sa_orm_load_options": self.load_options},
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\orm\session.py", line 2365, in execute
    return self._execute_internal(
           ~~~~~~~~~~~~~~~~~~~~~~^
        statement,
        ^^^^^^^^^^
    ...<4 lines>...
        _add_event=_add_event,
        ^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\orm\session.py", line 2241, in _execute_internal
    conn = self._connection_for_bind(bind)
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\orm\session.py", line 2110, in _connection_for_bind
    return trans._connection_for_bind(engine, execution_options)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<string>", line 2, in _connection_for_bind
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\orm\state_changes.py", line 139, in _go
    ret_value = fn(self, *arg, **kw)
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\orm\session.py", line 1189, in _connection_for_bind
    conn = bind.connect()
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\engine\base.py", line 3274, in connect
    return self._connection_cls(self)
           ~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\engine\base.py", line 146, in __init__
    self._dbapi_connection = engine.raw_connection()
                             ~~~~~~~~~~~~~~~~~~~~~^^
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\engine\base.py", line 3298, in raw_connection
    return self.pool.connect()
           ~~~~~~~~~~~~~~~~~^^
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\pool\base.py", line 449, in connect
    return _ConnectionFairy._checkout(self)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\pool\base.py", line 1263, in _checkout
    fairy = _ConnectionRecord.checkout(pool)
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\pool\base.py", line 712, in checkout
    rec = pool._do_get()
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\pool\impl.py", line 179, in _do_get
    with util.safe_reraise():
         ~~~~~~~~~~~~~~~~~^^
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 146, in __exit__
    raise exc_value.with_traceback(exc_tb)
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\pool\impl.py", line 177, in _do_get
    return self._create_connection()
           ~~~~~~~~~~~~~~~~~~~~~~~^^
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\pool\base.py", line 390, in _create_connection
    return _ConnectionRecord(self)
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\pool\base.py", line 674, in __init__
    self.__connect()
    ~~~~~~~~~~~~~~^^
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\pool\base.py", line 900, in __connect
    with util.safe_reraise():
         ~~~~~~~~~~~~~~~~~^^
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 146, in __exit__
    raise exc_value.with_traceback(exc_tb)
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\pool\base.py", line 896, in __connect
    self.dbapi_connection = connection = pool._invoke_creator(self)
                                         ~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\engine\create.py", line 646, in connect
    return dialect.connect(*cargs, **cparams)
           ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\sqlalchemy\engine\default.py", line 622, in connect
    return self.loaded_dbapi.connect(*cargs, **cparams)
           ~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Marcus\noCodeProj\testFastApi\venv\Lib\site-packages\psycopg2\__init__.py", line 135, in connect
    conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe9 in position 103: invalid continuation byte

My code :

in main.py :


@app.post("/login")
async def login(response: Response, email: str = Form(...), password: str = Form(...)):
    print(f"🔹 Tentative de connexion: {email}")
    
    token = loginUser(email, password)

    if token is None:
        print("❌ Identifiants invalides")  # Log en cas d'erreur
        raise HTTPException(status_code=401, detail="Email ou mot de passe incorrect")

    # 🔹 Stocker le token dans un cookie sécurisé
    response.set_cookie(
        key="session_token",
        value=token,
        httponly=True,
        secure=False,  # 🔹 En dev, mettre `False`, en prod mettre `True`
        max_age=7200  # 2 heures
    )

    print("✅ Connexion réussie, cookie défini")  # Log de succès
    return {"message": "Connexion réussie", "token": token}  # Log dans la console

In db.py :

def create_session(email):
    db = SessionLocal()
    try:
        new_session = Session(email=email)
        db.add(new_session)
        db.commit()
        db.refresh(new_session)
        return new_session.session_token  # Renvoie le token
    finally:
        db.close()

def loginUser(email, password):
    db = SessionLocal()

    user = db.query(User).filter(User.email == email, User.password == password).first()
    
    if not user:
        return 0000
    
    # Créer une session et récupérer le token
    session_token = create_session(email)
    return session_token

My shemas :

class User(Base):
    __tablename__ = 'USER'

    id = Column(Integer, primary_key=True, index=True, autoincrement=True)
    nom = Column(String, index=True)
    prenom = Column(String, index=True)
    email = Column(String, unique=True, index=True)
    password = Column(String, index=True)


class Dispo(Base):
    __tablename__ = 'DISPO'

    id = Column(Integer, primary_key=True, index=True)
    jour = Column(Integer, index=True)
    mois = Column(Integer, index=True)
    annee = Column(Integer, index=True)
    dispo = Column(Integer, index=True)
    userid = Column(Integer, index=True)



class Session(Base):
    __tablename__ = 'SESSION'  

    id = Column(Integer, primary_key=True, autoincrement=True)
    session_token = Column(String, unique=True, index=True, nullable=False, default=lambda: str(uuid.uuid4())) 
    email = Column(String, ForeignKey('USER.email', ondelete="CASCADE"), nullable=False)
    expires_at = Column(DateTime, nullable=False, default=lambda: datetime.datetime.utcnow() + datetime.timedelta(hours=2))

    user = relationship("User")

And finaly, here is the way I send my data to my endpoint /login :

    <script>
        document.getElementById("loginForm").addEventListener("submit", async function(event) {
            event.preventDefault(); // Empêche le rechargement de la page

            const formData = new FormData(this);

            try {
                const response = await fetch("/login", {
                    method: "POST",
                    body: formData
                });

                const data = await response.json();

                // Affichage du message
                const messageElement = document.getElementById("responseMessage");
                messageElement.innerText = data.message;

                if (response.ok) {
                    messageElement.style.color = "green";
                    // Redirection après 2 secondes
                    setTimeout(() => {
                        window.location.href = "home.html";
                    }, 2000);
                } else {
                    messageElement.style.color = "red";
                }
            } catch (error) {
                console.error("Erreur de connexion :", error);
                document.getElementById("responseMessage").innerText = "Erreur de connexion";
                document.getElementById("responseMessage").style.color = "red";
            }
        });
    </script>

Thanks in advance

Upvotes: 1

Views: 42

Answers (2)

Marcucus _
Marcucus _

Reputation: 98

I figure out that the problem come from a part of a library who wasen't imported

Upvotes: 0

J_H
J_H

Reputation: 20550

Ok, so your call to loginUser() goes south on this line:

  File "C:\Users\Marcus\noCodeProj\testFastApi\db.py", line 98, in loginUser
    user = db.query(User).filter(User.email == email, User.password == password).first()

(BTW, nit: PEP 8 asks that you call it login_user(), similar to the create_session() you wrote just above it.)

This is something we can dig into. You might extract it as an automated unit test so you can easily reproduce it, without the starlette / uvicorn clutter distracting you.

Or we could tackle it in place. Do the following to get a better handle on the unknowns.

  1. Log both the type() and the value of those email and password input parameters
  2. Verify that db.query(User) will, in fact, produce the set of all users. Log at least one user's email and password.
  3. Hardcode email = "[email protected]" so we're ignoring the input parameter, and similarly for password, then verify the query works as expected.

table encoding

You didn't mention which backend RDBMS vendor you're using, nor whether the table is encoded with UTF-8 (we hope!), CP-1252, Latin1, or something else. The goal is for a password like "déjà vu" to be SELECTed from the table and appear in python as seven sensible 32-bit code points. The "codec can't decode byte 0xe9" diagnostic suggests to me that that didn't happen. It's as though a binary BLOB was offered to decode(), although Latin1 data can produce a similar effect. Recall that a UTF8 bytestream has some structure to it, so not all of the possible byte combinations will lead to a successful decode. You need to find where in the stack the charset mismatch arose.

SQL commands like SHOW CREATE TABLE USER will typically reveal details like data encoding and collation encoding. Nearly always you want them to be identical. You probably want them to be Unicode.

If the database defaults are different from the table settings, you have a regrettably complex setup, which you may want to consider simplifying. Go with "unicode everywhere!"

Upvotes: 1

Related Questions