Comments (10)
I created a pull request that gets at this from a slightly different angle (#570). It supports functions similar to contextmanager-decorated functions or pytest yield fixtures. These can be easily used with enter and exit (and the async equivalents) by yielding inside the with statement.
I’m still working on docs for the pull request but I’ll include examples along the lines described above.
from fastapi.
Implemented in version 0.42.0 #595
Docs: https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-with-yield/
Thank you guys. It looks awesome!
from fastapi.
Sounds like a good idea. I don't particularly like having such a long list of arguments for the path functions, though. It will be easy to end up with something like this:
@app.get("/groups/{group_id}/user/{user_id}")
def read_user(group_id: int, user_id: int, request: Request, current_user: User = Depends(get_current_active_user), db_session: Session = Depends(db)):
...
from fastapi.
Great ideas!
Actually, I was thinking on adding it or something similar :)
I was thinking on vanilla context managers, classes with "dunder" methods, without @contextmanager
, as it is only available in 3.7 and FastAPI is compatible with 3.6.
I agree using request.state.db
is not ideal, as the typing is lost, etc. For that, I just updated the tutorial to have a dependency that extracts the DB from the request: https://fastapi.tiangolo.com/tutorial/sql-databases/
This doesn't solve having a session in requests that didn't need them, but at least is cleaner for bigger applications.
I also created a project generator with this style, for FastAPI with PostgreSQL, you might wanna check it out: https://github.com/tiangolo/full-stack-fastapi-postgresql
Coming back to the context managers, I would like to have them. I would prefer them both handled by Depends
, but I think there are a couple of things that need to be taken care of/analyzed.
For example, right now, the dependency management handles a tree of dependencies, but if two dependencies require a DB connection, having a single dependency that provides it, would create 2 DB sessions, as the solved dependencies are not re-used (yet). If we solve it, by having a cache of already solved dependencies, the dependency injection system would be able to handle DAGs (directed acyclic graphs), a lot more powerful than only trees. That would allow us having a DB dependency that can be required by several points in the dependency chain/graph/tree but that re-uses the same connection for the same request.
from fastapi.
Glad you liked the idea.
Yeah, adding Depends()
to extract session from request.state
is a great idea - at least if one forgets to add a middleware it will fail early.
Back to the discussion...
I'm not sure that going with DAG it justified at this stage (at least most of my microservices have very simple requirements with regards to DI). The current DI is very light both API and implementation wise,
and if one uses his own "full-fledged" DI, he/she can easily integrate it with FastAPI.
To utilize caching I think you need to start distinguishing between Services and Factories (to cache the former but not the latter). And then it may start to look like "full-fledged" DI, which can deserve a project of its own. On the other hand, DI design pattern is not very popular in Python world AFAIK so may be FastAPI shouldn't go there as well.
My bottom line - lets follow agile philosophy. Stay with trees and see when the DAG user story comes in. If an injectable is essentially implemented as Service, there is no real performance penalty to resolve it twice, so I think trees are good enough, at least for me :)
Regarding using Depends
for both - can you share your ideas on how to do it? When Depends
resolves whatever was passed to it, it needs to deduce whether it should treat it as context manager or callable - and whatever you pass can be both. I can think of:
- Requiring
Depends
argument to be either callable or context manager - Providing
Depends
with a hint that passed arg should be treated as a context manager:Depends(get_db, ctx_mgr=True)
Option one sounds a bit limiting to me.
P.S. Is there any particular reason you are holding on to Python 3.6? - This project is young, and it's a great advantage to be able to use the latest tech from upstream Python.
P.P.S At worst case, AsyncExitStack can be borrowed from upstream. It's just 130 LOC :)
from fastapi.
Sorry for the delay.
I agree, good idea to keep it agile and see what we are actually needing.
It needs to deduce whether it should treat it as context manager or callable [...]
What I would do, is check first if the object has __enter__
and __exit__
, and then treat is a context manager, as that would be the "strange" case, it wouldn't be easy for a normal dependency to have those attributes, so then, default to standard dependency injection.
This is is somewhat similar to how the default parameter inference is done:
First, check if it's part of the path, it's just path. Then if it's a scalar value, it's a query param. Then if it's the Request
or BackgroundTasks
object, it's those two things, and then, otherwise, it is a body. All that overridden by explicit declarations of Query
, Body
, File
, etc.
I'm holding to Python 3.6 to be compatible with libraries like TensorFlow and Celery, that currently don't have versions for Python 3.7 :)
I think the current state of the system works well enough for us all, with the middleware and dependency trick. Let's see if we find a strong need for context managers later, as it would probably require quite some work.
from fastapi.
What I would do, is check first if the object has enter and exit
Or __aenter__
and __aexit__
.
I'm holding to Python 3.6 to be compatible with libraries like TensorFlow and Celery, that currently
don't have versions for Python 3.7 :)
Got it, thank you.
Let's see if we find a strong need for context managers later, as it would probably require quite some work.
I'll take it as "PR's welcome" in case I'll get to it :)
from fastapi.
Or aenter and aexit.
Yep, good point.
I'll take it as "PR's welcome" in case I'll get to it :)
Hehe, yep 😉 I still can do it, but as you said, let's keep it agile and see if we (or someone) actually need it.
from fastapi.
HI all ! I am looking for this feature, exactly for the same example given by @haizaar.
Is there something planned to implement this feature ?
from fastapi.
from fastapi.
Related Issues (20)
- No streaming interface can not support concurrency for two fastapi servers
- Using pydantic Json Type as Form data type doesn't work HOT 1
- Raw docstring (leading `r`) defeats form feed `\f` truncation HOT 3
- OpenAPI Example with multipart/form-data not showing up HOT 5
- [BUG] Using Nested Pydantic models and `params: MyModel = Depends()` forces OpenAPI docs GET methods to require a request body. HOT 6
- How to fix this bug? HOT 2
- [BUG] Upgrade python-mulipart==0.0.7 from low version fastapi upload file may be 400 HOT 4
- Use `RootModel` as query parameter HOT 2
- Context managers in `Depends` are broken after 0.106 HOT 16
- Middleware runs twice HOT 8
- Support for Pydantic deprecated fields HOT 1
- axios can't receive error response status code
- Potential footgun when using custom `Response(background=<Task()>)` in conjunction with injected `BackgroundTasks` - the custom response overwrites the tasks HOT 3
- lifespan
- Breaking change with path parameters when updating to pydantic>=2 from pydantic<2 HOT 1
- trying to live video stream using Fastapi
- Package on test.pypi.org is broken
- middleware type
- It throws an exception when I specify return Http status code
- When backend restart the frontend request a protected api cause an unhandle exception: Exception in ASGI application HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from fastapi.