11import abc
22import asyncio
33import functools
4+ import warnings
45from typing import Callable , Dict , TypeVar , Union
56
67from sqlalchemy .ext .asyncio import AsyncEngine
@@ -85,17 +86,15 @@ def __init__(self, engine: Union[Engine, AsyncEngine], *args, **kwargs) -> None:
8586 setattr (self , f"async_{ func_name } " , func )
8687
8788 async def asgi_dispatch (self , request , call_next ):
88- """Middleware for ASGI applications, such as: Starlette, FastAPI, Quart, Sanic, Hug, Responder, etc.
89- Bind a SQLAlchemy session connection to the incoming HTTP request session context,
90- you can access the session object through `self.session`.
91- The instance shortcut method will also try to use this `session` object by default.
92- Example:
93- ```Python
94- app = FastAPI()
95- db = Database.create("sqlite:///test.db")
96- app.add_middleware(BaseHTTPMiddleware, dispatch=db.asgi_dispatch)
97- ```
9889 """
90+ This method has been deprecated and is not recommended. Please use the `asgi_middleware` method instead.
91+ Reference: https://www.starlette.io/middleware/#limitations
92+ """
93+ # 打印警告信息
94+ warnings .warn (
95+ "This method has been deprecated and is not recommended. Please use the `asgi_middleware` method instead." ,
96+ DeprecationWarning ,
97+ )
9998 if request .scope .get (f"__sqlalchemy_database__:{ id (self )} " , False ):
10099 return await call_next (request )
101100 # bind session to request
@@ -112,6 +111,32 @@ def attach_middleware(self, app):
112111 db.attach_middlewares(app)
113112 ```
114113 """
115- from starlette .middleware .base import BaseHTTPMiddleware
114+ app .add_middleware (self .asgi_middleware )
115+
116+ @property
117+ def asgi_middleware (self ):
118+ """Middleware for ASGI applications, such as: Starlette, FastAPI, Quart, Sanic, Hug, Responder, etc.
119+ Bind a SQLAlchemy session connection to the incoming HTTP request session context,
120+ you can access the session object through `self.session`.
121+ The instance shortcut method will also try to use this `session` object by default.
122+ Example:
123+ ```Python
124+ app = FastAPI()
125+ db = Database.create("sqlite:///test.db")
126+ app.add_middleware(db.asgi_middleware)
127+ ```
128+ """
129+
130+ def asgi_decorator (app ):
131+ @functools .wraps (app )
132+ async def wrapped_app (scope , receive , send ):
133+ if scope .get (f"__sqlalchemy_database__:{ id (self )} " , False ):
134+ return await app (scope , receive , send )
135+ # bind session to request
136+ async with self .__call__ (scope = id (scope )):
137+ scope [f"__sqlalchemy_database__:{ id (self )} " ] = self
138+ await app (scope , receive , send )
139+
140+ return wrapped_app
116141
117- app . add_middleware ( BaseHTTPMiddleware , dispatch = self . asgi_dispatch )
142+ return asgi_decorator
0 commit comments