Python

Flight Deal

daylee de vel 2021. 6. 21. 19:25

5개월 전 Udemy Python API 토픽에서 진행한 프로젝트 "Flight Deal"
여행지 비행기 티켓 최저 가격을 설정해놓으면 이보다 낮은 가격이 떳을 때 메세지 알림을 보내주는 유용한 프로그램이다 :)

그런데...최근 Github 포트폴리오를 정리하다가 원본 파일을 삭제했다는 사실을 발견했다 ㅜㅜ
파이썬도 복습할 겸 처음부터 requirement를 보고 프로그램을 작성해봤다.

Program Requirements

  1. Use the Flight Search and Sheety API to populate your own copy of the Google Sheet with International Air Transport Association (IATA) codes for each city. Most of the cities in the sheet include multiple airports, you want the city code (not the airport code see here).
  2. Use the Flight Search API to check for the cheapest flights from tomorrow to 6 months later for all the cities in the Google Sheet.
  3. If the price is lower than the lowest price listed in the Google Sheet then send an SMS to your own number with the Twilio API.
  4. The SMS should include the departure airport IATA code, destination airport IATA code, departure city, destination city, flight price and flight dates. e.g.

강의 프로젝트 스타팅 파일에는 flight_search.py, flight_manager.py 등 용도에 따라 클래스를 나눠놓았다. 그런데 처음부터 object-oriented를 적용하며 자유자재로 코드를 작성하기 어려워 일단 main.py에 procedural code를 작성했다. 프로그램 작동을 확인하고 모듈을 나누는 방식으로 접근할 생각이다.

requests module

The requests module allows you to send HTTP requests using Python

이용한 APIs

이 프로그램은 Google Sheety와 Kiwi, Twillio API를 사용한다.

Struggles

1. Post, Put requests with json

문제: 파라미터의 형식에서 오류가 나서 sheet에 put이 안되는 상황.
해결책은 post method의 argument인 json은 dictionary 형식을 따름. '다음'의 sheety 데이터 형식을 파라미터로 가져오려면 key:value 페어를 중첩해서 넣어줘야 했음.('정상 작동' 참고)

다음

{'prices': [{'city': 'Paris',
             'iataCode': 'testing',
             'id': 2,
             'layoverLowestPrice': 664729}, ... ]}

오류

for city in sheet_data['prices']:
...
    params = {
         'iataCode': city['iataCode']
     }

정상 작동

for city in sheet_data['prices']:
...
    params = {
        "price": {
            "iataCode": city["iataCode"]
        }
    }

Starting with Requests version 2.4.2, you can use the json= parameter (which takes a dictionary) instead of data= (which takes a string) in the call:

관련 stackoverflow 포스트

final code

for city in sheet_data['prices']:
    id = city['id']
    params = {
        "price": {
            "iataCode": city["iataCode"]
        }
    }
    response = requests.put(
        url=f'{SHEETY_ENDPOINT}/{id}',
        json=params,
    )
    response.raise_for_status()
    print(response.text)

2. Get requests from Tequila with params

When to use params or json

Have a read of Requests Quickstart (https://docs.python-requests.org/en/master/user/quickstart/)
Use data={dictionary} for POST and PUT
Use json={dictionary} for POST and PUT to JSON encode your dictionary. (This changes the header "Content-Type": "application/json")
Use params={dictionary} to pass query ?key=value&... parameters as part of the URL
Use headers={dictionary} to pass secrets not visible in the URL
You can also use data="string", data=(tuple) and maybe others!
In the end it depends what the particular API accepts, and it's not always obvious what to use from reading the documentation. If one option doesn't work, try another 🤔

Endpoint의 주소뒤에 슬래쉬 주의해야함!!

ENDPOINT

location_endpoint = f"{TEQUILA_ENDPOINT}/locations/query"