2012-04-06 2 views
19

저는이 방법으로 파일을 다운로드하는 방법을 알고있었습니다 - key.generate_url (3600).boto 라이브러리로 Amazon S3에 파일을 업로드 할 임시 URL을 생성하는 방법은 무엇입니까?

업로드하려고 할 때 : key.generate_url (3600, method = 'PUT'), URL이 작동하지 않았습니다. 나는 들었다 : "우리가 계산 한 요청 서명이 당신이 제공 한 서명과 일치하지 않습니다. 당신의 키와 서명 방법을 확인하십시오."

generate_url (method = 'PUT') 함수 사용 방법은 boto 홈페이지에 예제 코드가 없습니다. 여기에 업로드하는 데 사용하는 방법을 알고있는 사람이 있습니까? 어떻게 업로드 파일의 경로에 대한 매개 변수를 설정하려면?

+0

? 새 파일을 만들려면'PUT'이 아닌'POST'를 사용해야합니다. – vartec

+0

@vartec : "새 파일"이란 무엇입니까? 필자의 경우 때때로 새 버킷을 특정 버킷에 업로드해야 할 때가 있으며 때로는 이전 키를 덮어 쓸 필요가 있습니다. 그래서 'PUT'과 'POST'에 대한 코드 예제가 필요하다고 생각합니다. –

답변

40

나는 이것을 실험 해보기에 약간의 시간이 걸렸고 여기에 내가 찾은 것이있다.

>>> import boto 
>>> c =boto.connect_s3() 
>>> fp = open('myfiletoupload.txt') 
>>> content_length = len(fp.read()) 
>>> c.generate_url(300, 'PUT', 'test-1332789015', 'foobar', headers={'Content-Length': str(content_length)}, force_http=True) 
'http://test-1332789015.s3.amazonaws.com/foobar?Signature=oUARG45mR95utXsiQYRJNiCI4x4%3D&Expires=1333731456&AWSAccessKeyId=AKIAJOTCCJRP4C3NSMYA&Content-Length=16' 

나는 다음과 같이 해당 URL에 파일을 넣어 컬을 사용할 수 있었다 :
$ curl --request PUT --upload-file myfiletoupload.txt "http://test-1332789015.s3.amazonaws.com/foobar?Signature=oUARG45mR95utXsiQYRJNiCI4x4%3D&Expires=1333731456&AWSAccessKeyId=AKIAJOTCCJRP4C3NSMYA&Content-Length=16" 

이 버킷에 업로드되는 파일에 결과. 따라서, 가능할 것으로 보입니다. content-md5 값을 계산하여 헤더에 포함시킬 수 있는지 알아야 할 것입니다. 그렇다면 컬을 가져 와서 헤더를 보내는 방법도 알아야합니다. 또한 HTTP보다는 HTTPS를 통해이 작업을 수행 할 수 있어야하지만 시도하지는 않았습니다.

+0

정말 고마워요! –

+2

이 답변의'headers' 인수가 작동하지 않습니다. 업로드 할 때 '서명 불일치'오류가 발생합니다. 나중에 파일을 가져올 때 응답 *에 헤더 *를 지정하려면'response_headers'를 사용하고'response-content-type' 등의 필드를 사용해야합니다. – MLister

+0

Google Cloud Storage에서 테스트되었지만 실패했습니다. 이 질문을 한 번보세요. 감사. http://stackoverflow.com/questions/38938203/django-heroku-boto-direct-file-upload-to-google-cloud-storage –

8

이것은 garnaat의 답변에 대한 후속 조치입니다.

저는 자격 증명이있는 서명 된 URL 서버 쪽을 생성하고 있으며, 클라이언트가 콘텐츠를 직접 업로드 할 수 있도록 클라이언트에 전달합니다. 클라이언트가 임의 크기의 파일을 업로드 할 수있을만큼 충분히 신뢰하지만 보안 토큰을 제공하기에 충분하지 않습니다. 클라이언트가 요청 내용의 일부로 콘텐츠의 크기를 알리는 것을 피하고 싶었습니다. 그러므로 내 후속 답변.

