fastgenerateapi 1.1.8__tar.gz → 1.1.10__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of fastgenerateapi might be problematic. Click here for more details.

Files changed (118) hide show
  1. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/PKG-INFO +1 -1
  2. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/__version__.py +1 -1
  3. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/api_view/base_view.py +5 -2
  4. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/api_view/create_view.py +4 -0
  5. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/api_view/delete_filter_view.py +7 -2
  6. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/api_view/delete_tree_view.py +8 -2
  7. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/api_view/delete_view.py +8 -2
  8. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/api_view/get_all_view.py +8 -4
  9. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/api_view/get_one_view.py +5 -1
  10. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/api_view/get_relation_view.py +3 -0
  11. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/api_view/get_tree_view.py +3 -0
  12. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/api_view/mixin/base_mixin.py +1 -1
  13. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/api_view/switch_view.py +9 -3
  14. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/api_view/update_relation_view.py +4 -0
  15. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/api_view/update_view.py +4 -0
  16. fastgenerateapi-1.1.10/fastgenerateapi/channel/connection_manager.py +30 -0
  17. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/channel/consumer.py +25 -20
  18. fastgenerateapi-1.1.10/fastgenerateapi/channel/websocket_view.py +83 -0
  19. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/my_fields/enum_field.py +8 -6
  20. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/schemas_factory/filter_schema_factory.py +5 -1
  21. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/schemas_factory/get_all_schema_factory.py +6 -6
  22. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/schemas_factory/response_factory.py +2 -2
  23. fastgenerateapi-1.1.10/fastgenerateapi/settings/all_settings.py +98 -0
  24. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/settings/app_settings.py +14 -5
  25. fastgenerateapi-1.1.10/fastgenerateapi/settings/db_settings.py +59 -0
  26. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/settings/file_settings.py +13 -7
  27. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/settings/jwt_settings.py +13 -6
  28. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/settings/otlp_settings.py +14 -7
  29. fastgenerateapi-1.1.10/fastgenerateapi/settings/redis_settings.py +23 -0
  30. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/settings/sms_settings.py +13 -6
  31. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/settings/system_settings.py +8 -2
  32. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/utils/snowflake.py +1 -1
  33. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi.egg-info/PKG-INFO +1 -1
  34. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi.egg-info/SOURCES.txt +1 -0
  35. fastgenerateapi-1.1.8/fastgenerateapi/channel/websocket_view.py +0 -25
  36. fastgenerateapi-1.1.8/fastgenerateapi/settings/all_settings.py +0 -91
  37. fastgenerateapi-1.1.8/fastgenerateapi/settings/db_settings.py +0 -69
  38. fastgenerateapi-1.1.8/fastgenerateapi/settings/redis_settings.py +0 -16
  39. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/LICENSE +0 -0
  40. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/README.md +0 -0
  41. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/__init__.py +0 -0
  42. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/api_view/__init__.py +0 -0
  43. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/api_view/api_view.py +0 -0
  44. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/api_view/mixin/__init__.py +0 -0
  45. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/api_view/mixin/dbmodel_mixin.py +0 -0
  46. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/api_view/mixin/get_mixin.py +0 -0
  47. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/api_view/mixin/response_mixin.py +0 -0
  48. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/api_view/mixin/save_mixin.py +0 -0
  49. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/api_view/mixin/tool_mixin.py +0 -0
  50. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/api_view/mixin/utils/__init__.py +0 -0
  51. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/api_view/mixin/utils/docx_util.py +0 -0
  52. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/api_view/mixin/utils/file_util.py +0 -0
  53. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/api_view/mixin/utils/pdf_util.py +0 -0
  54. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/api_view/mixin/utils/xlsx_util.py +0 -0
  55. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/api_view/mixin/utils/zip_util.py +0 -0
  56. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/api_view/sql_get_view.py +0 -0
  57. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/cache/__init__.py +0 -0
  58. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/cache/cache_decorator.py +0 -0
  59. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/cache/key_builder.py +0 -0
  60. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/channel/__init__.py +0 -0
  61. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/controller/__init__.py +0 -0
  62. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/controller/filter_controller.py +0 -0
  63. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/controller/router_controller.py +0 -0
  64. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/controller/rpc_controller.py +0 -0
  65. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/controller/search_controller.py +0 -0
  66. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/controller/ws_controller.py +0 -0
  67. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/data_type/__init__.py +0 -0
  68. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/data_type/data_type.py +0 -0
  69. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/data_type/mysql_data_type.py +0 -0
  70. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/deps/__init__.py +0 -0
  71. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/deps/filter_params_deps.py +0 -0
  72. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/deps/paginator_deps.py +0 -0
  73. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/deps/tree_params_deps.py +0 -0
  74. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/example/__init__.py +0 -0
  75. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/example/models.py +0 -0
  76. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/example/routers.py +0 -0
  77. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/example/schemas.py +0 -0
  78. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/example/views.py +0 -0
  79. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/fastapi_utils/__init__.py +0 -0
  80. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/fastapi_utils/all.py +0 -0
  81. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/fastapi_utils/param_utils.py +0 -0
  82. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/fastapi_utils/response_utils.py +0 -0
  83. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/model/__init__.py +0 -0
  84. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/model/base_model.py +0 -0
  85. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/my_fields/__init__.py +0 -0
  86. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/my_fields/aes_field.py +0 -0
  87. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/my_fields/pk_field.py +0 -0
  88. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/my_fields/pwd_field.py +0 -0
  89. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/my_fields/soft_delete_field.py +0 -0
  90. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/my_fields/validator.py +0 -0
  91. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/pydantic_utils/__init__.py +0 -0
  92. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/pydantic_utils/base_model.py +0 -0
  93. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/pydantic_utils/base_settings.py +0 -0
  94. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/pydantic_utils/json_encoders.py +0 -0
  95. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/schemas_factory/__init__.py +0 -0
  96. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/schemas_factory/common_function.py +0 -0
  97. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/schemas_factory/common_schema_factory.py +0 -0
  98. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/schemas_factory/create_schema_factory.py +0 -0
  99. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/schemas_factory/get_one_schema_factory.py +0 -0
  100. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/schemas_factory/get_relation_schema_factory.py +0 -0
  101. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/schemas_factory/get_tree_schema_factory.py +0 -0
  102. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/schemas_factory/sql_get_all_schema_factory.py +0 -0
  103. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/schemas_factory/update_schema_factory.py +0 -0
  104. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/settings/__init__.py +0 -0
  105. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/utils/__init__.py +0 -0
  106. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/utils/aes.py +0 -0
  107. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/utils/auto_discover.py +0 -0
  108. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/utils/exception.py +0 -0
  109. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/utils/file_utils.py +0 -0
  110. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/utils/pwd_utils.py +0 -0
  111. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/utils/ramdom_utils.py +0 -0
  112. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/utils/str_util.py +0 -0
  113. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi/utils/swagger_to_js.py +0 -0
  114. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi.egg-info/dependency_links.txt +0 -0
  115. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/fastgenerateapi.egg-info/top_level.txt +0 -0
  116. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/script/__init__.py +0 -0
  117. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/setup.cfg +0 -0
  118. {fastgenerateapi-1.1.8 → fastgenerateapi-1.1.10}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fastgenerateapi
