파이썬에서 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.