def binance(args: tuple[str, URL], kwargs: dict[str, Any]) -> tuple[str, URL]: method: str = args[0] url: URL = args[1] data: dict[str, Any] = kwargs["data"] or {} headers: CIMultiDict = kwargs["headers"] session: aiohttp.ClientSession = kwargs["session"] key: str = session.__dict__["_apis"][Hosts.items[url.host].name][0] secret: bytes = session.__dict__["_apis"][Hosts.items[url.host].name][1] expires = str(int(time.time() * 1000)) if method == METH_GET: if url.scheme == "https": query = MultiDict(url.query) query.extend({"timestamp": expires}) query_string = "&".join(f"{k}={v}" for k, v in query.items()) signature = hmac.new( secret, query_string.encode(), hashlib.sha256 ).hexdigest() query.extend({"signature": signature}) url = url.with_query(query) args = ( method, url, ) else: data.update({"timestamp": expires}) body = FormData(data)() signature = hmac.new(secret, body._value, hashlib.sha256).hexdigest() body._value += f"&signature={signature}".encode() body._size = len(body._value) kwargs.update({"data": body}) headers.update({"X-MBX-APIKEY": key}) return args
async def fetch_content(url, session): async with aiofiles.open("input.docx", mode='rb') as file: data = FormData() data.add_field('file', file, filename='_.docx') async with session.post(url, data=data) as response: data = await response.read() await write_image(data)
async def call(self, method, **params): """ Call an Slack Web API method :param method: Slack Web API method to call :param params: {str: object} parameters to method :return: dict() """ url = self.SLACK_RPC_PREFIX + method data = FormData() data.add_fields(MultiDict(token=self.bot_token, charset='utf-8', **params)) response_body = await self.request( method='POST', url=url, data=data ) if 'warning' in response_body: logger.warning(f'Warnings received from API call {method}: {response_body["warning"]}') if 'ok' not in response_body: logger.error(f'No ok marker in slack API call {method} {params} => {response_body}') raise SlackCallException('There is no ok marker, ... strange', method=method) if not response_body['ok']: logger.error(f'Slack API call failed {method} {params} => {response_body}') raise SlackCallException(f'No OK response returned', method=method) return response_body
def function398(function1105, function604): var3042 = FormData(quote_fields=False, charset='ascii') var3042.add_field('emails[]', '*****@*****.**', content_type='multipart/form-data') var4723 = var3042() yield from var4723.function2007(function604) assert (b'name="emails[]"' in function1105)
def function1429(function1105, function604): var4060 = FormData(charset='ascii') var4060.add_field('emails[]', '*****@*****.**', content_type='multipart/form-data') var3464 = var4060() yield from var3464.function2007(function604) assert (b'name="emails%5B%5D"' in function1105)
def test_invalid_formdata_content_transfer_encoding() -> None: form = FormData() invalid_vals = [0, 0.1, {}, [], b'foo'] for invalid_val in invalid_vals: with pytest.raises(TypeError): form.add_field('foo', 'bar', content_transfer_encoding=invalid_val)
async def process_partition( loop: asyncio.BaseEventLoop, results_queue: asyncio.Queue, server_address: URL, http: aiohttp.ClientSession, partition: PointsPartition, mission_template: Template, mission_loader: str, mission_name: str, width: int, scale: int, ) -> Awaitable[None]: LOG.debug( f"query range [{partition.start}:{partition.end}] on server " f"{server_address}" ) file_name = f"{mission_name}_{partition.start}_{partition.end}.mis" missions_url = server_address / "missions" mission_dir_url = missions_url / "heightmap" mission_url = mission_dir_url / file_name points = ( index_to_point(i, width, scale) for i in range(partition.start, partition.end + 1) ) mission = mission_template.render( loader=mission_loader, points=points, ) data = FormData() data.add_field( 'mission', mission.encode(), filename=file_name, content_type='plain/text', ) await http.post(mission_dir_url, data=data) await http.post(mission_url / "load") await http.post(missions_url / "current" / "begin") async with http.get(server_address / "radar" / "stationary-objects") as response: data = await response.json() data = [ pack(HEIGHT_PACK_FORMAT, int(point['pos']['z'])) for point in data ] data = b''.join(data) await http.post(missions_url / "current" / "unload") await http.delete(mission_url) await results_queue.put((partition, data))
def gmocoin(args: tuple[str, URL], kwargs: dict[str, Any]) -> tuple[str, URL]: method: str = args[0] url: URL = args[1] data: dict[str, Any] = kwargs["data"] or {} headers: CIMultiDict = kwargs["headers"] session: aiohttp.ClientSession = kwargs["session"] key: str = session.__dict__["_apis"][Hosts.items[url.host].name][0] secret: bytes = session.__dict__["_apis"][Hosts.items[url.host].name][1] path = "/" + "/".join(url.parts[2:]) body = JsonPayload(data) if data else FormData(data)() timestamp = str(int(time.time() * 1000)) # PUT and DELETE requests do not require payload inclusion if method == "POST": text = f"{timestamp}{method}{path}".encode() + body._value else: text = f"{timestamp}{method}{path}".encode() signature = hmac.new(secret, text, hashlib.sha256).hexdigest() kwargs.update({"data": body}) headers.update( {"API-KEY": key, "API-TIMESTAMP": timestamp, "API-SIGN": signature} ) return args
def liquid(args: tuple[str, URL], kwargs: dict[str, Any]) -> tuple[str, URL]: url: URL = args[1] data: dict[str, Any] = kwargs["data"] or {} headers: CIMultiDict = kwargs["headers"] session: aiohttp.ClientSession = kwargs["session"] key: str = session.__dict__["_apis"][Hosts.items[url.host].name][0] secret: bytes = session.__dict__["_apis"][Hosts.items[url.host].name][1] json_payload = json.dumps( { "path": url.raw_path_qs, "nonce": str(int(time.time() * 1000)), "token_id": key, }, separators=(",", ":"), ).encode() json_header = json.dumps( {"typ": "JWT", "alg": "HS256"}, separators=(",", ":"), ).encode() segments = [ base64.urlsafe_b64encode(json_header).replace(b"=", b""), base64.urlsafe_b64encode(json_payload).replace(b"=", b""), ] signing_input = b".".join(segments) signature = hmac.new(secret, signing_input, hashlib.sha256).digest() segments.append(base64.urlsafe_b64encode(signature).replace(b"=", b"")) encoded_string = b".".join(segments).decode() body = JsonPayload(data) if data else FormData(data)() kwargs.update({"data": body}) headers.update({"X-Quoine-API-Version": "2", "X-Quoine-Auth": encoded_string}) return args
def phemex(args: tuple[str, URL], kwargs: dict[str, Any]) -> tuple[str, URL]: url: URL = args[1] data: dict[str, Any] = kwargs["data"] or {} headers: CIMultiDict = kwargs["headers"] session: aiohttp.ClientSession = kwargs["session"] key: str = session.__dict__["_apis"][Hosts.items[url.host].name][0] secret: bytes = session.__dict__["_apis"][Hosts.items[url.host].name][1] path = url.raw_path query = url.query_string body = JsonPayload(data) if data else FormData(data)() expiry = str(int((time.time() + 60.0))) formula = f"{path}{query}{expiry}".encode() + body._value signature = hmac.new(secret, formula, hashlib.sha256).hexdigest() kwargs.update({"data": body}) headers.update( { "x-phemex-access-token": key, "x-phemex-request-expiry": expiry, "x-phemex-request-signature": signature, } ) return args
def okx(args: tuple[str, URL], kwargs: dict[str, Any]) -> tuple[str, URL]: method: str = args[0] url: URL = args[1] data: dict[str, Any] = kwargs["data"] or {} headers: CIMultiDict = kwargs["headers"] session: aiohttp.ClientSession = kwargs["session"] api_name = NameSelector.okx(headers) key: str = session.__dict__["_apis"][api_name][0] secret: bytes = session.__dict__["_apis"][api_name][1] passphrase: str = session.__dict__["_apis"][api_name][2] timestamp = f'{datetime.datetime.utcnow().isoformat(timespec="milliseconds")}Z' body = JsonPayload(data) if data else FormData(data)() text = f"{timestamp}{method}{url.raw_path_qs}".encode() + body._value sign = base64.b64encode( hmac.new(secret, text, hashlib.sha256).digest() ).decode() kwargs.update({"data": body}) headers.update( { "OK-ACCESS-KEY": key, "OK-ACCESS-SIGN": sign, "OK-ACCESS-TIMESTAMP": timestamp, "OK-ACCESS-PASSPHRASE": passphrase, "Content-Type": "application/json", } ) return args
def bitget(args: tuple[str, URL], kwargs: dict[str, Any]) -> tuple[str, URL]: method: str = args[0] url: URL = args[1] data: dict[str, Any] = kwargs["data"] or {} headers: CIMultiDict = kwargs["headers"] session: aiohttp.ClientSession = kwargs["session"] key: str = session.__dict__["_apis"][Hosts.items[url.host].name][0] secret: bytes = session.__dict__["_apis"][Hosts.items[url.host].name][1] passphase: str = session.__dict__["_apis"][Hosts.items[url.host].name][2] path = url.raw_path_qs body = JsonPayload(data) if data else FormData(data)() timestamp = str(int(time.time() * 1000)) msg = f"{timestamp}{method}{path}".encode() + body._value sign = base64.b64encode( hmac.new(secret, msg, digestmod=hashlib.sha256).digest() ).decode() kwargs.update({"data": body}) headers.update( { "Content-Type": "application/json", "ACCESS-KEY": key, "ACCESS-SIGN": sign, "ACCESS-TIMESTAMP": timestamp, "ACCESS-PASSPHRASE": passphase, } ) return args
def mexc_v2(args: tuple[str, URL], kwargs: dict[str, Any]) -> tuple[str, URL]: method: str = args[0] url: URL = args[1] data: dict[str, Any] = kwargs["data"] or {} headers: CIMultiDict = kwargs["headers"] session: aiohttp.ClientSession = kwargs["session"] key: str = session.__dict__["_apis"][Hosts.items[url.host].name][0] secret: bytes = session.__dict__["_apis"][Hosts.items[url.host].name][1] timestamp = str(int(time.time() * 1000)) if method in (METH_GET, METH_DELETE) and url.scheme == "https": parameter = url.raw_query_string.encode() else: body = JsonPayload(data) if data else FormData(data)() parameter = body._value kwargs.update({"data": body}) signature = hmac.new( secret, f"{key}{timestamp}".encode() + parameter, hashlib.sha256 ).hexdigest() headers.update( { "ApiKey": key, "Request-Time": timestamp, "Signature": signature, "Content-Type": "application/json", } ) return args
def btcmex(args: Tuple[str, URL], kwargs: Dict[str, Any]) -> Tuple[str, URL]: method: str = args[0] url: URL = args[1] data: Dict[str, Any] = kwargs['data'] or {} headers: CIMultiDict = kwargs['headers'] session: aiohttp.ClientSession = kwargs['session'] key: str = session.__dict__['_apis'][Hosts.items[url.host].name][0] secret: bytes = session.__dict__['_apis'][Hosts.items[ url.host].name][1] path = url.raw_path_qs if url.scheme == 'https' else '/api/v1/signature' body = FormData(data)() expires = str(int(time.time() + 5.0)) message = f'{method}{path}{expires}'.encode() + body._value signature = hmac.new(secret, message, hashlib.sha256).hexdigest() kwargs.update({'data': body}) headers.update({ 'api-expires': expires, 'api-key': key, 'api-signature': signature }) return args
async def upload_file( self, user_id: int, file_content: bytes, file_meta: dict, as_voice: bool, thumbnail: bytes = None, ) -> dict: """ Публичный метод загрузки файла на сервера Telegram. Thumbnail: Шлется только байтами, только если аудиофайл так же шлется байтами, только для метода sendAudio. """ path: str params: dict = { 'chat_id': str(user_id), 'duration': int(file_meta.get('duration', 0)) } # TODO: кажется на самом деле свыше около 20 МБ телеграм уже не принимает. if len(file_content) >= SIZE_50MB: raise FileError( f'Uploading file size limit exceeded. Size: {len(file_content)}, limit: {SIZE_50MB}', { 'size': len(file_content), 'limit': SIZE_50MB }) suffix: str = self.audio_suffix_mimetype_map[file_meta['mime_type']] performer: str = file_meta.get('performer', '') title: str = file_meta.get('title', '') file_unique_id: str = file_meta.get('file_unique_id', '') if title and performer: filename: str = f'{performer}-{title}' else: filename = f'{file_unique_id}' form_data: FormData = FormData(quote_fields=False) if as_voice: path = 'sendVoice' form_data.add_field('voice', file_content, filename=f"{filename}.ogg", content_type='audio/ogg') if thumbnail: log.error('Thumbnails allowed for sendAudio only.') else: path = 'sendAudio' params.update({'performer': performer, 'title': title}) form_data.add_field('audio', file_content, filename=f"{filename}{suffix}", content_type=file_meta['mime_type']) if thumbnail: form_data.add_field('thumb', thumbnail, filename=f"thumb.jpeg", content_type='image/jpeg') return await self._request(path, params=params, form_data=form_data)
async def post(): async with aiohttp.ClientSession() as session: # 表单模式(转码) payload = {'key1': 'value1', 'key2': 'value2'} # 表单模式(不转码) payload = json.dumps(payload) # 上传小文件 # files = {'file': open('test.py', 'rb')} # 设置文件名称 data = FormData() data.add_field('file', open('test.py', 'rb'), filename='test.py', content_type='application/vnd.ms-excel') async with session.post('http://httpbin.org/post', data=data) as resp: print(resp.status) print(await resp.text()) print(resp.url)
def bybit(args: Tuple[str, URL], kwargs: Dict[str, Any]) -> Tuple[str, URL]: method: str = args[0] url: URL = args[1] data: Dict[str, Any] = kwargs['data'] or {} session: aiohttp.ClientSession = kwargs['session'] key: str = session.__dict__['_apis'][Hosts.items[url.host].name][0] secret: bytes = session.__dict__['_apis'][Hosts.items[ url.host].name][1] expires = str(int((time.time() + 1.0) * 1000)) if method == METH_GET: query = MultiDict(url.query) if url.scheme == 'https': query.extend({'api_key': key, 'timestamp': expires}) query_string = '&'.join(f'{k}={v}' for k, v in sorted(query.items())) sign = hmac.new(secret, query_string.encode(), hashlib.sha256).hexdigest() query.extend({'sign': sign}) else: path = f'{method}/realtime{expires}' signature = hmac.new(secret, path.encode(), hashlib.sha256).hexdigest() query.extend({ 'api_key': key, 'expires': expires, 'signature': signature }) url = url.with_query(query) args = ( method, url, ) else: data.update({'api_key': key, 'timestamp': expires}) body = FormData(sorted(data.items()))() sign = hmac.new(secret, body._value, hashlib.sha256).hexdigest() body._value += f'&sign={sign}'.encode() body._size = len(body._value) kwargs.update({'data': body}) return args
def bybit(args: tuple[str, URL], kwargs: dict[str, Any]) -> tuple[str, URL]: method: str = args[0] url: URL = args[1] data: dict[str, Any] = kwargs["data"] or {} session: aiohttp.ClientSession = kwargs["session"] key: str = session.__dict__["_apis"][Hosts.items[url.host].name][0] secret: bytes = session.__dict__["_apis"][Hosts.items[url.host].name][1] if url.scheme == "https": expires = str(int((time.time() - 5.0) * 1000)) recv_window = ( "recv_window" if not url.path.startswith("/spot") else "recvWindow" ) auth_params = {"api_key": key, "timestamp": expires, recv_window: 10000} if method in (METH_GET, METH_DELETE): query = MultiDict(url.query) query.extend(auth_params) query_string = "&".join(f"{k}={v}" for k, v in sorted(query.items())) sign = hmac.new( secret, query_string.encode(), hashlib.sha256 ).hexdigest() query.extend({"sign": sign}) url = url.with_query(query) args = (method, url) else: data.update(auth_params) body = FormData(sorted(data.items()))() sign = hmac.new(secret, body._value, hashlib.sha256).hexdigest() body._value += f"&sign={sign}".encode() body._size = len(body._value) kwargs.update({"data": body}) elif url.scheme == "wss": query = MultiDict(url.query) expires = str(int((time.time() + 5.0) * 1000)) path = f"{method}/realtime{expires}" signature = hmac.new(secret, path.encode(), hashlib.sha256).hexdigest() query.extend({"api_key": key, "expires": expires, "signature": signature}) url = url.with_query(query) args = (method, url) return args
def binance(args: Tuple[str, URL], kwargs: Dict[str, Any]) -> Tuple[str, URL]: method: str = args[0] url: URL = args[1] data: Dict[str, Any] = kwargs['data'] or {} headers: CIMultiDict = kwargs['headers'] session: aiohttp.ClientSession = kwargs['session'] key: str = session.__dict__['_apis'][Hosts.items[url.host].name][0] secret: bytes = session.__dict__['_apis'][Hosts.items[ url.host].name][1] expires = str(int(time.time() * 1000)) if method == METH_GET: if url.scheme == 'https': query = MultiDict(url.query) query.extend({'timestamp': expires}) query_string = '&'.join(f'{k}={v}' for k, v in query.items()) signature = hmac.new(secret, query_string.encode(), hashlib.sha256).hexdigest() query.extend({'signature': signature}) url = url.with_query(query) args = ( method, url, ) else: data.update({'timestamp': expires}) body = FormData(data)() signature = hmac.new(secret, body._value, hashlib.sha256).hexdigest() body._value += f'&signature={signature}'.encode() body._size = len(body._value) kwargs.update({'data': body}) headers.update({'X-MBX-APIKEY': key}) return args
async def upload_roundy(self, user_id: int, video: bytes, duration: int, radius: int): params: dict = { 'chat_id': str(user_id), 'duration': duration, 'length': radius } form_data: FormData = FormData(quote_fields=False) filename: str = 'roundy' form_data.add_field('video_note', video, filename=f"{filename}.mp4", content_type='video/mp4') return await self._request('sendVideoNote', params=params, form_data=form_data)
async def request(self, method, url, data=None, headers=None, files=None, timeout=5, timeout_retry=3, decode_json=True, return_binary=False, **kwargs): for _ in range(timeout_retry): try: post_data = data if files is None: if isinstance(data, dict) or isinstance(data, list): post_data = json.dumps(data, ensure_ascii=False) else: post_data = FormData() if data: for k, v in data.items(): post_data.add_field(k, v) file_args, fileobs = convert_file_args(files) for name, (filename, fileobj, mimetype) in file_args.items(): post_data.add_field(name, fileobj, content_type=mimetype, filename=filename) func = getattr(self.session, method) async with func(url, data=post_data, headers=headers, timeout=ClientTimeout(timeout), **kwargs) as resp: if resp.status != 200: self.logger.error( "[%s] url[%s], data[%s] headers[%s] kwargs[%s] failed,"\ " code[%d], resp[%s]", method, url, post_data, headers, kwargs, resp.status, resp) return None if return_binary: result = await resp.content.read() else: result = await resp.text(encoding='UTF-8') if decode_json: result = json.loads(result) return result except asyncio.TimeoutError: self.logger.warning( "[%s] url[%s], data[%s] headers[%s] kwargs[%s] timeout", method, url, data, headers, kwargs) else: self.logger.error("[%s] url[%s], timeout after retry [%d] times", method, url, timeout_retry)
async def http(session, domain, *args, **kwargs): """ TODO 补充一下参数和返回值格式说明 http请求处理器 :param session: ClientSession对象 :param domain: 服务地址 :param args: :param kwargs: :return: """ method, api = args arguments = kwargs.get('data') or kwargs.get('params') or kwargs.get( 'json') or {} # kwargs中加入token # TODO 实现getheader 通用方法 # 已经实现了 # kwargs.setdefault('headers', {}).update({'token': bxmat.token}) contentType = kwargs.setdefault('headers', {}).setdefault('Content-Type', '') #TODO 补充文件上传的处理 if contentType.startswith('multipart/'): formData = FormData() data = kwargs.get('data') or {} if isinstance(data, dict): for k, v in data.items(): if os.path.isfile(v): formData.add_field(k, await aiofiles.open(v, 'rb'), filename=os.path.basename(v)) # content_type=contentType) else: formData.add_field(k, str(v)) # print('111') pass kwargs['data'] = formData # 拼接服务地址和api url = ''.join([domain, api]) # print(kwargs['data'].__dict__) # print() # async with ClientSession() as session: # async with session.request(method, url, **kwargs) as response: # res = await response_handler(response) # return { # 'response': res, # 'url': url, # 'arguments': arguments # } # async with ClientSession() as session: async with session.request(method, url, **kwargs) as response: res = await response_handler(response) return {'response': res, 'url': url, 'arguments': arguments}
def coincheck(args: tuple[str, URL], kwargs: dict[str, Any]) -> tuple[str, URL]: url: URL = args[1] data: dict[str, Any] = kwargs["data"] or {} headers: CIMultiDict = kwargs["headers"] session: aiohttp.ClientSession = kwargs["session"] key: str = session.__dict__["_apis"][Hosts.items[url.host].name][0] secret: bytes = session.__dict__["_apis"][Hosts.items[url.host].name][1] nonce = str(int(time.time() * 1000)) body = FormData(data)() message = f"{nonce}{url}".encode() + body._value signature = hmac.new(secret, message, hashlib.sha256).hexdigest() kwargs.update({"data": body}) headers.update( {"ACCESS-KEY": key, "ACCESS-NONCE": nonce, "ACCESS-SIGNATURE": signature} ) return args
def ftx(args: tuple[str, URL], kwargs: dict[str, Any]) -> tuple[str, URL]: method: str = args[0] url: URL = args[1] data: dict[str, Any] = kwargs["data"] or {} headers: CIMultiDict = kwargs["headers"] session: aiohttp.ClientSession = kwargs["session"] key: str = session.__dict__["_apis"][Hosts.items[url.host].name][0] secret: bytes = session.__dict__["_apis"][Hosts.items[url.host].name][1] path = url.raw_path_qs body = JsonPayload(data) if data else FormData(data)() ts = str(int(time.time() * 1000)) text = f"{ts}{method}{path}".encode() + body._value signature = hmac.new(secret, text, hashlib.sha256).hexdigest() kwargs.update({"data": body}) headers.update({"FTX-KEY": key, "FTX-SIGN": signature, "FTX-TS": ts}) return args
def bitmex(args: tuple[str, URL], kwargs: dict[str, Any]) -> tuple[str, URL]: method: str = args[0] url: URL = args[1] data: dict[str, Any] = kwargs["data"] or {} headers: CIMultiDict = kwargs["headers"] session: aiohttp.ClientSession = kwargs["session"] key: str = session.__dict__["_apis"][Hosts.items[url.host].name][0] secret: bytes = session.__dict__["_apis"][Hosts.items[url.host].name][1] path = url.raw_path_qs if url.scheme == "https" else "/realtime" body = FormData(data)() expires = str(int((time.time() + 5.0) * 1000)) message = f"{method}{path}{expires}".encode() + body._value signature = hmac.new(secret, message, hashlib.sha256).hexdigest() kwargs.update({"data": body}) headers.update( {"api-expires": expires, "api-key": key, "api-signature": signature} ) return args
def mexc_v3(args: tuple[str, URL], kwargs: dict[str, Any]) -> tuple[str, URL]: method: str = args[0] url: URL = args[1] data: dict[str, Any] = kwargs["data"] or {} headers: CIMultiDict = kwargs["headers"] session: aiohttp.ClientSession = kwargs["session"] key: str = session.__dict__["_apis"][Hosts.items[url.host].name][0] secret: bytes = session.__dict__["_apis"][Hosts.items[url.host].name][1] timestamp = str(int(time.time() * 1000)) query = MultiDict(url.query) body = FormData(data)() if query: query.extend({"timestamp": timestamp}) url = url.with_query(query) query = MultiDict(url.query) else: body._value += f"×tamp={timestamp}".encode() query_string = url.raw_query_string.encode() signature = hmac.new( secret, query_string + body._value, hashlib.sha256 ).hexdigest() if query: query.extend({"signature": signature}) else: body._value += f"&signature={signature}".encode() body._size += len(body._value) url = url.with_query(query) args = (method, url) kwargs.update({"data": body._value}) headers.update({"X-MEXC-APIKEY": key, "Content-Type": "application/json"}) return args
def bitbank(args: tuple[str, URL], kwargs: dict[str, Any]) -> tuple[str, URL]: method: str = args[0] url: URL = args[1] data: dict[str, Any] = kwargs["data"] or {} headers: CIMultiDict = kwargs["headers"] session: aiohttp.ClientSession = kwargs["session"] key: str = session.__dict__["_apis"][Hosts.items[url.host].name][0] secret: bytes = session.__dict__["_apis"][Hosts.items[url.host].name][1] path = url.raw_path_qs body = JsonPayload(data) if data else FormData(data)() nonce = str(int(time.time() * 1000)) if method == METH_GET: text = f"{nonce}{path}".encode() else: text = nonce.encode() + body._value signature = hmac.new(secret, text, hashlib.sha256).hexdigest() kwargs.update({"data": body}) headers.update( {"ACCESS-KEY": key, "ACCESS-NONCE": nonce, "ACCESS-SIGNATURE": signature} ) return args
async def upload_file(path, existing_id=""): if not path.exists(): return with load_data_file(path.parent) as parent_data_file: parent_id = parent_data_file["id"] if parent_id is None: return with path.open("rb") as file: data = FormData(fields=[("existing_id", existing_id), ("product_id", str(parent_id)), ("token", utils.get_login_token()), ("user_id", str(utils.get_user_id()))], quote_fields=False) data.add_field("file", file, filename=path.name) resp = await (await utils.upload_file( constants.SERVER_HOST + "/_back/product-sync-upload", data)).json() with load_data_file(path) as data: data["id"] = resp.get("id", data.get("id", None)) data["type"] = resp.get("type", data.get("type", None)) data["name"] = path.name
def test_invalid_formdata_content_type(): form = FormData() invalid_vals = [0, 0.1, {}, [], b'foo'] for invalid_val in invalid_vals: with pytest.raises(TypeError): form.add_field('foo', 'bar', content_type=invalid_val)
def test_formdata_field_name_is_quoted(buf, writer): form = FormData(charset="ascii") form.add_field("emails[]", "*****@*****.**", content_type="multipart/form-data") payload = form() yield from payload.write(writer) assert b'name="emails%5B%5D"' in buf
def test_invalid_formdata_payload() -> None: form = FormData() form.add_field('test', object(), filename='test.txt') with pytest.raises(TypeError): form()
def test_invalid_formdata_filename() -> None: form = FormData() invalid_vals = [0, 0.1, {}, [], b'foo'] for invalid_val in invalid_vals: with pytest.raises(TypeError): form.add_field('foo', 'bar', filename=invalid_val)
async def test_formdata_field_name_is_not_quoted(buf, writer) -> None: form = FormData(quote_fields=False, charset="ascii") form.add_field("emails[]", "*****@*****.**", content_type="multipart/form-data") payload = form() await payload.write(writer) assert b'name="emails[]"' in buf
def test_invalid_formdata_content_transfer_encoding(): form = FormData() invalid_vals = [0, 0.1, {}, [], b'foo'] for invalid_val in invalid_vals: with pytest.raises(TypeError): form.add_field('foo', 'bar', content_transfer_encoding=invalid_val)
def test_formdata_multipart(buf, writer) -> None: form = FormData() assert not form.is_multipart form.add_field('test', b'test', filename='test.txt') assert form.is_multipart
def request( self, request_params: MutableMapping[str, Any], operation: Optional[Operation] = None, request_config: Optional[RequestConfig] = None, ) -> HttpFuture: """Sets up the request params for aiohttp and executes the request in the background. :param request_params: request parameters for the http request. :param operation: operation that this http request is for. Defaults to None - in which case, we're obviously just retrieving a Swagger Spec. :param request_config:RequestConfig request_config: Per-request config that is passed to :class:`bravado.http_future.HttpFuture`. :rtype: :class: `bravado_core.http_future.HttpFuture` """ orig_data = request_params.get("data", {}) if isinstance(orig_data, Mapping): data = FormData() for name, value in orig_data.items(): str_value = ( str(value) if not is_list_like(value) else [str(v) for v in value] ) data.add_field(name, str_value) else: data = orig_data if isinstance(data, FormData): for name, file_tuple in request_params.get("files", {}): stream_obj = file_tuple[1] data.add_field(name, stream_obj, filename=file_tuple[0]) params = self.prepare_params(request_params.get("params")) connect_timeout = request_params.get("connect_timeout") # type: Optional[float] request_timeout = request_params.get("timeout") # type: Optional[float] # mypy thinks the type of total and connect is float, even though it is Optional[float]. Let's ignore the error. timeout = ( aiohttp.ClientTimeout(total=request_timeout, connect=connect_timeout) if (connect_timeout or request_timeout) else None ) follow_redirects = request_params.get("follow_redirects", False) # aiohttp always adds a Content-Type header, and this breaks some servers that don't # expect it for non-POST/PUT requests: https://github.com/aio-libs/aiohttp/issues/457 skip_auto_headers = ( ["Content-Type"] if request_params.get("method") not in ["POST", "PUT"] else None ) coroutine = self.client_session.request( method=request_params.get("method") or "GET", url=cast(str, request_params.get("url", "")), params=params, data=data, headers={ # Convert not string headers to string k: from_bytes(v) if isinstance(v, bytes) else str(v) for k, v in request_params.get("headers", {}).items() }, allow_redirects=follow_redirects, skip_auto_headers=skip_auto_headers, timeout=timeout, **self._get_ssl_params() ) future = self.run_coroutine_func(coroutine, loop=self.loop) return self.bravado_future_class( self.future_adapter(future), self.response_adapter(loop=self.loop), operation, request_config=request_config, )
def test_formdata_field_name_is_not_quoted(buf, writer): form = FormData(quote_fields=False, charset="ascii") form.add_field("emails[]", "*****@*****.**", content_type="multipart/form-data") payload = form() yield from payload.write(writer) assert b'name="emails[]"' in buf