dummy_wsgi_framework

Dummy WSGI Framework is base for your Web-applications or your own WSGI-framework


Install
pip install dummy_wsgi_framework==0.0.19

Documentation

Dummy WSGI Framework

Dummy WSGI Framework - это WSGI-Ρ„Ρ€Π΅ΠΉΠΌΠΎΡ€ΠΊ для Π²Π°ΡˆΠΈΡ… Π’Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ ΠΈΠ»ΠΈ основа для вашСго собствСнного WSGI-Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ°, ΠΎΠ½ "ΠΏΡ€ΠΎΡΡ‚Π΅Π½ΡŒΠΊΠΈΠΉ" ΠΈ "Π³Π»ΡƒΠΏΠ΅Π½ΡŒΠΊΠΈΠΉ" (хотя Π½Π° самом Π΄Π΅Π»Π΅ ΠΎΠ½ Π½Π΅ Ρ‚Π°ΠΊ ΡƒΠΆ "прост" ΠΈ "Π³Π»ΡƒΠΏ", ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ Π½Π° ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ взгляд), Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π°Π½ ΠΊΠ°ΠΊ Just4Fun-ΠΏΡ€ΠΎΠ΅ΠΊΡ‚.

Dummy WSGI Framework мСтодологичСски состоит ΠΈΠ· "ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€ΠΎΠ²" ΠΈ "прСдставлСний", ΠΊΠ°ΠΊ ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½ "Model-View-Controller", Π½ΠΎ Π±Π΅Π· "Model".

Он позволяСт Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с прСдставлСниями, Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅ΠΌΡ‹ΠΌΠΈ Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€ΠΎΠ² ΠΈΠ»ΠΈ ΠΏΠΎΠ΄Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌΡ‹ΠΌΠΈ ΠΈΠ· Ρ„Π°ΠΉΠ»ΠΎΠ², Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π² Π±Π°Π·ΠΎΠ²ΠΎΠΌ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π΅ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ° это просто HTML-Ρ„Π°ΠΉΠ»Ρ‹.

Dummy WSGI Framework Ρ€Π°ΡΡˆΠΈΡ€ΡΠ΅ΠΌ:

  • Π² силу ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΠ³ΠΎ доступа ΠΊ WSGI-интСрфСйсу Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€ΠΎΠ² прилоТСния, Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π°Π½Π½ΠΎΠ³ΠΎ Π½Π° Π΅Π³ΠΎ (Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ°) основС;
  • Π² силу возмоТности использования ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹Ρ… ΡˆΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°Ρ‚ΠΎΡ€ΠΎΠ² Π·Π° счСт Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ Π² ядрС Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ° Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Ρ„Π°ΠΉΠ»ΠΎΠ² прСдставлСний;
  • ΠΈ, Π² ΠΊΠΎΠ½Ρ†Π΅ ΠΊΠΎΠ½Ρ†ΠΎΠ², это ΠΆΠ΅ Python, Ρ‚ΡƒΡ‚ ΠΌΠ½ΠΎΠ³ΠΎΠ΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ.

Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ свободно ΠΈΡΠΏΠΎΠ»ΡŒΡ‚Π·ΠΎΠ²Π°Ρ‚ΡŒ Dummy WSGI Framework. Π‘ΡΡ‹Π»Π°Ρ‚ΡŒΡΡ Π½Π° Ρ„Π°ΠΊΡ‚ использования Π’Π°ΠΌΠΈ Dummy WSGI Framework Π½Π΅ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, Π½ΠΎ ΠΌΠ½Π΅ Π±Ρ‹ Ρ…ΠΎΡ‚Π΅Π»ΠΎΡΡŒ ΠΈΠΌΠ΅Ρ‚ΡŒ ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΉ ΠΎΡ‚Π·Ρ‹Π², Π΄Π°ΠΆΠ΅ Ссли ΠΎΠ½ ΠΈ Π½Π΅ ΠΏΠΎΠ»ΠΎΠΆΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ.

ОглавлСниС Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ описания

ВрСбования

Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Π²Π΅Ρ€ΡΠΈΡŽ Python 3.4

Установка

Dummy WSGI Framework Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ Π² рССст ΠΏΠ°ΠΊΠ΅Ρ‚ΠΎΠ² PyPI (Python Package Index) - https://pypi.org/project/dummy_wsgi_framework/

Π•Π³ΠΎ установка Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Π° с использованиСм pip

$ pip install dummy_wsgi_framework

Или ΠΈΠ½Ρ‹ΠΌ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹ΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ (ΠΊΠΎΠΌΠ°Π½Π΄Π° для OS Debian):

$ cd <your_project_dir>
$ git clone git://github.com/BorisPlus/dummy_wsgi_framework.git

ΠΈΠ»ΠΈ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΏΠΎ ссылкС для скачивания master-Π²Π΅Ρ‚ΠΊΠΈ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° Zip (ΠΊΠΎΠΌΠ°Π½Π΄Π° для OS Debian):

$ wget https://github.com/BorisPlus/dummy_wsgi_framework/archive/master.zip

↑ Π½Π°Π²Π΅Ρ€Ρ… Π² ΠΎΠ³Π»Π°Π²Π»Π΅Π½ΠΈΠ΅

Руководство Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°

ДирСктория dummy_wsgi_framework - это ΠΈ Π΅ΡΡ‚ΡŒ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊ с Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΌ ядром Π² Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ dummy_wsgi_framework/core ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠΌ Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ одностраничного прилоТСния Π² Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ dummy_wsgi_framework/app.template.

Для быстрого старта:

  1. Π‘ΠΎΠ·Π΄Π°ΠΉΡ‚Π΅ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΡŽ вашСго прилоТСния app (Π³Π΄Π΅ ΡƒΠ³ΠΎΠ΄Π½ΠΎ).
  2. CΠΊΠΎΠΏΠΈΡ€ΡƒΠΉΡ‚Π΅ Π² Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΡŽ app содСрТимоС Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ dummy_wsgi_framework/app.template.
  3. ЗапуститС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅:
$ uwsgi --http 127.0.0.1:8080 --wsgi-file /<absolute_path>/app/application.py

↑ Π½Π°Π²Π΅Ρ€Ρ… Π² ΠΎΠ³Π»Π°Π²Π»Π΅Π½ΠΈΠ΅

ОписаниС структуры прилоТСния

ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ

