파이썬에서 HTTP PUT을 수행하는 방법이 있습니까


220

PUT파이썬에서 HTTP 를 사용하여 서버에 일부 데이터를 업로드해야합니다 . urllib2 문서에 대한 간단한 읽기에서 HTTP 만 수행 POST합니다. PUT파이썬 에서 HTTP를 수행하는 방법이 있습니까?

답변:


311

나는 과거에 다양한 파이썬 HTTP 라이브러리를 사용해 왔으며 ' 내가 가장 좋아하는 것으로 요청 '을 정했습니다. 기존 라이브러리에는 꽤 유용한 인터페이스가 있지만 간단한 작업을하기에는 코드가 너무 길어질 수 있습니다. 요청의 기본 PUT은 다음과 같습니다.

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

그런 다음 다음을 사용하여 응답 상태 코드를 확인할 수 있습니다.

r.status_code

또는 다음과 같은 응답 :

r.content

요청에는 많은 양의 구문 설탕과 단축키가있어 인생을 더 쉽게 만들 수 있습니다.


11
위의 코드는 매우 단순 해 보이지만 '요청'이 어떤 식 으로든 부족하거나 전력이 부족하다는 것을 암시하지 마십시오. 매우 깔끔한 인터페이스로 매우 유능합니다.
Jonathan Hartley

5
이 투표가 새로운 최고 투표 응답이 될 때까지 점진적으로 투표를 누적하는 데 얼마나 걸립니까?
Jonathan Hartley

2
당신은 이것이 얼마나 멋진 지 이해하지 못합니다 !!! 나는 잔인한 자바 라이브러리로 고투하고 있었다! ... "요청"을 가리켜 서 당신을 사랑한다고 생각합니다!
Shehaaz

3
json=payload본문에 데이터가 포함되도록 하려면 매개 변수를 사용하십시오 .
ManuelSchneid3r

1
이 인터페이스는 함수형 프로그래밍이기 때문에 다른 인터페이스보다 낫다는 것을 빨리 지적하고 싶습니다. 매개 변수처럼 간단한 데이터 구조를 가진 함수가 객체를 생성하는 이유 다른 파이썬 라이브러리가 적합하기를 바랍니다.
Marc

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

23
이 답변은 작성되었을 때 훌륭했지만 요즘에는 '요청'패키지를 사용하는 것이 훨씬 쉽습니다. John Carter의 답변을 참조하십시오. '요청'은 결코 장난감이 아닙니다. 그것은 매우 유능합니다.
Jonathan Hartley

5
이 답변은 정식이지만 구식입니다. requests대신 라이브러리 사용을 고려하십시오 .
jsalonen

13
감사합니다. 표준 파이썬 라이브러리 이외의 것을 사용하고 싶지 않았으며 완벽하게 작동합니다. 왜 urllib2가 표준으로 GET 및 POST만을 제공하도록 설계되었는지 이해하지 못하지만이 해결 방법은 챔피언입니다. urllib2.build_opener (urllib2.HTTPHandler)를 여러 호출에서 재사용 할 수 있습니까?
WeNeedAnswers

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

왜 그렇게 말하겠습니까? 귀하의 기사에는 분명히 작동한다고 명시되어 있습니다. Rolf Wester의 답변을 참조하십시오 .urlurl은 실패하지만 httplib는 작동합니다.
스풀

httplib는 사용자가 프록시에 명시 적으로 연결하고 GET 매개 변수에 전체 URL을 포함하도록 요청을 수정하는 경우에만 작동합니다. urllib가 실패한 이유는 http_proxy가 올바르게 설정되지 않았기 때문입니다. urllib는 씬에서 httplib를 사용하지만 리디렉션, 프록시 등도 처리합니다.
Jason R. Coombs

이 솔루션은 효과가 있지만 요청을 사용하는 솔루션은 훨씬 간단하고 우아하며 내 의견으로는 더 좋습니다.
tgrosinger 2016 년

