본문 바로가기
x

AI 파이프라인 연구 7 - 공중화장실 도우미 GPTS 만들기 1(FastAPI)

by Nomad3795 2024. 1. 16.
반응형

"서울시 공중 화장실 찾기 GPTS"

 

사용자 친화적이며 언젠가 한 번쯤은 누군가에게 도움이 될 수도 있는 GPTS를 만들어 보고자 했다.

살면서 그런 날이 올 지도 모른다. 생리 현상이 급한데 화장실이 없을 때가...

 

세상에 널린 게 화장실인데? 

상가에 있는 대부분의 화장실은 도어록이 걸려있다.

 

그러면 매장에 물어보면 되는데? 

그분들은 관리비를 내는 입장이니 대부분 자기 매장의 제품을 소비해 줘야 알려 주신다.

 

물론 이해한다. 

 

그렇다면

당장 바지에 뭔가 나올 것 같을 때!

인생 최대의 위기가 찾아오려고 할 때!

이 GPTS를 활용하면 된다!

 

Chat GPT Store에 "서울시 공중화장실 도우미"를 검색!

 

 

운이 좋다면 반경 1M , 아니 바로 1분 거리에 있는 공중화장실을 찾을지도 모른다.

(사실 편의점 가서 휴지 산 다음 화장실 비밀번호 물어보면  알려줍니다)

 

오늘은 이 GPTS를 만드는 과정을 공유해보고자 한다.

 

나도 개발언어에 대해서 정말 아무것도 모르는데 만들었다.

그냥 해당 과정을 따라 하기만 해도 완성할 수 있다.

 

 

준비물 : Chat GPT 4 , 서울시 공공 데이터, VSCode , SERPAPI KEY , GOOGLE CLOUD

 

0. 기본세팅 및 프로젝트 구조

우리가 지금부터 만들 공중 화장실 도우미 GPTS가 어떤 방식으로 작동하는지 부터 이해하고 시작해야 한다.

 

  • 사용자가 공중 화장실 도우미 GPTS에 현재 위치한 주소를 입력
  • 주소를 입력하면 GPTS가 해당 주소를 GoogleMapsApi서버 전송
  • GoogleMapsApi에서 지오코딩을 진행, 경도와 위도를 추출
  • 추출한 값을 GPTS에게 반환
  • GPTS가 추출값을 받으면 MyFastApi서버로 추출값(경도와 위도) 데이터 전송
  • MyFastApi서버에서 경도와 위도를 받으면 해당 경도와 위도를 기준으로 data.xlsx 파일의 데이터에서 가장 가까운 좌표를 찾는다
  • 이때 거리 계산 공식은 유클리드 계산식을 사용 (문과는 이런 이상한 거 이해하지 말고 그러려니 하자, 나도 문과)
  • MyFastApi 서버에서 찾은 데이터값을 GPTS로 전송
  • GPTS가 데이터값을 받으면 사용자에게 출력

 

 

1. 서울 열린 데이터 광장

-바탕화면 > my_fastapi_project > data 순서대로 폴더생성

모자이크된 폴더는 무시하세요

 

서울 열린데이터 광장 이미지 클릭

 

이미지를 클릭하면 이동합니다

 

 

-서울시 공중화장실 위치정보 (좌표계: WGS1984) 검색 (ITRF2000 버전은 x)

좌표계 데이터를 써야 위치를 찾을 수 있습니다.

 

 

 

-내려받기(csv)

 

 

 

-다운로드 완료 후 해당 파일을 data.xlsx로 변경 // data 폴더로 data.xlsx파일 이동

 

 

2. VsCode 실행

 

-유튜브에 "VSCODE 초기설정" 검색 // 파이썬 설치 ( 이 부분은 검색 후 따라 하세요)

-VSCODE 실행 후 단축키 Ctrl+N 단축키를 눌러주면 아직 저장되지 않은 untitled1.txt 파일이 생성된다.

-Ctrl + Shift + S를 입력해서 main.py로 저장

