[QUESTION] how to have sqlalchemy mixins that need user id?
See original GitHub issueFirst check
- I used the GitHub search to find a similar issue and didn’t find it.
- I searched the FastAPI documentation, with the integrated search.
- I already searched in Google “How to X in FastAPI” and didn’t find any information.
Description
I see Flask-appbuilder’s Mixins and want to implement the AuditMixin
. Here is a part code of AuditMixin
from Flask-appbuilder:
from flask import g
from sqlalchemy import Column, ForeignKey, Integer
from sqlalchemy.ext.declarative import declared_attr
from sqlalchemy.orm import relationship
class AuditMixin(object):
@declared_attr
def created_by_fk(cls):
return Column(
Integer, ForeignKey("fa_user.id"), default=cls.get_user_id, nullable=False
)
@declared_attr
def created_by(cls):
return relationship(
"User",
primaryjoin="%s.created_by_fk == User.id" % cls.__name__,
enable_typechecks=False,
)
@classmethod
def get_user_id(cls):
try:
return g.user.id
except Exception:
return None
It seems there is no object like g
in FastAPI.
Is there a way to get this AuditMixin
to work in FastAPI?
Issue Analytics
- State:
- Created 3 years ago
- Comments:6 (1 by maintainers)
Top Results From Across the Web
How do I use Mixins with SQLAlchemy to simplify querying ...
from sqlalchemy import Column, Integer, String from ; import declarative_base Base = declarative_base() class MyClass ; Base): id = Column(Integer ...
Read more >Mixin and Custom Base Classes
Where above, the class MyModel will contain an “id” column as the primary key, a __tablename__ attribute that derives from the name of...
Read more >Are Python mixins an anti-pattern?
Now if you could show a case where you want common features across classes but do not want a common base class, that's...
Read more >Implementing the "Soft Delete" Pattern with Flask and ...
What I want to do now, is allow users to delete their accounts. Physically deleting users from the database is not a great...
Read more >Multiple inheritance and mixin classes in Python
To discuss mixins we need to start from one of the most controversial ... Please note that this doesn't even take into account...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
I have never used Flask-appbuilder, but from your code, I see it uses
g
, the global thread local proxy object from Flask.I imagine Flask-appbuilder sets the “current user” in it, but I don’t know how. It probably reads authentication details from a cookie, a JWT token, or some other specific method, then it probably verifies it, extracts some ID, and gets the user record from the DB with that ID. Or something similar.
FastAPI doesn’t make any compromise on which DB, ORM, nor specific authentication method you use, but you can integrate anything you want.
In FastAPI there are no global proxy objects, you access the data directly. To get the current user you would probably read the cookie, JWT, or method you chose in a dependency, then verify it, and then get the user from the DB using those credentials. You could probably do all that in dependencies. And that way the data that you require (e.g. JWT tokens using OAuth2) will be integrated into OpenAPI and the docs UI.
To read more about a similar example, check the docs here for SQL DBs with SQLAlchemy: https://fastapi.tiangolo.com/tutorial/sql-databases/
And the docs for dependencies and auth stuff here: https://fastapi.tiangolo.com/tutorial/security/get-current-user/
You would probably take that out of your custom class and put it in a simple function to be used as a dependency. And then you would get the current user with it.
@tiangolo Thanks for your reply. I didn’t realize I can access the parameter of request with the method in a class. So I need to have a parameter with the same name like
current_user
in every request when I need to create a new instance of the audited class. Or set a variable likerequest.state.current_user
inside a middleware as @maverick42 suggests.