Первое веб приложение на фреймворке Sanic

Sanic — это асинхронный фреймворк для создания веб-приложений на языке Python. Sanic - один из самых популярных фреймворков в PyPI и лучший фреймворк с поддержкой асинхронности. Вот как можно запустить Sanic.

Создайте, перейдите в каталог, где вы хотите создать виртуальное окружение.

python3 -m venv myvenv && source ./myvenv/bin/activate

Установите необходимые зависимости.

pip install sanic sanic_ext jinja2

Создайте новый файл с расширением .py.

touch app.py

Сoдержание файла app.py.

#Импортируйте необходимые модули
from sanic import Sanic
from sanic.response import json
from sanic_ext import Extend, render




app = Sanic('Sanic_App')
Extend(app)


#Для статических файлов определим директорию static
app.static('/static', './static')



#Определите маршрут:
@app.route('/')
async def home(request):

   context = {"test": "Привет! У тебя получилось."}
   #Наши шаблоны будут находится в директории 'templates/'
   return await render("/index.html", context=context)

@app.get("/start")
async def start_app(request):
    return await render("/start.html")


#Запустите приложение:
if __name__ == '__main__':
   app.run(host='127.0.0.1', port=8000, workers=1, auto_reload=True, debug=True)

Создадим две директории, для шаблонов (*.html, *.htm) и статических файлов (*.css, *.js, *.png, *.svg, *.jpg).

Папка или директория – это специальное место на компьютерном носителе информации, в котором хранятся имена файлов и сведения об этих файлах (размер файлов, время их последнего обновления, свойства файлов)

#для шаблонов
mkdir templates

#для статических файлов
mkdir static

Начнем c директории 'static/'. Чтобы всё было ясно и понятно нам нужно создать в директории еще три папки.

#переходим в эту папку
cd static/
#создадим папку для файлов *.css
mkdir css
#создадим папку для файлов *.js
mkdir js
#создадим папку для файлов *.png, *.jpg и т.д.
mkdir media

За внешней вид (frontend), я буду использовать фреймворк Bulma (ознакомится).

В это папке ./static/css/ у меня находится файл "bulma.css" (./static/css/bulma.css)

Содержание файла main.js в папке (./static/js/main.js). Функционал открыть/закрыть (navbar), open/close (modal).

//Navbar open/close
document.addEventListener('DOMContentLoaded', () => {

  // Get all "navbar-burger" elements
  const $navbarBurgers = Array.prototype.slice.call(document.querySelectorAll('.navbar-burger'), 0);

  // Add a click event on each of them
  $navbarBurgers.forEach( el => {
    el.addEventListener('click', () => {

      // Get the target from the "data-target" attribute
      const target = el.dataset.target;
      const $target = document.getElementById(target);

      // Toggle the "is-active" class on both the "navbar-burger" and the "navbar-menu"
      el.classList.toggle('is-active');
      $target.classList.toggle('is-active');

    });
  });

});
//Modal open/close
document.addEventListener('DOMContentLoaded', () => {
  // Functions to open and close a modal
  function openModal($el) {
    $el.classList.add('is-active');
  }

  function closeModal($el) {
    $el.classList.remove('is-active');
  }

  function closeAllModals() {
    (document.querySelectorAll('.modal') || []).forEach(($modal) => {
      closeModal($modal);
    });
  }

  // Add a click event on buttons to open a specific modal
  (document.querySelectorAll('.js-modal-trigger') || []).forEach(($trigger) => {
    const modal = $trigger.dataset.target;
    const $target = document.getElementById(modal);

    $trigger.addEventListener('click', () => {
      openModal($target);
    });
  });

  // Add a click event on various child elements to close the parent modal
  (document.querySelectorAll('.modal-background, .modal-close, .modal-card-head .delete, .modal-card-foot .button') || []).forEach(($close) => {
    const $target = $close.closest('.modal');

    $close.addEventListener('click', () => {
      closeModal($target);
    });
  });

  // Add a keyboard event to close all modals
  document.addEventListener('keydown', (event) => {
    if(event.key === "Escape") {
      closeAllModals();
    }
  });
});

// скопировано с сайта https://bulma.io/

Содержание папки (./static/media/),два файла иконка с расширением *.ico и  фотография с расширением *.jpg.

Фавиконка (favicon.ico) — это иконка, которая отображается во вкладке браузера перед названием страницы. Также эта иконка отображается в закладках и на рабочем столе для веб-приложений.

А теперь разбирёмся директорий 'templates/', тут всё проще работа с шаблонизатором 'jinja2'. Если вы не знакомы с работай этого замечательного инструмента, шаблонизатора 'jinja2' здесь ясно и понятно рассказано https://proproprogs.ru
#переходим в эту директорию
cd templates/
#создадим три файла 'basic.html', 'index.html', 'start.html'
#любым для вас способом
vim basic.html
touch index.html
touch start.html

Содержание файла 'basic.html'.

<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="icon" type="image/ico" sizes="32x32" href="/static/media/w_s.ico">
    <title>Landing - Free Bulma template</title>
    <link rel="stylesheet" href="/static/css/bulma.css" />
</head>

<body>
    <section class="hero is-info is-fullheight">
        <div class="hero-head">
            <nav class="navbar">
                <div class="container">
                    <div class="navbar-brand">
                        <a class="navbar-item" href="/">
                            <img src="/static/media/foto_1.jpg" alt="Logo">
                        </a>
                        <span class="navbar-burger burger" data-target="navbarMenu">
                            <span></span>
                            <span></span>
                            <span></span>
                            <span></span>

                        </span>
                    </div>
                    <div id="navbarMenu" class="navbar-menu">
                        <div class="navbar-end">
                            <span class="navbar-item">
                                <a class="button is-black is-outlined" href="/">
                                    <span>Home</span>
                                </a>
                            </span>

                            <span class="navbar-item">
                                <a class="button is-black is-outlined" href="/start">
                                    <span>Page Start</span>
                                </a>
                            </span>
                        </div>
                    </div>
                </div>
            </nav>
            </div>

            <div class="hero-body">
                <div class="container has-text-centered">
                    <div class="column is-6 is-offset-3">
                        <h1 class="title">
                            {{test}}
                        </h1>
                        <div class="box">

                           {% block content %}{% endblock content %}

                        </div>
                    </div>
                </div>
            </div>

    </section>
    <script  src="/static/js/main.js"></script>
</body>

</html>

Содержание файла 'index.html'.

{% extends '/basic.html' %}
<!-- наследуем от файла basic.html --> 
{% block content %}
 <div class="field is-grouped">
    <p class="control is-expanded">
       <input class="input" type="text" placeholder="Enter your email">
      </p>
     <p class="control">
      <a class="button is-info">Notify Me</a>
    </p>
 </div>
{% endblock content %}
foto moto boto

Содержание файла 'start.html'. На ваш выбор. Где выбрать? Bulma free templates
Теперь мы можем его запустить наше первое веб-приложение на фреймворке Sanic .

python3 app.py

Исходники этого примера лежит на gitverse. Example code