-저장 경로는 바탕화면에 생성한 my_fastapi_project

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

VSCODE에서

-Terminal > New Terminal 클릭

 

 

 

 

-터미널에 다음 명령어들을 입력

pip install fastapi[all]

pip install openpyxl

pip install uvicorn

pip install google-cloud-storage

 

 

 

 

 

 

 

 

 

 

pip install fastapi

 

pip install openpyxl

 

pip install uvicorn
pip install google-cloud-storage
 

 

-본문에 들어갈 코드 (터미널에 넣는 거 아닙니다. 본문에 넣으세요)

from fastapi import FastAPI
import openpyxl
import uvicorn
from google.cloud import storage
import io

app = FastAPI()

# 데이터를 저장할 리스트
data_list = []

def load_data_from_gcs():
    # 구글 클라우드 클라이언트 초기화
    client = storage.Client()
    bucket = client.get_bucket('구글 클라우드 버킷의 이름')

    # GCS에서 파일 로드
    blob = bucket.blob('클라우드 스토리지에 있는 data.xlsx 경로')
    data = blob.download_as_bytes()
    
    # openpyxl로 파일을 읽기 위해 BytesIO 사용
    wb = openpyxl.load_workbook(io.BytesIO(data))
    sheet = wb.active

    # 엑셀 시트의 데이터를 읽어와서 데이터 리스트에 저장
    for row in sheet.iter_rows(min_row=2, values_only=True):
        data = {
            "구명": row[1],
            "법정동명": row[2],
            "주지번": row[4],
            "부지번": row[5],
            "latitude": row[8],
            "longitude": row[9]
        }
        data_list.append(data)

# 애플리케이션 시작 시 데이터 로드
load_data_from_gcs()

@app.get("/get_data/")
async def get_data():
    return data_list

@app.post("/api/coordinates")
async def get_closest_toilet(latitude: float, longitude: float):
    # 가장 가까운 화장실 찾기
    closest_location = find_closest_location(latitude, longitude)

    if closest_location:
        info = f"가장 가까운 주소는 : {closest_location['구명']}({closest_location['법정동명']}){closest_location['주지번']}{closest_location['부지번']}"
    else:
        info = "가까운 화장실을 찾을 수 없습니다." 

    return {"message": info}

def find_closest_location(latitude, longitude):
    closest = None
    closest_distance = float("inf")
    
    for data in data_list:
        lat = float(data["latitude"])
        lon = float(data["longitude"])
        # 현재 위치와의 거리 계산
        distance = ((latitude - lat) ** 2 + (longitude - lon) ** 2) ** 0.5
        
        if distance < closest_distance:
            closest_distance = distance
            closest = data
    
    return closest

 

"구명": row[1],
        "법정동명": row[2],
        "주지번": row[4],
        "부지번": row[5],
        "latitude": row[8],
        "longitude": row[9]

 

엑셀 파일을 열어보면 제일 상단 열에 해당 명칭들이 있고 그 위치에 대한 값이다.

 

여기서 중요한 건

사람은 1이 첫 번째 시작점

컴퓨터는 0이 첫 번째 시작점

 

즉, 사람은 1~9까지 숫자가 있다면 1부터 시작하지만 [1,2,3,4,5,6,7,8,9]

컴퓨터는 0부터 시작하기 때문에 9가 10번째인 셈 [0,1,2,3,4,5,6,7,8,9]

 

이 코드는 유클리드 계산식을 코드로 짠 것

distance = ((latitude - lat) ** 2 + (longitude - lon) ** 2) ** 0.5

 

그 외 데이터 저장, 경로설정, 데이터 반환등의 내용이다.

 

 

 

-코드를 입력했으면 서버를 실행해야 한다. Ctrl+Shist+S로 my_fastapi_project로 저장 후에 터미널에 명령어 입력

 

cd C:\Users\dynam\바탕 화면\my_fastapi_project

(이건 경로 설정인데 그대로 붙여 넣지 말고 밑에 이미지 참고하세요)

 

 

 

 

 

 

 

 

 

 

 

