IIS & FastAPI(venv) 구동하기

dbkim-geo·2023년 8월 3일
0
post-thumbnail

1. 개요

기존의 레거시 프로젝트가 IIS 에 .NET 으로 돌아가고 있었다.
여기서 기계학습 로직을 추가해야해서 간단히 python 프레임워크인 FastAPI 를 추가해야하는 상황이다.
서버의 경우 window 서버이기에 IIS에 FastAPI 를 넣으려고 한다.
기존에 포스팅 된 경우 플라스크나 장고가 많지만, FastAPI는 안보여 정리를 시작한다.

2. 작업

2.1. 준비

IIS에 fastAPI를 구동하기 이전에 사전 준비 작업을 한다.

우선 기존 fastAPI 를 구동하는데 이슈가 없는지 체크해보자.

프로젝트 생성

IIS_FastAPI_WebAPP 이라는 프로젝트 폴더를 생성하였다.

참고로 python 3.8.10 기준으로 하였으며, python3.7.9 도 이슈 없이 동작하였다.

여기서 venv 을 세팅해보자.
E:\geo-workspace\IIS_FastAPI_WebApp>python -m venv iisfastapi38

가상환경에 들어가고,
E:\geo-workspace\IIS_FastAPI_WebApp>iisfastapi38\Scripts\activate.bat

가상환경에서 fastapiuvicorn 라이브러리를 설치하자.
(iisfastapi38) E:\geo-workspace\IIS_FastAPI_WebApp>pip install fastapi
(iisfastapi38) E:\geo-workspace\IIS_FastAPI_WebApp>pip install uvicorn

이제 체크를 해보자

# main.py
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse

app = FastAPI()

@app.get("/")
async def root(request: Request):
    return_msg = {}
    return_msg["message"] = "Hello World"
    return_msg["client_host"] = request.client.host
    return_msg["client_port"] = request.client.port

    return JSONResponse(content=return_msg)

8088 포트로 열어보고 테스트 해보았다.

굿

2.2. IIS + FastAPI

wfastcgi 라이브러리를 설치하자.
(iisfastapi38) E:\geo-workspace\IIS_FastAPI_WebApp>pip install wfastcgi

여기서 프로젝트 루트 폴더에서 wfastcgi-enable을 입력하여 fastCGI 세팅을 실행한다.
IIS에서 귀찮게 안해도 되고, 해당 명령어를 입력하면 세팅이 잘 된다.

당연히 관리자 권한으로 명령 프롬프트를 실행해야 된다.

(iisfastapi38) E:\geo-workspace\IIS_FastAPI_WebApp>wfastcgi-enable

위와 같이 커밋되었으면 굿이다.

이제 IIS 로 들어가서 웹사이트 추가를 한다.

사이트이름 은 마음대로 지정
실제 경로 의 경우 프로젝트 루트 디렉토리
포트 는 서비스 하고 싶은 포트
로 세팅하고 확인을 누르자.

이제 추가한 사이트 홈 탭에서 처리기 매핑 세팅을 한다.

이제 모듈 매핑 추가 를 한다.
요청 경로*
모듈FastCgiModule (이건 드롭박스 열면 있다.)
실행 파일(옵션) 의 경우 타이핑 쳐도 되나, 귀찮으니깐 아까 wfastcgi-enable 을 하였을 때 경로가 나온 것을 복사 붙여 넣기 한다.
타이핑 할 경우,
venv의 파이썬.exe 경로 | venv 라이브러리의 wfastcgi.py 경로 이다.
이름은 마음대로 작성

이후 요청 제한 을 열어 체크 해제 를 한다.

최종적으로 확인을 누를 경우, 다음의 알림 창이 나온다.
여기서는 아니오 를 누른다.

아까 wfastcgi-enable 로 세팅 다했으니깐 추가적으로 경로 세팅 안하는 것이다.
그냥 누르고 편집해도 된다.

이제 다시 FastCGI 설정에서 경로 세팅이 잘 되어 있는지 체크해보자.

아래와 같이 잘 세팅된 경로에서 환경변수 세팅을 추가적으로 해야한다.
2개를 추가하는데,
PYTHONPATH프로젝트 루트 디렉토리
WSGI_HANDLER실행할파이썬파일이름.app변수이름
이다.

2.3. 중간 점검

여기서까지 하였으면, 대부분 잘 된다고들 한다.
근데 500 error 가 뜨는 경우가 있다. (나는 그랬다.)

권한 이슈로 IISUser에 대해 권한 설정을 2곳에 한다.
1. 프로젝트 폴더
2. python(local) 경로 (venv 경로가 아닌, 기본 경로로 하였다.)

2.4. 최종 점검

이런 다음, API 테스트를 해보았는데 다음의 에러 코드를 뜨는 경우가 있다.

Error occurred:

Traceback (most recent call last):
    File "당신의 가상환경 경로\lib\site-packages\wfastcgi.py", line 847, in main
        result = handler(record.params, response.start)
TypeError: __call__() missing 1 required positional argument: 'send'

다음의 사이트 https://stackoverflow.com/questions/67395604/is-there-a-way-to-deploy-fastapi-on-iis-server 를 참고하여 해결하였다.

a2wsgi 라이브러리를 설치한다.
(iisfastapi38) E:\geo-workspace\IIS_FastAPI_WebApp>pip install a2wsgi

소스 코드는 ASGIMiddleware 클래스를 기존의 app 으로 쌈싸먹는다.

# main.py
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from a2wsgi import ASGIMiddleware # <-- 추가한 코드

app = FastAPI()

@app.get("/")
async def root(request: Request):
    return_msg = {}
    return_msg["message"] = "Hello World"
    return_msg["client_host"] = request.client.host
    return_msg["client_port"] = request.client.port

    return JSONResponse(content=return_msg)

app = ASGIMiddleware(app) # <-- 추가한 코드

3. 결과

이제 API 테스트 해보면 정상 작동 한다.

추가로 시작모드의 경우 AlwaysRunning 으로 세팅하였다.

실제 서비스 시 이슈사항이 발생하면 추가할 예정이다.

4. 수정사항

4.1. 방화벽 이슈

인바운드 외부 접속 허용을 하지 않았다.

제어판시스템 및 보안Windows Defender 방화벽고급설정

여기서 인바운드 규칙 에서 새 규칙을 추가한다.

새 인바운드 규칙 마법사 에서는
1. 포트 체크
2. TCP특정 로컬 포트 (열고 싶은 포트 번호 입력, 본 포스팅에서는 8088이다.)
3. 연결 허용
4. 무지성 ALL 체크 후 다음
5. 이름과 설명 작성
마침

다른 PC에서 postman으로 테스트 해보니 잘 된다.

1개의 댓글

comment-user-thumbnail
2023년 8월 3일

잘 읽었습니다. 좋은 정보 감사드립니다.

답글 달기