ohmyapi 0.2.1__py3-none-any.whl → 0.2.2__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.
- ohmyapi/db/model/model.py +6 -3
- ohmyapi-0.2.2.dist-info/METADATA +75 -0
- {ohmyapi-0.2.1.dist-info → ohmyapi-0.2.2.dist-info}/RECORD +5 -5
- ohmyapi-0.2.1.dist-info/METADATA +0 -436
- {ohmyapi-0.2.1.dist-info → ohmyapi-0.2.2.dist-info}/WHEEL +0 -0
- {ohmyapi-0.2.1.dist-info → ohmyapi-0.2.2.dist-info}/entry_points.txt +0 -0
ohmyapi/db/model/model.py
CHANGED
@@ -39,9 +39,7 @@ class ModelMeta(type(TortoiseModel)):
|
|
39
39
|
|
40
40
|
class BoundSchema:
|
41
41
|
def __call__(self, readonly: bool = False):
|
42
|
-
|
43
|
-
return self.readonly
|
44
|
-
return self.model
|
42
|
+
return self.get(readonly)
|
45
43
|
|
46
44
|
@property
|
47
45
|
def model(self):
|
@@ -68,6 +66,11 @@ class ModelMeta(type(TortoiseModel)):
|
|
68
66
|
exclude_readonly=True,
|
69
67
|
)
|
70
68
|
|
69
|
+
def get(self, readonly: bool = False):
|
70
|
+
if readonly:
|
71
|
+
return self.readonly
|
72
|
+
return self.model
|
73
|
+
|
71
74
|
new_cls.Schema = BoundSchema()
|
72
75
|
return new_cls
|
73
76
|
|
@@ -0,0 +1,75 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: ohmyapi
|
3
|
+
Version: 0.2.2
|
4
|
+
Summary: Django-flavored scaffolding and management layer around FastAPI, Pydantic, TortoiseORM and Aerich migrations
|
5
|
+
License-Expression: MIT
|
6
|
+
Keywords: fastapi,tortoise,orm,pydantic,async,web-framework
|
7
|
+
Author: Brian Wiborg
|
8
|
+
Author-email: me@brianwib.org
|
9
|
+
Requires-Python: >=3.11
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
11
|
+
Classifier: Programming Language :: Python :: 3.11
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
14
|
+
Classifier: Programming Language :: Python :: 3.14
|
15
|
+
Provides-Extra: auth
|
16
|
+
Requires-Dist: aerich (>=0.9.1,<0.10.0)
|
17
|
+
Requires-Dist: argon2-cffi (>=25.1.0,<26.0.0)
|
18
|
+
Requires-Dist: argon2-cffi ; extra == "auth"
|
19
|
+
Requires-Dist: crypto (>=1.4.1,<2.0.0)
|
20
|
+
Requires-Dist: crypto ; extra == "auth"
|
21
|
+
Requires-Dist: fastapi (>=0.117.1,<0.118.0)
|
22
|
+
Requires-Dist: ipython (>=9.5.0,<10.0.0)
|
23
|
+
Requires-Dist: jinja2 (>=3.1.6,<4.0.0)
|
24
|
+
Requires-Dist: passlib (>=1.7.4,<2.0.0)
|
25
|
+
Requires-Dist: passlib ; extra == "auth"
|
26
|
+
Requires-Dist: pyjwt (>=2.10.1,<3.0.0)
|
27
|
+
Requires-Dist: pyjwt ; extra == "auth"
|
28
|
+
Requires-Dist: python-multipart (>=0.0.20,<0.0.21)
|
29
|
+
Requires-Dist: python-multipart ; extra == "auth"
|
30
|
+
Requires-Dist: tortoise-orm (>=0.25.1,<0.26.0)
|
31
|
+
Requires-Dist: typer (>=0.19.1,<0.20.0)
|
32
|
+
Requires-Dist: uvicorn (>=0.36.0,<0.37.0)
|
33
|
+
Description-Content-Type: text/markdown
|
34
|
+
|
35
|
+
# OhMyAPI
|
36
|
+
|
37
|
+
OhMyAPI is a web-application scaffolding framework and management layer built around `FastAPI`, `TortoiseORM` and `Aerich` migrations.
|
38
|
+
|
39
|
+
> *Think: Django RestFramework, but less clunky and 100% async.*
|
40
|
+
|
41
|
+
It is ***blazingly fast***, extremely ***fun to use*** and comes with ***batteries included***!
|
42
|
+
|
43
|
+
**Features**
|
44
|
+
|
45
|
+
- Django-like project structure and application directories
|
46
|
+
- Django-like per-app migrations (makemigrations & migrate) via Aerich
|
47
|
+
- Django-like CLI tooling (startproject, startapp, shell, serve, etc)
|
48
|
+
- Customizable pydantic model serializer built-in
|
49
|
+
- Various optional built-in apps you can hook into your project
|
50
|
+
- Highly configurable and customizable
|
51
|
+
- 100% async
|
52
|
+
|
53
|
+
**Goals**
|
54
|
+
|
55
|
+
- combine FastAPI, TortoiseORM, Aerich migrations and Pydantic into a high-productivity web-application framework
|
56
|
+
- tie everything neatly together into a concise and straight-forward API
|
57
|
+
- AVOID adding any abstractions on top, unless they make things extremely convenient
|
58
|
+
|
59
|
+
## Installation
|
60
|
+
|
61
|
+
```
|
62
|
+
pipx install ohmyapi
|
63
|
+
```
|
64
|
+
|
65
|
+
|
66
|
+
## Docs
|
67
|
+
|
68
|
+
See: `docs/`
|
69
|
+
|
70
|
+
- [Projects](docs/projects.md)
|
71
|
+
- [Apps](docs/apps.md)
|
72
|
+
- [Models](docs/models.md)
|
73
|
+
- [Migrations](docs/migrations.md)
|
74
|
+
- [Routes](docs/routes.md)
|
75
|
+
|
@@ -20,9 +20,9 @@ ohmyapi/core/templates/project/settings.py.j2,sha256=So6w1OiL_jU-FyeT8IHueDjGNuE
|
|
20
20
|
ohmyapi/db/__init__.py,sha256=5QKUycxnN83DOUD_Etoee9tEOYjnZ74deqrSOOx_MiQ,204
|
21
21
|
ohmyapi/db/exceptions.py,sha256=vb4IIUoeYAY6sK42zRtjMy-39IFVi_Qb6mWySTY0jYw,34
|
22
22
|
ohmyapi/db/model/__init__.py,sha256=k3StTNuKatpwZo_Z5JBFa-927eJrzibFE8U4SA82asc,32
|
23
|
-
ohmyapi/db/model/model.py,sha256=
|
23
|
+
ohmyapi/db/model/model.py,sha256=ui4g78c5xoS06Dj8Cdk7QgTjRnE68zKeL-AdmeYYPuQ,2776
|
24
24
|
ohmyapi/router.py,sha256=5g0U59glu4hxxnIoTSFzb2S2offkOT3eE39aprzVxwo,83
|
25
|
-
ohmyapi-0.2.
|
26
|
-
ohmyapi-0.2.
|
27
|
-
ohmyapi-0.2.
|
28
|
-
ohmyapi-0.2.
|
25
|
+
ohmyapi-0.2.2.dist-info/METADATA,sha256=73UvH4QOy4q4OgAom0k8d7dtSgeqYSG6VhYRGu0WXDA,2556
|
26
|
+
ohmyapi-0.2.2.dist-info/WHEEL,sha256=M5asmiAlL6HEcOq52Yi5mmk9KmTVjY2RDPtO4p9DMrc,88
|
27
|
+
ohmyapi-0.2.2.dist-info/entry_points.txt,sha256=wb3lw8-meAlpiv1mqcQ3m25ukL7djagU_w89GkrC37k,43
|
28
|
+
ohmyapi-0.2.2.dist-info/RECORD,,
|
ohmyapi-0.2.1.dist-info/METADATA
DELETED
@@ -1,436 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.4
|
2
|
-
Name: ohmyapi
|
3
|
-
Version: 0.2.1
|
4
|
-
Summary: Django-flavored scaffolding and management layer around FastAPI, Pydantic, TortoiseORM and Aerich migrations
|
5
|
-
License-Expression: MIT
|
6
|
-
Keywords: fastapi,tortoise,orm,pydantic,async,web-framework
|
7
|
-
Author: Brian Wiborg
|
8
|
-
Author-email: me@brianwib.org
|
9
|
-
Requires-Python: >=3.11
|
10
|
-
Classifier: Programming Language :: Python :: 3
|
11
|
-
Classifier: Programming Language :: Python :: 3.11
|
12
|
-
Classifier: Programming Language :: Python :: 3.12
|
13
|
-
Classifier: Programming Language :: Python :: 3.13
|
14
|
-
Classifier: Programming Language :: Python :: 3.14
|
15
|
-
Provides-Extra: auth
|
16
|
-
Requires-Dist: aerich (>=0.9.1,<0.10.0)
|
17
|
-
Requires-Dist: argon2-cffi (>=25.1.0,<26.0.0)
|
18
|
-
Requires-Dist: argon2-cffi ; extra == "auth"
|
19
|
-
Requires-Dist: crypto (>=1.4.1,<2.0.0)
|
20
|
-
Requires-Dist: crypto ; extra == "auth"
|
21
|
-
Requires-Dist: fastapi (>=0.117.1,<0.118.0)
|
22
|
-
Requires-Dist: ipython (>=9.5.0,<10.0.0)
|
23
|
-
Requires-Dist: jinja2 (>=3.1.6,<4.0.0)
|
24
|
-
Requires-Dist: passlib (>=1.7.4,<2.0.0)
|
25
|
-
Requires-Dist: passlib ; extra == "auth"
|
26
|
-
Requires-Dist: pyjwt (>=2.10.1,<3.0.0)
|
27
|
-
Requires-Dist: pyjwt ; extra == "auth"
|
28
|
-
Requires-Dist: python-multipart (>=0.0.20,<0.0.21)
|
29
|
-
Requires-Dist: python-multipart ; extra == "auth"
|
30
|
-
Requires-Dist: tortoise-orm (>=0.25.1,<0.26.0)
|
31
|
-
Requires-Dist: typer (>=0.19.1,<0.20.0)
|
32
|
-
Requires-Dist: uvicorn (>=0.36.0,<0.37.0)
|
33
|
-
Description-Content-Type: text/markdown
|
34
|
-
|
35
|
-
# OhMyAPI
|
36
|
-
|
37
|
-
> Think: Django RestFramework, but less clunky and 100% async.
|
38
|
-
|
39
|
-
OhMyAPI is a Django-flavored web-application scaffolding framework and management layer,
|
40
|
-
built around FastAPI and TortoiseORM and is thus 100% async.
|
41
|
-
|
42
|
-
It is ***blazingly fast***, extremely ***fun to use*** and comes with ***batteries included***!
|
43
|
-
|
44
|
-
**Features**
|
45
|
-
|
46
|
-
- Django-like project structure and application directories
|
47
|
-
- Django-like per-app migrations (`makemigrations` & `migrate`) via Aerich
|
48
|
-
- Django-like CLI tooling (`startproject`, `startapp`, `shell`, `serve`, etc)
|
49
|
-
- Customizable pydantic model serializer built-in
|
50
|
-
- Various optional built-in apps you can hook into your project
|
51
|
-
- Highly configurable and customizable
|
52
|
-
- 100% async
|
53
|
-
|
54
|
-
**Goals**
|
55
|
-
|
56
|
-
- combine `FastAPI`, `TortoiseORM`, `Aerich` migrations and `Pydantic` into a high-productivity web-application framework
|
57
|
-
- tie everything neatly together into a concise and straight-forward API
|
58
|
-
- ***AVOID*** adding any abstractions on top, unless they make things extremely convenient
|
59
|
-
|
60
|
-
---
|
61
|
-
|
62
|
-
## Getting started
|
63
|
-
|
64
|
-
**Creating a Project**
|
65
|
-
|
66
|
-
```
|
67
|
-
pipx install ohmyapi
|
68
|
-
ohmyapi startproject myproject
|
69
|
-
cd myproject
|
70
|
-
```
|
71
|
-
|
72
|
-
This will create the following directory structure:
|
73
|
-
|
74
|
-
```
|
75
|
-
myproject/
|
76
|
-
- pyproject.toml
|
77
|
-
- README.md
|
78
|
-
- settings.py
|
79
|
-
```
|
80
|
-
|
81
|
-
Run your project with:
|
82
|
-
|
83
|
-
```
|
84
|
-
ohmyapi serve
|
85
|
-
```
|
86
|
-
|
87
|
-
In your browser go to:
|
88
|
-
- http://localhost:8000/docs
|
89
|
-
|
90
|
-
**Creating an App**
|
91
|
-
|
92
|
-
Create a new app by:
|
93
|
-
|
94
|
-
```
|
95
|
-
ohmyapi startapp tournament
|
96
|
-
```
|
97
|
-
|
98
|
-
This will create the following directory structure:
|
99
|
-
|
100
|
-
```
|
101
|
-
myproject/
|
102
|
-
- tournament/
|
103
|
-
- __init__.py
|
104
|
-
- models.py
|
105
|
-
- routes.py
|
106
|
-
- pyproject.toml
|
107
|
-
- README.md
|
108
|
-
- settings.py
|
109
|
-
```
|
110
|
-
|
111
|
-
Add 'tournament' to your `INSTALLED_APPS` in `settings.py`.
|
112
|
-
|
113
|
-
### Models
|
114
|
-
|
115
|
-
Write your first model in `turnament/models.py`:
|
116
|
-
|
117
|
-
```python
|
118
|
-
from ohmyapi.db import Model, field
|
119
|
-
|
120
|
-
from datetime import datetime
|
121
|
-
from decimal import Decimal
|
122
|
-
from uuid import UUID
|
123
|
-
|
124
|
-
|
125
|
-
class Tournament(Model):
|
126
|
-
id: UUID = field.data.UUIDField(primary_key=True)
|
127
|
-
name: str = field.TextField()
|
128
|
-
created: datetime = field.DatetimeField(auto_now_add=True)
|
129
|
-
|
130
|
-
def __str__(self):
|
131
|
-
return self.name
|
132
|
-
|
133
|
-
|
134
|
-
class Event(Model):
|
135
|
-
id: UUID = field.data.UUIDField(primary_key=True)
|
136
|
-
name: str = field.TextField()
|
137
|
-
tournament: UUID = field.ForeignKeyField('tournament.Tournament', related_name='events')
|
138
|
-
participants: field.ManyToManyRelation[Team] = field.ManyToManyField('tournament.Team', related_name='events', through='event_team')
|
139
|
-
modified: datetime = field.DatetimeField(auto_now=True)
|
140
|
-
prize: Decimal = field.DecimalField(max_digits=10, decimal_places=2, null=True)
|
141
|
-
|
142
|
-
def __str__(self):
|
143
|
-
return self.name
|
144
|
-
|
145
|
-
|
146
|
-
class Team(Model):
|
147
|
-
id: UUID = field.data.UUIDField(primary_key=True)
|
148
|
-
name: str = field.TextField()
|
149
|
-
|
150
|
-
def __str__(self):
|
151
|
-
return self.name
|
152
|
-
```
|
153
|
-
|
154
|
-
### API Routes
|
155
|
-
|
156
|
-
Next, create your endpoints in `tournament/routes.py`:
|
157
|
-
|
158
|
-
```python
|
159
|
-
from ohmyapi.router import APIRouter, HTTPException, HTTPStatus
|
160
|
-
from ohmyapi.db.exceptions import DoesNotExist
|
161
|
-
|
162
|
-
from typing import List
|
163
|
-
|
164
|
-
from .models import Tournament
|
165
|
-
|
166
|
-
# OhMyAPI will automatically pick up all instances of `fastapi.APIRouter` and
|
167
|
-
# add their routes to the main project router.
|
168
|
-
#
|
169
|
-
# Note:
|
170
|
-
# Use prefixes wisely to avoid cross-app namespace-collisions!
|
171
|
-
# Tags improve the UX of the OpenAPI docs at /docs.
|
172
|
-
#
|
173
|
-
tournament_router = APIRouter(prefix="/tournament", tags=['Tournament'])
|
174
|
-
|
175
|
-
|
176
|
-
@tournament_router.get("/", response_model=List[Tournament.Schema()])
|
177
|
-
async def list():
|
178
|
-
queryset = Tournament.all()
|
179
|
-
return await Tournament.Schema.model.from_queryset(queryset)
|
180
|
-
|
181
|
-
|
182
|
-
@tournament_router.post("/", status_code=HTTPStatus.CREATED)
|
183
|
-
async def post(tournament: Tournament.Schema(readonly=True)):
|
184
|
-
queryset = Tournament.create(**payload.model_dump())
|
185
|
-
return await Tournament.Schema().from_queryset(queryset)
|
186
|
-
|
187
|
-
|
188
|
-
@tournament_router.get("/:id", response_model=Tournament.Schema())
|
189
|
-
async def get(id: str):
|
190
|
-
try:
|
191
|
-
queryset = Tournament.get(id=id)
|
192
|
-
return await Tournament.Schema().from_queryset_single(tournament)
|
193
|
-
except DoesNotExist:
|
194
|
-
raise HTTPException(status_code=404, detail="not found")
|
195
|
-
|
196
|
-
|
197
|
-
@tournament_router.delete("/:id")
|
198
|
-
async def delete(id: str):
|
199
|
-
try:
|
200
|
-
tournament = await Tournament.get(id=id)
|
201
|
-
return await Tournament.Schema.model.from_queryset(tournament.delete())
|
202
|
-
except DoesNotExist:
|
203
|
-
raise HTTPException(status_code=404, detail="not found")
|
204
|
-
|
205
|
-
|
206
|
-
...
|
207
|
-
```
|
208
|
-
|
209
|
-
## Migrations
|
210
|
-
|
211
|
-
Before we can run the app, we need to create and initialize the database.
|
212
|
-
|
213
|
-
Similar to Django, first run:
|
214
|
-
|
215
|
-
```
|
216
|
-
ohmyapi makemigrations [ <app> ] # no app means all INSTALLED_APPS
|
217
|
-
```
|
218
|
-
|
219
|
-
This will create a `migrations/` folder in you project root.
|
220
|
-
|
221
|
-
```
|
222
|
-
myproject/
|
223
|
-
- tournament/
|
224
|
-
- __init__.py
|
225
|
-
- models.py
|
226
|
-
- routes.py
|
227
|
-
- migrations/
|
228
|
-
- tournament/
|
229
|
-
- pyproject.toml
|
230
|
-
- README.md
|
231
|
-
- settings.py
|
232
|
-
```
|
233
|
-
|
234
|
-
Apply your migrations via:
|
235
|
-
|
236
|
-
```
|
237
|
-
ohmyapi migrate [ <app> ] # no app means all INSTALLED_APPS
|
238
|
-
```
|
239
|
-
|
240
|
-
Run your project:
|
241
|
-
|
242
|
-
```
|
243
|
-
ohmyapi serve
|
244
|
-
```
|
245
|
-
|
246
|
-
## Authentication
|
247
|
-
|
248
|
-
A builtin auth app is available.
|
249
|
-
|
250
|
-
Simply add `ohmyapi_auth` to your INSTALLED_APPS and define a JWT_SECRET in your `settings.py`.
|
251
|
-
Remember to `makemigrations` and `migrate` for the necessary tables to be created in the database.
|
252
|
-
|
253
|
-
`settings.py`:
|
254
|
-
|
255
|
-
```
|
256
|
-
INSTALLED_APPS = [
|
257
|
-
'ohmyapi_auth',
|
258
|
-
...
|
259
|
-
]
|
260
|
-
|
261
|
-
JWT_SECRET = "t0ps3cr3t"
|
262
|
-
```
|
263
|
-
|
264
|
-
After restarting your project you will have access to the `ohmyapi_auth` app.
|
265
|
-
It comes with a `User` and `Group` model, as well as endpoints for JWT auth.
|
266
|
-
|
267
|
-
You can use the models as `ForeignKeyField` in your application models:
|
268
|
-
|
269
|
-
```python
|
270
|
-
from ohmyapi.db import Model, field
|
271
|
-
from ohmyapi_auth.models import User
|
272
|
-
|
273
|
-
|
274
|
-
class Team(Model):
|
275
|
-
[...]
|
276
|
-
members: field.ManyToManyRelation[User] = field.ManyToManyField('ohmyapi_auth.User', related_name='tournament_teams', through='tournament_teams')
|
277
|
-
[...]
|
278
|
-
```
|
279
|
-
|
280
|
-
Remember to run `makemigrations` and `migrate` in order for your model changes to take effect in the database.
|
281
|
-
|
282
|
-
Create a super-user:
|
283
|
-
|
284
|
-
```
|
285
|
-
ohmyapi createsuperuser
|
286
|
-
```
|
287
|
-
|
288
|
-
## Permissions
|
289
|
-
|
290
|
-
### API-Level Permissions
|
291
|
-
|
292
|
-
Use FastAPI's `Depends` pattern to implement API-level access-control.
|
293
|
-
|
294
|
-
|
295
|
-
In your `routes.py`:
|
296
|
-
|
297
|
-
```python
|
298
|
-
from ohmyapi.router import APIRouter, Depends
|
299
|
-
from ohmyapi_auth import (
|
300
|
-
models as auth,
|
301
|
-
permissions,
|
302
|
-
)
|
303
|
-
|
304
|
-
from .models import Tournament
|
305
|
-
|
306
|
-
router = APIRouter(prefix="/tournament", tags=["Tournament"])
|
307
|
-
|
308
|
-
|
309
|
-
@router.get("/")
|
310
|
-
async def list(user: auth.User = Depends(permissions.require_authenticated)):
|
311
|
-
queryset = Tournament.all()
|
312
|
-
return await Tournament.Schema().from_queryset(queryset)
|
313
|
-
|
314
|
-
|
315
|
-
...
|
316
|
-
```
|
317
|
-
|
318
|
-
### Model-Level Permissions
|
319
|
-
|
320
|
-
Use Tortoise's `Manager` to implement model-level permissions.
|
321
|
-
|
322
|
-
```python
|
323
|
-
from ohmyapi.db import Manager
|
324
|
-
from ohmyapi_auth.models import User
|
325
|
-
|
326
|
-
|
327
|
-
class TeamManager(Manager):
|
328
|
-
async def for_user(self, user: User):
|
329
|
-
return await self.filter(members=user).all()
|
330
|
-
|
331
|
-
|
332
|
-
class Team(Model):
|
333
|
-
[...]
|
334
|
-
|
335
|
-
class Meta:
|
336
|
-
manager = TeamManager()
|
337
|
-
```
|
338
|
-
|
339
|
-
Use the custom manager in your FastAPI route handler:
|
340
|
-
|
341
|
-
```python
|
342
|
-
from ohmyapi.router import APIRouter
|
343
|
-
from ohmyapi_auth import (
|
344
|
-
models as auth,
|
345
|
-
permissions,
|
346
|
-
)
|
347
|
-
|
348
|
-
router = APIRouter(prefix="/tournament", tags=["Tournament"])
|
349
|
-
|
350
|
-
|
351
|
-
@router.get("/teams")
|
352
|
-
async def teams(user: auth.User = Depends(permissions.require_authenticated)):
|
353
|
-
queryset = Team.for_user(user)
|
354
|
-
return await Tournament.Schema().from_queryset(queryset)
|
355
|
-
```
|
356
|
-
|
357
|
-
## Shell
|
358
|
-
|
359
|
-
Similar to Django, you can attach to an interactive shell with your project already loaded inside.
|
360
|
-
|
361
|
-
```
|
362
|
-
ohmyapi shell
|
363
|
-
|
364
|
-
Python 3.13.7 (main, Aug 15 2025, 12:34:02) [GCC 15.2.1 20250813]
|
365
|
-
Type 'copyright', 'credits' or 'license' for more information
|
366
|
-
IPython 9.5.0 -- An enhanced Interactive Python. Type '?' for help.
|
367
|
-
|
368
|
-
OhMyAPI Shell | Project: {{ project_name }} [{{ project_path }}]
|
369
|
-
Find your loaded project singleton via identifier: `p`
|
370
|
-
```
|
371
|
-
|
372
|
-
```python
|
373
|
-
In [1]: p
|
374
|
-
Out[1]: <ohmyapi.core.runtime.Project at 0x7f00c43dbcb0>
|
375
|
-
|
376
|
-
In [2]: p.apps
|
377
|
-
Out[2]:
|
378
|
-
{'ohmyapi_auth': {
|
379
|
-
"models": [
|
380
|
-
"Group",
|
381
|
-
"User"
|
382
|
-
],
|
383
|
-
"routes": [
|
384
|
-
{
|
385
|
-
"path": "/auth/login",
|
386
|
-
"name": "login",
|
387
|
-
"methods": [
|
388
|
-
"POST"
|
389
|
-
],
|
390
|
-
"endpoint": "login",
|
391
|
-
"response_model": null,
|
392
|
-
"tags": [
|
393
|
-
"auth"
|
394
|
-
]
|
395
|
-
},
|
396
|
-
{
|
397
|
-
"path": "/auth/refresh",
|
398
|
-
"name": "refresh_token",
|
399
|
-
"methods": [
|
400
|
-
"POST"
|
401
|
-
],
|
402
|
-
"endpoint": "refresh_token",
|
403
|
-
"response_model": null,
|
404
|
-
"tags": [
|
405
|
-
"auth"
|
406
|
-
]
|
407
|
-
},
|
408
|
-
{
|
409
|
-
"path": "/auth/introspect",
|
410
|
-
"name": "introspect",
|
411
|
-
"methods": [
|
412
|
-
"GET"
|
413
|
-
],
|
414
|
-
"endpoint": "introspect",
|
415
|
-
"response_model": null,
|
416
|
-
"tags": [
|
417
|
-
"auth"
|
418
|
-
]
|
419
|
-
},
|
420
|
-
{
|
421
|
-
"path": "/auth/me",
|
422
|
-
"name": "me",
|
423
|
-
"methods": [
|
424
|
-
"GET"
|
425
|
-
],
|
426
|
-
"endpoint": "me",
|
427
|
-
"response_model": null,
|
428
|
-
"tags": [
|
429
|
-
"auth"
|
430
|
-
]
|
431
|
-
}
|
432
|
-
]
|
433
|
-
}}
|
434
|
-
```
|
435
|
-
|
436
|
-
|
File without changes
|
File without changes
|