main.py

cd C:\Users\dynam\바탕 화면\my_fastapi_project

cd <복사한 경로>

 

실행하면 경로가 변경되어 있을 것이다. 터미널에 다음 명령어 실행

uvicorn main:app --reload

 

 

입력 시 이런 화면이 뜨면 완성

 

 

여기까지 따라왔다면 당신은 로컬 API서버와 문서를 만든 것이다.

API는 일종의 메뉴판이라고 생각하면 된다.

(API , 로컬, 문서 이런 내용들이 궁금하다면 ChatGPT)

 

 

 

이제 거의 끝나간다. 

 

 

사실 이제부터 시작이다

 

 

 

3. Google Cloud Console

이미지를 클릭하면 페이지 이동

 

 

-구글 클라우드 콘솔 회원가입

-페이지 안내에 따라서 정보 입력

-새 프로젝트 생성

 

 

-햄버거 아이콘 클릭 후 Cloud Storage 클릭

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

-버킷 만들기 클릭

 

버킷 이름 지정 : 원하는 이름

데이터 저장 위치 선택 : region // seoul

객체 엑서스 제어 : 균일

객체 데이터 보호 : 원하는 옵션으로

 

버킷을 만들면 버킷 대시보드에 이런 상자가 생성됩니다.

 

 

-버킷 이름 클릭

 

-여기서 바탕화면에 있는 my_fastapi_project 폴더를 업로드할 수 있습니다.

하지만 지금은 업로드하지 마시고 추후 안내 시 업로드해주세요

 

Cloud Storage 서버에 저장하는 이유 :

GPTS를 완성하고 난 뒤 나만 사용한다 -> Cloud Storage 불필요 // 로컬 경로로 데이터 읽기 가능

GPTS를 완성하고 다른 사람들도 사용 할 수 있게 Public 으로 사용한다 -> Cloud Storage 필요

 

 

즉 , API서버로 좌표값을 보내서 data.xlsx의 데이터와 매칭해서 값을 찾아야 하지만 불특정 다수들은 개인 컴퓨터에 있는 로컬 경로에 진입이 불가능합니다.

 

vscode 환경 내에서도 추가 설치를 해줘야 합니다.-터미널에 해당 코드 입력

pip install google-cloud-storage

 

 

이제부터는 우리가 만들었던 API서버를 호스팅해야 합니다.

호스팅을 하는 이유:

인터넷 홈페이지 주소를 보면 http: 와 https: 가 있습니다.

s가 붙은건 SSL 보안 인증서가 설정되어 있다는 뜻입니다.

즉 , http: 는 신뢰할 수 없는 url 주소가 되는 겁니다.



테스트 결과로는

신뢰할 수 없는 url 주소는 GPTS와 연결이 되지 않았고, 된다고 하더라도

