Tvorba internetových aplikací

Jakub Klinkovský

:: České vysoké učení technické v Praze
:: Fakulta jaderná a fyzikálně inženýrská
:: Katedra softwarového inženýrství

Akademický rok 2022-2023

Jazyk Python – pokračování

Sortování seznamu

In [1]: a = [5, 1, 4, 3]
  1. Funkce sorted() vrací seřazený seznam a nemění vstupní data:
    In [2]: sorted(a)
    Out[2]: [1, 3, 4, 5]
    
  2. Metoda .sort() mění daný seznam (a vrací None):
    In [3]: a.sort()
    
    In [4]: a
    Out[4]: [1, 3, 4, 5]
    

Sortování dle vlastního klíče

In [1]: s = ["ccc", "aaaa", "d", "bb"]

In [2]: sorted(s, key=len)
Out[2]: ['d', 'bb', 'ccc', 'aaaa']

Klíč může obsahovat i více hodnot (tuple má lexikografické porovnávání):

In [1]: s = ["xyz", "aaa", "z", "ccc"]

In [2]: sorted(s, key=lambda v: (len(v), v))
Out[2]: ['z', 'aaa', 'ccc', 'xyz']

Importování modulů

Python obsahuje mnoho standardních modulů, které rozšiřují funkčnost jazyka. Dále lze instalovat externí moduly (balíčky) nebo definovat vlastní.

Příklad:

import math

r = 0.123
s = math.pi * r ** 2
print(f"plocha kruhu o poloměru {r} je {s}")

Dostupné objekty uvnitř modulu: viz např. dir(math)

Příklad: pomocí from ... import ... lze importovat jen určité identifikátory:

from pprint import pprint

m = [[0, 1, 2], [3, 4, 5], [6, 7, 9]] * 3
pprint(m)

Definice vlastní třídy

class MyClass:
    """A simple example class"""
    i = 12345

    def __init__(self, data):
        self.data = data

    def f(self):
        return f"hello world: {self.data=}"

obj = MyClass(3.14)
obj.f()
  • první parametr metody (konvence: self) představuje instanci objektu
  • atributy třídy (MyClass.i) vs atributy instance (self.data)

Zdroje informací

Python jako web server

Python web server pro statický web

Python obsahuje modul http.server, který lze použít přímo pro poskytování statického obsahu, nebo pro vývoj dynamických aplikací.

Přímé použití:

M:\>python -m http.server --help
usage: server.py [-h] [--cgi] [--bind ADDRESS] [--directory DIRECTORY] [port]

positional arguments:
  port                  specify alternate port (default: 8000)

options:
  -h, --help            show this help message and exit
  --cgi                 run as CGI server
  --bind ADDRESS, -b ADDRESS
                        specify alternate bind address (default: all interfaces)
  --directory DIRECTORY, -d DIRECTORY
                        specify alternate directory (default: current directory)

Např. python -m http.server --directory C:\Users\klinkjak\Documents

Python web server pro statický web

  1. Vytvořte adresář pro obsah webu (např. INTA_cv2)
  2. V tomto adresáři vytvořte soubor index.html
    (např. echo "Hello, world!" > INTA_cv2\index.html nebo zkopírujte soubor z předchozího cvičení)
  3. Spusťte web server: python -m http.server --directory INTA_cv2)

Základní dynamický web server

from http.server import BaseHTTPRequestHandler, HTTPServer

hostName = "localhost"
serverPort = 8080

class MyServer(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header("Content-type", "text/html")
        self.end_headers()
        self.wfile.write(bytes("<html><head><title>Basic web server</title></head>", "utf-8"))
        self.wfile.write(bytes(f"<p>Request: {self.path}</p>", "utf-8"))
        self.wfile.write(bytes("<body>", "utf-8"))
        self.wfile.write(bytes("<p>This is an example web server.</p>", "utf-8"))
        self.wfile.write(bytes("</body></html>", "utf-8"))

if __name__ == "__main__":        
    webServer = HTTPServer((hostName, serverPort), MyServer)
    print(f"Server started, go to http://{hostName}:{serverPort}")

    try:
        webServer.serve_forever()
    except KeyboardInterrupt:
        pass

    webServer.server_close()
    print("Server stopped.")

Framework Django

Django – přehled

Django je framework pro vývoj webových aplikací postavený na jazyku Python.

Poskytované funkce:

  • mapování URL
  • šablony
  • formuláře
  • databáze
  • ověřování uživatelů, administrátorské rozhraní
  • tvorba vícejazyčných stránek
  • bezpečnostní prvky

Django – instalace

Příkazem pip install django (případně python -m pip install django)

Ověření: příkazem django-admin --version v terminálu, nebo v IPythonu:

In [1]: import django
   ...: print(django.get_version())
4.1.7

Poznámka: po instalaci může být nutné zavřít terminál a otevřít nový (např. Windows)

Django – vytvoření projektu

V adresáři, kde chcete vytvořit projekt, spusťte příkaz:

django-admin startproject mysite

Přikaz vytvoří následující strukturu souborů:

mysite/
    manage.py
    mysite/
        __init__.py
        settings.py
        urls.py
        asgi.py
        wsgi.py

Django – první projekt

  • manage.py: program/skript pro obsluhu projektu
  • mysite/__init__.py: prázdný soubor, který označuje daný adresář jako balíček (package) pro jazyk Python
  • mysite/settings.py: soubor s konfigurací projektu
  • mysite/urls.py: soubor s deklaracemi, které mapují URL na funkce v Pythonu
  • mysite/asgi.py: vstupní skript pro web server využívající standard ASGI
  • mysite/wsgi.py: vstupní skript pro web server využívající standard WSGI

Spuštění vývojového serveru

Pomocí skriptu manage.py spustíme podpříkaz runserver:

python manage.py runserver

Web server běží na pozadí a prázdná aplikace je dostupná na defaultní adrese http://localhost:8000/

Poznámka: Tento web server je určený pro vývoj a ne k produkčnímu nasazení. Není příliš efektivní, ale poskytuje užitečné funkce usnadňující programování aplikace (např. automatické obnovení/restartování aplikace po změnách v kódu).

Poznámka: Po spuštění vznikne v projektu adresář __pycache__, který obsahuje předkompilované soubory (bytecode) pro efektivnější běh aplikace.

Přidání aplikace

Pomocí skriptu manage.py vytvoříme soubory pro novou aplikaci v projektu:

python manage.py startapp pokus

Přikaz vytvoří následující strukturu souborů (ve vnějším adresáři mysite):

pokus/
    __init__.py
    admin.py
    apps.py
    migrations/
        __init__.py
    models.py
    tests.py
    views.py

Mapování URL na view

views.py:

from django.http import HttpResponse

def index(request):
    return HttpResponse("<b>Hello, world!</b>")

urls.py:

from django.contrib import admin
from django.urls import path

from pokus import views

urlpatterns = [
    path("", views.index),
    path('admin/', admin.site.urls),
]

Úkol

Upravte view index v aplikaci pokus tak, že se v textu zobrazí aktuální datum a čas (dle zpracování požadavku serverem).

Bonus: Zobrazte také svátek připadající na daný den.

Výsledný projekt zazipujte a odevzdejte přes Moodle.