### Ako zvládnuť webinár * pomenuj svojho avatara * napr. dvojkliknutím na svoje meno vpravo hore * nevysielaj obraz, pokiaľ nemusíš * ušetríš linku ostatným ;) * vypni mikrofón, keď nehovoríš * ušetríš linku ostatným ;) * minimalizuješ vzruchy * pýtaj sa, ak máš nejasnosti * stlač medzerník a drž ho, kým rozprávaš (ako na vysielačke) alebo použi chat
## Tvorba webových stránok v jazyku Python mirek@cnl.sk / [**Namakaný deň - Webináre**](http://www.namakanyden.sk/webinare/)

Newsletter

[![FastAPI](images/logo.fastapi.png)](https://fastapi.tiangolo.com) FastAPI framework, high performance, easy to learn, fast to code, ready for production
## Features [Fast](https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=z8kflr-v&a=2), Fast to code, Fewer bugs, Intuitive, Easy, Short, Robust, Standards-based
![Sebastian Ramirez](images/sebastian.ramirez.jpg)] ## [Sebastian Ramirez](https://github.com/tiangolo)
Talk Python To Me Podcast · Modern and fast APIs with FastAPI
## The Plan ### One Time 0. installation 1. introduction 2. web templates ### Next Time 3. REST API 4. Open API (Swagger)
## #1 Installation ```bash $ pip install fastapi uvicorn ```
## #2 Introduction
## Code... ```python # file: hello.py from fastapi import FastAPI app = FastAPI() @app.get("/") def hello(): return {"Hello": "World"} ```
## ...and Run! ```bash $ uvicorn hello:app --reload ```
## Run from Code ```python # file: hello2.py from fastapi import FastAPI import uvicorn app = FastAPI() @app.get("/") def hello(): return {"Hello": "World"} if __name__ == "__main__": uvicorn.run('hello:app', host="0.0.0.0", port=5000, # default port is 8000 reload=True) ```

FastAPI vs Flask

      
from fastapi import FastAPI
app = FastAPI()

@app.get("/")
def hello():
    return {"Hello": "World"}
      
      
      
from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello():
    return 'Hello, World!'
      
      
## Key Difference... ...API First Approach
```bash $ curl -v http://localhost:5000 * Connected to localhost (127.0.0.1) port 5000 > GET / HTTP/1.1 > Host: localhost:5000 > User-Agent: curl/7.71.1 > Accept: */* > < HTTP/1.1 200 OK < date: Wed, 04 Nov 2020 09:46:48 GMT < server: uvicorn < content-length: 17 < content-type: application/json < {"Hello":"World"} ```
## The Use Case simple sensor dashboard
![Components of URL](images/url.format.explained.png) Notes: * https://bind.media/cro/how-to-setup-hotjar-basic-account/
## #3 Web Templates * you can use any template engine you want * we will use [Jinja2](https://jinja.palletsprojects.com/en/2.11.x/) * "native" support in Flask * very popular
[![Jinja2 Logo](images/logo.jinja2.png)](https://jinja.palletsprojects.com/en/2.11.x/)
## Installing Jinja2 ```bash $ pip install jinja2 ```
## Jinja2 Introduction ```python from jinja2 import Template template = Template('Hello {{ name }}!') print(template.render(name='John Doe')) # 'Hello John Doe!' ```
## Model Template View web version of MVC
## Jinja2 with FastAPI ```python # file: dashboard.start.py from fastapi import FastAPI, Request from fastapi.responses import HTMLResponse from fastapi.templating import Jinja2Templates app = FastAPI() templates = Jinja2Templates(directory="templates") @app.get("/dashboard", response_class=HTMLResponse) def view_dashboard(request: Request): return templates.TemplateResponse( "dashboard.html", {"request": request, "title": "My Dashboard"} ) ```
[![Bootstrap](https://www.fullstackpython.com/img/logos/bootstrap.png)](https://getbootstrap.com)
## Getting the Data from JSON File ```python import json @app.get("/dashboard", response_class=HTMLResponse) async def view_dashboard(request: Request): data = json.load(open('data.json')) return templates.TemplateResponse( "dashboard.html", { "request": request, "title": "Magic Dashboard!", "temperature": data['temperature'], "timestamp": data['timestamp'] } ) ```
## Rendering Form ```python @app.get("/form", response_class=HTMLResponse) async def view_form(request: Request): return templates.TemplateResponse( "form.html", {"request": request} ) ```
## Processing Form Data ```python # imports! @app.post("/form") async def process_form(request: Request, temperature: float = Form(...)): now = datetime.now() data = { 'temperature': str(temperature), 'timestamp': now.strftime("%d.%m.%Y %H:%M:%S") } with open('data.json', 'w+') as file: json.dump(data, file) return RedirectResponse(url='/dashboard', status_code=HTTP_303_SEE_OTHER) ```
## REST API * one endpoint for two HTTP methods * `GET /api/temp/` - get curren temperature * `POST /api/temp/` - add new measurement
## `GET /api/temp` ```python @app.get('/api/temp') def get_latest_value(): file = open('data.json') data = json.load(file) return data ```
## Documentation * builtin support for * [Swagger/OpenAPI](https://github.com/swagger-api/swagger-ui) * [ReDoc](https://github.com/Redocly/redoc) * accessing the doc: * Swagger on `http://URL/docs` * ReDoc on `http://URL/redoc`
## [Pydantic](https://pydantic-docs.helpmanual.io) Data validation and settings management using python type annotations.
## `Payload` Model ```python from datetime import datetime from pydantic import BaseModel class Payload(BaseModel): temperature: float created: datetime = datetime.now().isoformat() ```
## `POST /api/temp` ```python @app.post('/api/temp', status_code = 201) def add_new_value(data: Payload): with open('data.json', 'w+') as file: json.dump(data.dict(), file) return data ```
## Testing/Using ```python import requests url = 'http://localhost:8000/api/temp' r = requests.post(url, json={'temperature': -3}) print(r.status_code) # 201 Created ```
## Questions?
![qr code](https://api.qrserver.com/v1/create-qr-code/?data=https://bit.ly/2HSPYkr&size=300x300) (**https://bit.ly/2HSPYkr**)