Coverage for fastapi/datastructures.py: 100%
57 statements
« prev ^ index » next coverage.py v7.6.1, created at 2024-08-08 03:53 +0000
« prev ^ index » next coverage.py v7.6.1, created at 2024-08-08 03:53 +0000
1from typing import ( 1abcde
2 Any,
3 BinaryIO,
4 Callable,
5 Dict,
6 Iterable,
7 Optional,
8 Type,
9 TypeVar,
10 cast,
11)
13from fastapi._compat import ( 1abcde
14 PYDANTIC_V2,
15 CoreSchema,
16 GetJsonSchemaHandler,
17 JsonSchemaValue,
18 with_info_plain_validator_function,
19)
20from starlette.datastructures import URL as URL # noqa: F401 1abcde
21from starlette.datastructures import Address as Address # noqa: F401 1abcde
22from starlette.datastructures import FormData as FormData # noqa: F401 1abcde
23from starlette.datastructures import Headers as Headers # noqa: F401 1abcde
24from starlette.datastructures import QueryParams as QueryParams # noqa: F401 1abcde
25from starlette.datastructures import State as State # noqa: F401 1abcde
26from starlette.datastructures import UploadFile as StarletteUploadFile 1abcde
27from typing_extensions import Annotated, Doc 1abcde
30class UploadFile(StarletteUploadFile): 1abcde
31 """
32 A file uploaded in a request.
34 Define it as a *path operation function* (or dependency) parameter.
36 If you are using a regular `def` function, you can use the `upload_file.file`
37 attribute to access the raw standard Python file (blocking, not async), useful and
38 needed for non-async code.
40 Read more about it in the
41 [FastAPI docs for Request Files](https://fastapi.tiangolo.com/tutorial/request-files/).
43 ## Example
45 ```python
46 from typing import Annotated
48 from fastapi import FastAPI, File, UploadFile
50 app = FastAPI()
53 @app.post("/files/")
54 async def create_file(file: Annotated[bytes, File()]):
55 return {"file_size": len(file)}
58 @app.post("/uploadfile/")
59 async def create_upload_file(file: UploadFile):
60 return {"filename": file.filename}
61 ```
62 """
64 file: Annotated[ 1abcde
65 BinaryIO,
66 Doc("The standard Python file object (non-async)."),
67 ]
68 filename: Annotated[Optional[str], Doc("The original file name.")] 1abcde
69 size: Annotated[Optional[int], Doc("The size of the file in bytes.")] 1abcde
70 headers: Annotated[Headers, Doc("The headers of the request.")] 1abcde
71 content_type: Annotated[ 1abcde
72 Optional[str], Doc("The content type of the request, from the headers.")
73 ]
75 async def write( 1abcde
76 self,
77 data: Annotated[
78 bytes,
79 Doc(
80 """
81 The bytes to write to the file.
82 """
83 ),
84 ],
85 ) -> None:
86 """
87 Write some bytes to the file.
89 You normally wouldn't use this from a file you read in a request.
91 To be awaitable, compatible with async, this is run in threadpool.
92 """
93 return await super().write(data) 1abcde
95 async def read( 1abcde
96 self,
97 size: Annotated[
98 int,
99 Doc(
100 """
101 The number of bytes to read from the file.
102 """
103 ),
104 ] = -1,
105 ) -> bytes:
106 """
107 Read some bytes from the file.
109 To be awaitable, compatible with async, this is run in threadpool.
110 """
111 return await super().read(size) 1abcde
113 async def seek( 1abcde
114 self,
115 offset: Annotated[
116 int,
117 Doc(
118 """
119 The position in bytes to seek to in the file.
120 """
121 ),
122 ],
123 ) -> None:
124 """
125 Move to a position in the file.
127 Any next read or write will be done from that position.
129 To be awaitable, compatible with async, this is run in threadpool.
130 """
131 return await super().seek(offset) 1abcde
133 async def close(self) -> None: 1abcde
134 """
135 Close the file.
137 To be awaitable, compatible with async, this is run in threadpool.
138 """
139 return await super().close() 1abcde
141 @classmethod 1abcde
142 def __get_validators__(cls: Type["UploadFile"]) -> Iterable[Callable[..., Any]]: 1abcde
143 yield cls.validate 1abcde
145 @classmethod 1abcde
146 def validate(cls: Type["UploadFile"], v: Any) -> Any: 1abcde
147 if not isinstance(v, StarletteUploadFile): 1abcde
148 raise ValueError(f"Expected UploadFile, received: {type(v)}") 1abcde
149 return v 1abcde
151 @classmethod 1abcde
152 def _validate(cls, __input_value: Any, _: Any) -> "UploadFile": 1abcde
153 if not isinstance(__input_value, StarletteUploadFile): 1abcde
154 raise ValueError(f"Expected UploadFile, received: {type(__input_value)}") 1abcde
155 return cast(UploadFile, __input_value) 1abcde
157 if not PYDANTIC_V2: 1abcde
159 @classmethod 1abcde
160 def __modify_schema__(cls, field_schema: Dict[str, Any]) -> None: 1abcde
161 field_schema.update({"type": "string", "format": "binary"}) 1abcde
163 @classmethod 1abcde
164 def __get_pydantic_json_schema__( 1abcde
165 cls, core_schema: CoreSchema, handler: GetJsonSchemaHandler
166 ) -> JsonSchemaValue:
167 return {"type": "string", "format": "binary"} 1abcde
169 @classmethod 1abcde
170 def __get_pydantic_core_schema__( 1abcde
171 cls, source: Type[Any], handler: Callable[[Any], CoreSchema]
172 ) -> CoreSchema:
173 return with_info_plain_validator_function(cls._validate) 1abcde
176class DefaultPlaceholder: 1abcde
177 """
178 You shouldn't use this class directly.
180 It's used internally to recognize when a default value has been overwritten, even
181 if the overridden default value was truthy.
182 """
184 def __init__(self, value: Any): 1abcde
185 self.value = value 1abcde
187 def __bool__(self) -> bool: 1abcde
188 return bool(self.value) 1abcde
190 def __eq__(self, o: object) -> bool: 1abcde
191 return isinstance(o, DefaultPlaceholder) and o.value == self.value 1abcde
194DefaultType = TypeVar("DefaultType") 1abcde
197def Default(value: DefaultType) -> DefaultType: 1abcde
198 """
199 You shouldn't use this function directly.
201 It's used internally to recognize when a default value has been overwritten, even
202 if the overridden default value was truthy.
203 """
204 return DefaultPlaceholder(value) # type: ignore 1abcde