Project

요기약(4)

codingtori 2025. 2. 18. 20:57

원래 huggingface에서 API 요청을 해서 데이터를 받아오는 식으로 모델과 연결을 수행하려했지만, 모델의 JSON응답을 받아오는 과정에서 계속 문제가 발생하여 ngrok을 이용해서 모델과 연결하는 방식을 선택하였다

 

Ngrok

로컬 개발 환경에서 인터넷을 통해 웹 애플리케이션에 안전하게 접근할 수 있도록 해주는 도구

 

연결 방법

 

  • 로컬 서버 실행: 모델을 로컬 환경에서 실행하고 이를 웹 서버로 감쌉니다 (예: Flask나 FastAPI로 REST API 구현).
  • ngrok으로 터널링: ngrok을 사용해 로컬 서버에 대한 임시 공용 URL을 생성합니다.
  • 외부 시스템에서 요청: 생성된 ngrok URL을 통해 외부 시스템이 로컬 서버에 요청을 보냅니다

 


원래 함수 -> 서버가 먼저 시작되고 ngrok 생성 안되는 문제 계속 발생

import asyncio
from pyngrok import ngrok
import uvicorn
import nest_asyncio
from fastapi import FastAPI

app = FastAPI()

# 예시 엔드포인트
@app.get("/")
def read_root():
    return {"message": "Hello World"}

async def start_ngrok():
    # ngrok 터널 시작
    public_url = ngrok.connect(8000)
    print(f" * Public URL: {public_url}")
    return public_url

async def start_server():
    # ngrok을 먼저 시작하고 그 다음에 서버 시작
    await start_ngrok()

    # nest_asyncio 적용 (코랩 환경에서 필요)
    nest_asyncio.apply()

    # 서버 시작
    uvicorn.run(app, host="0.0.0.0", port=8000)

if __name__ == "__main__":
    asyncio.run(start_server())  # 비동기로 서버 시작

 

따라서, @app.on_event("startup") 안에다가 넣음

서버가 시작될 때 자동으로 ngrok 연결이 설정되고 public URL이 출력됨.  ngrok 연결이 서버 시작과 동시에 이루어지도록 보장

@app.on_event("startup")
async def startup_event():
    global chatbot
    # 샘플 데이터 생성 및 저장
    sample_df = create_sample_data()
    data_dir = "/content/sample_data"
    os.makedirs(data_dir, exist_ok=True)
    temp_file = f"{data_dir}/sick.xlsx"
    sample_df.to_excel(temp_file, index=False)
    
    # 챗봇 초기화
    chatbot = SimplifiedMedicalChatbot(temp_file)

    # ngrok 연결 설정
    public_url = ngrok.connect(8000)
    print(f" * Public URL: {public_url}")

 

C:\Users\mini0\Anaconda3\envs\gamza\lib\asyncio\runners.py", line 33, in run [1] [0] raise RuntimeError( [1] [0] RuntimeError: asyncio.run() cannot be called from a running event loop [1] [0] python utils/model_connection.py exited with code 1

에러발생!!  이미 실행 중인 이벤트 루프 내에서 asyncio.run()을 호출하려고 했기 때문에 발생

 

  1. start_server() 함수를 수정하여 uvicorn.run()을 직접 호출하는 대신 비동기 설정을 사용:
async def start_server():

    config = uvicorn.Config(app, host="0.0.0.0", port=8000)

    server = uvicorn.Server(config)

    await server.server()

    2. 메인 스크립트에서 asyncio.run() 대신 이벤트 루프를 직접 생성하고 관리:

if __name__ == "__main__":

    loop = asyncio.new_event_loop()

    asyncio.set_event_loop(loop)

    try:

        loop.run_until_complete(start_server())

    finally:

        loop.close()

 

이렇게 해도 에러가 해결 안되서 비동기 -> 동기로 바꿈 && 로그 출력에  flush 사용

print(f" * Public URL: {public_url}", flush=True)

 

이후에

에러코드

이렇게 에러가 나서 보니,,,,,

 

형식이 모델에서 요구하는 것과 다름

모델에서는 bornYear str형식인데 여기서는 숫자였었음~!


 

드디어ㅠ 완성했다!!