Werkzeug๋ ๋ง์ ์ ์ฉํ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค. ์ฒ์๋ถํฐ ์์ํ๋ ๊ฒ๋ณด๋ค ASGI๋ฅผ ์ง์ํ๋ ๊ฒ์ด ํจ์ฌ ์ฌ์ธ ๊ฒ์ ๋๋ค.
์, Werkzeug์ Flask๋ ๊ฒฐ๊ตญ ASGI๋ฅผ ์ง์ํ ๊ฒ์ ๋๋ค. ์ด์ ๋ํ ์ผ์ ์ ์์ง๋ง ๋๊ตฐ๊ฐ PR์ ์์ํ๋ค๋ฉด ๊ธฐ๊บผ์ด ๊ฒํ ํ๋ ๋ฐ ๋์์ ๋๋ฆฌ๊ฒ ์ต๋๋ค.
๊ทธ๋ฌ๋ ๋๋ ๊ทธ๊ฒ์ ๊ตฌํํ๋ ์ฌ๋์ด ์๋๋ฏ๋ก ์ปค๋ฎค๋ํฐ์ ๋์์ด ํ์ํฉ๋๋ค. ์๋์ ์ต์ ์ ๋ฐ์ดํธ๋ฅผ ์ฐธ์กฐํ์ญ์์ค. https://github.com/pallets/werkzeug/issues/1322#issuecomment -600926145
์ด ์์ ์ ๊ด์ฌ์ด ์์ต๋๋ค.
์ผ๋ถ ์๋ํ์ง๋ง ํดํน๋ ASGI ์ง์์ด ์งํ ์ค์ ๋๋ค: werkzeug , flask . ๋ ์งํํ๊ธฐ ์ ์ ๊ฐ์ง๊ณ ๊ณ์ ๊ณํ์ ๋ํด ๋ ์๊ณ ์ถ์ต๋๋ค.
๋ด๊ฐ ๊ฑฐ๊ธฐ์์ ํ ๋ชจ๋ ๊ฒ์ด ์ผ๋ฐ์ ์ผ๋ก ๋ ์ข์ ์ ์๋ค๋ ์ฌ์ค์ ๋์ด์ ์ด๋ฏธ ๋์๊ฒ ์ผ์ด๋๋ ์ผ:
๋น์ ์ ์๊ฐ์ ์ ์๊ฒ ๋ง ํด์ฃผ์ธ์.
์ ๋ ์ค๋ ๋์์ ๋๊ธฐ ์ฝ๋๋ฅผ ์คํํ์ฌ ์์ ํ์๋ฅผ ์ง์ํ๊ณ ์์ต๋๋ค(๋ฐ์ดํฐ๋ฅผ ๋น๋๊ธฐ์ ์ผ๋ก ์ฝ๋ ๋์ ์ฐจ๋จ). ๋๋ ์ด๊ฒ์ด ํ ๊ฒ์ด๋ผ๊ณ ์๊ฐํ์ง ์์ต๋๋ค. ๋ด๊ฐ ์ ํธํ๋ ์ ๊ทผ ๋ฐฉ์์ IO๋ฅผ ์ ์ธํ๋ ๊ฒ์ ๋๋ค.
๊ฐ๋ฒผ์ด ํฐ์น ์ ๊ทผ ๋ฐฉ์์ ๊ธฐ์กด ํ์๋ฅผ ๋ค์ ๊ตฌํํ์ง๋ง ๋น๋๊ธฐ IO๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค. ๋ ๊ฐ์ ํ์ ํด๋์ค๊ฐ ํ๋ ์๋์์ ๊ณตํต sans-IO ๊ตฌํ์ ๊ณต์ ํ ์ ์๋ค๋ฉด ๋ ๊นจ๋ํ๊ฒ ์ง๋ง ๊ธฐ์กด ๊ตฌํ์ ๋ณต์ ํ๊ณ ์ฝ๊ฐ ์์ ํ๋ ๊ฒ์ด ๋ ์ค์ฉ์ ์ผ ์ ์์ต๋๋ค.
์ปจํ ์คํธ ๋ก์ปฌ ์ง์์ ๋งค์ฐ ์ทจ์ฝํฉ๋๋ค.
์ปจํ
์คํธ ๋ก์ปฌ(asyncio์ฉ)์ 3.7 stdlib์ ์์ต๋๋ค. https://docs.python.org/3.7/library/contextvars.html
์ด์ ๋ฒ์ ์ Python์ ์ง์ํ๊ธฐ ์ํด ์ ํ์ compat ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํจ๊ป ์ฌ์ฉํ๋ ๊ฒ ๊ฐ์ต๋๋ค. (๋๋ Flask์ ASGI๊ฐ 3.7 ์ด์์ด ๋ ๊ฒ์ด๋ผ๊ณ ๊ฐ์ ํ์ญ์์ค)
werkzeug๋ ์ค๋ ๋ ๋ก์ปฌ์ ์ฌ์ฉํฉ๋๊น? (๋๋ Flask๊ฐ ํ๋ค๋ ๊ฒ์ ์๊ณ ์์ต๋๋ค)
ASGI์์ ์คํํ ๋ ๋๊ธฐ ํจ์์ ๋ํ ์์ฒญ ์ ์์ ๋ฐ์ดํฐ๋ฅผ ๊ตฌ๋ฌธ ๋ถ์ํ๋ ํ์คํ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค.
์์ ๋ฐ์ดํฐ๋ฅผ ๊ตฌ๋ฌธ ๋ถ์ํ๊ธฐ ์ํ ๋๊ธฐ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ์ง ์๋ ๊ฒ์ด ์ข์ต๋๋ค. (๋๋ ์ด๋ค ์์ผ๋ก๋ ์์ฒญ ๋ณธ๋ฌธ์ ์ก์ธ์คํ๊ธฐ ์ํด) ๋์ ๋น๋๊ธฐ API๋ฅผ ์ ๊ณตํฉ๋๋ค. ์ฌ๊ธฐ์์ ๋ช ๊ฐ์ง ์๋ฅผ ๋ณด๋ ค๋ฉด Starlette์ API๋ฅผ ์ฐธ์กฐํ์ธ์. https://github.com/encode/starlette#body
Python 3.7์ด ๋์๊ธฐ ๋๋ฌธ์ ๋ค๋ฅธ ์ฝ๋๊ฐ ์ํฅ์ ๋ฐ์ง ์๋ ํ Python 3.7์ด ํ์ํ ๋น๋๊ธฐ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ ๊ฒ์ ๋ฐ๋ํ์ง ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๊ธฐ๋ณธ 3.7 ์๋ฃจ์ ๋งํผ ์ข์ ๋ฐฑํฌํธ๊ฐ ์๋ค๋ฉด ๋ ์ข์ต๋๋ค!
๋น๋๊ธฐ ์์ ๋ฐ์ดํฐ ๊ตฌ๋ฌธ ๋ถ์์ ๊ดํด์๋... ๋น๋๊ธฐ ํจ์์์ await request.parse()
์ ๊ฐ์ ๊ฒ์ผ๋ก ์ถฉ๋ถํ ๊ฒ ๊ฐ์๋ฐ ๊ตฌ๋ฌธ ๋ถ์๋์ง ์์ ์์ ๋ฐ์ดํฐ์ ์ก์ธ์คํ๋ ค๊ณ ํ ๋ ์์ธ๊ฐ ๋ฐ์ํฉ๋๊น?
๋ฌผ๋ก ์
๋๋ค. ๋๋ $ values = await request.values()
values = await request.values
values
๋ฐ ์น๊ตฌ๋ฅผ ๋น๋๊ธฐ์์ผ๋ก ๋ง๋ญ๋๋ค.
์ฌ์ด์ ํ ๋นํ์ง ์๊ณ dict ์์๋ฅผ ์ง์ ๊ฐ์ ธ์ค๋ ๋์ ๋น๋๊ธฐ ํธ์ถ์ ์ํํ๋ ค๋ฉด (await request.form)['foo']
์ ๊ฐ์ ๋ค์ ์ถํ ๊ฒ์ด ํ์ํ์ง ์์ต๋๊น?
๋ค :(
๊ทธ๋ฌ๋ ๊ทธ๊ฒ์ด ํนํ ํผํ ์ ์๋์ง ํ์คํ์ง ์์ต๋๋ค. ๋๋ ์๊ฐํ์ง ์๋๋ค
form = await request.form
form['foo']
์ ๋ง ๊ทธ ์ด์๋ ์ดํ๋ ์๋๋ค.
await request.parse()
request.form['foo']
๊ทธ๊ฒ์ ๋ถ๋ช ํ ์ทจํฅ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง ์ ์์ง๋ง.
๋๋ ์ฐ๋ฆฌ๊ฐ _members_๊ฐ ๋ชจ๋ ๋น๋๊ธฐํ๋๋ "๋น๋๊ธฐ ์ฌ์ "์ ๋์ ๋ฐ๋ช ํ ์๋ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
๋ฌผ๋ก , ์๋๋ฉด ๊ฐ๊ณผ ์น๊ตฌ๋ฅผ ๋น๋๊ธฐ์์ผ๋ก ๋ง๋์ญ์์ค. values โโ= await request.values โโ๋๋ values โโ= await request.values(), ์ฃผ๋ก ์ด๋ ๊ฒ์ด ๋ ์ข์ ๋ณด์ด๋์ง์ ๋ฐ๋ผ ๋ค๋ฆ ๋๋ค.
์์ฑ๋ณด๋ค๋ I/O ์ํ ์์ ์ ๋ํ ํจ์ ํธ์ถ์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
(await request.form)['foo'] ์ ๊ฐ์ ๋ค์ ์ถํ ๊ฒ์ด ํ์ํ์ง ์์ต๋๊น? ์ฌ์ด์ ํ ๋นํ์ง ์๊ณ dict ์์๋ฅผ ์ง์ ๊ฐ์ ธ์ค๋ ๋์ ๋น๋๊ธฐ ํธ์ถ์ ์ํํ๋ ค๋ฉด?
์ด๊นจ๋ฅผ ์ผ์ฑ - ํ์ง ๋ง์ธ์.
asyncio๋ ์ฝ๋๋ฒ ์ด์ค์ ์ด๋ ๋ถ๋ถ์ด I/O๋ฅผ ์ํํ๋์ง์ ๋ํด ๋ฐ๋์ ๋ ๋ช ์์ ์ด๋ฏ๋ก ์ด๋ฅผ ๋ณ๋์ ์ค๋ก ๋๋๋ ๊ฒฝํฅ์ด ์์ต๋๋ค.
form = await request.form()
form['foo']
๋น๋๊ธฐ ์ง์์ ์ถ๊ฐํ๋ ๋ฐ ์ฐฌ์ฑํ์ง๋ง ์ฌ์ ํ Python 2 ๋ฐ ๋๊ธฐํ ๋ฒ์ ์ ์ค๋จํ ์ ์์ต๋๋ค. @njsmith ์๊ฒ ๋ค์ ํ ๊ฐ์ง ์ ๊ทผ ๋ฐฉ์์ ๋ชจ๋ ๊ฒ์ ๋น๋๊ธฐ์์ผ๋ก ์์ฑํ ๋ค์ 2to3๊ณผ ์ ์ฌํ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ ๋๊ธฐํ ๋ฒ์ ์ ์์ฑํ๋ ๊ฒ์ ๋๋ค. ๋ถ๋ช ํ ๊ทธ๊ฒ์ urllib3์์ ์๋๋๊ณ ์์ง๋ง ๊ทธ๊ฒ์ ๋ํด ์ถฉ๋ถํ ๋ชจ๋ฆ ๋๋ค.
request.form
๋ฑ ๋ค์ ์๋ ๊ฐ์ฒด์ ๋ง๋ฒ์ ์ถ๊ฐํ ์ ์๋์ง ๊ถ๊ธํฉ๋๋ค. ๊ทธ๋์ ํธ์ถํ๋ฉด ๋น๋๊ธฐ ์์
์ ์ํํ๋ ๋ฐ๋ฉด ์ผ๋ฐ์ ์ธ dict-like ๋ฉ์๋๋ ๋๊ธฐํ๋๊ณ ๋น๋๊ธฐ ๋ชจ๋์์๋ ์คํจํฉ๋๋ค. ๋๋ ๋น๋๊ธฐ ๋ชจ๋์์ request.form
๋ฑ์ ๋ํ ์ก์ธ์ค์ ์คํจํ๊ณ ๋น๋๊ธฐ ๋ฒ์ ์ ๋ํด ๋ณ๋์ ์ด๋ฆ์ ์ฌ์ฉํ ์ ์์ต๋๋ค(์: request.parse_form()
).
๋๋... request_class = AsyncRequest
๋น๋๊ธฐ๋ฅผ ์ํ๋ ๊ฒฝ์ฐ; ์ด๊ฒ์ ์ค์ ๋ก AsyncFlask
ํด๋์ค์ ๊ธฐ๋ณธ๊ฐ์ด ๋ ์ ์์ต๋๋ค.
๋๋... request_class = ๋๊ตฐ๊ฐ๊ฐ ๋น๋๊ธฐ๋ฅผ ์ํ๋ ๊ฒฝ์ฐ AsyncRequest; ์ด๊ฒ์ ์ค์ ๋ก AsyncFlask ํด๋์ค์ ๊ธฐ๋ณธ๊ฐ์ด ๋ ์ ์์ต๋๋ค.
๊ทธ๊ฒ์ ๋์๊ฒ ์๋ฏธ๊ฐ ์๋ ์ ๊ทผ ๋ฐฉ์์ ๋๋ค. ๋ค.
ํผ ํ์์ ๊ดํด์๋ #1330์์ sansio-ing์ ์๋ํ์ต๋๋ค.
https://github.com/andrew-d/python-multipart ์ 100% ์ ์ฉ ๋ฒ์์ ์คํธ๋ฆฌ๋ฐ ์์ ํ์ ๊ตฌํ๋ ์์ต๋๋ค. (๋ค๋ฅธ ํ๋๋ฅผ ์ฐพ์์ง๋ง "ํผ๋ ๋ฐ์ดํฐ, ์ด๋ฒคํธ ์ฒ๋ฆฌ" ํ๋ฆ์ ์ฝ๊ฒ ์ ์ํ ์ ์๋์ง ๋ช ํํ์ง ์์์ต๋๋ค.)
python-multipart
๋ ํ์ฌ Starlette์ ์ฌ์ฉ ์ค์ธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์
๋๋ค. ์ฌ๊ธฐ์์ ๋น๋๊ธฐ ์คํธ๋ฆผ๊ณผ์ ํตํฉ์ ์ดํด๋ณผ ์ ์์ต๋๋ค. https://github.com/encode/starlette/blob/master/starlette/formparsers.py#L207
๋๋ ๋ํ ๋๊ธฐํ ๋ฐ ๋น๋๊ธฐ ํธํ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ๋ ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ ๋ํด ์๊ฐํ๊ณ ์์ต๋๋ค. Starlette์ ๋ํด์๋ ๊ทธ๋ ๊ฒ ํ๊ธฐ๋ฅผ ์ํ๊ธฐ ๋๋ฌธ์ ๋๋ค(Werkzeug์ ๋ค๋ฅธ ๋ฐฉํฅ์ผ๋ก ๊ฐ๊ณ ์์ง๋ง ์ ์๊ฒ๋ "๊ธฐ์กด ๋น๋๊ธฐ ์ธํฐํ์ด์ค๊ฐ ์์ต๋๋ค. ์ด๋ป๊ฒ ํด์ผ ์ด์ ๋๊ธฐํ ํญ๋ชฉ๋ ํ์ํ์ญ์์ค.")
Starlette์ ๊ฒฝ์ฐ ์ค์ ๊ตฌ๋ฌธ ๋ถ์์ async parse(self)
๋ฉ์๋๋ก ํธ์ํ๊ณ ์ผ๋ฐ์ ์ผ๋ก ์์ฒญ ๋์คํจ์น ์ค ์ธ์ ๊ฐ๋ ํธ์ถํ์ง๋ง ์ผ๋ฐ ์ผ๋ฐ ์์ฑ form
, files
๋ฑ์ ๋
ธ์ถํฉ๋๋ค. ... ์ฌ์ฉ์ ์ฝ๋์์ ๊ฒฐ๊ณผ์ ์ก์ธ์คํฉ๋๋ค.
์ฃผ์ ์์ ๋ฒ์ด๋์ง๋ง ์ธ๊ธฐ ์๋ ASGI ๋ฐ werkzeug ์ฌ๋ก์ ๊ด๋ จ์ด ์์ต๋๋ค(์ด ๋ฌธ์ ๋ฅผ ํ์ ์ํค๊ณ ์ถ์ง ์์ง๋ง ์ถ๊ฐํ ๋ด์ฉ ์์ด ์ค๋ณต ๋ฌธ์ ๋ฅผ ๋ง๋ค๊ณ ์ถ์ง๋ ์์).
https://github.com/django-extensions/django-extensions with ./manage.py runserver_plus
๋ฐ https://github.com/django/channels(ASGI ์ฌ์ฉ)๋ฅผ ์คํ ์ค์ธ ๊ฒฝ์ฐ Opcode -1
์ธ์คํํฐ์์ ./manage.py runserver
๋ฅผ ์คํํด ๋ณด์ธ์.
(Werkzeug๋ django-extensions๊ฐ ์๋ Django์ ํ๋ ์๋์์ ์ฌ์ฉ๋๋ฉฐ ๋๋ฒ๊น
์ ์ํด runserver_plus
๋ก ๊ฐ๋ฐํ๋ ๋ฐ ๋๋ฌด ์ต์ํด์ ๋ช ์๊ฐ ๋์ ์ด์ ๋ฅผ ์์๋์ต๋๋ค.)
๊ฐ๋ฐ์์ https๋ฅผ ์ฌ์ฉํ ์ ์๋๋ก runserver_plus๋ฅผ ์ฌ์ฉํฉ๋๋ค.
์ด์ Django ์ฑ๋์ ์ฌ์ฉํ์ฌ Websockets ์ง์์ ์ถ๊ฐํ๋ ค๊ณ ํ๋๋ฐ ์ฑ๋์ด runserver๋ฅผ ์ฌ์ฉํ๊ณ runserver_plus๋ฅผ ์ง์ํ์ง ์๋๋ค๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค. ๋ฐ๋ผ์ ์ฑ๋์ ์ฌ์ฉํ ์๋ ์๊ณ https๋ฅผ ์ฌ์ฉํ ์๋ ์์ต๋๋ค. ๋ ๋ค ์ฌ์ฉํ ์๋ ์์ต๋๋ค!
@davidism ์ด ์ฃผ์ ์ ๋ํ ๋ง์ง๋ง ๋ต๋ณ ์ดํ Flask์ ๋ํ ASGI ์ง์ ๊ตฌํ์ ๋ณ๊ฒฝ ์ฌํญ์ด ์๋์ง, Python 2์ ๋ํ ์ง์์ ์ข ๋ฃํ๊ธฐ ์ํด ์ด ์์ ๊ณผ ๊ด๋ จํ์ฌ ๊ณํ์ด ๋ณ๊ฒฝ๋์๋์ง ์ฌ๋ถ๋ฅผ ์๋ ค์ฃผ์ญ์์ค.
2018๋ 7์ 2์ผ @davidism ์ ๋ค์๊ณผ ๊ฐ์ด ์๋๋ค.
๋ถ๋ช ํ ๊ทธ๊ฒ์ urllib3์์ ์๋๋๊ณ ์์ง๋ง ๊ทธ๊ฒ์ ๋ํด ์ถฉ๋ถํ ๋ชจ๋ฆ ๋๋ค.
์ผ๋ง ์ ์ ์ด๊ฒ์ ๋ณด์์ต๋๋ค. ๋๊ตฐ๊ฐ ๋ ๋ฐฐ์ฐ๊ณ ์ถ๋ค๋ฉด python-trio/urllib3#1์ ๋ง์ ์ธ๋ถ ์ ๋ณด๊ฐ ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ๋ค์์ ํฌํจํ๋ urllib3/urllib3#1323์ ๋ํ ๋งํฌ๋ฅผ ํ์ธํ์ธ์.
์๋ฃจ์ : ์ฐ๋ฆฌ๋ async/await ์ฃผ์์ด ์๋ ๋ฒ์ ์ ์ฝ๋ ๋ณต์ฌ๋ณธ์ ์ ์งํ๊ณ ์ฝ๊ฐ์ ์คํฌ๋ฆฝํธ๊ฐ ๋๊ธฐ ๋ณต์ฌ๋ณธ์ ์๋์ผ๋ก ๋ค์ ์ ๊ฑฐํ์ฌ ์ ์งํฉ๋๋ค. ์๋ฆ๋ต์ง๋ ์์ง๋ง ๋ชจ๋ ๋์์ด ๋ ๋์๋ค๊ณ ๋งํ ์ ์๋ ํ...
(๊ด์ฌ ์์ผ๋ฉด ๊ฑฐ๊ธฐ์์ ๊ณ์ ์ฝ์ผ์ญ์์ค.)
์ด ๋ฌธ์ ๋ฅผ ๋ค์ ๋ ์ด๋์ ์ฌ๋ฆฌ๊ธฐ ์ํ ์์ ๋ฒํ. ์ฌํด 3.5๊ฐ EOL์ ๋๋ฌํ๋ฉด ๋น๋๊ธฐ ์ง์์ ๋ํด ์๊ฐํ๊ธฐ ์์ํ๊ธฐ์ ์ข์ ์๊ธฐ๋ผ๊ณ ์๊ฐํฉ๋๋ค.
์ด ๊ธ์ด ๊ฒ์๋ ์ง 1๋ ๋ฐ์ด ์ง๋ฌ์ง๋ง ์ด๋ฅผ ๊ตฌํํ๊ธฐ ์ํ ํ๋์ด ๋ง์ง ์์์ต๋๋ค. ๋๋ ๊ฐ์ธ์ ์ผ๋ก asyncio์ ๋ํ ๊ฒฝํ์ด๋ ํ์์ฑ์ด ์์ผ๋ฉฐ ASGI๋ฅผ ์ข์ํ์ง๋ง ๊ฒฐ์ฝ ๋ ์์ ์ ๋งก์ ์ผ์ด ์๋๋๋ค.
๊ทธ ์ฌ์ด Quart์ ์ ์์ธ @pgjones ๋ Werkzeug์ ๋ ๋ง์ด ๊ด์ฌํ๊ฒ ๋์์ต๋๋ค. Quart๋ ์ด์ ๊ฐ๋ฅํ ํ ๋ฐฐํ์์ Werkzeug๋ฅผ ์ฌ์ฉํ๊ณ ์์ผ๋ฉฐ ๊ณ์ํด์ ๊ฐ๋ฐํ๊ณ ์์ต๋๋ค. ASGI๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๋ํด Flask ์ ์ง ๊ด๋ฆฌ์๋ก๋ถํฐ ์ฝ๊ฐ์ ๋ฐ๋ฐ์ด ์์๊ธฐ ๋๋ฌธ์ Phil์ ๋ํ ์ต์ํ async def
๊ธฐ๋ฅ์ ๋ํ ๋ผ์ฐํ
์ ํ์ฉํ๋ ํ๋ ํธ/ํ๋ผ์คํฌ#3412๋ฅผ ๋ง๋ค์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด๋ ์ ์ ๋์ ์ค๋จ๋์์ต๋๋ค. ์ด ์์ ์์ ๋๋ ๊ทธ๊ฒ์ ์์ฃผํ๊ธฐ๋ณด๋ค ASGI๋ก ๊ฐ๊ณ ์ถ์ต๋๋ค. @edk0 ์ sans-io ํ์์ ๊ตฌ๋ฌธ ๋ถ์ํ๊ธฐ ์ํด #1330์ ๋ง๋ค์์ต๋๋ค. ํ์ง๋ง ์ด ์ญ์ ์์ง ์งํ ์ค์ด๋ฉฐ ๋จผ์ ๋ ๋ง์ ๋์์ธ๊ณผ ๊ฒํ ๋ฅผ ๊ฑฐ์ณ์ผ ํ ๊ฒ์
๋๋ค.
"์ Flask๋ Django๊ฐ ํ๋ ์ผ์ ํ ์ ์๋์?"๋ผ๊ณ ๋ฌผ์ ์ ์์ต๋๋ค. ์ ๋ Django ๋ด๋ถ ์ ๋ฌธ๊ฐ๋ ์๋์ง๋ง @andrewgodwin ์ Django๊ฐ ์๋ WSGI์ ์ ์ํ ๋ฐฉ์ ๋๋ฌธ์ Django๊ฐ "๋ ์ฌ์ด"(์ฝ๊ธฐ: ์ฌ์ ํ ๋งค์ฐ ๋ณต์กํ) ์๊ฐ์ ๊ฐ๋๋ค๊ณ ์ค๋ช ํ์ต๋๋ค. Werkzeug์ Flask๊ฐ ์์ํ ๋งค์ฐ WSGI ์ค์ฌ API์ ๋๋ค. ๋ํ Django๋ Pallets๋ณด๋ค ํจ์ฌ ๋ ๋ง์ ํํ์ ๊ด์ฌ๊ณผ ๋ฆฌ์์ค๋ฅผ ๋ฐ์ต๋๋ค.
๊ทธ๋ ๋ค๋ฉด ์ด ๋ฌธ์ ๋ ์ด๋์ ์์ต๋๊น? Werkzeug๋ฅผ ์ฌ์ฉํ๋ Flask ํธํ ํ๋ ์์ํฌ๋ฅผ ์ํ๋ค๋ฉด Quart๋ฅผ ์ฌ์ฉํ์ธ์. Quart(๋๋ Flask)์ ๊ธฐ์ฌํ์ฌ ๋๋ฝ๋ ๋ถ๋ถ์์ API ํธํ์ฑ์ ๋์ ๋๋ค. Werkzeug์ Flask๊ฐ ASGI๋ฅผ ์ง์ํ๋๋ก ํ๋ ค๋ฉด ํ ๋จ๊ณ ๋ ์ฌ๋ผ์ผ ํฉ๋๋ค. ASGI์ ๋ํด ๋ฐฐ์ฐ๊ธฐ ์์ํฉ๋๋ค. Werkzeug API์ WSGI ๊ด๋ จ ๋ฐ ์ฐจ๋จ ๋ถ๋ถ์ ์๋ณํ๊ธฐ ์์ํฉ๋๋ค. WSGI์ ASGI ๋ชจ๋์ ๋ํ ๊ตฌํ์ ๊ฐ๋ฅํ๊ฒ ํ๊ธฐ ์ํด ๋ง๋ค ์ ์๋ ์ถ์ํ์ ๋ํด ์๊ฐํ๊ธฐ ์์ํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ ํด๋น ์ฐ๊ตฌ๋ฅผ ์ด ํ ๋ก ์ผ๋ก ๊ฐ์ ธ์์ PR ๋์์ธ ๋ฐ ์์ฑ์ ์์ํ ์ ์์ต๋๋ค.
Quart ์ ์์ ๊ฐ์ฌ๋๋ฆฌ๋ฉฐ, ์ด์ ๋ํ ๊ธฐ์ฌ๋ฅผ ์๋ฝํ๊ฒ ๋์ด ๋งค์ฐ ๊ธฐ์ฉ๋๋ค.
๋๋ ์ Flask๊ฐ Django๊ฐ ์ด ๊ธฐ์ฌ ์์ ํ ์ผ์ ํ ์ ์๋ค๊ณ ์๊ฐํ๋์ง ๋๋ตํ๋ ค๊ณ ๋ ธ๋ ฅํ์ต๋๋ค. ๊ถ๊ทน์ ์ผ๋ก ๋๋ palettes/flask#3412๊ฐ Flask๋ฅผ ์ํ ์ต๊ณ ์ ์๋ฃจ์ ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
Werkzeug์ ๊ด์ ์์ ASGI๊ฐ ๊ฐ๋ฅํ์ง๋ง ์ฝ๊ฐ์ ๊ณ ํต์ด ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ๊ณ ํต์ ์ฃผ๋ชฉํ ๋งํ ์๋ Werkzeug์ ๋ง์ ๊ฒ๋ค์ด WSGI ํธ์ถ ๊ฐ๋ฅ(์: ์์ธ)์ด๋ผ๋ ๊ฒ์ ๋๋ค. ASGI์์๋ ์ด ๊ธฐ๋ฅ์ ์ด๋ป๊ฒ ์ฌ์ฉํ ์ ์๋์ง/์ฌ์ฉํด์ผ ํ๋์ง ๋ช ํํ์ง ์์ผ๋ฏ๋ก ์ ๊ฑฐํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
๋ด ๊ณํ์ Werkzeug๋ฅผ Quart์ ๊ณ์ ํตํฉํ๋ ๊ฒ์ ๋๋ค. Werkzeug๋ฅผ ASGI(sans-io)์ ๋ง๊ฒ ์กฐ์ ํ๋ ๊ฒ์ ๋๋ค.
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
์, Werkzeug์ Flask๋ ๊ฒฐ๊ตญ ASGI๋ฅผ ์ง์ํ ๊ฒ์ ๋๋ค. ์ด์ ๋ํ ์ผ์ ์ ์์ง๋ง ๋๊ตฐ๊ฐ PR์ ์์ํ๋ค๋ฉด ๊ธฐ๊บผ์ด ๊ฒํ ํ๋ ๋ฐ ๋์์ ๋๋ฆฌ๊ฒ ์ต๋๋ค.
๊ทธ๋ฌ๋ ๋๋ ๊ทธ๊ฒ์ ๊ตฌํํ๋ ์ฌ๋์ด ์๋๋ฏ๋ก ์ปค๋ฎค๋ํฐ์ ๋์์ด ํ์ํฉ๋๋ค. ์๋์ ์ต์ ์ ๋ฐ์ดํธ๋ฅผ ์ฐธ์กฐํ์ญ์์ค. https://github.com/pallets/werkzeug/issues/1322#issuecomment -600926145