03_Oct_2021 ๐Ÿฐ ์—˜๋ฆฌ์Šค AI ํŠธ๋ž™ TIL: Flask๋ฅผ ํ†ตํ•œ ์„œ๋น„์Šค ๋‹ค๋ฃจ๊ธฐ

์œ ํ™˜์ตยท2021๋…„ 11์›” 6์ผ
0

Alexander Yoo์˜ Back-end Engineering

๋ชฉ๋ก ๋ณด๊ธฐ
6/6

Blueprint์™€ Jinja Template

Blueprint

API๋“ค์„ ๋ถ„๋ฅ˜ํ•˜๊ณ  ๊ด€๋ฆฌํ•œ๋‹ค.
Flask์˜ ๊ธฐ๋Šฅ์ด ์ ์  ๋Š˜์–ด๋‚ ์ˆ˜๋ก, ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์ฝ”๋“œ์˜ ์–‘์ด ์ฆ๊ฐ€ํ•œ๋‹ค.
์ด๋•Œ, Blueprint๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ธธ์–ด์ง„ ์ฝ”๋“œ๋ฅผ ๋ชจ๋“ˆํ™”ํ•ด์ฃผ์–ด ์ˆ˜์ • ๊ฐœ๋ฐœ๊ณผ ์œ ์ง€๋ณด์ˆ˜์— ์šฉ์ดํ•˜๊ฒŒ ์ฝ”๋“œ๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค.

Blueprint๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜์„ ๋•Œ์˜ ์˜ˆ

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')
...
if __name__ == '__main__':
	app.run(debug=True)
  • app.route์˜ ๊ฐœ์ˆ˜๊ฐ€ API์˜ ๊ฐœ์ˆ˜ (๊ต‰์žฅํžˆ ๋งŽ์•„์ง„๋‹ค)

Blueprint๋ฅผ ์‚ฌ์šฉํ–ˆ์„ ๋•Œ์˜ ์˜ˆ

app.py

from flask import Flask
from first_api import bp

app = Flask(__name__)
app.register_blueprint(bp)

if __name__ == '__main__':
	app.run(debug==True)
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')
  • app.py๋Š” ์˜ค๋กœ์ง€ ์„œ๋ฒ„๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.
  • blueprint๋Š” flask ์„œ๋ฒ„์™€ ์—ฐ๋™, blueprint๋ฅผ ์‚ฌ์šฉํ•œ ๊ฐ์ฒด๋กœ ๋ฐ”๋กœ ๋ผ์šฐํŒ… ๊ฐ€๋Šฅ.
  • ํŒŒ์ผ์„ ์—ฌ๋Ÿฌ ๊ฐœ ํšจ๊ณผ์ ์œผ๋กœ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜์—ฌ ์œ ์ง€๋ณด์ˆ˜์ ์ธ ์ธก๋ฉด์—์„œ ์ด์ ์„ ๊ฐ€์ง„๋‹ค.
  • Flask์˜ ์š”์ฒญ์œผ๋กœ URL์„ ์ƒ์„ฑ ํ•  ๋•Œ ํ™”๋ฉด์„ ์ถœ๋ ฅํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ Blueprint์™€ ์—ฐ๊ฒฐํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค.
  • API๋“ค์„ ๋”ฐ๋กœ ๋ชจ์•„์„œ ํŒŒ์ด์ฌ ํŒŒ์ผ๋“ค์„ ๊ตฌ์„ฑ

Jinja2๋ž€?

Jinja2๋Š” Python์—์„œ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” ํ…œํ”Œ๋ฆฟ์ด๋‹ค. ์„œ๋ฒ„์—์„œ ๋ฐ›์•„์˜จ ๋ฐ์ดํ„ฐ๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ๋ณด์—ฌ์ฃผ๊ณ  ๋น„๊ต์  ๊ฐ„๋žตํ•œ ํ‘œํ˜„์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€๊ณตํ•  ์ˆ˜ ์žˆ๋‹ค.

  • render_template๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํ…œํ”Œ๋ฆฟ์— ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ™์ด ๋ณด์—ฌ์ค€๋‹ค.
  • HTML ๋‚ด์—์„œ ํŒŒ์ด์ฌ ๋ฌธ๋ฒ•์ฒ˜๋Ÿผ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ๋‚ด์–ด ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ๋‹ค.

