fastapi-extra 0.1.5__cp312-cp312-win_amd64.whl → 0.1.6__cp312-cp312-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
fastapi_extra/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
- __version__ = "0.1.5"
1
+ __version__ = "0.1.6"
2
2
 
3
3
 
4
4
  from fastapi import FastAPI
@@ -1,10 +1,8 @@
1
1
  __author__ = "ziyan.yin"
2
2
  __date__ = "2025-01-10"
3
3
 
4
- from .redis import Redis, RedisCli, RedisMaker
4
+ from .redis import DefaultRedis as Redis
5
5
 
6
6
  __all__ = [
7
- "Redis",
8
- "RedisMaker",
9
- "RedisCli"
7
+ "Redis"
10
8
  ]
@@ -8,6 +8,7 @@ from fastapi.params import Depends
8
8
  from pydantic import BaseModel, Field, RedisDsn
9
9
  from redis.asyncio import ConnectionPool, Redis
10
10
 
11
+ from fastapi_extra.dependency import AbstractWidget
11
12
  from fastapi_extra.settings import Settings
12
13
 
13
14
 
@@ -21,32 +22,38 @@ class DefaultRedisSettings(Settings):
21
22
  redis: RedisConfig
22
23
 
23
24
 
24
- def load_pool(config: RedisConfig) -> ConnectionPool:
25
- return ConnectionPool.from_url(
26
- config.url,
27
- **config.model_dump(exclude_defaults=True, exclude={"url", "connection_kwargs"}),
28
- **config.connection_kwargs
29
- )
25
+ _settings = DefaultRedisSettings() # type: ignore
26
+ _loaded_pools: list[ConnectionPool] = []
30
27
 
31
28
 
32
- _settings = DefaultRedisSettings() # type: ignore
33
- DEFAULT_POOL = load_pool(_settings.redis)
29
+ class RedisCli(AbstractWidget):
30
+ default_config = _settings.redis
31
+
32
+
33
+ def __init__(self):
34
+ self._pool = None
35
+
36
+ @property
37
+ def pool(self) -> ConnectionPool:
38
+ if not self._pool:
39
+ self._pool = ConnectionPool.from_url(
40
+ self.default_config.url,
41
+ **self.default_config.model_dump(exclude_defaults=True, exclude={"url", "connection_kwargs"}),
42
+ **self.default_config.connection_kwargs
43
+ )
44
+ _loaded_pools.append(self)
45
+ return self._pool
34
46
 
35
47
 
36
48
  async def dispose() -> None:
37
- await DEFAULT_POOL.aclose()
49
+ for redis_pool in _loaded_pools:
50
+ redis_pool.aclose()
38
51
 
39
52
 
40
- class RedisMaker(Depends):
41
-
42
- def __init__(self, pool: ConnectionPool):
43
- super().__init__()
44
- self.dependency = self
45
- self.pool = pool
46
-
47
- async def __call__(self) -> AsyncGenerator[Redis, None]:
48
- async with Redis(connection_pool=self.pool) as session:
49
- yield session
53
+
54
+ async def get_redis(redis_cli: RedisCli) -> AsyncGenerator[Redis, None]:
55
+ async with Redis(connection_pool=redis_cli.pool) as redis:
56
+ yield redis
50
57
 
51
58
 
52
- RedisCli = Annotated[Redis, RedisMaker(DEFAULT_POOL)]
59
+ DefaultRedis = Annotated[Redis, Depends(get_redis)]
Binary file
@@ -4,14 +4,11 @@ __date__ = "2025-01-05"
4
4
 
5
5
  from fastapi_extra.database.model import SQLBase
6
6
  from fastapi_extra.database.service import ModelService
7
- from fastapi_extra.database.session import AsyncSessionMaker
8
7
  from fastapi_extra.database.session import DefaultSession as Session
9
- from fastapi_extra.database.session import SessionMaker
10
8
 
11
9
  __all__ = [
12
10
  "AsyncSessionMaker",
13
11
  "ModelService",
14
12
  "Session",
15
- "SessionMaker",
16
13
  "SQLBase"
17
14
  ]