우리가 전에 만들었던 API서버(http://127.0.0.1:8000)와의 연결은 권장할 수 없습니다.



그래서 Googole Cloud  Platform을 선택했습니다.

Google storage 서비스 , 무료체험판 제공 , 호스팅 서비스까지 필요한건 다 지원이 됩니다.



Google Cloud CLI를 설치해서 Google Cloud sdk shell 에서 호스팅을 완료하고 나면 

새로운 URL주소를 받게 되고 SSL 인증서까지 설정이 완료됩니다.

 

-해당 이미지 클릭

이미지를 클릭하면 해당 링크로 이동합니다

 

 

-Windows 탭이 이미지와 같이 활성화되어있는지 확인 후 Google Cloud CLI 설치 프로그램 클릭

-다운로드한 설치파일 실행해서 프로그램 설치

 

 

-Chat GPT4 "FastAPI 애플리케이션을 Google App Engine에 호스팅 " 프롬프트 입력 

-Chat GPT4의 안내에 따라 진행

 

 

GPT의 설명이 이해가 어려울 수  있으니 디테일한 부분은 제가 설명하겠습니다.

 

-호스팅 하기 전에 my_fastapi_project 내에 새로운 파일 2개가 필요합니다.

(requirements.txt // app.yaml)

 

 

*requirements.txt

fastapi==0.105.0
uvicorn==0.25.0
openpyxl==3.1.2
gunicorn==21.2.0
google-cloud-storage==2.14.0

-----------------------------------------------------------------------------------

== 뒤에 숫자로 현재 버전이 몇인가를 명시해줘야 합니다.
그대로 복사 붙여넣기 하지 마시고 vscode에 들어간 뒤 해당 명령어들로 버전을 확인하세요

pip show fastapi
pip show uvicorn
pip show openpyxl
pip show gunicorn
pip show google-cloud-storage

 

 

*app.yaml

-VSCODE 실행 

-CTRL + N 입력

-본문에 해당 코드 입력

runtime: python39  # specify the Python version
entrypoint: gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app  # replace 'main' with your main module name if different

handlers:
- url: /.*
  script: auto
  secure: always

automatic_scaling:
  target_cpu_utilization: 0.65
  min_instances: 1
  max_instances: 5

-CTRL + SHIFT + N 입력 

-my_fastapit_project 폴더에 저장

 

아까 Google Cloud Storage 버킷에서 업로드를 진행하지 않았습니다. 이제 업로드해주시면 됩니다.

 

- windows 검색창에 "Google Cloud SDK Shell" 클릭

 

- 중간중간 제 안내와 다른 점이 있다면 ChatGPT를 활용하세요

( 프로젝트 선택 / 진행하시겠습니까? 등등)

(프로젝트 선택 시 우리는 이미 프로젝트를 생성한 것을 잊지 마세요)

 

- gcloud auth loginGoogle Cloud 입력 후 계정 인증

gcloud auth loginGoogle Cloud

 

- cd <app.yaml 경로> 입력

- cd app.yaml 경로

(경로 확인은 app.yaml 우클릭 > 속성)

 

- gcloud app deploy 입력

gcloud app deploy

 

여기까지 진행 완료 시 배포가 완료되어 SDK shell 화면에 새로 부여받은 URL 주소가 출력되어 있습니다. (완료)

해당 주소 까먹으면 찾기가 어려우니 바탕화면에 있는 my_fastapi_project에 텍스트파일로 저장하는 걸 권장합니다.

 

 

4. 문서 확인 및 엔드포인트 테스트

이제 우리가 만든 API서버는 http: 에서 https:로 설정 되었습니다.

 

-인터넷창을 하나 열어주고 해당 url을 입력해서 문서 페이지로 이동

https://새로부여받은 url 주소/docs 

 

-실제로 프로젝트를 마무리하기 전에 꼭 테스트를 해봐야 합니다.

 

-GET 클릭 > Try it Out 클릭 > Execute 클릭

 

 

 

 

 

 

 

 

 

 

 

 

 

Google Storage에 업로드된 데이터가 출력됩니다.

 

-네이버 지도에서 서울시에 있는 주소를 하나 가져오겠습니다.

 

-"세븐일레븐 삼양복지점" // 서울 강북구 삼양로47길 23 

 

-문서 테스트에서는 실제 위도와 경도를 입력해야 합니다.

"latitude": 37.6228142, "longitude": 127.017762

 

-Post 클릭 > Try it Out 클릭  > 위도와 경도에 맞게 좌표 입력 후 Execute 입력

-Response body를 보시면 가장 가까운 주소는 : 강북구(미아동)7463 이라고 합니다.

 

-주의사항

"강북구 미아동 7463" 이 아니라 "강북구 미아동 746-3"입니다.

주지번 - 부지번 순으로 출력되기 때문에 붙어서 나오는 거죠

 

 

 

 

 

네이버 지도로 가서 길 찾기로 루트를 보겠습니다.

 

근처에 주유소가 있네요. 문서 테스트 시 문제가 없는 걸 확인했습니다.

 

이제 Chat GPT로 접속해서 프로젝트를 마무리하면 됩니다. 하지만 스크롤이 너무 길어서 다음 편에 올리겠습니다. ^^7

반응형