fastgenerateapi 0.0.28__py2.py3-none-any.whl → 1.1.7__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.

Files changed (80) hide show
  1. fastgenerateapi/__init__.py +2 -2
  2. fastgenerateapi/__version__.py +1 -1
  3. fastgenerateapi/api_view/base_view.py +17 -7
  4. fastgenerateapi/api_view/create_view.py +1 -1
  5. fastgenerateapi/api_view/delete_filter_view.py +1 -1
  6. fastgenerateapi/api_view/delete_tree_view.py +3 -3
  7. fastgenerateapi/api_view/delete_view.py +3 -3
  8. fastgenerateapi/api_view/get_all_view.py +10 -8
  9. fastgenerateapi/api_view/get_one_view.py +1 -1
  10. fastgenerateapi/api_view/get_relation_view.py +1 -1
  11. fastgenerateapi/api_view/get_tree_view.py +1 -1
  12. fastgenerateapi/api_view/mixin/base_mixin.py +11 -7
  13. fastgenerateapi/api_view/mixin/dbmodel_mixin.py +30 -20
  14. fastgenerateapi/api_view/mixin/response_mixin.py +68 -38
  15. fastgenerateapi/api_view/mixin/tool_mixin.py +1 -357
  16. fastgenerateapi/api_view/mixin/utils/__init__.py +0 -0
  17. fastgenerateapi/api_view/mixin/utils/docx_util.py +399 -0
  18. fastgenerateapi/api_view/mixin/utils/file_util.py +30 -0
  19. fastgenerateapi/api_view/mixin/utils/pdf_util.py +76 -0
  20. fastgenerateapi/api_view/mixin/utils/xlsx_util.py +336 -0
  21. fastgenerateapi/api_view/mixin/utils/zip_util.py +50 -0
  22. fastgenerateapi/api_view/switch_view.py +2 -2
  23. fastgenerateapi/api_view/update_relation_view.py +3 -3
  24. fastgenerateapi/api_view/update_view.py +1 -1
  25. fastgenerateapi/cache/cache_decorator.py +1 -1
  26. fastgenerateapi/controller/filter_controller.py +68 -26
  27. fastgenerateapi/controller/router_controller.py +9 -9
  28. fastgenerateapi/controller/rpc_controller.py +1 -1
  29. fastgenerateapi/controller/ws_controller.py +1 -1
  30. fastgenerateapi/deps/filter_params_deps.py +34 -4
  31. fastgenerateapi/deps/paginator_deps.py +4 -4
  32. fastgenerateapi/deps/tree_params_deps.py +4 -4
  33. fastgenerateapi/fastapi_utils/__init__.py +0 -0
  34. fastgenerateapi/fastapi_utils/all.py +5 -0
  35. fastgenerateapi/fastapi_utils/param_utils.py +37 -0
  36. fastgenerateapi/fastapi_utils/response_utils.py +344 -0
  37. fastgenerateapi/model/__init__.py +0 -0
  38. fastgenerateapi/model/base_model.py +56 -0
  39. fastgenerateapi/my_fields/enum_field.py +5 -5
  40. fastgenerateapi/my_fields/validator.py +60 -0
  41. fastgenerateapi/pydantic_utils/base_model.py +46 -20
  42. fastgenerateapi/pydantic_utils/base_settings.py +16 -0
  43. fastgenerateapi/pydantic_utils/json_encoders.py +2 -1
  44. fastgenerateapi/schemas_factory/common_function.py +1 -1
  45. fastgenerateapi/schemas_factory/common_schema_factory.py +4 -4
  46. fastgenerateapi/schemas_factory/create_schema_factory.py +4 -4
  47. fastgenerateapi/schemas_factory/filter_schema_factory.py +6 -6
  48. fastgenerateapi/schemas_factory/get_all_schema_factory.py +5 -5
  49. fastgenerateapi/schemas_factory/get_one_schema_factory.py +4 -3
  50. fastgenerateapi/schemas_factory/get_relation_schema_factory.py +3 -3
  51. fastgenerateapi/schemas_factory/get_tree_schema_factory.py +3 -3
  52. fastgenerateapi/schemas_factory/response_factory.py +3 -3
  53. fastgenerateapi/schemas_factory/sql_get_all_schema_factory.py +3 -3
  54. fastgenerateapi/schemas_factory/update_schema_factory.py +4 -4
  55. fastgenerateapi/settings/__init__.py +6 -0
  56. fastgenerateapi/settings/all_settings.py +91 -0
  57. fastgenerateapi/settings/{settings.py → app_settings.py} +9 -9
  58. fastgenerateapi/settings/db_settings.py +69 -0
  59. fastgenerateapi/settings/file_settings.py +24 -0
  60. fastgenerateapi/settings/jwt_settings.py +23 -0
  61. fastgenerateapi/settings/otlp_settings.py +69 -0
  62. fastgenerateapi/settings/redis_settings.py +16 -0
  63. fastgenerateapi/settings/sms_settings.py +25 -0
  64. fastgenerateapi/settings/system_settings.py +30 -0
  65. fastgenerateapi/utils/auto_discover.py +61 -0
  66. fastgenerateapi/utils/file_utils.py +76 -0
  67. fastgenerateapi/utils/pwd_utils.py +49 -0
  68. fastgenerateapi/utils/ramdom_utils.py +48 -0
  69. fastgenerateapi/utils/snowflake.py +23 -20
  70. fastgenerateapi/utils/str_util.py +120 -0
  71. fastgenerateapi/utils/swagger_to_js.py +26 -0
  72. {fastgenerateapi-0.0.28.dist-info → fastgenerateapi-1.1.7.dist-info}/METADATA +61 -24
  73. fastgenerateapi-1.1.7.dist-info/RECORD +109 -0
  74. {fastgenerateapi-0.0.28.dist-info → fastgenerateapi-1.1.7.dist-info}/WHEEL +1 -1
  75. {fastgenerateapi-0.0.28.dist-info → fastgenerateapi-1.1.7.dist-info}/top_level.txt +1 -0
  76. script/__init__.py +2 -0
  77. fastgenerateapi/settings/register_settings.py +0 -6
  78. fastgenerateapi/utils/parse_str.py +0 -36
  79. fastgenerateapi-0.0.28.dist-info/RECORD +0 -82
  80. {fastgenerateapi-0.0.28.dist-info → fastgenerateapi-1.1.7.dist-info}/LICENSE +0 -0
