fastapi-startkit-auth 0.3.0__py3-none-any.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.
Files changed (57) hide show
  1. fastapi_startkit_auth/__init__.py +67 -0
  2. fastapi_startkit_auth/apitokens/__init__.py +13 -0
  3. fastapi_startkit_auth/apitokens/manager.py +122 -0
  4. fastapi_startkit_auth/apitokens/models.py +29 -0
  5. fastapi_startkit_auth/apitokens/repository.py +120 -0
  6. fastapi_startkit_auth/apitokens/sql.py +152 -0
  7. fastapi_startkit_auth/application.py +38 -0
  8. fastapi_startkit_auth/clients/__init__.py +4 -0
  9. fastapi_startkit_auth/clients/models.py +29 -0
  10. fastapi_startkit_auth/clients/repository.py +69 -0
  11. fastapi_startkit_auth/config.py +103 -0
  12. fastapi_startkit_auth/dependencies.py +93 -0
  13. fastapi_startkit_auth/exceptions.py +90 -0
  14. fastapi_startkit_auth/facade.py +107 -0
  15. fastapi_startkit_auth/grants/__init__.py +13 -0
  16. fastapi_startkit_auth/grants/authorization_code.py +83 -0
  17. fastapi_startkit_auth/grants/client_credentials.py +19 -0
  18. fastapi_startkit_auth/grants/password.py +32 -0
  19. fastapi_startkit_auth/grants/pkce.py +27 -0
  20. fastapi_startkit_auth/grants/refresh.py +13 -0
  21. fastapi_startkit_auth/guards/__init__.py +5 -0
  22. fastapi_startkit_auth/guards/guard.py +85 -0
  23. fastapi_startkit_auth/guards/session.py +81 -0
  24. fastapi_startkit_auth/guards/token.py +58 -0
  25. fastapi_startkit_auth/manager.py +320 -0
  26. fastapi_startkit_auth/middleware/__init__.py +4 -0
  27. fastapi_startkit_auth/middleware/csrf.py +160 -0
  28. fastapi_startkit_auth/middleware/session.py +117 -0
  29. fastapi_startkit_auth/passwords/__init__.py +4 -0
  30. fastapi_startkit_auth/passwords/broker.py +69 -0
  31. fastapi_startkit_auth/passwords/repository.py +44 -0
  32. fastapi_startkit_auth/provider.py +69 -0
  33. fastapi_startkit_auth/providers/__init__.py +4 -0
  34. fastapi_startkit_auth/providers/base.py +38 -0
  35. fastapi_startkit_auth/providers/memory.py +69 -0
  36. fastapi_startkit_auth/providers/model.py +70 -0
  37. fastapi_startkit_auth/publishable/cors.py +44 -0
  38. fastapi_startkit_auth/py.typed +0 -0
  39. fastapi_startkit_auth/routes.py +362 -0
  40. fastapi_startkit_auth/routes_spa.py +34 -0
  41. fastapi_startkit_auth/security/__init__.py +4 -0
  42. fastapi_startkit_auth/security/hashing.py +43 -0
  43. fastapi_startkit_auth/security/jwt.py +49 -0
  44. fastapi_startkit_auth/sessions/__init__.py +5 -0
  45. fastapi_startkit_auth/sessions/models.py +29 -0
  46. fastapi_startkit_auth/sessions/sql.py +158 -0
  47. fastapi_startkit_auth/sessions/state.py +11 -0
  48. fastapi_startkit_auth/sessions/store.py +100 -0
  49. fastapi_startkit_auth/startkit.py +38 -0
  50. fastapi_startkit_auth/tokens/__init__.py +9 -0
  51. fastapi_startkit_auth/tokens/models.py +68 -0
  52. fastapi_startkit_auth/tokens/repository.py +129 -0
  53. fastapi_startkit_auth/tokens/service.py +189 -0
  54. fastapi_startkit_auth-0.3.0.dist-info/METADATA +243 -0
  55. fastapi_startkit_auth-0.3.0.dist-info/RECORD +57 -0
  56. fastapi_startkit_auth-0.3.0.dist-info/WHEEL +4 -0
  57. fastapi_startkit_auth-0.3.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,243 @@
