๐ŸŽจ'ํ”Œ๋ผ์Šคํฌ ์›น ๊ฐœ๋ฐœ' 2์žฅ

Jake_Youngยท2020๋…„ 7์›” 29์ผ
0

๊ธฐ๋ณธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ตฌ์กฐ

์ดˆ๊ธฐํ™”

๋ชจ๋“  ํ”Œ๋ผ์Šคํฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•œ๋‹ค.

์›น ์„œ๋ฒ„๋Š” ํด๋ผ์ด์–ธํŠธ๋กœ๋ถ€ํ„ฐ ์ˆ˜์‹ ํ•œ ๋ชจ๋“  ๋ฆฌํ€˜์ŠคํŠธ๋ฅผ ์ด ์˜ค๋ธŒ์ ํŠธ์—์„œ ์ฒ˜๋ฆฌํ•˜๋Š”๋ฐ,
์ด๋•Œ ์›น ์„œ๋ฒ„ ๊ฒŒ์ดํŠธ์›จ์ด ์ธํ„ฐํŽ˜์ด์Šค(WSGI)๋ผ๋Š” ํ”„๋กœํ† ์ฝœ์„ ์‚ฌ์šฉํ•œ๋‹ค.
์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ธ์Šคํ„ด์Šค๋Š” Flask ํด๋ž˜์Šค์˜ ์˜ค๋ธŒ์ ํŠธ์ด๋ฉฐ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ƒ์„ฑ๋œ๋‹ค

from flask import Flask
app = Flask(__name__)

Flask ํด๋ž˜์Šค ์ƒ์„ฑ์ž์— ํ•„์š”ํ•œ ํ•œ ๊ฐ€์ง€ ์ธ์ˆ˜๋Š” ๋ฉ”์ธ ๋ชจ๋“ˆ์˜ ์ด๋ฆ„์ด๋‚˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํŒจํ‚ค์ง€ ์ด๋ฆ„์ด๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋Š” ํŒŒ์ด์ฌ์˜ name ๋ณ€์ˆ˜๊ฐ€ ์ ์ ˆํ•œ ๊ฐ’์ด๋‹ค.

  • ํ”Œ๋ผ์Šคํฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ƒ์„ฑ์ž์— ์ „๋‹ฌ๋˜๋Š” name ์ธ์ˆ˜๋Š” route path๋ฅผ ๊ฒฐ์ •ํ•˜๊ฒŒ ๋˜๋ฉฐ ์ƒ๋Œ€์ ์ธ ๋ฆฌ์†Œ์Šค ํŒŒ์ผ๋“ค์„ ์ฐพ์„ ๋•Œ ํ™œ์šฉ๋œ๋‹ค.

๋ผ์šฐํŠธ์™€ ๋ทฐ ํ•จ์ˆ˜

URL๊ณผ ์ด URL์„ ์ฒ˜๋ฆฌํ•˜๋Š” ํ•จ์ˆ˜์˜ ๊ด€๋ จ์„ฑ์„ route๋ผ๊ณ  ํ•œ๋‹ค.

ํ”Œ๋ผ์Šคํฌ์—์„œ ๋ผ์šฐํŠธ๋ฅผ ์ •์˜ํ•˜๋Š” ๊ฐ€์žฅ ์†์‰ฌ์šด ๋ฐฉ๋ฒ•์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ธ์Šคํ„ด์Šค์—์„œ app.route ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

@app.route('/user/<name>') # ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋กœ ํ•จ์ˆ˜์˜ ๋™์ž‘์„ ๋‹ค๋ฅธ ํ˜•ํƒœ๋กœ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
def index(name): # ์ด๋Ÿฐ ํ•จ์ˆ˜๋ฅผ view ํ•จ์ˆ˜๋ผ๊ณ  ํ•œ๋‹ค.
	return '<h1>Hello World, %s!</h1>' % name
@app.route('/user/<int:id>') # ์™ผ์ชฝ ์ฒ˜๋Ÿผ ํƒ€์ž… ์ง€์ •๋„ ๊ฐ€๋Šฅ, ๊ธฐ๋ณธ์€ string

