Requests: Amazon S3에 λŒ€ν•œ 'PUT' μ‹€νŒ¨

에 λ§Œλ“  2015λ…„ 07μ›” 10일  Β·  4μ½”λ©˜νŠΈ  Β·  좜처: psf/requests

Python μš”μ²­μ„ μ‚¬μš©ν•˜μ—¬ Amazon S3에 νŒŒμΌμ„ μ—…λ‘œλ“œν•˜λ €κ³  ν•©λ‹ˆλ‹€(Python은 v2.7.9이고 μš”μ²­μ€ v2.7μž„). μ™„λ²½ν•˜κ²Œ μž‘λ™ν•˜λŠ” curl λͺ…령을 λ”°λ₯΄μ‹­μ‹œμ˜€.

curl --request PUT --upload-file img.png https://mybucket-dev.s3.amazonaws.com/6b89e187-26fa-11e5-a04f-a45e60d45b53?Signature=Ow%3D&Expires=1436595966&AWSAccessKeyId=AQ

κ·ΈλŸ¬λ‚˜ μš”μ²­μ— λŒ€ν•΄ λ™μΌν•œ μž‘μ—…μ„ μ‹œλ„ν•˜λ©΄ λ‹€μŒ 였λ₯˜μ™€ ν•¨κ»˜ 403으둜 μ‹€νŒ¨ν•©λ‹ˆλ‹€.

<Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>

λ‚΄κ°€ μ‹œλ„ν•œ 것은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

url = https://mybucket-dev.s3.amazonaws.com/6b89e187-26fa-11e5-a04f-a45e60d45b53?Signature=Ow%3D&Expires=1436595966&AWSAccessKeyId=AQ
headers = {'Content-Length': '52369', 'Host': 'mybucket-dev.s3.amazonaws.com', 'Expect': '100-continue', 'Accept': '*/*', 'User-Agent': 'curl/7.37.1'}
payload={'Expires': '1436595966', 'AWSAccessKeyId': 'AQ', 'Signature': 'Ow%3D'}

requests.put(url, files={'file': base64_encoded_image})
requests.put(url, files={'upload_file': base64_encoded_image})
requests.put(url, files={'file': base64_encoded_image}, headers=headers)
requests.put(url, files={'file': base64_encoded_image}, headers=headers, data=payload)

λͺ¨λ‘ λ™μΌν•œ 였λ₯˜λ‘œ μ‹€νŒ¨ν•©λ‹ˆλ‹€. μžμ„Έν•œ 정보 ν‘œμ‹œ λͺ¨λ“œμ˜ 컬은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

