Slide 1

Slide 1 text

Joyful Python Web App development with Appier João Magalhães

Slide 2

Slide 2 text

A bit of history ● Born out of Hive Solutions’ necessity ● Built in 2013 out of Flask Quorum set of Flask extensions ● Simple design influenced by Flask ● “Some batteries included” philosophy

Slide 3

Slide 3 text

“Some batteries included” ● Django, batteries included (too bloated) ● Flask (minimalist, some major things are missing) ● Appier in between both

Slide 4

Slide 4 text

Design decisions ● Object oriented in nature ● Data model layer out of the box ● Built for easy REST API building ● Extensible by design ● Scalable and performant ● Asynchronous (coroutines and futures)

Slide 5

Slide 5 text

Code... class HelloApp(appier.App): @appier.route("/", "GET") def hello(self): return "Hello World" HelloApp().serve()

Slide 6

Slide 6 text

… and JSON class HelloApp(appier.App): @appier.route("/", "GET", json=True) def hello_json(self): return {"Hello" : "world"} HelloApp().serve()

Slide 7

Slide 7 text

Async support design ● Scalable (solves the C10K problem) ● Compatible (supports both Python 2.6+ and 3.3+) ● Simple (code looks as similar as possible to “normal” blocking Appier code) ● Uses (semi-)coroutines together with futures ● Works great with the asyncio module (from standard lib)

Slide 8

Slide 8 text

What’s asynchronous on Appier ● Async from top to bottom & out-of-the box ● Lots of challenges implementing it ● Template rendering ● Data layer ● Filesystem IO, HTTP clients, etc.

Slide 9

Slide 9 text

Not Async example class NotAsyncHTTPApp(appier.App): @appier.route("/", "GET") def example(self): return appier.get("https://appier.hive.pt/") NotAsyncHTTPApp().serve()

Slide 10

Slide 10 text

Async example class AsyncHTTPApp(appier.App): @appier.route("/", "GET") async def example(self): return await appier.get_w("https://appier.hive.pt/") AsyncHTTPApp().serve()

Slide 11

Slide 11 text

Another async example class AsyncHTTPApp(appier.App): @appier.route("/", "GET") async def example(self): url = "https://appier.hive.pt/” await asyncio.sleep(3) response = await aiohttp.request("GET", url) return await response.read() AsyncHTTPApp().serve()

Slide 12

Slide 12 text

Async data layer class AsyncModelsApp(appier.App): @appier.route("/", "GET") async def example(self): person = models.Person(name="Tobias") await person.save() print(person.id) person = await models.Person.get(name="Tobias") return person.map() HelloApp().serve()

Slide 13

Slide 13 text

Templates ● Modular template support ● Jinja2 is first class citizen ● Async rendering support for Jinja2 out-of-the-box

Slide 14

Slide 14 text

Models ● Simple model design approach ● Multiple back-end support ● Validations, pre_*, post_* and on_* hooks ● Custom type support (implement loads() and dumps()) ● Async support (still under construction)

Slide 15

Slide 15 text

Models - Example class Person(appier.Model): identifier = appier.field( type = int, index = True, increment = True ) name = appier.field() age = appier.field( type = int )

Slide 16

Slide 16 text

Models - Custom Types class Person(appier.Model): thumbnail = appier.field( type = appier.image( width = 400, height = 400, format = "png" ) )

Slide 17

Slide 17 text

Models - Custom Types class DateTime(appier.Type): def loads(self, value): self._datetime = datetime.datetime.utcfromtimestamp(value) def dumps(self): return self.timestamp() def timestamp(self): return time.mktime(self._datetime.timetuple())

Slide 18

Slide 18 text

● Admin interface ● Access control ● Auto-snapshotting of models ● Encrypted model fields ● App configuration (JSON, env variables, DB, other) Other cool features

Slide 19

Slide 19 text

Who uses it ?

Slide 20

Slide 20 text

● nicholaskirkwood.com ● budy.hive.pt ● rocklobby.com ● oioba.com ● webook.pt ● dev.windows.com ● karl.com ● my-swear.com ● hive.pt ● lugardajoia.com Who uses it ?

Slide 21

Slide 21 text

What’s joy ? ● Having a minimal set of dependencies ● Owning the code by understanding it ● Having code that scales properly ● Using simple tools to build complex things

Slide 22

Slide 22 text

Q & A Best question gets a free PyCharm subscription