Little things with raffia-work base

8. 12. 2012 20:04 Petr Blahoš

Před takovými šesti lety jsem začal s frameworkem Pylons. Oproti té šílenosti co jsem měl před tím – jscript na serveru, no vlastně ne na serveru, ale na IIS – to bylo čisté nebe. Člověk (aspoň některý) se snaží proniknout trochu do hloubky, takže jsem časem pochopil něco o WSGI, middleware, o tom, jakou roli tam vlastně ten framework hraje, a tak dál. Ten rozdíl mezi poměrně komplexním frameworkem (jako je třeba Pylons) a čistým WSGI je poměrně velký. Ikdyž, když si to tak vezmeme, tak ten framework tam má hlavní roli na dvou místech:

  • Mapování url na nějaký handler (většinou routing)
  • Zjednodušení vyrenderování nějaké odpovědi (většinou integraci šablonovacího systému)
Kromě toho dělá pár dalších drobností:
  • Internacionalizace/lokalizace
  • Datový model/podpora databází/ORM
  • Testovací framework
  • Sessions
  • Bezpečnost
  • Caching
  • Ladění, prostě drobnosti
Takže mám framework a docela pěkně se v něm orientuju, ale teď potřebuju udělat nějakou hodně malou, která vpodstatě nic z toho nahoře nepotřebuje (ani routing). Naopak, potřebuju tam něco, čemu vlastně ten framework trochu brání. Tak to zkusíme bez frameworku, jenom s WebOb.

WSGI aplikace je vlastně jakékoliv callable, které bere nějaké parametry, a vrací něco. V principu vrací nějakou formou string, nebo iterable, ale jakou přesně mě teď moc nezajímá. To za nás vyřeší WebOb. Takže kdybyste chtěli hodně malou aplikaci, mohla by vypadat třeba takto:

from webob import Response

class TinyApp(object):
    def __call__(self, environ, start_response):
        resp = Response("""<html><body>AHOJ</body></html>""")
        return resp(environ, start_response)

if __name__ == '__main__':
    from wsgiref.simple_server import make_server
    server_ip = ""
    server_port = 8080
    make_server(server_ip, server_port, TinyApp()).serve_forever()

(taky tady)

Žádný routing, žádné šablony. Na jakoukoliv otázku stejná odpověď.

Abychom tomu dali aspoň minimální možnosti, přidáme takový banální routing. Dál, na neznámé url bude vracet 404. A nakonec, proč to celé dělám? Podívejte se na slowtest.

import time

from webob import Request, Response
from webob import exc

def slow_generator():
    yield "<html><body><h1>Starting</h1>\n"
    for i in range(10):
        yield("%s: Hello!!! Hello!!! Hello!!! Hello!!! Hello!!! Hello!!!<br>\n" % (i+1))
        time.sleep(0.4)
    yield("Finito")
    yield("<body><html>")

class TinyApp(object):
    def slowtest(self):
        resp = Response()
        resp.app_iter = slow_generator()
        return resp
    def index(self):
        resp = Response()
        resp.body = """<html><body><<h1>WSGI WebOb Test</h1>
            <a href="slowtest">Click here</a> to try a slow generator.<br>
            <body><html>
        """
        return resp
    def __call__(self, environ, start_response):
        req = Request(environ)
        resp = {
                "/": self.index,
                "/slowtest": self.slowtest,
        }.get(req.path_info, exc.HTTPNotFound)
        return resp()(environ, start_response)

if __name__ == '__main__':
    from wsgiref.simple_server import make_server
    server_ip = ""
    server_port = 8080
    make_server(server_ip, server_port, TinyApp()).serve_forever()

(taky tady)

Ve své aplikaci potřebuju provést pár testů, každý z nich chvilku trvá. A chtěl bych, aby uživatel viděl průběh jednotlivých testů, ne celou stránku najednou až potom, co všechny testy doběhnou. Jak na to ukazuje právě ten slowtest a slow_generator.

Příště si tam doděláme jednu moc důležitou věc. Nebo možná dvě. Uhodnete někdo jaké?

Sdílet