Π€Π°ΠΉΠ» config.py вашСго прилоТСния содСрТит ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅, ΠΈ ΠΏΡ€Π΅Π΄ΠΏΠΎΡ‡Ρ‚ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ, Π±Π΅Π· Π΄ΠΎΠ»ΠΆΠ½ΠΎΠ³ΠΎ ΠΎΠΏΡ‹Ρ‚Π°, Π½Π΅ ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ ΠΈΡ… значСния (хотя это Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, см. ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡŽ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° "ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ с ΠΏΠ΅Ρ€Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΌΠΈ путями хранСния Ρ„Π°ΠΉΠ»ΠΎΠ² ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€ΠΎΠ² ΠΈ прСдставлСний") ΠΈ Π΄ΠΎΠ±Π°Π²Π»ΡΡ‚ΡŒ свои ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΈΠΌΠ΅Π½Π½ΠΎ сюда.

↑ Π½Π°Π²Π΅Ρ€Ρ… Π² ΠΎΠ³Π»Π°Π²Π»Π΅Π½ΠΈΠ΅

ΠœΠ°Ρ€ΡˆΡ€ΡƒΡ‚Ρ‹

Π€Π°ΠΉΠ» routes.py прилоТСния содСрТит Ρ‚Π°ΠΊ Π½Π°Π·Ρ‹Π²Π°Π΅ΠΌΡ‹Π΅ "ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Ρ‹" - соотвСтствиС HTTP-запросов (Π½Π° самом Π΄Π΅Π»Π΅ ΠΈΡ… масок) ΠΈ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Π»ΠΎΠ² прилоТСния.

ΠœΠ°Ρ€ΡˆΡ€ΡƒΡ‚Ρ‹ Π·Π°Π΄Π°ΡŽΡ‚ΡΡ Π² Π²ΠΈΠ΄Π΅:

routes_of_uri_regexps = (
    dict(uri_regexp='/index/', controller='index.py'),
    dict(uri_regexp='/', controller='index.py'),
)

ΠΈΠ»ΠΈ с ΠΏΠΎΠ΄Π³Ρ€ΡƒΠ·ΠΊΠΎΠΉ Π±Π°Π·ΠΎΠ²Ρ‹Ρ… ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΎΠ² Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ°:

from dummy_wsgi_framework.core.routes import base_routes_of_uri_regexps

routes_of_uri_regexps = tuple([
    dict(uri_regexp='^/page_one/$',
         controller='page_one.py'),
    dict(uri_regexp='^/page_two/$',
         controller='page_two.py')
    ] + list(base_routes_of_uri_regexps).copy())

, Π³Π΄Π΅:

  • Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΊΠ»ΡŽΡ‡Π° uri_regexp - это REQUEST_URI, ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π°Ρ послС Π΄ΠΎΠΌΠ΅Π½Π½ΠΎΠ³ΠΎ ΠΈΠΌΠ΅Π½ΠΈ ΠΈΠ»ΠΈ IP-адрСса Ρ‡Π°ΡΡ‚ΡŒ HTTP-запроса. Π—Π½Π°ΠΊ косой Ρ‡Π΅Ρ€Ρ‚Ρ‹ "/" Π² ΠΊΠΎΠ½Ρ†Π΅ uri_regexp обязатСлСн, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ диспСтчСр ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€ΠΎΠ² Ρ‡Π΅Ρ€Π΅Π· Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π» ядра Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ° ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Ρ‹ HTTP-запросов, ΠΈ Ссли Π² ΠΊΠΎΠ½Ρ†Π΅ REQUEST_URI Π·Π½Π°ΠΊ косой Ρ‡Π΅Ρ€Ρ‚Ρ‹ "/" отсутствуСт, Ρ‚ΠΎ происходит Ρ€Π΅Π΄ΠΈΡ€Π΅ΠΊΡ‚ (ΠΏΠ΅Ρ€Π΅Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ HTTP-запроса) Π½Π° REQUEST_URI с приписанной Π² ΠΊΠΎΠ½Π΅Ρ† косой Ρ‡Π΅Ρ€Ρ‚ΠΎΠΉ "/".
  • Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΊΠ»ΡŽΡ‡Π° controller - это сам Python-Ρ„Π°ΠΉΠ» ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π°, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π³ΠΎ uri_regexp ΠΈ Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΡŽΡ‰Π΅Π³ΠΎ Π»ΠΎΠ³ΠΈΠΊΡƒ Ρ€Π΅Π°ΠΊΡ†ΠΈΠΈ Π½Π° HTTP-запрос.

Π‘ΡƒΠ΄Ρ‚Π΅ Π²Π½ΠΈΠΌΠ°Ρ‚Π΅Π»ΡŒΠ½Ρ‹, срабатываСт ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΠΏΠΎ порядку (свСрху Π²Π½ΠΈΠ·) ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚. Алгоритм сопоставлСния опираСтся Π½Π° успСх Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ re.compile(uri_regexp).findall(REQUEST_URI). Π€ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π» рСгулярных Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ Π² uri_regexp Π±Ρ‹Π» Π²Π²Π΅Π΄Π΅Π½ Π² ядро Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ° для возмоТности назначСния ΠΈ использования Π² ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π°Ρ… ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹Ρ… ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² HTTP-запросов ("ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ с ΠΎΡ€Π°Π±ΠΎΡ‚ΠΊΠΎΠΉ Π΄ΠΎΠΏΡƒΡ‰Π΅Π½Π½Ρ‹Ρ… ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ²").

↑ Π½Π°Π²Π΅Ρ€Ρ… Π² ΠΎΠ³Π»Π°Π²Π»Π΅Π½ΠΈΠ΅

ДиспСтчСр ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€ΠΎΠ²

Π—Π° Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ HTTP-запросов ΠΊ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π°ΠΌ Π² соотвСтствии с ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π°ΠΌΠΈ ΠΈΠ· routes.py ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ функция application() - Ρ‚Π°ΠΊ Π½Π°Π·Ρ‹Π²Π°Π΅ΠΌΡ‹ΠΉ "диспСтчСр ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€ΠΎΠ²" прилоТСния, располоТСнный Π² application.py (Ρ„Π°ΠΉΠ» Π½Π°Π·Ρ‹Π²Π°Ρ‚ΡŒ Π½Π΅ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ ΠΈΠΌΠ΅Π½Π½ΠΎ Ρ‚Π°ΠΊ). Π­Ρ‚ΠΎΡ‚ Ρ„Π°ΠΉΠ» выступаСт Π² качСствС Π²Ρ…ΠΎΠ΄Π½ΠΎΠΉ Ρ‚ΠΎΡ‡ΠΊΠΈ вашСго WSGI-прилоТСния.