๊บฝ์‡ ('<','>')๋ฅผ ์ด์šฉํ•˜๋ฉด ๋™์ ์œผ๋กœ URL์„ ๋ฐ›๊ณ  ์ด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์„œ๋ฒ„ ์‹œ์ž‘

run ๋ฉ”์†Œ๋“œ๋Š” ํ”Œ๋ผ์Šคํฌ์˜ ํ†ตํ•ฉ ๊ฐœ๋ฐœ ์›น ์„œ๋ฒ„๋ฅผ ์‹คํ–‰ํ•œ๋‹ค

if __name__ == '__main__': # '์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์ง์ ‘ ์‹คํ–‰๋  ๋•Œ'๋ผ๋Š” ์˜๋ฏธ
	app.run(debug=True) # ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋‹ค๋ฅธ ์Šคํฌ๋ฆฝํŠธ์— ์˜ํ•ด ์ž„ํฌํŠธ๋˜๋ฉด ๊ฑด๋„ˆ ๋›ด๋‹ค. 

์„œ๋ฒ„๊ฐ€ ์‹คํ–‰๋˜๋ฉด ์„œ๋ฒ„๋Š” ๋ฃจํ”„๋ฅผ ์ง„ํ–‰ํ•˜๋ฉฐ request๋ฅผ ๊ธฐ๋‹ค๋ฆฐ๋‹ค

๋ฆฌํ€˜์ŠคํŠธ-์‘๋‹ต ์‚ฌ์ดํด

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ๋ฆฌํ€˜์ŠคํŠธ ์ปจํ…์ŠคํŠธ

๋ฆฌํ€˜์ŠคํŠธ๋ฅผ ์ˆ˜์‹ ํ•˜๋ฉด HTTP ๋ฆฌํ€˜์ŠคํŠธ๋ฅผ ์บก์Šํ™”ํ•˜์—ฌ ๋ฆฌํ€˜์ŠคํŠธ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

# ๋ทฐ ํ•จ์ˆ˜ ์•ž ๋’ค ๋‚ด์šฉ์€ ๋ชจ๋‘ ์ƒ๋žต
def index():
    user_agent = request.headers.get('User-Agent')
    return '<p>Your Browswer is %s</p>' % user_agent

์—ฌ๊ธฐ์„œ request๋Š” ์–ด๋–ป๊ฒŒ ์ „์—ญ ๋ณ€์ˆ˜์ฒ˜๋Ÿผ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์—ˆ์„๊นŒ?
์ปจํ…์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“ค์—ˆ๋‹ค
ํ”Œ๋ผ์Šคํฌ์—๋Š” ๋‘ ๊ฐ€์ง€ ์ปจํ…์ŠคํŠธ๊ฐ€ ์žˆ๋‹ค.

  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ปจํ…์ŠคํŠธ

    1. current_app: ํ™œ์„ฑํ™”๋œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์œ„ํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ธ์Šคํ„ด์Šค
    2. g: ๋ฆฌํ€˜์ŠคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋™์•ˆ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ž„์‹œ ์Šคํ† ๋ฆฌ์ง€๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์˜ค๋ธŒ์ ํŠธ
  • ๋ฆฌํ€˜์ŠคํŠธ ์ปจํ…์ŠคํŠธ

    1. request: ํด๋ผ์ด์–ธํŠธ์— ์˜ํ•ด ์†ก์‹ ๋œ HTTP ๋ฆฌํ€˜์ŠคํŠธ์˜ ์ฝ˜ํ…์ธ ๋ฅผ ์บก์Šํ™”ํ•˜๋Š” ๋ฆฌํ€˜์ŠคํŠธ ์˜ค๋ธŒ์ ํŠธ
    2. session: ์‚ฌ์šฉ์ž ์„ธ์…˜์ด๋ฉฐ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋ฆฌํ€˜์ŠคํŠธ ์‚ฌ์ด์˜ "remembered"์ธ ๊ฐ’๋“ค์„ ์ €์žฅํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•˜๋Š” ๋”•์…”๋„ˆ๋ฆฌ

