#app.py
import hug

@hug.get('/')
def spam():
    return 'ham!'

!hug -f app.py

spam()

#app_cli.py
import hug

@hug.cli()
@hug.get('/')
def spam():
    return 'ham!'

!hug -f app_cli.py

!hug -f app_cli.py -c spam

"""
Explanation: Michał Bultrowicz
Zadawajcie pytania w trakcie prezentacji

Ideologia

Tylko Python3
Pisz kod raz, udostępniaj przez wiele interfejsów
HTTP
CLI
Zwykły kod Pythona
Zachowanie dużej szybkości (Falcon jako baza)
End of explanation
"""


# przez get i URL jak w dokumentacji, ale to nie REST
import hug

@hug.get()
def hello(name: hug.types.text, age: int):
    return "Hello {}! You've lived for {} years.".format(name, age)

hug.API(__name__).http.serve()

import socketserver
socketserver.TCPServer.allow_reuse_address = True

# zwolnienie socketu zajętego przez proces Notebooka
import gc
gc.collect()

@hug.get('/smallish-number/{number}')
def hello(number: hug.types.in_range(1,30)):
    return {'bigger_number': number+1}

hug.API(__name__).http.serve()

gc.collect()

@hug.post('/rectangle', status=hug.HTTP_201)
def hello(a: int, b: int):
    return {'width': a, 'height': b}

hug.API(__name__).http.serve()

gc.collect()

"""
Explanation: Czas pokaże czy wiele rodzajów interfejsów to sensowne podejście.

Szybkie tworzenie minimalnych serwisów

Alternatywa dla Bottle, Flaska itd.
Framework ma kod wyższej jakości
Duża wydajność

Uwaga! Aplikacje robione "na szybko" zazwyczaj żyją dłużej, niż powinny.

Walidacja wejścia
End of explanation
"""


@hug.get('/', response_headers={'X-bblabla': 'jakas wartosc'})
def spam():
    return 'ham!'

hug.API(__name__).http.serve()

gc.collect()

@hug.directive()
def http_req(**kwargs):
    return kwargs['request']

@hug.directive()
def http_resp(**kwargs):
    return kwargs['response']

@hug.get('/')
def spam(hug_http_req, hug_http_resp):
    print(hug_http_req)
    print(hug_http_resp)
    
    print(hug_http_req.headers)
    hug_http_resp.status = hug.HTTP_418
    return 'ham!'

hug.API(__name__).http.serve()

# czytanie headerów z dyrektywy
# hug_session - ustawianie statusu, też czytanie headerów

gc.collect()

"""
Explanation: Można definiować swoje typy przez:
* rozszerzanie istniejacych typów z hug.types
* tworzenie klas Marshmallow


Bardziej zaawansowana interakcja z HTTP
End of explanation
"""