# Content of: app/application.py
import config as app_config
from dummy_wsgi_framework.core.dispatchers import get_controller_response

def application(environ, start_response):
    return get_controller_response(environ, start_response, app_config)

Π’ ΠΈΡ‚ΠΎΠ³Π΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ запускаСтся Ρ‚Π°ΠΊ:

$ uwsgi --http 127.0.0.1:8080 --wsgi-file /<absolute_path>/app/application.py

Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ Ρƒ Вас Π΅ΡΡ‚ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Π½Π° основС Dummy WSGI Framework нСсколько ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Ρ… ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ, запуская ΠΈΡ… Π½Π° Ρ€Π°Π·Π½Ρ‹Ρ… ΠΏΠΎΡ€Ρ‚Π°Ρ… сСрвСра.

↑ Π½Π°Π²Π΅Ρ€Ρ… Π² ΠΎΠ³Π»Π°Π²Π»Π΅Π½ΠΈΠ΅

ΠšΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Ρ‹

"ΠšΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Ρ‹" это Python-Ρ„Π°ΠΉΠ»Ρ‹, Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΡŽΡ‰ΠΈΠ΅ Π»ΠΎΠ³ΠΈΠΊΡƒ Ρ€Π΅Π°ΠΊΡ†ΠΈΠΈ Π½Π° HTTP-запросы Π² соотвСтствии с ΠΎΠ±ΡŠΡΠ²Π»Π΅Π½Π½Ρ‹ΠΌΠΈ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π°ΠΌΠΈ.

Π‘ΠΎΠ·Π΄Π°ΠΉΡ‚Π΅ свои ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Ρ‹, Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π² ΠΈΡ… Π»ΠΎΠ³ΠΈΠΊΡƒ Ρ€Π°Π±ΠΎΡ‚Ρ‹ (ΠΌΠΎΠΆΠ½ΠΎ Π²Π·ΡΡ‚ΡŒ Ρ‚ΠΈΠΏΠΎΠ²Ρ‹Π΅ с ΠΏΠΎΠ΄Π³Ρ€ΡƒΠ·ΠΊΠΎΠΉ шаблонов ΠΈ Π±Π΅Π·, ΠΈΠ»ΠΈ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ свои с посылкой ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹Ρ… HTTP-Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠ², Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, для Basic Access Authentication ΠΊΠ°ΠΊ Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ "ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ с двумя сСкрСтными страницами (Basic access authentication)").

ΠšΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Ρ‹ Ρ€Π°Π·ΠΌΠ΅Ρ‰Π°ΡŽΡ‚ΡΡ Π² Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ controllers Π² ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠΉ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ прилоТСния (Ρ‡Ρ‚ΠΎ Π½Π΅ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ Π² config.py ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ Π±Π°Π·ΠΎΠ²ΠΎΠ΅ располоТСниС Ρ„Π°ΠΉΠ»ΠΎΠ² ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€ΠΎΠ², см. ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡŽ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° "ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ с ΠΏΠ΅Ρ€Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΌΠΈ путями хранСния Ρ„Π°ΠΉΠ»ΠΎΠ² ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€ΠΎΠ² ΠΈ прСдставлСний").

ΠžΡΠ½ΠΎΠ²Π½Ρ‹ΠΌ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠΌ Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠΌ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π΅ Π²Ρ‹Π·ΠΎΠ²Π° ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π° прилоТСния являСтся функция get_response(). ΠžΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠΉΡ‚Π΅ Π΅Π΅, ΠΈΠ½Π°Ρ‡Π΅ диспСтчСр ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€ΠΎΠ² Π½Π΅ смоТСт Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€, ΠΈ Π±ΡƒΠ΄Π΅Ρ‚ сгСнСнрировано ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ControllerFileIsInvalid с ΡƒΠΊΠ°Π·Π°Π½ΠΈΠ΅ΠΌ отсутствия Ρƒ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ get_response()

ΠšΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Ρ‹ "Ρ€Π΅Π΄ΠΈΡ€Π΅ΠΊΡ‚Π°" ΠΈ "404-ΠΎΠΉ ошибки" Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Ρ‹ Π² ядрС Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ°:

# File: core/controllers/redirect.py
def get_response(environ, start_response, app_config, location):
    start_response('301 Moved Permanently', [('Location', location)])
    return b''

ΠΈ

# File: core/controllers/error404.py
def get_response(environ, start_response, app_config, message):
    start_response('404 Not found', [('Content-Type', 'text/html; charset=utf-8')])
    return [
        # some template
    ]

↑ Π½Π°Π²Π΅Ρ€Ρ… Π² ΠΎΠ³Π»Π°Π²Π»Π΅Π½ΠΈΠ΅

ΠŸΡ€Π΅Π΄ΡΡ‚Π°Π²Π»Π΅Π½ΠΈΡ

ΠšΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Ρ‹ ΠΌΠΎΠ³ΡƒΡ‚ нСпосрСдствСнно ΠΎΠ²Π΅Ρ‡Π°Ρ‚ΡŒ Π½Π° HTTP-запрос ΠΈΠ»ΠΈ ΠΆΠ΅ Π·Π°Π³Ρ€ΡƒΠΆΠ°Ρ‚ΡŒ Π·Π°Ρ€Π°Π½Π΅Π΅ ΠΏΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²Π»Π΅Π½Π½Ρ‹Π΅ Π² ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ Ρ„Π°ΠΉΠ»Ρ‹ прСдставлСний, ΠΈΠ½ΠΎΠ³Π΄Π° ΠΈΡ… Ρ‚Π°ΠΊ ΠΆΠ΅ Π½Π°Π·Ρ‹Π²Π°ΡŽΡ‚ "ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹".