ํ”Œ๋ผ์Šคํฌ๋Š” ๋ฆฌํ€˜์ŠคํŠธ๋ฅผ ๋””์ŠคํŒจ์น˜ํ•˜๊ธฐ ์ „์— ๋‘ ์ปจํ…์ŠคํŠธ๋ฅผ ๋ชจ๋‘ ํ™œ์„ฑํ™”(push)ํ•˜๋ฉฐ, ๋ฆฌํ€˜์ŠคํŠธ๊ฐ€ ์ฒ˜๋ฆฌ๋  ๋•Œ ๊ทธ๊ฒƒ๋“ค์„ ์‚ญ์ œํ•œ๋‹ค.

from hello import app # ๋‹ค๋ฅธ ํŒŒ์ผ์˜ app์„ ๊ฐ€์ ธ์˜จ๋‹ค
from flask import current_app # ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ปจํ…์ŠคํŠธ ์ค‘ ํ•˜๋‚˜

current_app.name # ์—๋Ÿฌ ๋ฐœ์ƒ

app_ctx = app.app_context()
app_ctx.push() # ํ™œ์„ฑํ™”
current_app.name # 'hello'
app_ctx.pop() # ๋น„ํ™œ์„ฑํ™”

๋ฆฌํ€˜์ŠคํŠธ ๋””์ŠคํŒจ์น˜

url_map์„ ์‚ฌ์šฉํ•˜๋ฉด URL ๋งต์ด ์–ด๋–ป๊ฒŒ ๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

