20 Stimmen

Konvertieren Sie eine curl POST-Anfrage nur unter Verwendung der Standardbibliothek in Python

Ich möchte diesen curl-Befehl in etwas umwandeln, das ich in Python für ein vorhandenes Skript verwenden kann.

curl -u 7898678:X -H 'Content-Type: application/json' \
-d '{"message":{"body":"TEXT"}}' http://sample.com/36576/speak.json

TEXT möchte ich durch eine vom restlichen Skript generierte Nachricht ersetzen. (Das bereits vernünftig funktioniert, obwohl ich glaube, dass es nicht den besten Praktiken folgt oder besonders zuverlässig ist. - muss herausfinden, wie man richtig programmieren lernt (z.B. nicht Google verwenden, um Sachen zusammenzustellen))

Ich möchte, dass dies mit der Standardbibliothek funktioniert, wenn möglich.

24voto

John Feminella Punkte 292907

Ich möchte, dass dies mit der Standardbibliothek funktioniert, wenn möglich.

Die Standardbibliothek bietet urllib und httplib zum Arbeiten mit URLs:

>>> import httplib, urllib
>>> params = urllib.urlencode({'apple': 1, 'banana': 2, 'coconut': 'yummy'})
>>> headers = {"Content-type": "application/x-www-form-urlencoded",
...            "Accept": "text/plain"}
>>> conn = httplib.HTTPConnection("example.com:80")
>>> conn.request("POST", "/some/path/to/site", params, headers)
>>> response = conn.getresponse()
>>> print response.status, response.reason
200 OK

Wenn Sie jedoch curl selbst ausführen möchten, können Sie einfach os.system() aufrufen:

import os
TEXT = ...
cmd = """curl -u 7898678:X -H 'Content-Type: application/json'""" \
  """-d '{"message":{"body":"%{t}"}}' http://sample.com/36576/speak.json""" % \
  {'t': TEXT}

Wenn Sie die Beschränkung nur auf die Standardbibliothek lockern möchten, können Sie PycURL verwenden. Beachten Sie, dass es nicht sehr pythonisch ist (es ist im Grunde nur eine dünnflächige Schicht über libcurl) und ich bin mir nicht sicher, wie kompatibel es mit Python 3 ist.

12voto

Andrew Dalke Punkte 14207

Während es Möglichkeiten gibt, Authentifizierung in urllib2 zu behandeln, wenn Sie Basic Authorization verwenden (was effektiv das Senden des Benutzernamens und des Passworts im Klartext bedeutet), können Sie alles, was Sie wollen, mit einem urllib2.Request und urllib2.urlopen tun:

import urllib2

def basic_authorization(user, password):
    s = user + ":" + password
    return "Basic " + s.encode("base64").rstrip()

req = urllib2.Request("http://localhost:8000/36576/speak.json",
                      headers = {
        "Authorization": basic_authorization("7898678", "X"),
        "Content-Type": "application/json",

        # Einige zusätzliche Header zum Spaß
        "Accept": "*/*",   # curl macht das
        "User-Agent": "my-python-app/1", # sonst wird "Python-urllib/..." verwendet
        },
                      data = '{"message":{"body":"TEXT"}}')

f = urllib2.urlopen(req)

Ich habe dies mit netcat getestet, damit ich sehen konnte, dass die gesendeten Daten in beiden Fällen bis auf die Reihenfolge identisch waren. Hier wurde der erste mit curl und der zweite mit urllib2 gemacht

% nc -l 8000
POST /36576/speak.json HTTP/1.1
Authorization: Basic Nzg5ODY3ODpY
User-Agent: curl/7.19.4 (universal-apple-darwin10.0) libcurl/7.19.4 OpenSSL/0.9.8k zlib/1.2.3
Host: localhost:8000
Accept: */*
Content-Type: application/json
Content-Length: 27

{"message":{"body":"TEXT"}} ^C

% nc -l 8000
POST /36576/speak.json HTTP/1.1
Accept-Encoding: identity
Content-Length: 27
Connection: close
Accept: */*
User-Agent: my-python-app/1
Host: localhost:8000
Content-Type: application/json
Authorization: Nzg5ODY3ODpY

{"message":{"body":"TEXT"}}^C

(Dies wurde leicht angepasst aus der Ausgabe. Mein Testfall hat nicht denselben URL-Pfad verwendet, den Sie verwendet haben.)

Es ist nicht notwendig, das zugrunde liegende httplib zu verwenden, das Dinge, die urllib2 Ihnen bietet, wie z.B. Proxy-Unterstützung, nicht unterstützt. Andererseits finde ich urllib2 außerhalb dieser einfachen Art von Anfrage kompliziert und wenn Sie eine bessere Unterstützung dafür haben möchten, welche Header gesendet werden und in welcher Reihenfolge sie gesendet werden, dann nutzen Sie httplib.

2voto

Jimm Punkte 21

Danke jeder

dies funktioniert

import urllib2

def speak(status):

    def basic_authorization(user, password):
        s = user + ":" + password
        return "Basic " + s.encode("base64").rstrip()

    req = urllib2.Request("http://example.com/60/speak.json",
                  headers = {
       "Authorization": basic_authorization("2345670", "X"),
     "Content-Type": "application/json",

        "Accept": "*/*",   
        "User-Agent": "my-python-app/1", 
        },
                      data = '{"message":{"body":'+ status +'}}')

    f = urllib2.urlopen(req)

speak('Yay')

1voto

z33m Punkte 5853

Werfen Sie einen Blick auf pycurl http://pycurl.sourceforge.net/

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X