def _get_requested_range(request: Request) -> Optional[Range]: # http://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7233.html#rfc.section.3.1 # A server must ignore a Range header field received with a request method # other than GET if request.method != "GET": return None # NB: only the first Range request header is taken into consideration; # if the HTTP contains several Range headers, only the first is used range_header = request.get_first_header(b"range") if not range_header: return None try: value = Range.parse(range_header) except InvalidRangeValue: raise BadRequest("Invalid Range header") else: # An origin server must ignore a Range header field that contains # a range unit it does not understand. if value.unit != "bytes": return None return value
async def example_2(): # example: use an exception to control the execution flow, # the error handler defined in app.exceptions_handlers will produce the # response object # the response object must be populated with CORS headers, otherwise the # client won't expose the error details - for example we might send a JSON # structure with error information raise BadRequest("Some user friendly client error detail")
def converter(data): try: return expected_type(**data) except TypeError as type_error: raise BadRequest( f"invalid parameter in request payload, " + f"caused by type {_try_get_type_name(expected_type)} or " + "one of its subproperties. Error: " + _generalize_init_type_error_message(type_error))
def _default_bool_converter(value: str) -> bool: if value in {"1", "true"}: return True if value in {"0", "false"}: return False # bad request: expected a bool value, but # got something different that is not handled raise BadRequest(f"Expected a bool value for a parameter, but got {value}.")
def _default_bool_converter(value: str): if value in {'1', 'true'}: return True if value in {'0', 'false'}: return False # bad request: expected a bool value, but # got something different that is not handled raise BadRequest()
def parse_value(value, desired_type: type, param_name: str): try: if desired_type is bool: return bool(int(value)) if desired_type in {int, float}: return desired_type(value) return value except ValueError: raise BadRequest( f'invalid parameter "{param_name}". ' f'The value cannot be parsed as {desired_type.__name__}.')
def __call__(self, request): value = get_param(request, self.name) if value is None or value == '': if self.is_optional: return None raise BadRequest(f'missing parameter: {self.name}.') if self.annotation is str: return unwrap(value) return value
async def file_chunker() -> AsyncIterable[bytes]: async with files_handler.open(file_path) as file: for part in range_option: if part.start is None and part.end is None: raise BadRequest("Invalid range part: both boundaries are None") if part.start is not None and part.end is not None: # return a portion between start and end indexes await file.seek(part.start, 0) part_size = part.end - part.start elif part.end is None: assert part.start is not None # return all bytes to the end, starting from start index await file.seek(part.start) part_size = file_size - part.start elif part.start is None: # return a number of units at the end of the file await file.seek(file_size - part.end) part_size = part.end bytes_to_return = part_size while True: chunk_limit = ( size_limit if bytes_to_return > size_limit else bytes_to_return ) chunk = await file.read(chunk_limit) if not chunk: break bytes_to_return -= len(chunk) if boundary: yield b"--" + boundary + b"\r\n" yield b"Content-Type: " + file_type + b"\r\n" yield b"Content-Range: " + _get_content_range_value( part, file_size ) + b"\r\n\r\n" yield chunk if boundary: yield b"\r\n" if boundary: yield b"--" + boundary + b"--\r\n" yield b""
async def get_value(self, request: Request) -> T: raw_value = self.get_raw_value(request) try: value = self.converter(raw_value) except (ValueError, BadRequest): raise BadRequest( f'Invalid value for parameter `{self.name}`; expected {self.expected_type}' ) if value is None and self.required: raise MissingParameterError(self.name, self.source_name) if not self.required and self._empty_iterable(value): return None return value
async def get_value(self, request: Request) -> Optional[T]: # TODO: support get_raw_value returning None, to not instantiate lists # when a parameter is not present raw_value = self.get_raw_value(request) try: value = self.converter(raw_value) except (ValueError, BadRequest): raise BadRequest( f"Invalid value {raw_value} for parameter `{self.parameter_name}`; " f"expected a valid {self.expected_type.__name__}." ) if self.default is not empty and (value is None or self._empty_iterable(value)): return None if value is None and self.required and self.root_required: raise MissingParameterError(self.parameter_name, self.source_name) if not self.required and self._empty_iterable(value): return None return value