@@ -23,6 +23,6 @@ from fastgenerateapi.api_view.update_relation_view import UpdateRelationView
23
23
  from fastgenerateapi.channel.websocket_view import WebsocketView
24
24
  from fastgenerateapi.channel.consumer import Consumer
25
25
 
26
- # 查看配置模型
27
- from fastgenerateapi.settings.settings import SettingsModel
26
+ # 模型相关类
27
+ from fastgenerateapi.pydantic_utils.base_model import model_config, BaseModel, IdList
28
28
 
@@ -8,7 +8,7 @@
8
8
  # d8888P
9
9
 
10
10
 
11
- VERSION = (0, 0, 28)
11
+ VERSION = (1, 1, 7)
12
12
 
13
13
  __version__ = '.'.join(map(str, VERSION))
14
14
 
@@ -15,7 +15,7 @@ from fastgenerateapi.api_view.mixin.base_mixin import BaseMixin
15
15
  from fastgenerateapi.api_view.mixin.dbmodel_mixin import DBModelMixin
16
16
  from fastgenerateapi.api_view.mixin.response_mixin import ResponseMixin
17
17
  from fastgenerateapi.api_view.mixin.tool_mixin import ToolMixin
18
- from fastgenerateapi.settings.register_settings import settings
18
+ from fastgenerateapi.settings.all_settings import settings
19
19
  from fastgenerateapi.utils.exception import NOT_FOUND
20
20
 
21
21
 
@@ -93,10 +93,17 @@ class BaseView(BaseMixin, ResponseMixin, ToolMixin, DBModelMixin):
93
93
  return result
94
94
 
95
95
  async def delete_queryset(self, queryset: QuerySet):
96
-
97
- await queryset.update(**{
98
- settings.app_settings.WHETHER_DELETE_FIELD: self._delete_value()
99
- })
96
+ """
97
+ 考虑到不一定会集成已有的模型,删除根据是否存在字段来判断
98
+ :param queryset:
99
+ :return:
100
+ """
101
+ if settings.app_settings.WHETHER_DELETE_FIELD in queryset.fields:
102
+ await queryset.update(**{
103
+ settings.app_settings.WHETHER_DELETE_FIELD: self._delete_value()
104
+ })
105
+ else:
106
+ await queryset.delete()
100
107
 
