MCPcopy
hub / github.com/encode/starlette / MultiPartParser

Class MultiPartParser

starlette/formparsers.py:146–297  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

144
145
146class MultiPartParser:
147 spool_max_size = 1024 * 1024 # 1MB
148 """The maximum size of the spooled temporary file used to store file data."""
149 max_part_size = 1024 * 1024 # 1MB
150 """The maximum size of a part in the multipart request."""
151
152 def __init__(
153 self,
154 headers: Headers,
155 stream: AsyncGenerator[bytes, None],
156 *,
157 max_files: int | float = 1000,
158 max_fields: int | float = 1000,
159 max_part_size: int = 1024 * 1024, # 1MB
160 ) -> None:
161 assert multipart is not None, "The `python-multipart` library must be installed to use form parsing."
162 self.headers = headers
163 self.stream = stream
164 self.max_files = max_files
165 self.max_fields = max_fields
166 self.items: list[tuple[str, str | UploadFile]] = []
167 self._current_files = 0
168 self._current_fields = 0
169 self._current_partial_header_name: bytes = b""
170 self._current_partial_header_value: bytes = b""
171 self._current_part = MultipartPart()
172 self._charset = ""
173 self._file_parts_to_write: list[tuple[MultipartPart, bytes]] = []
174 self._file_parts_to_finish: list[MultipartPart] = []
175 self._files_to_close_on_error: list[SpooledTemporaryFile[bytes]] = []
176 self.max_part_size = max_part_size
177
178 def on_part_begin(self) -> None:
179 self._current_part = MultipartPart()
180
181 def on_part_data(self, data: bytes, start: int, end: int) -> None:
182 message_bytes = data[start:end]
183 if self._current_part.file is None:
184 if len(self._current_part.data) + len(message_bytes) > self.max_part_size:
185 raise MultiPartException(f"Part exceeded maximum size of {int(self.max_part_size / 1024)}KB.")
186 self._current_part.data.extend(message_bytes)
187 else:
188 self._file_parts_to_write.append((self._current_part, message_bytes))
189
190 def on_part_end(self) -> None:
191 if self._current_part.file is None:
192 self.items.append(
193 (
194 self._current_part.field_name,
195 _user_safe_decode(self._current_part.data, self._charset),
196 )
197 )
198 else:
199 self._file_parts_to_finish.append(self._current_part)
200 # The file can be added to the items right now even though it's not
201 # finished yet, because it will be finished in the `parse()` method, before
202 # self.items is used in the return value.
203 self.items.append((self._current_part.field_name, self._current_part.file))

Callers 1

_get_formMethod · 0.90

Calls

no outgoing calls

Tested by

no test coverage detected