fastapi 0.117.1__py3-none-any.whl → 0.118.1__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 fastapi might be problematic. Click here for more details.

fastapi/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  """FastAPI framework, high performance, easy to learn, fast to code, ready for production"""
2
2
 
3
- __version__ = "0.117.1"
3
+ __version__ = "0.118.1"
4
4
 
5
5
  from starlette import status as status
6
6
 
fastapi/_compat.py CHANGED
@@ -1,3 +1,4 @@
1
+ import warnings
1
2
  from collections import deque
2
3
  from copy import copy
3
4
  from dataclasses import dataclass, is_dataclass
@@ -109,9 +110,20 @@ if PYDANTIC_V2:
109
110
  return self.field_info.annotation
110
111
 
111
112
  def __post_init__(self) -> None:
112
- self._type_adapter: TypeAdapter[Any] = TypeAdapter(
113
- Annotated[self.field_info.annotation, self.field_info]
114
- )
113
+ with warnings.catch_warnings():
114
+ # Pydantic >= 2.12.0 warns about field specific metadata that is unused
115
+ # (e.g. `TypeAdapter(Annotated[int, Field(alias='b')])`). In some cases, we
116
+ # end up building the type adapter from a model field annotation so we
117
+ # need to ignore the warning:
118
+ if PYDANTIC_VERSION_MINOR_TUPLE >= (2, 12):
119
+ from pydantic.warnings import UnsupportedFieldAttributeWarning
120
+
121
+ warnings.simplefilter(
122
+ "ignore", category=UnsupportedFieldAttributeWarning
123
+ )
124
+ self._type_adapter: TypeAdapter[Any] = TypeAdapter(
125
+ Annotated[self.field_info.annotation, self.field_info]
126
+ )
115
127
 
116
128
  def get_default(self) -> Any:
117
129
  if self.field_info.is_required():
fastapi/applications.py CHANGED
@@ -22,6 +22,7 @@ from fastapi.exception_handlers import (
22
22
  )
23
23
  from fastapi.exceptions import RequestValidationError, WebSocketRequestValidationError
24
24
  from fastapi.logger import logger