@@ -0,0 +1,81 @@
1
+ __author__ = "ziyan.yin"
2
+ __date__ = "2024-12-26"
3
+
4
+
5
+ from typing import Literal
6
+
7
+ from pydantic import AnyUrl, BaseModel, Field
8
+ from sqlalchemy import Engine, NullPool
9
+ from sqlalchemy.ext.asyncio import AsyncEngine
10
+ from sqlalchemy.util import _concurrency_py3k
11
+ from sqlmodel import Session, create_engine
12
+ from sqlmodel.ext.asyncio.session import AsyncSession
13
+
14
+ from fastapi_extra.dependency import AbstractWidget
15
+ from fastapi_extra.settings import Settings
16
+
17
+
18
+ class DatabaseConfig(BaseModel):
19
+ url: AnyUrl
20
+ echo: bool = False
21
+ echo_pool: bool = False
22
+ isolation_level: Literal[
23
+ "SERIALIZABLE",
24
+ "REPEATABLE READ",
25
+ "READ COMMITTED",
26
+ "READ UNCOMMITTED",
27
+ "AUTOCOMMIT",
28
+ ] | None = None
29
+ options: dict = Field(default_factory=dict)
30
+
31
+
32
+ class DefaultDatabaseSettings(Settings):
33
+ datasource: DatabaseConfig
34
+
35
+
36
+ _settings = DefaultDatabaseSettings() # type: ignore
37
+ _loaded_engines: list[Engine] = []
38
+
39
+
40
+ class DB(AbstractWidget):
41
+ default_config = _settings.datasource
42
+ default_options = {}
43
+
44
+ def __init__(self):
45
+ self._engine = None
46
+
47
+ @property
48
+ def engine(self) -> Engine:
49
+ if not self._engine:
50
+ self._engine = create_engine(
51
+ url=str(self.default_config.url),
52
+ **self.default_config.model_dump(exclude_defaults=True, exclude={"url", "options"}),
53
+ **self.default_config.options,
54
+ **self.default_options
55
+ )
56
+ _loaded_engines.append(self._engine)
57
+ return self._engine
58
+
59
+ @property
60
+ def session(self) -> Session:
61
+ return Session(self.engine)
62
+
63
+
64
+ class AsyncDB(DB):
65
+
66
+ @property
67
+ def engine(self) -> AsyncEngine:
68
+ return AsyncEngine(super().engine)
69
+
70
+ @property
71
+ def session(self) -> AsyncSession:
72
+ return AsyncSession(self.engine)
73
+
74
+
75
+ if _settings.mode == "test":
76
+ DB.default_options = {"poolclass": NullPool}
77
+
78
+
79
+ async def dispose() -> None:
80
+ for engine in _loaded_engines:
81
+ await _concurrency_py3k.greenlet_spawn(engine.dispose)
@@ -5,35 +5,20 @@ __date__ = "2025-01-05"
5
5
  from typing import Annotated, AsyncGenerator, Generator
6
6
 
7
7
  from fastapi.params import Depends
8
- from sqlalchemy.ext.asyncio import AsyncEngine
9
- from sqlmodel import Session as _Session
8
+ from sqlmodel import Session
10
9
  from sqlmodel.ext.asyncio.session import AsyncSession
11
10
 
12
- from fastapi_extra.database.engine import DEFAULT_ENGINE, Engine
11
+ from fastapi_extra.database.driver import DB, AsyncDB
13
12
 
14
13
 
15
- class SessionMaker(Depends):
16
- __slots__ = ("engine", )
17
-
18
- def __init__(self, engine: Engine):
19
- super().__init__()
20
- self.engine = engine
21
- self.dependency = self
14
+ async def get_async_session(db: AsyncDB) -> AsyncGenerator[AsyncSession, None]:
15
+ async with db.session as session:
16
+ yield session
22
17
 
23
- def __call__(self) -> Generator[_Session, None, None]:
24
- with _Session(self.engine) as session:
25
- yield session
26
18
 
19
+ def get_session(db: DB) -> Generator[Session, None, None]:
20
+ with db.session as session:
21
+ yield session
27
22
 
28
- class AsyncSessionMaker(SessionMaker):
29
-
30
- def __init__(self, engine: Engine):
31
- super().__init__(engine)
32
- self.async_engine: AsyncEngine = AsyncEngine(self.engine)
33
-
34
- async def __call__(self) -> AsyncGenerator[AsyncSession, None]:
35
- async with AsyncSession(self.async_engine) as session:
36
- yield session
37
-
38
23
 
39
- DefaultSession = Annotated[AsyncSession, AsyncSessionMaker(DEFAULT_ENGINE)]
24
+ DefaultSession = Annotated[AsyncSession, Depends(get_async_session)]
Binary file
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: fastapi-extra
3
- Version: 0.1.5
3
+ Version: 0.1.6
4
4
  Summary: extra package for fastapi.
5
5
  Author-email: Ziyan Yin <408856732@qq.com>
6
6
  License: BSD-3-Clause
