crudadmin 0.3.2__tar.gz → 0.3.4__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.
- {crudadmin-0.3.2 → crudadmin-0.3.4}/.gitignore +8 -2
- {crudadmin-0.3.2 → crudadmin-0.3.4}/PKG-INFO +18 -3
- {crudadmin-0.3.2 → crudadmin-0.3.4}/README.md +17 -2
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/admin_interface/admin_site.py +3 -1
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/admin_interface/crud_admin.py +36 -2
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/admin_interface/model_view.py +17 -4
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/admin_user/models.py +3 -1
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/core/schemas/timestamp.py +6 -4
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/event/decorators.py +3 -1
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/event/models.py +3 -1
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/event/service.py +3 -1
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/session/backends/database.py +3 -1
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/session/backends/memory.py +3 -1
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/session/manager.py +3 -1
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/session/models.py +3 -1
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/session/schemas.py +3 -1
- {crudadmin-0.3.2 → crudadmin-0.3.4}/pyproject.toml +1 -1
- {crudadmin-0.3.2 → crudadmin-0.3.4}/LICENSE +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/__init__.py +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/admin_interface/__init__.py +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/admin_interface/auth.py +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/admin_interface/helper.py +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/admin_interface/middleware/__init__.py +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/admin_interface/middleware/auth.py +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/admin_interface/middleware/https.py +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/admin_interface/middleware/ip_restriction.py +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/admin_interface/typing.py +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/admin_user/__init__.py +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/admin_user/schemas.py +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/admin_user/service.py +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/core/__init__.py +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/core/auth.py +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/core/db.py +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/core/exceptions.py +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/core/rate_limiter.py +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/core/schemas/__init__.py +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/event/__init__.py +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/event/integration.py +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/event/schemas.py +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/py.typed +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/session/__init__.py +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/session/backends/__init__.py +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/session/backends/hybrid.py +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/session/backends/memcached.py +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/session/backends/redis.py +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/session/storage.py +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/session/user_agents_types.py +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/static/favicon.png +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/static/htmx.min.js +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/templates/admin/dashboard/dashboard.html +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/templates/admin/dashboard/dashboard_content.html +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/templates/admin/management/events.html +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/templates/admin/management/events_content.html +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/templates/admin/management/health.html +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/templates/admin/management/health_content.html +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/templates/admin/model/components/list_content.html +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/templates/admin/model/components/pagination.html +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/templates/admin/model/components/table_content.html +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/templates/admin/model/create.html +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/templates/admin/model/list.html +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/templates/admin/model/update.html +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/templates/auth/login.html +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/templates/base/base.html +0 -0
- {crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/templates/shared/utils/refresh.html +0 -0
|
@@ -61,6 +61,12 @@ local_settings.py
|
|
|
61
61
|
db.sqlite3
|
|
62
62
|
db.sqlite3-journal
|
|
63
63
|
|
|
64
|
+
# SQLite databases
|
|
65
|
+
*.db
|
|
66
|
+
*.db-journal*
|
|
67
|
+
*.sqlite
|
|
68
|
+
*.sqlite3
|
|
69
|
+
|
|
64
70
|
# Flask stuff:
|
|
65
71
|
instance/
|
|
66
72
|
.webassets-cache
|
|
@@ -167,6 +173,6 @@ cython_debug/
|
|
|
167
173
|
.ruff_cache
|
|
168
174
|
|
|
169
175
|
uv.lock
|
|
170
|
-
.python-version
|
|
171
176
|
|
|
172
|
-
local_test
|
|
177
|
+
local_test
|
|
178
|
+
crudadmin_data/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: crudadmin
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.4
|
|
4
4
|
Summary: FastAPI-based admin interface with authentication, event logging and CRUD operations
|
|
5
5
|
Project-URL: Homepage, https://github.com/benavlabs/crudadmin
|
|
6
6
|
Project-URL: Documentation, https://benavlabs.github.io/crudadmin
|
|
@@ -115,8 +115,8 @@ Description-Content-Type: text/markdown
|
|
|
115
115
|
|
|
116
116
|
**Documentation**: [https://benavlabs.github.io/crudadmin/](https://benavlabs.github.io/crudadmin/)
|
|
117
117
|
|
|
118
|
-
> [!WARNING]
|
|
119
|
-
> CRUDAdmin is still experimental. While actively developed and tested, APIs may change between versions. Upgrade with caution in production environments, always
|
|
118
|
+
> \[!WARNING\]
|
|
119
|
+
> CRUDAdmin is still experimental. While actively developed and tested, APIs may change between versions. Upgrade with caution in production environments, always carefully reading the changelog.
|
|
120
120
|
|
|
121
121
|
## Features
|
|
122
122
|
|
|
@@ -218,6 +218,21 @@ Navigate to `/admin` to access your admin interface with:
|
|
|
218
218
|
- Responsive UI with dark/light themes
|
|
219
219
|
- Built-in security features
|
|
220
220
|
|
|
221
|
+
> \[!WARNING\]
|
|
222
|
+
> **Important for SQLite users:** If you're using SQLite databases (which is the default for CRUDAdmin), make sure to add database files to your `.gitignore` to avoid committing sensitive data like admin credentials and session tokens.
|
|
223
|
+
>
|
|
224
|
+
> ```gitignore
|
|
225
|
+
> # SQLite databases - NEVER commit these to version control
|
|
226
|
+
> *.db
|
|
227
|
+
> *.sqlite
|
|
228
|
+
> *.sqlite3
|
|
229
|
+
> crudadmin_data/
|
|
230
|
+
>
|
|
231
|
+
> # Also exclude database journals
|
|
232
|
+
> *.db-journal
|
|
233
|
+
> *.sqlite3-journal
|
|
234
|
+
> ```
|
|
235
|
+
|
|
221
236
|
## Session Backends
|
|
222
237
|
|
|
223
238
|
### Development (Default)
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
|
|
29
29
|
**Documentation**: [https://benavlabs.github.io/crudadmin/](https://benavlabs.github.io/crudadmin/)
|
|
30
30
|
|
|
31
|
-
> [!WARNING]
|
|
32
|
-
> CRUDAdmin is still experimental. While actively developed and tested, APIs may change between versions. Upgrade with caution in production environments, always
|
|
31
|
+
> \[!WARNING\]
|
|
32
|
+
> CRUDAdmin is still experimental. While actively developed and tested, APIs may change between versions. Upgrade with caution in production environments, always carefully reading the changelog.
|
|
33
33
|
|
|
34
34
|
## Features
|
|
35
35
|
|
|
@@ -131,6 +131,21 @@ Navigate to `/admin` to access your admin interface with:
|
|
|
131
131
|
- Responsive UI with dark/light themes
|
|
132
132
|
- Built-in security features
|
|
133
133
|
|
|
134
|
+
> \[!WARNING\]
|
|
135
|
+
> **Important for SQLite users:** If you're using SQLite databases (which is the default for CRUDAdmin), make sure to add database files to your `.gitignore` to avoid committing sensitive data like admin credentials and session tokens.
|
|
136
|
+
>
|
|
137
|
+
> ```gitignore
|
|
138
|
+
> # SQLite databases - NEVER commit these to version control
|
|
139
|
+
> *.db
|
|
140
|
+
> *.sqlite
|
|
141
|
+
> *.sqlite3
|
|
142
|
+
> crudadmin_data/
|
|
143
|
+
>
|
|
144
|
+
> # Also exclude database journals
|
|
145
|
+
> *.db-journal
|
|
146
|
+
> *.sqlite3-journal
|
|
147
|
+
> ```
|
|
148
|
+
|
|
134
149
|
## Session Backends
|
|
135
150
|
|
|
136
151
|
### Development (Default)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
from collections.abc import AsyncGenerator, Callable
|
|
3
|
-
from datetime import
|
|
3
|
+
from datetime import datetime, timezone
|
|
4
4
|
from typing import Any, Dict, Optional, cast
|
|
5
5
|
|
|
6
6
|
from fastapi import APIRouter, Cookie, Depends, Request, Response
|
|
@@ -19,6 +19,8 @@ from ..session.storage import AbstractSessionStorage, get_session_storage
|
|
|
19
19
|
from .auth import AdminAuthentication
|
|
20
20
|
from .typing import RouteResponse
|
|
21
21
|
|
|
22
|
+
UTC = timezone.utc
|
|
23
|
+
|
|
22
24
|
logger = logging.getLogger(__name__)
|
|
23
25
|
|
|
24
26
|
EndpointCallable = Callable[..., Any]
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import os
|
|
3
|
+
import sys
|
|
3
4
|
import time
|
|
4
5
|
from collections.abc import Awaitable, Callable
|
|
5
|
-
from datetime import
|
|
6
|
+
from datetime import datetime, timedelta, timezone
|
|
6
7
|
from typing import (
|
|
7
8
|
Any,
|
|
8
9
|
AsyncGenerator,
|
|
@@ -10,13 +11,17 @@ from typing import (
|
|
|
10
11
|
List,
|
|
11
12
|
Optional,
|
|
12
13
|
Type,
|
|
13
|
-
TypeAlias,
|
|
14
14
|
TypedDict,
|
|
15
15
|
TypeVar,
|
|
16
16
|
Union,
|
|
17
17
|
cast,
|
|
18
18
|
)
|
|
19
19
|
|
|
20
|
+
if sys.version_info >= (3, 10):
|
|
21
|
+
from typing import TypeAlias
|
|
22
|
+
else:
|
|
23
|
+
from typing_extensions import TypeAlias
|
|
24
|
+
|
|
20
25
|
from fastapi import APIRouter, Depends, FastAPI, Request
|
|
21
26
|
from fastapi.security import OAuth2PasswordBearer
|
|
22
27
|
from fastapi.staticfiles import StaticFiles
|
|
@@ -43,6 +48,8 @@ from .admin_site import AdminSite
|
|
|
43
48
|
from .model_view import ModelView
|
|
44
49
|
from .typing import RouteResponse
|
|
45
50
|
|
|
51
|
+
UTC = timezone.utc
|
|
52
|
+
|
|
46
53
|
logger = logging.getLogger("crudadmin")
|
|
47
54
|
|
|
48
55
|
ModelType = TypeVar("ModelType", bound=DeclarativeBase)
|
|
@@ -796,6 +803,7 @@ class CRUDAdmin:
|
|
|
796
803
|
update_schema: Type[BaseModel],
|
|
797
804
|
update_internal_schema: Optional[Type[BaseModel]] = None,
|
|
798
805
|
delete_schema: Optional[Type[BaseModel]] = None,
|
|
806
|
+
select_schema: Optional[Type[BaseModel]] = None,
|
|
799
807
|
include_in_models: bool = True,
|
|
800
808
|
allowed_actions: Optional[set[str]] = None,
|
|
801
809
|
password_transformer: Optional[Any] = None,
|
|
@@ -812,6 +820,7 @@ class CRUDAdmin:
|
|
|
812
820
|
update_schema: Pydantic schema for update operations
|
|
813
821
|
update_internal_schema: Internal schema for special update cases
|
|
814
822
|
delete_schema: Schema for delete operations
|
|
823
|
+
select_schema: Optional schema for read operations (excludes fields from queries)
|
|
815
824
|
include_in_models: Show in models list in admin UI
|
|
816
825
|
allowed_actions: **Set of allowed operations:**
|
|
817
826
|
- **"view"**: Allow viewing records
|
|
@@ -828,6 +837,7 @@ class CRUDAdmin:
|
|
|
828
837
|
Notes:
|
|
829
838
|
- Forms are auto-generated with field types determined from Pydantic schemas
|
|
830
839
|
- Actions controlled by allowed_actions parameter
|
|
840
|
+
- Use select_schema to exclude problematic fields (e.g., TSVector) from read operations
|
|
831
841
|
- Use password_transformer for models with password fields that need hashing
|
|
832
842
|
|
|
833
843
|
URL Routes:
|
|
@@ -865,6 +875,29 @@ class CRUDAdmin:
|
|
|
865
875
|
)
|
|
866
876
|
```
|
|
867
877
|
|
|
878
|
+
Excluding problematic fields (e.g., TSVector):
|
|
879
|
+
```python
|
|
880
|
+
class DocumentCreate(BaseModel):
|
|
881
|
+
title: str
|
|
882
|
+
content: str
|
|
883
|
+
# TSVector field excluded from this schema
|
|
884
|
+
|
|
885
|
+
class DocumentSelect(BaseModel):
|
|
886
|
+
id: int
|
|
887
|
+
title: str
|
|
888
|
+
content: str
|
|
889
|
+
created_at: datetime
|
|
890
|
+
# search_vector (TSVector) field excluded
|
|
891
|
+
|
|
892
|
+
admin.add_view(
|
|
893
|
+
model=Document,
|
|
894
|
+
create_schema=DocumentCreate,
|
|
895
|
+
update_schema=DocumentCreate,
|
|
896
|
+
select_schema=DocumentSelect, # TSVector field excluded from reads
|
|
897
|
+
allowed_actions={"view", "create", "update"}
|
|
898
|
+
)
|
|
899
|
+
```
|
|
900
|
+
|
|
868
901
|
User with password handling:
|
|
869
902
|
```python
|
|
870
903
|
from crudadmin.admin_interface.model_view import PasswordTransformer
|
|
@@ -1021,6 +1054,7 @@ class CRUDAdmin:
|
|
|
1021
1054
|
update_schema=update_schema,
|
|
1022
1055
|
update_internal_schema=update_internal_schema,
|
|
1023
1056
|
delete_schema=delete_schema,
|
|
1057
|
+
select_schema=select_schema,
|
|
1024
1058
|
admin_site=self.admin_site,
|
|
1025
1059
|
allowed_actions=allowed_actions,
|
|
1026
1060
|
event_integration=self.event_integration,
|
|
@@ -772,7 +772,10 @@ class ModelView:
|
|
|
772
772
|
f"{pk_name}__in": valid_ids
|
|
773
773
|
}
|
|
774
774
|
records_to_delete = await self.crud.get_multi(
|
|
775
|
-
db=db,
|
|
775
|
+
db=db,
|
|
776
|
+
limit=len(valid_ids),
|
|
777
|
+
schema_to_select=self.select_schema,
|
|
778
|
+
**cast(Any, filter_criteria),
|
|
776
779
|
)
|
|
777
780
|
|
|
778
781
|
request.state.deleted_records = records_to_delete.get("data", [])
|
|
@@ -804,6 +807,7 @@ class ModelView:
|
|
|
804
807
|
db=db,
|
|
805
808
|
offset=(adjusted_page - 1) * rows_per_page,
|
|
806
809
|
limit=rows_per_page,
|
|
810
|
+
schema_to_select=self.select_schema,
|
|
807
811
|
)
|
|
808
812
|
|
|
809
813
|
items: Dict[str, Any] = {
|
|
@@ -947,6 +951,7 @@ class ModelView:
|
|
|
947
951
|
limit=rows_per_page,
|
|
948
952
|
sort_columns=sort_columns,
|
|
949
953
|
sort_orders=sort_orders,
|
|
954
|
+
schema_to_select=self.select_schema,
|
|
950
955
|
**cast(Any, filter_criteria),
|
|
951
956
|
)
|
|
952
957
|
|
|
@@ -1053,7 +1058,9 @@ class ModelView:
|
|
|
1053
1058
|
db: AsyncSession = Depends(self.session),
|
|
1054
1059
|
) -> Response:
|
|
1055
1060
|
"""Show a form to update an existing record by `id`."""
|
|
1056
|
-
item = await self.crud.get(
|
|
1061
|
+
item = await self.crud.get(
|
|
1062
|
+
db=db, id=id, schema_to_select=self.select_schema
|
|
1063
|
+
)
|
|
1057
1064
|
if not item:
|
|
1058
1065
|
return JSONResponse(
|
|
1059
1066
|
status_code=404, content={"message": f"Item with id {id} not found"}
|
|
@@ -1112,7 +1119,9 @@ class ModelView:
|
|
|
1112
1119
|
status_code=422, content={"message": "No id parameter provided"}
|
|
1113
1120
|
)
|
|
1114
1121
|
|
|
1115
|
-
item = await self.crud.get(
|
|
1122
|
+
item = await self.crud.get(
|
|
1123
|
+
db=db, id=id, schema_to_select=self.select_schema
|
|
1124
|
+
)
|
|
1116
1125
|
if not item:
|
|
1117
1126
|
return JSONResponse(
|
|
1118
1127
|
status_code=404, content={"message": f"Item with id {id} not found"}
|
|
@@ -1283,7 +1292,11 @@ class ModelView:
|
|
|
1283
1292
|
filter_criteria[f"{search_column}__ilike"] = f"%{search_value}%"
|
|
1284
1293
|
|
|
1285
1294
|
items_result = await self.crud.get_multi(
|
|
1286
|
-
db=db,
|
|
1295
|
+
db=db,
|
|
1296
|
+
offset=offset,
|
|
1297
|
+
limit=limit,
|
|
1298
|
+
schema_to_select=self.select_schema,
|
|
1299
|
+
**cast(Any, filter_criteria),
|
|
1287
1300
|
)
|
|
1288
1301
|
|
|
1289
1302
|
items: Dict[str, Any] = {
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
from datetime import
|
|
1
|
+
from datetime import datetime, timezone
|
|
2
2
|
from typing import Optional, Type
|
|
3
3
|
|
|
4
4
|
from sqlalchemy import Boolean, DateTime, String
|
|
5
5
|
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
|
|
6
6
|
|
|
7
|
+
UTC = timezone.utc
|
|
8
|
+
|
|
7
9
|
|
|
8
10
|
def create_admin_user(base: Type[DeclarativeBase]) -> Type[DeclarativeBase]:
|
|
9
11
|
class AdminUser(base): # type: ignore
|
|
@@ -1,23 +1,25 @@
|
|
|
1
|
-
from datetime import
|
|
1
|
+
from datetime import datetime, timezone
|
|
2
2
|
from typing import Any, Optional
|
|
3
3
|
|
|
4
4
|
from pydantic import BaseModel, Field, field_serializer
|
|
5
5
|
|
|
6
|
+
UTC = timezone.utc
|
|
7
|
+
|
|
6
8
|
|
|
7
9
|
class TimestampSchema(BaseModel):
|
|
8
10
|
created_at: datetime = Field(default_factory=lambda: datetime.now(UTC))
|
|
9
11
|
updated_at: Optional[datetime] = Field(default=None)
|
|
10
12
|
|
|
11
13
|
@field_serializer("created_at")
|
|
12
|
-
def serialize_dt(self, created_at: datetime
|
|
14
|
+
def serialize_dt(self, created_at: Optional[datetime], _info: Any) -> Optional[str]:
|
|
13
15
|
if created_at is not None:
|
|
14
16
|
return created_at.isoformat()
|
|
15
17
|
return None
|
|
16
18
|
|
|
17
19
|
@field_serializer("updated_at")
|
|
18
20
|
def serialize_updated_at(
|
|
19
|
-
self, updated_at: datetime
|
|
20
|
-
) -> str
|
|
21
|
+
self, updated_at: Optional[datetime], _info: Any
|
|
22
|
+
) -> Optional[str]:
|
|
21
23
|
if updated_at is not None:
|
|
22
24
|
return updated_at.isoformat()
|
|
23
25
|
return None
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import functools
|
|
2
2
|
import logging
|
|
3
3
|
from collections.abc import Callable
|
|
4
|
-
from datetime import
|
|
4
|
+
from datetime import datetime, timezone
|
|
5
5
|
from typing import Any, Dict, Optional, Type
|
|
6
6
|
|
|
7
7
|
from fastapi import Request
|
|
@@ -11,6 +11,8 @@ from sqlalchemy.orm import DeclarativeBase
|
|
|
11
11
|
|
|
12
12
|
from .models import EventType
|
|
13
13
|
|
|
14
|
+
UTC = timezone.utc
|
|
15
|
+
|
|
14
16
|
logger = logging.getLogger(__name__)
|
|
15
17
|
|
|
16
18
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from datetime import
|
|
1
|
+
from datetime import datetime, timezone
|
|
2
2
|
from typing import Any, Optional, cast
|
|
3
3
|
|
|
4
4
|
from sqlalchemy import JSON, DateTime, String
|
|
@@ -7,6 +7,8 @@ from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
|
|
|
7
7
|
|
|
8
8
|
from .schemas import EventStatus, EventType
|
|
9
9
|
|
|
10
|
+
UTC = timezone.utc
|
|
11
|
+
|
|
10
12
|
|
|
11
13
|
def create_admin_event_log(base: type[DeclarativeBase]) -> type[DeclarativeBase]:
|
|
12
14
|
tablename = "admin_event_log"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import logging
|
|
3
|
-
from datetime import
|
|
3
|
+
from datetime import datetime, timedelta, timezone
|
|
4
4
|
from decimal import Decimal
|
|
5
5
|
from enum import Enum
|
|
6
6
|
from typing import Any, Optional, cast
|
|
@@ -19,6 +19,8 @@ from .schemas import (
|
|
|
19
19
|
EventType,
|
|
20
20
|
)
|
|
21
21
|
|
|
22
|
+
UTC = timezone.utc
|
|
23
|
+
|
|
22
24
|
logger = logging.getLogger(__name__)
|
|
23
25
|
|
|
24
26
|
|
|
@@ -6,7 +6,7 @@ dashboard for session management and monitoring.
|
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
8
|
import logging
|
|
9
|
-
from datetime import
|
|
9
|
+
from datetime import datetime, timezone
|
|
10
10
|
from typing import Any, Optional, TypeVar
|
|
11
11
|
|
|
12
12
|
from pydantic import BaseModel
|
|
@@ -16,6 +16,8 @@ from ...core.db import DatabaseConfig
|
|
|
16
16
|
from ..schemas import AdminSessionCreate, AdminSessionUpdate
|
|
17
17
|
from ..storage import AbstractSessionStorage
|
|
18
18
|
|
|
19
|
+
UTC = timezone.utc
|
|
20
|
+
|
|
19
21
|
T = TypeVar("T", bound=BaseModel)
|
|
20
22
|
logger = logging.getLogger(__name__)
|
|
21
23
|
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import logging
|
|
3
3
|
import re
|
|
4
|
-
from datetime import
|
|
4
|
+
from datetime import datetime, timedelta, timezone
|
|
5
5
|
from typing import Optional, Pattern, TypeVar
|
|
6
6
|
|
|
7
7
|
from pydantic import BaseModel
|
|
8
8
|
|
|
9
9
|
from ..storage import AbstractSessionStorage
|
|
10
10
|
|
|
11
|
+
UTC = timezone.utc
|
|
12
|
+
|
|
11
13
|
T = TypeVar("T", bound=BaseModel)
|
|
12
14
|
logger = logging.getLogger(__name__)
|
|
13
15
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import secrets
|
|
3
|
-
from datetime import
|
|
3
|
+
from datetime import datetime, timedelta, timezone
|
|
4
4
|
from typing import Any, Literal, Optional
|
|
5
5
|
|
|
6
6
|
from fastapi import Request, Response
|
|
@@ -10,6 +10,8 @@ from .schemas import CSRFToken, SessionCreate, SessionData, UserAgentInfo
|
|
|
10
10
|
from .storage import AbstractSessionStorage, get_session_storage
|
|
11
11
|
from .user_agents_types import parse
|
|
12
12
|
|
|
13
|
+
UTC = timezone.utc
|
|
14
|
+
|
|
13
15
|
logger = logging.getLogger(__name__)
|
|
14
16
|
|
|
15
17
|
SamesiteType = Literal["lax", "strict", "none"]
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
from datetime import
|
|
1
|
+
from datetime import datetime, timezone
|
|
2
2
|
from typing import Any
|
|
3
3
|
|
|
4
4
|
from sqlalchemy import JSON, Boolean, DateTime, String
|
|
5
5
|
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
|
|
6
6
|
|
|
7
|
+
UTC = timezone.utc
|
|
8
|
+
|
|
7
9
|
|
|
8
10
|
def create_admin_session_model(base: type[DeclarativeBase]) -> type[DeclarativeBase]:
|
|
9
11
|
class AdminSession(base): # type: ignore
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from datetime import
|
|
1
|
+
from datetime import datetime, timezone
|
|
2
2
|
from enum import Enum
|
|
3
3
|
from typing import Any, Optional
|
|
4
4
|
from uuid import uuid4
|
|
@@ -7,6 +7,8 @@ from pydantic import BaseModel, Field, field_validator
|
|
|
7
7
|
|
|
8
8
|
from ..core.schemas.timestamp import TimestampSchema
|
|
9
9
|
|
|
10
|
+
UTC = timezone.utc
|
|
11
|
+
|
|
10
12
|
|
|
11
13
|
class DeviceType(str, Enum):
|
|
12
14
|
"""Device type enumeration"""
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/templates/admin/dashboard/dashboard_content.html
RENAMED
|
File without changes
|
|
File without changes
|
{crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/templates/admin/management/events_content.html
RENAMED
|
File without changes
|
|
File without changes
|
{crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/templates/admin/management/health_content.html
RENAMED
|
File without changes
|
{crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/templates/admin/model/components/list_content.html
RENAMED
|
File without changes
|
{crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/templates/admin/model/components/pagination.html
RENAMED
|
File without changes
|
{crudadmin-0.3.2 → crudadmin-0.3.4}/crudadmin/templates/admin/model/components/table_content.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|