Python-Ρ„Π°ΠΉΠ»Ρ‹ прСдставлСний Ρ€Π°Π·ΠΌΠ΅Ρ‰Π°ΡŽΡ‚ΡΡ Π² Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ views Π² ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠΉ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ прилоТСния (Ρ‡Ρ‚ΠΎ Π½Π΅ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ Π² config.py ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ Π±Π°Π·ΠΎΠ²ΠΎΠ΅ располоТСниС Ρ„Π°ΠΉΠ»ΠΎΠ² прСдставлСний, см. ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡŽ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° "ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ с ΠΏΠ΅Ρ€Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΌΠΈ путями хранСния Ρ„Π°ΠΉΠ»ΠΎΠ² ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€ΠΎΠ² ΠΈ прСдставлСний").

ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎΠ΅ описаниС Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€ΠΎΠΌ Ρ„Π°ΠΉΠ»Π° прСдставлСния ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ΠΎ здСсь Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ "ДСмонстрация Π±Π°Π·ΠΎΠ²Ρ‹Ρ…_возмоТностСй Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ°".

↑ Π½Π°Π²Π΅Ρ€Ρ… Π² ΠΎΠ³Π»Π°Π²Π»Π΅Π½ΠΈΠ΅

ОписаниС Π»ΠΎΠ³ΠΈΠΊΠΈ Ρ€Π°Π±ΠΎΡ‚Ρ‹ прилоТСния

Π’ΠΎΡ‡ΠΊΠ° Π²Ρ…ΠΎΠ΄Π° вашСго прилоТСния (app/application.py: def application()...), пСрСдаст ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Π΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ Π±Π°Π·ΠΎΠ²ΠΎΠΌΡƒ диспСтчСру ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€ΠΎΠ² (core/dispatchers.py: def get_controller_response()...) вмСстС с отсылкой Π½Π° ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ прилоТСния. Π‘Π°Π·ΠΎΠ²Ρ‹ΠΉ диспСтчСр ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€ΠΎΠ² Π² соотвСтствии с ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹ΠΌ Π΅ΠΌΡƒ REQUEST_URI ΠΏΠΎ ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΠΌΡ Π΄Π°Π½Π½Ρ‹ΠΌ Π² ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π°Ρ… Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ прилоТСния (app/routes.py: routes_of_uri_regexps) Π²Ρ‹Π·ΠΎΠ²Π΅Ρ‚ ΠΏΠΎ успСху (core/routes.py: def get_controller_by_uri_regexp()...) ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ Π΄Π°Π½Π½ΠΎΠΌΡƒ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Ρƒ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€ (app/controllers/ACTION.py: def get_response()), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π² свою ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ ΠΎΡ‚Π²Π΅Ρ‚ΠΈΡ‚ прСдставлСниСм ΠΏΠΎ "Π·Π°ΡˆΠΈΡ‚ΠΎΠΌΡƒ" Π² Π½Π΅Π³ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»Ρƒ ΠΈΠ»ΠΈ пСрСдаст (Ссли Π²Ρ‹ Ρ‚Π°ΠΊ Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚Π΅) ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Π΅ ΠΈΠΌ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ дальшС ΠΌΠ΅Ρ‚ΠΎΠ΄Ρƒ (core/dispatchers.py: def load_view()..._), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ "Π·Π°Π³Ρ€ΡƒΠ·ΠΈΡ‚" Ρ„Π°ΠΉΠ» вашСго прСдставлСния (app/views/ACTION.html).

↑ Π½Π°Π²Π΅Ρ€Ρ… Π² ΠΎΠ³Π»Π°Π²Π»Π΅Π½ΠΈΠ΅

ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹

ΠŸΠΎΠ»Π½Ρ‹ΠΉ список ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠ²

ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π°Π½Π½Ρ‹Ρ… Π½Π° основС Dummy WSGI Framework ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ:

↑ Π½Π°Π²Π΅Ρ€Ρ… Π² ΠΎΠ³Π»Π°Π²Π»Π΅Π½ΠΈΠ΅

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ "ДСмонстрация Π±Π°Π·ΠΎΠ²Ρ‹Ρ… возмоТностСй Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ°"

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ "ДСмонстрация Π±Π°Π·ΠΎΠ²Ρ‹Ρ…_возмоТностСй Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ°" содСрТит дСмонстрационный Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ Π’Π΅Π±-прилоТСния, Π° ΠΈΠΌΠ΅Π½Π½ΠΎ:

  • Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ Π²Ρ‹Π·ΠΎΠ²Π° ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π° Π±Π΅Π· прСдставлСния;
  • Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ Π²Ρ‹Π·ΠΎΠ²Π° ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π° с Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΎΠΉ прСдставлСния ΠΈΠ· HTML-Ρ„Π°ΠΉΠ»Π°;
  • Π΄Π΅ΠΌΠΎΠ½ΡΡ‚Ρ€Π°Ρ†ΠΈΡŽ ΡˆΡ‚Π°Ρ‚Π½ΠΎΠ³ΠΎ ΠΎΡ‚Π»ΠΎΠ²Π° Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ ядра Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ° ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ RouteDoesNotExist, Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡŽΡ‰Π΅Π³ΠΎ ΠΏΡ€ΠΈ Π·Π°Π²Π΅Π΄ΠΎΠΌΠΎ ΠΎΡ‚ΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΌ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π΅, ΡƒΠ΄ΠΎΠ²Π»Π΅Ρ‚Π²ΠΎΡ€ΡΡŽΡ‰Π΅Π³ΠΎ ΠΏΡ€ΠΈΡˆΠ΅Π΄ΡˆΠ΅ΠΌΡƒ HTTP-запросу;
  • Π΄Π΅ΠΌΠΎΠ½ΡΡ‚Ρ€Π°Ρ†ΠΈΡŽ ΡˆΡ‚Π°Ρ‚Π½ΠΎΠ³ΠΎ ΠΎΡ‚Π»ΠΎΠ²Π° Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ ядра Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ° ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ControllerFileDoesNotExist, Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡŽΡ‰Π΅Π³ΠΎ ΠΏΡ€ΠΈ Π·Π°Π²Π΅Π΄ΠΎΠΌΠΎ ΠΎΡ‚ΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΌ Ρ„Π°ΠΉΠ»Π΅ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π°, ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ Π΄ΠΎ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ сущСствуСт;
  • Π΄Π΅ΠΌΠΎΠ½ΡΡ‚Ρ€Π°Ρ†ΠΈΡŽ ΡˆΡ‚Π°Ρ‚Π½ΠΎΠ³ΠΎ ΠΎΡ‚Π»ΠΎΠ²Π° Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ ядра Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ° ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ControllerFileIsInvalid, Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡŽΡ‰Π΅Π³ΠΎ ΠΏΡ€ΠΈ Π·Π°Π²Π΅Π΄ΠΎΠΌΠΎ ΠΎΡ‚ΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΉ Ρƒ Ρ„Π°ΠΉΠ»Π° ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π°, ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ Π΄ΠΎ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ сущСствуСт, Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ get_response();
  • Π΄Π΅ΠΌΠΎΠ½ΡΡ‚Ρ€Π°Ρ†ΠΈΡŽ ΡˆΡ‚Π°Ρ‚Π½ΠΎΠ³ΠΎ ΠΎΡ‚Π»ΠΎΠ²Π° Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ ядра Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ° ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ViewDoesNotExist, Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡŽΡ‰Π΅Π³ΠΎ ΠΏΡ€ΠΈ Π·Π°Π²Π΅Π΄ΠΎΠΌΠΎ ΠΎΡ‚ΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΌ Ρ„Π°ΠΉΠ»Π΅ прСдставлСния, ΠΏΠΎΠ΄Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌΠΎΠΌ Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ get_response() ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π°, ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ Π΄ΠΎ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ сущСствуСт.

ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, с Ρ†Π΅Π»ΡŒΡŽ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΠ³ΠΎ использования Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°ΠΌΠΈ ΠΊΠ°ΠΊΠΈΡ…-Π»ΠΈΠ±ΠΎ ΡˆΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°Ρ‚ΠΎΡ€ΠΎΠ² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎ продСмонстрирвана Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ дСкорирования Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Ρ„Π°ΠΉΠ»Π° прСдставлСния:

  • рСализация "ΠΊΠ°ΠΊ Π΅ΡΡ‚ΡŒ" - Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ° Ρ„Π°ΠΉΠ»Π° прСдставлСния, рСализованная Π² ядрС Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ°;
  • рСализация с использованиСм "Ρ‡Π΅Π³ΠΎ-Ρ‚ΠΎ" самописного - Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ° Ρ„Π°ΠΉΠ»Π° прСдставлСния ΠΈ Π·Π°ΠΌΠ΅Π½Π° ΡΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… лСксСм, Ссли Ρ‚Π°ΠΊΠΎΠ²Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Ρ‹;
  • рСализация с использованиСм Jinja2 - Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ° Ρ„Π°ΠΉΠ»Π° прСдставлСния ΠΈ Π΅Π³ΠΎ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Jinja2.

