일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- DIF_SR
- session-basedRecommendation
- jsonl
- decimal error
- pandas
- Cast
- Convert
- vscode
- Visualization
- github2FA
- 텐서플로자격증
- MatrixFactorization
- 지도시각화
- Python
- ExplicitData
- iterrows
- str.replace
- Colab
- VScodeNotResponding
- jsonlines
- sshtunnel
- numpy.bool
- wordembedding
- BloombergMarketConcepts
- implicitData
- MySQL
- TensorflowDeveloperCertificate
- json
- LatentFactorModel
- gluonnlp
- Today
- Total
garret
[Python] requests, MultipartEncoder 라이브러리로 REST API 호출 본문
이전까진 postman을 통한 rest api 호출로 값을 확인했었다.
하지만, 최근 실제 rest api를 python으로 호출해 사용할 일이 생겨서 REST API 호출하는 과정을 시행착오 포함해 모두 정리해보았다.
앞 2가지는 실패한 것들의 원인을 적어놓았고, 마지막은 성공한 코드를 적어놓았으니,
급한 사람은 마지막 시도를 참고할 것.
첫번째 시도 [실패]
구글링해서 가장 먼저 나온 블로그를 참고해서 아래처럼 시도해보았다.
#예시 코드
import requests
import json
def send_api(path, method):
API_HOST = "http://www.example.com"
url = API_HOST + path
headers = {
'Authorization': 'Basic #####',
'Username': 'aaa',
'Password': '1234',
'Content-Type': 'application/json'}
body = {
"key1": "value1"
}
try:
if method == 'GET':
response = requests.get(url, headers=headers)
elif method == 'POST':
response = requests.post(url, headers=headers, data=json.dumps(body, ensure_ascii=False, indent="\t"))
print("response status %r" % response.status_code)
print("response text %r" % response.text)
except Exception as ex:
print(ex)
# 호출 예시
send_api("/test", "POST")
400 에러가 발생하면서 response가 안오는 오류 발생
두번째 시도 [실패]
포스트맨을 확인해보니, Content-Type이 multipart/form-data;로 되어 있는 것을 확인.
multipart/form-data를 처리하기 위해서는
requests_toolbelt.multipart.encoder 라이브러리의 MultipartEncoder가 필요하다.
import requests
import json
from requests_toolbelt.multipart.encoder import MultipartEncoder
def send_api(path, method):
API_HOST = "http://www.example.com"
url = API_HOST + path
headers = {
'Authorization':'Basic #####',
'Username': 'aaa',
'Password':'1234',
'Content-Type': 'multipart/form-data; boundary=<calculated when request is sent>'
}
multipart_data = MultipartEncoder(
fields={
'key': 'value'
}
)
try:
if method == 'GET':
response = requests.get(url, headers=headers)
elif method == 'POST':
response = requests.post(url, headers=headers, data=multipart_data)
print("response status %r" % response.status_code)
print("response text %r" % response.text)
except Exception as ex:
print(ex)
# 호출 예시
send_api("/test", "POST")
MultipartEncoder 추가 결과
내가 입력한 value값이 아니라, value 값에 '\\r\\n--#####' 이상한 string이 추가로 붙어서 response가 안오는 오류 발생
이 string이 왜 붙어서 출력되는지 아무리 검색해도 원인을 찾을 수 없어서, chatgpt한테 마지막으로 물어봤더니,
MultipartEncoder의 delimiter일 수도 있다는 답변이 나왔다!!! (Thanks chatgpt!!)
즉, MultipartEncoder를 사용할 때,
boundary 매개변수를 설정하여 delimiter 문자열을 지정하지 않으면,
무작위로 생성된 delimiter 문자열이 사용된다고 한다.
세번째 시도 [성공!]
Content-Type에 지정된 boundary를 MultipartEncoder의 boundary 매개변수에 똑같이 작성해주었다.
import requests
import json
from requests_toolbelt.multipart.encoder import MultipartEncoder
def send_api(path, method):
API_HOST = "http://www.example.com"
url = API_HOST + path
headers = {
'Authorization':'Basic #######',
'Username': 'aaa',
'Password':'1234',
'Content-Type': 'multipart/form-data; boundary=<calculated when request is sent>'
}
multipart_data = MultipartEncoder(
fields={
'key': 'value'
}, boundary = '<calculated when request is sent>'
)
try:
if method == 'GET':
response = requests.get(url, headers=headers)
elif method == 'POST':
response = requests.post(url, headers=headers, data=multipart_data)
print("response status %r" % response.status_code)
print("response text %r" % response.text)
except Exception as ex:
print(ex)
# 호출 예시
send_api("/test", "POST")
이랬더니 REST API 호출 성공!
결론
header의 ‘Content-Type’이 ‘multipart/form-data’로 되어 있으면 MultipartEncoder를 사용해야 하고, 이때 boundary매개변수에 delimiter 지정해줘야 한다.
Reference
'Programming > Python' 카테고리의 다른 글
[Python] pandas.Series.str.replace 함수 (0) | 2023.07.05 |
---|---|
[Python] pandas.DataFrame.dropna() 함수 (0) | 2023.06.21 |
[Python, 환경설정] conda에서 python 가상환경 생성 (0) | 2023.06.14 |
[Python] pandas.DataFrame.select_dtypes 함수 (0) | 2023.06.13 |
[Python] pandas.DataFrame.sample() 함수 (0) | 2023.06.09 |