fastgenerateapi 0.0.26__py2.py3-none-any.whl → 0.0.28__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/delete_view.py +13 -11
- fastgenerateapi/api_view/get_all_view.py +14 -9
- fastgenerateapi/api_view/mixin/dbmodel_mixin.py +6 -3
- fastgenerateapi/api_view/mixin/response_mixin.py +27 -10
- fastgenerateapi/api_view/switch_view.py +9 -9
- fastgenerateapi/example/models.py +3 -2
- fastgenerateapi/example/schemas.py +1 -1
- fastgenerateapi/example/views.py +1 -1
- fastgenerateapi/my_fields/enum_field.py +8 -3
- fastgenerateapi/my_fields/pk_field.py +3 -5
- fastgenerateapi/my_fields/soft_delete_field.py +4 -3
- fastgenerateapi/pydantic_utils/base_model.py +19 -12
- fastgenerateapi/schemas_factory/response_factory.py +2 -7
- fastgenerateapi/schemas_factory/update_schema_factory.py +1 -1
- fastgenerateapi/settings/settings.py +27 -24
- {fastgenerateapi-0.0.26.dist-info → fastgenerateapi-0.0.28.dist-info}/METADATA +1 -1
- {fastgenerateapi-0.0.26.dist-info → fastgenerateapi-0.0.28.dist-info}/RECORD +21 -21
- {fastgenerateapi-0.0.26.dist-info → fastgenerateapi-0.0.28.dist-info}/WHEEL +1 -1
- {fastgenerateapi-0.0.26.dist-info → fastgenerateapi-0.0.28.dist-info}/LICENSE +0 -0
- {fastgenerateapi-0.0.26.dist-info → fastgenerateapi-0.0.28.dist-info}/top_level.txt +0 -0
fastgenerateapi/__version__.py
CHANGED
|
@@ -28,19 +28,21 @@ class DeleteView(BaseView):
|
|
|
28
28
|
queryset = await self.get_del_queryset(request_data=request_data, *args, **kwargs)
|
|
29
29
|
await self.delete_queryset(queryset)
|
|
30
30
|
|
|
31
|
-
# if unique_fields := self._get_unique_fields(self.model_class):
|
|
32
|
-
# for model in await queryset:
|
|
33
|
-
# model.is_active = False
|
|
34
|
-
# for field in unique_fields:
|
|
35
|
-
# try:
|
|
36
|
-
# setattr(model, field, getattr(model, field) + f"__{int(time.time() * 1000)}")
|
|
37
|
-
# except Exception as e:
|
|
38
|
-
# setattr(model, field, getattr(model, field) + f"__{int(time.time() * 1000)}")
|
|
39
|
-
# await model.save()
|
|
40
|
-
# else:
|
|
41
|
-
# await queryset.update(is_active=False)
|
|
42
31
|
return
|
|
43
32
|
|
|
33
|
+
# 弃用思路:唯一字段加时间戳
|
|
34
|
+
# if unique_fields := self._get_unique_fields(self.model_class):
|
|
35
|
+
# for model in await queryset:
|
|
36
|
+
# model.is_active = False
|
|
37
|
+
# for field in unique_fields:
|
|
38
|
+
# try:
|
|
39
|
+
# setattr(model, field, getattr(model, field) + f"__{int(time.time() * 1000)}")
|
|
40
|
+
# except Exception as e:
|
|
41
|
+
# setattr(model, field, getattr(model, field) + f"__{int(time.time() * 1000)}")
|
|
42
|
+
# await model.save()
|
|
43
|
+
# else:
|
|
44
|
+
# await queryset.update(is_active=False)
|
|
45
|
+
|
|
44
46
|
async def get_del_queryset(self, request_data, *args, **kwargs):
|
|
45
47
|
queryset = self.queryset.filter(id__in=request_data.id_list)
|
|
46
48
|
return queryset
|
|
@@ -25,7 +25,6 @@ from fastgenerateapi.settings.register_settings import settings
|
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
class GetAllView(BaseView, GetMixin):
|
|
28
|
-
|
|
29
28
|
get_all_route: Union[bool, DEPENDENCIES] = True
|
|
30
29
|
get_all_schema: Optional[Type[BaseModel]] = None
|
|
31
30
|
search_fields: Union[None, list] = None
|
|
@@ -81,14 +80,15 @@ class GetAllView(BaseView, GetMixin):
|
|
|
81
80
|
async def pagination_data(
|
|
82
81
|
self,
|
|
83
82
|
queryset: QuerySet,
|
|
84
|
-
paginator,
|
|
83
|
+
paginator=None,
|
|
85
84
|
schema: Type[BaseModel] = None,
|
|
86
85
|
fields: List[Union[str, tuple]] = None,
|
|
87
86
|
*args, **kwargs
|
|
88
87
|
):
|
|
89
88
|
|
|
90
89
|
data_list = []
|
|
91
|
-
if getattr(paginator, settings.app_settings.DETERMINE_WHETHER_PAGE_FIELD) ==
|
|
90
|
+
if paginator is None or getattr(paginator, settings.app_settings.DETERMINE_WHETHER_PAGE_FIELD) == \
|
|
91
|
+
settings.app_settings.DETERMINE_PAGE_BOOL_VALUE:
|
|
92
92
|
model_list = await queryset.all()
|
|
93
93
|
else:
|
|
94
94
|
count = await queryset.count()
|
|
@@ -112,7 +112,8 @@ class GetAllView(BaseView, GetMixin):
|
|
|
112
112
|
else:
|
|
113
113
|
data_list.append(self.get_all_schema.from_orm(model))
|
|
114
114
|
|
|
115
|
-
if getattr(paginator, settings.app_settings.DETERMINE_WHETHER_PAGE_FIELD) ==
|
|
115
|
+
if paginator is None or getattr(paginator, settings.app_settings.DETERMINE_WHETHER_PAGE_FIELD) == \
|
|
116
|
+
settings.app_settings.DETERMINE_PAGE_BOOL_VALUE:
|
|
116
117
|
if schema or fields:
|
|
117
118
|
return get_list_schema_factory()(**{settings.app_settings.LIST_RESPONSE_FIELD: data_list})
|
|
118
119
|
return self.get_list_schema(**{settings.app_settings.LIST_RESPONSE_FIELD: data_list})
|
|
@@ -130,8 +131,12 @@ class GetAllView(BaseView, GetMixin):
|
|
|
130
131
|
settings.app_settings.LIST_RESPONSE_FIELD: data_list,
|
|
131
132
|
})
|
|
132
133
|
|
|
134
|
+
def get_page_list(self, page_result: BaseModel):
|
|
135
|
+
return getattr(page_result, settings.app_settings.LIST_RESPONSE_FIELD, [])
|
|
136
|
+
|
|
133
137
|
def _get_all_decorator(self, *args: Any, **kwargs: Any) -> DecoratedCallable:
|
|
134
|
-
@get_all_cache_decorator(cache(expire=settings.app_settings.CACHE_GET_ALL_SECONDS, coder=JsonCoder,
|
|
138
|
+
@get_all_cache_decorator(cache(expire=settings.app_settings.CACHE_GET_ALL_SECONDS, coder=JsonCoder,
|
|
139
|
+
key_builder=generate_key_builder))
|
|
135
140
|
async def route(
|
|
136
141
|
request: Request,
|
|
137
142
|
paginator=Depends(paginator_deps()),
|
|
@@ -147,6 +152,7 @@ class GetAllView(BaseView, GetMixin):
|
|
|
147
152
|
**kwargs
|
|
148
153
|
)
|
|
149
154
|
return self.success(data=data)
|
|
155
|
+
|
|
150
156
|
return route
|
|
151
157
|
|
|
152
158
|
def _handler_get_all_settings(self):
|
|
@@ -154,7 +160,9 @@ class GetAllView(BaseView, GetMixin):
|
|
|
154
160
|
return
|
|
155
161
|
self.search_controller = SearchController(self.get_base_filter(self.search_fields))
|
|
156
162
|
self.filter_controller = FilterController(self.get_base_filter(self.filter_fields))
|
|
157
|
-
self.get_all_schema = self.get_all_schema or get_all_schema_factory(
|
|
163
|
+
self.get_all_schema = self.get_all_schema or get_all_schema_factory(
|
|
164
|
+
self.model_class) or self.get_one_schema if hasattr(self, "get_one_schema") else get_one_schema_factory(
|
|
165
|
+
self.model_class)
|
|
158
166
|
self.get_page_schema = get_page_schema_factory(self.get_all_schema)
|
|
159
167
|
self.get_list_schema = get_list_schema_factory(self.get_all_schema)
|
|
160
168
|
self.get_all_response_schema = response_factory(self.get_page_schema, name="GetPage")
|
|
@@ -169,6 +177,3 @@ class GetAllView(BaseView, GetMixin):
|
|
|
169
177
|
summary=summary,
|
|
170
178
|
dependencies=self.get_all_route,
|
|
171
179
|
)
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
@@ -41,7 +41,7 @@ class DBModelMixin:
|
|
|
41
41
|
"lt": "小于",
|
|
42
42
|
"lte": "小于等于",
|
|
43
43
|
"contains": "模糊搜索",
|
|
44
|
-
"in": "范围"
|
|
44
|
+
"in": "范围",
|
|
45
45
|
}
|
|
46
46
|
return others_description.get(fields, "")
|
|
47
47
|
|
|
@@ -84,9 +84,12 @@ class DBModelMixin:
|
|
|
84
84
|
return []
|
|
85
85
|
|
|
86
86
|
@staticmethod
|
|
87
|
-
def _get_foreign_key_fields(model_class: Type[Model] = None) -> List[str]:
|
|
87
|
+
def _get_foreign_key_fields(model_class: Type[Model] = None, is_with_id: bool = True) -> List[str]:
|
|
88
88
|
try:
|
|
89
|
-
|
|
89
|
+
fields = list(model_class._meta.fk_fields)
|
|
90
|
+
if is_with_id:
|
|
91
|
+
fields = [field + "_id" for field in fields]
|
|
92
|
+
return fields
|
|
90
93
|
except:
|
|
91
94
|
return []
|
|
92
95
|
|
|
@@ -6,17 +6,25 @@ from pydantic import BaseModel
|
|
|
6
6
|
|
|
7
7
|
from fastgenerateapi.settings.register_settings import settings
|
|
8
8
|
from starlette.background import BackgroundTask
|
|
9
|
-
from starlette.responses import JSONResponse
|
|
9
|
+
from starlette.responses import JSONResponse, Response
|
|
10
10
|
|
|
11
11
|
from fastgenerateapi.pydantic_utils.base_model import JSON_ENCODERS
|
|
12
12
|
from fastgenerateapi.schemas_factory import response_factory
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
# class
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
15
|
+
# class CustomSuccessJsonResponse(JSONResponse):
|
|
16
|
+
# def __init__(self, content: Any, *args, **kwargs):
|
|
17
|
+
# if not isinstance(content, Response) or not (hasattr(content, "success") or hasattr(content, "code")):
|
|
18
|
+
# if isinstance(content, dict) and ("success" in content or "code" in content):
|
|
19
|
+
# super().__init__(content, *args, **kwargs)
|
|
20
|
+
# else:
|
|
21
|
+
# content = response_factory()(**{
|
|
22
|
+
# "success": True,
|
|
23
|
+
# "code": settings.app_settings.CODE_SUCCESS_DEFAULT_VALUE,
|
|
24
|
+
# settings.app_settings.MESSAGE_RESPONSE_FIELD: "请求成功",
|
|
25
|
+
# "data": content
|
|
26
|
+
# })
|
|
27
|
+
# super().__init__(content.dict(), *args, **kwargs)
|
|
20
28
|
|
|
21
29
|
|
|
22
30
|
class ResponseMixin:
|
|
@@ -35,7 +43,12 @@ class ResponseMixin:
|
|
|
35
43
|
json_compatible_data = jsonable_encoder(data, custom_encoder=JSON_ENCODERS)
|
|
36
44
|
if code is None:
|
|
37
45
|
code = settings.app_settings.CODE_SUCCESS_DEFAULT_VALUE
|
|
38
|
-
resp = response_factory()(
|
|
46
|
+
resp = response_factory()(**{
|
|
47
|
+
"success": True,
|
|
48
|
+
"code": code,
|
|
49
|
+
settings.app_settings.MESSAGE_RESPONSE_FIELD: msg,
|
|
50
|
+
"data": json_compatible_data
|
|
51
|
+
})
|
|
39
52
|
kwargs.update(resp.dict())
|
|
40
53
|
return JSONResponse(kwargs, status_code=status_code, background=background)
|
|
41
54
|
|
|
@@ -43,7 +56,7 @@ class ResponseMixin:
|
|
|
43
56
|
def fail(msg: str = "请求失败",
|
|
44
57
|
status_code: int = 200,
|
|
45
58
|
code: Optional[int] = None,
|
|
46
|
-
success: bool = False,
|
|
59
|
+
# success: bool = False,
|
|
47
60
|
data: Union[BaseModel, dict, str, None] = None,
|
|
48
61
|
background: Optional[BackgroundTask] = None,
|
|
49
62
|
headers: Optional[Dict[str, Any]] = None,
|
|
@@ -56,7 +69,12 @@ class ResponseMixin:
|
|
|
56
69
|
json_compatible_data = jsonable_encoder(data, custom_encoder=JSON_ENCODERS)
|
|
57
70
|
if code is None:
|
|
58
71
|
code = settings.app_settings.CODE_FAIL_DEFAULT_VALUE
|
|
59
|
-
resp = response_factory()(
|
|
72
|
+
resp = response_factory()(**{
|
|
73
|
+
"success": False,
|
|
74
|
+
"code": code,
|
|
75
|
+
settings.app_settings.MESSAGE_RESPONSE_FIELD: msg,
|
|
76
|
+
"data": json_compatible_data
|
|
77
|
+
})
|
|
60
78
|
kwargs.update(resp.dict())
|
|
61
79
|
return JSONResponse(
|
|
62
80
|
kwargs,
|
|
@@ -77,4 +95,3 @@ class ResponseMixin:
|
|
|
77
95
|
detail=msg,
|
|
78
96
|
headers=headers or {"Access-Control-Allow-Origin": '*'},
|
|
79
97
|
)
|
|
80
|
-
|
|
@@ -13,11 +13,11 @@ from fastgenerateapi.utils.parse_str import parse_str_to_bool
|
|
|
13
13
|
|
|
14
14
|
class SwitchView(BaseView):
|
|
15
15
|
|
|
16
|
-
switch_route_fields: List[str] = None #
|
|
16
|
+
switch_route_fields: List[str] = None # 布尔值|枚举值切换路由
|
|
17
17
|
"""
|
|
18
|
-
# 生成一个路由: .../is_enabled/{pk} 方法:
|
|
19
|
-
# 无参数:
|
|
20
|
-
switch_route_fields = ["is_enabled", ...]
|
|
18
|
+
# 生成一个路由: .../is_enabled/{pk} 方法:PUT
|
|
19
|
+
# 无参数: 默认布尔值类型切换相反值 有参数:{"is_enabled":True} 切换参数值
|
|
20
|
+
switch_route_fields = ["is_enabled", "status", ...]
|
|
21
21
|
"""
|
|
22
22
|
|
|
23
23
|
async def switch(self, pk, request, filed, *args, **kwargs):
|
|
@@ -33,7 +33,7 @@ class SwitchView(BaseView):
|
|
|
33
33
|
setattr(
|
|
34
34
|
model,
|
|
35
35
|
filed,
|
|
36
|
-
not getattr(model, filed) if request_data.get(filed) is None else
|
|
36
|
+
not getattr(model, filed) if request_data.get(filed) is None else request_data.get(filed)
|
|
37
37
|
)
|
|
38
38
|
|
|
39
39
|
await model.save()
|
|
@@ -58,14 +58,14 @@ class SwitchView(BaseView):
|
|
|
58
58
|
if not hasattr(self, "get_one_response_schema"):
|
|
59
59
|
self.get_one_response_schema = response_factory(self.get_one_schema, name="GetOne")
|
|
60
60
|
for switch_route_field in self.switch_route_fields:
|
|
61
|
-
if self.model_class._meta.fields_map.get(switch_route_field).field_type
|
|
62
|
-
self.error(msg=f"{switch_route_field} not
|
|
61
|
+
if self.model_class._meta.fields_map.get(switch_route_field).field_type not in [bool, int]:
|
|
62
|
+
self.error(msg=f"{switch_route_field} is not bool or int")
|
|
63
63
|
# 待增加数据库模型description的读取
|
|
64
64
|
summary = f"Switch {switch_route_field}"
|
|
65
65
|
self._add_api_route(
|
|
66
|
-
path="/%s/{pk}" % switch_route_field,
|
|
66
|
+
path="/%s/{pk}" % ("switch_"+switch_route_field),
|
|
67
67
|
endpoint=self._switch_decorator(switch_route_field),
|
|
68
|
-
methods=["
|
|
68
|
+
methods=["PUT"],
|
|
69
69
|
response_model=self.get_one_response_schema,
|
|
70
70
|
summary=summary,
|
|
71
71
|
dependencies=True,
|
|
@@ -31,7 +31,7 @@ class StaffInfo(Model):
|
|
|
31
31
|
|
|
32
32
|
class PydanticMeta:
|
|
33
33
|
# 以下内容仅用于演示,存在重复和多余写法
|
|
34
|
-
exclude = ["created_at"]
|
|
34
|
+
exclude = ["delete_at", "created_at"]
|
|
35
35
|
get_include = ["category_name", "name"]
|
|
36
36
|
get_all_include = ["company__name"]
|
|
37
37
|
get_one_include = [("test", Optional[str], FieldInfo(default="", description="测试字段")), ]
|
|
@@ -52,7 +52,8 @@ class CompanyInfo(Model):
|
|
|
52
52
|
db_constraint=False,
|
|
53
53
|
description='父级')
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
class PydanticMeta:
|
|
56
|
+
exclude = ["delete_at"]
|
|
56
57
|
|
|
57
58
|
|
|
58
59
|
|
fastgenerateapi/example/views.py
CHANGED
|
@@ -15,7 +15,7 @@ class CompanyView(APIView, DeleteTreeView, GetTreeView):
|
|
|
15
15
|
# create_schema = CompanyInfoCreate
|
|
16
16
|
|
|
17
17
|
@cache()
|
|
18
|
-
async def view_get_list(self, paginator=Depends(paginator_deps()))
|
|
18
|
+
async def view_get_list(self, paginator=Depends(paginator_deps())):
|
|
19
19
|
|
|
20
20
|
return await self.pagination_data(queryset=self.queryset, fields=["id", "name"], paginator=paginator)
|
|
21
21
|
|
|
@@ -28,8 +28,8 @@ class IntEnumField(IntEnumFieldInstance):
|
|
|
28
28
|
enum_list = ["A", "B"]
|
|
29
29
|
相当于枚举
|
|
30
30
|
class CategoryEnum(IntEnum):
|
|
31
|
+
zero = 0
|
|
31
32
|
one = 1
|
|
32
|
-
two = 2
|
|
33
33
|
通过方法 get_name 获取对应的值, "A"
|
|
34
34
|
"""
|
|
35
35
|
|
|
@@ -51,6 +51,8 @@ class IntEnumField(IntEnumFieldInstance):
|
|
|
51
51
|
Converts from the Python type to the DB type.
|
|
52
52
|
"""
|
|
53
53
|
if value is not None:
|
|
54
|
+
if isinstance(value, IntEnumClass):
|
|
55
|
+
value = value.value
|
|
54
56
|
value = int(value) # pylint: disable=E1102
|
|
55
57
|
if value > len(self.enum_list) or 0 > value:
|
|
56
58
|
raise HTTPException(detail=f"枚举值:{value} 校验失败。【{self.description}】", status_code=422)
|
|
@@ -75,7 +77,7 @@ class IntEnumField(IntEnumFieldInstance):
|
|
|
75
77
|
def create_enum(self, enum_list):
|
|
76
78
|
# 创建枚举类的成员字典,确保值是唯一的
|
|
77
79
|
|
|
78
|
-
members = {self.number_to_words(name): name for name, _ in enumerate(enum_list,
|
|
80
|
+
members = {self.number_to_words(name): name for name, _ in enumerate(enum_list, 0)}
|
|
79
81
|
|
|
80
82
|
# 使用Enum的元类EnumMeta来动态创建枚举类
|
|
81
83
|
enum_class = IntEnum("CategoryEnum", members)
|
|
@@ -125,10 +127,13 @@ class IntEnumClass:
|
|
|
125
127
|
def __str__(self):
|
|
126
128
|
return f"{self.value}"
|
|
127
129
|
|
|
130
|
+
def __int__(self):
|
|
131
|
+
return self.value
|
|
132
|
+
|
|
128
133
|
@property
|
|
129
134
|
def name(self):
|
|
130
135
|
try:
|
|
131
|
-
return self.name_list[self.value
|
|
136
|
+
return self.name_list[self.value]
|
|
132
137
|
except:
|
|
133
138
|
return self.value
|
|
134
139
|
|
|
@@ -29,11 +29,9 @@ class PrimaryKeyField(Field[str], str):
|
|
|
29
29
|
allows_generated = True
|
|
30
30
|
|
|
31
31
|
def __init__(self, **kwargs: Any) -> None:
|
|
32
|
-
kwargs
|
|
33
|
-
kwargs
|
|
34
|
-
kwargs
|
|
35
|
-
kwargs["default"] = worker.get_id
|
|
36
|
-
super().__init__(pk=True, **kwargs)
|
|
32
|
+
kwargs.setdefault("description", "主键")
|
|
33
|
+
kwargs.setdefault("default", worker.get_id)
|
|
34
|
+
super().__init__(**kwargs)
|
|
37
35
|
|
|
38
36
|
def to_db_value(self, value: Any, instance: "Union[Type[Model], Model]") -> Any:
|
|
39
37
|
"""
|
|
@@ -12,14 +12,15 @@ from typing import (
|
|
|
12
12
|
Union,
|
|
13
13
|
overload,
|
|
14
14
|
)
|
|
15
|
-
from tortoise.fields import
|
|
15
|
+
from tortoise.fields import BigIntField
|
|
16
|
+
|
|
16
17
|
if TYPE_CHECKING: # pragma: nocoverage
|
|
17
18
|
from tortoise.models import Model
|
|
18
19
|
|
|
19
20
|
|
|
20
|
-
class SoftDeleteField(
|
|
21
|
+
class SoftDeleteField(BigIntField):
|
|
21
22
|
"""
|
|
22
|
-
|
|
23
|
+
毫秒级时间戳储存
|
|
23
24
|
"""
|
|
24
25
|
|
|
25
26
|
allows_generated = False
|
|
@@ -1,28 +1,36 @@
|
|
|
1
|
+
import importlib
|
|
1
2
|
from typing import List
|
|
2
3
|
|
|
3
4
|
from pydantic import BaseModel as PydanticBaseModel, Extra, BaseConfig
|
|
4
5
|
|
|
5
6
|
from fastgenerateapi.pydantic_utils.json_encoders import JSON_ENCODERS
|
|
7
|
+
from fastgenerateapi.settings.register_settings import settings
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
from_attributes = True
|
|
9
|
+
try:
|
|
10
|
+
module_path, class_name = settings.app_settings.ALIAS_GENERATOR.rsplit('.', maxsplit=1)
|
|
11
|
+
module = importlib.import_module(module_path)
|
|
12
|
+
alias_generator = getattr(module, class_name)
|
|
13
|
+
except Exception:
|
|
14
|
+
alias_generator = None
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
class Config(BaseConfig):
|
|
17
18
|
json_encoders = JSON_ENCODERS
|
|
18
19
|
extra = Extra.ignore
|
|
19
|
-
orm_mode = True
|
|
20
|
+
orm_mode = True # v1 版本
|
|
20
21
|
from_attributes = True # v2 版本
|
|
22
|
+
allow_population_by_field_name = True # v1 版本
|
|
23
|
+
populate_by_name = True # v2 版本
|
|
24
|
+
alias_generator = alias_generator
|
|
21
25
|
|
|
22
26
|
|
|
23
|
-
class
|
|
24
|
-
|
|
25
|
-
|
|
27
|
+
class BaseModel(PydanticBaseModel):
|
|
28
|
+
class Config(Config):
|
|
29
|
+
...
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class QueryConfig(Config):
|
|
33
|
+
...
|
|
26
34
|
|
|
27
35
|
|
|
28
36
|
class IDList(BaseModel):
|
|
@@ -31,4 +39,3 @@ class IDList(BaseModel):
|
|
|
31
39
|
# class Config:
|
|
32
40
|
# json_encoders = JSON_ENCODERS
|
|
33
41
|
# extra = Extra.ignore
|
|
34
|
-
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import time
|
|
1
2
|
from typing import Type, Union, Optional
|
|
2
3
|
|
|
3
4
|
from pydantic import create_model
|
|
@@ -32,15 +33,9 @@ def response_factory(schema_cls: Union[Type[T], BaseModel, None] = None, name: s
|
|
|
32
33
|
)
|
|
33
34
|
|
|
34
35
|
try:
|
|
35
|
-
name = schema_cls.__name__ + name + "Response"
|
|
36
|
+
name = schema_cls.__name__ + name + "Response" + str(time.time())
|
|
36
37
|
except:
|
|
37
38
|
name = "CommonResponse"
|
|
38
39
|
schema: Type[T] = create_model(__model_name=name, **fields, __config__=Config)
|
|
39
40
|
|
|
40
41
|
return schema
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
@@ -43,7 +43,7 @@ def update_schema_factory(
|
|
|
43
43
|
all_fields_info.update(update_include_fields_dict)
|
|
44
44
|
include_fields.update(update_include_fields_dict.keys())
|
|
45
45
|
if hasattr(model_class.PydanticMeta, "save_exclude"):
|
|
46
|
-
exclude_fields.update(model_class.PydanticMeta.
|
|
46
|
+
exclude_fields.update(model_class.PydanticMeta.save_exclude)
|
|
47
47
|
if hasattr(model_class.PydanticMeta, "update_exclude"):
|
|
48
48
|
exclude_fields.update(model_class.PydanticMeta.update_exclude)
|
|
49
49
|
else:
|
|
@@ -4,18 +4,21 @@ from pydantic import BaseSettings, Field, BaseModel
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
class AppSettings(BaseSettings):
|
|
7
|
+
# 字段配置
|
|
8
|
+
ALIAS_GENERATOR: Optional[str] = Field(default="pydantic.utils.to_lower_camel", description="序列化参数命名方法路径")
|
|
9
|
+
|
|
7
10
|
# 分页对应字段以及配置默认值
|
|
8
|
-
CURRENT_PAGE_FIELD: Optional[str] = Field(default=
|
|
9
|
-
PAGE_SIZE_FIELD: Optional[str] = Field(default=
|
|
10
|
-
TOTAL_SIZE_FIELD: Optional[str] = Field(default=
|
|
11
|
-
DETERMINE_WHETHER_PAGE_FIELD: Optional[str] = Field(default=
|
|
11
|
+
CURRENT_PAGE_FIELD: Optional[str] = Field(default="page", description="当前页字段")
|
|
12
|
+
PAGE_SIZE_FIELD: Optional[str] = Field(default="page_size", description="每页数量字段")
|
|
13
|
+
TOTAL_SIZE_FIELD: Optional[str] = Field(default="total", description="统计数量字段")
|
|
14
|
+
DETERMINE_WHETHER_PAGE_FIELD: Optional[str] = Field(default="no_page", description="判断是否分页字段")
|
|
12
15
|
DETERMINE_PAGE_BOOL_VALUE: Optional[bool] = Field(default=True, description="分页对应的布尔值")
|
|
13
16
|
DEFAULT_WHETHER_PAGE: Optional[bool] = Field(default=False, description="默认是否分页")
|
|
14
17
|
DEFAULT_PAGE_SIZE: Optional[int] = Field(default=10, description="默认每页数量")
|
|
15
18
|
DEFAULT_MAX_PAGE_SIZE: Optional[int] = Field(default=200, description="默认最大每页数量")
|
|
16
19
|
|
|
17
20
|
# 方法优化项
|
|
18
|
-
METHOD_TREE_CHOICE: Optional[str] = Field(default=
|
|
21
|
+
METHOD_TREE_CHOICE: Optional[str] = Field(default="map", description="树状查询方式{sql: sql循环查询,map: 内存查询}")
|
|
19
22
|
|
|
20
23
|
# 缓存配置参数
|
|
21
24
|
CACHE_GET_ONE_WHETHER_OPEN: Optional[bool] = Field(default=False, description="查询详情是否打开缓存")
|
|
@@ -28,24 +31,24 @@ class AppSettings(BaseSettings):
|
|
|
28
31
|
# 路由后缀字段是否添加以及配置默认值
|
|
29
32
|
ROUTER_WHETHER_UNDERLINE_TO_STRIKE: Optional[bool] = Field(default=False, description="路由是否下划线转中划线")
|
|
30
33
|
ROUTER_WHETHER_ADD_SUFFIX: Optional[bool] = Field(default=True, description="增删改查路由是否添加后缀")
|
|
31
|
-
ROUTER_CREATE_SUFFIX_FIELD: Optional[str] = Field(default=
|
|
32
|
-
ROUTER_GET_ONE_SUFFIX_FIELD: Optional[str] = Field(default=
|
|
33
|
-
ROUTER_GET_ALL_SUFFIX_FIELD: Optional[str] = Field(default=
|
|
34
|
-
ROUTER_GET_TREE_SUFFIX_FIELD: Optional[str] = Field(default=
|
|
35
|
-
ROUTER_UPDATE_SUFFIX_FIELD: Optional[str] = Field(default=
|
|
36
|
-
ROUTER_DELETE_SUFFIX_FIELD: Optional[str] = Field(default=
|
|
37
|
-
ROUTER_RECURSION_DELETE_SUFFIX_FIELD: Optional[str] = Field(default=
|
|
38
|
-
ROUTER_FILTER_DELETE_SUFFIX_FIELD: Optional[str] = Field(default=
|
|
34
|
+
ROUTER_CREATE_SUFFIX_FIELD: Optional[str] = Field(default="create", description="创建路由后缀字段")
|
|
35
|
+
ROUTER_GET_ONE_SUFFIX_FIELD: Optional[str] = Field(default="get_one", description="获取一个路由后缀字段")
|
|
36
|
+
ROUTER_GET_ALL_SUFFIX_FIELD: Optional[str] = Field(default="get_all", description="获取列表路由后缀字段")
|
|
37
|
+
ROUTER_GET_TREE_SUFFIX_FIELD: Optional[str] = Field(default="get_tree", description="获取树状数据路由后缀字段")
|
|
38
|
+
ROUTER_UPDATE_SUFFIX_FIELD: Optional[str] = Field(default="update", description="修改路由后缀字段")
|
|
39
|
+
ROUTER_DELETE_SUFFIX_FIELD: Optional[str] = Field(default="delete", description="删除路由后缀字段")
|
|
40
|
+
ROUTER_RECURSION_DELETE_SUFFIX_FIELD: Optional[str] = Field(default="delete_tree", description="递归删除路由后缀字段")
|
|
41
|
+
ROUTER_FILTER_DELETE_SUFFIX_FIELD: Optional[str] = Field(default="delete_filter", description="递归删除路由后缀字段")
|
|
39
42
|
|
|
40
43
|
# 函数转换路由时,默认添加字段,(遵循restful规范时,get路由处理方案)
|
|
41
|
-
RESTFUL_GET_ROUTER_ADD_PREFIX: Optional[str] = Field(default=
|
|
42
|
-
RESTFUL_GET_ROUTER_ADD_SUFFIX: Optional[str] = Field(default=
|
|
43
|
-
RESTFUL_POST_ROUTER_ADD_PREFIX: Optional[str] = Field(default=
|
|
44
|
-
RESTFUL_POST_ROUTER_ADD_SUFFIX: Optional[str] = Field(default=
|
|
45
|
-
RESTFUL_PUT_ROUTER_ADD_PREFIX: Optional[str] = Field(default=
|
|
46
|
-
RESTFUL_PUT_ROUTER_ADD_SUFFIX: Optional[str] = Field(default=
|
|
47
|
-
RESTFUL_DELETE_ROUTER_ADD_PREFIX: Optional[str] = Field(default=
|
|
48
|
-
RESTFUL_DELETE_ROUTER_ADD_SUFFIX: Optional[str] = Field(default=
|
|
44
|
+
RESTFUL_GET_ROUTER_ADD_PREFIX: Optional[str] = Field(default="", description="函数转换路由时:前缀添加字段")
|
|
45
|
+
RESTFUL_GET_ROUTER_ADD_SUFFIX: Optional[str] = Field(default="", description="函数转换路由时:后缀pk前添加字段")
|
|
46
|
+
RESTFUL_POST_ROUTER_ADD_PREFIX: Optional[str] = Field(default="", description="函数转换路由时:前缀添加字段")
|
|
47
|
+
RESTFUL_POST_ROUTER_ADD_SUFFIX: Optional[str] = Field(default="", description="函数转换路由时:后缀pk前添加字段")
|
|
48
|
+
RESTFUL_PUT_ROUTER_ADD_PREFIX: Optional[str] = Field(default="", description="函数转换路由时:前缀添加字段")
|
|
49
|
+
RESTFUL_PUT_ROUTER_ADD_SUFFIX: Optional[str] = Field(default="", description="函数转换路由时:后缀pk前添加字段")
|
|
50
|
+
RESTFUL_DELETE_ROUTER_ADD_PREFIX: Optional[str] = Field(default="", description="函数转换路由时:前缀添加字段")
|
|
51
|
+
RESTFUL_DELETE_ROUTER_ADD_SUFFIX: Optional[str] = Field(default="", description="函数转换路由时:后缀pk前添加字段")
|
|
49
52
|
|
|
50
53
|
# 分布式id
|
|
51
54
|
WORKER_ID: Optional[int] = Field(default=1, description="数据中心(机器区域)ID")
|
|
@@ -67,16 +70,16 @@ class AppSettings(BaseSettings):
|
|
|
67
70
|
CODE_SUCCESS_DEFAULT_VALUE: Optional[int] = Field(default=200, description="code成功返回值")
|
|
68
71
|
CODE_FAIL_DEFAULT_VALUE: Optional[int] = Field(default=-1, description="code失败返回值")
|
|
69
72
|
SUCCESS_RESPONSE_FIELD: Optional[bool] = Field(default=True, description="success返回字段")
|
|
70
|
-
MESSAGE_RESPONSE_FIELD: Optional[str] = Field(default="
|
|
73
|
+
MESSAGE_RESPONSE_FIELD: Optional[str] = Field(default="msg", description="消息返回字段")
|
|
71
74
|
DATA_RESPONSE_FIELD: Optional[str] = Field(default="data", description="数据返回字段")
|
|
72
|
-
LIST_RESPONSE_FIELD: Optional[str] = Field(default=
|
|
75
|
+
LIST_RESPONSE_FIELD: Optional[str] = Field(default="list", description="列表页返回字段")
|
|
73
76
|
|
|
74
77
|
# GetAll 筛选是否双下划线转单下划线
|
|
75
78
|
FILTER_UNDERLINE_WHETHER_DOUBLE_TO_SINGLE: Optional[bool] = Field(default=True, description="筛选是否双下划线转单下划线")
|
|
76
79
|
SCHEMAS_UNDERLINE_WHETHER_DOUBLE_TO_SINGLE: Optional[bool] = Field(default=True, description="序列化字段是否双下划线转单下划线")
|
|
77
80
|
|
|
78
81
|
class Config:
|
|
79
|
-
env_prefix =
|
|
82
|
+
env_prefix = "APP_"
|
|
80
83
|
env_file = "./.env"
|
|
81
84
|
case_sensitive = True
|
|
82
85
|
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
fastgenerateapi/__init__.py,sha256=70KtJJxhQcntZJTt2ilIR2pvokI4X6Xp200nHGZ5dkU,1264
|
|
2
|
-
fastgenerateapi/__version__.py,sha256=
|
|
2
|
+
fastgenerateapi/__version__.py,sha256=rysPaiAgrOtENJ-hp_rsL8uD-TOg9m_fOhXJxCDvmLM,497
|
|
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
5
|
fastgenerateapi/api_view/base_view.py,sha256=EvEVPJIkJNQct-s_DtN1YdRA3r97RDRYmLsPGbZOPzU,9245
|
|
6
6
|
fastgenerateapi/api_view/create_view.py,sha256=q8vlTvJfjmhqLKA4WAiIzpSSgKEvo96Ftkaa2cGwUSo,4409
|
|
7
7
|
fastgenerateapi/api_view/delete_filter_view.py,sha256=QSrFEjYmhCkSJIZw6XYl7elJr4PycxqkhMmT1D8JjJk,2479
|
|
8
8
|
fastgenerateapi/api_view/delete_tree_view.py,sha256=11kdktfLuUAnI381_uVoBw_PwCTquigQjADG7JPJEuo,3695
|
|
9
|
-
fastgenerateapi/api_view/delete_view.py,sha256=
|
|
10
|
-
fastgenerateapi/api_view/get_all_view.py,sha256=
|
|
9
|
+
fastgenerateapi/api_view/delete_view.py,sha256=KVgUr_8ElLKUHg282Ew7A61zLNAtckUJhrAQ4CyliSg,3109
|
|
10
|
+
fastgenerateapi/api_view/get_all_view.py,sha256=mXZOE4klLuSBVh_XiFVKGSl8o3Rlv_c3548EDp764vs,8600
|
|
11
11
|
fastgenerateapi/api_view/get_one_view.py,sha256=BhhQMdcD85W2FgGiJBCdQfI1TYldVAGREK1ZQFPXjnc,3359
|
|
12
12
|
fastgenerateapi/api_view/get_relation_view.py,sha256=h8D6N71L51Ifu2SkM3DcmYIICQTprrNmdW1Wbl_qeoM,9583
|
|
13
13
|
fastgenerateapi/api_view/get_tree_view.py,sha256=VRg9xqBcxXfrHrDeOUshsbEuOX8UExvB-WMWaa9-Ad8,9129
|
|
14
14
|
fastgenerateapi/api_view/sql_get_view.py,sha256=wxYI0JuH8Gw99LfMMwA4rQ_a_tBrKYxYhA7MNGQOx3A,6691
|
|
15
|
-
fastgenerateapi/api_view/switch_view.py,sha256=
|
|
15
|
+
fastgenerateapi/api_view/switch_view.py,sha256=OLZEu1nx7vlotKKjqPnF-9InB7OzHyrbtcy4517M41w,3067
|
|
16
16
|
fastgenerateapi/api_view/update_relation_view.py,sha256=UvCdnhazEein2jSRx-KFbMe7LK4ojoFXAwRwxCumOZQ,3550
|
|
17
17
|
fastgenerateapi/api_view/update_view.py,sha256=9b5-RxfSAGJIiQheM_qgin8Tkd9-Nz8LOCHw6IPatJk,3894
|
|
18
18
|
fastgenerateapi/api_view/mixin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
19
|
fastgenerateapi/api_view/mixin/base_mixin.py,sha256=JI9xFkWCTLVKI7aP92v2cXCIY8GPAIE46JxJgNKSbEw,6595
|
|
20
|
-
fastgenerateapi/api_view/mixin/dbmodel_mixin.py,sha256=
|
|
20
|
+
fastgenerateapi/api_view/mixin/dbmodel_mixin.py,sha256=W-jbt4Q1aX5WHBHiERS3aer5qJ7_ioOhe_UAs57Q70w,4403
|
|
21
21
|
fastgenerateapi/api_view/mixin/get_mixin.py,sha256=cpyTHaKFNsAhbtnLkz057rGcaKJXipNS-m9ftITsz1I,266
|
|
22
|
-
fastgenerateapi/api_view/mixin/response_mixin.py,sha256=
|
|
22
|
+
fastgenerateapi/api_view/mixin/response_mixin.py,sha256=VyJMwkm_tpGk54t1U1eo_sh0ioO85yq8TGebsHsghZA,3740
|
|
23
23
|
fastgenerateapi/api_view/mixin/save_mixin.py,sha256=inRppAov9ruKqTgGhxPto84ETp1T1WP62n6OgEBIgyU,317
|
|
24
24
|
fastgenerateapi/api_view/mixin/tool_mixin.py,sha256=Hjmb3FHDPzvr328nrTzlOEDC-0ZMqUV7FFtJqASJ1QY,15174
|
|
25
25
|
fastgenerateapi/cache/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -42,18 +42,18 @@ fastgenerateapi/deps/filter_params_deps.py,sha256=v1DRbufhwza6qnk-5LWdx84OXdAy_c
|
|
|
42
42
|
fastgenerateapi/deps/paginator_deps.py,sha256=SWXXNK9f9PXDzccHieNICSgPAG-5qMOKX2WRS4ZxHeY,3171
|
|
43
43
|
fastgenerateapi/deps/tree_params_deps.py,sha256=qpDc_HEg9FJqxJkmiGMGm04qvRs4cwII63t-aGHWTA4,1264
|
|
44
44
|
fastgenerateapi/example/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
45
|
-
fastgenerateapi/example/models.py,sha256=
|
|
45
|
+
fastgenerateapi/example/models.py,sha256=eR0fUiMNSH6fwzwBtGZOukcxPI-_uyS7vP4nHukpIc8,2203
|
|
46
46
|
fastgenerateapi/example/routers.py,sha256=gsmViGNqO1JbVc0M8tZPvD46kReOYJ5I457WwBHt4l4,437
|
|
47
|
-
fastgenerateapi/example/schemas.py,sha256=
|
|
48
|
-
fastgenerateapi/example/views.py,sha256=
|
|
47
|
+
fastgenerateapi/example/schemas.py,sha256=8UjQxy0lAvQ-nY2-PPNcsmzfg5TZJe0bVyhuIokPlgY,1677
|
|
48
|
+
fastgenerateapi/example/views.py,sha256=eYy5jgcc-IVwKREMA3U4RNDku27Nn9NJU_Flwbp3R-4,3258
|
|
49
49
|
fastgenerateapi/my_fields/__init__.py,sha256=StbTm3_2IBZ8U5kEWxtNyZ3I-Qs-pCFd5vtAZTq52wA,202
|
|
50
50
|
fastgenerateapi/my_fields/aes_field.py,sha256=r4_Jhuq5lgwmITWjUYcFrv5uBR57GPGCVMgy3yNDvp4,4518
|
|
51
|
-
fastgenerateapi/my_fields/enum_field.py,sha256=
|
|
52
|
-
fastgenerateapi/my_fields/pk_field.py,sha256=
|
|
51
|
+
fastgenerateapi/my_fields/enum_field.py,sha256=EKCUIaWU_p2ZpGcKu081IAUC7xBD4yrGnncW3HmUqWg,7810
|
|
52
|
+
fastgenerateapi/my_fields/pk_field.py,sha256=0rZIylE98xyW9QNlInr-HN843sxChwpoO4wRumWNKw4,1317
|
|
53
53
|
fastgenerateapi/my_fields/pwd_field.py,sha256=eUnarxEyHgpOzTBmsl0KxsI8lR7FzUDjxyFCKTqJDBU,2191
|
|
54
|
-
fastgenerateapi/my_fields/soft_delete_field.py,sha256=
|
|
54
|
+
fastgenerateapi/my_fields/soft_delete_field.py,sha256=0Vf_BWewF71M27pAXkaUM82EyMe_pf3KDnW2aZmToEQ,1452
|
|
55
55
|
fastgenerateapi/pydantic_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
56
|
-
fastgenerateapi/pydantic_utils/base_model.py,sha256=
|
|
56
|
+
fastgenerateapi/pydantic_utils/base_model.py,sha256=vElGjFMf1bwlMW2Jfs9ZAmUTxko-Wuj8MxcACuZbC_o,1087
|
|
57
57
|
fastgenerateapi/pydantic_utils/json_encoders.py,sha256=yzmezJk1FsLtuZ7gEM-xW1YWAO0aBf4615V6AgMrK4M,2814
|
|
58
58
|
fastgenerateapi/schemas_factory/__init__.py,sha256=X9U96fiyRfCY0u6SzaCYG62RdpEGFX7yOZh_cJl6R2E,472
|
|
59
59
|
fastgenerateapi/schemas_factory/common_function.py,sha256=zU46EbMm0NQndMpUuDSuxe2WcEr4puibehZMudbrifo,5229
|
|
@@ -64,19 +64,19 @@ fastgenerateapi/schemas_factory/get_all_schema_factory.py,sha256=H2V0u04YfvhwyT0
|
|
|
64
64
|
fastgenerateapi/schemas_factory/get_one_schema_factory.py,sha256=8rrIzAnp5ZxWdVjGxCmcUxUPWmv7hFgHLhkEmvQCMIs,3373
|
|
65
65
|
fastgenerateapi/schemas_factory/get_relation_schema_factory.py,sha256=00Mpz6kO4pH-fPoTv3HGT7P9XS0Q0Zi48WfAGy5YrNE,3117
|
|
66
66
|
fastgenerateapi/schemas_factory/get_tree_schema_factory.py,sha256=6HSXOKu73p4o2ugf4LnY8SJ18npdIGMqZ0itZVOATHU,7265
|
|
67
|
-
fastgenerateapi/schemas_factory/response_factory.py,sha256=
|
|
67
|
+
fastgenerateapi/schemas_factory/response_factory.py,sha256=4Y9e-rqvpcbaUUlIfkUvOnV4FRcXaYMIegL1-_4NXlw,1667
|
|
68
68
|
fastgenerateapi/schemas_factory/sql_get_all_schema_factory.py,sha256=fr-_J2FdLfhAQTXZHMwhF56KIf_y7suI9TCOmAV4zI8,1816
|
|
69
|
-
fastgenerateapi/schemas_factory/update_schema_factory.py,sha256=
|
|
69
|
+
fastgenerateapi/schemas_factory/update_schema_factory.py,sha256=c2K0RnKcwMaoYHJ_ak94vgvkeW4B_WIBXL-EQy9uGTY,3735
|
|
70
70
|
fastgenerateapi/settings/__init__.py,sha256=rqUtJyMLicobcyhmr74TepjmUQAEmlazKT3vjV_n3aA,6
|
|
71
71
|
fastgenerateapi/settings/register_settings.py,sha256=yeVkXuarA_OdxPQ6F4y1eW-_OuFAm9eJcFaz-YZwodg,97
|
|
72
|
-
fastgenerateapi/settings/settings.py,sha256=
|
|
72
|
+
fastgenerateapi/settings/settings.py,sha256=4RfLH65q3yRfcHlDJQ3YHX6h4yYSt6SNqHb1N0p0_To,7029
|
|
73
73
|
fastgenerateapi/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
74
74
|
fastgenerateapi/utils/aes.py,sha256=2ewx-qc7wAN68iExyNM97F8dB1sXhfGYVpNWFYR_a1k,3569
|
|
75
75
|
fastgenerateapi/utils/exception.py,sha256=dnBmVpHLUS_PZ2cwIvpAJ3ncswZnn31L98gNmCoe8_k,121
|
|
76
76
|
fastgenerateapi/utils/parse_str.py,sha256=vDUjx_Fx0nOHwtkWnOauN21NB_ecNglr5bVBKrLL33g,850
|
|
77
77
|
fastgenerateapi/utils/snowflake.py,sha256=ufr6aayY0McRp6epw2AGMqSA-CEzvXwSF5VmnIzPhLo,4539
|
|
78
|
-
fastgenerateapi-0.0.
|
|
79
|
-
fastgenerateapi-0.0.
|
|
80
|
-
fastgenerateapi-0.0.
|
|
81
|
-
fastgenerateapi-0.0.
|
|
82
|
-
fastgenerateapi-0.0.
|
|
78
|
+
fastgenerateapi-0.0.28.dist-info/LICENSE,sha256=gcuuhKKc5-dwvyvHsXjlC9oM6N5gZ6umYbC8ewW1Yvg,35821
|
|
79
|
+
fastgenerateapi-0.0.28.dist-info/METADATA,sha256=tjscZg9uptPjh5EBowCeKdl04wmUJB5Jx1NGpo_XMlo,4887
|
|
80
|
+
fastgenerateapi-0.0.28.dist-info/WHEEL,sha256=a-zpFRIJzOq5QfuhBzbhiA1eHTzNCJn8OdRvhdNX0Rk,110
|
|
81
|
+
fastgenerateapi-0.0.28.dist-info/top_level.txt,sha256=7RBBRe1lBEnxZtP89_Wj1QwI2KE8r3Pi9IwywUHTdVg,16
|
|
82
|
+
fastgenerateapi-0.0.28.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|