Today I Learned/django

requests.post() 로 tmap API 에 위치정보 POST해서 결과 받아오기

하나719 2023. 10. 11. 16:39
반응형

참고 링크

https://tmap-public-skopenapi.readme.io/reference/%EB%8C%80%EC%A4%91%EA%B5%90%ED%86%B5-%EC%9A%94%EC%95%BD%EC%A0%95%EB%B3%B4-api

 

대중교통 요약정보 API

/ title [s] /.App .rm-Guides header h1, .App .rm-ReferenceMain header h1, .App .rm-Changelog header h1 {color:#3b454e; font-size:32px;}.headline-container21aRBSn8Bqg6 .excerptT2m-MzSJGRK7 {font-size:18px;}h2.heading.heading .heading-text {font-size:22px; l

tmap-public-skopenapi.readme.io

 

최근 진행하고 있는 프로젝트에서 지도 API를 사용하고 있는데, 카카오에서는 경로 API를 제공해주지 않았습니다.

구글은 유료이고 찾아보니 tmap에서 하루 10건 무료로 사용이 가능했습니다^^

근데 로컬에서 테스트할때 예제에 있는 API키로 작동이 잘 돼서 해당 API키로 테스트를 진행했습니다.

 

위 링크에서 원하는 언어를 선택하면 예제 코드가 나오는데, 

payload 객체와 headers 객체에 정보를 담아서 tmap 에 post 하고 결과를 받아옵니다.

 

requests.post() 함수를 호출하면, 서버로부터의 응답을 나타내는 Response 객체가 반환됩니다.

이 Response 객체는 HTTP 응답에 포함된 여러 정보를 담고 있습니다

  • .status_code: HTTP 상태 코드 (예: 200, 404 등)
  • .headers: HTTP 응답 헤더
  • .text: 서버에서 보낸 응답 본문을 문자열로 표현한 것
  • .content: 서버에서 보낸 응답 본문을 바이트열로 표현한 것
  • .json(): JSON 형식의 응답 본문을 파이썬 객체로 변환한 것 (응답 본문이 JSON 형식일 때 사용 가능

데이터를 파이썬 객체 형태로 변환해주면 for문을 사용해서 원하는 컬럼의 정보만 뽑아올 수 있기 때문에 .json()을 활용했습니다.

 

tmap API를 사용해서 원하는 호출하여 리스트에 결과값을 저장하는 함수 입니다. 

@login_required
def plan_map(request, pk):
    plan = get_object_or_404(Plan, pk=pk)

    # UserLocation 객체들을 가져옵니다. 
    user_locations = UserLocation.objects.filter(#원하는 조건)

    # 경로 계산
    url = "https://apis.openapi.sk.com/transit/routes/sub"
    headers = {
        "accept": "application/json",
        "content-type": "application/json",
        "appKey": "발급받은 API key",
    }
    
    # 결과 dict를 저장할 리스트
    user_result = []
    
    for item in user_locations:
        user_info = {}
        # 목적지와 출발지가 같을 경우 
        if item.longitude == plan.longitude and item.latitude == plan.latitude:
            user_info["user"] = item.user.username
            user_info["distance"] = 0
            user_info["time"] = 0
            user_result.append(user_info)
		# 목적지와 출발지가 다를 경우 
        else:
            payload = {
                "startX": item.longitude, 
                "startY": item.latitude,
                "endX": plan.longitude,
                "endY": plan.latitude,
                "format": "json",
                "count": 1, #최대 20개까지 받아올 수 있는데 한개로 지정
                "searchDttm": "202310101200",
            }
            
            response = requests.post(url, json=payload, headers=headers)
            data = response.json()

            user_info["user"] = item.user.username
            user_info["distance"] = (
                data["metaData"]["plan"]["itineraries"][0]["totalDistance"] / 1000
            )
            user_info["time"] = (
                data["metaData"]["plan"]["itineraries"][0]["totalTime"] / 60
            )

            user_result.append(user_info)

    return render(
        request,
        "plan/plan_map.html",
        {
            "plan_lat": plan.latitude,
            "plan_lng": plan.longitude,
            "result": user_result,
        },
    )

* 결과화면 

왼쪽은 카카오 지도 API로 구현하였고 우측에 남은거리, 남은시간은 tmap API로 구현하였습니다. 

이 작업을 하면서 API를 통해 데이터를 주고받을때 데이터핸들링과  Response 객체를 다루는 방법에 대해서 알아볼 수 있었습니다. 

샘플 코드에는 정적인 데이터 1가지만 들어있었는데, 실제 db에 있는 값을 여러개 전달해서 받아와야했습니다.

for문으로 효율적으로 원하는 데이터만 뽑아오기위해 Response.json() 데이터가 어떤 형태로 들어 있는지 하나하나 살펴보면서 데이터를 다루는 연습을 해볼 수 있어서 좋았습니다. 

반응형