starmallow 0.6.3__tar.gz → 0.6.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. {starmallow-0.6.3 → starmallow-0.6.4}/PKG-INFO +1 -1
  2. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/__init__.py +1 -1
  3. starmallow-0.6.4/starmallow/background.py +29 -0
  4. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/request_resolver.py +7 -6
  5. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/routing.py +6 -1
  6. {starmallow-0.6.3 → starmallow-0.6.4}/.editorconfig +0 -0
  7. {starmallow-0.6.3 → starmallow-0.6.4}/.gitignore +0 -0
  8. {starmallow-0.6.3 → starmallow-0.6.4}/.pre-commit-config.yaml +0 -0
  9. {starmallow-0.6.3 → starmallow-0.6.4}/Dockerfile +0 -0
  10. {starmallow-0.6.3 → starmallow-0.6.4}/LICENSE.md +0 -0
  11. {starmallow-0.6.3 → starmallow-0.6.4}/README.md +0 -0
  12. {starmallow-0.6.3 → starmallow-0.6.4}/docker-compose.yml +0 -0
  13. {starmallow-0.6.3 → starmallow-0.6.4}/docs/design_ideas.md +0 -0
  14. {starmallow-0.6.3 → starmallow-0.6.4}/examples/__init__.py +0 -0
  15. {starmallow-0.6.3 → starmallow-0.6.4}/examples/cache_server.py +0 -0
  16. {starmallow-0.6.3 → starmallow-0.6.4}/examples/flask_server.py +0 -0
  17. {starmallow-0.6.3 → starmallow-0.6.4}/examples/goals.ipynb +0 -0
  18. {starmallow-0.6.3 → starmallow-0.6.4}/examples/gunicorn.py +0 -0
  19. {starmallow-0.6.3 → starmallow-0.6.4}/examples/recommended_server.py +0 -0
  20. {starmallow-0.6.3 → starmallow-0.6.4}/examples/sample_server.py +0 -0
  21. {starmallow-0.6.3 → starmallow-0.6.4}/pyproject.toml +0 -0
  22. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/applications.py +0 -0
  23. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/concurrency.py +0 -0
  24. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/constants.py +0 -0
  25. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/dataclasses.py +0 -0
  26. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/datastructures.py +0 -0
  27. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/decorators.py +0 -0
  28. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/delimited_field.py +0 -0
  29. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/docs.py +0 -0
  30. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/endpoint.py +0 -0
  31. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/endpoints.py +0 -0
  32. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/exception_handlers.py +0 -0
  33. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/exceptions.py +0 -0
  34. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/ext/__init__.py +0 -0
  35. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/ext/marshmallow/__init__.py +0 -0
  36. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/ext/marshmallow/openapi.py +0 -0
  37. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/fields.py +0 -0
  38. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/middleware/__init__.py +0 -0
  39. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/middleware/asyncexitstack.py +0 -0
  40. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/params.py +0 -0
  41. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/requests.py +0 -0
  42. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/responses.py +0 -0
  43. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/schema_generator.py +0 -0
  44. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/security/__init__.py +0 -0
  45. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/security/api_key.py +0 -0
  46. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/security/base.py +0 -0
  47. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/security/http.py +0 -0
  48. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/security/oauth2.py +0 -0
  49. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/security/open_id_connect_url.py +0 -0
  50. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/security/utils.py +0 -0
  51. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/serializers.py +0 -0
  52. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/types.py +0 -0
  53. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/utils.py +0 -0
  54. {starmallow-0.6.3 → starmallow-0.6.4}/starmallow/websockets.py +0 -0
  55. {starmallow-0.6.3 → starmallow-0.6.4}/tests/__init__.py +0 -0
  56. {starmallow-0.6.3 → starmallow-0.6.4}/tests/basic_api.py +0 -0
  57. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/__init__.py +0 -0
  58. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/api_key/__init__.py +0 -0
  59. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/api_key/test_api_key_cookie.py +0 -0
  60. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/api_key/test_api_key_cookie_description.py +0 -0
  61. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/api_key/test_api_key_cookie_optional.py +0 -0
  62. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/api_key/test_api_key_header.py +0 -0
  63. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/api_key/test_api_key_header_description.py +0 -0
  64. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/api_key/test_api_key_header_optional.py +0 -0
  65. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/api_key/test_api_key_query.py +0 -0
  66. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/api_key/test_api_key_query_description.py +0 -0
  67. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/api_key/test_api_key_query_optional.py +0 -0
  68. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/http/__init__.py +0 -0
  69. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/http/test_http_base.py +0 -0
  70. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/http/test_http_base_description.py +0 -0
  71. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/http/test_http_base_optional.py +0 -0
  72. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/http/test_http_basic.py +0 -0
  73. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/http/test_http_basic_realm.py +0 -0
  74. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/http/test_http_basic_realm_description.py +0 -0
  75. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/http/test_http_bearer.py +0 -0
  76. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/http/test_http_bearer_description.py +0 -0
  77. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/http/test_http_bearer_optional.py +0 -0
  78. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/http/test_http_digest.py +0 -0
  79. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/http/test_http_digest_description.py +0 -0
  80. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/http/test_http_digest_optional.py +0 -0
  81. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/oauth2/__init__.py +0 -0
  82. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/oauth2/test_oauth2.py +0 -0
  83. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/oauth2/test_oauth2_authorization_code_bearer.py +0 -0
  84. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/oauth2/test_oauth2_authorization_code_bearer_description.py +0 -0
  85. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/oauth2/test_oauth2_optional.py +0 -0
  86. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/oauth2/test_oauth2_optional_description.py +0 -0
  87. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/oauth2/test_oauth2_password_bearer_optional.py +0 -0
  88. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/oauth2/test_oauth2_password_bearer_optional_description.py +0 -0
  89. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/openid_connect/__init__.py +0 -0
  90. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/openid_connect/test_openid_connect.py +0 -0
  91. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/openid_connect/test_openid_connect_description.py +0 -0
  92. {starmallow-0.6.3 → starmallow-0.6.4}/tests/security/openid_connect/test_openid_connect_optional.py +0 -0
  93. {starmallow-0.6.3 → starmallow-0.6.4}/tests/test_additional_properties.py +0 -0
  94. {starmallow-0.6.3 → starmallow-0.6.4}/tests/test_additional_response_extra.py +0 -0
  95. {starmallow-0.6.3 → starmallow-0.6.4}/tests/test_additional_responses_bad.py +0 -0
  96. {starmallow-0.6.3 → starmallow-0.6.4}/tests/test_additional_responses_custom_model_in_callback.py +0 -0
  97. {starmallow-0.6.3 → starmallow-0.6.4}/tests/test_additional_responses_custom_validationerror.py +0 -0
  98. {starmallow-0.6.3 → starmallow-0.6.4}/tests/test_additional_responses_default_validationerror.py +0 -0
  99. {starmallow-0.6.3 → starmallow-0.6.4}/tests/test_additional_responses_response_class.py +0 -0
  100. {starmallow-0.6.3 → starmallow-0.6.4}/tests/test_additional_responses_router.py +0 -0
  101. {starmallow-0.6.3 → starmallow-0.6.4}/tests/test_annotated.py +0 -0
  102. {starmallow-0.6.3 → starmallow-0.6.4}/tests/test_basic_api.py +0 -0
  103. {starmallow-0.6.3 → starmallow-0.6.4}/tests/test_dataclass_fields.py +0 -0
  104. {starmallow-0.6.3 → starmallow-0.6.4}/tests/test_delimited_params.py +0 -0
  105. {starmallow-0.6.3 → starmallow-0.6.4}/tests/test_http_endpoints.py +0 -0
  106. {starmallow-0.6.3 → starmallow-0.6.4}/tests/test_input.py +0 -0
  107. {starmallow-0.6.3 → starmallow-0.6.4}/tests/test_middleware.py +0 -0
  108. {starmallow-0.6.3 → starmallow-0.6.4}/tests/test_requests_orjson.py +0 -0
  109. {starmallow-0.6.3 → starmallow-0.6.4}/tests/test_requests_ujson.py +0 -0
  110. {starmallow-0.6.3 → starmallow-0.6.4}/tests/test_resolved_param_contextmanagers.py +0 -0
  111. {starmallow-0.6.3 → starmallow-0.6.4}/tests/test_resolved_params.py +0 -0
  112. {starmallow-0.6.3 → starmallow-0.6.4}/tests/test_responses.py +0 -0
  113. {starmallow-0.6.3 → starmallow-0.6.4}/tests/test_responses_orjson.py +0 -0
  114. {starmallow-0.6.3 → starmallow-0.6.4}/tests/test_responses_ujson.py +0 -0
  115. {starmallow-0.6.3 → starmallow-0.6.4}/tests/test_ws_router.py +0 -0
  116. {starmallow-0.6.3 → starmallow-0.6.4}/tests/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: starmallow