app.url_map
Map([<Rule '/' (HEAD, OPTIONS, GET -> index>,
<Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static,
<Rule '/user/<name>' (HEAD, OPTIONS, GET) -> user])

๋ฆฌํ€˜์ŠคํŠธ ํ›„ํฌ

๋•Œ๋•Œ๋กœ ๊ฐ๊ฐ์˜ ๋ฆฌํ€˜์ŠคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์ „ํ›„์— ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์€ ์œ ์šฉํ•˜๋‹ค.
์ด๋ฅผ ์œ„ํ•ด ๋ฆฌํ€˜์ŠคํŠธ ํ›„ํฌ๋ฅผ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

  1. before_first_request: ํ•จ์ˆ˜๋ฅผ ๋“ฑ๋กํ•˜์—ฌ ์ฒซ ๋ฒˆ์งธ ๋ฆฌํ€˜์ŠคํŠธ๊ฐ€ ์ฒ˜๋ฆฌ๋˜๊ธฐ ์ „์— ์‹คํ–‰ํ•œ๋‹ค.
  2. before_request: ๊ฐ ๋ฆฌํ€˜์ŠคํŠธ ์ „์— ์‹คํ–‰ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋“ฑ๋กํ•œ๋‹ค
  3. after_request: ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š๋Š” ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด, ๊ฐ ๋ฆฌํ€˜์ŠคํŠธ ์ดํ›„์— ์‹คํ–‰ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋“ฑ๋กํ•œ๋‹ค.
  4. teardown_request: ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š๋Š” ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋”๋ผ๋„, ๊ฐ ๋ฆฌํ€˜์ŠคํŠธ ์ดํ›„์— ์‹คํ–‰ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋“ฑ๋กํ•œ๋‹ค.

๋ฆฌํ€˜์ŠคํŠธ ํ›„ํฌ ํ•จ์ˆ˜์™€ ๋ทฐ ํ•จ์ˆ˜ ์‚ฌ์ด์— ๋ฐ์ดํ„ฐ๋ฅผ ๊ณต์œ ํ•˜๊ธฐ ์œ„ํ•œ ๊ณตํ†ต ํŒจํ„ด์€ g ์ปจํ…์ŠคํŠธ ์ „์—ญ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

์‘๋‹ต

๋ทฐ ํ•จ์ˆ˜๊ฐ€ ๋‹ค๋ฅธ ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ์‘๋‹ต์œผ๋กœ ๋ณด๋‚ด๊ณ ์ž ํ•  ๋•Œ๋Š”, ์‘๋‹ต ํ…์ŠคํŠธ ์ดํ›„์— ๋‘๋ฒˆ ์งธ ๋ฆฌํ„ด๊ฐ’์œผ๋กœ ๋‰ด๋ฉ”๋ฆฐ(numeric) ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผํ•œ๋‹ค.

# ๋ทฐ ์ด์ „ ์ฝ”๋“œ๋Š” ์ƒ๋žต
def index():
  return '<h1>'hello'</h1>', 400 # ์‘๋‹ต์ฝ”๋“œ๋กœ 400์„ ๋ณด๋‚ธ๋‹ค

์„ธ๋ฒˆ ์งธ ์ธ์ˆ˜๋ฅผ ๋ถ™์ด๋ฉด ์ด๋Š” ์‘๋‹ต ํ—ค๋”์˜ ๋”•์…”๋„ˆ๋ฆฌ์— ํ•ด๋‹นํ•œ๋‹ค.
์‘๋‹ต์„ Response ์˜ค๋ธŒ์ ํŠธ๋กœ ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

from flask import make_response

@app.route('/')
def index():
  response = make_response('<h1>response with cookie</h1>')
  response.set_cookie('answer', '42')
  return response

๊ทธ๋Ÿฌ๋ฉด ์ด๋ ‡๊ฒŒ ์‘๋‹ต์— ์ฟ ํ‚ค๋ฅผ ๋ถ™์ผ ์ˆ˜ ์žˆ๋‹ค.

๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ์‘๋‹ต์˜ ์˜ˆ์ œ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค

from flask import redirect

@app.route('/')
def index():
  return redirect('http://www.example.com')

ํŠน๋ณ„ํ•œ ์‘๋‹ต์œผ๋กœ๋Š” abort ํ•จ์ˆ˜๊ฐ€ ์žˆ๋‹ค.
์ด ํ•จ์ˆ˜๋Š” ์—๋Ÿฌ๋ฅผ ํ•ธ๋“ค๋ง ํ•˜๊ธฐ ์œ„ํ•œ ํ•จ์ˆ˜์ด๋‹ค.

from flask import abort

@app.route('/user/<id>')
def get_user(id):
  user = load_user(id)
  if not user:
    abort(404)
  return '<h1>Error, %s</h1>' % user.name

ํ”Œ๋ผ์Šคํฌ ํ™•์žฅ

pip install flask-script

ํ”Œ๋ผ์Šคํฌ์˜ ๊ฐœ๋ฐœ ์›น ์„œ๋ฒ„์— ์„ค์ • ์˜ต์…˜์„ ๋„˜๊ฒจ์ฃผ๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์€ app.run()์— ์ธ์ˆ˜๋กœ ๋„˜๊ฒจ์ฃผ๋Š” ๊ฒƒ์ด๋‹ค.
ํ•˜์ง€๋งŒ ๋” ์ด์ƒ์ ์ธ ๋ฐฉ๋ฒ•์€ ์ปค๋ฉ˜๋“œ ๋ผ์ธ ์ธ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
์‚ฌ์šฉ ์˜ˆ์ œ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

from flask.ext.script import Manager # Manager๋ฅผ ์จ๋ณด๊ฒ ๋‹ค.
manager = Manager(app)

# ...

if __name__ == '__main__':
  manager.run()

flask.ext ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋กœ extension์„ ๊ฐ€์ ธ์˜ค๊ณ 
๋ฉ”๋‹ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ธ์Šคํ„ด์Šค(app)๋ฅผ ์ƒ์„ฑ์ž(Manager)์— ์ธ์ˆ˜๋กœ ๋„˜๊น€์œผ๋กœ์จ ์ดˆ๊ธฐํ™”๋œ๋‹ค.
์„œ๋ฒ„ ์Šคํƒ€ํŠธ์—…์€ manager.run()์œผ๋กœ ๋ผ์šฐํŠธ๋˜๋ฉฐ ์ปค๋งจ๋“œ ๋ผ์ธ์€ ํŒŒ์‹ฑ๋จ.

profile
์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์™€ ํŒŒ์ด์ฌ ๊ทธ๋ฆฌ๊ณ  ์ปดํ“จํ„ฐ์™€ ๋„คํŠธ์›Œํฌ

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