Robotframework.request - Как сделать POST-запрос с содержимым «multipart / form-data» - PullRequest
0 голосов
/ 25 ноября 2018

Я хочу сделать POST-запрос в Robot Framework с «Content-Type: multipart / form-data», используя RequestsLibrary , но, похоже, ничего не работает.Ключевое слово, которое делает этот запрос, выглядит следующим образом:

*** Variables ***
&{API_CREDS}  username=myusername  password=mypwd

*** Keywords ***
Get token
    # Assumes that session has been created
    [Arguments]  ${Session_id}
    &{headers}=  create dictionary  Content-Type=multipart/form-data
    ${response}=  Post Request  ${Session_id}  ${AUTH_TOKEN_URL_PATH}  data=${API_CREDS}   headers=${headers}
    should be equal as integers  ${response.status_code}  200
    [Return]  ${response.json()['token']}

Но фактически отправленный запрос POST не содержит заголовка «Content-Type», а тело является просто необработанным data={'username' = 'myusername', ' password' = 'mypwd'}

Я перепробовал много вещей, которые я искал, но ничего не помогало.RequestsLibrary Robot Framework действительно поддерживает отправку запроса POST с "Content-Type: multipart / form-data"? Если да, то как это сделать?

PS: я использую Robot Framework на Windows 10 с Python 3.7.1.Запрос POST фактически отправляется, но он не содержит ни заголовка Content-Type, ни полезных данных формы, как упомянуто выше.

1 Ответ

0 голосов
/ 25 ноября 2018

Используемая базовая библиотека python - requests, имеет некоторые особенности, работающие с составным содержимым "form-data".Он использует его в основном для отправки файлов как часть запроса (функция загрузки);грубо говоря, когда он анализировал ваши аргументы, он удалял заголовок, потому что не было файлов для отправки.Кроме того, если он этого не сделал, он не предназначен для того, чтобы вычитать, какие есть разные части в вашей многокомпонентной полезной нагрузке - например, он не помещает каждую пару ключ-значение в отдельную часть.

Для преодолениядля этого обычно используется параметр files, передавая в качестве аргумента содержимое различных частей.При этом библиотека requests автоматически устанавливает заголовок данных формы и разбивает содержимое по частям.
Вот как это сделать в RF, пояснение приведено ниже:

${data}=    Evaluate    {'username': (None, 'myusername'), 'password': (None, 'mypwd')}
${response}=  Post Request  ${Session_id}  ${AUTH_TOKEN_URL_PATH}  files=${data}

Используя параметр files в ключевом слове Post Request, ваша полезная нагрузка будет передана методу requests post как есть.Вам не нужно явно устанавливать заголовки, библиотека сделает это за вас.

То, что передается в качестве аргумента, является словарем, если значения являются содержимым частей.Как вы можете видеть, фактические значения являются кортежами Python, потому что вы хотите переопределить имя файла в детали.Это лучше объяснить на примере;если данные похожи на это, значение представляет собой простую строку:

${data}=    Evaluate    {'username': 'myusername', 'password': 'mypwd'}

, тогда полезная нагрузка будет выглядеть так:

--7579227dh785568ha91866339229add786
Content-Disposition: form-data; name="username"; filename="username"

myusername
--7579227dh785568ha91866339229add786
Content-Disposition: form-data; name="password"; filename="password"

mypwd
--7579227dh785568ha91866339229add786--

Обратите внимание, что у каждой части есть «имя файла»свойство, равное имени параметра.

Когда значение является кортежем, его первый член устанавливает свойство "filename" детали;и когда это None, «имя файла» вообще отсутствует, что приводит к следующему результату:

--7579227dh785568ha91866339229add786
Content-Disposition: form-data; name="username"

myusername
--7579227dh785568ha91866339229add786
Content-Disposition: form-data; name="password"

mypwd
--7579227dh785568ha91866339229add786--

, что, вероятно, является вашей целью.

...