3
- Version: 0.6.3
3
+ Version: 0.6.4
4
4
  Summary: StarMallow framework
5
5
  Project-URL: Homepage, https://github.com/mvanderlee/starmallow
6
6
  Author-email: Michiel Vanderlee <jmt.vanderlee@gmail.com>
@@ -1,4 +1,4 @@
1
- __version__ = "0.6.3"
1
+ __version__ = "0.6.4"
2
2
 
3
3
  from .applications import StarMallow
4
4
  from .exceptions import RequestValidationError
@@ -0,0 +1,29 @@
1
+ import typing
2
+ from logging import getLogger
3
+
4
+ from starlette.background import BackgroundTask as StarletteBackgroundTask
5
+ from starlette.background import BackgroundTasks as StarletteBackgroundTasks
6
+ from starlette.background import P
7
+ from starlette.concurrency import run_in_threadpool
8
+
9
+ logger = getLogger(__name__)
10
+
11
+
12
+ class BackgroundTask(StarletteBackgroundTask):
13
+
14
+ async def __call__(self) -> None:
15
+ try:
16
+ if self.is_async:
17
+ await self.func(*self.args, **self.kwargs)
18
+ else:
19
+ await run_in_threadpool(self.func, *self.args, **self.kwargs)
20
+ except BaseException as e:
21
+ logger.exception(f'Background Task {self.func} failed: {e}')
22
+
23
+
24
+ class BackgroundTasks(StarletteBackgroundTasks):
25
+ def add_task(
26
+ self, func: typing.Callable[P, typing.Any], *args: P.args, **kwargs: P.kwargs
27
+ ) -> None:
28
+ task = BackgroundTask(func, *args, **kwargs)
29
+ self.tasks.append(task)
@@ -8,13 +8,14 @@ import marshmallow as ma
8
8
  import marshmallow.fields as mf
