fastadmin 0.3.8__tar.gz → 0.3.9__tar.gz
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.
- {fastadmin-0.3.8 → fastadmin-0.3.9}/PKG-INFO +1 -1
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/__init__.py +4 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/api/frameworks/django/app/api.py +15 -5
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/api/frameworks/fastapi/api.py +17 -4
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/api/frameworks/flask/api.py +16 -5
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/api/schemas.py +16 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/api/service.py +3 -2
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/models/base.py +10 -2
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/models/decorators.py +1 -1
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/static/index.min.js +173 -173
- {fastadmin-0.3.8 → fastadmin-0.3.9}/pyproject.toml +1 -1
- {fastadmin-0.3.8 → fastadmin-0.3.9}/LICENSE +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/README.md +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/api/__init__.py +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/api/exceptions.py +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/api/frameworks/__init__.py +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/api/frameworks/django/__init__.py +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/api/frameworks/django/app/__init__.py +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/api/frameworks/django/app/urls.py +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/api/frameworks/django/app/views.py +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/api/frameworks/fastapi/__init__.py +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/api/frameworks/fastapi/app.py +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/api/frameworks/fastapi/views.py +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/api/frameworks/flask/__init__.py +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/api/frameworks/flask/app.py +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/api/frameworks/flask/views.py +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/api/helpers.py +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/models/__init__.py +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/models/helpers.py +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/models/orms/__init__.py +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/models/orms/django.py +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/models/orms/ponyorm.py +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/models/orms/sqlalchemy.py +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/models/orms/tortoise.py +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/models/schemas.py +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/settings.py +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/static/assets/worker-6Z7niv9l.js +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/static/assets/worker-C151k0-L.js +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/static/assets/worker-C9KPOOKD.js +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/static/assets/worker-D1fCgYB7.js +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/static/assets/worker-D3TWcJOI.js +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/static/assets/worker-DRNcaZ-V.js +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/static/assets/worker-MF2p-l5_.js +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/static/images/favicon.png +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/static/images/header-logo.svg +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/static/images/sign-in-logo.svg +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/static/index.html +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/static/index.min.css +0 -0
- {fastadmin-0.3.8 → fastadmin-0.3.9}/fastadmin/templates/index.html +0 -0
|
@@ -32,6 +32,10 @@ try:
|
|
|
32
32
|
except ModuleNotFoundError: # pragma: no cover
|
|
33
33
|
logging.info("TortoiseORM is not installed") # pragma: no cover
|
|
34
34
|
|
|
35
|
+
# api
|
|
36
|
+
from fastadmin.api.exceptions import AdminApiException # noqa: F401
|
|
37
|
+
from fastadmin.api.schemas import ActionResponseSchema, ActionResponseType # noqa: F401
|
|
38
|
+
|
|
35
39
|
# models
|
|
36
40
|
from fastadmin.models.base import DashboardWidgetAdmin, InlineModelAdmin, ModelAdmin # noqa: F401
|
|
37
41
|
from fastadmin.models.decorators import action, display, register, register_widget # noqa: F401
|
|
@@ -13,7 +13,13 @@ from django.http.request import HttpRequest
|
|
|
13
13
|
|
|
14
14
|
from fastadmin.api.exceptions import AdminApiException
|
|
15
15
|
from fastadmin.api.helpers import is_valid_id, parse_list_filters_from_query_params
|
|
16
|
-
from fastadmin.api.schemas import
|
|
16
|
+
from fastadmin.api.schemas import (
|
|
17
|
+
ActionInputSchema,
|
|
18
|
+
ActionResponseSchema,
|
|
19
|
+
ActionResponseType,
|
|
20
|
+
ExportInputSchema,
|
|
21
|
+
SignInInputSchema,
|
|
22
|
+
)
|
|
17
23
|
from fastadmin.api.service import ApiService, get_user_id_from_session_id
|
|
18
24
|
from fastadmin.settings import settings
|
|
19
25
|
|
|
@@ -379,21 +385,25 @@ async def action(
|
|
|
379
385
|
:params model: a name of model.
|
|
380
386
|
:params action: a name of action.
|
|
381
387
|
:params payload: a payload object.
|
|
382
|
-
:return:
|
|
388
|
+
:return: action result.
|
|
383
389
|
"""
|
|
384
390
|
if request.method != "POST":
|
|
385
391
|
return JsonResponse({"error": "Method not allowed"}, status=405)
|
|
386
392
|
try:
|
|
387
393
|
payload = ActionInputSchema(**json.loads(request.body))
|
|
388
|
-
await api_service.action(
|
|
394
|
+
response = await api_service.action(
|
|
389
395
|
request.COOKIES.get(settings.ADMIN_SESSION_ID_KEY, None),
|
|
390
396
|
model,
|
|
391
397
|
action,
|
|
392
398
|
payload,
|
|
393
399
|
request=request,
|
|
394
400
|
)
|
|
395
|
-
|
|
396
|
-
|
|
401
|
+
if not response:
|
|
402
|
+
response = ActionResponseSchema(
|
|
403
|
+
type=ActionResponseType.MESSAGE,
|
|
404
|
+
data="Successfully applied",
|
|
405
|
+
)
|
|
406
|
+
return JsonResponse(asdict(response))
|
|
397
407
|
except AdminApiException as e:
|
|
398
408
|
return JsonResponse({"detail": e.detail}, status=e.status_code)
|
|
399
409
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
|
+
from dataclasses import asdict
|
|
2
3
|
from typing import Any
|
|
3
4
|
from uuid import UUID
|
|
4
5
|
|
|
@@ -7,7 +8,13 @@ from fastapi.responses import Response, StreamingResponse
|
|
|
7
8
|
|
|
8
9
|
from fastadmin.api.exceptions import AdminApiException
|
|
9
10
|
from fastadmin.api.helpers import parse_list_filters_from_query_params
|
|
10
|
-
from fastadmin.api.schemas import
|
|
11
|
+
from fastadmin.api.schemas import (
|
|
12
|
+
ActionInputSchema,
|
|
13
|
+
ActionResponseSchema,
|
|
14
|
+
ActionResponseType,
|
|
15
|
+
ExportInputSchema,
|
|
16
|
+
SignInInputSchema,
|
|
17
|
+
)
|
|
11
18
|
from fastadmin.api.service import ApiService, get_user_id_from_session_id
|
|
12
19
|
from fastadmin.models.schemas import ConfigurationSchema
|
|
13
20
|
from fastadmin.settings import settings
|
|
@@ -328,22 +335,28 @@ async def action(
|
|
|
328
335
|
model: str,
|
|
329
336
|
action: str,
|
|
330
337
|
payload: ActionInputSchema,
|
|
331
|
-
) ->
|
|
338
|
+
) -> dict:
|
|
332
339
|
"""This method is used to perform an action.
|
|
333
340
|
|
|
334
341
|
:params model: a name of model.
|
|
335
342
|
:params action: a name of action.
|
|
336
343
|
:params payload: a payload object.
|
|
337
|
-
:return:
|
|
344
|
+
:return: action result.
|
|
338
345
|
"""
|
|
339
346
|
try:
|
|
340
|
-
|
|
347
|
+
response = await api_service.action(
|
|
341
348
|
request.cookies.get(settings.ADMIN_SESSION_ID_KEY, None),
|
|
342
349
|
model,
|
|
343
350
|
action,
|
|
344
351
|
payload,
|
|
345
352
|
request=request,
|
|
346
353
|
)
|
|
354
|
+
if not response:
|
|
355
|
+
response = ActionResponseSchema(
|
|
356
|
+
type=ActionResponseType.MESSAGE,
|
|
357
|
+
data="Successfully applied",
|
|
358
|
+
)
|
|
359
|
+
return asdict(response)
|
|
347
360
|
except AdminApiException as e:
|
|
348
361
|
raise HTTPException(e.status_code, detail=e.detail) from None
|
|
349
362
|
|
|
@@ -7,7 +7,13 @@ from werkzeug.exceptions import HTTPException
|
|
|
7
7
|
|
|
8
8
|
from fastadmin.api.exceptions import AdminApiException
|
|
9
9
|
from fastadmin.api.helpers import is_valid_id, parse_list_filters_from_query_params
|
|
10
|
-
from fastadmin.api.schemas import
|
|
10
|
+
from fastadmin.api.schemas import (
|
|
11
|
+
ActionInputSchema,
|
|
12
|
+
ActionResponseSchema,
|
|
13
|
+
ActionResponseType,
|
|
14
|
+
ExportInputSchema,
|
|
15
|
+
SignInInputSchema,
|
|
16
|
+
)
|
|
11
17
|
from fastadmin.api.service import ApiService, get_user_id_from_session_id
|
|
12
18
|
from fastadmin.settings import settings
|
|
13
19
|
|
|
@@ -336,25 +342,30 @@ async def delete(
|
|
|
336
342
|
async def action(
|
|
337
343
|
model: str,
|
|
338
344
|
action: str,
|
|
339
|
-
) ->
|
|
345
|
+
) -> Response:
|
|
340
346
|
"""This method is used to perform an action.
|
|
341
347
|
|
|
342
348
|
:params model: a name of model.
|
|
343
349
|
:params action: a name of action.
|
|
344
350
|
:params payload: a payload object.
|
|
345
|
-
:return:
|
|
351
|
+
:return: action result.
|
|
346
352
|
"""
|
|
347
353
|
try:
|
|
348
354
|
request_payload: dict = request.json
|
|
349
355
|
payload: ActionInputSchema = ActionInputSchema(**request_payload)
|
|
350
|
-
await api_service.action(
|
|
356
|
+
response = await api_service.action(
|
|
351
357
|
request.cookies.get(settings.ADMIN_SESSION_ID_KEY, None),
|
|
352
358
|
model,
|
|
353
359
|
action,
|
|
354
360
|
payload,
|
|
355
361
|
request=request,
|
|
356
362
|
)
|
|
357
|
-
|
|
363
|
+
if not response:
|
|
364
|
+
response = ActionResponseSchema(
|
|
365
|
+
type=ActionResponseType.MESSAGE,
|
|
366
|
+
data="Successfully applied",
|
|
367
|
+
)
|
|
368
|
+
return make_response(asdict(response))
|
|
358
369
|
except AdminApiException as e:
|
|
359
370
|
http_exception = HTTPException(e.detail)
|
|
360
371
|
http_exception.code = e.status_code
|
|
@@ -10,6 +10,13 @@ class ExportFormat(str, Enum):
|
|
|
10
10
|
JSON = "JSON"
|
|
11
11
|
|
|
12
12
|
|
|
13
|
+
class ActionResponseType(str, Enum):
|
|
14
|
+
"""Action response type"""
|
|
15
|
+
|
|
16
|
+
DOWNLOAD_BASE64 = "DOWNLOAD_BASE64"
|
|
17
|
+
MESSAGE = "MESSAGE"
|
|
18
|
+
|
|
19
|
+
|
|
13
20
|
@dataclass
|
|
14
21
|
class DashboardWidgetQuerySchema:
|
|
15
22
|
"""DashboardWidge query schema"""
|
|
@@ -70,3 +77,12 @@ class ActionInputSchema:
|
|
|
70
77
|
"""Action input schema"""
|
|
71
78
|
|
|
72
79
|
ids: list[int | UUID]
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
@dataclass
|
|
83
|
+
class ActionResponseSchema:
|
|
84
|
+
"""Action response schema"""
|
|
85
|
+
|
|
86
|
+
type: ActionResponseType
|
|
87
|
+
data: str
|
|
88
|
+
file_name: str | None = None
|
|
@@ -14,6 +14,7 @@ from fastadmin.api.exceptions import AdminApiException
|
|
|
14
14
|
from fastadmin.api.helpers import sanitize_filter_key, sanitize_filter_value
|
|
15
15
|
from fastadmin.api.schemas import (
|
|
16
16
|
ActionInputSchema,
|
|
17
|
+
ActionResponseSchema,
|
|
17
18
|
ChangePasswordInputSchema,
|
|
18
19
|
DashboardWidgetDataOutputSchema,
|
|
19
20
|
DashboardWidgetQuerySchema,
|
|
@@ -478,7 +479,7 @@ class ApiService:
|
|
|
478
479
|
action: str,
|
|
479
480
|
payload: ActionInputSchema,
|
|
480
481
|
request: Any | None = None,
|
|
481
|
-
) -> None:
|
|
482
|
+
) -> ActionResponseSchema | None:
|
|
482
483
|
_current_user_id, current_user = await self._get_authenticated_user(session_id)
|
|
483
484
|
|
|
484
485
|
admin_model = get_admin_or_admin_inline_model(model)
|
|
@@ -498,7 +499,7 @@ class ApiService:
|
|
|
498
499
|
else:
|
|
499
500
|
action_function_fn = sync_to_async(action_function)
|
|
500
501
|
|
|
501
|
-
await action_function_fn(payload.ids)
|
|
502
|
+
return await action_function_fn(payload.ids)
|
|
502
503
|
|
|
503
504
|
async def get_configuration(
|
|
504
505
|
self,
|
|
@@ -4,6 +4,7 @@ import inspect
|
|
|
4
4
|
import json
|
|
5
5
|
from collections.abc import Sequence
|
|
6
6
|
from contextvars import ContextVar
|
|
7
|
+
from decimal import Decimal
|
|
7
8
|
from io import BytesIO, StringIO
|
|
8
9
|
from typing import Any
|
|
9
10
|
from uuid import UUID
|
|
@@ -31,7 +32,7 @@ class BaseModelAdmin:
|
|
|
31
32
|
# @action(
|
|
32
33
|
# description="Mark selected stories as published",
|
|
33
34
|
# )
|
|
34
|
-
# async def make_published(self, objs: list[Any]) -> None:
|
|
35
|
+
# async def make_published(self, objs: list[Any]) -> ActionResponseSchema | None:
|
|
35
36
|
# ...
|
|
36
37
|
actions: Sequence[str] = ()
|
|
37
38
|
|
|
@@ -384,7 +385,14 @@ class BaseModelAdmin:
|
|
|
384
385
|
:params attributes_to_serizalize: a list of attributes to serialize.
|
|
385
386
|
:return: A dict of serialized attributes.
|
|
386
387
|
"""
|
|
387
|
-
serialized_dict
|
|
388
|
+
serialized_dict: dict[str, Any] = {}
|
|
389
|
+
for field in attributes_to_serizalize:
|
|
390
|
+
value = getattr(obj, field.column_name)
|
|
391
|
+
if isinstance(value, Decimal):
|
|
392
|
+
# Avoid scientific notation for Decimal values in API responses,
|
|
393
|
+
# e.g. 3.75E+3 -> "3750"
|
|
394
|
+
value = format(value, "f")
|
|
395
|
+
serialized_dict[field.name] = value
|
|
388
396
|
if inspect.iscoroutinefunction(obj.__str__):
|
|
389
397
|
str_fn = obj.__str__
|
|
390
398
|
else:
|
|
@@ -5,7 +5,7 @@ def action(function=None, *, description: str | None = None):
|
|
|
5
5
|
@action(
|
|
6
6
|
description="Mark selected stories as published",
|
|
7
7
|
)
|
|
8
|
-
async def make_published(self, objs: list[Any]) -> None:
|
|
8
|
+
async def make_published(self, objs: list[Any]) -> ActionResponseSchema | None:
|
|
9
9
|
...
|
|
10
10
|
|
|
11
11
|
:param function: A function to decorate.
|