ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Python - Flask 활용
    Python 2020. 5. 29. 16:35

    Python - Flask

    Flask

    • 파이썬 기반 마이크로 웹 개발 프레임워크

    • 웹 개발의 핵심기능만 간경하게 유지

    • 필요한 기능은 다른 라이브러리나 프레임워크로 손쉽게 확장

    • 신속하게 최소한의 노력으로 웹 애플리케이션 개발 가능

    Flask 특징

    • 개발용 서버와 디버거 내장

    • RESTful 요청 처리

    • Jinja2 템플릿 엔진 내장(JADE 등 다른 템플릿 엔진 사용 가능)

    • 유니코드 기반

    홈페이지

    개발 환경 설정

    파이썬 3 설치 (파이썬 2도 가능)

    가상 파이썬 실행 환경 구성 (virtualenv)

    • 다양한 환경이나 특정 실행 환경 구성하기

    • virtualev 라는 가상의 파이썬 실행 환경 지원 함

    # 설치
    pip install virtualenv
    # 확인
    virtualenv -help 
    virtualenv --viersion
    • 가상 환경으로 만들고 싶은 폴더에서 명령어 실행

    virtualenv venv
    • 가상 환경 활성화

    cd venv/scripts
    activate.bat
    • pyenv, autoenv 함께 사용하면 더 편리

    플라스크 설치

    pip install flask

    note: could not find a version that satisfies the requirement flask가 나올 경우, 네트워크 문제로 외부 라이브러리 저장소에 접근하지 못할 경우 나오는 문제.

    직접 https://github.com/mitsuhiko/flask 위치로 가서 소스 받아 설치 해야 함.

    • 설치 방법 – python setup.py install

    통합개발환경(IDE) / 에디터 설치

    시작하기

    Hello world

    • 소스를 실행하고, terminal 에서 'python flask_test.py' 입력 후 http://127.0.0.1:5000 으로 접근

    실행결과

    플라스크 애플리케이션 실행 순서

    1. 특정 URL 호출(request) : http://127.0.0.1:5000/ 또는 http://localhost:5000

    2. 특정 URL 매핑 검색 : @app.route('/')

    3. 특정 URL에 매칭된 함수(def 함수) 실행 : def hello_world()

    4. 비즈니스 로직 실행 : result

    5. 결과 응답으로 전송(response): return result

    6. HTML 로 화면에 출력

    7. 쿠키(Cookie), 세션(Session), 로깅(logging) 등 제공

    라우팅

    • URL을 통해 처리할 핸들러를 찾는 것

    • 플라스크는 복잡한 URI를 함수로 연결하는 방법을 제공

    • URI 를 연결하는 route() 데코레이터 함수 제공

    • / 접속 시 root_world() 가 호출 됨

    • /hello 접속 시 hello_world() 가 호출 됨

     

    /hello 결과

    • 동적 변수를 사용하여 URI 접속

    • <동적변수> 를 뷰 함수의 인자로 사용

    • <동적변수> 다음에 / 를 넣으면 안됨

    • app.debug는 개발의 편의를 위해 존재

      • True값을 경우 코드를 변경하면 자동으로 서버가 재 실행 됨

      • 또한, 웹상에서 파이썬 코드를 수행할 수 있게 되므로, 운영환경에서 사용을 유의해야 함.

    • 현재 접근은 개발 소스가 존재하는 로컬에서만 접근 가능

      • 외부에서도 접근을 가능하게 하려면 app.run(host='0.0.0.0')로 서버 실행 부를 변경해야 함.

    • url_for() 함수 : 함수를 호출 하는 URI 를 반환

    • redirect() : 다른 route 경로 이동 (다른 페이지로 이동)

    guest 테스트 결과

    Flask GET 방식으로 값 전송 및 처리

    • mkdir templates 폴더 생성

    • login_form_get.html 파일 작성

    • get 방식 지정 : method="get"

    templates폴더 및 login_form_get.html 작성

    • from flask import Flask, request, session, render_template 추가

    • 사용자가 요청한 값은 request 모듈의 args 객체의 get 메소드로 값을 가져옴

    • 내부에 methods 항목을 통해 받을 REST Action Type을 지정

    @app.route('/login_get_proc', methods=['GET'])
    • 지정 이외의 Action Type을 사용하면 Flask가 405 에러를 출력

    • request 모듈에서 GET 한 파라미터 값을 가져오기 위해서는

    request.args.get('name') # url?name=value name 값

    app.py 작성
    Get 방식 실행 결과

    Flask POST 방식으로 으로 값 전송 및 처리

    • login_form_post.html 파일 작성

    • post 방식 지정 : method="post"

    login_form_post.html 작성

    • 사용자가 요청한 값은 request 모듈의 form 객체로 값을 가져옴

    • 내부에 methods 항목을 통해 받을 REST Action Type을 지정

    @app.route('/login_post_proc', methods=['POST'])
    • 지정 이외의 Action Type을 사용하면 Flask가 405 에러를 출력

    • request 모듈에서 POST 한 파라미터 값을 가져오기 위해서는

    request.form['name'] # html form input등의 Element들의 name 값
    • request.form['name']로 사용 시 name 파라미터가 없으면 Flask가 400 에러를 출력

    app.py에 post부분 추가
    /login_form_post로 접속
    결과

    Flask 에서 HTML 처리 하기

    from flask import Flask
    app = Flask(__name__)
    
    @app.route('/')
    def index():
       html = "<html><body><h1>Hello World</h1></body></html>"
       return html
    
    if __name__ == '__main__':
       app.run(debug = True)
    • user_id 값 html 과 함께 처리 하기

    • 처리할 값이 많아지면 너무 복잡해 짐

    @app.route('/users/<userid>') # route 데코레이터
    def user_id(userid): # View 함수
    
        html = "<html><body><h1> User Id : "
        html = html + userid
        html = html + "</h1></body></html>"
    
        return html

    Flask – Jinja2 템플릿 : 기본

    • 플라스크에서는 Jinja2 템플릿의 사용

    • Jinja2에 대한 더 자세한 내용은 Jinja2 Template Documentation 공식 문서를 참고

    • Jinja2 Template Documentation

    • template 폴더 생성 (Jinja2 템플릿 기본 문서 위치)

    • template 폴더 아래에 userid_view.html 생성

    • return render_template('userid_view.html', userid=userid) userid 전달

    • {{ userid }}

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h1> User Id : {{ userid }}</h1>
    </body>
    </html>
    @app.route('/users/<userid>') # route 데코레이터
    def user_id(userid): # View 함수
    
        return render_template('userid_view.html', userid=userid)

    Flask – Jinja2 템플릿 : 리스트(list) , 튜블(tuple) 등 전달

    @app.route('/plays')
    def palys():
        games = ('갤러그', '너구리', '리니지')
        sports = ['야구', '축구', '농구']
        return render_template('plays/play.html', title='PLAYS', games=games, sports=sports, )
    • play.html

    • {# 주석(comment) #}

    • 반복문 : {% for i in sports %} ~ {% endfor %}

    plays 폴더 생성 후 play.html 작성

    Flask – Jinja2 템플릿 : <form> 값 전달

    • input.html

    templates 폴더에 input.html 작성

    • result.html

    plays 폴더 안에 result.html 작성

    • flask_test.py작성

    flask_test.py 작성

     

    /input_form
    Submit 한 result

    Flask – 쿠키 (Cookie)

    • http 프로토콜은 기본적으로 상태 값을 유지 하지 않음(stateless protocol)

    • 쿠키(cookie) 와 세션(session)은 서버와 클라이언트 간 상태 값을 저장 하는 기술

    • 쿠키(cokkie) 심기 : response 객체의 set_cookie() 메서드 사용

    • 쿠키(cokkie) 일기 : request 객체의 cookie.get() 사용

    app2.py 작성
    templates/cookie/setcookie.html 작성
    templates/cookie/readcookie.html 작성

     

    http://127.0.0.1:5000 접속

     

    Login 버튼 눌러서 이동된 화면

     

    GET Cookie 누른 결과 창

    Flask 로그인 및 세션 생성

    • 쿠키(cookie)는 클라이언트 피씨에 생성

    • 세선은 서버 메모리에 생성되어 생성 후 바로 사용 가능

    app.py 작성

    app.secret_key #  세션 키를 생성하며, 로그인과 같이 세션을 맺는 경우 필수적으로 넣어야 한다.
    • 세션 생성 시, app.secret_key로 키를 생성하지 않으면 Flask가 500 에러를 출력

    login_form.html 작성

    • session_view.html ( 세션이 유지 되는 시간동안 세션값은 바로 사용 가능)

    session_view.html 작성
    /login_form
    /login_proc

    sqlite3 db 및 table생성

    • DB 서버 필요 없는 파일 기반 Embedded SQL DB 엔진

    • sqlite브라우저 : http://sqlitebrowser.org/

    • db 없을 시 python.db 자동 생성 됨

    db_proc.py 작성
    데이터베이스 열기 - python.db 클릭
    Table확인

    로그인 체크 로직 변경

    app.py의 로그인 체크 로직 변경

    • main.html 작성

    main.html

    로그인 정보 수정

    app.py에 내용 추가
    app.py에 내용 추가

    • user_info.html

    user_info.html 작성

    로그아웃

    • redirect()를 활용하면, 사용자의 조회 위치를 변경할 수 있다.

    • url_for()는 route 주소로 이동하는 것이 아닌 정의된 함수를 호출한다. 위 예제에서 main을 호출하는 대상은 main()인 함수다.

    • session.clear()를 사용하면 따로 설정 필요없이 session을 비울 수 있다.

    Flask 리스트 페이징 하기(list paging)

    lists.html
    list.html

    • Flask 소스 : miniboard_app.py
    from flask import Flask, request, session, render_template, url_for
    import sqlite3, math
    app = Flask(__name__)
    
    @app.route('/')
    def index():
        return 'root - index'
    
    def select():
        conn = sqlite3.connect('python.db')
        cursor = conn.cursor()
        sql = 'select * from miniboard order by idx desc'
        cursor.execute(sql)
        rows = cursor.fetchall()
        conn.close()
        return rows
    
    def select_page(list_limit, page):
        conn = sqlite3.connect('python.db')
        cursor = conn.cursor()
        offset = (page - 1) * list_limit
        sql = 'select * from miniboard order by idx desc limit ? offset ?'
        cursor.execute(sql, (list_limit, offset))
        rows = cursor.fetchall()
        conn.close()
        return rows
    
    def select_count():
        conn = sqlite3.connect('python.db')
        cursor = conn.cursor()
        sql = 'select count(idx) from miniboard' # 10
        cursor.execute(sql)
        rows = cursor.fetchone() # class tuple
        cursor.close()
        conn.close()
        return rows[0]
    
    def list_test():
        list = select()
        print(list)
    
    @app.route('/lists')
    def lists():
        lists = select()
        return render_template('miniboard/lists.html', lists=lists)
    
    @app.route('/list/<int:page>')
    def list(page):
        list_num = 4
        list_count = select_count()
        #page_count = int(list_count / list_num)
        page_count = math.ceil(list_count / list_num)
        lists = select_page(list_num, page)
        return render_template('miniboard/list.html', lists=lists, page_count=page_count)
    
    if __name__ == '__main__':
        app.secret_key = '202006011522'
        app.run(debug=True)
        #list_test()

    결과창 확인

    출처 : http://thecoding.kr/category/phython/phython-flask/

    'Python' 카테고리의 다른 글

    Jupyter Notebook  (0) 2020.06.02
    Python 가상환경 생성 및 R 주피터 노트북 연결  (0) 2020.06.02
    Python - Sqlite3 활용  (0) 2020.05.29
    Python - JSON 활용  (0) 2020.05.29
    Python - CSV 활용  (0) 2020.05.28
Designed by Tistory.