0

파이썬에서 요청이있는 REST API를 사용하여 일부 JSON과 함께 비디오 파일을 업로드하려고합니다.json으로 다중 업로드 보내기

다음은 요청에 대한 cURL의 예입니다.

curl -XPOST -i "https://io.cimediacloud.com/upload" \ 
-H "Authorization: Bearer ACCESS_TOKEN" \ 
-F [email protected] 
-F metadata="{ 'metadata' : { 'Resolution' : '1080p', 'Language' : 'English' },   
'workspaceId' : 'a585b641a60843498543597d16ba0108', 'folderId' : 
'a585b641a60843498543597d16ba0108' }" 

그리고 여기에 내 코드가 있습니다.

url = 'https://io.cimediacloud.com/upload' 
files = {'file': ('video.mp4', open('files/video.mp4', 'rb')), 
        } 
data = {'metadata': {'Resolution' : '1080p', 'Language' : 'English'}, 
     'workspaceId': your_workspace_id, 
     'folderId': folder_id,} 

r = session.post(url, files=files, data=data) 

실행하면 API 서버가 MissingOrInvalidFileName 오류를 반환합니다. 내 데이터 매개 변수를 생략하면 파일이 올바르게 업로드됩니다. 이 요청을하는 올바른 방법은 무엇입니까?

+0

기술적으로 CURL 명령은 JSON을 게시하지 않습니다. 형식이 유효하지 않습니다. 서버가 여전히 그것을 받아들이면 매우 관대 한 파서를 사용하고 있습니다. –

답변

2

파일 매개 변수는 curl 요청에서 filename이고 metadata 부분은 JSON으로 인코딩 된 문자열이어야합니다. 하나의 필드이고 중첩 된metadata 개체가 있습니다.

import json 

files = {'filename': ('video.mp4', open('files/video.mp4', 'rb')), 
metadata = { 
    'metadata': {'Resolution': '1080p', 'Language': 'English'}, 
    'workspaceId': your_workspace_id, 
    'folderId': folder_id 
} 
data = {'metadata': json.dumps(metadata)} 
r = session.post(url, files=files, data=data) 
+0

답장을 보내 주셔서 감사합니다. 그러나 제안 후에도 동일한 문제가 발생합니다./다른 점은 무엇입니까? – jahmezz

+1

@jahmezz 당신이'JSON.dumps()'대신에'str()'을 시도해 볼 수는 있습니다. 그 외에도 내 답변은 'curl'명령 샘플이 생성하는 것을 복제합니다. API에 대한 추가 설명서가 없으면 다른 말을 할 수 없습니다. –

+0

안녕하세요, 내 요청 본문을 인쇄 할 때 내 json 데이터가 파일에 업로드되기 전에 본문에 인쇄되고 있다는 것을 알았습니다. 요청 본문에 'Content-Disposition : form-data; name = "workspaceId"및 그 파일 자체 앞. 이게 받아 들여질 수 있니? @Martijn Pieters – jahmezz

1

최종적 해결 : wordspaceIdfolderId는 최 metadata 오브젝트 아닌 별도의 파라미터열쇠! 요청은 API가 파일 다음에 데이터를 필요로하는 동안 요청은 데이터와 함께 멀티 파트를 인코딩합니다.

@Martijn 모든 데이터를 튜플로 입력하는 Pieters의 솔루션은 거의 작동합니다. 유일한 문제는 이러한 방식으로 데이터를 설정하면 요청 유형의 콘텐츠 유형 헤더를 자동으로 설정하는 기능이 중단된다는 것입니다 (내 데이터는 content-type application/json이라고 생각합니다).

마지막으로 request-toolbelt의 MultipartEncoder를 사용하여 튜플을 사용하여 멀티 파트 본문을 주문하고 해당 인스턴스에 콘텐츠 유형을 저장합니다. 다음은 최종 작업 코드입니다.

m = MultipartEncoder([('filename', ('video.mp4', open('files/video.mp4', 'rb'))), 
         ('metadata', json.dumps(metadata))]) 

r = session.post(url, data=m, headers={'Content-Type': m.content_type}) 

마지막으로 작동합니다.