프로그래밍/C, C++, Java, Python

[Python3] Python과 Node.js 사이의 JSON 통신

포도알77 2019. 7. 5. 10:13

[Client / python] <===http===> [node / Server]와 같이 Python이 클라이언트, Node.js가 서버일 때 두 프로그램간 HTTP 통신을 한다.

 

(1) Python 측에서는 "requests" 모듈을 이용해서 HTTP 요청을 송신하고 응답을 수신한다.
(2) 두 프로그램간 JSON으로 데이터를 교환한다.

- Client

import requests, json

data = {}
headers = {}
requests.post(url, data=json.dumps(data), headers=headers)

 

- Node

app.post('/abc',function(req,res,next){
  return res.json({success:true, msg:"good"});
});

 

 

사실 매우 간단한 예제이기 때문에 그리 큰 어려움 없이 데이터 교환을 할 수 있다?였으면 이 글 안썼지

막상 실행해보면 알겠지만, Node단에서 문제가 발생한다.

 

 Python의 requests.post 함수는 json과 data라는 두개의 매개변수를 사용하는데, data는 평문 그리고 json는 문자로 encoding된 값을 전달한다. 근데 문제는 json 매개변수에 dump된 문자열을 담으면 아래와 같이 Node에서 에러가 발생한다.

SyntaxError: Unexpected token s in JSON at position 0
at JSON.parse ()
at verify (/home/gseng/Desktop/server/server.js:44:24)) 
at /home/gseng/Desktop/server/node_modules/body-parser/lib/read.js:104:9
at invokeCallback (/home/gseng/Desktop/server/node_modules/raw-body/index.js:224:16)) 
at done (/home/gseng/Desktop/server/node_modules/raw-body/index.js:213:7)) 
at IncomingMessage.onEnd (/home/gseng/Desktop/server/node_modules/raw-body/index.js:273:7)) 
at emitNone (events.js:106:13)) 
at IncomingMessage.emit (events.js:208:7)) 
at endReadableNT (_stream_readable.js:1055:12)) 
at _combinedTickCallback (internal/process/next_tick.js:138:11))

 

 위의 에러는 post로 전달된 데이터가 형식에 맞지않아서 decoding시에 에러가 발생한 것이다. 위 문젠 아래와 같이 해결할 수 있다.

- 수정된 python 코드

import requests, json

data = {}
headers = {}
requests.post(url, json=data, headers=headers)

 아마도 data에 json으로 인코딩된 dictionary를 전달하면 한번더 인코딩하는 과정이 발생하면서 문제가 된 것 같다.

 

 

 아무튼 Python -> Node로의 통신이 정상적으로 되었으면, Node->Python으로 데이터 전송을 위해서는 아래와 같이 실행하면 된다.

import requests, json

data = {}
headers = {}

res = requests.post(url, json=data, headers=headers)
# HTTP CODE
print(res.status_code)
# HTTP 응답 원문
print(res.text)
# HTTP 요청 값
print(res.request, res.request.body, res.content)
# HTTP 응답 원문(JSON)을 디코딩하여 Dictionary로 반환
print(res.json())

 서버단 응답은 requests.post 함수의 반환값에 담겨있고, HTTP 응답 코드와 응답 원문을 확인할 수 있다.

특히, 위의 예에서 JSON으로 서버가 응답을 반환하면, res.text에 인코딩한 JSON을 담아보내므로, res.json()을 실행하여 서버 응답 값을 확인할 수 있다.

 

 

 여기서 res.text에 담긴 원문이 JSON이 아닌 경우도 있을 수 있으니, try-except 구문을 통해서 에러를 처리해주어야 한다. 내 경우는 서버의 실패 응답 { success:false, msg:"no good" }을 json 파싱에 실패했을 때, 담아서 반환했다.

try:
  result = res.json()
except Exception as e :
  result = { success : false, msg : "no good" }

 

페이스북으로 공유카카오톡으로 공유카카오스토리로 공유트위터로 공유URL 복사