1
+ Metadata-Version: 2.4
2
+ Name: fastapi-startkit-auth
3
+ Version: 0.3.0
4
+ Summary: Laravel-style authentication for FastAPI: OAuth2/JWT authorization server, cookie/session guard, SPA + CSRF protection, and Sanctum-style API tokens.
5
+ Keywords: fastapi,oauth2,jwt,auth,passport,sanctum,authentication,authorization,security,tokens,session,cookie,csrf,spa,starter-kit
6
+ Author: Bedram Tamang
7
+ Author-email: Bedram Tamang <tmgbedu@gmail.com>
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Framework :: FastAPI
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Internet :: WWW/HTTP :: Session
21
+ Classifier: Topic :: Security
22
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
+ Requires-Dist: fastapi>=0.110
24
+ Requires-Dist: pyjwt>=2.8
25
+ Requires-Dist: bcrypt>=4.1
26
+ Requires-Dist: pydantic>=2
27
+ Requires-Dist: python-multipart>=0.0.9
28
+ Requires-Dist: masonite-orm>=2.18 ; extra == 'masoniteorm'
29
+ Requires-Dist: fastapi-startkit>=0.51 ; python_full_version >= '3.12' and extra == 'startkit'
30
+ Requires-Dist: pytest>=8 ; extra == 'test'
31
+ Requires-Dist: pytest-asyncio>=0.23 ; extra == 'test'
32
+ Requires-Dist: httpx>=0.27 ; extra == 'test'
33
+ Requires-Python: >=3.9
34
+ Project-URL: Homepage, https://github.com/fastapi-startkit/fastapi-startkit-auth
35
+ Project-URL: Repository, https://github.com/fastapi-startkit/fastapi-startkit-auth
36
+ Project-URL: Issues, https://github.com/fastapi-startkit/fastapi-startkit-auth/issues
37
+ Project-URL: Changelog, https://github.com/fastapi-startkit/fastapi-startkit-auth/releases
38
+ Provides-Extra: masoniteorm
39
+ Provides-Extra: startkit
40
+ Provides-Extra: test
41
+ Description-Content-Type: text/markdown
42
+
43
+ # fastapi-startkit-auth
44
+
45
+ Passport-style OAuth2 + JWT authentication for FastAPI.
46
+
47
+ `fastapi-startkit-auth` brings the ergonomics of [Laravel Passport](https://laravel.com/docs/13.x/passport)
48
+ to FastAPI: a config-driven guard/provider/passwords model layered on top of
49
+ OAuth2 grants and signed JWT access tokens (per the
50
+ [FastAPI security tutorial](https://fastapi.tiangolo.com/tutorial/security/oauth2-jwt/)).
51
+
52
+ ## Features
53
+
54
+ | Area | What you get |
55
+ | --- | --- |
56
+ | **Config layer** | `AuthConfig` (`default` / `guards` / `providers` / `passwords`) + `AuthProvider` that registers into the app |
57
+ | **Password grant** | OAuth2 password grant → signed JWT access tokens with expiry (`/oauth/token`, `/token`) |
58
+ | **Refresh tokens** | Opaque refresh tokens with **rotation** and configurable TTL |
59
+ | **Personal access tokens** | Named, long-lived tokens with scopes/abilities |
60
+ | **Client credentials** | Machine-to-machine grant |
61
+ | **Authorization code + PKCE** | Browser/SPA flow with S256 & plain PKCE |
62
+ | **Clients** | Register / list / delete confidential & public clients |
63
+ | **Revocation & introspection** | RFC 7009 revoke + RFC 7662 introspect |
64
+ | **Password reset** | `password_reset_tokens` flow with configurable `expire` + `throttle` |
65
+ | **Guards & deps** | `current_user`, `optional_user`, `require_scopes` FastAPI dependencies |
66
+ | **Pluggable providers** | In-memory, generic ORM/masoniteorm model, or any custom `UserProvider` |
67
+
68
+ ## Installation
69
+
70
+ ```bash
71
+ pip install fastapi-startkit-auth
72
+ # optional ORM provider driver
73
+ pip install "fastapi-startkit-auth[masoniteorm]"
74
+ ```
75
+
76
+ > Uses `bcrypt` directly (not `passlib`, which imports the `crypt` stdlib module
77
+ > removed in Python 3.13+), so it runs on modern Python.
78
+
79
+ ## Quickstart
80
+
81
+ ```python
82
+ from fastapi import Depends
83
+ from fastapi_startkit_auth import Application, AuthProvider, AuthConfig, current_user, require_scopes
84
+ from myapp.models import User # any active-record-style model
85
+
86
+
87
+ class Config(AuthConfig):
88
+ key = "change-me-to-a-long-random-secret" # JWT signing key
89
+
90
+ default = {"guard": "api", "passwords": "users"}
91
+ guards = {"api": {"driver": "passport", "provider": "users"}}
92
+ providers = {"users": {"driver": "masoniteorm", "model": User}}
93
+ passwords = {
94
+ "users": {"provider": "users", "table": "password_reset_tokens",
95
+ "expire": 60, "throttle": 60},
96
+ }
97
+
98
+
99
+ app = Application([(AuthProvider, Config)])
100
+ api = app.api # the underlying FastAPI instance
101
+
102
+
103
+ @api.get("/me")
104
+ def me(user=Depends(current_user)):
105
+ return user
106
+
107
+
108
+ @api.get("/reports")
109
+ def reports(ctx=Depends(require_scopes("reports:read"))):
110
+ return {"ok": True}
111
+ ```
112
+
113
+ Serve it:
114
+
115
+ ```bash
116
+ uvicorn myapp:app # Application is ASGI-callable
117
+ uvicorn myapp:app.api # or serve the FastAPI instance directly
118
+ ```
119
+
120
+ ## Configuration
121
+
122
+ `AuthConfig` mirrors Laravel's `config/auth.php` and adds JWT/token knobs:
123
+
124
+ ```python
125
+ class AuthConfig:
126
+ default = {"guard": "api", "passwords": "users"}
127
+ guards = {"api": {"driver": "passport", "provider": "users"}}
128
+ providers = {"users": {"driver": "masoniteorm", "model": User}}
129
+ passwords = {"users": {"provider": "users", "table": "password_reset_tokens",
130
+ "expire": 60, "throttle": 60}}
131
+
132
+ # token settings (all optional, sensible defaults shown)
133
+ key = None # JWT secret (required in production)
134
+ algorithm = "HS256"
135
+ access_token_ttl = 3600 # seconds
136
+ refresh_token_ttl = 60 * 60 * 24 * 14
137
+ personal_access_token_ttl = 60 * 60 * 24 * 365
138
+ authorization_code_ttl = 600
139
+ bcrypt_rounds = 12
140
+ ```
141
+
142
+ ### Provider drivers
143
+
144
+ | driver | meaning |
145
+ | --- | --- |
146
+ | `masoniteorm` / `orm` / `model` | wrap a model exposing `find(id)` and `where(field, value).first()` |
147
+ | `memory` | in-memory dict store (`users=[...]`) — great for tests/demos |
148
+ | `instance` | pass a ready `UserProvider` via `{"instance": ...}` |
149
+ | `factory` | pass a zero-arg callable returning a `UserProvider` |
150
+
151
+ Any object implementing the `UserProvider` protocol
152
+ (`retrieve_by_id`, `retrieve_by_credentials`, `validate_credentials`,
153
+ `get_identifier`, `update_password`) is a valid provider.
154
+
155
+ ## HTTP endpoints
156
+
157
+ | Method & path | Purpose |
158
+ | --- | --- |
159
+ | `POST /oauth/token` | Unified token endpoint: `password`, `refresh_token`, `client_credentials`, `authorization_code` |
160
+ | `POST /token` | Simple password grant (FastAPI-tutorial style) |
161
+ | `POST /oauth/authorize` | Approve an auth-code request (requires an authenticated user) → returns `code` |
162
+ | `POST /oauth/introspect` | RFC 7662 token introspection (**requires client authentication**) |
163
+ | `POST /oauth/revoke` | RFC 7009 access/refresh token revocation (**requires client authentication**) |
164
+ | `POST/GET /oauth/clients`, `DELETE /oauth/clients/{id}` | Client registration & management |
165
+ | `POST/GET /oauth/personal-access-tokens`, `DELETE .../{jti}` | Personal access tokens |
166
+ | `POST /password/email` | Trigger a password-reset token (delivered out-of-band; see below) |
167
+ | `POST /password/reset` | Reset the password with a token |
168
+
169
+ ### Password resets
170
+
171
+ `POST /password/email` always returns the same generic response whether or not
172
+ the account exists (no user enumeration) and **never** puts the token in the
173
+ response body. Configure how the token reaches the user with a notifier:
174
+
175
+ ```python
176
+ class AuthConfig(BaseAuthConfig):
177
+ password_reset_notifier = staticmethod(lambda email, token: send_email(email, token))
178
+ # debug_expose_reset_token = True # DEV ONLY: echo the token in the response
179
+ ```
180
+
181
+ The `code_challenge` for public clients is mandatory — a public (secretless)
182
+ client cannot obtain an authorization code without PKCE, and codes are verified
183
+ against the `code_verifier` at exchange.
184
+
185
+ ### Example: password grant
186
+
187
+ ```bash
188
+ curl -X POST localhost:8000/oauth/token \
189
+ -d grant_type=password -d username=ada@example.com -d password=secret -d scope="read write"
190
+ # → { "access_token": "...", "token_type": "Bearer", "expires_in": 3600,
191
+ # "refresh_token": "...", "scope": "read write" }
192
+ ```
193
+
194
+ ### Example: authorization code + PKCE
195
+
196
+ 1. `POST /oauth/authorize` with a bearer token and `code_challenge` → returns a single-use `code`.
197
+ 2. `POST /oauth/token` with `grant_type=authorization_code`, the `code`, and the `code_verifier`.
198
+
199
+ ## Scopes / abilities
200
+
201
+ Tokens carry scopes; enforce them with the `require_scopes` dependency:
202
+
203
+ ```python
204
+ require_scopes("posts:write") # must have this scope
205
+ require_scopes("a", "b") # must have all
206
+ require_scopes("a", "b", mode="any") # must have at least one
207
+ ```
208
+
209
+ `*` is a wildcard scope that satisfies any check. Inside a handler you can also
210
+ inspect the `AuthContext` (`ctx.can(...)`, `ctx.can_any(...)`, `ctx.scopes`).
211
+
212
+ ## Testing
213
+
214
+ ```bash
215
+ pip install -e ".[test]"
216
+ pytest
217
+ ```
218
+
219
+ Or with [uv](https://docs.astral.sh/uv/):
220
+
221
+ ```bash
222
+ uv sync --group dev
223
+ uv run pytest
224
+ ```
225
+
226
+ ## Releasing
227
+
228
+ Releases are cut from `main` with the release script (maintainers only):
229
+
230
+ ```bash
231
+ ./bin/release.sh # patch bump
232
+ ./bin/release.sh minor # or: major
233
+ ```
234
+
235
+ The script bumps the version, builds sdist + wheel, validates them with
236
+ `twine check`, uploads to PyPI, then commits, tags `vX.Y.Z`, and creates a
237
+ GitHub release. It requires `uv`, `gh` (authenticated), and PyPI credentials
238
+ for `twine` (e.g. a `pypi-*` API token via `TWINE_USERNAME=__token__` /
239
+ `TWINE_PASSWORD` or `~/.pypirc`).
240
+
241
+ ## License
242
+
243
+ MIT
@@ -0,0 +1,57 @@
1
+ fastapi_startkit_auth/__init__.py,sha256=1ypHry59Yyfl5xXbMVb2jbRnTwCVNmnwPOnaN29s7cM,3340
2
+ fastapi_startkit_auth/apitokens/__init__.py,sha256=zsQKxwUaPQyohbKz5d70q30Gxo4bmEt-h90BY_W3IMM,363
3
+ fastapi_startkit_auth/apitokens/manager.py,sha256=IQ38VzFmIuhBeCiWsy4CBcwv63cc1GfwM0LQqRqnWsQ,4419
4
+ fastapi_startkit_auth/apitokens/models.py,sha256=_U2NbhxzGTeHnGnUQR4VeMsdlQ9DdbfruRzSkp1e7BI,918
5
+ fastapi_startkit_auth/apitokens/repository.py,sha256=Il6M-MM4-n_jlYcX8kItC_1EmrV5HZ6LQKR_chT3TBE,3774
6
+ fastapi_startkit_auth/apitokens/sql.py,sha256=Y8omXmW9xg0EKZobHhyoQCo7nXqWHxyhkyUAh5nvObI,4706
7
+ fastapi_startkit_auth/application.py,sha256=NgO_6d66GBwOfGzYXrIr7sQ5YsL4t1DlG7K9ynYa3u4,1323
8
+ fastapi_startkit_auth/clients/__init__.py,sha256=paTMVVVzZeqbRkMSLpDkVz4ZFNXLcPNKudKhao0h4xY,126
9
+ fastapi_startkit_auth/clients/models.py,sha256=_6RWJsw6XwgE__dFnaN0lHdtE_EbUuCk9JhLyeFi89A,852
10
+ fastapi_startkit_auth/clients/repository.py,sha256=bJS5FvqV7X3c8LVOvCBjoPYhSrRUfwbkszbhKXWgvgw,2194
11
+ fastapi_startkit_auth/config.py,sha256=jGFz2GR40JfoP2kaX7YYVSgTvUZ-X8Y8pMsNkKsMx7I,4505
12
+ fastapi_startkit_auth/dependencies.py,sha256=GkbuyM2gTf2GIc78d0hB2s30I_Av5tKklO53g7FgC-c,3304
13
+ fastapi_startkit_auth/exceptions.py,sha256=z0yUnocN_95lvxVZhq5j85Uql1RY4n6yXHQZpsoqRCc,2255
14
+ fastapi_startkit_auth/facade.py,sha256=n5A9frFBxikDTyoFlO6rXV7lC8vPBDHZLGiGeKXzDjI,3989
15
+ fastapi_startkit_auth/grants/__init__.py,sha256=3oJFX3rN8yIxiT5CJEBCSG_IrCuPqSaDyF7AxXAedOk,355
16
+ fastapi_startkit_auth/grants/authorization_code.py,sha256=RJv3uaritCA-0cLKBeTsOlxmPux_uv60UQNtnxutjTw,3208
17
+ fastapi_startkit_auth/grants/client_credentials.py,sha256=KWP3OTMrGB5AkunpAPUwd5kfe7bXtNPnLO2AY0MyEao,577
18
+ fastapi_startkit_auth/grants/password.py,sha256=z9Y0Us4nZIF_QQoZxQuWG72BuP3pKrJ4UtcPPh16OSs,1402
19
+ fastapi_startkit_auth/grants/pkce.py,sha256=CWfdDWcdIIueYUsS_ZXelcI3o1TBSC4rOjTkYT4Exjg,867
20
+ fastapi_startkit_auth/grants/refresh.py,sha256=k00kTBPRQVUqt1-lDxHyjK3wn2NbubGHI1gK7O2-8bw,454
21
+ fastapi_startkit_auth/guards/__init__.py,sha256=jcIuIEsQZTjVW2b9UZVWvqUqHqUVvV_4exkdOjOWOUI,200
22
+ fastapi_startkit_auth/guards/guard.py,sha256=JGx-k5dKii8E69F2A8wm7KjMgapoWfrISKsLH7l0GNA,2930
23
+ fastapi_startkit_auth/guards/session.py,sha256=PBlBOulTY74znX3Bk4k2nHj4pkEfCHkaNuwzVPdNnd0,3326
24
+ fastapi_startkit_auth/guards/token.py,sha256=cBfGHqNi_dgirE1ylA30hGHy714vv8_TW-tmzCBCLm0,2038
25
+ fastapi_startkit_auth/manager.py,sha256=NFDE6X80lezs1IzgBmQY6z9yCFH07KIMbuO_XJdfoXs,13893
26
+ fastapi_startkit_auth/middleware/__init__.py,sha256=IPU2ueWzRMMy8vqbzU8VLlCN-unh1S52iv-VIe8wrWk,123
27
+ fastapi_startkit_auth/middleware/csrf.py,sha256=5zmz0UqS-VGBkTHNyMRWZ1829AplimMCh4VFcLsxd7I,6244
28
+ fastapi_startkit_auth/middleware/session.py,sha256=gbqfcuIYbEDU1GSskKRUNk9ExDUQrjZysdG4C7-s8eY,4122
29
+ fastapi_startkit_auth/passwords/__init__.py,sha256=rwG43cwCe_XK5MTIXgBS7QWHhgybvEUi8Pu6rtg5XfY,198
30
+ fastapi_startkit_auth/passwords/broker.py,sha256=w5_Gpt8jsmhHbkDW58YGhVs24yykzoHgKZffuQeQO38,2929
31
+ fastapi_startkit_auth/passwords/repository.py,sha256=y9Mx2TmJJ53mMOZZkiq861Mgo2wWNVdreViXEHEu-uE,1264
32
+ fastapi_startkit_auth/provider.py,sha256=HYS11h7h_MV8lXoXA8F9exa7C7DF5acLiCw1Wbjb-bk,2708
33
+ fastapi_startkit_auth/providers/__init__.py,sha256=yX-7Mv0nINduWBcDCQY0tNZ-Ei1FT-6xmiRZN3LNLek,124
34
+ fastapi_startkit_auth/providers/base.py,sha256=Zt7PtHY0iWDyecbtz7kF-tO-SdIDg-99e_rvcmUYzI0,1488
35
+ fastapi_startkit_auth/providers/memory.py,sha256=IRlBc2QZd_n4Y-2J5dKqD2xX6UAk3P6_f6c1NMIpj1E,2551
36
+ fastapi_startkit_auth/providers/model.py,sha256=hplnIKX2xMbSzpsidKno3sgcLc57Wh9dUETMGdika-4,2425
37
+ fastapi_startkit_auth/publishable/cors.py,sha256=rcgH4K7wGhFqM_pjk7aLfzUg60GVOZskEOS3AfJtty0,1415
38
+ fastapi_startkit_auth/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
39
+ fastapi_startkit_auth/routes.py,sha256=Vggj_VEYGecApgEl--7-dm2f1aDLMlhwEsvnkJML3uA,14352
40
+ fastapi_startkit_auth/routes_spa.py,sha256=YSMoQOTU9BRDtcIcU8lc1YMXc3WfFEWtfszD7pWZiTg,1441
41
+ fastapi_startkit_auth/security/__init__.py,sha256=djDbh1s-pHXxaSpzz4htxzfpDf5LFp4n9voK35mm2Hw,122
42
+ fastapi_startkit_auth/security/hashing.py,sha256=DoNBte1krYbKmsgGxzmj3ozzrimYPByNv2FAESsco_U,1302
43
+ fastapi_startkit_auth/security/jwt.py,sha256=HRUU5PFctewSFs3J3NvAYoJPcd15pHf4CgWCjNMNkP0,1568
44
+ fastapi_startkit_auth/sessions/__init__.py,sha256=2itWqr2pE4c68jf5MurjB8O39UxdEalcaYHaS_gqXkY,209
45
+ fastapi_startkit_auth/sessions/models.py,sha256=wS67vZCfmnAM-laO3P0Umh2GKb10fYgzNKDOMdiUk-0,964
46
+ fastapi_startkit_auth/sessions/sql.py,sha256=YQhOL_WmvVvIO7upfYb8FbguSUU3PXzlI5wu_wIsuO0,5268
47
+ fastapi_startkit_auth/sessions/state.py,sha256=YS71XVkbqeehgI5h6u8drVtcAAj8oOUWmbkKJugOhlo,499
48
+ fastapi_startkit_auth/sessions/store.py,sha256=Rsm-vy5L8-ChNbm0FFtrmX6_aVO07cZsRyMGbMmIlsw,3365
49
+ fastapi_startkit_auth/startkit.py,sha256=xy475PN3DMs0Lm3lwBmMfHT_UEzbW6xMxBj2fS2qI0U,1407
50
+ fastapi_startkit_auth/tokens/__init__.py,sha256=I_lkDpM4FT753QGCuBLHnCnrarEoI-srRcM4FsRwrE8,247
51
+ fastapi_startkit_auth/tokens/models.py,sha256=nb7MJ7XKr2Q38-0xR-o9DL3aBe2tg1J8Z0y1Zw6E-fA,1734
52
+ fastapi_startkit_auth/tokens/repository.py,sha256=20mUrjsGKwM5iYusVTDGQxGs-kwuHfnQI-V3rxKeFWw,4266
53
+ fastapi_startkit_auth/tokens/service.py,sha256=TCu6nUS_3AlVQbREee5CM-EGq_eA4wRDSQ3pt-VfSAg,6448
54
+ fastapi_startkit_auth-0.3.0.dist-info/licenses/LICENSE,sha256=hzOerAuIkzIMJRcRsvB1ui45yso-JACJesM5TzO_PIQ,1073
55
+ fastapi_startkit_auth-0.3.0.dist-info/WHEEL,sha256=GuAqCqoyQuys5_R4zkHUJFlKXw4RpRLNzo31-ui90WQ,81
56
+ fastapi_startkit_auth-0.3.0.dist-info/METADATA,sha256=Hean_dpyS_NDd5UIVtjbFgWNs3RD4lWNA0D9D81ke_8,9519
57
+ fastapi_startkit_auth-0.3.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: uv 0.10.12
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 FastAPI Startkit
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.