Jinja2 Template์—์„œ ๋ฐ์ดํ„ฐ ๋„˜๊ฒจ์ฃผ๊ธฐ - ๋‹จ์ผ๋ณ€์ˆ˜

app.py

@app.route('/')
def alex():
	return render_template('index.html', data='alex')
<html>
    <head>
    	<title> jinja example</title>
        <body>
        	{{ data }}
        </body>
    </head>
</html>

Jinja2 Template์—์„œ ๋ฐ์ดํ„ฐ ๋„˜๊ฒจ์ฃผ๊ธฐ - list

app.py

@app.route('/')
def alex():
	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 %}
    </body>
</html>

Jinja2 Template์—์„œ ๋ฐ์ดํ„ฐ ๋„˜๊ฒจ์ฃผ๊ธฐ - dictionary

app.py

@app.route('/')
def alex():
	my_data = {'name':'alex'}
	return render_template('index.html', data=my_data)

index.html

<html>
    <head>
    	<title>jinja example</title>
    </head>
    <body>
    	{{ data.get('name') }}
    </body>
</html>

๊ฒŒ์‹œํŒ์„ ์œ„ํ•œ CRUD ์„ค๊ณ„ ๋ฐ ์ œ์ž‘

API ๋™์ž‘ ์›๋ฆฌ

ํด๋ผ์ด์–ธํŠธ๋Š” HTTP request๋ฅผ API ์ฃผ์†Œ๋กœ ๋ณด๋‚ด๋Š” ๋ฐ, API ์„œ๋ฒ„์˜ ๊ธฐ๋Šฅ์œผ๋กœ ์–ด๋–ค ์‘๋‹ต์„ ๋“ค๋ ค์ค„ ์ง€ ํŒŒ์•…ํ•˜๊ณ , ์„œ๋ฒ„๋Š” page๋‚˜ JSON์˜ ํ˜•ํƒœ๋กœ ์‘๋‹ต์„ ๋Œ๋ ค์ค€๋‹ค.

ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์š”์ฒญํ•˜๋Š” ๋ชจ๋“  ์ž‘์—…์€ ๊ฐœ์ธ์˜ ์ปดํ“จํ„ฐ(๋ธŒ๋ผ์šฐ์ €)์—์„œ ์ด๋ฃจ์–ด์ง„๋‹ค. ์š”์ฒญ์ด ์„œ๋ฒ„๋กœ ์ „๋‹ฌ ๋  ๋•Œ์—๋Š” HTTP request ํ˜•ํƒœ๋กœ ๋„˜์–ด๊ฐ„๋‹ค. ์ค‘๊ฐ„์˜ API ์ฃผ์†Œ๋“ค์€ ์„œ๋ฒ„์— ๋งคํ•‘๋˜์–ด ์žˆ๋‹ค.[@app.route()] ์ฆ‰, ์„œ๋ฒ„ ์•ˆ์—์„œ API์˜ ์ฃผ์†Œ๋ฅผ ํ™•์ธํ•˜๊ณ , ํ•ด๋‹น ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜๊ณ  ๋ฆฌํ„ด ๊ฐ’์„ ๋Œ๋ ค์ฃผ๋Š” ๊ฒƒ์ด ์‘๋‹ต์˜ ๊ณผ์ •์ด๋‹ค.

CRUD๋ž€?

  • Create : ๋ฐ์ดํ„ฐ์˜ ์ƒ์„ฑ
  • Read : ๋ฐ์ดํ„ฐ์˜ ์กฐํšŒ
  • Update : ๋ฐ์ดํ„ฐ์˜ ์ˆ˜์ •
  • Delete : ๋ฐ์ดํ„ฐ์˜ ์‚ญ์ œ

๋ฅผ ๋œปํ•œ๋‹ค. ์—ฌ๊ธฐ์„œ ๋˜ ๋ถ„๋ฅ˜๋ฅผ ํ•˜์ž๋ฉด, CREATE์™€ READ๋ฅผ ๋ฌถ๊ณ , Update์™€ Delete๋ฅผ ํ•จ๊ป˜ ๋ฌถ์„ ์ˆ˜ ์žˆ๋‹ค. ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃจ๋Š” ๊ธฐ์ค€์œผ๋กœ ๋ฌถ์€ ๊ฒƒ์ด๋‹ค.