101
108
  @staticmethod
102
109
  async def setattr_model(model: Model, prefetch_related_fields, *args, **kwargs) -> Model:
@@ -137,8 +144,11 @@ class BaseView(BaseMixin, ResponseMixin, ToolMixin, DBModelMixin):
137
144
  attr_model = getattr(attr_model, attr_key, None)
138
145
  model_dict[field[1]] = attr_model
139
146
  model_fields[field[1]] = (type(attr_model), ...)
140
- schema = create_model(__model_name=f"{Model.__name__}{uuid.uuid4()}", **model_fields)
141
- return schema.parse_obj(model_dict)
147
+ schema = create_model(
148
+ f"{Model.__name__}{uuid.uuid4()}",
149
+ **model_fields
150
+ )
151
+ return schema.model_validate(model_dict)
142
152
 
143
153
  async def check_unique_field(
144
154
  self,
@@ -11,7 +11,7 @@ from fastgenerateapi.api_view.base_view import BaseView
11
11
  from fastgenerateapi.api_view.mixin.save_mixin import SaveMixin
12
12
  from fastgenerateapi.data_type.data_type import DEPENDENCIES
13
13
  from fastgenerateapi.schemas_factory import get_one_schema_factory, create_schema_factory, response_factory
14
- from fastgenerateapi.settings.register_settings import settings
14
+ from fastgenerateapi.settings.all_settings import settings
15
15
 
16
16
 
17
17
  class CreateView(BaseView, SaveMixin):
@@ -10,7 +10,7 @@ from fastgenerateapi.api_view.base_view import BaseView
10
10
  from fastgenerateapi.data_type.data_type import CALLABLE, DEPENDENCIES
11
11
  from fastgenerateapi.deps import filter_params_deps
12
12
  from fastgenerateapi.schemas_factory import response_factory
13
- from fastgenerateapi.settings.register_settings import settings
13
+ from fastgenerateapi.settings.all_settings import settings
14
14
 
15
15
 
16
16
  class DeleteFilterView(BaseView):
@@ -9,15 +9,15 @@ from tortoise.transactions import atomic
9
9
 
10
10
  from fastgenerateapi.api_view.base_view import BaseView
11
11
  from fastgenerateapi.data_type.data_type import CALLABLE, DEPENDENCIES
12
- from fastgenerateapi.pydantic_utils.base_model import IDList
12
+ from fastgenerateapi.pydantic_utils.base_model import IdList
13
13
  from fastgenerateapi.schemas_factory import response_factory
14
- from fastgenerateapi.settings.register_settings import settings
14
+ from fastgenerateapi.settings.all_settings import settings
15
15
 
16
16
 
17
17
  class DeleteTreeView(BaseView):
18
18
 
19
19
  delete_tree_route: Union[bool, DEPENDENCIES] = True
20
- delete_tree_schema: Optional[Type[BaseModel]] = IDList
20
+ delete_tree_schema: Optional[Type[BaseModel]] = IdList
21
21
  """
22
22
  delete_route: 删除路由开关,可以放依赖函数列表
23
23
  delete_schema: 删除请求模型
@@ -9,15 +9,15 @@ from tortoise.transactions import atomic
9
9
 
10
10
  from fastgenerateapi.api_view.base_view import BaseView
11
11
  from fastgenerateapi.data_type.data_type import CALLABLE, DEPENDENCIES
12
- from fastgenerateapi.pydantic_utils.base_model import IDList
12
+ from fastgenerateapi.pydantic_utils.base_model import IdList
13
13
  from fastgenerateapi.schemas_factory import response_factory
14
- from fastgenerateapi.settings.register_settings import settings
14
+ from fastgenerateapi.settings.all_settings import settings
15
15
 
16
16
 
17
17
  class DeleteView(BaseView):
18
18
 
19
19
  delete_route: Union[bool, DEPENDENCIES] = True
20
- delete_schema: Optional[Type[BaseModel]] = IDList
20
+ delete_schema: Optional[Type[BaseModel]] = IdList
21
21
  """
22
22
  delete_route: 删除路由开关,可以放依赖函数列表
23
23
  delete_schema: 删除请求模型
@@ -16,18 +16,20 @@ from fastgenerateapi.api_view.mixin.get_mixin import GetMixin
16
16
  from fastgenerateapi.cache.cache_decorator import get_all_cache_decorator
17
17
  from fastgenerateapi.cache.key_builder import generate_key_builder
18
18
  from fastgenerateapi.controller import SearchController, BaseFilter, FilterController
19
- from fastgenerateapi.data_type.data_type import DEPENDENCIES
19
+ from fastgenerateapi.data_type.data_type import DEPENDENCIES, PYDANTIC_SCHEMA
20
20
  from fastgenerateapi.deps import paginator_deps, filter_params_deps
21
+ from fastgenerateapi.deps.filter_params_deps import search_params_deps
21
22
  from fastgenerateapi.schemas_factory import get_all_schema_factory, get_page_schema_factory, get_one_schema_factory, \
22
23
  response_factory
23
24
  from fastgenerateapi.schemas_factory.get_all_schema_factory import get_list_schema_factory
24
- from fastgenerateapi.settings.register_settings import settings
25
+ from fastgenerateapi.settings.all_settings import settings
25
26
 
26
27
 
27
28
  class GetAllView(BaseView, GetMixin):
28
29
  get_all_route: Union[bool, DEPENDENCIES] = True
29
- get_all_schema: Optional[Type[BaseModel]] = None
30
+ get_all_schema: Optional[Type[PYDANTIC_SCHEMA]] = None
30
31
  search_fields: Union[None, list] = None
32
+ filter_schema: Optional[Type[PYDANTIC_SCHEMA]] = None
31
33
  filter_fields: Union[None, list] = None
32
34
  order_by_fields: Union[None, list] = None
33
35
  """
@@ -44,12 +46,12 @@ class GetAllView(BaseView, GetMixin):
44
46
  order_by_fields: 排序对应字段
45
47
  """
46
48
 
47
- async def get_all(self, search: str, filters: dict, *args, **kwargs) -> Union[BaseModel, dict, None]:
49
+ async def get_all(self, search: Optional[str], filters: dict, *args, **kwargs) -> Union[BaseModel, dict, None]:
48
50
  queryset = await self.get_queryset(search=search, filters=filters, *args, **kwargs)
49
51
 
50
52
  return await self.pagination_data(queryset=queryset, *args, **kwargs)
51
53
 
52
- async def get_queryset(self, search: str, filters: dict, *args, **kwargs) -> QuerySet:
54
+ async def get_queryset(self, search: Optional[str], filters: dict, *args, **kwargs) -> QuerySet:
53
55
  """
54
56
  处理search搜索;处理筛选字段;处理外键预加载;处理排序
55
57
  """
@@ -140,8 +142,8 @@ class GetAllView(BaseView, GetMixin):
140
142
  async def route(
141
143
  request: Request,
142
144
  paginator=Depends(paginator_deps()),
143
- search: str = Query(default="", description="搜索"),
144
- filters: dict = Depends(filter_params_deps(model_class=self.model_class, fields=self.filter_fields)),
145
+ search: Optional[str] = Depends(search_params_deps(self.search_fields)),
146
+ filters: dict = Depends(filter_params_deps(model_class=self.model_class, fields=self.filter_fields, schema=self.filter_schema)),
145
147
  ) -> JSONResponse:
146
148
  data = await self.get_all(
147
149
  paginator=paginator,
@@ -159,7 +161,7 @@ class GetAllView(BaseView, GetMixin):
159
161
  if not self.get_all_route:
160
162
  return
161
163
  self.search_controller = SearchController(self.get_base_filter(self.search_fields))
162
- self.filter_controller = FilterController(self.get_base_filter(self.filter_fields))
164
+ self.filter_controller = FilterController(self.get_base_filter(self.filter_fields, self.filter_schema))
163
165
  self.get_all_schema = self.get_all_schema or get_all_schema_factory(
164
166
  self.model_class) or self.get_one_schema if hasattr(self, "get_one_schema") else get_one_schema_factory(
165
167
  self.model_class)
@@ -14,7 +14,7 @@ from fastgenerateapi.cache.cache_decorator import get_one_cache_decorator
14
14
  from fastgenerateapi.cache.key_builder import generate_key_builder
15
15
  from fastgenerateapi.data_type.data_type import CALLABLE, DEPENDENCIES
16
16
  from fastgenerateapi.schemas_factory import get_one_schema_factory, response_factory
17
- from fastgenerateapi.settings.register_settings import settings
17
+ from fastgenerateapi.settings.all_settings import settings
18
18
  from fastgenerateapi.utils.exception import NOT_FOUND
19
19
 
20
20
 
@@ -16,7 +16,7 @@ from fastgenerateapi.deps import paginator_deps, filter_params_deps
16
16
  from fastgenerateapi.schemas_factory import get_page_schema_factory, response_factory
17
17
  from fastgenerateapi.schemas_factory.get_all_schema_factory import get_list_schema_factory
18
18
  from fastgenerateapi.schemas_factory.get_relation_schema_factory import get_relation_schema_factory
19
- from fastgenerateapi.settings.register_settings import settings
19
+ from fastgenerateapi.settings.all_settings import settings
20
20
 
21
21
 
22
22
  class GetRelationView(BaseView):
@@ -25,7 +25,7 @@ from fastgenerateapi.deps import paginator_deps, filter_params_deps
25
25
  from fastgenerateapi.deps.tree_params_deps import tree_params_deps
26
26
  from fastgenerateapi.schemas_factory import get_one_schema_factory, response_factory
27
27
  from fastgenerateapi.schemas_factory.get_tree_schema_factory import get_tree_schema_factory
28
- from fastgenerateapi.settings.register_settings import settings
28
+ from fastgenerateapi.settings.all_settings import settings
29
29
 
30
30
 
31
31
  class GetTreeView(BaseView):
@@ -10,10 +10,10 @@ from fastgenerateapi.controller.filter_controller import BaseFilter
10
10
  from fastgenerateapi.controller import RouterController
11
11
  from fastgenerateapi.controller.ws_controller import WsController
12
12
 
13
- from fastgenerateapi.settings.register_settings import settings
13
+ from fastgenerateapi.settings.all_settings import settings
14
14
  from starlette.exceptions import HTTPException
15
15
 
16
- from fastgenerateapi.data_type.data_type import DEPENDENCIES, T
16
+ from fastgenerateapi.data_type.data_type import DEPENDENCIES, T, PYDANTIC_SCHEMA
17
17
 
18
18
 
19
19
  class BaseMixin(Generic[T], APIRouter, ABC):
@@ -52,10 +52,13 @@ class BaseMixin(Generic[T], APIRouter, ABC):
52
52
  # if hasattr(self, "_handler_sql_get_all_settings"):
53
53
  # getattr(self, "_handler_sql_get_all_settings")()
54
54
 
55
- def get_base_filter(self, fields: list) -> list:
56
- if fields is None:
57
- return []
58
- return [BaseFilter(field) if not isinstance(field, BaseFilter) else field for field in fields]
55
+ def get_base_filter(self, fields: list, schema: Optional[PYDANTIC_SCHEMA] = None) -> list:
56
+ bast_filter_list = []
57
+ if fields:
58
+ bast_filter_list += [BaseFilter(field) if not isinstance(field, BaseFilter) else field for field in fields]
59
+ if schema:
60
+ bast_filter_list += [BaseFilter((field, model_field.alias)) for field, model_field in schema.__fields__.items()]
61
+ return bast_filter_list
59
62
 
60
63
  @staticmethod
61
64
  def _get_routes(is_controller_field: bool = False) -> List[str]:
@@ -70,7 +73,8 @@ class BaseMixin(Generic[T], APIRouter, ABC):
70
73
  def _get_cls_api_func(cls):
71
74
  func_list = inspect.getmembers(cls, inspect.isfunction)
72
75
 
73
- return [(func[0], inspect.signature(func[1]).return_annotation) for func in func_list if func[0].startswith("view_")]
76
+ return [(func[0], inspect.signature(func[1]).return_annotation) for func in func_list if
77
+ func[0].startswith("view_")]
74
78
 
75
79
  @classmethod
76
80
  def _get_cls_ws_func(cls):
@@ -1,11 +1,19 @@
1
1
  import inspect
2
2
  from typing import Type, Union, List, Optional
3
3
 
4
- from fastgenerateapi.settings.register_settings import settings
4
+ from fastgenerateapi.settings.all_settings import settings
5
5
  from tortoise import Model
6
6
 
7
7
 
8
8
  class DBModelMixin:
9
+ others_description = {
10
+ "gt": "大于",
11
+ "gte": "大于等于",
12
+ "lt": "小于",
13
+ "lte": "小于等于",
14
+ "contains": "模糊搜索",
15
+ "in": "范围",
16
+ }
9
17
 
10
18
  @staticmethod
11
19
  def _get_pk_field(model_class: Type[Model]) -> str:
@@ -16,34 +24,33 @@ class DBModelMixin:
16
24
 
17
25
  @staticmethod
18
26
  def get_field_description(model_class: Type[Model], fields: Union[str, list, tuple, set]) -> str:
19
-
27
+ if fields in ["id", "pk"]:
28
+ return "主键"
20
29
  if type(fields) == str:
21
30
  try:
22
31
  field_info = model_class._meta.fields_map.get(fields)
23
32
  field_info_fk = model_class._meta.fields_map.get(fields.rstrip("_id"))
24
33
  if field_info:
25
- return field_info.description
34
+ return field_info.description or ""
26
35
  elif fields.endswith("_id") and field_info_fk:
27
- return field_info_fk.description
36
+ return field_info_fk.description or ""
28
37
  elif "__" in fields:
29
38
  field_list = fields.split("__", maxsplit=1)
30
39
  description = ""
31
40
  description += DBModelMixin.get_field_description(model_class=model_class, fields=field_list[0])
32
- description += DBModelMixin.get_field_description(
33
- model_class=DBModelMixin._get_foreign_key_relation_class(model_class=model_class, field=field_list[0]),
34
- fields=field_list[1]
35
- )
41
+ if field_list[1] in DBModelMixin.others_description:
42
+ description += DBModelMixin.get_field_description(
43
+ model_class=model_class,
44
+ fields=field_list[1]
45
+ )
46
+ else:
47
+ description += DBModelMixin.get_field_description(
48
+ model_class=DBModelMixin._get_foreign_key_relation_class(model_class=model_class, field=field_list[0]),
49
+ fields=field_list[1]
50
+ )
36
51
  return description
37
52
  else:
38
- others_description = {
39
- "gt": "大于",
40
- "gte": "大于等于",
41
- "lt": "小于",
42
- "lte": "小于等于",
43
- "contains": "模糊搜索",
44
- "in": "范围",
45
- }
46
- return others_description.get(fields, "")
53
+ return DBModelMixin.others_description.get(fields, "")
47
54
 
48
55
  except Exception:
49
56
  return fields
@@ -102,7 +109,10 @@ class DBModelMixin:
102
109
 
103
110
  @staticmethod
104
111
  def _get_foreign_key_relation_class(model_class: Type[Model], field: str) -> Type[Model]:
105
- module = inspect.getmodule(model_class, inspect.getfile(model_class))
106
- res_class = getattr(module, model_class._meta.fields_map.get(field).model_name.split(".")[1])
107
- return res_class
112
+ try:
113
+ module = inspect.getmodule(model_class, inspect.getfile(model_class))
114
+ res_class = getattr(module, model_class._meta.fields_map.get(field).model_name.split(".")[1])
115
+ return res_class
116
+ except:
117
+ return model_class
108
118
 
@@ -1,42 +1,32 @@
1
+ import time
2
+ from io import BytesIO
1
3
  from typing import Union, Optional, Dict, Any
4
+ from urllib.parse import quote
2
5
 
3
6
  from fastapi import HTTPException
4
7
  from fastapi.encoders import jsonable_encoder
5
8
  from pydantic import BaseModel
6
9
 
7
- from fastgenerateapi.settings.register_settings import settings
10
+ from fastgenerateapi.settings.all_settings import settings
8
11
  from starlette.background import BackgroundTask
9
- from starlette.responses import JSONResponse, Response
12
+ from starlette.responses import JSONResponse, Response, StreamingResponse
10
13
 
11
14
  from fastgenerateapi.pydantic_utils.base_model import JSON_ENCODERS
12
15
  from fastgenerateapi.schemas_factory import response_factory
13
16
 
14
17
 
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)
28
-
29
-
30
18
  class ResponseMixin:
31
19
 
32
20
  @staticmethod
33
- def success(msg: str = "请求成功",
34
- status_code: int = 200,
35
- code: Optional[int] = None,
36
- data: Union[BaseModel, dict, str, None] = None,
37
- background: Optional[BackgroundTask] = None,
38
- *args,
39
- **kwargs):
21
+ def success(
22
+ msg: str = "请求成功",
23
+ status_code: int = 200,
24
+ code: Optional[int] = None,
25
+ data: Union[BaseModel, dict, str, None] = None,
26
+ background: Optional[BackgroundTask] = None,
27
+ *args,
28
+ **kwargs
29
+ ):
40
30
  if data is None:
41
31
  json_compatible_data = {}
42
32
  else:
@@ -53,15 +43,17 @@ class ResponseMixin:
53
43
  return JSONResponse(kwargs, status_code=status_code, background=background)
54
44
 
55
45
  @staticmethod
56
- def fail(msg: str = "请求失败",
57
- status_code: int = 200,
58
- code: Optional[int] = None,
59
- # success: bool = False,
60
- data: Union[BaseModel, dict, str, None] = None,
61
- background: Optional[BackgroundTask] = None,
62
- headers: Optional[Dict[str, Any]] = None,
63
- *args,
64
- **kwargs):
46
+ def fail(
47
+ msg: str = "请求失败",
48
+ status_code: int = 200,
49
+ code: Optional[int] = None,
50
+ # success: bool = False,
51
+ data: Union[BaseModel, dict, str, None] = None,
52
+ background: Optional[BackgroundTask] = None,
53
+ headers: Optional[Dict[str, Any]] = None,
54
+ *args,
55
+ **kwargs,
56
+ ):
65
57
 
66
58
  if data is None:
67
59
  json_compatible_data = {}
@@ -84,14 +76,52 @@ class ResponseMixin:
84
76
  )