@@ -0,0 +1,23 @@
1
+ fastapi_extra/__init__.py,sha256=s2AZTyatkiSeY9OmuW6p45fFgX9Dz_nVH0jV8ut52q0,286
2
+ fastapi_extra/cursor.cp312-win_amd64.pyd,sha256=IWj0owGMJBYMGeuU-MXPSVRwUCt1hwrlJoqnp97OBNk,57344
3
+ fastapi_extra/dependency.py,sha256=Pgl4Y9Mm6JY5pw19w_xJEmnnLkQ9p_K1h1w9lLVHUJQ,907
4
+ fastapi_extra/form.py,sha256=LikaJkA16dSRGCqX9K7z2S8-e3SJcMiVXX5nRZU_kVY,957
5
+ fastapi_extra/response.py,sha256=DHvhOSgwot5eBNKuI_jPYxZ5rshZ55Xkg-FNBJlHD1E,9609
6
+ fastapi_extra/routing.cp312-win_amd64.pyd,sha256=to_HPQbAav7fTQeOYYaFT9zb1b4qdABNkWqQb1uDZdo,94720
7
+ fastapi_extra/settings.py,sha256=cCcwaper5GiNNoT4gNKqf-iloSOTNnMsiUR0knJx4Mw,1461
8
+ fastapi_extra/types.py,sha256=EUjT9jFryzlazHvWs4m-IfUezmSEvyxwaOGe_vTTBnY,763
9
+ fastapi_extra/utils.py,sha256=tsPX3kpF_P5D9Bd3gnlG6rkVsLkv5gbxjml-s6ZL_6I,346
10
+ fastapi_extra/cache/__init__.py,sha256=2bwWFRf6giDo0QiFWEvekQwga9kGTK_9BJdxe32Nru8,126
11
+ fastapi_extra/cache/redis.py,sha256=N4ntWFNjW1w3OJB64AYSrXbLumPUPK9j2iQcfXxJTC8,1586
12
+ fastapi_extra/database/__init__.py,sha256=B59umaoNjDuXyoNh7EYWYEk4xr9tfgVjXsSaOPz3y_Q,328
13
+ fastapi_extra/database/driver.py,sha256=VOJxRtXusuRyOJHMHLu18ZYbPQtoIbrkQyyADpHs9cA,2146
14
+ fastapi_extra/database/model.py,sha256=icHh6tnVKYVGl0hNX6pYypTiyGQt3g41geOkjBZTTv4,2467
15
+ fastapi_extra/database/service.py,sha256=efDZuz__RqEom-UZHfKQ3rHkxnEYmQocWduVbm3rcy0,1478
16
+ fastapi_extra/database/session.py,sha256=XZ5DfkDn4rHHqdJwhRDP87VPDcycxrq6-j_mu4w9Ou0,633
17
+ fastapi_extra/native/cursor.pyx,sha256=bESprFDgk9gGjyPQ4YCSg51dov2WB6s60XrOs3r5-r0,1146
18
+ fastapi_extra/native/routing.pyx,sha256=GrdGAoBospwCpxMHBon5cuRYcz9ifAFSSYa2Ytf49lg,3841
19
+ fastapi_extra-0.1.6.dist-info/LICENSE,sha256=0vTjHDa3VDsxTT-R-sH6SpYcA2F1hKtbX9ZFZQm-EcU,1516
20
+ fastapi_extra-0.1.6.dist-info/METADATA,sha256=U2HYhcc5OTpOGcN5-hOdLXJ4pEIbzqMk5FC5C62lAX0,1348
21
+ fastapi_extra-0.1.6.dist-info/WHEEL,sha256=cRmSBGD-cl98KkuHMNqv9Ac9L9_VqTvcBYwpIvxN0cg,101
22
+ fastapi_extra-0.1.6.dist-info/top_level.txt,sha256=B7D80bEftE2E-eSd1be2r9BWkLLMZN21dRTWpb4y4Ig,14
23
+ fastapi_extra-0.1.6.dist-info/RECORD,,
@@ -1,50 +0,0 @@
1
- __author__ = "ziyan.yin"
2
- __date__ = "2024-12-26"
3
-
4
-
5
- from typing import Any, Literal
6
-
7
- from pydantic import AnyUrl, BaseModel, Field
8
- from sqlalchemy import Engine, NullPool
9
- from sqlalchemy.util import _concurrency_py3k
10
- from sqlmodel import create_engine
11
-
12
- from fastapi_extra.settings import Settings
13
-
14
-
15
- class DatabaseConfig(BaseModel):
16
- url: AnyUrl
17
- echo: bool = False
18
- echo_pool: bool = False
19
- isolation_level: Literal[
20
- "SERIALIZABLE",
21
- "REPEATABLE READ",
22
- "READ COMMITTED",
23
- "READ UNCOMMITTED",
24
- "AUTOCOMMIT",
25
- ] | None = None
26
- options: dict = Field(default_factory=dict)
27
-
28
-
29
- class DefaultDatabaseSettings(Settings):
30
- datasource: DatabaseConfig
31
-
32
-
33
- def load_engine(config: DatabaseConfig, **kw: Any) -> Engine:
34
- return create_engine(
35
- url=str(config.url),
36
- **config.model_dump(exclude_defaults=True, exclude={"url", "options"}),
37
- **config.options,
38
- **kw
39
- )
40
-
41
-
42
- _settings = DefaultDatabaseSettings() # type: ignore
43
- if _settings.mode == "test":
44
- DEFAULT_ENGINE: Engine = load_engine(_settings.datasource, poolclass=NullPool)
45
- else:
46
- DEFAULT_ENGINE: Engine = load_engine(_settings.datasource)
47
-
48
-
49
- async def dispose() -> None:
50
- await _concurrency_py3k.greenlet_spawn(DEFAULT_ENGINE.dispose)
@@ -1,23 +0,0 @@
1
- fastapi_extra/__init__.py,sha256=lG8uGj4bf5IlFbIznHTkpa5IGXFcxcBfCa2x-b_HhXY,286
2
- fastapi_extra/cursor.cp312-win_amd64.pyd,sha256=kWtFGDu_zSoytLufV74NuUciTAasxrJ73d5SlDpPWVo,57344
3
- fastapi_extra/dependency.py,sha256=Pgl4Y9Mm6JY5pw19w_xJEmnnLkQ9p_K1h1w9lLVHUJQ,907
4
- fastapi_extra/form.py,sha256=LikaJkA16dSRGCqX9K7z2S8-e3SJcMiVXX5nRZU_kVY,957
5
- fastapi_extra/response.py,sha256=DHvhOSgwot5eBNKuI_jPYxZ5rshZ55Xkg-FNBJlHD1E,9609
6
- fastapi_extra/routing.cp312-win_amd64.pyd,sha256=LSLlg7Ld5TtvJ46jhobMRuCCk5tsZqu6kcA86_J4Zk4,94720
7
- fastapi_extra/settings.py,sha256=cCcwaper5GiNNoT4gNKqf-iloSOTNnMsiUR0knJx4Mw,1461
8
- fastapi_extra/types.py,sha256=EUjT9jFryzlazHvWs4m-IfUezmSEvyxwaOGe_vTTBnY,763
9
- fastapi_extra/utils.py,sha256=tsPX3kpF_P5D9Bd3gnlG6rkVsLkv5gbxjml-s6ZL_6I,346
10
- fastapi_extra/cache/__init__.py,sha256=pg3VTyLBPy3j1pop_RSGLhaQqnUSNv0oznaOSjxM9rw,168
11
- fastapi_extra/cache/redis.py,sha256=6QNicKfn8_zkbL0m-mVAWcv5UrAbmH_ZZWz8xA7ES_w,1352
12
- fastapi_extra/database/__init__.py,sha256=GIWWUF-diioMsKW63x6lKpLWaRPCwTCZtr8n-EX3twc,468
13
- fastapi_extra/database/engine.py,sha256=vENq4-3mern_Nvd2n0GC5VeEvL6Ruv7uxutMBDpEJA8,1335
14
- fastapi_extra/database/model.py,sha256=icHh6tnVKYVGl0hNX6pYypTiyGQt3g41geOkjBZTTv4,2467
15
- fastapi_extra/database/service.py,sha256=efDZuz__RqEom-UZHfKQ3rHkxnEYmQocWduVbm3rcy0,1478
16
- fastapi_extra/database/session.py,sha256=KlzsZMQ1sHnUnYwLcI7AxY31vusmn_6aBT_YhsECQic,1152
17
- fastapi_extra/native/cursor.pyx,sha256=bESprFDgk9gGjyPQ4YCSg51dov2WB6s60XrOs3r5-r0,1146
18
- fastapi_extra/native/routing.pyx,sha256=GrdGAoBospwCpxMHBon5cuRYcz9ifAFSSYa2Ytf49lg,3841
19
- fastapi_extra-0.1.5.dist-info/LICENSE,sha256=0vTjHDa3VDsxTT-R-sH6SpYcA2F1hKtbX9ZFZQm-EcU,1516
20
- fastapi_extra-0.1.5.dist-info/METADATA,sha256=5QzhRf1SGhVn8SHL35vQepsAbEREiOGoYzhAo4ambkk,1348
21
- fastapi_extra-0.1.5.dist-info/WHEEL,sha256=cRmSBGD-cl98KkuHMNqv9Ac9L9_VqTvcBYwpIvxN0cg,101
22
- fastapi_extra-0.1.5.dist-info/top_level.txt,sha256=B7D80bEftE2E-eSd1be2r9BWkLLMZN21dRTWpb4y4Ig,14
23
- fastapi_extra-0.1.5.dist-info/RECORD,,