3
- Version: 1.1.8
3
+ Version: 1.1.10
4
4
  Summary: FastAPIView Class View
5
5
  Author: ShiLiang
6
6
  Author-email: 2509144896@qq.com
@@ -8,7 +8,7 @@
8
8
  # d8888P
9
9
 
10
10
 
11
- VERSION = (1, 1, 8)
11
+ VERSION = (1, 1, 10)
12
12
 
13
13
  __version__ = '.'.join(map(str, VERSION))
14
14
 
@@ -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
- queryset = self.queryset.filter(id=pk)
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(None, name="GetOne")
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(None, name="GetOne")
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(None, name="GetOne")
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
  )
@@ -162,4 +162,4 @@ class BaseMixin(Generic[T], APIRouter, ABC):
162
162
  route.path == f"{self.prefix}{path}" # type: ignore
163
163
  and route.methods == methods_ # type: ignore
164
164
  ):
165
- self.routes.remove(route)
165
+ self.routes.remove(route) # type: ignore
@@ -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(pk: str, request: Request) -> JSONResponse:
49
- data = await self.switch(pk=pk, request=request, filed=filed, *args, **kwargs)
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 aioredis
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 = websocket.query_params.get("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 self.redis_conn.hdel(self.group_id, self.user_id)
39
+ 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.redis_conn.hset(group_id, user_key, id(websocket))
57
+ if not await self.check_args(group_id, user_key):
58
+ await self.error(websocket, code=422, msg="无连接权限")
59
+ 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 key, value in result.items():
67
- if int(value) in exclude:
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,
@@ -0,0 +1,83 @@
1
+ from typing import Union
2
+
3
+ from starlette.websockets import WebSocket
4
+
5
+ from fastgenerateapi.api_view.base_view import BaseView
6
+ from fastgenerateapi.channel.connection_manager import ConnectionManager
7
+ from fastgenerateapi.controller.ws_controller import WsController
8
+ from fastgenerateapi.data_type.data_type import DEPENDENCIES
9
+
10
+
11
+ class WebsocketView(BaseView):
12
+ """
13
+ 客户端与服务器之间通信
14
+ """
15
+ websocket_route: Union[bool, DEPENDENCIES] = True
16
+
17
+ def _handler_websocket_settings(self):
18
+ self.ws_summary = WsController(self, self._get_cls_ws_func())
19
+ for ws_router in self.ws_summary.ws_router_data:
20
+ self._add_api_websocket_route(
21
+ f"/{ws_router.path}",
22
+ getattr(self, ws_router.func_name),
23
+ dependencies=ws_router.dependencies,
24
+ )
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 IntEnumClass(value, self.enum_list)
70
+ return value
70
71
 
71
- def get_description(self, enum_list):
72
+ @staticmethod
73
+ def get_description(enum_list, start_num=0):
72
74
  description = ""
73
- for index, val in enumerate(enum_list, 1):
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("CommonFilterParams", **model_fields, __config__=model_config)
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