Как отправить действительный запрос XML POST в ebay API через Python?

#python #xml #http-post #ebay-api

#python #xml #http-post #ebay-api

Вопрос:

Я предполагаю, что это скорее общая проблема, чем специфичная для ebay, но я не уверен: я пытаюсь отправить XML-запрос в ebay developer API для получения XML-ответа. При использовании curl все работает нормально, и я получаю XML-ответ, сообщающий мне, какие ключи API отсутствуют (если бы я предоставил их через HTTP-заголовки, я бы получил действительный результат XML):

 curl -d '<!xml version="1.0" encoding="utf-8"?><findItemsByKeywordsRequest xmlns="http://www.ebay.com/marketplace/search/v1/services"><keywords>harry potter phoenix</keywords></findItemsByKeywordsRequest>' 
http://svcs.sandbox.ebay.com/services/search/FindingService/v1
  

Что приводит к правильному ответу:

 <?xml version='1.0' encoding='UTF-8'?>
<ms:errorMessage xmlns:ms="http://www.ebay.com/marketplace/services" xmlns="http://www.ebay.com/marketplace/search/v1/services">
    <error>
        <errorId>2038</errorId>
        <domain>CoreRuntime</domain>
        <severity>Error</severity>
        <category>System</category>
        <message>Missing SOA operation name header</message>
        <subdomain>System</subdomain>
    </error>
</ms:errorMessage>
  

Но когда я пытаюсь работать с Python, я просто получаю «500 Internal Server error», независимо от того, насколько простыми я делаю свои примеры. Я попробовал два очень простых метода:

Номер один:

 serverUrl = 'svcs.sandbox.ebay.com'
xmlparameters = '<!xml version="1.0" encoding="utf-8"?><findItemsByKeywordsRequest xmlns="http://www.ebay.com/marketplace/search/v1/services"><keywords>harry potter phoenix</keywords></findItemsByKeywordsRequest>'

webservice = httplib.HTTP(serverUrl)
webservice.putrequest("POST", "/services/search/FindingService/v1")
webservice.putheader("Host", serverUrl)
webservice.putheader("Content-type", "text/xml; charset="UTF-8"")
webservice.putheader("Content-length", "%d" % len(xmlparameters))
webservice.endheaders()
webservice.send(xmlparameters)
  

Номер два (который является моим предпочтительным методом):

 serverUrl = 'svcs.sandbox.ebay.com'
xmlparameters = '<!xml version="1.0" encoding="utf-8"?><findItemsByKeywordsRequest xmlns="http://www.ebay.com/marketplace/search/v1/services"><keywords>harry potter phoenix</keywords></findItemsByKeywordsRequest>'

connection = httplib.HTTPConnection(serverUrl)
connection.request("POST", '/services/search/FindingService/v1', xmlparameters)
  

Как вы можете видеть в примере CURL, не имеет значения, что я не отправляю ключи API и т.д., Он в любом случае должен возвращать ответ об ошибке XML, а не только код состояния HTTP «Внутренняя ошибка сервера 500».

Кто-нибудь видит, что я делаю не так с моим POST-запросом?

[РЕДАКТИРОВАТЬ] кстати, использование API URL ValueName отлично работает с Python, но это всего лишь запрос GET на URL. Тем не менее, я бы предпочел использовать XML API. Однако, если это невозможно, я бы, конечно, переключился на URI ValueName.

Ответ №1:

Он возвращает статус 500 и XML-ответ:

 >>> connection.request("POST", '/services/search/FindingService/v1', xmlparameters)
>>> resp = connection.getresponse()
>>> resp.status
<<< 500
>>> resp.read()
<<< '<?xml version='1.0' encoding='UTF-8'?><ms:errorMessage xmlns:ms="http://www.ebay.com/marketplace/services" xmlns="http://www.ebay.com/marketplace/search/v1/services"><error><errorId>2038</errorId><domain>CoreRuntime</domain><severity>Error</severity><category>System</category><message>Missing SOA operation name header</message><subdomain>System</subdomain></error></ms:errorMessage>'
  

Комментарии:

1. Вы правы… В Германии мы обычно говорим «не видим лес из-за всех деревьев» в таких ситуациях. Всегда верно 😉 Как неловко. Большое спасибо! Это дало бы вам преимущество, но сначала я должен подумать о хорошем имени пользователя OpenID 😉

2. Некоторое дополнение, если кто-нибудь обнаружит этот вопрос через несколько месяцев: ebay не хочет, чтобы в начале была строка XML, иначе он вернет ошибку «Не удается создать программу чтения xml stream для XML: формат полезной нагрузки неверен или полезная нагрузка пуста». Удаление XML-тега в начале заставляет все работать.

Ответ №2:

Статус ответа 500 является довольно общим и должен возвращаться независимо от того, какая ошибка выдается на сервере. Не могли бы вы рассмотреть возможность использования CGI trackback для возврата сообщения об ошибке?

http://docs.python.org/library/cgitb.html#module-cgitb

Комментарии:

1. Сам мой скрипт не содержит ошибок, поэтому cgitb, похоже, не возвращает ошибок. Я включил его в первой строке, и он возвращает трассировку, когда я создаю ошибку в своем коде (например, вызываю переменную, которая не существует), но с моим текущим кодом весь скрипт просто выполняется нормально: «>>> Ошибка отправки запроса ebaypredict.sendRequest(): внутренняя ошибка сервера 500» (которая создается функцией, проверяющей, исправен код состояния или нет).

2. Полагаю, вы подумали, что я работаю со своим веб-сервером wn и поэтому порекомендовали инструмент обратной трассировки CGI? Я вызываю другой веб-сервер, и он выдает сообщение об ошибке, поэтому, похоже, я каким-то образом отправил неверный запрос на ebay.