85
77
 
86
78
  @staticmethod
87
- def error(msg: str = "系统繁忙,请稍后再试...",
88
- status_code: int = 400,
89
- headers: Optional[Dict[str, Any]] = None,
90
- *args,
91
- **kwargs):
79
+ def error(
80
+ msg: str = "系统繁忙,请稍后再试...",
81
+ status_code: int = 400,
82
+ headers: Optional[Dict[str, Any]] = None,
83
+ *args,
84
+ **kwargs,
85
+ ):
92
86
 
93
87
  raise HTTPException(
94
88
  status_code=status_code,
95
89
  detail=msg,
96
90
  headers=headers or {"Access-Control-Allow-Origin": '*'},
97
91
  )
92
+
93
+ @staticmethod
94
+ def stream(
95
+ bytes_io: BytesIO,
96
+ file_name: Optional[str] = None,
97
+ media_type: Optional[str] = None,
98
+ is_xlsx: Optional[bool] = None,
99
+ is_docx: Optional[bool] = None,
100
+ is_pdf: Optional[bool] = None,
101
+ ) -> StreamingResponse:
102
+ """
103
+
104
+ :param bytes_io: io.BytesIO()
105
+ :param file_name: 文件名称
106
+ :param media_type: 优先度大于其他参数
107
+ :param is_xlsx: 自动设置media_type
108
+ :param is_docx: 自动设置media_type
109
+ :param is_pdf: 自动设置media_type
110
+ :return: StreamingResponse
111
+ """
112
+
113
+ if not media_type:
114
+ if is_xlsx:
115
+ media_type = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8"
116
+ elif is_docx:
117
+ media_type = "application/vnd.openxmlformats-officedocument.wordprocessingml.document;charset=UTF-8"
118
+ elif is_pdf:
119
+ media_type = "application/pdf"
120
+ headers = {}
121
+ if file_name:
122
+ headers["Content-Disposition"] = f"attachment; filename={quote(file_name, safe='/:?=&')}"
123
+ return StreamingResponse(
124
+ bytes_io,
125
+ media_type= media_type,
126
+ headers=headers,
127
+ )