МнС Π½Π΅ Ρ…ΠΎΡ‚Π΅Π»ΠΎΡΡŒ Π²Π½ΠΎΡΠΈΡ‚ΡŒ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ ΠΎΡ‚ Jinja2 Π² ядро Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ°, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ я ΡΡ‡ΠΈΡ‚Π°ΡŽ ΠΏΠΎΠ΄ΠΎΠ±Π½ΡƒΡŽ связь слишком ТСсткой, Π΄Π° ΠΈ Dummy WSGI Framework ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ задумывался ΠΊΠ°ΠΊ "Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ", "каркасный", "ΠΏΡ€ΠΎΡΡ‚Π΅Π½ΡŒΠΊΠΈΠΉ" ΠΈ "Π³Π»ΡƒΠΏΠ΅Π½ΡŒΠΊΠΈΠΉ". ΠŸΡ€ΠΈ этом, понимая, Ρ‡Ρ‚ΠΎ этого ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π½Π΅ достаточно сторонним Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°ΠΌ, ΠΈ имСя интСрСс ΠΏΠΎ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎΠΉ Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Ρ‹ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ°, я Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π» Π² ядрС Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ° Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ для Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Ρ„Π°ΠΉΠ»Π° прСдставлСния.

Π”Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ @decorate_loaded_view_function_for_response ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΡƒ сущСствования Ρ„Π°ΠΉΠ»Π° прСдставлСния ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ этого Ρ„Π°ΠΉΠ»Π° ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Π΅ Сю Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹.

Π’ΠΎ Π΅ΡΡ‚ΡŒ для Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Ρ„Π°ΠΉΠ»Π° прСдставлСния "ΠΊΠ°ΠΊ Π΅ΡΡ‚ΡŒ", Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½ΠΎΠΉ Π² ядрС Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ°, прСдполагаСтся Π²Ρ‹Π·ΠΎΠ² Π² ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ load_view() ядра Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ°:

# Framework solution
from dummy_wsgi_framework.core.dispatchers import load_view

def get_response(environ, start_response, app_config):
    return load_view(
        environ,
        start_response,
        app_config,     # ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ Π±Π°Π·ΠΎΠ²ΠΎΠΌΡƒ диспСтчСру ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€ΠΎΠ²
                        # ΠΊΠ°ΠΊΠΎΠ΅ ΠΈΠ· Π²Π°ΡˆΠΈΡ… ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ
        'load_me.html'  # имя Ρ„Π°ΠΉΠ»Π° прСдставлСния, 
                        # ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ Π² качСствС Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° я ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽ Π²Ρ‹Π·ΠΎΠ²
                        # 
                        # from dummy_wsgi_framework.core.dispatchers import (
                        #   resolve_name_by_python_file_name
                        # )
                        # resolve_name_by_python_file_name(__file__, '%s.html')
                        # 
                        # Ρ‡Ρ‚ΠΎ обяТСт Ρ„Π°ΠΉΠ» прСдставлСния ΠΈΠΌΠ΅Ρ‚ΡŒ Ρ‚ΠΎΠΆΠ΅ имя, 
                        # Ρ‡Ρ‚ΠΎ ΠΈ Ρƒ Ρ„Π°ΠΉΠ»Π° ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π° ΠΈ упростит Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹ΠΉ Ρ€Π΅Ρ„Π°ΠΊΡ‚ΠΎΡ€ΠΈΠ½Π³
    )

А для "Ρ‡Π΅Π³ΠΎ-Ρ‚ΠΎ" самописного Ρƒ вас Π΅ΡΡ‚ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Ρ„Π°ΠΉΠ»Π° прСдставлСния, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, с Π·Π°ΠΌΠ΅Π½ΠΎΠΉ ΡΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… лСксСм шаблона. НСобходимо лишь ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΊ вашСй Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Ρ„Π°ΠΉΠ»Π° прСдставлСния Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ @decorate_loaded_view_function_for_response:

# Your self realization
from dummy_wsgi_framework.core.dispatchers import decorate_loaded_view_function_for_response

@decorate_loaded_view_function_for_response
def yourself_load_view_function(view_path, **kwargs):
    with open(view_path, 'rb') as f:
        response_body = f.read()
        for k in kwargs:
            response_body = response_body.replace(
                ("{{ %s }}" % k).encode(), 
                str(kwargs[k]).encode()
            )
    return response_body