Create๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๋Š” ์—ฐ์‚ฐ์ด๋‹ค.
Read๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด์˜ค๋Š” ์—ฐ์‚ฐ์ด๋‹ค. (์ „์ฒด ํ˜น์€ ํ•˜๋‚˜๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ๋‹ค.)
Update์™€ Delete๋Š” ๋ณธ์งˆ์ ์œผ๋กœ ์ €์žฅํ•˜๋Š” ์—ฐ์‚ฐ์ด๋‚˜, ์ฝ๊ธฐ ์ž‘์—…์— ํฐ ๋น„์ค‘์„ ๊ฐ€์ง„ ์ €์žฅ์ด๋‹ค. (๋ฐ์ดํ„ฐ๋ฅผ ๋จผ์ € ์ฝ์–ด์˜ค๊ณ , ์ฝ์–ด์˜จ ๋ฐ์ดํ„ฐ์— ์ˆ˜์ •/์‚ญ์ œ ์—ฐ์‚ฐ์„ ํ•œ๋‹ค.)

CRUD - API - DB ๋ช…๋ น์–ด ๋Œ€์‘

CRUDHTTP MethodDB ๋ช…๋ น์–ด
CreatePOSTINSERT
ReadGETSELECT
UpdatePUT, PATCH, (POST)UPDATE
DeleteDELETEDELETE

Authentication์ด๋ž€?

Authentication vs Authorization

  • Authentication(์ธ์ฆ)์€ ์‚ฌ์šฉ์ž๊ฐ€ ์–ด๋– ํ•œ ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์‚ฌ์šฉ์ž์ธ์ง€ ์•Œ๋ ค์ฃผ๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค (ex. log-in, 2FA, OTP, SMS, PIN)
  • Authorization(๊ถŒํ•œ)์€ ์‚ฌ์šฉ์ž๊ฐ€ ์–ด๋– ํ•œ ์—ญํ• ์„ ์„œ๋ฒ„์—์„œ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€๋ฅผ ๋œปํ•œ๋‹ค. ์ฆ‰, ์ธ์ฆ์ด ์ด๋ฃจ์–ด์ง„ ํ›„์— ๋ถ€์—ฌ๋˜๋Š” ๊ฒƒ์ด๋‹ค. (ex. ๋ฑ…ํ‚น -> ์˜ˆ๊ธˆ, ์†ก๊ธˆ, ์ธ์ถœ || ๋ฐฐ๋‹ฌ -> ์ฃผ๋ฌธ, ๊ฒฐ์ œ || Mail -> ์“ฐ๊ธฐ, ์ฝ๊ธฐ, ์‚ญ์ œ || SNS -> '๋‚ด๊ฐ€ ์“ด ๊ธ€ ์ˆ˜์ •')

Authentication

์‚ฌ์šฉ์ž๊ฐ€ ๋ˆ„๊ตฌ์ธ์ง€ ํ™•์ธํ•˜๋Š” ์ ˆ์ฐจ์ด๋ฉฐ, ๋Œ€ํ‘œ์ ์ธ ์˜ˆ๋กœ ํšŒ์›๊ฐ€์ž…ํ•˜๊ณ  ๋กœ๊ทธ์ธ ํ•˜๋Š” ๊ณผ์ •์ด ์žˆ๋‹ค.
1. ํšŒ์›๊ฐ€์ž… -> ๋‚ด ์ •๋ณด๋ฅผ ์„œ๋ฒ„๋กœ ์ „์†กํ•œ๋‹ค. create๋กœ ๊ณ„์ •์„ ๋งŒ๋“ค ๋•Œ, ํŒจ์Šค์›Œ๋“œ์˜ ๊ฒฝ์šฐ ์•”ํ˜ธํ™”๋ฅผ ๊ฑฐ์ณ ์ €์žฅ๋œ๋‹ค.
2. ๋กœ๊ทธ์ธ -> IP/PW๋ฅผ ์ž…๋ ฅํ•˜์—ฌ ์„œ๋ฒ„์— ์ „์†กํ•œ๋‹ค. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ •๋ณด๋ฅผ ์ฝ์–ด, ์ „์†กํ•œ ์ •๋ณด๋ž‘ ๊ฐ™์€ ๊ฒƒ์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค. ์ผ์น˜ํ•˜๋ฉด ๋กœ๊ทธ์ธ์ด ์ด๋ฃจ์–ด์ง„๋‹ค. (session, JWT[token])
3. ๋กœ๊ทธ์•„์›ƒ -> ์„ธ์…˜์˜ ์—ฐ๊ฒฐ์„ ๋Š๋Š”๋‹ค.

๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ ๊ตฌํ˜„

HTTP์˜ ํ•œ๊ณ„์ ์„ ๊ทน๋ณตํ•˜๊ธฐ ์œ„ํ•œ ๋ฐ์ดํ„ฐ

ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„๊ฐ„์˜ ํ†ต์‹ ์—์„œ (์š”์ฒญ/์‘๋‹ต == HTTP ํ†ต์‹ ์˜ ํ•œ ์‚ฌ์ดํด) ์„œ๋ฒ„๋Š” ํด๋ผ์ด์–ธํŠธ์˜ ์ ‘์† ์—ฌ๋ถ€๋ฅผ ์•Œ ์ˆ˜ ์—†๋‹ค. HTTP๋Š” ์ƒํƒœ ๊ฐ’์„ ์ €์žฅํ•˜๊ณ  ์žˆ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ด๋Ÿฌํ•œ ๊ฒƒ์„ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด ์ฟ ํ‚ค๋กœ ์ €์žฅํ•˜์—ฌ ์ „์†กํ•˜๋Š” ๊ฒƒ์ด๊ณ , ์„ธ์…˜์œผ๋กœ ์‹๋ณ„ํ•˜์—ฌ ์„œ๋ฒ„์—์„œ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

์ฟ ํ‚ค

ํด๋ผ์ด์–ธํŠธ์— ์ €์žฅ๋˜๋Š” ํ‚ค/๊ฐ’์ด ๋“ค์–ด ์žˆ๋Š” ๋ฐ์ดํ„ฐ์ด๋‹ค.

  • ์‚ฌ์šฉ์ž๊ฐ€ ๋”ฐ๋กœ ์š”์ฒญํ•˜์ง€ ์•Š์•„๋„, Request ์‹œ์— ์ž๋™์œผ๋กœ ์„œ๋ฒ„์— ์ „์†กํ•œ๋‹ค.
  • ์ด๋•Œ ์ฟ ํ‚ค๋Š” ํด๋ผ์ด์–ธํŠธ์˜ ๋ธŒ๋ผ์šฐ์ €์— ์ €์žฅ์ด ๋œ๋‹ค.

์„ธ์…˜

์ฟ ํ‚ค๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜์ง€๋งŒ ์„œ๋ฒ„ ์ธก์—์„œ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐ์ดํ„ฐ์ด๋‹ค.
ํด๋ผ์ด์–ธํŠธ์— ๊ณ ์œ  ID๋ฅผ ๋ถ€์—ฌํ•˜๊ณ  ํด๋ผ์ด์–ธํŠธ์— ์•Œ๋งž๋Š” ์„œ๋น„์Šค๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ์„œ๋ฒ„์—์„œ ๊ด€๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ณด์•ˆ์ด ์ฟ ํ‚ค๋ณด๋‹ค ์šฐ์ˆ˜ํ•˜๋‹ค.

๊ณตํ†ต์ : ์‚ฌ์šฉ์ž์˜ ์ •๋ณด๋ฅผ ๋‹ด๊ณ  ์žˆ๋‹ค.
์ฐจ์ด์ : ์„ธ์…˜์€ ์„œ๋ฒ„์—์„œ ๊ด€๋ฆฌํ•˜๋ฉฐ, ์ฟ ํ‚ค๋Š” ํด๋ผ์ด์–ธํŠธ์—์„œ ๊ด€๋ฆฌํ•œ๋‹ค.

๋กœ๊ทธ์ธ์˜ ๊ฒฝ์šฐ ์„ธ์…˜์—์„œ ์‚ฌ์šฉ. ์„œ๋ฒ„์—์„œ ๊ด€๋ฆฌ.

user_id = request.form['user_id']
user_pw = request.form['user_pw']
user = {'user_id': 'elice', '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)๋ฅผ ๋ณ€์ˆ˜์— ์ €์žฅํ•œ๋‹ค.
  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— user_id์™€ ๊ฐ™์€ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋Š”์ง€ ์ฐพ์•„์˜จ๋‹ค.
  • ์ž…๋ ฅ๋œ user_pw์™€ ์ €์žฅ๋œ ํŒจ์Šค์›Œ๋“œ๊ฐ€ ๊ฐ™์€์ง€ ์ฒดํฌํ•œ๋‹ค.
session['login'] = None
  • ๋กœ๊ทธ์•„์›ƒ์„ ํ•  ๋•Œ๋Š” ์ •๋ณด๋ฅผ ๋ฐ›์„ ํ•„์š”๊ฐ€ ์—†๋‹ค.
  • ํ˜„์žฌ ์ €์žฅ๋œ session์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋น„์›Œ ์ฃผ๋ฉด ๊ธฐ๋Šฅ์ด ์™„๋ฃŒ๋œ๋‹ค.

๋กœ๊น…

ํ”„๋กœ๊ทธ๋žจ์ด ์ž‘๋™ํ•  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ์ด๋ฒคํŠธ๋ฅผ ์ถ”์ ํ•˜๋Š” ํ–‰์œ„์ด๋‹ค.

์ด๋ฒคํŠธ: ํ”„๋กœ๊ทธ๋žจ์˜ ๊ธฐ๋Šฅ, ๋™์ž‘

ํ”„๋กœ๊ทธ๋žจ์˜ ๋ฌธ์ œ๋“ค์„ ํŒŒ์•…ํ•˜๊ณ  ์œ ์ง€๋ณด์ˆ˜ ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋ฉฐ, ๋กœ๊น…์„ ํ†ตํ•ด ๋ฐœ์ƒํ•œ ์—๋Ÿฌ๋ฅผ ์ถ”์ ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋กœ๊น… - level

DEBUG < INFO < WARNING < ERROR < CRITICAL : ์˜ค๋ฅธ์ชฝ์œผ๋กœ ๊ฐˆ์ˆ˜๋ก ์‹ฌ๊ฐ๋„๊ฐ€ ๋†’๋‹ค.
๊ธฐ๋ณธ ๋กœ๊ฑฐ ๋ ˆ๋ฒจ ์„ธํŒ…์€ WARNING์ด๊ธฐ ๋•Œ์— ์„ค์ • ์—†์ด INFO, DEBUG๋ฅผ ์ถœ๋ ฅํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
(๋†’์€ ์ˆœ์œผ๋กœ ์„ค์ •๋˜์žˆ์„ ์ˆ˜๋ก ํ•˜์œ„ ๋ ˆ๋ฒจ์€ ๋ฌด์‹œํ•œ๋‹ค.)

  • DEBUG: ์ƒ์„ธํ•œ ์ •๋ณด
  • INFO: ์ผ๋ฐ˜์ ์ธ ์ •๋ณด
  • WARNING: ์˜ˆ์ƒ์น˜ ๋ชปํ•˜๊ฑฐ๋‚˜ ๊ฐ€๊นŒ์šด ๋ฏธ๋ž˜์— ๋ฐœ์ƒํ•  ๋ฌธ์ œ
  • ERROR: ์—๋Ÿฌ ๋กœ๊ทธ. ์‹ฌ๊ฐํ•œ ๋ฌธ์ œ
  • CRITICAL: ํ”„๋กœ๊ทธ๋žจ ์ž์ฒด๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ
import logging

if __name__ == '__main__':
	logger.info('hello elice!')

ํŒŒ์ด์ฌ ๋””ํดํŠธ ๋กœ๊น… ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•œ๋‹ค.

import logging

if __name__ == '__main__':
	
    logger = logging.getLogger()
    logger.setlevel(logging.DEBUG)
    logger.info('hello elice!')
   #๋ ˆ๋ฒจ์„ ์ˆ˜๋™์œผ๋กœ ์„ค์ •ํ•˜๊ณ  ์ถœ๋ ฅํ•˜๋ฉด ์ •์ƒ์ ์œผ๋กœ ์ถœ๋ ฅ์ด ๋œ๋‹ค.

Flask์—์„œ ๋กœ๊น…

์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ Flask์˜ logger๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—๋Ÿฌ๋ฅผ ํ™•์ธ ๊ฐ€๋Šฅํ•˜๋‹ค.

from flask import Flask
app = Flask(__name__)

if __name__ == '__main__':
	app.logger.info('test')
    app.logger.debug('debug test')
    app.logger.error('error test')
    app.run()
profile
์‚ฌ์šฉ์ž์˜ ํŽธ์˜๋ฅผ ๋” ์ƒ๊ฐํ•˜๊ณ  ํŽธ์•ˆํ•œ UI/UX ๊ฐœ๋ฐœ์„ ๊ฟˆ๊พธ๋Š” ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์ž ์ง€๋ง์ƒ์ž…๋‹ˆ๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€