Я создал приложение Flask и хотел его протестировать.В одной конечной точке я хотел бы опубликовать составной запрос, который включает в себя файл и сложный объект JSON.Сначала я подумал об использовании werkzeug EnvironBuilder для этой задачи, поскольку он, кажется, обеспечивает достаточно автоматизированный подход, обработку типов содержимого и т. Д. Мой фрагмент кода для подготовки запроса следующий:
# client is an instance of FlaskClient produced using a pytest fixture and the method test client
def _post(endpoint, file_path=None, serialized_message=None):
with open(file_path, 'rb') as fin:
fil = io.BytesIO(fin.read())
file_name = file_path.split(os.sep)[-1]
builder = EnvironBuilder(path='/' + endpoint,
method='POST',
data=json.loads(
serialized_message),
content_type="application/json")
builder.files[file_name] = fil
result = client.open(builder, buffered=True)
return result
Thisошибка со следующей ошибкой:
def _add_file_from_data(self, key, value):
"""Called in the EnvironBuilder to add files from the data dict."""
if isinstance(value, tuple):
self.files.add_file(key, *value)
elif isinstance(value, dict):
from warnings import warn
warn(DeprecationWarning('it\'s no longer possible to pass dicts '
'as `data`. Use tuples or FileStorage '
'objects instead'), stacklevel=2)
value = dict(value)
mimetype = value.pop('mimetype', None)
if mimetype is not None:
value['content_type'] = mimetype
> self.files.add_file(key, **value)
E TypeError: add_file() got an unexpected keyword argument 'globalServiceOptionId'
С globalServiceOptionId
, являющимся ключом вложенного словаря в словаре, который я публикую.У меня есть некоторые мысли по поводу обхода этой проблемы с преобразованием в строковые jsons внутренних словарей, но я хотел бы получить что-то более конкретное в качестве ответа, так как я не хочу, чтобы представление запроса изменялось внутри и снаружи тестирования.Спасибо.
Обновление 1
Форма словаря с паролем не имеет большого значения, если в нем есть словари.Этот json приведен в следующем примере:
{
"attachments": [],
"Ids": [],
"globalServiceOptions": [{
"globalServiceOptionId": {
"id": 2,
"agentServiceId": {
"id": 2
},
"serviceOptionName": "Time",
"value": "T_last",
"required": false,
"defaultValue": "T_last",
"description": "UTC Timestamp",
"serviceOptionType": "TIME"
},
"name": "Time",
"value": null
}]
}
Обновление 2
Я проверил другой фрагмент:
def _post(endpoint, file_path=None, serialized_message=None):
with open(file_path, 'rb') as fin:
fil = io.BytesIO(fin.read())
files = {
'file': (file_path, fil, 'application/octet-stream')
}
for key, item in json.loads(serialized_message).items():
files[key] = (None, json.dumps(item), 'application/json')
builder = EnvironBuilder(path='/' + endpoint,
method='POST', data=files,
)
result = client.open(builder, buffered=True)
return result
Хотя это работает без ошибок, Flask распознает (как и ожидалось)) входящие jsons в виде файлов, что опять-таки требует другой обработки во время тестирования и нормальной работы.