def get_response(environ, start_response, app_config):
    return yourself_load_view_function(
        environ,
        start_response,
        app_config,
        'load_me.html',     # Ρ„Π°ΠΉΠ» прСдставлСния, шаблон
        id=1,               # Π½Π΅ΠΊΠΈΠ΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Ρ‹ Π² шаблон ΠΈ
        value=2,            # Π±ΡƒΠ΄ΡƒΡ‚ ΡƒΡ‡Π°ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ Π² Π·Π°ΠΌΠ΅Π½Π΅ Π² response_body.replace
        other=4
    )

Для использования ΡˆΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°Ρ‚ΠΎΡ€ΠΎΠ², Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Jinja2, Π²Ρ‹ΡˆΠ΅ΠΎΠΏΠΈΡΠ°Π½Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹Π³Π»ΡΠ΄Π΅Ρ‚ΡŒ Ρ‚Π°ΠΊ:

# Jinja2 realization
from dummy_wsgi_framework.core.dispatchers import (
    decorate_loaded_view_function_for_response
)
from dummy_wsgi_framework.core.exceptions import (
    ExistViewFileIsInvalid, 
    ViewDoesNotExist
)
import config
import jinja2
import os

@decorate_loaded_view_function_for_response
def load_jinja2_view_template(view_template_path, **kwargs):
    try:
        environment = jinja2.Environment(loader=jinja2.FileSystemLoader(config.APP_VIEWS_DIR))
        template = environment.get_template(os.path.basename(view_template_path))
        return template.render(**kwargs).encode()
    except jinja2.exceptions.TemplateSyntaxError as e:
        raise ExistViewFileIsInvalid('File "%s" - %s' % (view_template_path, e.message))
    except jinja2.exceptions.TemplateNotFound as e:
        raise ViewDoesNotExist('File "%s" not found %s' % (view_template_path, e.message))

def get_response(environ, start_response, app_config):
    return load_jinja2_view_template(
        environ,
        start_response,
        app_config,
        'load_me.html',     # шаблон Π² Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π΅ Jinja2, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ с Π±Π°Π·ΠΎΠ²Ρ‹ΠΌ.
        id=1,               # Π½Π΅ΠΊΠΈΠ΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Ρ‹ Π² шаблон ΠΈ
        value=2,            # Π±ΡƒΠ΄ΡƒΡ‚ ΡƒΡ‡Π°ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ Π² Π·Π°ΠΌΠ΅Π½Π΅ Π² template.render
        other=4
    )

Π Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΡŽ Π²Ρ‹Π½ΠΎΡΠΈΡ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΏΠΎΠ΄ΠΎΠ±Π½Ρ‹Π΅ load_jinja2_view_template(), Π² Ρ€Π°Π·Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅ΠΌΠΎΠΌ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ Ρ„Π°ΠΉΠ», Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΊΠ°ΠΊ здСсь - user_def.py, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ это прСдставляСтся мСтодологичСски Π²Π΅Ρ€Π½Ρ‹ΠΌ для ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠ³ΠΎ использования Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, ΠΏΠΎΠ΄ΠΎΠ±Π½Ρ‹Ρ… load_jinja2_view_template(), Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, для использования load_jinja2_view_template() Π² Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π°Ρ….

↑ Π½Π°Π²Π΅Ρ€Ρ… Π² ΠΎΠ³Π»Π°Π²Π»Π΅Π½ΠΈΠ΅

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ 'ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ с двумя сСкрСтными страницами (Basic access authentication)'

Когда Π²Ρ‹ΡˆΠ΅ Π³ΠΎΠ²ΠΎΡ€ΠΈΠ»ΠΎΡΡŒ, Ρ‡Ρ‚ΠΎ Dummy WSGI Framework Ρ€Π°ΡΡˆΠΈΡ€ΡΠ΅ΠΌ Π² силу ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΠ³ΠΎ доступа ΠΊ WSGI-интСрфСйсу Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€ΠΎΠ² прилоТСния, Ρ‚ΠΎ имСлось Π² Π²ΠΈΠ΄Ρƒ, Ρ‡Ρ‚ΠΎ Ρƒ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° сущСствуСт Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΎΡ€Π³Π°Π½ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ посыл HTTP-Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠ² ΠΈ ΠΈΠ½ΠΎΠΉ слуТСбной ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ нСпосрСдствСнно Π² ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π°Ρ… своСго прилоТСния, Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π°Π½Π½ΠΎΠ³ΠΎ Π½Π° основС Dummy WSGI Framework. Π’ΠΎΠΌΡƒ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠ»ΡƒΠΆΠΈΡ‚ΡŒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ "ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ с двумя сСкрСтными страницами (Basic access authentication)"

Π—Π°ΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅ ΠΎ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π΅ запроса Π»ΠΎΠ³ΠΈΠ½Π° ΠΈ пароля:
* Π’Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ (Π² нашСм случаС это ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€) ΠΏΠΎΡˆΠ»Π΅Ρ‚ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ 
  HTTP-Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ запроса Basic Π°Π²Ρ‚ΠΎΡ€ΠΈΠ·Π°Ρ†ΠΈΠΈ.
* Π‘Ρ€Π°ΡƒΠ·Π΅Ρ‚ продСмонстрируСт Ρ„ΠΎΡ€ΠΌΡƒ.
* Π’Ρ‹ Π²Π²Π΅Π΄Π΅Ρ‚Π΅ Π»ΠΎΠ³ΠΈΠ½ ΠΈ ΠΏΠ°Ρ€ΠΎΠ»ΡŒ.
* Они ΠΊΠΎΠ½ΠΊΠ°Ρ‚Π΅Π½ΠΈΡ€ΡƒΡŽΡ‚ΡΡ с использованиСм двоСточия ":", Π·Π°ΠΊΠΎΠ΄ΠΈΡ€ΡƒΡŽΡ‚ΡΡ 
  Π±Ρ€Π°ΡƒΠ·Π΅Ρ€ΠΎΠΌ ΠΏΠΎ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Ρƒ Base64 ΠΈ пСрСдадутся Π½Π° сСрвСр.
* ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ Π΄Π΅ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ Π½Π° Π²Π°Π»ΠΈΠ΄Π½ΠΎΡΡ‚ΡŒ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½ΡƒΡŽ 
  ΠΏΠ°Ρ€Ρƒ "login:password".