9
9
  from marshmallow.error_store import ErrorStore
10
10
  from marshmallow.utils import missing as missing_
11
- from starlette.background import BackgroundTasks
11
+ from starlette.background import BackgroundTasks as StarletteBackgroundTasks
12
12
  from starlette.datastructures import FormData, Headers, QueryParams
13
13
  from starlette.exceptions import HTTPException
14
14
  from starlette.requests import HTTPConnection, Request
15
15
  from starlette.responses import Response
16
16
  from starlette.websockets import WebSocket
17
17
 
18
+ from starmallow.background import BackgroundTasks
18
19
  from starmallow.params import Param, ParamType, ResolvedParam
19
20
  from starmallow.utils import (
20
21
  is_async_gen_callable,
@@ -113,7 +114,7 @@ def request_params_to_args(
113
114
  async def resolve_basic_args(
114
115
  request: Request | WebSocket,
115
116
  response: Response,
116
- background_tasks: BackgroundTasks,
117
+ background_tasks: StarletteBackgroundTasks,
117
118
  params: Dict[ParamType, Dict[str, Param]],
118
119
  ):
119
120
  path_values, path_errors = request_params_to_args(
@@ -183,7 +184,7 @@ async def resolve_basic_args(
183
184
  values[param_name] = request
184
185
  elif lenient_issubclass(param_type, Response):
185
186
  values[param_name] = response
186
- elif lenient_issubclass(param_type, BackgroundTasks):
187
+ elif lenient_issubclass(param_type, StarletteBackgroundTasks):
187
188
  values[param_name] = background_tasks
188
189
 
189
190
  return values, errors
@@ -217,7 +218,7 @@ async def call_resolver(
217
218
  async def resolve_subparams(
218
219
  request: Request | WebSocket,
219
220
  response: Response,
220
- background_tasks: BackgroundTasks,
221
+ background_tasks: StarletteBackgroundTasks,
221
222
  params: Dict[str, ResolvedParam],
222
223
  dependency_cache: Optional[Dict[Tuple[Callable[..., Any], Tuple[str]], Any]],
223
224
  ) -> Dict[str, Any]:
@@ -250,10 +251,10 @@ async def resolve_subparams(
250
251
  async def resolve_params(
251
252
  request: Request | WebSocket,
252
253
  params: Dict[ParamType, Dict[str, Param]],
253
- background_tasks: Optional[BackgroundTasks] = None,
254
+ background_tasks: Optional[StarletteBackgroundTasks] = None,
254
255
  response: Optional[Response] = None,
255
256
  dependency_cache: Optional[Dict[Tuple[Callable[..., Any], Tuple[str]], Any]] = None,
256
- ) -> Tuple[Dict[str, Any], Dict[str, Union[Any, List, Dict]], BackgroundTasks, Response]:
257
+ ) -> Tuple[Dict[str, Any], Dict[str, Union[Any, List, Dict]], StarletteBackgroundTasks, Response]:
257
258
  dependency_cache = dependency_cache or {}
258
259
 
259
260
  if response is None:
@@ -96,7 +96,12 @@ def request_response(
96
96
  response = await run_in_threadpool(func, request)
97
97
  await response(scope, receive, send)
98
98
 
99
- await wrap_app_handling_exceptions(app, request)(scope, receive, send)
99
+ try:
100
+ await wrap_app_handling_exceptions(app, request)(scope, receive, send)
101
+ except RuntimeError as e:
102
+ # This likely means that the exception was thrown by a background task
103
+ # after the response has been successfully send to the client
104
+ logger.exception(f'Runtime error occurred: {e}')
100
105
 
101
106
  return app
102
107
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes