question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[QUESTION] how to have sqlalchemy mixins that need user id?

See original GitHub issue

First 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:closed
  • Created 3 years ago
  • Comments:6 (1 by maintainers)

github_iconTop GitHub Comments

2reactions
tiangolocommented, Jun 4, 2020

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.

1reaction
shizidushucommented, Jun 6, 2020

@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 like request.state.current_user inside a middleware as @maverick42 suggests.

Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found