fastgenerateapi 1.1.8__py2.py3-none-any.whl → 1.1.9__py2.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.
Potentially problematic release.
This version of fastgenerateapi might be problematic. Click here for more details.
- fastgenerateapi/__version__.py +1 -1
- fastgenerateapi/api_view/base_view.py +5 -2
- fastgenerateapi/api_view/create_view.py +4 -0
- fastgenerateapi/api_view/delete_filter_view.py +7 -2
- fastgenerateapi/api_view/delete_tree_view.py +8 -2
- fastgenerateapi/api_view/delete_view.py +8 -2
- fastgenerateapi/api_view/get_all_view.py +8 -4
- fastgenerateapi/api_view/get_one_view.py +5 -1
- fastgenerateapi/api_view/get_relation_view.py +3 -0
- fastgenerateapi/api_view/get_tree_view.py +3 -0
- fastgenerateapi/api_view/mixin/base_mixin.py +1 -1
- fastgenerateapi/api_view/switch_view.py +9 -3
- fastgenerateapi/api_view/update_relation_view.py +4 -0
- fastgenerateapi/api_view/update_view.py +4 -0
- fastgenerateapi/channel/connection_manager.py +30 -0
- fastgenerateapi/channel/consumer.py +25 -20
- fastgenerateapi/channel/websocket_view.py +60 -2
- fastgenerateapi/my_fields/enum_field.py +8 -6
- fastgenerateapi/schemas_factory/filter_schema_factory.py +5 -1
- fastgenerateapi/schemas_factory/get_all_schema_factory.py +6 -6
- fastgenerateapi/schemas_factory/response_factory.py +2 -2
- fastgenerateapi/settings/app_settings.py +14 -5
- fastgenerateapi/settings/db_settings.py +22 -31
- fastgenerateapi/settings/file_settings.py +13 -6
- fastgenerateapi/settings/jwt_settings.py +13 -6
- fastgenerateapi/settings/otlp_settings.py +14 -7
- fastgenerateapi/settings/redis_settings.py +13 -6
- fastgenerateapi/settings/sms_settings.py +13 -6
- fastgenerateapi/settings/system_settings.py +8 -2
- fastgenerateapi/utils/snowflake.py +1 -1
- {fastgenerateapi-1.1.8.dist-info → fastgenerateapi-1.1.9.dist-info}/METADATA +1 -1
- {fastgenerateapi-1.1.8.dist-info → fastgenerateapi-1.1.9.dist-info}/RECORD +35 -34
- {fastgenerateapi-1.1.8.dist-info → fastgenerateapi-1.1.9.dist-info}/LICENSE +0 -0
- {fastgenerateapi-1.1.8.dist-info → fastgenerateapi-1.1.9.dist-info}/WHEEL +0 -0
- {fastgenerateapi-1.1.8.dist-info → fastgenerateapi-1.1.9.dist-info}/top_level.txt +0 -0
fastgenerateapi/__version__.py
CHANGED
|
@@ -78,8 +78,11 @@ class BaseView(BaseMixin, ResponseMixin, ToolMixin, DBModelMixin):
|
|
|
78
78
|
return self.error(msg="relation_model_class not allow None")
|
|
79
79
|
return self.get_active_queryset(self.relation_model_class)
|
|
80
80
|
|
|
81
|
-
async def get_object(self, pk, is_with_prefetch):
|
|
82
|
-
|
|
81
|
+
async def get_object(self, pk, model_class=None, is_with_prefetch=False):
|
|
82
|
+
if model_class:
|
|
83
|
+
queryset = self.get_active_queryset(model_class).filter(id=pk)
|
|
84
|
+
else:
|
|
85
|
+
queryset = self.queryset.filter(id=pk)
|
|
83
86
|
if is_with_prefetch:
|
|
84
87
|
queryset = queryset.prefetch_related(*self.prefetch_related_fields.keys())
|
|
85
88
|
model = await queryset.first()
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
from typing import Optional, Type, Union, Any
|
|
2
2
|
|
|
3
|
+
from fastapi import Depends
|
|
4
|
+
from fastapi.security import OAuth2PasswordBearer
|
|
3
5
|
from fastapi.types import DecoratedCallable
|
|
4
6
|
from pydantic import BaseModel
|
|
5
7
|
from starlette.requests import Request
|
|
@@ -73,10 +75,12 @@ class CreateView(BaseView, SaveMixin):
|
|
|
73
75
|
async def route(
|
|
74
76
|
request_data: self.create_schema, # type: ignore
|
|
75
77
|
request: Request,
|
|
78
|
+
token: Optional[str] = Depends(OAuth2PasswordBearer(tokenUrl="token", auto_error=False)),
|
|
76
79
|
) -> JSONResponse:
|
|
77
80
|
data = await self.create(
|
|
78
81
|
request_data=request_data,
|
|
79
82
|
request=request,
|
|
83
|
+
token=token,
|
|
80
84
|
*args,
|
|
81
85
|
**kwargs
|
|
82
86
|
)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from typing import Optional, Type, Any, Union
|
|
2
2
|
|
|
3
3
|
from fastapi import Query, Depends
|
|
4
|
+
from fastapi.security import OAuth2PasswordBearer
|
|
4
5
|
from fastapi.types import DecoratedCallable
|
|
5
6
|
from starlette.requests import Request
|
|
6
7
|
from starlette.responses import JSONResponse
|
|
@@ -9,7 +10,7 @@ from tortoise.transactions import atomic
|
|
|
9
10
|
from fastgenerateapi.api_view.base_view import BaseView
|
|
10
11
|
from fastgenerateapi.data_type.data_type import CALLABLE, DEPENDENCIES
|
|
11
12
|
from fastgenerateapi.deps import filter_params_deps
|
|
12
|
-
from fastgenerateapi.schemas_factory import response_factory
|
|
13
|
+
from fastgenerateapi.schemas_factory import response_factory, get_one_schema_factory
|
|
13
14
|
from fastgenerateapi.settings.all_settings import settings
|
|
14
15
|
|
|
15
16
|
|
|
@@ -34,11 +35,13 @@ class DeleteFilterView(BaseView):
|
|
|
34
35
|
request: Request,
|
|
35
36
|
search: str = Query(default="", description="搜索"),
|
|
36
37
|
filters: dict = Depends(filter_params_deps(model_class=self.model_class, fields=self.filter_fields)),
|
|
38
|
+
token: Optional[str] = Depends(OAuth2PasswordBearer(tokenUrl="token", auto_error=False)),
|
|
37
39
|
) -> JSONResponse:
|
|
38
40
|
await self.destroy_filter(
|
|
39
41
|
search=search,
|
|
40
42
|
filters=filters,
|
|
41
43
|
request=request,
|
|
44
|
+
token=token,
|
|
42
45
|
*args, **kwargs
|
|
43
46
|
)
|
|
44
47
|
return self.success(msg="删除成功")
|
|
@@ -47,8 +50,10 @@ class DeleteFilterView(BaseView):
|
|
|
47
50
|
def _handler_destroy_filter_settings(self):
|
|
48
51
|
if self.delete_filter_route:
|
|
49
52
|
return
|
|
53
|
+
if not hasattr(self, "get_one_schema"):
|
|
54
|
+
self.get_one_schema = get_one_schema_factory(model_class=self.model_class)
|
|
50
55
|
if not hasattr(self, "get_one_response_schema"):
|
|
51
|
-
self.get_one_response_schema = response_factory(
|
|
56
|
+
self.get_one_response_schema = response_factory(self.get_one_schema, name="GetOne")
|
|
52
57
|
doc = self.destroy_filter.__doc__
|
|
53
58
|
summary = doc.strip().split("\n")[0] if doc else "Delete Filter"
|
|
54
59
|
path = f"/{settings.app_settings.ROUTER_FILTER_DELETE_SUFFIX_FIELD}" if settings.app_settings.ROUTER_WHETHER_ADD_SUFFIX else ""
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import time
|
|
2
2
|
from typing import Optional, Type, Any, Union
|
|
3
3
|
|
|
4
|
+
from fastapi import Depends
|
|
5
|
+
from fastapi.security import OAuth2PasswordBearer
|
|
4
6
|
from fastapi.types import DecoratedCallable
|
|
5
7
|
from pydantic import BaseModel
|
|
6
8
|
from starlette.requests import Request
|
|
@@ -10,7 +12,7 @@ from tortoise.transactions import atomic
|
|
|
10
12
|
from fastgenerateapi.api_view.base_view import BaseView
|
|
11
13
|
from fastgenerateapi.data_type.data_type import CALLABLE, DEPENDENCIES
|
|
12
14
|
from fastgenerateapi.pydantic_utils.base_model import IdList
|
|
13
|
-
from fastgenerateapi.schemas_factory import response_factory
|
|
15
|
+
from fastgenerateapi.schemas_factory import response_factory, get_one_schema_factory
|
|
14
16
|
from fastgenerateapi.settings.all_settings import settings
|
|
15
17
|
|
|
16
18
|
|
|
@@ -61,10 +63,12 @@ class DeleteTreeView(BaseView):
|
|
|
61
63
|
async def route(
|
|
62
64
|
request_data: self.delete_tree_schema, # type: ignore
|
|
63
65
|
request: Request,
|
|
66
|
+
token: Optional[str] = Depends(OAuth2PasswordBearer(tokenUrl="token", auto_error=False)),
|
|
64
67
|
) -> JSONResponse:
|
|
65
68
|
await self.destroy_tree(
|
|
66
69
|
request_data=request_data,
|
|
67
70
|
request=request,
|
|
71
|
+
token=token,
|
|
68
72
|
*args, **kwargs
|
|
69
73
|
)
|
|
70
74
|
return self.success(msg="删除成功")
|
|
@@ -73,8 +77,10 @@ class DeleteTreeView(BaseView):
|
|
|
73
77
|
def _handler_delete_tree_settings(self):
|
|
74
78
|
if self.delete_tree_route:
|
|
75
79
|
return
|
|
80
|
+
if not hasattr(self, "get_one_schema"):
|
|
81
|
+
self.get_one_schema = get_one_schema_factory(model_class=self.model_class)
|
|
76
82
|
if not hasattr(self, "get_one_response_schema"):
|
|
77
|
-
self.get_one_response_schema = response_factory(
|
|
83
|
+
self.get_one_response_schema = response_factory(self.get_one_schema, name="GetOne")
|
|
78
84
|
doc = self.destroy_tree.__doc__
|
|
79
85
|
summary = doc.strip().split("\n")[0] if doc else "Delete Tree"
|
|
80
86
|
path = f"/{settings.app_settings.ROUTER_RECURSION_DELETE_SUFFIX_FIELD}" if settings.app_settings.ROUTER_WHETHER_ADD_SUFFIX else ""
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import time
|
|
2
2
|
from typing import Optional, Type, Any, Union
|
|
3
3
|
|
|
4
|
+
from fastapi import Depends
|
|
5
|
+
from fastapi.security import OAuth2PasswordBearer
|
|
4
6
|
from fastapi.types import DecoratedCallable
|
|
5
7
|
from pydantic import BaseModel
|
|
6
8
|
from starlette.requests import Request
|
|
@@ -10,7 +12,7 @@ from tortoise.transactions import atomic
|
|
|
10
12
|
from fastgenerateapi.api_view.base_view import BaseView
|
|
11
13
|
from fastgenerateapi.data_type.data_type import CALLABLE, DEPENDENCIES
|
|
12
14
|
from fastgenerateapi.pydantic_utils.base_model import IdList
|
|
13
|
-
from fastgenerateapi.schemas_factory import response_factory
|
|
15
|
+
from fastgenerateapi.schemas_factory import response_factory, get_one_schema_factory
|
|
14
16
|
from fastgenerateapi.settings.all_settings import settings
|
|
15
17
|
|
|
16
18
|
|
|
@@ -51,10 +53,12 @@ class DeleteView(BaseView):
|
|
|
51
53
|
async def route(
|
|
52
54
|
request_data: self.delete_schema, # type: ignore
|
|
53
55
|
request: Request,
|
|
56
|
+
token: Optional[str] = Depends(OAuth2PasswordBearer(tokenUrl="token", auto_error=False)),
|
|
54
57
|
) -> JSONResponse:
|
|
55
58
|
await self.destroy(
|
|
56
59
|
request_data=request_data,
|
|
57
60
|
request=request,
|
|
61
|
+
token=token,
|
|
58
62
|
*args, **kwargs
|
|
59
63
|
)
|
|
60
64
|
return self.success(msg="删除成功")
|
|
@@ -63,8 +67,10 @@ class DeleteView(BaseView):
|
|
|
63
67
|
def _handler_delete_settings(self):
|
|
64
68
|
if not self.delete_route:
|
|
65
69
|
return
|
|
70
|
+
if not hasattr(self, "get_one_schema"):
|
|
71
|
+
self.get_one_schema = get_one_schema_factory(model_class=self.model_class)
|
|
66
72
|
if not hasattr(self, "get_one_response_schema"):
|
|
67
|
-
self.get_one_response_schema = response_factory(
|
|
73
|
+
self.get_one_response_schema = response_factory(self.get_one_schema, name="GetOne")
|
|
68
74
|
doc = self.destroy.__doc__
|
|
69
75
|
summary = doc.strip().split("\n")[0] if doc else "Delete All"
|
|
70
76
|
path = f"/{settings.app_settings.ROUTER_DELETE_SUFFIX_FIELD}" if settings.app_settings.ROUTER_WHETHER_ADD_SUFFIX else ""
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from typing import Union, Optional, Type, cast, List, Any, Callable, Coroutine
|
|
2
2
|
|
|
3
3
|
from fastapi import Depends, Query
|
|
4
|
+
from fastapi.security import OAuth2PasswordBearer
|
|
4
5
|
from fastapi.types import DecoratedCallable
|
|
5
6
|
from fastapi_cache import JsonCoder
|
|
6
7
|
from fastapi_cache.decorator import cache
|
|
@@ -56,7 +57,7 @@ class GetAllView(BaseView, GetMixin):
|
|
|
56
57
|
处理search搜索;处理筛选字段;处理外键预加载;处理排序
|
|
57
58
|
"""
|
|
58
59
|
queryset = self.search_controller.query(queryset=self.queryset, value=search)
|
|
59
|
-
queryset = await self.filter_queryset(queryset, filters)
|
|
60
|
+
queryset = await self.filter_queryset(queryset, filters, *args, **kwargs)
|
|
60
61
|
queryset = self.filter_controller.query(queryset=queryset, values=filters)
|
|
61
62
|
queryset = queryset.prefetch_related(*self.prefetch_related_fields.keys())
|
|
62
63
|
if self.order_by_fields:
|
|
@@ -66,7 +67,7 @@ class GetAllView(BaseView, GetMixin):
|
|
|
66
67
|
|
|
67
68
|
return queryset
|
|
68
69
|
|
|
69
|
-
async def filter_queryset(self, queryset: QuerySet, filters: dict) -> QuerySet:
|
|
70
|
+
async def filter_queryset(self, queryset: QuerySet, filters: dict, *args, **kwargs) -> QuerySet:
|
|
70
71
|
"""
|
|
71
72
|
处理filters
|
|
72
73
|
example: value = filters.pop(value, None) queryset = queryset.filter(field=value+string)
|
|
@@ -84,6 +85,7 @@ class GetAllView(BaseView, GetMixin):
|
|
|
84
85
|
queryset: QuerySet,
|
|
85
86
|
paginator=None,
|
|
86
87
|
schema: Type[BaseModel] = None,
|
|
88
|
+
name: str = "", # 当使用fields时,需要输入名称用于自动生成schema
|
|
87
89
|
fields: List[Union[str, tuple]] = None,
|
|
88
90
|
*args, **kwargs
|
|
89
91
|
):
|
|
@@ -117,10 +119,10 @@ class GetAllView(BaseView, GetMixin):
|
|
|
117
119
|
if paginator is None or getattr(paginator, settings.app_settings.DETERMINE_WHETHER_PAGE_FIELD) == \
|
|
118
120
|
settings.app_settings.DETERMINE_PAGE_BOOL_VALUE:
|
|
119
121
|
if schema or fields:
|
|
120
|
-
return get_list_schema_factory()(**{settings.app_settings.LIST_RESPONSE_FIELD: data_list})
|
|
122
|
+
return get_list_schema_factory(schema, name)(**{settings.app_settings.LIST_RESPONSE_FIELD: data_list})
|
|
121
123
|
return self.get_list_schema(**{settings.app_settings.LIST_RESPONSE_FIELD: data_list})
|
|
122
124
|
if schema or fields:
|
|
123
|
-
return get_page_schema_factory()(**{
|
|
125
|
+
return get_page_schema_factory(schema, name)(**{
|
|
124
126
|
settings.app_settings.CURRENT_PAGE_FIELD: current_num,
|
|
125
127
|
settings.app_settings.PAGE_SIZE_FIELD: page_size,
|
|
126
128
|
settings.app_settings.TOTAL_SIZE_FIELD: count,
|
|
@@ -144,12 +146,14 @@ class GetAllView(BaseView, GetMixin):
|
|
|
144
146
|
paginator=Depends(paginator_deps()),
|
|
145
147
|
search: Optional[str] = Depends(search_params_deps(self.search_fields)),
|
|
146
148
|
filters: dict = Depends(filter_params_deps(model_class=self.model_class, fields=self.filter_fields, schema=self.filter_schema)),
|
|
149
|
+
token: Optional[str] = Depends(OAuth2PasswordBearer(tokenUrl="token", auto_error=False)),
|
|
147
150
|
) -> JSONResponse:
|
|
148
151
|
data = await self.get_all(
|
|
149
152
|
paginator=paginator,
|
|
150
153
|
search=search,
|
|
151
154
|
filters=filters,
|
|
152
155
|
request=request,
|
|
156
|
+
token=token,
|
|
153
157
|
*args,
|
|
154
158
|
**kwargs
|
|
155
159
|
)
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
from typing import Any, Union, Optional, Type
|
|
2
2
|
|
|
3
|
+
from fastapi import Depends
|
|
4
|
+
from fastapi.security import OAuth2PasswordBearer
|
|
3
5
|
from fastapi.types import DecoratedCallable
|
|
4
6
|
from fastapi_cache import JsonCoder
|
|
5
7
|
from fastapi_cache.decorator import cache
|
|
@@ -36,7 +38,7 @@ class GetOneView(BaseView, GetMixin):
|
|
|
36
38
|
"""
|
|
37
39
|
|
|
38
40
|
async def get_one(self, pk: str, *args, **kwargs):
|
|
39
|
-
model = await self.get_object(pk, self.is_with_prefetch)
|
|
41
|
+
model = await self.get_object(pk, is_with_prefetch=self.is_with_prefetch)
|
|
40
42
|
if self.is_with_prefetch:
|
|
41
43
|
await self.setattr_model(model, prefetch_related_fields=self.prefetch_related_fields, *args, **kwargs)
|
|
42
44
|
|
|
@@ -50,10 +52,12 @@ class GetOneView(BaseView, GetMixin):
|
|
|
50
52
|
async def route(
|
|
51
53
|
pk: str,
|
|
52
54
|
request: Request,
|
|
55
|
+
token: Optional[str] = Depends(OAuth2PasswordBearer(tokenUrl="token", auto_error=False)),
|
|
53
56
|
) -> JSONResponse:
|
|
54
57
|
data = await self.get_one(
|
|
55
58
|
pk=pk,
|
|
56
59
|
request=request,
|
|
60
|
+
token=token,
|
|
57
61
|
*args, **kwargs
|
|
58
62
|
)
|
|
59
63
|
return self.success(data=data)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from typing import Union, Optional, Type, cast, List, Any
|
|
2
2
|
|
|
3
3
|
from fastapi import Depends, Query
|
|
4
|
+
from fastapi.security import OAuth2PasswordBearer
|
|
4
5
|
from fastapi.types import DecoratedCallable
|
|
5
6
|
from pydantic import BaseModel
|
|
6
7
|
from starlette.requests import Request
|
|
@@ -160,6 +161,7 @@ class GetRelationView(BaseView):
|
|
|
160
161
|
filters: dict = Depends(filter_params_deps(model_class=self.model_class, fields=self.filter_fields)),
|
|
161
162
|
relation_filters: dict = Depends(
|
|
162
163
|
filter_params_deps(model_class=self.relation_model_class, fields=self.relation_filter_fields)),
|
|
164
|
+
token: Optional[str] = Depends(OAuth2PasswordBearer(tokenUrl="token", auto_error=False)),
|
|
163
165
|
) -> JSONResponse:
|
|
164
166
|
data = await self.get_relation(
|
|
165
167
|
pk=pk,
|
|
@@ -168,6 +170,7 @@ class GetRelationView(BaseView):
|
|
|
168
170
|
filters=filters,
|
|
169
171
|
relation_filters=relation_filters,
|
|
170
172
|
request=request,
|
|
173
|
+
token=token,
|
|
171
174
|
*args,
|
|
172
175
|
**kwargs
|
|
173
176
|
)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from typing import Union, Optional, Type, cast, List, Any, Callable, Coroutine
|
|
2
2
|
|
|
3
3
|
from fastapi import Depends, Query
|
|
4
|
+
from fastapi.security import OAuth2PasswordBearer
|
|
4
5
|
from fastapi.types import DecoratedCallable
|
|
5
6
|
from fastapi_cache import JsonCoder
|
|
6
7
|
from fastapi_cache.decorator import cache
|
|
@@ -157,12 +158,14 @@ class GetTreeView(BaseView):
|
|
|
157
158
|
search: str = Query(default="", description="搜索"),
|
|
158
159
|
node_id: Optional[str] = Depends(tree_params_deps()),
|
|
159
160
|
filters: dict = Depends(filter_params_deps(model_class=self.model_class, fields=self.filter_fields)),
|
|
161
|
+
token: Optional[str] = Depends(OAuth2PasswordBearer(tokenUrl="token", auto_error=False)),
|
|
160
162
|
) -> JSONResponse:
|
|
161
163
|
data = await self.get_tree(
|
|
162
164
|
search=search,
|
|
163
165
|
node_id=node_id,
|
|
164
166
|
filters=filters,
|
|
165
167
|
request=request,
|
|
168
|
+
token=token,
|
|
166
169
|
*args,
|
|
167
170
|
**kwargs
|
|
168
171
|
)
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
from typing import List, Any
|
|
1
|
+
from typing import List, Any, Optional
|
|
2
2
|
|
|
3
|
+
from fastapi import Depends
|
|
4
|
+
from fastapi.security import OAuth2PasswordBearer
|
|
3
5
|
from fastapi.types import DecoratedCallable
|
|
4
6
|
from starlette.requests import Request
|
|
5
7
|
from starlette.responses import JSONResponse
|
|
@@ -45,8 +47,12 @@ class SwitchView(BaseView):
|
|
|
45
47
|
return self.get_one_schema.from_orm(model)
|
|
46
48
|
|
|
47
49
|
def _switch_decorator(self, filed, *args: Any, **kwargs: Any) -> DecoratedCallable:
|
|
48
|
-
async def route(
|
|
49
|
-
|
|
50
|
+
async def route(
|
|
51
|
+
pk: str,
|
|
52
|
+
request: Request,
|
|
53
|
+
token: Optional[str] = Depends(OAuth2PasswordBearer(tokenUrl="token", auto_error=False)),
|
|
54
|
+
) -> JSONResponse:
|
|
55
|
+
data = await self.switch(pk=pk, request=request, filed=filed, token=token, *args, **kwargs)
|
|
50
56
|
return self.success(data=data)
|
|
51
57
|
return route
|
|
52
58
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
from typing import Optional, Type, Union, Any
|
|
2
2
|
|
|
3
|
+
from fastapi import Depends
|
|
4
|
+
from fastapi.security import OAuth2PasswordBearer
|
|
3
5
|
from fastapi.types import DecoratedCallable
|
|
4
6
|
from pydantic import BaseModel
|
|
5
7
|
from starlette.requests import Request
|
|
@@ -55,11 +57,13 @@ class UpdateRelationView(BaseView, SaveMixin):
|
|
|
55
57
|
pk: str,
|
|
56
58
|
request_data: self.update_relation_schema, # type: ignore
|
|
57
59
|
request: Request,
|
|
60
|
+
token: Optional[str] = Depends(OAuth2PasswordBearer(tokenUrl="token", auto_error=False)),
|
|
58
61
|
) -> JSONResponse:
|
|
59
62
|
await self.update_relation(
|
|
60
63
|
pk=pk,
|
|
61
64
|
request_data=request_data,
|
|
62
65
|
request=request,
|
|
66
|
+
token=token,
|
|
63
67
|
*args, **kwargs
|
|
64
68
|
)
|
|
65
69
|
return self.success()
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
from typing import Optional, Type, Union, Any
|
|
2
2
|
|
|
3
|
+
from fastapi import Depends
|
|
4
|
+
from fastapi.security import OAuth2PasswordBearer
|
|
3
5
|
from fastapi.types import DecoratedCallable
|
|
4
6
|
from starlette.requests import Request
|
|
5
7
|
from starlette.responses import JSONResponse
|
|
@@ -63,11 +65,13 @@ class UpdateView(BaseView, SaveMixin):
|
|
|
63
65
|
pk: str,
|
|
64
66
|
request_data: self.update_schema, # type: ignore
|
|
65
67
|
request: Request,
|
|
68
|
+
token: Optional[str] = Depends(OAuth2PasswordBearer(tokenUrl="token", auto_error=False)),
|
|
66
69
|
) -> JSONResponse:
|
|
67
70
|
data = await self.update(
|
|
68
71
|
pk=pk,
|
|
69
72
|
request_data=request_data,
|
|
70
73
|
request=request,
|
|
74
|
+
token=token,
|
|
71
75
|
*args, **kwargs
|
|
72
76
|
)
|
|
73
77
|
return self.success(data=data)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from typing import Dict
|
|
2
|
+
|
|
3
|
+
from starlette.websockets import WebSocket
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ConnectionManager:
|
|
7
|
+
active_connections: Dict[str, WebSocket] = {}
|
|
8
|
+
active_group_connections: Dict[str, Dict[str, WebSocket]] = {}
|
|
9
|
+
|
|
10
|
+
@classmethod
|
|
11
|
+
def add_connection(cls, user_id: str, websocket: WebSocket):
|
|
12
|
+
cls.active_connections[user_id] = websocket
|
|
13
|
+
|
|
14
|
+
@classmethod
|
|
15
|
+
def del_connection(cls, user_id: str):
|
|
16
|
+
if user_id in cls.active_connections:
|
|
17
|
+
del cls.active_connections[user_id]
|
|
18
|
+
|
|
19
|
+
@classmethod
|
|
20
|
+
def add_group_connection(cls, group_id: str, user_id: str, connection: WebSocket):
|
|
21
|
+
cls.active_group_connections.setdefault(group_id, {})[user_id] = connection
|
|
22
|
+
|
|
23
|
+
@classmethod
|
|
24
|
+
def del_group_connection(cls, group_id: str, user_id: str):
|
|
25
|
+
if group_id in cls.active_group_connections:
|
|
26
|
+
user_dict = cls.active_group_connections[group_id]
|
|
27
|
+
if user_id in user_dict:
|
|
28
|
+
del user_dict[user_id]
|
|
29
|
+
if not user_dict:
|
|
30
|
+
del cls.active_group_connections[group_id]
|
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
import _ctypes
|
|
2
1
|
from typing import List, Union
|
|
3
2
|
|
|
4
|
-
import
|
|
3
|
+
# from _ctypes import PyObj_FromPtr
|
|
5
4
|
from starlette.endpoints import WebSocketEndpoint
|
|
6
5
|
|
|
6
|
+
from fastgenerateapi.channel.connection_manager import ConnectionManager
|
|
7
|
+
|
|
7
8
|
|
|
8
9
|
class Consumer(WebSocketEndpoint):
|
|
9
10
|
"""
|
|
10
11
|
群聊
|
|
11
|
-
redis_conn: must
|
|
12
|
-
使用 aioredis
|
|
13
12
|
"""
|
|
14
|
-
redis_conn: aioredis.Redis
|
|
15
13
|
encoding = "json"
|
|
16
14
|
group_id = None
|
|
17
15
|
user_id = None
|
|
@@ -22,9 +20,13 @@ class Consumer(WebSocketEndpoint):
|
|
|
22
20
|
|
|
23
21
|
# 用户输入名称
|
|
24
22
|
self.group_id = websocket.path_params.get("group_id")
|
|
25
|
-
self.user_id =
|
|
23
|
+
self.user_id = await self.get_user_id(websocket)
|
|
26
24
|
await self.group_add(websocket, self.group_id, self.user_id)
|
|
27
|
-
await self.group_send(self.group_id, {"msg": f"{self.user_id}-加入了聊天室"})
|
|
25
|
+
# await self.group_send(self.group_id, {"msg": f"{self.user_id}-加入了聊天室"})
|
|
26
|
+
|
|
27
|
+
@staticmethod
|
|
28
|
+
async def get_user_id(websocket):
|
|
29
|
+
return websocket.query_params.get("user_id")
|
|
28
30
|
|
|
29
31
|
# 收消息后自动转发
|
|
30
32
|
async def on_receive(self, websocket, data):
|
|
@@ -34,18 +36,27 @@ class Consumer(WebSocketEndpoint):
|
|
|
34
36
|
# 断开 删除
|
|
35
37
|
async def on_disconnect(self, websocket, close_code):
|
|
36
38
|
if self.group_id and self.user_id:
|
|
37
|
-
await
|
|
39
|
+
await ConnectionManager.del_group_connection(self.group_id, self.user_id)
|
|
38
40
|
pass
|
|
39
41
|
|
|
42
|
+
async def check_args(self, group_id, user_id):
|
|
43
|
+
"""
|
|
44
|
+
用于检查数据是否有效
|
|
45
|
+
:param group_id:
|
|
46
|
+
:param user_id:
|
|
47
|
+
:return:
|
|
48
|
+
"""
|
|
49
|
+
return True
|
|
50
|
+
|
|
40
51
|
# 添加组
|
|
41
52
|
async def group_add(self, websocket, group_id, user_key):
|
|
42
|
-
if not self.redis_conn:
|
|
43
|
-
await self.error(websocket, code=500, msg="redis未设置")
|
|
44
53
|
if not group_id:
|
|
45
54
|
await self.error(websocket, code=422, msg="未获取到组信息")
|
|
46
55
|
if not user_key:
|
|
47
56
|
await self.error(websocket, code=422, msg="未获取到用户信息")
|
|
48
|
-
await self.
|
|
57
|
+
if not await self.check_args(group_id, user_key):
|
|
58
|
+
await self.error(websocket, code=422, msg="无连接权限")
|
|
59
|
+
await ConnectionManager.add_group_connection(group_id, user_key, websocket)
|
|
49
60
|
|
|
50
61
|
# 群发消息
|
|
51
62
|
@classmethod
|
|
@@ -59,17 +70,11 @@ class Consumer(WebSocketEndpoint):
|
|
|
59
70
|
:param exclude: 默认True排除自己;[int] 时可选排除其他人
|
|
60
71
|
:return:
|
|
61
72
|
"""
|
|
62
|
-
|
|
63
|
-
result = await cls.redis_conn.hgetall(group_id)
|
|
73
|
+
result = ConnectionManager.active_group_connections.get(group_id, {})
|
|
64
74
|
if type(exclude) == bool:
|
|
65
75
|
exclude = [user_id] if user_id and exclude else []
|
|
66
|
-
for
|
|
67
|
-
if
|
|
68
|
-
continue
|
|
69
|
-
try:
|
|
70
|
-
websocket = _ctypes.PyObj_FromPtr(int(value))
|
|
71
|
-
except Exception:
|
|
72
|
-
await cls.redis_conn.hdel(group_id, key)
|
|
76
|
+
for user_id, websocket in result.items():
|
|
77
|
+
if user_id in exclude:
|
|
73
78
|
continue
|
|
74
79
|
await websocket.send_json({
|
|
75
80
|
"code": code,
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
from typing import Union
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
from starlette.websockets import WebSocket
|
|
4
4
|
|
|
5
5
|
from fastgenerateapi.api_view.base_view import BaseView
|
|
6
|
+
from fastgenerateapi.channel.connection_manager import ConnectionManager
|
|
6
7
|
from fastgenerateapi.controller.ws_controller import WsController
|
|
7
8
|
from fastgenerateapi.data_type.data_type import DEPENDENCIES
|
|
8
9
|
|
|
@@ -12,7 +13,6 @@ class WebsocketView(BaseView):
|
|
|
12
13
|
客户端与服务器之间通信
|
|
13
14
|
"""
|
|
14
15
|
websocket_route: Union[bool, DEPENDENCIES] = True
|
|
15
|
-
redis_conn: aioredis.Redis
|
|
16
16
|
|
|
17
17
|
def _handler_websocket_settings(self):
|
|
18
18
|
self.ws_summary = WsController(self, self._get_cls_ws_func())
|
|
@@ -23,3 +23,61 @@ class WebsocketView(BaseView):
|
|
|
23
23
|
dependencies=ws_router.dependencies,
|
|
24
24
|
)
|
|
25
25
|
|
|
26
|
+
@classmethod
|
|
27
|
+
async def accept(cls, user_id:str, websocket: WebSocket):
|
|
28
|
+
await websocket.accept()
|
|
29
|
+
ConnectionManager.add_connection(user_id=user_id, websocket=websocket)
|
|
30
|
+
|
|
31
|
+
return websocket
|
|
32
|
+
|
|
33
|
+
@classmethod
|
|
34
|
+
async def send(cls, user_id, data, code=200):
|
|
35
|
+
"""
|
|
36
|
+
群发送消息
|
|
37
|
+
:param user_id: 用户id
|
|
38
|
+
:param data: 发送的数据
|
|
39
|
+
:param code: 状态码
|
|
40
|
+
:return:
|
|
41
|
+
"""
|
|
42
|
+
if not user_id or not data:
|
|
43
|
+
return False
|
|
44
|
+
|
|
45
|
+
websocket = ConnectionManager.active_connections.get(user_id)
|
|
46
|
+
if not websocket:
|
|
47
|
+
return False
|
|
48
|
+
await websocket.send_json({
|
|
49
|
+
"code": code,
|
|
50
|
+
"from": user_id,
|
|
51
|
+
# "message": "请求成功",
|
|
52
|
+
"data": data
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
return True
|
|
56
|
+
|
|
57
|
+
@classmethod
|
|
58
|
+
async def group_send(cls, user_id_list, data, code=200):
|
|
59
|
+
"""
|
|
60
|
+
群发送消息
|
|
61
|
+
:param user_id_list: 用户id列表
|
|
62
|
+
:param data: 发送的数据
|
|
63
|
+
:param code: 状态码
|
|
64
|
+
:return:
|
|
65
|
+
"""
|
|
66
|
+
if not user_id_list or not data:
|
|
67
|
+
return [], user_id_list
|
|
68
|
+
success_user_id_list = []
|
|
69
|
+
fail_user_id_list = []
|
|
70
|
+
for user_id in user_id_list:
|
|
71
|
+
websocket = ConnectionManager.active_connections.get(user_id)
|
|
72
|
+
if not websocket:
|
|
73
|
+
fail_user_id_list.append(user_id)
|
|
74
|
+
continue
|
|
75
|
+
await websocket.send_json({
|
|
76
|
+
"code": code,
|
|
77
|
+
"from": user_id,
|
|
78
|
+
# "message": "请求成功",
|
|
79
|
+
"data": data
|
|
80
|
+
})
|
|
81
|
+
success_user_id_list.append(user_id)
|
|
82
|
+
|
|
83
|
+
return success_user_id_list, fail_user_id_list
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from enum import IntEnum
|
|
1
|
+
from enum import IntEnum, Enum
|
|
2
2
|
from typing import (
|
|
3
3
|
TYPE_CHECKING,
|
|
4
4
|
Any,
|
|
@@ -36,7 +36,8 @@ class IntEnumField(IntEnumFieldInstance):
|
|
|
36
36
|
|
|
37
37
|
def __init__(self, enum_list: List[any], start_num=0, **kwargs: Any) -> None:
|
|
38
38
|
self.enum_list = enum_list
|
|
39
|
-
self.description = kwargs.get("description", "") + " >> " + self.get_description(enum_list)
|
|
39
|
+
self.description = kwargs.get("description", "") + " >> " + self.get_description(enum_list, start_num)
|
|
40
|
+
kwargs["description"] = self.description
|
|
40
41
|
super().__init__(enum_type=self.create_enum(enum_list, start_num=start_num), **kwargs)
|
|
41
42
|
|
|
42
43
|
@property
|
|
@@ -66,15 +67,16 @@ class IntEnumField(IntEnumFieldInstance):
|
|
|
66
67
|
if value is not None:
|
|
67
68
|
value = int(value) # pylint: disable=E1102
|
|
68
69
|
self.validate(value)
|
|
69
|
-
return
|
|
70
|
+
return value
|
|
70
71
|
|
|
71
|
-
|
|
72
|
+
@staticmethod
|
|
73
|
+
def get_description(enum_list, start_num=0):
|
|
72
74
|
description = ""
|
|
73
|
-
for index, val in enumerate(enum_list,
|
|
75
|
+
for index, val in enumerate(enum_list, start_num):
|
|
74
76
|
description += f"{index}:{val};"
|
|
75
77
|
return description
|
|
76
78
|
|
|
77
|
-
def create_enum(self, enum_list, start_num=0):
|
|
79
|
+
def create_enum(self, enum_list, start_num=0) -> Type[IntEnum]:
|
|
78
80
|
# 创建枚举类的成员字典,确保值是唯一的
|
|
79
81
|
|
|
80
82
|
members = {self.number_to_words(name): name for name, _ in enumerate(enum_list, start_num)}
|
|
@@ -32,7 +32,11 @@ def filter_schema_factory(model_class: Type[Model], fields: list[str, tuple[str,
|
|
|
32
32
|
))
|
|
33
33
|
})
|
|
34
34
|
|
|
35
|
-
filter_params_model: Type[BaseModel] = create_model(
|
|
35
|
+
filter_params_model: Type[BaseModel] = create_model(
|
|
36
|
+
model_class.__name__+"CommonFilterParams",
|
|
37
|
+
**model_fields,
|
|
38
|
+
__config__=model_config
|
|
39
|
+
)
|
|
36
40
|
|
|
37
41
|
return filter_params_model
|
|
38
42
|
|
|
@@ -81,22 +81,22 @@ def get_all_schema_factory(
|
|
|
81
81
|
return schema
|
|
82
82
|
|
|
83
83
|
|
|
84
|
-
def get_list_schema_factory(schema_cls: Type[T] = None) -> Type[T]:
|
|
84
|
+
def get_list_schema_factory(schema_cls: Type[T] = None, name: str = "") -> Type[T]:
|
|
85
85
|
if schema_cls:
|
|
86
86
|
fields = {
|
|
87
87
|
settings.app_settings.LIST_RESPONSE_FIELD: (Optional[List[schema_cls]], FieldInfo(default=[], description="数据返回")),
|
|
88
88
|
}
|
|
89
|
-
name = schema_cls.__name__ + "GetListSchema"
|
|
89
|
+
name = schema_cls.__name__ + name + "GetListSchema"
|
|
90
90
|
else:
|
|
91
91
|
fields = {
|
|
92
92
|
settings.app_settings.LIST_RESPONSE_FIELD: (Optional[List], FieldInfo(default=[], description="数据返回")),
|
|
93
93
|
}
|
|
94
|
-
name = "GetListSchema"
|
|
94
|
+
name = name + "GetListSchema"
|
|
95
95
|
schema: Type[T] = create_model(name, **fields, __config__=model_config)
|
|
96
96
|
return schema
|
|
97
97
|
|
|
98
98
|
|
|
99
|
-
def get_page_schema_factory(schema_cls: Type[T] = None) -> Type[T]:
|
|
99
|
+
def get_page_schema_factory(schema_cls: Type[T] = None, name: str = "") -> Type[T]:
|
|
100
100
|
fields = {
|
|
101
101
|
settings.app_settings.CURRENT_PAGE_FIELD: (Optional[int], FieldInfo(default=1, description="当前页")),
|
|
102
102
|
settings.app_settings.PAGE_SIZE_FIELD: (Optional[int], FieldInfo(default=settings.app_settings.DEFAULT_PAGE_SIZE, description="每页数量")),
|
|
@@ -104,10 +104,10 @@ def get_page_schema_factory(schema_cls: Type[T] = None) -> Type[T]:
|
|
|
104
104
|
}
|
|
105
105
|
if schema_cls:
|
|
106
106
|
fields.update({settings.app_settings.LIST_RESPONSE_FIELD: (Optional[List[schema_cls]], FieldInfo(default=[], description="数据返回"))})
|
|
107
|
-
name = schema_cls.__name__ + "GetPageSchema"
|
|
107
|
+
name = schema_cls.__name__ + name + "GetPageSchema"
|
|
108
108
|
else:
|
|
109
109
|
fields.update({settings.app_settings.LIST_RESPONSE_FIELD: (Optional[List], FieldInfo(default=[], description="数据返回"))})
|
|
110
|
-
name = "GetPageSchema"
|
|
110
|
+
name = name + "GetPageSchema"
|
|
111
111
|
schema: Type[T] = create_model(name, **fields, __config__=model_config)
|
|
112
112
|
return schema
|
|
113
113
|
|
|
@@ -33,9 +33,9 @@ def response_factory(schema_cls: Union[Type[T], BaseModel, None] = None, name: s
|
|
|
33
33
|
)
|
|
34
34
|
|
|
35
35
|
try:
|
|
36
|
-
name = schema_cls.__name__ + name + "Response"
|
|
36
|
+
name = schema_cls.__name__ + name + "Response"
|
|
37
37
|
except:
|
|
38
|
-
name = "CommonResponse"
|
|
38
|
+
name = name + "CommonResponse"
|
|
39
39
|
schema: Type[T] = create_model(name, **fields, __config__=model_config)
|
|
40
40
|
|
|
41
41
|
return schema
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
from typing import Optional
|
|
2
2
|
|
|
3
3
|
from pydantic import Field
|
|
4
|
+
from pydantic_settings import SettingsConfigDict
|
|
5
|
+
|
|
4
6
|
from fastgenerateapi.pydantic_utils.base_settings import BaseSettings
|
|
5
7
|
|
|
6
8
|
|
|
@@ -79,11 +81,18 @@ class AppSettings(BaseSettings):
|
|
|
79
81
|
FILTER_UNDERLINE_WHETHER_DOUBLE_TO_SINGLE: Optional[bool] = Field(default=True, description="筛选是否双下划线转单下划线")
|
|
80
82
|
SCHEMAS_UNDERLINE_WHETHER_DOUBLE_TO_SINGLE: Optional[bool] = Field(default=True, description="序列化字段是否双下划线转单下划线")
|
|
81
83
|
|
|
82
|
-
|
|
83
|
-
env_prefix
|
|
84
|
-
env_file
|
|
85
|
-
case_sensitive
|
|
86
|
-
extra
|
|
84
|
+
model_config = SettingsConfigDict(
|
|
85
|
+
env_prefix="APP_",
|
|
86
|
+
env_file=".env",
|
|
87
|
+
case_sensitive=True,
|
|
88
|
+
extra='ignore'
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
# class Config:
|
|
92
|
+
# env_prefix = "APP_"
|
|
93
|
+
# env_file = "./.env"
|
|
94
|
+
# case_sensitive = True
|
|
95
|
+
# extra = 'allow'
|
|
87
96
|
|
|
88
97
|
|
|
89
98
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from typing import Optional
|
|
2
2
|
|
|
3
3
|
from pydantic import Field
|
|
4
|
-
from pydantic_settings import BaseSettings
|
|
4
|
+
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class DBSettings(BaseSettings):
|
|
@@ -9,22 +9,29 @@ class DBSettings(BaseSettings):
|
|
|
9
9
|
Database Settings
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
DB_TYPE: Optional[str] = Field(default='mysql', description="数据库类型")
|
|
13
|
+
DB_HOST: Optional[str] = Field(default='127.0.0.1', description="数据库域名")
|
|
14
|
+
DB_PORT: Optional[str] = Field(default='3306', description="数据库端口")
|
|
15
|
+
DB_DATABASE: Optional[str] = Field(default='admin', description="数据库名")
|
|
16
|
+
DB_USERNAME: Optional[str] = Field(default='root', description="数据库用户名")
|
|
17
|
+
DB_PASSWORD: Optional[str] = Field(default='', description="数据库密码")
|
|
18
18
|
|
|
19
19
|
@property
|
|
20
20
|
def dsn(self):
|
|
21
|
-
return f"{self.
|
|
21
|
+
return f"{self.DB_TYPE.lower()}://{self.DB_USERNAME}:{self.DB_PASSWORD}@{self.DB_HOST}:{self.DB_PORT}/{self.DB_DATABASE}"
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
env_prefix
|
|
25
|
-
env_file
|
|
26
|
-
case_sensitive
|
|
27
|
-
extra
|
|
23
|
+
model_config = SettingsConfigDict(
|
|
24
|
+
env_prefix="",
|
|
25
|
+
env_file=".env",
|
|
26
|
+
case_sensitive=True,
|
|
27
|
+
extra='ignore'
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
# class Config:
|
|
31
|
+
# env_prefix = ''
|
|
32
|
+
# env_file = "./.env"
|
|
33
|
+
# case_sensitive = True
|
|
34
|
+
# extra = 'allow'
|
|
28
35
|
|
|
29
36
|
|
|
30
37
|
class PostgresqlSettings(DBSettings):
|
|
@@ -33,36 +40,20 @@ class PostgresqlSettings(DBSettings):
|
|
|
33
40
|
"""
|
|
34
41
|
TYPE: Optional[str] = Field(default='postgres', description="数据库类型")
|
|
35
42
|
|
|
36
|
-
class Config:
|
|
37
|
-
env_prefix = 'Postgresql_'
|
|
38
|
-
env_file = "./.env"
|
|
39
|
-
case_sensitive = True
|
|
40
|
-
extra = 'allow'
|
|
41
|
-
|
|
42
43
|
|
|
43
44
|
class MySQLSettings(DBSettings):
|
|
44
45
|
"""
|
|
45
46
|
MySQL Settings
|
|
46
47
|
"""
|
|
47
|
-
|
|
48
|
-
class Config:
|
|
49
|
-
env_prefix = 'MYSQL_'
|
|
50
|
-
env_file = "./.env"
|
|
51
|
-
case_sensitive = True
|
|
52
|
-
extra = 'allow'
|
|
48
|
+
...
|
|
53
49
|
|
|
54
50
|
|
|
55
51
|
class LocalSettings(DBSettings):
|
|
56
52
|
"""
|
|
57
|
-
|
|
53
|
+
Local Settings
|
|
58
54
|
"""
|
|
59
55
|
TYPE: str = Field(..., description="数据库类型")
|
|
60
56
|
|
|
61
|
-
class Config:
|
|
62
|
-
env_prefix = 'LOCAL_'
|
|
63
|
-
env_file = "./.env"
|
|
64
|
-
case_sensitive = True
|
|
65
|
-
extra = 'allow'
|
|
66
57
|
|
|
67
58
|
|
|
68
59
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from typing import Optional
|
|
2
2
|
|
|
3
3
|
from pydantic import Field
|
|
4
|
-
from pydantic_settings import BaseSettings
|
|
4
|
+
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class FileServerSettings(BaseSettings):
|
|
@@ -12,11 +12,18 @@ class FileServerSettings(BaseSettings):
|
|
|
12
12
|
FILE_URL: Optional[str] = Field(default='/static/', description="文件路径前缀", title="file url prefix")
|
|
13
13
|
FILE_ROOT: Optional[str] = Field(default='static', description="文件储存路径", title="file storage path")
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
env_prefix
|
|
17
|
-
env_file
|
|
18
|
-
case_sensitive
|
|
19
|
-
extra
|
|
15
|
+
model_config = SettingsConfigDict(
|
|
16
|
+
env_prefix="FILESERVER_",
|
|
17
|
+
env_file=".env",
|
|
18
|
+
case_sensitive=True,
|
|
19
|
+
extra='ignore'
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
# class Config:
|
|
23
|
+
# env_prefix = 'FILESERVER_'
|
|
24
|
+
# env_file = "./.env"
|
|
25
|
+
# case_sensitive = True
|
|
26
|
+
# extra = 'allow'
|
|
20
27
|
|
|
21
28
|
|
|
22
29
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from typing import Optional
|
|
2
2
|
|
|
3
3
|
from pydantic import Field
|
|
4
|
-
from pydantic_settings import BaseSettings
|
|
4
|
+
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class JWTSettings(BaseSettings):
|
|
@@ -13,11 +13,18 @@ class JWTSettings(BaseSettings):
|
|
|
13
13
|
ACCESS_TOKEN_EXPIRE_MINUTES: Optional[int] = Field(default=30, description="过期时间 (分钟)", title="JWT Access Token")
|
|
14
14
|
REFRESH_TOKEN_EXPIRE_MINUTES: Optional[int] = Field(default=60, description="过期时间(分钟)", title="JWT Refresh Token")
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
env_prefix
|
|
18
|
-
env_file
|
|
19
|
-
case_sensitive
|
|
20
|
-
extra
|
|
16
|
+
model_config = SettingsConfigDict(
|
|
17
|
+
env_prefix="JWT_",
|
|
18
|
+
env_file=".env",
|
|
19
|
+
case_sensitive=True,
|
|
20
|
+
extra='ignore'
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
# class Config:
|
|
24
|
+
# env_prefix = 'JWT_'
|
|
25
|
+
# env_file = "./.env"
|
|
26
|
+
# case_sensitive = True
|
|
27
|
+
# extra = 'allow'
|
|
21
28
|
|
|
22
29
|
|
|
23
30
|
|
|
@@ -15,14 +15,14 @@ from opentelemetry.sdk.trace import TracerProvider
|
|
|
15
15
|
from opentelemetry.sdk.trace.export import BatchSpanProcessor
|
|
16
16
|
|
|
17
17
|
from pydantic import Field
|
|
18
|
-
from pydantic_settings import BaseSettings
|
|
18
|
+
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
class OpenTelemetrySettings(BaseSettings):
|
|
22
22
|
"""
|
|
23
23
|
跟踪和指标配置
|
|
24
24
|
"""
|
|
25
|
-
ENDPOINT: Optional[str] = Field(default=None, description="访问接口",
|
|
25
|
+
ENDPOINT: Optional[str] = Field(default=None, description="访问接口", examples=["http://127.0.0.1"])
|
|
26
26
|
AUTHORIZATION: Optional[str] = Field(default=None, description="认证字符串")
|
|
27
27
|
|
|
28
28
|
def setup_open_telemetry(self, app: FastAPI, service_name: str):
|
|
@@ -62,8 +62,15 @@ class OpenTelemetrySettings(BaseSettings):
|
|
|
62
62
|
TortoiseORMInstrumentor().instrument(tracer_provider=tracer_provider)
|
|
63
63
|
HTTPXClientInstrumentor().instrument(tracer_provider=tracer_provider)
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
env_prefix
|
|
67
|
-
env_file
|
|
68
|
-
case_sensitive
|
|
69
|
-
extra
|
|
65
|
+
model_config = SettingsConfigDict(
|
|
66
|
+
env_prefix="OTLP_",
|
|
67
|
+
env_file=".env",
|
|
68
|
+
case_sensitive=True,
|
|
69
|
+
extra='ignore'
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
# class Config:
|
|
73
|
+
# env_prefix = 'OTLP_'
|
|
74
|
+
# env_file = "./.env"
|
|
75
|
+
# case_sensitive = True
|
|
76
|
+
# extra = 'allow'
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from typing import Optional
|
|
2
2
|
|
|
3
3
|
from pydantic import Field
|
|
4
|
-
from pydantic_settings import BaseSettings
|
|
4
|
+
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class RedisSettings(BaseSettings):
|
|
@@ -9,8 +9,15 @@ class RedisSettings(BaseSettings):
|
|
|
9
9
|
PORT: Optional[int] = Field(default=6379, description="映射端口")
|
|
10
10
|
PASSWORD: Optional[str] = Field(default="", description="密码")
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
env_prefix
|
|
14
|
-
env_file
|
|
15
|
-
case_sensitive
|
|
16
|
-
extra
|
|
12
|
+
model_config = SettingsConfigDict(
|
|
13
|
+
env_prefix="REDIS_",
|
|
14
|
+
env_file=".env",
|
|
15
|
+
case_sensitive=True,
|
|
16
|
+
extra='ignore'
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
# class Config:
|
|
20
|
+
# env_prefix = 'REDIS_'
|
|
21
|
+
# env_file = "./.env"
|
|
22
|
+
# case_sensitive = True
|
|
23
|
+
# extra = 'allow'
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from typing import Optional
|
|
2
2
|
|
|
3
3
|
from pydantic import Field
|
|
4
|
-
from pydantic_settings import BaseSettings
|
|
4
|
+
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class SmsSettings(BaseSettings):
|
|
@@ -15,11 +15,18 @@ class SmsSettings(BaseSettings):
|
|
|
15
15
|
CHECK_CODE_RESEND_TIME: Optional[int] = Field(default=1, description="验证码重新发送时间", title="check code resend time (minute)")
|
|
16
16
|
DEFAULT_CODE: Optional[int] = Field(default="654123", description="默认验证码", title="sms default code")
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
env_prefix
|
|
20
|
-
env_file
|
|
21
|
-
case_sensitive
|
|
22
|
-
extra
|
|
18
|
+
model_config = SettingsConfigDict(
|
|
19
|
+
env_prefix="SMS_",
|
|
20
|
+
env_file=".env",
|
|
21
|
+
case_sensitive=True,
|
|
22
|
+
extra='ignore'
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
# class Config:
|
|
26
|
+
# env_prefix = 'SMS_'
|
|
27
|
+
# env_file = "./.env"
|
|
28
|
+
# case_sensitive = True
|
|
29
|
+
# extra = 'allow'
|
|
23
30
|
|
|
24
31
|
|
|
25
32
|
|
|
@@ -22,9 +22,15 @@ class SystemSettings(BaseSettings):
|
|
|
22
22
|
DATACENTER_ID: Optional[int] = Field(default='1', description="机器ID")
|
|
23
23
|
|
|
24
24
|
class Config:
|
|
25
|
-
env_prefix = ''
|
|
25
|
+
env_prefix = 'SYSTEM_'
|
|
26
26
|
env_file = "./.env"
|
|
27
27
|
case_sensitive = True
|
|
28
|
-
extra = '
|
|
28
|
+
extra = 'ignore'
|
|
29
|
+
|
|
30
|
+
# class Config:
|
|
31
|
+
# env_prefix = 'SYSTEM_'
|
|
32
|
+
# env_file = "./.env"
|
|
33
|
+
# case_sensitive = True
|
|
34
|
+
# extra = 'allow'
|
|
29
35
|
|
|
30
36
|
|
|
@@ -125,7 +125,7 @@ class IdWorker(object):
|
|
|
125
125
|
|
|
126
126
|
new_id = ((timestamp - TWEPOCH) << TIMESTAMP_LEFT_SHIFT) | (self.datacenter_id << DATACENTER_ID_SHIFT) | \
|
|
127
127
|
(self.worker_id << WOKER_ID_SHIFT) | self.sequence
|
|
128
|
-
return new_id
|
|
128
|
+
return str(new_id)
|
|
129
129
|
|
|
130
130
|
def _til_next_millis(self, last_timestamp):
|
|
131
131
|
"""
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
fastgenerateapi/__init__.py,sha256=eh2qtp7FbjrgaRX5b3H3UWpasFdNHbVFqLUhpqVbaTU,1287
|
|
2
|
-
fastgenerateapi/__version__.py,sha256=
|
|
2
|
+
fastgenerateapi/__version__.py,sha256=sI8rW3wVqSh9IB7senA2sM8kxpevmXiyJUcRPE0EWQk,496
|
|
3
3
|
fastgenerateapi/api_view/__init__.py,sha256=zkaTX5JxsNfjF-dFeEbHfUB58vhPMjm6Iiqx9HgJOrY,14
|
|
4
4
|
fastgenerateapi/api_view/api_view.py,sha256=mfD8GB-hnyI2XO3tkSOlEa2FfBLdq0_Wqvp8gFrXFKU,1160
|
|
5
|
-
fastgenerateapi/api_view/base_view.py,sha256=
|
|
6
|
-
fastgenerateapi/api_view/create_view.py,sha256=
|
|
7
|
-
fastgenerateapi/api_view/delete_filter_view.py,sha256=
|
|
8
|
-
fastgenerateapi/api_view/delete_tree_view.py,sha256
|
|
9
|
-
fastgenerateapi/api_view/delete_view.py,sha256=
|
|
10
|
-
fastgenerateapi/api_view/get_all_view.py,sha256=
|
|
11
|
-
fastgenerateapi/api_view/get_one_view.py,sha256=
|
|
12
|
-
fastgenerateapi/api_view/get_relation_view.py,sha256=
|
|
13
|
-
fastgenerateapi/api_view/get_tree_view.py,sha256=
|
|
5
|
+
fastgenerateapi/api_view/base_view.py,sha256=s8f6zdoRqPRmo6o2FqHZG2MKcn1gc8JELix8VetVo3k,9810
|
|
6
|
+
fastgenerateapi/api_view/create_view.py,sha256=NvJ0ocD2UMHcdipA4W7MYamxAw8sYeXAc176VAdkLek,4621
|
|
7
|
+
fastgenerateapi/api_view/delete_filter_view.py,sha256=ZP9pmRNeCTu_Go4ErfnDPnkPMShEh_Ql18iNCfMNJ3s,2838
|
|
8
|
+
fastgenerateapi/api_view/delete_tree_view.py,sha256=oqkWQNlA7TNZHHRTJJwxidOHxOgmvUpcnu81cT3oTA0,4083
|
|
9
|
+
fastgenerateapi/api_view/delete_view.py,sha256=FvaltPR1ttLfUvBoRoSHP-dGb79LRZlEMSEbYzE_W1E,3497
|
|
10
|
+
fastgenerateapi/api_view/get_all_view.py,sha256=mxX7H9DZR7FMqtSz80qj5GJ5Rg_8a8z5R3gwkZnBqmI,9176
|
|
11
|
+
fastgenerateapi/api_view/get_one_view.py,sha256=jw_H2z4rmRYgNfvBHSBgjnBNe1hpE6-A1EWRQR6bFD0,3762
|
|
12
|
+
fastgenerateapi/api_view/get_relation_view.py,sha256=mhPXoEos_2GQQSk3xlD2t_WYAiYuy1vRFR4jnBnbeSg,9766
|
|
13
|
+
fastgenerateapi/api_view/get_tree_view.py,sha256=8BQomoOU954bXrqGzeFrKS8ydHL9VPxQfwvhV59rQxg,9312
|
|
14
14
|
fastgenerateapi/api_view/sql_get_view.py,sha256=wxYI0JuH8Gw99LfMMwA4rQ_a_tBrKYxYhA7MNGQOx3A,6691
|
|
15
|
-
fastgenerateapi/api_view/switch_view.py,sha256=
|
|
16
|
-
fastgenerateapi/api_view/update_relation_view.py,sha256=
|
|
17
|
-
fastgenerateapi/api_view/update_view.py,sha256=
|
|
15
|
+
fastgenerateapi/api_view/switch_view.py,sha256=M_GSgnziz1vhrvNSwT_8I2oRy4zJnnFHh9HzUJBuy68,3317
|
|
16
|
+
fastgenerateapi/api_view/update_relation_view.py,sha256=Z77KgRE85Nkz3Y513l10CVQLcR0phhfIBCyI7LpV-hY,3762
|
|
17
|
+
fastgenerateapi/api_view/update_view.py,sha256=Y9cZwgQIl88-Gz6IhyufCB8cdVRMZ6NwhGUTUtDV5VA,4106
|
|
18
18
|
fastgenerateapi/api_view/mixin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
|
-
fastgenerateapi/api_view/mixin/base_mixin.py,sha256=
|
|
19
|
+
fastgenerateapi/api_view/mixin/base_mixin.py,sha256=qho7YCd4C1FtzTjsCU7Ax5uRx5-ryLwPEG0i_1IcTvI,6877
|
|
20
20
|
fastgenerateapi/api_view/mixin/dbmodel_mixin.py,sha256=T09Ydqr9Mt75CW6imxyNa8FsZ3wHaVS8WRmViGBmDSc,4757
|
|
21
21
|
fastgenerateapi/api_view/mixin/get_mixin.py,sha256=cpyTHaKFNsAhbtnLkz057rGcaKJXipNS-m9ftITsz1I,266
|
|
22
22
|
fastgenerateapi/api_view/mixin/response_mixin.py,sha256=cTKmrPAxjG-28Ls94-YWCl-YgvGB_0VLdYyR6t_RIhA,4404
|
|
@@ -32,8 +32,9 @@ fastgenerateapi/cache/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
|
|
|
32
32
|
fastgenerateapi/cache/cache_decorator.py,sha256=u6dfanX2GMkjsJANgT8qXuEgw1fSPXFsmpL05b0PI44,579
|
|
33
33
|
fastgenerateapi/cache/key_builder.py,sha256=6Vudd19EGg1IUGT5ftPDqLUNCCqXzmQNV69zBfjGf9A,503
|
|
34
34
|
fastgenerateapi/channel/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
35
|
-
fastgenerateapi/channel/
|
|
36
|
-
fastgenerateapi/channel/
|
|
35
|
+
fastgenerateapi/channel/connection_manager.py,sha256=BrsS0TMfgMBu3AQEb2RJwgfEUW27-e3bdZC0lM3qCls,1092
|
|
36
|
+
fastgenerateapi/channel/consumer.py,sha256=1AZFAoeUZHZYZYJbN9s4pzI4xTG8uD0FbiSvmwjRGD8,3221
|
|
37
|
+
fastgenerateapi/channel/websocket_view.py,sha256=lG9rYMO_FTdULi--oEdqCtdguR5ZM8Uzrk6f3z-86zo,2656
|
|
37
38
|
fastgenerateapi/controller/__init__.py,sha256=eM5a3k_G0bf-k_WcwfcBbI-M3kLFJIITBWX85lVyClE,316
|
|
38
39
|
fastgenerateapi/controller/filter_controller.py,sha256=PX-2oOo7WGZWePjm318RCbIlLIdeYwHKG-u1onpjB24,5030
|
|
39
40
|
fastgenerateapi/controller/router_controller.py,sha256=HnvQgFXv2EPmzeiEPjcCyy6pZL2e7s5hB9TW1fRtZvM,5364
|
|
@@ -60,7 +61,7 @@ fastgenerateapi/model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
|
|
|
60
61
|
fastgenerateapi/model/base_model.py,sha256=0eeIOHvkR4ZBpcs9mh-zlgMglJ8IGX9x7-lxdq8RPfI,1776
|
|
61
62
|
fastgenerateapi/my_fields/__init__.py,sha256=StbTm3_2IBZ8U5kEWxtNyZ3I-Qs-pCFd5vtAZTq52wA,202
|
|
62
63
|
fastgenerateapi/my_fields/aes_field.py,sha256=r4_Jhuq5lgwmITWjUYcFrv5uBR57GPGCVMgy3yNDvp4,4518
|
|
63
|
-
fastgenerateapi/my_fields/enum_field.py,sha256=
|
|
64
|
+
fastgenerateapi/my_fields/enum_field.py,sha256=5aRaJ1caiNxAzD_sNlRqGxS-knX9iUHd3pk5hCAXBAo,7986
|
|
64
65
|
fastgenerateapi/my_fields/pk_field.py,sha256=0rZIylE98xyW9QNlInr-HN843sxChwpoO4wRumWNKw4,1317
|
|
65
66
|
fastgenerateapi/my_fields/pwd_field.py,sha256=eUnarxEyHgpOzTBmsl0KxsI8lR7FzUDjxyFCKTqJDBU,2191
|
|
66
67
|
fastgenerateapi/my_fields/soft_delete_field.py,sha256=0Vf_BWewF71M27pAXkaUM82EyMe_pf3KDnW2aZmToEQ,1452
|
|
@@ -73,24 +74,24 @@ fastgenerateapi/schemas_factory/__init__.py,sha256=X9U96fiyRfCY0u6SzaCYG62RdpEGF
|
|
|
73
74
|
fastgenerateapi/schemas_factory/common_function.py,sha256=kwEQeGIA9rw4NHUVuXl9iZ2ijlHGwZVv08p5Gy3Mfcc,5224
|
|
74
75
|
fastgenerateapi/schemas_factory/common_schema_factory.py,sha256=ac_tYOcBqpnGVSkx4NCAZz3Hd1PHmwSocBRld5Jxro4,2904
|
|
75
76
|
fastgenerateapi/schemas_factory/create_schema_factory.py,sha256=rkah8geyfMkfqA6IhHDxq-lFomn8DA3bca1AtFcrLpQ,3733
|
|
76
|
-
fastgenerateapi/schemas_factory/filter_schema_factory.py,sha256=
|
|
77
|
-
fastgenerateapi/schemas_factory/get_all_schema_factory.py,sha256=
|
|
77
|
+
fastgenerateapi/schemas_factory/filter_schema_factory.py,sha256=emCfhL99Y7wi8-f3FgIZXJgG1iMd9u2ItmxA6E7m8DI,1396
|
|
78
|
+
fastgenerateapi/schemas_factory/get_all_schema_factory.py,sha256=gM2pYAGxNiqy3cmwW5lYcZHucilhI1aqCVRj2nt0EWw,5177
|
|
78
79
|
fastgenerateapi/schemas_factory/get_one_schema_factory.py,sha256=cgKoCOSK-4Lky8xUoZHIMAZmVSyWOW5-DmxaM6RAQEY,3431
|
|
79
80
|
fastgenerateapi/schemas_factory/get_relation_schema_factory.py,sha256=VvzWaxAwOnMdtaUYxmWw1tOw3KP0KBwmR6J3UAld2x0,3111
|
|
80
81
|
fastgenerateapi/schemas_factory/get_tree_schema_factory.py,sha256=v0DAf7kwB-17rHbkzVscLkm6Jh53qa2cieQ7awH78pw,7259
|
|
81
|
-
fastgenerateapi/schemas_factory/response_factory.py,sha256=
|
|
82
|
+
fastgenerateapi/schemas_factory/response_factory.py,sha256=C-E3lqIdfIJCIZhvmSaAiNJpYVOs6AGVyl90B5KRo4M,1655
|
|
82
83
|
fastgenerateapi/schemas_factory/sql_get_all_schema_factory.py,sha256=dhgMvXZIq4av7puIMiQOTuVqNOuBoMvBZVd98GWJTRg,1810
|
|
83
84
|
fastgenerateapi/schemas_factory/update_schema_factory.py,sha256=E-86vF98Ed92Q2VFqtS35xqxr_c34du9ok42JBfnj1g,3729
|
|
84
85
|
fastgenerateapi/settings/__init__.py,sha256=dlyJb7BNh8Svau-UOrV4pxfoSYnNTA6eE41fu43vlT8,173
|
|
85
86
|
fastgenerateapi/settings/all_settings.py,sha256=riAFFyOVRszZ3DZUVcudHgCgYrICnusuuFcth9zfeDM,3889
|
|
86
|
-
fastgenerateapi/settings/app_settings.py,sha256=
|
|
87
|
-
fastgenerateapi/settings/db_settings.py,sha256=
|
|
88
|
-
fastgenerateapi/settings/file_settings.py,sha256=
|
|
89
|
-
fastgenerateapi/settings/jwt_settings.py,sha256=
|
|
90
|
-
fastgenerateapi/settings/otlp_settings.py,sha256=
|
|
91
|
-
fastgenerateapi/settings/redis_settings.py,sha256=
|
|
92
|
-
fastgenerateapi/settings/sms_settings.py,sha256=
|
|
93
|
-
fastgenerateapi/settings/system_settings.py,sha256=
|
|
87
|
+
fastgenerateapi/settings/app_settings.py,sha256=FgRVIrWUmfvfDohP2pP4JO7nFevUPEG3MNuUyfjM9BA,7294
|
|
88
|
+
fastgenerateapi/settings/db_settings.py,sha256=ClmQg00bpn-EWnrdKjjJ5_emPoa1eEDf0oBoNGp7g3M,1594
|
|
89
|
+
fastgenerateapi/settings/file_settings.py,sha256=Vtzp_LV4tBYQDwNOJfY3QyoQGvDEv_KZ3N_HR9md1-o,898
|
|
90
|
+
fastgenerateapi/settings/jwt_settings.py,sha256=mRtzLZz1bntrl6UXAnIq6xilEEN8NS8oJSv62CGXOEs,971
|
|
91
|
+
fastgenerateapi/settings/otlp_settings.py,sha256=4haWpSdJBeor-rq_rBOgQl6oYRv9eppdwm1yWGt6GyE,3161
|
|
92
|
+
fastgenerateapi/settings/redis_settings.py,sha256=6T-KqCj2Jva7SarDCExZZbdvr54u6n08mEJ0gQhlUoc,700
|
|
93
|
+
fastgenerateapi/settings/sms_settings.py,sha256=NUsryRgr4Li5JXXcDMV5sfgzApX0GGyfJWAmCa_OV-U,1185
|
|
94
|
+
fastgenerateapi/settings/system_settings.py,sha256=3AGyhdBkkTJzfOeC6gHKweQ3aLsQ0GE63T5y7sLHQgo,1302
|
|
94
95
|
fastgenerateapi/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
95
96
|
fastgenerateapi/utils/aes.py,sha256=2ewx-qc7wAN68iExyNM97F8dB1sXhfGYVpNWFYR_a1k,3569
|
|
96
97
|
fastgenerateapi/utils/auto_discover.py,sha256=1R5weLj1moWbRiUXQA0dKJvsaJw4wwE-YM57bUVrGgU,2316
|
|
@@ -98,12 +99,12 @@ fastgenerateapi/utils/exception.py,sha256=dnBmVpHLUS_PZ2cwIvpAJ3ncswZnn31L98gNmC
|
|
|
98
99
|
fastgenerateapi/utils/file_utils.py,sha256=m9PrWLQ6mpT2XJyDxJtNzV3HnhQubqGb3awswSb-miM,2389
|
|
99
100
|
fastgenerateapi/utils/pwd_utils.py,sha256=Ub_CANZNX9Thv4I3U8f7op2pT_cqjxC3viqYxtZFYeA,1448
|
|
100
101
|
fastgenerateapi/utils/ramdom_utils.py,sha256=dOZyj9y1Ry8qMhAQKcVCnNtA9r5SNnR1iqGW656IH_o,984
|
|
101
|
-
fastgenerateapi/utils/snowflake.py,sha256=
|
|
102
|
+
fastgenerateapi/utils/snowflake.py,sha256=GiFVkE10sPiqJ094sMfrPsaV7Y9Y3c1djrSfgs06uIk,4643
|
|
102
103
|
fastgenerateapi/utils/str_util.py,sha256=c-jUlCFw-Dz4W1W9Jc1TqGZw3JXu-qN5ovnE6fjc9j0,3445
|
|
103
104
|
fastgenerateapi/utils/swagger_to_js.py,sha256=pPPTag6TYtxdbKMHD3m8lJvc8Gv9HC97CGHt4esU1-E,530
|
|
104
105
|
script/__init__.py,sha256=26UWatnbm6ZIwQMuu9NNzQ0IW1ACO4Oe9caModuTpWM,4
|
|
105
|
-
fastgenerateapi-1.1.
|
|
106
|
-
fastgenerateapi-1.1.
|
|
107
|
-
fastgenerateapi-1.1.
|
|
108
|
-
fastgenerateapi-1.1.
|
|
109
|
-
fastgenerateapi-1.1.
|
|
106
|
+
fastgenerateapi-1.1.9.dist-info/LICENSE,sha256=gcuuhKKc5-dwvyvHsXjlC9oM6N5gZ6umYbC8ewW1Yvg,35821
|
|
107
|
+
fastgenerateapi-1.1.9.dist-info/METADATA,sha256=dfLtlXB1ICGWrrJIb2aHRbe0j0yOYHbjZcajqSbpWxU,5960
|
|
108
|
+
fastgenerateapi-1.1.9.dist-info/WHEEL,sha256=iYlv5fX357PQyRT2o6tw1bN-YcKFFHKqB_LwHO5wP-g,110
|
|
109
|
+
fastgenerateapi-1.1.9.dist-info/top_level.txt,sha256=CW2SlpYjTRdacF-5ufnPMtwpYcR0XYn_bDxa2ZrrTBI,23
|
|
110
|
+
fastgenerateapi-1.1.9.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|