PythonでHTTP PUTを行う方法はありますか


220

PUTPythonでHTTP を使用してサーバーにデータをアップロードする必要があります。私がurllib2ドキュメントを簡単に読んだところ、HTTPのみを実行していますPOSTPUTPythonでHTTPを行う方法はありますか?

回答:


311

私は過去にさまざまなpython HTTPライブラリを使用したことがあり、お気に入りとして「リクエスト」に落ち着きました。既存のライブラリにはかなり使いやすいインターフェースがありましたが、コードが数行になりすぎて単純な操作には長すぎる場合があります。リクエストの基本的なPUTは次のようになります。

payload = {'username': 'bob', 'email': 'bob@bob.com'}
>>> r = requests.put("http://somedomain.org/endpoint", data=payload)

その後、次のようにして応答ステータスコードを確認できます。

r.status_code

または次の応答:

r.content

リクエストには、多くのシンタクティックシュガーとショートカットがあり、あなたの生活をより簡単にします。


11
上記のコードは非常にシンプルに見えますが、「リクエスト」が不足している、または不十分であると推測しないでください。非常に整頓されたインターフェースで、それは非常に能力があります。
ジョナサンハートレー

5
この回答が新しい投票数の回答になるまで、次第に票を集めるのにどれくらい時間がかかるのでしょうか。
ジョナサンハートレー

2
あなたはこれがどれほど素晴らしいか理解していません!!! 私はお粗末なJavaライブラリと格闘していました!...「リクエスト」を指摘してくれて、私はちょっとあなたを愛していると思います!
Shehaaz 2013

3
json=payloadデータを本文に含める場合は、parameterを使用します。
ManuelSchneid3r 2017年

1
このインターフェイスは関数型プログラミングであるため、他の答えよりも優れていることをすぐに指摘しておきます。パラメータとして単純なデータ構造を持つ関数が機能するときにオブジェクトを作成する理由。他のpythonライブラリもそれに倣って欲しいです。
マルク

242
import urllib2
opener = urllib2.build_opener(urllib2.HTTPHandler)
request = urllib2.Request('http://example.org', data='your_put_data')
request.add_header('Content-Type', 'your/contenttype')
request.get_method = lambda: 'PUT'
url = opener.open(request)

4
ちょっと汚いハックのように見えますが、エレガントで完全に機能しているようです
Rory

6
モンキーパッチを適用する代わりにurllib2.Requestをサブクラス化する場合は、ハックが少なくなります。
Jason R. Coombs、2011年

23
この回答は書かれたときは素晴らしかったですが、今日では代わりに 'requests'パッケージを使用する方がはるかに簡単です。JohnCarterの回答を参照してください。「リクエスト」は決しておもちゃではありません-それは非常に有能です。
ジョナサンハートレー

5
この答えは標準的ですが、時代遅れです。requests代わりにライブラリの使用を検討してください。
jsalonen

13
ありがとう、標準のPythonライブラリ以外のものは使いたくありませんでした。これは完璧に機能します。urllib2が標準でGETとPOSTのみに対応するように設計されている理由がよくわかりませんが、この回避策はチャンピオンです。urllib2.build_opener(urllib2.HTTPHandler)を複数の呼び出しで再利用できますか?
WeNeedAnswers 2012年

46

Httplibはよりクリーンな選択のようです。

import httplib
connection =  httplib.HTTPConnection('1.2.3.4:1234')
body_content = 'BODY CONTENT GOES HERE'
connection.request('PUT', '/url/path/to/put/to', body_content)
result = connection.getresponse()
# Now result.status and result.reason contains interesting stuff

プロキシサポートが必要な場合は、httplibを使用しないでください。詳細については、この記事を参照してください。
Jason R. Coombs、2011年

どうしてそう言うの?あなたの記事はそれが機能することを明確に述べています。Rolf Westerの回答を参照してください。urllibは失敗しますが、httplibは機能します。
スプール、2011年

httplibは、ユーザーが明示的にプロキシに接続し、GETパラメータに完全なURLを含めるようにリクエストを変更した場合にのみ機能します。urllibが失敗した理由は、http_proxyが正しく設定されていなかったためです。urllibは、シーンでhttplibを使用しますが、リダイレクト、プロキシなども処理します
Jason R. Coombs

このソリューションは機能しますが、リクエストを使用する方がはるかに単純でエレガントで、私の意見ではより優れています。
tgrosinger

1
@tgrosinger同意する。この回答は、リクエストが存在する前に投稿されました。現在のところ、このソリューションの方が優れているのは、Python標準ライブラリのみが利用できる場合のみです。それ以外の場合は、リクエストを使用することもお勧めします。
スプール

