[Flask 웹 프레임워크] Blueprint를 이용한 모듈화 이해하기

Flask 웹 프레임워크를 이용해 작성한 첫 웹 어플리케이션은 전통적인 하나의 소스파일에서 실행하도록 작성되었다.

blogger.py 라는 파이썬 소스파일에서 Flask 웹 어플리케이션 객체인 app를 생성하고 이 어플리케이션 객체에  / 경로를 라우팅하고 / 경로에 hello_index()라는 함수를 매핑했다. 그리고 hello_index()에서 ‘Hello, Flask!’라는 문자열을 출력하도록 했다.

모듈화 고려 없이 작성된 첫 Python 웹소스

이 모든 코드가 blogger.py 라는 소스파일에 코딩되었다.

하지만 프로그램은 조금만 커져도 코드가 복잡해져 무거워지며 코드의 작성도 어려워진다. 따라서 개발 초기 단계부터  “모듈화”를 고려하여 설계하여야 한다. 파이썬의 Flask 웹 프레임워크에서도 모듈화를 위한 기능들을 제공하는데 어플리케이션 팩토리(Application factory)라고 부르는 모양이다.

그리고 어플리케이션 팩토리를 사용할 때 블루프린트(Blueprint)라는 기능을 사용하면 보다 효과적으로 어플리케이션의 모듈화가 가능하다.

먼저 어플리케이션 팩토리를 적용해보자.

어플리케이션 팩토리 적용

위의 소스코드를 어플리케이션 이름과 동일한 디렉토리(blogger)를 만들고 소스코드가 담긴 blogger.py를 __init__.py 라는 이름으로 변경하여 blogger 디렉토리 아래로 이동시킨다.

모듈화를 위한 App 디렉토리 생성 및 초기화 소스로 이름 변경

디렉토리의 이름은 반드시 어플리케이션 이름과 동일하게 작성하여야 flask 명령이 앱의 이름에 해당되는 디렉토리를 찾아 그 디렉토리에 위치하고 있는 초기화 소스인 __init__.py 를 찾아 실행시켜줄 수 있는 것으로 보인다.

그리고 __init__.py 파일을 다음과 같이 수정한다.

create_app() 함수로 작성된 blogger 앱 초기화 및 / 매핑

Flask(__name__) 함수로 app 객체를 생성하던 것을 create_app() 함수에 넣어주었다. 그리고 맨 아래에 app 객체를 return 하는 코드가 추가되었다.

그리고 flask 명령을 이용해 blogger 어플리케이션을 실행시켜본다.

blogger 디렉토리로 이동시킨 blogger 어플리케이션 실행하기

그리고 웹페이지에 접속해 정상적으로 동작하는지 확인한다.

__init__.py에 정의된 / 경로의 hello_flask() 함수가 실행된 화면

Blueprint 적용

지금까지의 소스코드에서는 어플리케이션의 메인모듈(blogger.py 또는 __init__.py)에서 Flask() 함수를 이용해 blogger 어플리케이션의 객체인 app 를 생성하고 생성한 app 객체에 / 경로를 매핑해주었다.

Blueprint를 이용하면 flask()함수에서 생성한 app 객체가 아닌 Blueprint()라는 함수에서 생성한 객체에 어플리케이션 이름을 지정하여 / 경로 등을 매핑해줄 수 있다.

blogger 디렉토리 아래에 pages라는 디렉토리를 만들고 pages 디렉토리에 main_page.py 라는 파일을 생성하고 다음과 같이 코드를 작성한다.

Blueprint 객체를 이용한 경로 매핑

소스코드를 간단하게 설명해보자면…

1. Blueprint 클래스(라이브러리? 모듈?)를 import 한다.

2. Blueprint 생성자함수에서 어플리케이션의 이름(__name__)과 bp 이름은 main으로, URL prefix는 최상위 경로인 / 를 지정한 bp 객체를 생성한다.

3. bp 객체의 / 경로 함수 index()를 매핑한다.

다음은 Blueprint가 적용된 main_page.py 를 blogger 어플리케이션 초기화 코드에 연결해준다.

blogger 어플리케이션에 Blueprint 객체 import 하기

위 화면에 보면 main_page.py가 있는 pages 디렉토리가 보이고 어플리케이션 초기화 코드가 담긴 __init__.py도 보인다. __init__.py의 코드를 위 화면과 같이 수정한다.

이 코드를 간단히 설명하자면…

1. create_app() 함수에서 Flask 클래스의 생성자 Flask() 함수를 이용해 blogger Flask 어플리케이션 객체를 생성하고… (__name__ 변수에 blogger 어플리케이션 이름이 들어가 있음)

2. pages 디렉토리 아래에 있는 main_page라는 파이썬 모듈을 import 한다.

3. app 객체에 main_page에서 생성한 bp라는 Blueprint 객체를 등록(register)한다.

4. app 객체를 리턴하고…

5. flask가 app 객체를 실행한다. (소스코드에는 없지만..)

다음 화면은 http://193.*.*.42:5000 으로 접속했을 때 표시되는 화면이다.

웹사이트의 / 경로에 매핑된 index() 함수가 실행된 화면

Blueprint에 두 번째 경로 매핑하기

앞에서 웹서버의 최상위 경로인 / 를 Blueprint를 이용해 main_page.py에서 정의된 index() 함수가 실행되도록 매핑해보았다. 그러면 두 번째 경로를 독립된 소스코드 파일을 이용해 적용해보자.

두 번째 경로는 http://193.*.*.42:5000/sub/index 로 접속했을 때 다음과 같이 화면이 출력되도록 한다.

웹사이트의 /sub/index로 접근했을 때 출력된 화면

먼저 pages 디렉토리에 sub_page.py 파일을 만들고 코드를 작성한다.

/sub/를 url_prefix 로 지정한 Blueprint 객체와 /sub/index 경로를 라우팅

소스코드를 간단히 설명하면…

1. bp1 이라는 Bluprint 객체를 생성한다. bp1의 이름은 sub, 어플리케이션은 __name__에 지정, url_prefix는 /sub/ 으로 설정한다.

2. bp1 블루프린트 객체에 index 라는 경로로 접속 시 second() 함수가 실행된다.

는 의미다.

다음은 이 sub_page.py를 다음과 같이 __init__.py서 app 객체에 등록해주어야 한다.

어플리케이션이 sub_page.py에서 생성한 블루프린트 객체 bp1을 등록

이렇게 작성하고 나면 “Second Route page!!”가 출력된다.

#python  #flask #Blueprint

댓글 달기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

Scroll to Top