* Π’ случаС успСха Π’Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ доступ ΠΊ "сСкрСтной" ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ :)

ΠŸΡƒΡΡ‚ΡŒ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Ρ‹ Π±ΡƒΠ΄ΡƒΡ‚ Ρ‚Π°ΠΊΠΎΠ²Ρ‹:

routes_of_uri_regexps = (
    dict(uri_regexp=r'^/index_1/$', controller='first_secret_page.py'),
    dict(uri_regexp=r'^/index_2/$', controller='second_secret_page.py'),
    dict(uri_regexp=r'^/$', controller='first_secret_page.py'),
)

ΠšΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€:

# Content of 'first_secret_page.py'
import base64

def get_response(environ, start_response, app_config):
    if environ.get('HTTP_AUTHORIZATION', '').startswith('Basic '):  # ΠΏΡ€ΠΈΡˆΠ΅Π» Π»ΠΈ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ
        login_password_at_b64 = environ.get('HTTP_AUTHORIZATION', '')[6:]
        login_password = base64.b64decode(login_password_at_b64)  # Π΄Π΅ΠΊΠΎΠ΄ΠΈΡ€ΡƒΠ΅ΠΌ
        if login_password == b'user:user':
            start_response('200 OK', [('Content-Type', 'text/html; charset=utf-8')])
            return [
                # some template
            ]
    # "login:password" is empty or not valid
    start_response('401 Access Denied', [
        ('Content-Type', 'text/html; charset=utf-8'),
        ('WWW-Authenticate', 'Basic realm="Dummy WSGI Framework"'),
        ('Content-Length', '0'),
    ])
    return b'Basic Auth'

А Π½Π° "Π²Ρ‚ΠΎΡ€ΠΎΠΉ сСкрСтной" страницС ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½Π½ΠΎ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ "login:password", Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, "admin:admin".

↑ Π½Π°Π²Π΅Ρ€Ρ… Π² ΠΎΠ³Π»Π°Π²Π»Π΅Π½ΠΈΠ΅

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ 'ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ с ΠΎΡ€Π°Π±ΠΎΡ‚ΠΊΠΎΠΉ Π΄ΠΎΠΏΡƒΡ‰Π΅Π½Π½Ρ‹Ρ… ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ²'

Π‘ Ρ†Π΅Π»ΡŒΡŽ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΠΉ нСобходимости использования Π²Π°ΠΌΠΈ Π² вашСм ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² HTTP-запросов Π±Ρ‹Π» Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ назначСния ΠΈΠΌΠ΅Π½Π½ΠΎΠ²Π°Π½Π½Ρ‹Ρ… ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² (Π² Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ "name=value") для ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π°, допустимых Π² HTTP-запросС ΠΈ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Ρ… для Π΅Π³ΠΎ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π°, с ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ ΠΈΡ… "ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π΅ΠΉ" дальшС Π² прСдставлСниС (Π² Ρ‚ΠΎΠΉ ΠΆΠ΅ Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ "name=value"). Π­Ρ‚ΠΎ продСмонстировано Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ "ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ с ΠΎΡ€Π°Π±ΠΎΡ‚ΠΊΠΎΠΉ Π΄ΠΎΠΏΡƒΡ‰Π΅Π½Π½Ρ‹Ρ… ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ²"

ΠšΠ»ΡŽΡ‡Π΅Π²Ρ‹ΠΌ ΠΌΠΎΠΌΠ΅Π½Ρ‚ΠΎΠΌ для использования ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² являСтся ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠ΅ написаниС рСгулярного выраТСния Π² ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΌ uri_regexp.

routes_of_uri_regexps = (
    ...
    dict(uri_regexp=r'^(/view_random/\?(id=[0-9]*)&(value=[A-F0-9]*)/)$', controller='view.py'),
    ...
)

ΠŸΡ€ΠΈ Ρ„ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ Π² uri_regexp рСгулярного выраТСния Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΡ€ΠΈΠ΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒΡΡ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… ΠΏΡ€Π°Π²ΠΈΠ»:

  • ΡΡ„ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠΉ HTTP-ΠΏΡƒΡ‚ΡŒ, Ρ‚Π°ΠΊ Π½Π°Π·Ρ‹Π²Π°Π΅ΠΌΡ‹ΠΉ PATH_INFO, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, "/path/info/"
  • ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒΡΡ с Π½Π°Π±ΠΎΡ€ΠΎΠΌ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ², ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΡ‹Ρ… ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Ρƒ, ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΌΡƒ Π² ΠΊΠ»ΡŽΡ‡Π΅ controller, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, это "id", "hex", "word"
  • ΡΡ„ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠ°Ρ€Ρ‹ ΠΈΠ· ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² ΠΈ ΠΈΡ… ΡˆΠ°Π±Π»ΠΎΠ½Π½Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ² Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, "id=id_value_type", "hex=hex_value_type", "word=word_value_type"
  • Π·Π°ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ ΠΏΠ°Ρ€Ρ‹ Π² скобки ΠΈ ΡΠΊΠΎΠ½ΠΊΠ°Ρ‚Π΅Π½ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΡ…, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ "&", Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, "(id=id_value_type)&(hex=hex_value_type)&(word=word_value_type)"
  • ΡΠΊΠΎΠ½ΠΊΠ°Ρ‚Π΅Π½ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½ΠΎΠ΅ с ΠΊΠΎΡ€Π½Π΅Π²Ρ‹ΠΌ HTTP-ΠΏΡƒΡ‚Π΅ΠΌ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ "\?", Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, "/path/info/\?(id=id_value_type)&(hex=hex_value_type)&(word=word_value_type)"
  • ΠΏΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Π² ΠΊΠΎΠ½Ρ†Π΅ Π·Π½Π°ΠΊ косой Ρ‡Π΅Ρ€Ρ‚Ρ‹ "/", Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, "/path/info/\?(id=id_value_type)&(hex=hex_value_type)&(word=word_value_type)/"
  • Π·Π°ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Π² ΠΊΡ€ΡƒΠ³Π»Ρ‹Π΅ скобки, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, "(/path/info/\?(id=id_value_type)&(hex=hex_value_type)&(word=word_value_type)/)"
  • ΠΏΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Π·Π½Π°ΠΊΠΈ Π½Π°Ρ‡Π°Π»Π° "^" ΠΈ ΠΊΠΎΠ½Ρ†Π° "$" рСгулярного выраТСния, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, "^(/path/info/\?(id=id_value_type)&(hex=hex_value_type)&(word=word_value_type)/)$"
  • Π·Π°ΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΡˆΠ°Π±Π»ΠΎΠ½Π½Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Π½Π° ΠΈΡ… ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹ Π² Π½ΠΎΡ‚Π°Ρ†ΠΈΠΈ рСгулярных Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€:
    • для "id_value_type" - "[0-9]*"
    • для "hex_value_type" - "[0-9A-Fa-f]*"
    • для "word_value_type" - "[0-9A-Za-z_]*" ΠΈΠ»ΠΈ "\w*"
  • ΠΊΠ°ΠΊ ΠΈΡ‚ΠΎΠ³ Π² uri_regexp внСсти "^(/path/info/\?(id=[0-9]*)&(hex=[0-9A-Fa-f]*)&(word=[0-9A-Za-z_]*)/)$"