* Hostname was NOT found in DNS cache
*   Trying 54.231.168.134...
* Connected to mybucket-dev.s3.amazonaws.com (54.231.168.134) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
* Server certificate: *.s3.amazonaws.com
* Server certificate: VeriSign Class 3 Secure Server CA - G3
* Server certificate: VeriSign Class 3 Public Primary Certification Authority - G5
> PUT /6b89e187-26fa-11e5-a04f-a45e60d45b53?Signature=Ow%3D&Expires=1436595966&AWSAccessKeyId=AQ HTTP/1.1
> User-Agent: curl/7.37.1
> Host: mybucket-dev.s3.amazonaws.com
> Accept: */*
> Content-Length: 52369
> Expect: 100-continue
>
< HTTP/1.1 100 Continue
* We are completely uploaded and fine
< HTTP/1.1 200 OK
< x-amz-id-2: 5lLCQ3FVrTBg2vkyk44E+MecQJb2OGiloO0+2pKePtxPgZptKECNlUyYN43sl4LBNe9f8idh/cc=
< x-amz-request-id: 636A24D53DEB5215
< Date: Fri, 10 Jul 2015 12:04:44 GMT
< ETag: "5802130d4320b56a72afe720e2c323a7"
< Content-Length: 0
* Server AmazonS3 is not blacklisted
< Server: AmazonS3
<
* Connection #0 to host mybucket-dev.s3.amazonaws.com left intact

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

κ·Έλž˜μ„œ 랜덀으둜 이미지λ₯Ό λ§Œλ“€μ–΄μ„œ

curl --request PUT --upload-file img.png https://httpbin.org/put

curl이 λ‚΄κ°€ μ˜ˆμƒν•œ 것과 μ •ν™•νžˆ μΌμΉ˜ν•˜λŠ”μ§€ ν™•μΈν•˜κΈ° μœ„ν•΄. νŒŒμΌμ„ μ›μ‹œ λ°μ΄ν„°λ‘œ μ—…λ‘œλ“œν•©λ‹ˆλ‹€.

μš”μ²­μ˜ files= λ§€κ°œλ³€μˆ˜λŠ” μ›μ‹œ 데이터 μ—…λ‘œλ“œκ°€ μ•„λ‹ˆλΌ multipart/form-data μ—…λ‘œλ“œλ₯Ό μˆ˜ν–‰ν•©λ‹ˆλ‹€. μš”μ²­μ—μ„œ λ™μΌν•œ λ™μž‘μ„ λ³΅μ œν•˜λ €λ©΄ λ‹€μŒ μž‘μ—…λ§Œ ν•˜λ©΄ λ©λ‹ˆλ‹€.

with open('img.png', 'rb') as data:
    requests.put(url, data=data)

μš”μ²­μ€ μ½˜ν…μΈ  길이 및 기타 λͺ¨λ“  섀정을 μ²˜λ¦¬ν•©λ‹ˆλ‹€.

λͺ¨λ“  4 λŒ“κΈ€

음, 1λ‹¨κ³„λŠ” Expect: 100 Continue λ³΄λ‚΄λŠ” 것을 ν”Όν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. μš°λ¦¬λŠ” 그듀을 μ œλŒ€λ‘œ μ²˜λ¦¬ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. λ˜ν•œ μžμ‹ μ˜ Content-Length 헀더λ₯Ό 보내지 λ§ˆμ‹­μ‹œμ˜€. μš”μ²­μ— 따라 μ²˜λ¦¬λ©λ‹ˆλ‹€.

μ§„μ§œ λ¬Έμ œλŠ” μ—…λ‘œλ“œκ°€ λ©€ν‹°νŒŒνŠΈ/폼 인코딩이 될 것이라고 μƒκ°ν•˜μ§€λ§Œ curl이 νŒŒμΌμ„ 직접 μ—…λ‘œλ“œν•œλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. μ‹œλ„: requests.put(url, data=open('img.png', 'rb'))

κ·Έλž˜μ„œ 랜덀으둜 이미지λ₯Ό λ§Œλ“€μ–΄μ„œ

curl --request PUT --upload-file img.png https://httpbin.org/put

curl이 λ‚΄κ°€ μ˜ˆμƒν•œ 것과 μ •ν™•νžˆ μΌμΉ˜ν•˜λŠ”μ§€ ν™•μΈν•˜κΈ° μœ„ν•΄. νŒŒμΌμ„ μ›μ‹œ λ°μ΄ν„°λ‘œ μ—…λ‘œλ“œν•©λ‹ˆλ‹€.

μš”μ²­μ˜ files= λ§€κ°œλ³€μˆ˜λŠ” μ›μ‹œ 데이터 μ—…λ‘œλ“œκ°€ μ•„λ‹ˆλΌ multipart/form-data μ—…λ‘œλ“œλ₯Ό μˆ˜ν–‰ν•©λ‹ˆλ‹€. μš”μ²­μ—μ„œ λ™μΌν•œ λ™μž‘μ„ λ³΅μ œν•˜λ €λ©΄ λ‹€μŒ μž‘μ—…λ§Œ ν•˜λ©΄ λ©λ‹ˆλ‹€.

with open('img.png', 'rb') as data:
    requests.put(url, data=data)

μš”μ²­μ€ μ½˜ν…μΈ  길이 및 기타 λͺ¨λ“  섀정을 μ²˜λ¦¬ν•©λ‹ˆλ‹€.

곡μž₯! 정말 κ°μ‚¬ν•©λ‹ˆλ‹€ μ—¬λŸ¬λΆ„ :dancer: :smile:

zip νŒŒμΌμ„ μ‚¬μš©ν•˜μ—¬ λ‹€μŒκ³Ό 같은 λ‹¨μ„œλ₯Ό μ–»μŠ΅λ‹ˆλ‹€. (requests-2.13.0)

with open('default.zip', 'rb') as data:
    requests.put(url, data=data)

μ‚°μΆœ:

C:\svn\libraries\cpp>python req_put.py default.zip
MD5: 5dc0658d93e942fa7d1fa443e04bba83
SHA1: 18e7980d9d9ac544ac3e684a4d051932c3a3a336
Traceback (most recent call last):
  File "req_put.py", line 102, in <module>
    resp = requests.put(uri,  headers=headers, data=data) # data=data , params=payload)
  File "C:\Python27\lib\site-packages\requests\api.py", line 124, in put
    return request('put', url, data=data, **kwargs)
  File "C:\Python27\lib\site-packages\requests\api.py", line 56, in request
    return session.request(method=method, url=url, **kwargs)
  File "C:\Python27\lib\site-packages\requests\sessions.py", line 488, in request
    resp = self.send(prep, **send_kwargs)
  File "C:\Python27\lib\site-packages\requests\sessions.py", line 609, in send
    r = adapter.send(request, **kwargs)
  File "C:\Python27\lib\site-packages\requests\adapters.py", line 473, in send
    raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', error(10054, 'An existing connection was forcibly closed by the remote host'))

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