본문으로 바로가기
목차
1. 기본 라우트 설정
2. Python의 순환참조
3. Blueprint

1. 기본 라우트 설정

파이썬의 기본 라우트 설정은 이 전 포스트의 설치 편에 포함된 코드에도 나와 있듯,

@app.route 데코레이터를 통해 설정이 가능하다는 것을 알 수 있다. 

아래의 코드는 각각 메소드 별로 지정된 텍스트를 리턴한다.

  • GET / : return Hellow, World!
  • POST / : return foo
# {Project Root}/app.py
from flask import Flask

app = Flask(__name__)


@app.route('/')
def home():
    return 'Hello, World!'


@app.route('/', methods=['POST'])
def foo():
    return 'foo'


if __name__ == '__main__':
    app.run(debug=True)

 

2. 순환 참조

순환참조란 A 모듈에서 B 모듈을 참조하고 B 모듈에서 또한 A 모듈을 참조하는 경우를 말한다.

하지만 Python 은 순환참조를 허용하지 않는다.

아래와 같이 route 에 해당하는 코드를 별도의 파일로 분리한 후 각각 app.pyroute/api.py 파일을 참조하도록 변경한 후 실행을 하게 되면 아래와 같은 에러가 발생한다.

AttributeError: partially initialized module 'app' has no attribute 'route' (most likely due to a circular import)

# /bootstrap/__init__.py
from flask import Flask
from routes.api import routes

app = Flask(__name__)



if __name__ == '__main__':
    app.run(debug=True)
    
    
# route/api.py
import app

@app.route('/')
def home():
    return 'Hello, World!'


@app.route('/', methods=['POST'])
def foo():
    return 'foo'

이 문제를 해결하기 위해 코드를 아래와 같이 수정한다.

  1. app.py 파일을 통해 실행되던 코드를 app/__init__.py 파일에 아래와 create_app 메소드를 통해 구현한다.
  2. routes 파일에도 마찬가지로 메소드를 통해 app 을 주입받아  route 를 등록할 수 있도록 수정한다.
# app/__init__.py
from flask import Flask
from routes.api import routes


def create_app():
    app = Flask(__name__)
    routes(app)
    return app



# routes/api.py
from flask import Flask


def routes(app: Flask):

    @app.route('/')
    def home():
        return 'Hello, World!'

    @app.route('/', methods=['POST'])
    def foo():
        return 'foo'

__init__.py 파일에 생성한 create_app 메소드는 Flask 공식 문서에서 말하는 애플리케이션 팩토리 이다.

routes/api.py 파일에서 또한 create_app 메소드를 통해 리턴되는 app 을 주입받아 라우트를 등록한다.

위와 같이 코드를 수정한 후 실행하게 되면 문제 없이 실행된다.

 

3. Blueprint

위에 설명한 방법 이외에 Flask 에서는 Blueprint 라는 모듈을 제공한다.

위의 코드를 아래와 같이 수정해보자.

# app/__init__.py
from flask import Flask


def create_app():
    from routes.api import api
    app = Flask(__name__)
    # api blueprint 를 Flask APP 에 등록한다.
    app.register_blueprint(api)
    return app


# routes/api.py
from flask import Blueprint

# Blueprint (api) 객체 생성
api = Blueprint('api', __name__, url_prefix='/api')

# Blueprint (user) 객체 생성
user = Blueprint('user', __name__, url_prefix='/user')

# Flask 2.x 부터는 중첩된 구조를 등록할 수 있는 기능을 지원한다.
# api 라우트의 하위에 user 를 등록한다.
# /api/user/* 형태의 endpoint 가 생성된다.
api.register_blueprint(user)


@user.route('/')
def index():
    return 'Hello, World!'

@user.route('/<id>')
def find_one(id):
    return 'user_id : {}'.format(id)

상기와 같이 Blueprint 를 통해 모듈화된 형태의 라우트 관리가 가능하다.