헤더에 컨텐츠 길이를 지정하거나 force_http = True를 지정하지 않고 PUT 메소드에 대한 서명 된 URL을 얻을 수있었습니다. garnaat의 answere에로 : BOTO 2.31.1를 사용

다음

>>> import boto 
>>> c =boto.connect_s3() 

대신 내가 사용 :

https://s3_location/bucket_name/s3_key?Signature=Ew407JMktSIcFln%2FZe00VroCmTU%3D&Expires=1405647669&AWSAccessKeyId=kM__pEQo2AEVd_Juz4Qq 
:

>>> temp_url = c.generate_url(seconds_available, 'PUT', bucket_name, s3_key) 

이 다음과 같은 형태의 URL을 생성

나는 컬을 사용하여 파일을 올릴 수있었습니다 :

>>> os.system('curl --request PUT --upload-file true_measure/test_files/test_file_w_content.txt "'+temp_url+'"') 

일반적으로 python requests을 사용하여 테스트 및 디버그를 작성했기 때문에이 작업을 수행하는 데 어려움이있었습니다. 그러나 나는 그것을 사용하려고 시도 할 때 인증 실패를받습니다. 요청을 사용하여 서명 된 URL을 생성 한 boto 중 하나에 파일을 저장하려고합니다. 필자는 이것을 완전히 디버깅하지는 못했지만 요청이 컬이 생성하는 것과 비교할 때 몇 가지 추가 헤더를 추가하기 때문인 것으로 의심됩니다.

나는이 후속 답변이 내가 겪은 디버깅 통증을 다른 사람에게 안겨주기를 바랍니다.

17

다음은 boto3에서 보이는 것입니다 (버전 1.2.3에서 테스트 됨).

첫째, s3.generate_presigned_url 방법으로 presigned URL을 생성 : S3에

>>> import boto3 
>>> s3 = boto3.client('s3') 
>>> s3.generate_presigned_url('put_object', Params={'Bucket':'YourBucket', 'Key':'YourKey'}, ExpiresIn=3600, HttpMethod='PUT') 
u'https://s3-ap-northeast-1.amazonaws.com/YourBucket/YourKey?AWSAccessKeyId=AKIAXXXXXXXXXXXXXXXX&Expires=1451061671&Signature=%2FtyAyCd5vrp13p%2FqLdoPkox7yTM%3D' 

PUT입니다

$ curl \ 
    --request PUT \ 
    --upload-file path/to/file \ 
    "https://s3-ap-northeast-1.amazonaws.com/YourBucket/YourKey?AWSAccessKeyId=AKIAXXXXXXXXXXXXXXXX&Expires=1451061671&Signature=%2FtyAyCd5vrp13p%2FqLdoPkox7yTM%3D" 
+0

자격 증명 (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)을 어떻게 추가합니까? – CpILL

+1

@CpILL 환경 변수를 통해 자격 증명을 전달할 수 있습니다. 예 : $ export AWS_ACCESS_KEY_ID = AKIAIOSFODNN7EXAMPLE http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html#cli-environment – quiver

+0

감사합니다. –

9

다른 모든 답변을 파일 curl로 업로드됩니다 가정합니다 presigned URL로 정말 대부분의 파이썬 스크립트에서 편리하지 않습니다. 다음에, 미리 서명 된 URL이 boto3 생성되고 파일은 requests 라이브러리에 업로드 : 새 파일인가요

session = boto3.Session(aws_access_key_id="XXX", aws_secret_access_key="XXX") 
s3client = session.client('s3') 
url = s3client.generate_presigned_url('put_object', Params={'Bucket': 'mybucket', 'Key': 'mykey'}) 

requests.put(url, data=open("/path/to/file").read()) 
관련 문제