Π’ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€ list Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ прСдставлСниС со списком ссылок, Π³Π΄Π΅ ΡƒΠΊΠ°Π·Π°Π½Ρ‹ ΡˆΠ΅ΡΡ‚Π½Π°Π΄Ρ†Π°Ρ‚ΠΈΡ€ΠΈΡ‡Π½Ρ‹Π΅ значСния Π² Π²Π΅Ρ€Ρ…Π½Π΅ΠΌ рСгистрС ΠΈ ΠΈΡ… id, присвоСнныС ΠΈΠΌ Π² порядкС ΠΈΡ… Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ.

А ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€ view ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Π΅ Π² HTTP-запросС id ΠΈ ΡˆΠ΅ΡΡ‚Π½Π°Π΄Ρ†Π°Ρ‚ΠΈΡ€ΠΈΡ‡Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π² Π²Π΅Ρ€Ρ…Π½Π΅ΠΌ рСгистрС . ΠœΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ (ΠΈΠ»ΠΈ ΠΏΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ), Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Ρ… ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² с нСдопустимыми значСниями, Π΄Π°ΠΆΠ΅ ΡˆΠ΅ΡΡ‚Π½Π°Π΄Ρ‡Π°Ρ‚ΠΈΡ€ΠΈΡ‡Π½Ρ‹ΠΌΠΈ Π² Π½ΠΈΠΆΠ½Π΅ΠΌ рСгистрС, Π° Ρ‚Π°ΠΊΠΆΠ΅ отсутствиС Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Ρ… ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² ΠΈΠ»ΠΈ Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ ΠΈΠ½Ρ‹Ρ… ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² ΠΏΡ€ΠΈΠ²Π΅Π΄ΡƒΡ‚ Π² Π²Ρ‹Π·ΠΎΠ²Ρƒ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ RouteDoesNotExist, вСдь Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π½Π΅Ρ‚ ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚Π° ΡƒΠ΄ΠΎΠ²Π»Π΅Ρ‚Π²ΠΎΡ€ΡΡŽΡ‰Π΅Π³ΠΎ ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎΠΌΡƒ uri_regexp.

↑ Π½Π°Π²Π΅Ρ€Ρ… Π² ΠΎΠ³Π»Π°Π²Π»Π΅Π½ΠΈΠ΅

ЛицСнзия

Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ свободно ΠΈΡΠΏΠΎΠ»ΡŒΡ‚Π·ΠΎΠ²Π°Ρ‚ΡŒ Dummy WSGI Framework Π² качСствС каркаса для своих Π’Π΅Π±-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ ΠΈΠ»ΠΈ основы для своСго Π’Π΅Π±-Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊΠ°. Π‘ΡΡ‹Π»Π°Ρ‚ΡŒΡΡ Π½Π° Ρ„Π°ΠΊΡ‚ использования Π’Π°ΠΌΠΈ Dummy WSGI Framework Π½Π΅ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, Π½ΠΎ ΠΌΠ½Π΅ Π±Ρ‹ Ρ…ΠΎΡ‚Π΅Π»ΠΎΡΡŒ ΠΈΠΌΠ΅Ρ‚ΡŒ ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΉ ΠΎΡ‚Π·Ρ‹Π², Π΄Π°ΠΆΠ΅ Ссли ΠΎΠ½ ΠΈ Π½Π΅ ΠΏΠΎΠ»ΠΎΠΆΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ.

↑ Π½Π°Π²Π΅Ρ€Ρ… Π² ΠΎΠ³Π»Π°Π²Π»Π΅Π½ΠΈΠ΅

Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ свСдСния

ΠŸΡ€ΠΎΠ΅ΠΊΡ‚ Π±Ρ‹Π» Π½Π°Ρ‡Π°Ρ‚ Π² Ρ€Π°ΠΌΠΊΠ°Ρ… домашнСго задания курса "Web-Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ Π½Π° Python" Π½Π° https://otus.ru/learning ΠΈ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ ΠΊΠ°ΠΊ Just4Fun-ΠΏΡ€ΠΎΠ΅ΠΊΡ‚.

Π˜Π·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ Π±Ρ‹Π»ΠΎ Ρ€Π΅ΡˆΠ΅Π½ΠΎ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ классы, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΎ Π½ΠΈΡ… ΠΏΡ€ΠΈ постановкС Π·Π°Π΄Π°Ρ‡ΠΈ Π½Π΅ Π³ΠΎΠ²ΠΎΡ€ΠΈΠ»ΠΎΡΡŒ, Π° Ρ‚Π°ΠΊΠΆΠ΅ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΈ сторонниС Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Dummy WSGI Framework Π±Ρ‹Π» максимально "чистым".

ΠŸΡ€ΠΎΡˆΡƒ ΠΏΠΎΠ½ΡΡ‚ΡŒ ΠΈ ΠΏΡ€ΠΎΡΡ‚ΠΈΡ‚ΡŒ.

Π’Π΅ΠΏΠ΅Ρ€ΡŒ, надСюсь, ΠΈ Π’Π°ΠΌ каТСтся, Ρ‡Ρ‚ΠΎ Dummy WSGI Framework Π½Π΅ Ρ‚Π°ΠΊ ΡƒΠΆ "прост" ΠΈ "Π³Π»ΡƒΠΏ".

↑ Π½Π°Π²Π΅Ρ€Ρ… Π² ΠΎΠ³Π»Π°Π²Π»Π΅Π½ΠΈΠ΅