1
@tgrosinger 동의합니다. 이 답변은 요청이 존재하기 전에 게시되었습니다. 현재로서는이 솔루션이 더 나은 유일한 사례는 Python Standard Library 만 사용할 수있는 경우입니다. 그렇지 않으면 요청을 사용하는 것이 좋습니다.
스풀


8

RESTful API의 클라이언트 역할을 할 수 있도록이 문제를 너무 오래 해결해야했습니다. Glib 및 POST 외에도 PUT 및 DELETE를 보낼 수 있기 때문에 httplib2에 정착했습니다. Httplib2는 표준 라이브러리의 일부는 아니지만 치즈 샵에서 쉽게 얻을 수 있습니다.


2
httplib2는 경계선 포기입니다. 커뮤니티 기여 (패치)에도 불구하고 수정되지 않은 긴 버그 목록이 있습니다. 프로덕션 환경에서 httplib2를 사용하기 전에 두 번 생각하는 것이 좋습니다.
Jason R. Coombs

8

요청 라이브러리를 사용할 수 있으며 urllib2 접근 방식을 사용하는 것과 비교하여 작업을 단순화합니다. 먼저 pip에서 설치하십시오.

pip install requests

요청 설치에 대한 추가 정보 .

그런 다음 풋 요청을 설정하십시오.

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

요청은 가져 오기, 넣기, 게시, 삭제 헤드 및 옵션을 지원합니다. put을 사용하도록 예제를 수정했습니다. 요청 빠른 시작을 확인하십시오.
radtek

@RPradeep 감사합니다.
radtek

8

이것은 python3에서 더 잘 만들어졌고 stdlib 문서에 문서화되어 있습니다.

urllib.request.Request클래스는 method=...python3 에서 매개 변수를 얻었습니다 .

일부 샘플 사용법 :

req = urllib.request.Request('https://example.com/', data=b'DATA!', method='PUT')
urllib.request.urlopen(req)


3

put.py를 살펴 보셨습니까 ? 나는 과거에 그것을 사용했습니다. urllib로 자신의 요청을 해킹 할 수도 있습니다.


난 정말 임의의 사람 http 라이브러리를 사용하고 싶지 않습니다
Rory

가져 오기 시도 중 # pip install put 다운로드 / 포장 풀기
puts

# tail -f /root/.pip/pip.log 역 추적 (가장 최근 호출) : "/usr/lib/python2.7/dist-packages/pip/basecommand.py"파일, 122 행, 기본 상태 = self.run (옵션, args) 실행 파일의 "/usr/lib/python2.7/dist-packages/pip/commands/install.py", 278 행, requirements_set.prepare_files (finder, force_root_egg_info = self.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) find_requirement에서 "/usr/lib/python2.7/dist-packages/pip/index.py"파일, 277 행, find_requirement raise DistributionNotFound ( '분포가 전혀 없음 % s '% req에 대해) DistributionNotFound : put에 대한 분포가 전혀 없습니다
Ashish Karpe

2

물론 소켓에서 urllib 조정에 이르기까지 모든 수준의 기존 표준 라이브러리로 자신을 롤업 할 수 있습니다.

http://pycurl.sourceforge.net/

"PyCurl은 libcurl에 대한 Python 인터페이스입니다."

"libcurl은 무료이며 사용하기 쉬운 클라이언트 측 URL 전송 라이브러리입니다 ... ... HTTP PUT 지원"

"PycURL의 주요 단점은 멋진 파이썬 클래스 계층 구조가없는 libcurl에 비해 상대적으로 얇은 계층이라는 것입니다. 이는 libcurl의 C API에 익숙하지 않으면 학습 곡선이 다소 가파르다는 것을 의미합니다."


나는 그것이 효과가있을 것이라고 확신하지만 좀 더 파이썬적인 것을 원한다
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.