치악산 복숭아
[엘리스 AI트랙] 07-02-01 ~ 07-02-02 Flask 기초 1 본문
1. Flask Framework란?
- 파이썬을 사용해서 웹 서버를 만들수 있게 도와주는 Web Framework
- 파이썬의 패키지
- micro framework
- 기본적인 기능만 제공
- Flask의 장점
- 나만의 서버를 쉽게 작성 가능
- 간단한 코드로 빠르게 실행 가능
- 원하는 기능을 유연하게 확장하기 편리함
2. Flask로 Web server 만들기
from flask import Flask
app = Flask(__name__)
@app.route("/")
def home():
return "hello world!"
if __name__ == "__main__":
app.run()
- __name__은 파일이 다른 파일에서 실행됐는지, 아니면 직접 실행했는지 알게 해줌
- app.route(url) 아래의 함수는 url에서 실행할 함수
- if __name__ == "__main__"은 파일 이름이 main일 때만 app을 실행하도록 함
3. JSON 형식의 데이터 나타내기
from flask import Flask jsonify
app = Flask(__name__)
@app.route("/")
def home_json():
blog_info = {"mountain":"chiak"}
return jsonify(blog_info)
if __name__ == "__main__":
app.run()
jsonify()
- 딕셔너리 형태의 데이터를 전달함으로써 JSON 형태의 데이터를 화면에 전달
4. HTML 형식의 데이터 나타내기
- 나타낼 html 파일을 templates 폴더에 넣어주어야 함
- templates 폴더에 html 파일을 넣어놓으면 Flask가 자동으로 파일을 찾아서 연결해 줌
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def home_html():
return render_template("index.html")
if __name__ == "__main__":
app.run()
- render_template은 templates 폴더 안의 html 파일을 불러와주는 역할을 함
- trmeplates 폴더의 html 파일의 이름과 render_template() 안의 이름이 같아야 화면에 잘 전달할 수 있음
5. 여러가지 url 연결하기
@app.route("URL 주소")
- 1개의 @app.route는 여러개의 함수를 가질 수 있지만 1개와 연결하는게 가장 깔끔
- 함수의 이름은 중복될 수 없음
from flask import *
app = Flask(__name__)
@app.route("/")
def home():
return jsonify("home")
@app.route("/admin")
def admin():
return jsonify("admin page")
@app.route("/student")
def student():
return jsonify("student Page")
@app.route("/student/<name>")
def user(name):
user = {"name" : name}
return jsonify(user)
if __name__ == "__main__":
app.run()
6. REST API
- HTTP URI을 통해서 데이터의 자원을 명시하고 HTTP Method(POST, GET, PUT, DELETE)를 통해 해당 자원에 대한 CRUD Operation을 적용하는 것
- DB, 이미지, 텍스트 등의 다양한 데이터에 적용할 수 있음
- 메시지가 의도하는 바를 URL에서 나타내므로, 쉽게 기능을 파악할 수 있음
- HTTP 표준 프로토콜에 따르는 플랫폼에서 사용 가능
- 서버와 클라이언트의 구분을 명확하게 할 수 있음
- REST API의 표준이 존재하지 않음(➡️ 권고사항만 있음, 단점)
7. HTTP Method
- GET과 POST 등이 있음
GET | POST | |
데이터를 URL 뒤에 ?와 함께 사용 | 사용방법 | 특정 양식(form)에 데이터를 넣어 전송하는 방법 |
|
단점 | |
http://사이트_주소?id=julie&pwd=1234 | 예시 | http://사이트_주소 |
app.route()에 method 옵션 사용하기
# app.py
@app.route('url1', methods=["GET"])
@app.route('url2', methods=["POST"])
@app.route('url3', methods=["GET", "POST"])
- app.route()에 methods라는 옵션을 추가해서 해당하는 HTTP Method만 사용할 수 있도록 적용할 수 있음
- 이렇게 나누면 좋은 점: URL1과 URL2가 같아도 상관 X -> methods 옵션이 다르기 때문
GET 요청만 사용하기
from flask import *
app = Flask(__name__)
@app.route("/", methods=["GET"])
def home():
# localhost:5000?name=elice
name = request.args.get('name')
# name == elice
result = "hello " + name
return result
if __name__ == "__main__":
app.run()
POST 요청만 사용하기
<html>
<body>
<form action='/login' method='post'>
<p>
아이디: <input type='text' name='id'>
</p>
<p>
비밀번호: <input type='password' name='pwd'>
</p>
<button type='submit' />
</form>
</body>
</html>
# app.py
from flask import *
app = Flask(__name__)
@app.route("/", methods=["GET"])
def home():
return render_template("index.html")
@app.route("/login", methods=["POST"])
def post():
id = request.form['id']
pwd = request.form['pwd']
if id == 'julie' and pwd = '1234':
return 'Hello Julie!'
else:
return 'Go away'
if __name__ == "__main__":
app.run()
8. Blueprint란?
- API들을 분류 / 관리할 수 있게 해줌
- Flask의 기능이 점점 늘어날수록, 자연스럽게 코드의 양 ⬆️
- 이 때 Blueprint를 사용해서 길어진 코드를 모듈화
- 수정 개발과 유지보수에 용이하게 코드 관리 가능
1) Blueprint를 사용하지 않았을 경우의 코드
- app.route의 개수 == API의 개수
from flask import Flask, jsonify
app = Flask(__name__)
@app.route("/", methods=['GET'])
def home_route():
return jsonify('home')
@app.route("/first", methods=['GET'])
def first_route():
return jsonify('first page')
@app.route("/second", methods=['GET'])
def first_route():
return jsonify('second page')
@app.route("/third", methods=['GET'])
def first_route():
return jsonify('third page')
# ... 중략 ...
if __name__ == '__main__':
app.run()
2) Blueprint를 사용했을 경우
# 1 app.py
# 오직 서버 실행에 집중
from flask import Flask
from first_api import bp
app = Flask(__name__)
app.register_blueprint(bp)
if __name__ == '__main__':
app.run()
# 2 first_api.py
# API들을 따로 모아놓은 파일
from flask import Blueprint, jsonify
bp = Blueprint('bp', __name__)
@bp.route('/first', methods=['GET'])
def first_route():
return jsonify('first page')
@bp.route('/second', methods=['GET'])
def second_route():
return jsonify('second page')
9. Jinja2
- 파이썬에서 가장 많이 사용되는 템플릿
- 서버에서 받아온 데이터를 효과적으로 보여주고 비교적 간략한 표현으로 데이터를 가공 가능
1) Jinja2 Template에서 데이터 넘겨주기 - 단일변수
# app.py
@app.route("/")
def home():
return render_template(
'index.html',
data = 'elice'
)
<!-- index.html -->
<html>
<head>
<title> jinja example </title>
</head>
<body>
{{ data }}
</body>
</html>
2) Jinja2 Template에서 데이터 넘겨주기 - list
# app.py
@app.route("/")
def home():
my_list = [1, 2, 3, 4, 5]
return render_template(
'index.html',
data = my_list
)
<!-- index.html -->
<html>
<head>
<title> jinja example </title>
</head>
<body>
{{ data }}
{% for d in data %}
{{ d }}
{% endfor %} # if문이 끝날땐 endif
</body>
</html>
3) Jinja2 Template에서 데이터 넘겨주기 - dictionary
# app.py
@app.route("/")
def home():
my_data = {'name': 'elice'}
return render_template(
'index.html',
data = my_data
)
<!-- index.html -->
<html>
<head>
<title> jinja example </title>
</head>
<body>
{{ data.get('name') }}
</body>
</html>
8. 로그인 기능 구현
1) 쿠키
- 클라이언트에 저장되는 키/값이 들어있는 데이터
- 쿠키는 내 컴퓨터의 브라우저에 저장이 된다
- 유효기간이 안에 저장되어 있으며 그 기간내에는 따로 삭제하지 않는한 계속 저장되어 있음
- 사용자가 따로 요청하지 않아도, Request 시에 자동으로 서버에 전송
2) 세션
- 쿠키를 기반으로 하지만 서버 측에서 관리하는 데이터
- 클라이언트에 고유 ID를 부여하고 클라이언트에 알맞은 서비스 제공
- 서버에서 관리하기 때문에 쿠키보다 보안이 우수함
- http 통신의 한 사이클
- http는 상태값을 저장하지 않음(stateless)
- http의 이런 단점을 보완하기 위해 cookie를 담아서 전송하는 등의 방법 사용
3) 예제 코드
# 로그인
user_id = request.form['user_id']
user_pw = request.form['user_pw']
user = {'user_id' : 'julie', 'user_pw': '1234'}
if user is not None:
if user_id == user['user_id'] and user_pw == user['user_pw']:
session['login'] = user.id
return jsonify({"result":"success"})
else:
return jsonify({"result":"fail"})
- request로 받아온 로그인 정보(user_id, user_pw)를 변수에 저장
- DB에 user_id와 가은 데이터가 있는지 찾아옴
- 입력된 user_pw와 저장된 패스워드가 같은지 체크
# 로그아웃
session['login'] = None
9. 로깅
- 프로그램이 작동할 때 발생하는 이벤트를 추적하는 행위
- 프로그램의 문제들을 파악하고 유지보수 하는데 사용
- 로깅을 통해 발생한 에러를 추적할 수 있음
1) 로거 레벨
- DEBUG < INFO < WARNING < ERROR < CRITICAL
- 기본 로거 레벨 세팅은 WARNING이기 때문에 설정 없이 INFO, DEBUG를 출력할 수 없음
- 에러가 발생했을 때 Flask의 logger(기본 내장)를 사용하여 에러 확인 가능
DEBUG: 상세한 정보
INFO: 일반적인 정보
WARNING: 예상치 못하거나 가까운 미래에 발생할 문제
ERROR: 에러 로그, 심각한 문제
CRITICAL: 프로그램 자체가 실행되지 않을 수 있는 문제
2) 특정 에러 제어하기
@app.errorhandler(404)
def page_not_found(error):
app.logger.error(error)
return render_template("page_not_found.html")
- app.route를 쓰는 것처럼 app.errorhandler를 사용하면 에러를 제어할 수 있다
'elice > 토끼성장일지' 카테고리의 다른 글
[엘리스 AI트랙] 07-04 Flask 기초 2 (1) | 2021.11.11 |
---|---|
[엘리스 AI트랙] 06-04 SQL 2 (0) | 2021.11.10 |
[엘리스 AI트랙] React Hook으로 상태관리 하기 (0) | 2021.11.06 |
[엘리스 AI트랙] 05-04 React UI (0) | 2021.11.02 |
[엘리스 AI트랙] 06-02-01 ~ 06-02-02 SQL 1 (0) | 2021.10.27 |
Comments