2013-11-26 2 views
3

I`m пытается сделать эти 2 запроса в Python:Отправка Curl данных/Json в Python

Запрос 1:

curl -X POST -H "Content-Type: application/json" -d '{ "auth_token": "auth1", "widget": "id1", "title": "Something1", "text": "Some text", "moreinfo": "Subtitle" }' serverip 

Запрос 2:

vsphere_dict = {} 
vsphere_dict['server_name'] = "servername" 
vsphere_dict['api_version'] = apiVersion 
vsphere_dict['guest_count'] = guestCount 
vsphere_dict['guest_on'] = guestOnLen 
vsphere_dict['guest_off'] = guestOffLen 

#Convert output to Json to be sent 
data = json.dumps(vsphere_dict) 

curl -X POST -H "Content-Type: application/json" -d 'data' serverip 

Ни один из них, кажется, работать. Есть ли способ отправить их на Python?

Update:

Та часть, которая не может справиться является передача аутентификации и виджет. Я попытался следующие без успеха:

import urllib2 
import urllib 

vsphere_dict = dict(
    server_name="servername", 
    api_version="apiVersion", 
    guest_count="guestCount", 
    guest_on="guestOnLen", 
    guest_off="guestOffLen", 
) 

url = "http://ip:port" 

auth = "authid89" 
widget = "widgetid1" 

# create request object, set url and post data 
req = urllib2.Request(auth,url, data=urllib.urlencode(vsphere_dict)) 
# set header 
req.add_header('Content-Type', 'application/json') 
# send request 
response = urllib2.urlopen(req)** 

В результате в «urllib2.HTTPError: Ошибка HTTP 500: Внутренняя ошибка сервера»

Любые идеи, как я могу сдавшие авторизацию и виджет правильно?

UPDATE:

Чтобы увидеть, что разные я начал сервер пс локально. Вот результаты:

Правильный завиток запрос с помощью этого кода:

curl -X POST -H "Content-Type: application/json" -d '{ "auth_token": "auth", "widget": "widgetid", "title": "Something", "text": "Some text", "moreinfo": "Subtitle" }' http://localhost:8123 

посылает эту , который делает работу:

POST/HTTP/1.1 
User-Agent: curl/7.21.0 (i386-redhat-linux-gnu) libcurl/7.21.0 NSS/3.12.10.0 zlib/1.2.5 libidn/1.18 libssh2/1.2.4 
Host: localhst:8123 
Accept: */* 
Content-Type: application/json 
Content-Length: 165 

{ "auth_token": "token", "widget": "widgetid", "title": "Something", "text": "Some text", "moreinfo": "Subtitle" } 

И запрос, используя этот код

import requests 
    import simplejson as json 

    url = "http://localhost:8123" 
    data = {'auth_token': 'auth1', 'widget': 'id1', 'title': 'Something1', 'text': 'Some text', 'moreinfo': 'Subtitle'} 
    headers = {'Content-type': 'application/json'} 
    r = requests.post(url, data=json.dumps(data), headers=headers) 

отправляет то, что не работает :

POST/HTTP/1.1 
Host: localhst:8123 
Content-Length: 108 
Content-type: application/json 
Accept-Encoding: gzip, deflate, compress 
Accept: */* 
User-Agent: python-requests/2.0.1 CPython/2.7.0 Linux/2.6.35.14-106.fc14.i686 

{"text": "Some text", "auth_token": "auth1", "moreinfo": "Subtitle", "widget": "id1", "title": "Something1"} 
+0

Вы использовали модуль подпроцесса? –

ответ

2

Ну конечно, с помощью Python-запросов, который является библиотека Python для отправки запросов, как Curl. Вы можете посмотреть раздел Complicated Post Requests.

Или, если вы хотите использовать curl внутри Python, вы можете использовать pyCurl.

+0

Auth and Widget - это те, которые я использую для аутентификации на сервере. Мне нужно отправить их как первые 2 параметра и отправить данные позже. Еще не повезло – Spanglish

1

Почему бы не использовать urllib2?

import urllib2 
import urllib 

vsphere_dict = dict(
    server_name="servername", 
    api_version=apiVersion, 
    guest_count=guestCount, 
    guest_on=guestOnLen, 
    guest_off=guestOffLen, 
) 
# create request object, set url and post data 
req = urllib2.Request(some_url, data=urllib.urlencode(vsphere_dict)) 
# set header 
req.add_header('Content-Type', 'application/json') 
# send request 
response = urllib2.urlopen(req) 

UPD:

извините, по я не понимаю, что auth и widget. Может быть, это тоже данные POST? Ошибка HTTP 500 - может означать, что сервер получил не все параметры POST.

3

Requests предоставляет вам самый простой и в то же время очень эффективный способ обработки HTTP-запросов в Python.

Может быть, попробовать что-то вроде этого:

import requests 
import simplejson as json 

url = "http://ip:port" 
data = {'auth_token': 'auth1', 'widget': 'id1', 'title': 'Something1', 'text': 'Some text', 'moreinfo': 'Subtitle'} 
headers = {'Content-type': 'application/json'} 
r = requests.post(url, data=json.dumps(data), headers=headers) 

Если аутентификации запросов API:

r = requests.post(url, data=json.dumps(data), headers=headers, auth=('user', 'pass')) 

См [просит аутентификации] для получения подробной информации.

+0

Это кажется идеальным, но не решает проблему. Я получаю: >>> r.reason «Неавторизованный» – Spanglish

+0

Возможно, API, который вы отправляете, запрашивает аутентификацию? Если это так, см. [Аутентификация] (http://www.python-requests.org/en/latest/user/authentication/), и не забудьте принять ответ :) –

+0

Пример BasicAuth добавлен в ответ. –

1

В примере с сайта лихой, они используют:

curl -d '{ "auth_token": "YOUR_AUTH_TOKEN", "current": 100 }' http://localhost:3030/widgets/karma 

От завитка страницы человека, может быть, вы должны разместить его в форме-urlencoded?

-d, --data

(HTTP) Отправляет указанные данные в запросе POST на сервер HTTP, таким же образом, что браузер делает, когда пользователь заполнил в HTML-форму и нажимает отправить кнопку. Это вызовет завихрение передачи данных на сервер с использованием приложения типа контента/x-www-form-urlencoded. Сравните с -F, --form.

-d, --data - это то же самое, что и -data-ascii. Чтобы отправлять данные чисто бинарными, вместо этого вы должны использовать опцию -data-binary. Чтобы URL-кодировать значение поля формы, вы можете использовать -data-urlencode.

Если какой-либо из этих параметров используется более одного раза в одной командной строке, указанные части данных будут объединены вместе с разделительным & -символом. Таким образом, использование '-d name = daniel -d skill = lousy' создаст пост-кусок, который выглядит как 'name = daniel & skill = lousy'.

Если вы начинаете данные с буквы @, остальное должно быть именем файла для чтения данных, или - если вы хотите, чтобы завиток читал данные из stdin. Также можно указать несколько файлов. Таким образом, отправка данных из файла с именем «foobar» выполняется с помощью --data @foobar. Когда -data говорят, чтобы читать из такого файла, возврат каретки и строки новой строки будут удалены.

Вы также можете попробовать питон-запросы http://requests.readthedocs.org/en/latest/user/quickstart/#more-complicated-post-requests

Обновление: Я получил его на работу

import requests 
import json 

payload = {'auth_token': 'YOUR_AUTH_TOKEN', 'title': "pythontest"} 
r = requests.post("http://localhost:3030/widgets/welcome", data=json.dumps(payload)) 

print r.text 

Вам нужно разместить JSON как форму.

Смежные вопросы