programing

Python 요청:JSON과 파일을 단일 요청으로 게시

minecode 2023. 3. 26. 12:45
반응형

Python 요청:JSON과 파일을 단일 요청으로 게시

파일에 대한 자세한 내용을 담은 JSON 문자열과 함께 파일을 업로드하기 위해 API 호출이 필요합니다.

이를 위해 python requests lib를 사용하려고 합니다.

import requests

info = {
    'var1' : 'this',
    'var2'  : 'that',
}

data = json.dumps({
    'token' : auth_token,
    'info'  : info,
})

headers = {'Content-type': 'multipart/form-data'}

files = {'document': open('file_name.pdf', 'rb')}

r = requests.post(url, files=files, data=data, headers=headers)

그러면 다음 오류가 발생합니다.

    raise ValueError("Data must not be a string.")
 ValueError: Data must not be a string

요청에서 '파일'을 제거하면 작동합니다.
요청에서 '데이터'를 삭제하면 동작합니다.
데이터를 JSON으로 인코딩하지 않으면 동작합니다.

이 때문에 JSON 데이터와 파일을 같은 요청으로 보낸 것이 에러라고 생각합니다.

어떻게 해야 할지 생각나는 거 없어?

멀티파트 POST-Request의 일부로 JSON을 보내는 방법 스레드를 참조하십시오.

콘텐츠 유형 헤더를 직접 설정하지 말고 pyrequests에 맡겨 생성하십시오.

def send_request():
    payload = {"param_1": "value_1", "param_2": "value_2"}
    files = {
        'json': (None, json.dumps(payload), 'application/json'),
        'file': (os.path.basename(file), open(file, 'rb'), 'application/octet-stream')
    }

    r = requests.post(url, files=files)
    print(r.content)

json을 사용하여 인코딩하지 마십시오.

import requests

info = {
    'var1' : 'this',
    'var2'  : 'that',
}

data = {
    'token' : auth_token,
    'info'  : info,
}

headers = {'Content-type': 'multipart/form-data'}

files = {'document': open('file_name.pdf', 'rb')}

r = requests.post(url, files=files, data=data, headers=headers)

이 섹션은 다른 폼 데이터 섹션이 되므로 반드시 원하는 섹션이 아닐 수 있습니다.

데이터와 파일을 모두 멀티파트 인코딩 파일로 전송할 수 없다고 생각하기 때문에 데이터도 "파일"로 만들어야 합니다.

files = {
    'data' : data,
    'document': open('file_name.pdf', 'rb')
}

r = requests.post(url, files=files, headers=headers)

사용하고 있습니다.requests==2.22.0

저는 아래 코드가 작동했습니다.

import requests


data = {
    'var1': 'this',
    'var2': 'that'
}

r = requests.post("http://api.example.com/v1/api/some/",
    files={'document': open('doocument.pdf', 'rb')},
    data=data,
    headers={"Authorization": "Token jfhgfgsdadhfghfgvgjhN"}. #since I had to authenticate for the same
)

print (r.json())

Facebook Messenger API 송신을 위해 payload 사전의 값을 모두 문자열로 변경하였습니다.그러면 payload를 통과시킬 수 있습니다.data파라미터를 지정합니다.

import requests

ACCESS_TOKEN = ''

url = 'https://graph.facebook.com/v2.6/me/messages'
payload = {
        'access_token' : ACCESS_TOKEN,
        'messaging_type' : "UPDATE",
        'recipient' : '{"id":"1111111111111"}',
        'message' : '{"attachment":{"type":"image", "payload":{"is_reusable":true}}}',
}
files = {'filedata': (file, open(file, 'rb'), 'image/png')}
r = requests.post(url, files=files, data=payload)

1. 요청서 발송

import json
import requests

cover   = 'superneat.jpg'
payload = {'title': 'The 100 (2014)', 'episodes': json.dumps(_episodes)}
files   = [
            ('json', ('payload.json', json.dumps(payload), 'application/json')),
            ('cover', (cover, open(cover, 'rb')))
          ]
r       = requests.post("https://superneatech.com/store/series", files=files)

print(r.text)

2. 요청 접수

JSON 데이터를 파일로 받아 내용을 받아 계속 진행합니다.

레퍼런스: 여기를 표시하다

기타 정보:

files = {
    'document': open('file_name.pdf', 'rb')
}

이것은, 파일이 스크립트가 있는 디렉토리와 같은 디렉토리에 있는 경우에만 동작합니다.

다른 디렉토리의 파일을 추가하는 경우는, 다음의 조작을 실시합니다.

files = {
    'document': open(os.path.join(dir_path, 'file_name.pdf'), 'rb')
}

여기서 dir_path는 'file_name.pdf' 파일이 있는 디렉토리입니다.

그러나 여러 개의 PDF를 보내려면 어떻게 해야 합니까?

필요한 파일 목록을 반환하는 커스텀 함수를 만들 수 있습니다(이 경우 확장자가 .pdf인 파일만 반환할 수 있습니다).서브디렉토리의 파일도 포함됩니다(재귀적으로 파일을 검색합니다).

def prepare_pdfs():
    return sorted([os.path.join(root, filename) for root, dirnames, filenames in os.walk(dir_path) for filename in filenames if filename.endswith('.pdf')])

그러면 다음과 같이 할 수 있습니다.

my_data = prepare_pdfs()

간단한 루프를 사용하면:

for file in my_data:

    pdf = open(file, 'rb')

    files = {
        'document': pdf
    }

    r = requests.post(url, files=files, ...)

언급URL : https://stackoverflow.com/questions/19439961/python-requests-post-json-and-file-in-single-request

반응형