25
+ from fastapi.middleware.asyncexitstack import AsyncExitStackMiddleware
25
26
  from fastapi.openapi.docs import (
26
27
  get_redoc_html,
27
28
  get_swagger_ui_html,
@@ -36,10 +37,12 @@ from starlette.datastructures import State
36
37
  from starlette.exceptions import HTTPException
37
38
  from starlette.middleware import Middleware
38
39
  from starlette.middleware.base import BaseHTTPMiddleware
40
+ from starlette.middleware.errors import ServerErrorMiddleware
41
+ from starlette.middleware.exceptions import ExceptionMiddleware
39
42
  from starlette.requests import Request
40
43
  from starlette.responses import HTMLResponse, JSONResponse, Response
41
44
  from starlette.routing import BaseRoute
42
- from starlette.types import ASGIApp, Lifespan, Receive, Scope, Send
45
+ from starlette.types import ASGIApp, ExceptionHandler, Lifespan, Receive, Scope, Send
43
46
  from typing_extensions import Annotated, Doc, deprecated
44
47
 
45
48
  AppType = TypeVar("AppType", bound="FastAPI")
@@ -990,6 +993,54 @@ class FastAPI(Starlette):
990
993
  self.middleware_stack: Union[ASGIApp, None] = None
991
994
  self.setup()
992
995
 
996
+ def build_middleware_stack(self) -> ASGIApp:
997
+ # Duplicate/override from Starlette to add AsyncExitStackMiddleware
998
+ # inside of ExceptionMiddleware, inside of custom user middlewares
999
+ debug = self.debug
1000
+ error_handler = None
1001
+ exception_handlers: dict[Any, ExceptionHandler] = {}
1002
+
1003
+ for key, value in self.exception_handlers.items():
1004
+ if key in (500, Exception):
1005
+ error_handler = value
1006
+ else:
1007
+ exception_handlers[key] = value
1008
+
1009
+ middleware = (
1010
+ [Middleware(ServerErrorMiddleware, handler=error_handler, debug=debug)]
1011
+ + self.user_middleware
1012
+ + [
1013
+ Middleware(
1014
+ ExceptionMiddleware, handlers=exception_handlers, debug=debug
1015
+ ),
1016
+ # Add FastAPI-specific AsyncExitStackMiddleware for closing files.
1017
+ # Before this was also used for closing dependencies with yield but
1018
+ # those now have their own AsyncExitStack, to properly support
1019
+ # streaming responses while keeping compatibility with the previous
1020
+ # versions (as of writing 0.117.1) that allowed doing
1021
+ # except HTTPException inside a dependency with yield.
1022
+ # This needs to happen after user middlewares because those create a
1023
+ # new contextvars context copy by using a new AnyIO task group.
1024
+ # This AsyncExitStack preserves the context for contextvars, not
1025
+ # strictly necessary for closing files but it was one of the original
1026
+ # intentions.
1027
+ # If the AsyncExitStack lived outside of the custom middlewares and
1028
+ # contextvars were set, for example in a dependency with 'yield'
1029
+ # in that internal contextvars context, the values would not be
1030
+ # available in the outer context of the AsyncExitStack.
1031
+ # By placing the middleware and the AsyncExitStack here, inside all
1032
+ # user middlewares, the same context is used.
1033
+ # This is currently not needed, only for closing files, but used to be
1034
+ # important when dependencies with yield were closed here.
1035
+ Middleware(AsyncExitStackMiddleware),
1036
+ ]
1037
+ )
1038
+
1039
+ app = self.router
1040
+ for cls, args, kwargs in reversed(middleware):
1041
+ app = cls(app, *args, **kwargs)
1042
+ return app
1043
+
993
1044
  def openapi(self) -> Dict[str, Any]:
994
1045
  """
995
1046
  Generate the OpenAPI schema of the application. This is called by FastAPI
@@ -0,0 +1,18 @@
1
+ from contextlib import AsyncExitStack
2
+
3
+ from starlette.types import ASGIApp, Receive, Scope, Send
4
+
5
+
6
+ # Used mainly to close files after the request is done, dependencies are closed
7
+ # in their own AsyncExitStack
8
+ class AsyncExitStackMiddleware:
9
+ def __init__(
10
+ self, app: ASGIApp, context_name: str = "fastapi_middleware_astack"
11
+ ) -> None:
12
+ self.app = app
13
+ self.context_name = context_name
14
+
15
+ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
16
+ async with AsyncExitStack() as stack:
17
+ scope[self.context_name] = stack
18
+ await self.app(scope, receive, send)
fastapi/params.py CHANGED
@@ -22,7 +22,7 @@ class ParamTypes(Enum):
22
22
  cookie = "cookie"
23
23
 
24
24
 
25
- class Param(FieldInfo):
25
+ class Param(FieldInfo): # type: ignore[misc]
26
26
  in_: ParamTypes
27
27
 
28
28
  def __init__(
@@ -136,7 +136,7 @@ class Param(FieldInfo):
136
136
  return f"{self.__class__.__name__}({self.default})"
137
137
 
138
138
 
139
- class Path(Param):
139
+ class Path(Param): # type: ignore[misc]
140
140
  in_ = ParamTypes.path
141
141
 
142
142
  def __init__(
@@ -222,7 +222,7 @@ class Path(Param):
222
222
  )
223
223
 
224
224
 
225
- class Query(Param):
225
+ class Query(Param): # type: ignore[misc]
226
226
  in_ = ParamTypes.query
227
227
 
228
228
  def __init__(
@@ -306,7 +306,7 @@ class Query(Param):
306
306
  )
307
307
 
308
308
 
309
- class Header(Param):
309
+ class Header(Param): # type: ignore[misc]
310
310
  in_ = ParamTypes.header
311
311
 
312
312
  def __init__(
@@ -392,7 +392,7 @@ class Header(Param):
392
392
  )
393
393
 
394
394
 
395
- class Cookie(Param):
395
+ class Cookie(Param): # type: ignore[misc]
396
396
  in_ = ParamTypes.cookie
397
397
 
398
398
  def __init__(
@@ -476,7 +476,7 @@ class Cookie(Param):
476
476
  )
477
477
 
478
478
 
479
- class Body(FieldInfo):
479
+ class Body(FieldInfo): # type: ignore[misc]
480
480
  def __init__(
481
481
  self,
482
482
  default: Any = Undefined,
@@ -593,7 +593,7 @@ class Body(FieldInfo):
593
593
  return f"{self.__class__.__name__}({self.default})"
594
594
 
595
595
 
596
- class Form(Body):
596
+ class Form(Body): # type: ignore[misc]
597
597
  def __init__(
598
598
  self,
599
599
  default: Any = Undefined,
@@ -677,7 +677,7 @@ class Form(Body):
677
677
  )
678
678
 
679
679
 
680
- class File(Form):
680
+ class File(Form): # type: ignore[misc]
681
681
  def __init__(
682
682
  self,
683
683
  default: Any = Undefined,
fastapi/routing.py CHANGED
@@ -1,5 +1,6 @@
1
1
  import dataclasses
2
2
  import email.message
3
+ import functools
3
4
  import inspect
4
5
  import json
5
6
  import sys
@@ -8,6 +9,7 @@ from enum import Enum, IntEnum
8
9
  from typing import (
9
10
  Any,
10
11
  AsyncIterator,
12
+ Awaitable,
11
13
  Callable,
12
14
  Collection,
13
15
  Coroutine,
@@ -59,6 +61,8 @@ from fastapi.utils import (
59
61
  )
60
62
  from pydantic import BaseModel
61
63
  from starlette import routing
64
+ from starlette._exception_handler import wrap_app_handling_exceptions
65
+ from starlette._utils import is_async_callable
62
66
  from starlette.concurrency import run_in_threadpool
63
67
  from starlette.exceptions import HTTPException
64
68
  from starlette.requests import Request
@@ -68,11 +72,9 @@ from starlette.routing import (
68
72
  Match,
69
73
  compile_path,
70
74
  get_name,
71
- request_response,
72
- websocket_session,
73
75
  )
74
76
  from starlette.routing import Mount as Mount # noqa
75
- from starlette.types import AppType, ASGIApp, Lifespan, Scope
77
+ from starlette.types import AppType, ASGIApp, Lifespan, Receive, Scope, Send
76
78
  from starlette.websockets import WebSocket
77
79
  from typing_extensions import Annotated, Doc, deprecated
78
80
 
@@ -82,6 +84,73 @@ else: # pragma: no cover
82
84
  from asyncio import iscoroutinefunction
83
85
 
84
86
 
87
+ # Copy of starlette.routing.request_response modified to include the
88
+ # dependencies' AsyncExitStack
89
+ def request_response(
90
+ func: Callable[[Request], Union[Awaitable[Response], Response]],
91
+ ) -> ASGIApp:
92
+ """
93
+ Takes a function or coroutine `func(request) -> response`,
94
+ and returns an ASGI application.
95
+ """
96
+ f: Callable[[Request], Awaitable[Response]] = (
97
+ func if is_async_callable(func) else functools.partial(run_in_threadpool, func) # type:ignore
98
+ )
99
+
100
+ async def app(scope: Scope, receive: Receive, send: Send) -> None:
101
+ request = Request(scope, receive, send)
102
+
103
+ async def app(scope: Scope, receive: Receive, send: Send) -> None:
104
+ # Starts customization
105
+ response_awaited = False
106
+ async with AsyncExitStack() as stack:
107
+ scope["fastapi_inner_astack"] = stack
108
+ # Same as in Starlette
109
+ response = await f(request)
110
+ await response(scope, receive, send)
111
+ # Continues customization
112
+ response_awaited = True
113
+ if not response_awaited:
114
+ raise FastAPIError(
115
+ "Response not awaited. There's a high chance that the "
116
+ "application code is raising an exception and a dependency with yield "
117
+ "has a block with a bare except, or a block with except Exception, "
118
+ "and is not raising the exception again. Read more about it in the "
119
+ "docs: https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-with-yield/#dependencies-with-yield-and-except"
120
+ )
121
+
122
+ # Same as in Starlette
123
+ await wrap_app_handling_exceptions(app, request)(scope, receive, send)
124
+
125
+ return app
126
+
127
+
128
+ # Copy of starlette.routing.websocket_session modified to include the
129
+ # dependencies' AsyncExitStack
130
+ def websocket_session(
131
+ func: Callable[[WebSocket], Awaitable[None]],
132
+ ) -> ASGIApp:
133
+ """
134
+ Takes a coroutine `func(session)`, and returns an ASGI application.
135
+ """
136
+ # assert asyncio.iscoroutinefunction(func), "WebSocket endpoints must be async"
137
+
138
+ async def app(scope: Scope, receive: Receive, send: Send) -> None:
139
+ session = WebSocket(scope, receive=receive, send=send)
140
+
141
+ async def app(scope: Scope, receive: Receive, send: Send) -> None:
142
+ # Starts customization
143
+ async with AsyncExitStack() as stack:
144
+ scope["fastapi_inner_astack"] = stack
145
+ # Same as in Starlette
146
+ await func(session)
147
+
148
+ # Same as in Starlette
149
+ await wrap_app_handling_exceptions(app, session)(scope, receive, send)
150
+
151
+ return app
152
+
153
+
85
154
  def _prepare_response_content(
86
155
  res: Any,
87
156
  *,
@@ -246,119 +315,120 @@ def get_request_handler(
246
315
 
247
316
  async def app(request: Request) -> Response:
248
317
  response: Union[Response, None] = None
249
- async with AsyncExitStack() as file_stack:
250
- try:
251
- body: Any = None
252
- if body_field:
253
- if is_body_form:
254
- body = await request.form()
255
- file_stack.push_async_callback(body.close)
256
- else:
257
- body_bytes = await request.body()
258
- if body_bytes:
259
- json_body: Any = Undefined
260
- content_type_value = request.headers.get("content-type")
261
- if not content_type_value:
262
- json_body = await request.json()
263
- else:
264
- message = email.message.Message()
265
- message["content-type"] = content_type_value
266
- if message.get_content_maintype() == "application":
267
- subtype = message.get_content_subtype()
268
- if subtype == "json" or subtype.endswith("+json"):
269
- json_body = await request.json()
270
- if json_body != Undefined:
271
- body = json_body
272
- else:
273
- body = body_bytes
274
- except json.JSONDecodeError as e:
275
- validation_error = RequestValidationError(
276
- [
277
- {
278
- "type": "json_invalid",
279
- "loc": ("body", e.pos),
280
- "msg": "JSON decode error",
281
- "input": {},
282
- "ctx": {"error": e.msg},
283
- }
284
- ],
285
- body=e.doc,
286
- )
287
- raise validation_error from e
288
- except HTTPException:
289
- # If a middleware raises an HTTPException, it should be raised again
290
- raise
291
- except Exception as e:
292
- http_error = HTTPException(
293
- status_code=400, detail="There was an error parsing the body"
294
- )
295
- raise http_error from e
296
- errors: List[Any] = []
297
- async with AsyncExitStack() as async_exit_stack:
298
- solved_result = await solve_dependencies(
299
- request=request,
300
- dependant=dependant,
301
- body=body,
302
- dependency_overrides_provider=dependency_overrides_provider,
303
- async_exit_stack=async_exit_stack,
304
- embed_body_fields=embed_body_fields,
318
+ file_stack = request.scope.get("fastapi_middleware_astack")
319
+ assert isinstance(file_stack, AsyncExitStack), (
320
+ "fastapi_middleware_astack not found in request scope"
321
+ )
322
+
323
+ # Read body and auto-close files
324
+ try:
325
+ body: Any = None
326
+ if body_field:
327
+ if is_body_form:
328
+ body = await request.form()
329
+ file_stack.push_async_callback(body.close)
330
+ else:
331
+ body_bytes = await request.body()
332
+ if body_bytes:
333
+ json_body: Any = Undefined
334
+ content_type_value = request.headers.get("content-type")
335
+ if not content_type_value:
336
+ json_body = await request.json()
337
+ else:
338
+ message = email.message.Message()
339
+ message["content-type"] = content_type_value
340
+ if message.get_content_maintype() == "application":
341
+ subtype = message.get_content_subtype()
342
+ if subtype == "json" or subtype.endswith("+json"):
343
+ json_body = await request.json()
344
+ if json_body != Undefined:
345
+ body = json_body
346
+ else:
347
+ body = body_bytes
348
+ except json.JSONDecodeError as e:
349
+ validation_error = RequestValidationError(
350
+ [
351
+ {
352
+ "type": "json_invalid",
353
+ "loc": ("body", e.pos),
354
+ "msg": "JSON decode error",
355
+ "input": {},
356
+ "ctx": {"error": e.msg},
357
+ }
358
+ ],
359
+ body=e.doc,
360
+ )
361
+ raise validation_error from e
362
+ except HTTPException:
363
+ # If a middleware raises an HTTPException, it should be raised again
364
+ raise
365
+ except Exception as e:
366
+ http_error = HTTPException(
367
+ status_code=400, detail="There was an error parsing the body"
368
+ )
369
+ raise http_error from e
370
+
371
+ # Solve dependencies and run path operation function, auto-closing dependencies
372
+ errors: List[Any] = []
373
+ async_exit_stack = request.scope.get("fastapi_inner_astack")
374
+ assert isinstance(async_exit_stack, AsyncExitStack), (
375
+ "fastapi_inner_astack not found in request scope"
376
+ )
377
+ solved_result = await solve_dependencies(
378
+ request=request,
379
+ dependant=dependant,
380
+ body=body,
381
+ dependency_overrides_provider=dependency_overrides_provider,
382
+ async_exit_stack=async_exit_stack,
383
+ embed_body_fields=embed_body_fields,
384
+ )
385
+ errors = solved_result.errors
386
+ if not errors:
387
+ raw_response = await run_endpoint_function(
388
+ dependant=dependant,
389
+ values=solved_result.values,
390
+ is_coroutine=is_coroutine,
391
+ )
392
+ if isinstance(raw_response, Response):
393
+ if raw_response.background is None:
394
+ raw_response.background = solved_result.background_tasks
395
+ response = raw_response
396
+ else:
397
+ response_args: Dict[str, Any] = {
398
+ "background": solved_result.background_tasks
399
+ }
400
+ # If status_code was set, use it, otherwise use the default from the
401
+ # response class, in the case of redirect it's 307
402
+ current_status_code = (
403
+ status_code if status_code else solved_result.response.status_code
305
404
  )
306
- errors = solved_result.errors
307
- if not errors:
308
- raw_response = await run_endpoint_function(
309
- dependant=dependant,
310
- values=solved_result.values,
311
- is_coroutine=is_coroutine,
312
- )
313
- if isinstance(raw_response, Response):
314
- if raw_response.background is None:
315
- raw_response.background = solved_result.background_tasks
316
- response = raw_response
317
- else:
318
- response_args: Dict[str, Any] = {
319
- "background": solved_result.background_tasks
320
- }
321
- # If status_code was set, use it, otherwise use the default from the
322
- # response class, in the case of redirect it's 307
323
- current_status_code = (
324
- status_code
325
- if status_code
326
- else solved_result.response.status_code
327
- )
328
- if current_status_code is not None:
329
- response_args["status_code"] = current_status_code
330
- if solved_result.response.status_code:
331
- response_args["status_code"] = (
332
- solved_result.response.status_code
333
- )
334
- content = await serialize_response(
335
- field=response_field,
336
- response_content=raw_response,
337
- include=response_model_include,
338
- exclude=response_model_exclude,
339
- by_alias=response_model_by_alias,
340
- exclude_unset=response_model_exclude_unset,
341
- exclude_defaults=response_model_exclude_defaults,
342
- exclude_none=response_model_exclude_none,
343
- is_coroutine=is_coroutine,
344
- )
345
- response = actual_response_class(content, **response_args)
346
- if not is_body_allowed_for_status_code(response.status_code):
347
- response.body = b""
348
- response.headers.raw.extend(solved_result.response.headers.raw)
349
- if errors:
350
- validation_error = RequestValidationError(
351
- _normalize_errors(errors), body=body
405
+ if current_status_code is not None:
406
+ response_args["status_code"] = current_status_code
407
+ if solved_result.response.status_code:
408
+ response_args["status_code"] = solved_result.response.status_code
409
+ content = await serialize_response(
410
+ field=response_field,
411
+ response_content=raw_response,
412
+ include=response_model_include,
413
+ exclude=response_model_exclude,
414
+ by_alias=response_model_by_alias,
415
+ exclude_unset=response_model_exclude_unset,
416
+ exclude_defaults=response_model_exclude_defaults,
417
+ exclude_none=response_model_exclude_none,
418
+ is_coroutine=is_coroutine,
352
419
  )
353
- raise validation_error
354
- if response is None:
355
- raise FastAPIError(
356
- "No response object was returned. There's a high chance that the "
357
- "application code is raising an exception and a dependency with yield "
358
- "has a block with a bare except, or a block with except Exception, "
359
- "and is not raising the exception again. Read more about it in the "
360
- "docs: https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-with-yield/#dependencies-with-yield-and-except"
420
+ response = actual_response_class(content, **response_args)
421
+ if not is_body_allowed_for_status_code(response.status_code):
422
+ response.body = b""
423
+ response.headers.raw.extend(solved_result.response.headers.raw)
424
+ if errors:
425
+ validation_error = RequestValidationError(
426
+ _normalize_errors(errors), body=body
361
427
  )
428
+ raise validation_error
429
+
430
+ # Return response
431
+ assert response
362
432
  return response
363
433
 
364
434
  return app
@@ -370,24 +440,23 @@ def get_websocket_app(
370
440
  embed_body_fields: bool = False,
371
441
  ) -> Callable[[WebSocket], Coroutine[Any, Any, Any]]:
372
442
  async def app(websocket: WebSocket) -> None:
373
- async with AsyncExitStack() as async_exit_stack:
374
- # TODO: remove this scope later, after a few releases
375
- # This scope fastapi_astack is no longer used by FastAPI, kept for
376
- # compatibility, just in case
377
- websocket.scope["fastapi_astack"] = async_exit_stack
378
- solved_result = await solve_dependencies(
379
- request=websocket,
380
- dependant=dependant,
381
- dependency_overrides_provider=dependency_overrides_provider,
382
- async_exit_stack=async_exit_stack,
383
- embed_body_fields=embed_body_fields,
443
+ async_exit_stack = websocket.scope.get("fastapi_inner_astack")
444
+ assert isinstance(async_exit_stack, AsyncExitStack), (
445
+ "fastapi_inner_astack not found in request scope"
446
+ )
447
+ solved_result = await solve_dependencies(
448
+ request=websocket,
449
+ dependant=dependant,
450
+ dependency_overrides_provider=dependency_overrides_provider,
451
+ async_exit_stack=async_exit_stack,
452
+ embed_body_fields=embed_body_fields,
453
+ )
454
+ if solved_result.errors:
455
+ raise WebSocketRequestValidationError(
456
+ _normalize_errors(solved_result.errors)
384
457
  )
385
- if solved_result.errors:
386
- raise WebSocketRequestValidationError(
387
- _normalize_errors(solved_result.errors)
388
- )
389
- assert dependant.call is not None, "dependant.call must be a function"
390
- await dependant.call(**solved_result.values)
458
+ assert dependant.call is not None, "dependant.call must be a function"
459
+ await dependant.call(**solved_result.values)
391
460
 
392
461
  return app
393
462
 
@@ -89,7 +89,7 @@ class OAuth2PasswordRequestForm:
89
89
  Doc(
90
90
  """
91
91
  `password` string. The OAuth2 spec requires the exact field name
92
- `password".
92
+ `password`.
93
93
  """
94
94
  ),
95
95
  ],
@@ -243,7 +243,7 @@ class OAuth2PasswordRequestFormStrict(OAuth2PasswordRequestForm):
243
243
  Doc(
244
244
  """
245
245
  `password` string. The OAuth2 spec requires the exact field name
246
- `password".
246
+ `password`.
247
247
  """
248
248
  ),
249
249
  ],
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: fastapi
3
- Version: 0.117.1
3
+ Version: 0.118.1
4
4
  Summary: FastAPI framework, high performance, easy to learn, fast to code, ready for production
5
5
  Author-Email: =?utf-8?q?Sebasti=C3=A1n_Ram=C3=ADrez?= <tiangolo@gmail.com>
6
6
  Classifier: Intended Audience :: Information Technology
@@ -1,11 +1,11 @@
1
- fastapi-0.117.1.dist-info/METADATA,sha256=CSMeNXJKTuCRib4fhSOBx_tdb_N2YOd8vfHzaDAx_X0,28135
2
- fastapi-0.117.1.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
3
- fastapi-0.117.1.dist-info/entry_points.txt,sha256=GCf-WbIZxyGT4MUmrPGj1cOHYZoGsNPHAvNkT6hnGeA,61
4
- fastapi-0.117.1.dist-info/licenses/LICENSE,sha256=Tsif_IFIW5f-xYSy1KlhAy7v_oNEU4lP2cEnSQbMdE4,1086
5
- fastapi/__init__.py,sha256=71oE4uLHKzglF1IOxDbfcd-YwW2Qeu5emeUz00x0S98,1081
1
+ fastapi-0.118.1.dist-info/METADATA,sha256=1lJR4RMjB0KOujx5btnmcdNbsJTv37qlicYZUphrEQY,28135
2
+ fastapi-0.118.1.dist-info/WHEEL,sha256=9P2ygRxDrTJz3gsagc0Z96ukrxjr-LFBGOgv3AuKlCA,90
3
+ fastapi-0.118.1.dist-info/entry_points.txt,sha256=GCf-WbIZxyGT4MUmrPGj1cOHYZoGsNPHAvNkT6hnGeA,61
4
+ fastapi-0.118.1.dist-info/licenses/LICENSE,sha256=Tsif_IFIW5f-xYSy1KlhAy7v_oNEU4lP2cEnSQbMdE4,1086
5
+ fastapi/__init__.py,sha256=b1Y5tsac-lGeykg5dBEqr560dTxtO-XapvIgZVeg3_o,1081
6
6
  fastapi/__main__.py,sha256=bKePXLdO4SsVSM6r9SVoLickJDcR2c0cTOxZRKq26YQ,37
7
- fastapi/_compat.py,sha256=EQyNY-qrN3cjwI1r69JVAROc2lQCvi6W1we6_7jx_gc,24274
8
- fastapi/applications.py,sha256=Sr6fkAYFmuyIT4b0Rm33NQzO8oz4-DEc3PLTxp4LJgU,177570
7
+ fastapi/_compat.py,sha256=n1chC6BiNuBbXVnvOskZSo_8_VeZ2ESoyaG9gt48W_g,24944
8
+ fastapi/applications.py,sha256=nLbGcVdmCxXsl4aTSuP0WVS_XGY7wXBL3vC7nqlplmA,180276
9
9
  fastapi/background.py,sha256=rouLirxUANrcYC824MSMypXL_Qb2HYg2YZqaiEqbEKI,1768
10
10
  fastapi/cli.py,sha256=OYhZb0NR_deuT5ofyPF2NoNBzZDNOP8Salef2nk-HqA,418
11
11
  fastapi/concurrency.py,sha256=MirfowoSpkMQZ8j_g0ZxaQKpV6eB3G-dB5TgcXCrgEA,1424
@@ -18,6 +18,7 @@ fastapi/exception_handlers.py,sha256=YVcT8Zy021VYYeecgdyh5YEUjEIHKcLspbkSf4OfbJI
18
18
  fastapi/exceptions.py,sha256=taNixuFEXb67lI1bnX1ubq8y8TseJ4yoPlWjyP0fTzk,4969
19
19
  fastapi/logger.py,sha256=I9NNi3ov8AcqbsbC9wl1X-hdItKgYt2XTrx1f99Zpl4,54
20
20
  fastapi/middleware/__init__.py,sha256=oQDxiFVcc1fYJUOIFvphnK7pTT5kktmfL32QXpBFvvo,58
21
+ fastapi/middleware/asyncexitstack.py,sha256=RKGlQpGzg3GLosqVhrxBy_NCZ9qJS7zQeNHt5Y3x-00,637
21
22
  fastapi/middleware/cors.py,sha256=ynwjWQZoc_vbhzZ3_ZXceoaSrslHFHPdoM52rXr0WUU,79
22
23
  fastapi/middleware/gzip.py,sha256=xM5PcsH8QlAimZw4VDvcmTnqQamslThsfe3CVN2voa0,79
23
24
  fastapi/middleware/httpsredirect.py,sha256=rL8eXMnmLijwVkH7_400zHri1AekfeBd6D6qs8ix950,115
@@ -29,16 +30,16 @@ fastapi/openapi/docs.py,sha256=zSDv4xY6XHcKsaG4zyk1HqSnrZtfZFBB0J7ZBk5YHPE,10345
29
30
  fastapi/openapi/models.py,sha256=m1BNHxf_RiDTK1uCfMre6XZN5y7krZNA62QEP_2EV9s,15625
30
31
  fastapi/openapi/utils.py,sha256=ZI-nwdT2PtX8kaRPJylZo4LJHjYAcoVGxkd181P75x4,23997
31
32
  fastapi/param_functions.py,sha256=JHNPLIYvoAwdnZZavIVsxOat8x23fX_Kl33reh7HKl8,64019
32
- fastapi/params.py,sha256=g450axUBQgQJODdtM7WBxZbQj9Z64inFvadrgHikBbU,28237
33
+ fastapi/params.py,sha256=SnkGa4nNdmRek6oOELBHcSieRGjYvDPTla3EOl5Zlis,28413
33
34
  fastapi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
35
  fastapi/requests.py,sha256=zayepKFcienBllv3snmWI20Gk0oHNVLU4DDhqXBb4LU,142
35
36
  fastapi/responses.py,sha256=QNQQlwpKhQoIPZTTWkpc9d_QGeGZ_aVQPaDV3nQ8m7c,1761
36
- fastapi/routing.py,sha256=4zaZIdeq8VtsBLCxmmEgnfHqDD6USTc_l8BxUe1ye4M,176533
37
+ fastapi/routing.py,sha256=tK_d2K_0kP-rcbAmjjlR0mZMR170QkBITvwHWPq7eiQ,178409
37
38
  fastapi/security/__init__.py,sha256=bO8pNmxqVRXUjfl2mOKiVZLn0FpBQ61VUYVjmppnbJw,881
38
39
  fastapi/security/api_key.py,sha256=di-0gQ8MKugi2YfmlMoDHk-QMF_vnLGJRFOA6tcZ7fA,9016
39
40
  fastapi/security/base.py,sha256=dl4pvbC-RxjfbWgPtCWd8MVU-7CB2SZ22rJDXVCXO6c,141
40
41
  fastapi/security/http.py,sha256=rWR2x-5CUsjWmRucYthwRig6MG1o-boyrr4Xo-PuuxU,13606
41
- fastapi/security/oauth2.py,sha256=M1AFIDT7G3oQChq83poI3eg8ZDeibcvnGmya2CTS7JY,22036
42
+ fastapi/security/oauth2.py,sha256=rKHIUHq29367Qpe0Ez5Gcu1yIIM6SMw7nEfh15gBNIQ,22036
42
43
  fastapi/security/open_id_connect_url.py,sha256=8vizZ2tGqEp1ur8SwtVgyHJhGAJ5AqahgcvSpaIioDI,2722
43
44
  fastapi/security/utils.py,sha256=bd8T0YM7UQD5ATKucr1bNtAvz_Y3__dVNAv5UebiPvc,293
44
45
  fastapi/staticfiles.py,sha256=iirGIt3sdY2QZXd36ijs3Cj-T0FuGFda3cd90kM9Ikw,69
@@ -47,4 +48,4 @@ fastapi/testclient.py,sha256=nBvaAmX66YldReJNZXPOk1sfuo2Q6hs8bOvIaCep6LQ,66
47
48
  fastapi/types.py,sha256=nFb36sK3DSoqoyo7Miwy3meKK5UdFBgkAgLSzQlUVyI,383
48
49
  fastapi/utils.py,sha256=S59stPvKPUJ7MSkke3FaegSyig_4Uwhd32jnLiMF1jE,8032
49
50
  fastapi/websockets.py,sha256=419uncYObEKZG0YcrXscfQQYLSWoE10jqxVMetGdR98,222
50
- fastapi-0.117.1.dist-info/RECORD,,
51
+ fastapi-0.118.1.dist-info/RECORD,,