async def register(request): """ Registers a new redirect with the server. """ if not is_authorized(request): raise ex.HTTPUnauthorized() data = await request.json(loads=quiet_json) ttl = int(data.get('ttl', 3600)) token = random_token() try: method = data['method'].upper() if method not in ('GET', 'POST', 'PUT'): raise ex.HTTPBadRequest( reason="Unsupported HTTP method {}".format(method)) request.app.db[token] = { 'url': data['url'], 'expiration': datetime.utcnow() + timedelta(seconds=ttl), 'secret': data['secret'], 'method': method, 'success_url': data['success_url'], 'error_url': data['error_url'] } except KeyError as e: raise ex.HTTPBadRequest(reason="Missing key: {}".format(e.args[0])) return web.json_response({'token': token})
def __paginate(self, request): qs = parse_qs(request.query_string) offsets = qs.get('offset', [0]) if len(offsets) > 1: raise web_exceptions.HTTPBadRequest(text='Invalid offset value') limits = qs.get('limit', [20]) if len(limits) > 1: raise web_exceptions.HTTPBadRequest(text='Invalid limit value') return int(offsets[0]), int(limits[0])
async def get_file_bytes(request: web.Request): """ Gets the file identified by the sha256sum. The client can decide the number of file to get using the "bytes" query param. """ id = request.match_info['id'] try: # all the following should probably go to another function with get_file(id) as (io, file_size, filename): # do we limit to N-nth byte or to the whole file? max_byte = request.query.get('max_byte', None) if max_byte: try: max_byte = int(max_byte) except ValueError: raise web_exceptions.HTTPBadRequest( text=f'max_byte must be an integer "{max_byte}" found') if max_byte <= 0: raise web_exceptions.HTTPBadRequest( text=f'max_byte must be positive "{max_byte}" found') else: max_byte = file_size # We use a streaming response here response = web.StreamResponse( headers={ 'Content-Length': str(max_byte), 'Content-Disposition': f'attachment;filename="{filename}"' }) await response.prepare(request) # stream with 16 Kib chunks chunk_size = (2**3)**4 # Iterate through the file until we hit 0. while max_byte > 0: chunk_size = min(max_byte, chunk_size) text = io.read(chunk_size) await response.write(text) max_byte -= chunk_size # ok we write the eof at the end of the cycle await response.write_eof(b'') except FileNotFoundError: raise web_exceptions.HTTPNotFound(text=f"Resource {id} not found.") return response
async def proxy_request(request: web.Request): """ Before python3.7: For non ascii domains served under https, SSL handshake does not work properly. :param request: :return: """ user_agent = 'Small Python Proxy' # we use the user agent to avoid the service proxing itself if request.headers.get('User-Agent') == user_agent: raise web_exceptions.HTTPNotImplemented( text=f'Proxy is not implemented for User-Agent: "{user_agent}".') if not request.query_string.startswith('url='): raise web_exceptions.HTTPBadRequest( text='Missing querystring parameter `url`') else: # trim off the first 4 characters [url=] from the querystring url = request.query_string[4:] content_type, text = await request_page(url, user_agent) response = web.Response(content_type=content_type, text=text) return response
async def add_client(self, request): """ --- description: Запрос для добавления нового клиента tags: - Clients produces: - application/json - application/xml parameters: - name: card in: body description: данные нового клиента required: true schema: type: object properties: name: type: string description: имя клиента responses: "200": description: успех. Возвращает данные нового клиента "406": description: ошибка клиента. Указан неверный Accept """ encoder = self.__choose_encoder(request) data = await self.__decode_post(request) try: client = await self.__client_model.add_client(data) return web.HTTPCreated(content_type=encoder.content_type, body=encoder.encode(client)) except MultipleInvalid as e: raise web_exceptions.HTTPBadRequest(text=str(e))
async def __decode_post(self, request): if request.content_type == "application/json": return await request.json() if request.content_type == "application/xml": return {"data": "xml"} raise web_exceptions.HTTPBadRequest( text="Unknown Content-Type header. Only application/json, application/xml are allowed." )
async def change_card(self, request): """ --- description: Запрос для изменение данных по карте tags: - Cards produces: - application/json - application/xml parameters: - name: id in: path description: идентификатор карты required: true type: integer - name: card in: body description: данные карты required: true schema: type: object properties: owner_id: type: integer description: идентификатор владельца карты payment_system: type: string description: платежная система currency: type: string description: валюта карты balance: type: float description: баланс карты responses: "200": description: успех. Возвращает измененные данные карты "400": description: ошибка клиента. Указаны неверные данные карты "404": description: ошибка. Карта не найдена "406": description: ошибка клиента. Указан неверный Accept """ card_id = int(request.match_info.get('id')) encoder = self.__choose_encoder(request) data = await self.__decode_post(request) try: card = await self.__client_model.change_card(card_id, data) return web.Response(content_type=encoder.content_type, body=encoder.encode(card)) except MultipleInvalid as e: raise web_exceptions.HTTPBadRequest(text=str(e))
async def add_card(self, request): """ --- description: Запрос для добавления новой карты клиента tags: - Cards produces: - application/json - application/xml parameters: - name: card in: body description: данные новой карты required: true schema: type: object properties: owner_id: type: integer description: идентификатор владельца карты required: true payment_system: type: string description: платежная система required: true currency: type: string description: валюта карты required: true balance: type: numeric description: баланс карты required: true responses: "200": description: успех. Возвращает данные новой карты клиента "404": description: ошибка. Клиент не найден "406": description: ошибка клиента. Указан неверный Accept """ encoder = self.__choose_encoder(request) data = await self.__decode_post(request) try: card = await self.__client_model.add_card(data) return web.HTTPCreated(content_type=encoder.content_type, body=encoder.encode(card)) except MultipleInvalid as e: raise web_exceptions.HTTPBadRequest(text=str(e)) except ItemNotFoundException as e: raise web_exceptions.HTTPNotFound(text=str(e))