amsdal_server 0.3.0__tar.gz → 0.3.2__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.
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/PKG-INFO +1 -1
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/change-logs.md +12 -0
- amsdal_server-0.3.2/latest-changelogs.md +6 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/pyproject.toml +11 -7
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/__about__.py +1 -1
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/classes/controllers/class_detail.py +1 -1
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/classes/controllers/class_list.py +1 -1
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/classes/mixins/model_class_info.py +12 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/classes/services/classes_api.py +84 -7
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/common/authentication.py +13 -5
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/common/middlewares/response_event.py +14 -5
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/common/mixins/permissions_mixin.py +28 -0
- amsdal_server-0.3.2/src/amsdal_server/apps/common/response.py +97 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/common/utils.py +13 -6
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/healthcheck/services/checkers/connections.py +8 -2
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/objects/controllers/bulk_operations.py +4 -4
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/objects/controllers/file_download.py +4 -4
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/objects/controllers/object_create.py +1 -1
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/objects/controllers/object_detail.py +11 -9
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/objects/controllers/object_list.py +17 -15
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/objects/controllers/object_update.py +2 -2
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/objects/mixins/object_data_mixin.py +13 -3
- amsdal_server-0.3.2/src/amsdal_server/apps/objects/services/file_object.py +63 -0
- amsdal_server-0.3.2/src/amsdal_server/apps/objects/services/object_api.py +950 -0
- amsdal_server-0.3.2/src/amsdal_server/apps/objects/services/object_list_api.py +406 -0
- amsdal_server-0.3.2/src/amsdal_server/apps/objects/services/object_versions_api.py +206 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/transactions/controllers/transaction_execute.py +1 -1
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/transactions/services/transaction_execution_api.py +11 -4
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/transactions/utils.py +8 -2
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/server.py +6 -1
- amsdal_server-0.3.0/latest-changelogs.md +0 -6
- amsdal_server-0.3.0/src/amsdal_server/apps/common/response.py +0 -23
- amsdal_server-0.3.0/src/amsdal_server/apps/objects/services/file_object.py +0 -32
- amsdal_server-0.3.0/src/amsdal_server/apps/objects/services/object_api.py +0 -426
- amsdal_server-0.3.0/src/amsdal_server/apps/objects/services/object_list_api.py +0 -183
- amsdal_server-0.3.0/src/amsdal_server/apps/objects/services/object_versions_api.py +0 -94
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/.editorconfig +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/.gitignore +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/CONTRIBUTING.md +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/LICENSE.txt +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/README.md +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/license_check.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/release_notes/.gitkeep +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/scripts/release.sh +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/scripts/tag_check.sh +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/Third-Party Materials - AMSDAL Dependencies - License Notices.md +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/__init__.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/__init__.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/classes/__init__.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/classes/controllers/__init__.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/classes/controllers/class_create.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/classes/controllers/class_delete.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/classes/errors.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/classes/mixins/__init__.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/classes/mixins/column_info_mixin.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/classes/router.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/classes/serializers/__init__.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/classes/serializers/class_info.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/classes/serializers/register_class.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/classes/services/__init__.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/common/__init__.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/common/depends.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/common/error_handlers/__init__.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/common/error_handlers/class_not_found.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/common/error_handlers/invalid_auth.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/common/error_handlers/permission_error.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/common/error_handlers/validation_error_handler.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/common/errors.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/common/middlewares/__init__.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/common/middlewares/logger.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/common/middlewares/utils.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/common/mixins/__init__.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/common/otel.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/common/permissions/__init__.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/common/permissions/enums.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/common/permissions/models.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/common/serializers/__init__.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/common/serializers/base_serializer.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/common/serializers/column_format.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/common/serializers/column_response.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/common/serializers/fields_restriction.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/common/serializers/filter.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/common/serializers/objects_response.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/common/serializers/option.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/common/serializers/validator.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/common/thumbnail.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/healthcheck/__init__.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/healthcheck/controllers/__init__.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/healthcheck/controllers/liveness.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/healthcheck/controllers/readiness.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/healthcheck/enums.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/healthcheck/router.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/healthcheck/serializers/__init__.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/healthcheck/serializers/healthcheck_result.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/healthcheck/services/__init__.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/healthcheck/services/checkers/__init__.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/healthcheck/services/checkers/base.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/healthcheck/services/healthcheck.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/objects/__init__.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/objects/controllers/__init__.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/objects/controllers/object_delete.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/objects/controllers/object_validate.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/objects/mixins/__init__.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/objects/router.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/objects/services/__init__.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/objects/utils.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/router.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/transactions/__init__.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/transactions/controllers/__init__.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/transactions/controllers/transaction_list.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/transactions/mixins/__init__.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/transactions/mixins/ast_parser_mixin.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/transactions/router.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/transactions/serializers/__init__.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/transactions/serializers/transaction_item.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/transactions/serializers/transaction_property.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/transactions/services/__init__.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/transactions/services/transaction_api.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/configs/__init__.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/configs/constants.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/configs/main.py +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/docs/api.md +0 -0
- {amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/py.typed +0 -0
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## [v0.3.2](https://pypi.org/project/amsdal_server/0.3.2/) - 2024-12-07
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Added
|
|
5
|
+
|
|
6
|
+
- Async support (async-support)
|
|
7
|
+
## [v0.3.1](https://pypi.org/project/amsdal_server/0.3.1/) - 2024-12-02
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Added support for Inf values (inf-values)
|
|
1
13
|
## [v0.3.0](https://pypi.org/project/amsdal_server/0.3.0/) - 2024-11-28
|
|
2
14
|
|
|
3
15
|
|
|
@@ -70,15 +70,17 @@ python = ["3.10", "3.11", "3.12"]
|
|
|
70
70
|
path = "../.venv/amsdal_server"
|
|
71
71
|
dependencies = [
|
|
72
72
|
"coverage[toml]>=7.4",
|
|
73
|
-
"pytest==8.
|
|
74
|
-
"pytest-mock==3.
|
|
75
|
-
"pytest-subtests==0.
|
|
73
|
+
"pytest==8.3.3",
|
|
74
|
+
"pytest-mock==3.14.0",
|
|
75
|
+
"pytest-subtests==0.13.1",
|
|
76
|
+
"pytest-asyncio>=0.24.0",
|
|
76
77
|
"black>=24.3.0",
|
|
77
78
|
"mypy>=1.9.0",
|
|
78
79
|
"ruff>=0.3.3",
|
|
79
80
|
"httpx==0.27.*",
|
|
80
81
|
"types-openpyxl==3.*",
|
|
81
82
|
"towncrier==23.11.0",
|
|
83
|
+
"aiosqlite>=0.20.0",
|
|
82
84
|
]
|
|
83
85
|
|
|
84
86
|
[tool.hatch.envs.default.scripts]
|
|
@@ -114,18 +116,20 @@ template = "local"
|
|
|
114
116
|
path = "../.venv/amsdal_server_local"
|
|
115
117
|
dependencies = [
|
|
116
118
|
"coverage[toml]>=7.4",
|
|
117
|
-
"pytest==8.
|
|
118
|
-
"pytest-mock==3.
|
|
119
|
-
"pytest-subtests==0.
|
|
119
|
+
"pytest==8.3.3",
|
|
120
|
+
"pytest-mock==3.14.0",
|
|
121
|
+
"pytest-subtests==0.13.1",
|
|
122
|
+
"pytest-asyncio>=0.24.0",
|
|
120
123
|
"black>=24.3.0",
|
|
121
124
|
"mypy>=1.9.0",
|
|
122
125
|
"ruff>=0.3.3",
|
|
123
126
|
"httpx==0.27.*",
|
|
124
127
|
"types-openpyxl==3.*",
|
|
128
|
+
"aiosqlite>=0.20.0",
|
|
125
129
|
]
|
|
126
130
|
pre-install-commands = [
|
|
127
131
|
"pip install -e ../amsdal-glue/libs/core/",
|
|
128
|
-
"pip install -e ../amsdal-glue/libs/connections/[postgres-binary]",
|
|
132
|
+
"pip install -e ../amsdal-glue/libs/connections/[postgres-binary,async-sqlite]",
|
|
129
133
|
"pip install -e ../amsdal-glue/libs/amsdal-glue/",
|
|
130
134
|
"pip install -e ../amsdal_utils/",
|
|
131
135
|
"pip install -e ../amsdal_data/",
|
|
@@ -16,7 +16,7 @@ CLASS_DETAIL_CACHE = {}
|
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
async def _cache_class_details(request: Request, class_name: str) -> tuple[dict[str, Any], str]:
|
|
19
|
-
_data = ClassesApi.get_class_by_name(request.user, class_name).model_dump()
|
|
19
|
+
_data = (await ClassesApi.get_class_by_name(request.user, class_name)).model_dump()
|
|
20
20
|
|
|
21
21
|
content_bytes = json.dumps(_data, default=str).encode('utf-8')
|
|
22
22
|
|
{amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/classes/controllers/class_list.py
RENAMED
|
@@ -18,7 +18,7 @@ CLASS_LIST_CACHE = {}
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
async def _cache_class_list(request: Request) -> tuple[dict[str, Any], str]:
|
|
21
|
-
class_items = ClassesApi.get_classes(request.user)
|
|
21
|
+
class_items = await ClassesApi.get_classes(request.user)
|
|
22
22
|
_data = ObjectsResponse(
|
|
23
23
|
columns=[
|
|
24
24
|
ColumnInfo(
|
|
@@ -23,6 +23,18 @@ class ModelClassMixin:
|
|
|
23
23
|
|
|
24
24
|
return cls.get_model_class(class_item)
|
|
25
25
|
|
|
26
|
+
@classmethod
|
|
27
|
+
async def async_get_model_class_by_name(cls, class_name: str) -> type[Model]:
|
|
28
|
+
class_item: Model | None = (
|
|
29
|
+
await cls.get_class_objects_qs().latest().filter(_address__object_id=class_name).first().aexecute()
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
if not class_item:
|
|
33
|
+
msg = f'Class not found: {class_name}'
|
|
34
|
+
raise ClassNotFoundError(class_name, msg)
|
|
35
|
+
|
|
36
|
+
return cls.get_model_class(class_item)
|
|
37
|
+
|
|
26
38
|
@classmethod
|
|
27
39
|
def get_model_class(cls, class_item: Model) -> type[Model]:
|
|
28
40
|
class_manager = ClassManager()
|
{amsdal_server-0.3.0 → amsdal_server-0.3.2}/src/amsdal_server/apps/classes/services/classes_api.py
RENAMED
|
@@ -14,6 +14,7 @@ from amsdal_models.classes.utils import resolve_base_class_for_schema
|
|
|
14
14
|
from amsdal_models.classes.writer import ClassWriter
|
|
15
15
|
from amsdal_models.querysets.executor import LAKEHOUSE_DB_ALIAS
|
|
16
16
|
from amsdal_models.schemas.manager import BuildSchemasManager
|
|
17
|
+
from amsdal_utils.config.manager import AmsdalConfigManager
|
|
17
18
|
from amsdal_utils.models.data_models.enums import MetaClasses
|
|
18
19
|
from amsdal_utils.models.data_models.schema import ObjectSchema
|
|
19
20
|
from amsdal_utils.models.data_models.schema import PropertyData
|
|
@@ -34,7 +35,32 @@ from amsdal_server.apps.objects.mixins.object_data_mixin import ObjectDataMixin
|
|
|
34
35
|
|
|
35
36
|
class ClassesApi(PermissionsMixin, ModelClassMixin, ColumnInfoMixin, ObjectDataMixin):
|
|
36
37
|
@classmethod
|
|
37
|
-
def get_classes(cls, user: BaseUser) -> list[ClassInfo]:
|
|
38
|
+
async def get_classes(cls, user: BaseUser) -> list[ClassInfo]:
|
|
39
|
+
if AmsdalConfigManager().get_config().async_mode:
|
|
40
|
+
return await cls._aget_classes(user)
|
|
41
|
+
|
|
42
|
+
return await cls._get_classes(user)
|
|
43
|
+
|
|
44
|
+
@classmethod
|
|
45
|
+
async def _aget_classes(cls, user: BaseUser) -> list[ClassInfo]:
|
|
46
|
+
classes: list[Model] = await cls.get_class_objects_qs().aexecute()
|
|
47
|
+
class_metas: dict[str, Model] = {
|
|
48
|
+
_item.object_id: _item for _item in await cls.get_class_object_metas_qs(classes).aexecute()
|
|
49
|
+
}
|
|
50
|
+
result: list[ClassInfo] = []
|
|
51
|
+
|
|
52
|
+
for class_item in classes:
|
|
53
|
+
if class_item.object_id not in class_metas:
|
|
54
|
+
# some core class, skip it
|
|
55
|
+
continue
|
|
56
|
+
|
|
57
|
+
class_meta_item = class_metas[class_item.object_id] # type: ignore[index]
|
|
58
|
+
result.append(await cls.get_class(user, class_item, class_meta_item))
|
|
59
|
+
|
|
60
|
+
return result
|
|
61
|
+
|
|
62
|
+
@classmethod
|
|
63
|
+
async def _get_classes(cls, user: BaseUser) -> list[ClassInfo]:
|
|
38
64
|
classes: list[Model] = cls.get_class_objects_qs().execute()
|
|
39
65
|
class_metas: dict[str, Model] = {
|
|
40
66
|
_item.object_id: _item for _item in cls.get_class_object_metas_qs(classes).execute()
|
|
@@ -47,28 +73,79 @@ class ClassesApi(PermissionsMixin, ModelClassMixin, ColumnInfoMixin, ObjectDataM
|
|
|
47
73
|
continue
|
|
48
74
|
|
|
49
75
|
class_meta_item = class_metas[class_item.object_id] # type: ignore[index]
|
|
50
|
-
result.append(cls.get_class(user, class_item, class_meta_item))
|
|
76
|
+
result.append(await cls.get_class(user, class_item, class_meta_item))
|
|
51
77
|
|
|
52
78
|
return result
|
|
53
79
|
|
|
54
80
|
@classmethod
|
|
55
|
-
def get_class_by_name(
|
|
81
|
+
async def get_class_by_name(
|
|
56
82
|
cls,
|
|
57
83
|
user: BaseUser,
|
|
58
84
|
class_name: str,
|
|
59
85
|
) -> ClassInfo:
|
|
60
|
-
|
|
86
|
+
|
|
87
|
+
class_item: Model | None
|
|
88
|
+
if AmsdalConfigManager().get_config().async_mode:
|
|
89
|
+
class_item = await cls.get_class_objects_qs().filter(_address__object_id=class_name).first().aexecute()
|
|
90
|
+
else:
|
|
91
|
+
class_item = cls.get_class_objects_qs().filter(_address__object_id=class_name).first().execute()
|
|
61
92
|
|
|
62
93
|
if not class_item:
|
|
63
94
|
msg = f'Class not found: {class_name}'
|
|
64
95
|
raise ClassNotFoundError(class_name, msg)
|
|
65
96
|
|
|
66
|
-
class_meta_item: Model
|
|
97
|
+
class_meta_item: Model
|
|
98
|
+
if AmsdalConfigManager().get_config().async_mode:
|
|
99
|
+
class_meta_item = (
|
|
100
|
+
await cls.get_class_object_metas_qs().get(_address__object_id=class_item.object_id).aexecute()
|
|
101
|
+
)
|
|
102
|
+
else:
|
|
103
|
+
class_meta_item = cls.get_class_object_metas_qs().get(_address__object_id=class_item.object_id).execute()
|
|
104
|
+
|
|
105
|
+
return await cls.get_class(user, class_item, class_meta_item)
|
|
106
|
+
|
|
107
|
+
@classmethod
|
|
108
|
+
async def get_class(
|
|
109
|
+
cls,
|
|
110
|
+
user: BaseUser,
|
|
111
|
+
class_item: Model,
|
|
112
|
+
class_meta_item: Model,
|
|
113
|
+
) -> ClassInfo:
|
|
114
|
+
if AmsdalConfigManager().get_config().async_mode:
|
|
115
|
+
return await cls._aget_class(user, class_item, class_meta_item)
|
|
116
|
+
|
|
117
|
+
return await cls._get_class(user, class_item, class_meta_item)
|
|
118
|
+
|
|
119
|
+
@classmethod
|
|
120
|
+
async def _aget_class(
|
|
121
|
+
cls,
|
|
122
|
+
user: BaseUser,
|
|
123
|
+
class_item: Model,
|
|
124
|
+
class_meta_item: Model,
|
|
125
|
+
) -> ClassInfo:
|
|
126
|
+
model_class = cls.get_model_class(class_item)
|
|
67
127
|
|
|
68
|
-
|
|
128
|
+
try:
|
|
129
|
+
permissions_info = await cls.async_get_permissions_info(model_class, user)
|
|
130
|
+
has_read_permission = permissions_info.has_read_permission
|
|
131
|
+
except AmsdalPermissionError:
|
|
132
|
+
has_read_permission = False
|
|
133
|
+
|
|
134
|
+
class_properties = cls.get_class_properties_by_class_and_meta(class_item, class_meta_item)
|
|
135
|
+
data: dict[str, Any] = {
|
|
136
|
+
'class': class_item.object_id,
|
|
137
|
+
'count': 0,
|
|
138
|
+
'properties': class_properties,
|
|
139
|
+
}
|
|
140
|
+
class_info = ClassInfo(**data)
|
|
141
|
+
|
|
142
|
+
if has_read_permission:
|
|
143
|
+
class_info.count = await model_class.objects.latest().filter(_metadata__is_deleted=False).count().aexecute()
|
|
144
|
+
|
|
145
|
+
return class_info
|
|
69
146
|
|
|
70
147
|
@classmethod
|
|
71
|
-
def
|
|
148
|
+
async def _get_class(
|
|
72
149
|
cls,
|
|
73
150
|
user: BaseUser,
|
|
74
151
|
class_item: Model,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from typing import Any
|
|
2
2
|
|
|
3
|
+
from amsdal_utils.config.manager import AmsdalConfigManager
|
|
3
4
|
from starlette.authentication import AuthCredentials
|
|
4
5
|
from starlette.authentication import AuthenticationBackend
|
|
5
6
|
from starlette.authentication import BaseUser
|
|
@@ -59,11 +60,18 @@ class AmsdalAuthenticationBackend(AuthenticationBackend):
|
|
|
59
60
|
if settings.AUTHORIZATION_HEADER in conn.headers:
|
|
60
61
|
auth = conn.headers[settings.AUTHORIZATION_HEADER]
|
|
61
62
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
if AmsdalConfigManager().get_config().async_mode:
|
|
64
|
+
await LifecycleProducer.publish_async(
|
|
65
|
+
LifecycleEvent.ON_AUTHENTICATE,
|
|
66
|
+
auth_header=auth,
|
|
67
|
+
authentication_info=authentication_info,
|
|
68
|
+
)
|
|
69
|
+
else:
|
|
70
|
+
LifecycleProducer.publish(
|
|
71
|
+
LifecycleEvent.ON_AUTHENTICATE,
|
|
72
|
+
auth_header=auth,
|
|
73
|
+
authentication_info=authentication_info,
|
|
74
|
+
)
|
|
67
75
|
conn.scope['user'] = authentication_info.user
|
|
68
76
|
|
|
69
77
|
return authentication_info.credentials, authentication_info.user
|
|
@@ -3,6 +3,7 @@ import logging
|
|
|
3
3
|
from collections.abc import AsyncGenerator
|
|
4
4
|
|
|
5
5
|
from amsdal.contrib.frontend_configs.constants import ON_RESPONSE_EVENT
|
|
6
|
+
from amsdal_utils.config.manager import AmsdalConfigManager
|
|
6
7
|
from amsdal_utils.lifecycle.producer import LifecycleProducer
|
|
7
8
|
from starlette.middleware.base import BaseHTTPMiddleware
|
|
8
9
|
from starlette.middleware.base import RequestResponseEndpoint
|
|
@@ -37,11 +38,19 @@ class ResponseEventMiddleware(BaseHTTPMiddleware):
|
|
|
37
38
|
if data:
|
|
38
39
|
response_dict = json.loads(data)
|
|
39
40
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
if AmsdalConfigManager().get_config().async_mode:
|
|
42
|
+
await LifecycleProducer.publish_async(
|
|
43
|
+
ON_RESPONSE_EVENT, # type: ignore[arg-type]
|
|
44
|
+
request=request,
|
|
45
|
+
response=response_dict,
|
|
46
|
+
)
|
|
47
|
+
else:
|
|
48
|
+
LifecycleProducer.publish(
|
|
49
|
+
ON_RESPONSE_EVENT, # type: ignore[arg-type]
|
|
50
|
+
request=request,
|
|
51
|
+
response=response_dict,
|
|
52
|
+
)
|
|
53
|
+
|
|
45
54
|
_result = JSONResponse.render(
|
|
46
55
|
response, # type: ignore[arg-type]
|
|
47
56
|
response_dict,
|
|
@@ -37,3 +37,31 @@ class PermissionsMixin:
|
|
|
37
37
|
)
|
|
38
38
|
|
|
39
39
|
return permissions_info
|
|
40
|
+
|
|
41
|
+
@classmethod
|
|
42
|
+
async def async_get_permissions_info(
|
|
43
|
+
cls,
|
|
44
|
+
class_item: type[Model],
|
|
45
|
+
user: BaseUser,
|
|
46
|
+
access_types: list[AccessTypes] | None = None,
|
|
47
|
+
obj: Model | None = None,
|
|
48
|
+
) -> PermissionsInfo:
|
|
49
|
+
permissions_info = PermissionsInfo()
|
|
50
|
+
_access_types = access_types or [AccessTypes.READ]
|
|
51
|
+
|
|
52
|
+
if getattr(user, 'permissions', None):
|
|
53
|
+
user.permissions = [ # type: ignore[attr-defined]
|
|
54
|
+
await ReferenceLoader(p).aload_reference() if isinstance(p, Reference) else p
|
|
55
|
+
for p in user.permissions # type: ignore[attr-defined]
|
|
56
|
+
]
|
|
57
|
+
|
|
58
|
+
await LifecycleProducer.publish_async(
|
|
59
|
+
LifecycleEvent.ON_PERMISSION_CHECK,
|
|
60
|
+
object_class=class_item,
|
|
61
|
+
user=user,
|
|
62
|
+
access_types=_access_types,
|
|
63
|
+
permissions_info=permissions_info,
|
|
64
|
+
obj=obj,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
return permissions_info
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
from json import JSONEncoder
|
|
4
|
+
from json.encoder import _make_iterencode # type: ignore[attr-defined]
|
|
5
|
+
from json.encoder import encode_basestring
|
|
6
|
+
from json.encoder import encode_basestring_ascii
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
from starlette.responses import JSONResponse
|
|
10
|
+
|
|
11
|
+
try:
|
|
12
|
+
from _json import make_encoder as c_make_encoder
|
|
13
|
+
except ImportError:
|
|
14
|
+
c_make_encoder = None # type: ignore[misc, assignment]
|
|
15
|
+
|
|
16
|
+
INFINITY = float('inf')
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class CustomJSONEncoder(JSONEncoder):
|
|
20
|
+
def iterencode(self, o: Any, _one_shot: bool = False) -> Any: # noqa: FBT001, FBT002
|
|
21
|
+
"""Encode the given object and yield each string
|
|
22
|
+
representation as available.
|
|
23
|
+
|
|
24
|
+
For example::
|
|
25
|
+
|
|
26
|
+
for chunk in JSONEncoder().iterencode(bigobject):
|
|
27
|
+
mysocket.write(chunk)
|
|
28
|
+
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
markers: dict[Any, Any] | None = {} if self.check_circular else None
|
|
32
|
+
|
|
33
|
+
if self.ensure_ascii:
|
|
34
|
+
_encoder = encode_basestring_ascii
|
|
35
|
+
else:
|
|
36
|
+
_encoder = encode_basestring
|
|
37
|
+
|
|
38
|
+
def floatstr( # type: ignore[no-untyped-def]
|
|
39
|
+
o,
|
|
40
|
+
allow_nan=self.allow_nan,
|
|
41
|
+
_repr=float.__repr__,
|
|
42
|
+
_inf=INFINITY,
|
|
43
|
+
_neginf=-INFINITY,
|
|
44
|
+
):
|
|
45
|
+
# Check for specials. Note that this type of test is processor
|
|
46
|
+
# and/or platform-specific, so do tests which don't depend on the
|
|
47
|
+
# internals.
|
|
48
|
+
|
|
49
|
+
if o != o: # noqa: PLR0124
|
|
50
|
+
text = 'NaN'
|
|
51
|
+
elif o == _inf:
|
|
52
|
+
# TODO: our custom implementation
|
|
53
|
+
return '"Infinity"'
|
|
54
|
+
elif o == _neginf:
|
|
55
|
+
# TODO: our custom implementation
|
|
56
|
+
return '"-Infinity"'
|
|
57
|
+
else:
|
|
58
|
+
return _repr(o)
|
|
59
|
+
|
|
60
|
+
if not allow_nan:
|
|
61
|
+
raise ValueError('Out of range float values are not JSON compliant: ' + repr(o))
|
|
62
|
+
|
|
63
|
+
return text
|
|
64
|
+
|
|
65
|
+
# TODO: due to the way we handle Infinity, we cannot use c_make_iterencode
|
|
66
|
+
_iterencode = _make_iterencode(
|
|
67
|
+
markers,
|
|
68
|
+
self.default,
|
|
69
|
+
_encoder,
|
|
70
|
+
self.indent,
|
|
71
|
+
floatstr,
|
|
72
|
+
self.key_separator,
|
|
73
|
+
self.item_separator,
|
|
74
|
+
self.sort_keys,
|
|
75
|
+
self.skipkeys,
|
|
76
|
+
_one_shot,
|
|
77
|
+
)
|
|
78
|
+
return _iterencode(o, 0)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def default_json_encoder(obj: Any) -> Any:
|
|
82
|
+
if isinstance(obj, datetime):
|
|
83
|
+
return obj.isoformat()
|
|
84
|
+
return str(obj)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class AmsdalJSONResponse(JSONResponse):
|
|
88
|
+
def render(self, content: Any) -> bytes:
|
|
89
|
+
return json.dumps(
|
|
90
|
+
content,
|
|
91
|
+
ensure_ascii=False,
|
|
92
|
+
allow_nan=False,
|
|
93
|
+
indent=None,
|
|
94
|
+
separators=(',', ':'),
|
|
95
|
+
default=default_json_encoder,
|
|
96
|
+
cls=CustomJSONEncoder,
|
|
97
|
+
).encode('utf-8')
|
|
@@ -8,6 +8,7 @@ from amsdal_models.classes.data_models.dependencies import DependencyModelNames
|
|
|
8
8
|
from amsdal_models.classes.errors import AmsdalClassNotFoundError
|
|
9
9
|
from amsdal_models.classes.helpers.reference_loader import ReferenceLoader
|
|
10
10
|
from amsdal_models.classes.manager import ClassManager
|
|
11
|
+
from amsdal_models.classes.model import Model
|
|
11
12
|
from amsdal_models.classes.utils import resolve_base_class_for_schema
|
|
12
13
|
from amsdal_models.classes.writer import ClassWriter
|
|
13
14
|
from amsdal_models.querysets.executor import LAKEHOUSE_DB_ALIAS
|
|
@@ -37,12 +38,8 @@ def build_missing_models() -> list[str]:
|
|
|
37
38
|
)
|
|
38
39
|
|
|
39
40
|
model = None
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
model = ClassManager().import_model_class(object_meta.title, _schema_type)
|
|
43
|
-
|
|
44
|
-
if model:
|
|
45
|
-
break
|
|
41
|
+
with contextlib.suppress(AmsdalClassNotFoundError):
|
|
42
|
+
model = import_class_model(object_meta.title)
|
|
46
43
|
|
|
47
44
|
if not model:
|
|
48
45
|
missed_models.append(object_meta.title)
|
|
@@ -85,3 +82,13 @@ def get_subclasses(class_item: type[ModelBase] | None) -> Iterator[type[ModelBas
|
|
|
85
82
|
subclass_name,
|
|
86
83
|
schema_type,
|
|
87
84
|
)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def import_class_model(class_name: str) -> type[Model]:
|
|
88
|
+
class_manager = ClassManager()
|
|
89
|
+
|
|
90
|
+
for _schema_type in [SchemaTypes.USER, SchemaTypes.CONTRIB]:
|
|
91
|
+
with contextlib.suppress(AmsdalClassNotFoundError):
|
|
92
|
+
return class_manager.import_model_class(class_name, _schema_type)
|
|
93
|
+
|
|
94
|
+
return class_manager.import_model_class(class_name, SchemaTypes.CORE)
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
from amsdal_data.application import AsyncDataApplication
|
|
1
2
|
from amsdal_data.application import DataApplication
|
|
3
|
+
from amsdal_utils.config.manager import AmsdalConfigManager
|
|
2
4
|
|
|
3
5
|
from amsdal_server.apps.healthcheck.enums import StatusEnum
|
|
4
6
|
from amsdal_server.apps.healthcheck.serializers.healthcheck_result import HealthcheckServiceResult
|
|
@@ -7,9 +9,13 @@ from amsdal_server.apps.healthcheck.services.checkers.base import BaseHealthchec
|
|
|
7
9
|
|
|
8
10
|
class ConnectionsHealthchecker(BaseHealthchecker):
|
|
9
11
|
async def check(self) -> HealthcheckServiceResult:
|
|
10
|
-
|
|
12
|
+
if AmsdalConfigManager().get_config().async_mode:
|
|
13
|
+
connections_statuses = await AsyncDataApplication().connections_statuses
|
|
11
14
|
|
|
12
|
-
|
|
15
|
+
else:
|
|
16
|
+
connections_statuses = DataApplication().connections_statuses
|
|
17
|
+
|
|
18
|
+
for connection in connections_statuses:
|
|
13
19
|
if not connection.is_connected:
|
|
14
20
|
return HealthcheckServiceResult(
|
|
15
21
|
status=StatusEnum.error,
|
|
@@ -18,7 +18,7 @@ async def object_bulk_create(
|
|
|
18
18
|
load_references: bool = False,
|
|
19
19
|
data: list[dict[str, Any]] = Body(...),
|
|
20
20
|
) -> list[dict[str, Any]]:
|
|
21
|
-
return ObjectApi.bulk_create_objects(
|
|
21
|
+
return await ObjectApi.bulk_create_objects(
|
|
22
22
|
request.user,
|
|
23
23
|
base_url=str(request.base_url),
|
|
24
24
|
class_name=class_name,
|
|
@@ -35,7 +35,7 @@ async def object_bulk_update(
|
|
|
35
35
|
data: list[BulkUpdateBody] = Body(...),
|
|
36
36
|
load_references: bool = False,
|
|
37
37
|
) -> Any:
|
|
38
|
-
return ObjectApi.bulk_update_objects(
|
|
38
|
+
return await ObjectApi.bulk_update_objects(
|
|
39
39
|
request.user,
|
|
40
40
|
base_url=str(request.base_url),
|
|
41
41
|
data=data,
|
|
@@ -50,7 +50,7 @@ async def object_bulk_partial_update(
|
|
|
50
50
|
data: list[BulkUpdateBody] = Body(...),
|
|
51
51
|
load_references: bool = False,
|
|
52
52
|
) -> Any:
|
|
53
|
-
return ObjectApi.bulk_partial_update_objects(
|
|
53
|
+
return await ObjectApi.bulk_partial_update_objects(
|
|
54
54
|
request.user,
|
|
55
55
|
base_url=str(request.base_url),
|
|
56
56
|
data=data,
|
|
@@ -64,4 +64,4 @@ async def object_bulk_delete(
|
|
|
64
64
|
*,
|
|
65
65
|
data: list[BulkAddressBody] = Body(...),
|
|
66
66
|
) -> None:
|
|
67
|
-
ObjectApi.bulk_delete_objects(request.user, data=data)
|
|
67
|
+
await ObjectApi.bulk_delete_objects(request.user, data=data)
|
|
@@ -18,14 +18,14 @@ from amsdal_server.apps.objects.services.file_object import ObjectFileApi
|
|
|
18
18
|
logger = logging.getLogger(__name__)
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
def _download_file(
|
|
21
|
+
async def _download_file(
|
|
22
22
|
object_id: str,
|
|
23
23
|
request: Request,
|
|
24
24
|
version_id: str = '',
|
|
25
25
|
width: int | None = None,
|
|
26
26
|
height: int | None = None,
|
|
27
27
|
) -> Response:
|
|
28
|
-
file_obj = ObjectFileApi.get_file(
|
|
28
|
+
file_obj = await ObjectFileApi.get_file(
|
|
29
29
|
request.user,
|
|
30
30
|
object_id,
|
|
31
31
|
version_id or Versions.LATEST,
|
|
@@ -84,7 +84,7 @@ async def file_download(
|
|
|
84
84
|
width: Optional[int] = Query(None), # noqa: UP007
|
|
85
85
|
height: Optional[int] = Query(None), # noqa: UP007
|
|
86
86
|
) -> Response:
|
|
87
|
-
return _download_file(object_id, request, version_id, width, height)
|
|
87
|
+
return await _download_file(object_id, request, version_id, width, height)
|
|
88
88
|
|
|
89
89
|
|
|
90
90
|
@router.get('/api/objects/download-file/')
|
|
@@ -95,4 +95,4 @@ async def download_file(
|
|
|
95
95
|
width: Optional[int] = Query(None), # noqa: UP007
|
|
96
96
|
height: Optional[int] = Query(None), # noqa: UP007
|
|
97
97
|
) -> Response:
|
|
98
|
-
return _download_file(unquote(object_id), request, version_id, width, height)
|
|
98
|
+
return await _download_file(unquote(object_id), request, version_id, width, height)
|
|
@@ -16,7 +16,7 @@ async def object_create(
|
|
|
16
16
|
load_references: bool = False,
|
|
17
17
|
data: dict[str, Any] = Body(...),
|
|
18
18
|
) -> dict[str, Any]:
|
|
19
|
-
return ObjectApi.create_object(
|
|
19
|
+
return await ObjectApi.create_object(
|
|
20
20
|
request.user,
|
|
21
21
|
base_url=str(request.base_url),
|
|
22
22
|
class_name=class_name,
|
|
@@ -27,15 +27,17 @@ async def _cache_object_detail(
|
|
|
27
27
|
) -> tuple[dict[str, Any], str]:
|
|
28
28
|
_select_related = select_related.split(',') if select_related else None
|
|
29
29
|
|
|
30
|
-
_data =
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
30
|
+
_data = (
|
|
31
|
+
await ObjectVersionsApi.get_object_versions(
|
|
32
|
+
request.user,
|
|
33
|
+
base_url=str(request.base_url),
|
|
34
|
+
address=urllib.parse.unquote(address),
|
|
35
|
+
version_id=version_id,
|
|
36
|
+
all_versions=all_versions,
|
|
37
|
+
include_metadata=include_metadata,
|
|
38
|
+
file_optimized=file_optimized,
|
|
39
|
+
select_related=_select_related,
|
|
40
|
+
)
|
|
39
41
|
).model_dump()
|
|
40
42
|
|
|
41
43
|
content_bytes = json.dumps(_data, default=str).encode('utf-8')
|
|
@@ -38,21 +38,23 @@ async def _cache_object_list(
|
|
|
38
38
|
) -> tuple[dict[str, Any], str]:
|
|
39
39
|
_select_related = select_related.split(',') if select_related else None
|
|
40
40
|
|
|
41
|
-
_data =
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
41
|
+
_data = (
|
|
42
|
+
await ObjectListApi.fetch_objects(
|
|
43
|
+
request.user,
|
|
44
|
+
base_url=str(request.base_url),
|
|
45
|
+
class_name=class_name,
|
|
46
|
+
filters=filters,
|
|
47
|
+
fields_restrictions=fields_restrictions,
|
|
48
|
+
include_metadata=include_metadata,
|
|
49
|
+
include_subclasses=include_subclasses,
|
|
50
|
+
load_references=load_references,
|
|
51
|
+
all_versions=all_versions,
|
|
52
|
+
file_optimized=file_optimized,
|
|
53
|
+
page=page,
|
|
54
|
+
page_size=page_size,
|
|
55
|
+
ordering=ordering,
|
|
56
|
+
select_related=_select_related,
|
|
57
|
+
)
|
|
56
58
|
).model_dump()
|
|
57
59
|
|
|
58
60
|
content_bytes = json.dumps(_data, default=str).encode('utf-8')
|