8

httplibモジュールを見てください。それはあなたがあなたが望むどんな種類のHTTPリクエストも作ることができるはずです。


素晴らしい解決策、静かなpythonicですが、金属に少し近すぎて、すでに他の多くのコードを書く必要があります
Rory

8

RESTful APIのクライアントとして機能できるように、この問題をしばらく前に解決する必要がありました。GETとPOSTに加えてPUTとDELETEを送信できるので、httplib2に決めました。Httplib2は標準ライブラリの一部ではありませんが、チーズショップから簡単に入手できます。


2
httplib2はボーダーラインの放棄ウェアです。コミュニティの貢献(パッチ)にもかかわらず、修正されないバグの長いリストがあります。本番環境でhttplib2を使用する前に、よく考えることをお勧めします。
Jason R. Coombs、2011年

8

リクエストライブラリを使用できます。urllib2アプローチを使用する場合に比べて、多くのことが単純化されます。まず、pipからインストールします。

pip install requests

リクエストのインストールの詳細

次にputリクエストを設定します。

import requests
import json
url = 'https://api.github.com/some/endpoint'
payload = {'some': 'data'}

# Create your header as required
headers = {"content-type": "application/json", "Authorization": "<auth-key>" }

r = requests.put(url, data=json.dumps(payload), headers=headers)

リクエストライブラリクイックスタートをご覧ください。これはurllib2よりもはるかに簡単だと思いますが、この追加パッケージをインストールしてインポートする必要があります。


リクエストはPUTもサポートしますか?
Jeef 2014

リクエストは、get、put、post、deleteヘッドとオプションをサポートしています。putを使用する例を修正しました。リクエストのクイックスタートをご覧ください。
radtek、2014

@RPradeepありがとうございます。
radtek、2016



3

put.pyを確認しましたか?過去に使ったことがあります。また、独自のリクエストをurllibでハックアップすることもできます。


私は実際にはランダムな人のhttpライブラリをいくつか使用したくない
Rory

インポートしようとしましたput
get

#tail -f /root/.pip/pip.logトレースバック(最新の呼び出しは最後):ファイル「/usr/lib/python2.7/dist-packages/pip/basecommand.py」、122行目、メインステータス= self.run(options、args)ファイル "/usr/lib/python2.7/dist-packages/pip/commands/install.py"、278行、requirement_set.prepare_files(finder、force_root_egg_info = self.bundle、bundleで実行= self.bundle)prepare_files内のファイル "/usr/lib/python2.7/dist-packages/pip/req.py"、1178行
Ashish Karpe

url = finder.find_requirement(req_to_install、upgrade = self.upgrade)File "/usr/lib/python2.7/dist-packages/pip/index.py"、line 277、in find_requirement raise DistributionNotFound( 'No distributions at all found %s '%reqの場合)DistributionNotFound:putのディストリビューションがまったく見つかりません
Ashish Karpe

2

もちろん、既存の標準ライブラリを使用して、ソケットからurllibの調整まで、あらゆるレベルで独自のライブラリをロールできます。

http://pycurl.sourceforge.net/

「PyCurlはlibcurlへのPythonインターフェースです。」

「libcurlは無料で使いやすいクライアント側のURL転送ライブラリで、...をサポートしています... HTTP PUT」

「PycURLの主な欠点は、Pythonクラスの階層がなく、libcurlに比べて比較的薄いレイヤーであることです。これは、libcurlのC APIに慣れていない限り、学習曲線がやや急になることを意味します。」


きっとうまくいくと思いますが、もう少しPython的なものが欲しいです
Rory

2

標準ライブラリ内にとどまりたい場合は、次のようにサブクラス化できますurllib2.Request

import urllib2

class RequestWithMethod(urllib2.Request):
    def __init__(self, *args, **kwargs):
        self._method = kwargs.pop('method', None)
        urllib2.Request.__init__(self, *args, **kwargs)

    def get_method(self):
        return self._method if self._method else super(RequestWithMethod, self).get_method()


def put_request(url, data):
    opener = urllib2.build_opener(urllib2.HTTPHandler)
    request = RequestWithMethod(url, method='PUT', data=data)
    return opener.open(request)

0

これを使用するより適切な方法はrequests次のとおりです。

import requests

payload = {'username': 'bob', 'email': 'bob@bob.com'}

try:
    response = requests.put(url="http://somedomain.org/endpoint", data=payload)
    response.raise_for_status()
except requests.exceptions.RequestException as e:
    print(e)
    raise

HTTP PUTリクエストにエラーがある場合、これにより例外が発生します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.