>

TIL

오픈 API 이용하기

ekdud 2024. 9. 26. 14:43

📑

    Open API 이용하기

    문화 공공데이터 광장에서 제공하는 오픈 API를 이용해보자. 🔗

    1. 오픈API 선택
    2. 활용신청
    3. 오픈API 키 발급(활용신청 후 즉시 이메일로 받을 수 있음)
    4. URL+오픈 API 키를 이용한 API 호출

     

     

    Open API URL 조합 예시

    요청URL + Service Key + 검색조건 값(파라미터)
    예)http://api.kcisa.kr/openapi/service/rest/meta16/getkopis01?serviceKey={서비스 키}&numOfRows=10&pageNo=1

     

     

    views.py

    from django.shortcuts import render
    from django.conf import settings
    from rest_framework import status
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from urllib.parse import urlencode
    from requests.exceptions import RequestException
    import requests
    
    
    
    class OpenApiView(APIView):
        def get(self, request, *args, **kwargs):
            base_url = f"https://api.odcloud.kr/api/15111405/v1/uddi:d8741b9c-f484-4ea8-8f54-bd21ab62de14"
    
            params = {
                "page": "int",  # 페이지 인덱스
                "perPage": "int",  # 세션당 요청레코드수
                "returnType": "JSON",
            }
            query_string = urlencode(params)
    
            full_url = f"{base_url}?{query_string}&serviceKey={settings.SERVICE_KEY}"
    
            response = requests.get(full_url)
            return Response(response.json(), status=status.HTTP_200_OK)
    
    
    class LocationListAPIView(APIView):
        def get(self, request, *args, **kwargs):
            base_url = f"https://api.odcloud.kr/api/15111405/v1/uddi:d8741b9c-f484-4ea8-8f54-bd21ab62de14"
    
            # page = request.query_params.get("page")
            # per_page = request.query_params.get("perPage")
            page = 1
            per_page = 1000
            all_data = []
    
            while True:
                params = {
                    "page": page,  # 페이지 인덱스
                    "perPage": per_page,  # 세션당 요청레코드수
                    "returnType": "JSON",
                }
                query_string = urlencode(params)
                full_url = f"{base_url}?{query_string}&serviceKey={settings.SERVICE_KEY}"
    
                try:
                    response = requests.get(full_url, timeout=10)  # 10초 타임아웃 설정
                    response.raise_for_status()  # HTTP 에러 발생 시 예외 발생
                    data = response.json()
                except RequestException as e:
                    return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    
                if not data['data']:
                    break
    
                all_data.extend(data['data'])
                page += 1
                
            sorted_data = sorted(all_data, key=lambda x: x['제목'])
            
            return Response(sorted_data, status=status.HTTP_200_OK)
    
    
    class LocationSearchAPIView(APIView):
        def get(self, request, *args, **kwargs):
            base_url = "https://api.odcloud.kr/api/15111405/v1/uddi:d8741b9c-f484-4ea8-8f54-bd21ab62de14"
            service_key = settings.SERVICE_KEY
    
            page = 1
            per_page = 1000  # 한 번에 1000개씩 요청
            keyword = request.query_params.get("keyword", "").lower()
    
            all_data = []
    
            while True:
                params = {
                    "page": page,
                    "perPage": per_page,
                    "returnType": "JSON",
                }
                query_string = urlencode(params)
                full_url = f"{base_url}?{query_string}&serviceKey={service_key}"
    
                try:
                    response = requests.get(full_url, timeout=10)  # 10초 타임아웃 설정
                    response.raise_for_status()  # HTTP 에러 발생 시 예외 발생
                    data = response.json()
                except RequestException as e:
                    return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    
                if not data['data']:
                    break
    
                all_data.extend(data['data'])
                page += 1
    
            # Filter the data based on the keyword
            if keyword:
                filtered_data = [
                    item for item in all_data 
                    if keyword in item['제목'].lower() 
                    or keyword in item['장소설명'].lower()
                    or keyword in item['장소명'].lower()
                    or keyword in item['미디어타입'].lower()
                    or keyword in item['장소타입'].lower()
                    or keyword in item['주소'].lower()
                ]
            else:
                filtered_data = all_data
    
            return Response(filtered_data)

     

     

     

    serviceKey는 secrets.json에 넣어놓고 settings에서 꺼내서 사용!

     

    settings.py

    secret_file = os.path.join(BASE_DIR, 'secrets.json')
    with open(secret_file, 'r') as f:
        secrets = json.loads(f.read())
    def get_secret(setting, secrets=secrets): #예외 처리를 통해 오류 발생을 검출합니다.
        try:
            return secrets[setting]
        except KeyError:
            error_msg = "Set the {} environment variable".format(setting)
            raise ImproperlyConfigured(error_msg)
            
    SERVICE_KEY = get_secret("SERVICE_KEY") # open_api

     

    secrets.json

    {
        "SECRET_KEY" : "django-insecure-vl*************",
        "EMAIL": "**********@gmail.com",
        "EMAIL_PASSWORD": "********",
        "SERVICE_KEY": "************************************"
    }