|
|
@@ -0,0 +1,212 @@
|
|
|
+Slug: falcon-intro
|
|
|
+Title: Going slim with Falcon
|
|
|
+Category: Je tisse ma toile
|
|
|
+Tags: développement, Falcon, Python, web, un peu compliqué quand même
|
|
|
+Date: 2018-08-06
|
|
|
+Summary: First contact with Falcon backend framework
|
|
|
+Image: /images/falcon_logo.svg
|
|
|
+Lang: en
|
|
|
+Status: published
|
|
|
+
|
|
|
+___
|
|
|
+
|
|
|
+![Falcon logo][falcon-logo]
|
|
|
+
|
|
|
+In one of those many "let's reconsider everything" periods I've experienced
|
|
|
+throughout my project, some new technical choices have brought into question my
|
|
|
+use of the most famous of Python web frameworks ([Django][django]), and brought
|
|
|
+into consideration a much more minimalist framework, whose little name is
|
|
|
+[Falcon][falcon].
|
|
|
+
|
|
|
+Let's start by reminding that a few months ago I still didn't know anything in
|
|
|
+web development (even the difference between frontend and backend was a mystery
|
|
|
+to me), and even though starting with Django helped me a lot learning through
|
|
|
+that at my own pace, it now seems a bit overkill for the few tasks that will
|
|
|
+now be handled by my backend.
|
|
|
+
|
|
|
+I might develop that point in a future article, but here's me exploring a new
|
|
|
+tool, and sharing my thoughts and findings might be useful.
|
|
|
+
|
|
|
+Anyhow, let's cut the talk.
|
|
|
+
|
|
|
+
|
|
|
+## My architecture
|
|
|
+
|
|
|
+Having finally discovered the benefits of a genuine frontend framework, I
|
|
|
+realize how valuable it would be now to drastically restrict the role of the
|
|
|
+backend, which was in charge of everything until now : authentication, sessions
|
|
|
+handling, page render, data validation, form handling, admin site generation,
|
|
|
+database migrations, internationalization, localization, ... Props to Django for
|
|
|
+that.
|
|
|
+
|
|
|
+This time, I'll keep to the bare minimum :
|
|
|
+
|
|
|
+* database management
|
|
|
+* data validation
|
|
|
+* RESTful API management
|
|
|
+* authentication
|
|
|
+
|
|
|
+That list might grow up as I advance in time, but the minimalist approach of
|
|
|
+Falcon is therefore quite appealing to me ; I'm the only captain onboard, and
|
|
|
+it seems reasonable enough to handle all those tasks myself now that I almost
|
|
|
+start to get a glimpse of what happens within a web server.
|
|
|
+
|
|
|
+## Installation
|
|
|
+
|
|
|
+### Procedure
|
|
|
+
|
|
|
+Everything starts by creating a virtual environment :
|
|
|
+
|
|
|
+ :::sh
|
|
|
+ # theenglishway @ time in ~/Documents [9:05:01]
|
|
|
+ $ mkdir falcon
|
|
|
+
|
|
|
+ # theenglishway @ time in ~/Documents [9:06:30]
|
|
|
+ $ cd falcon
|
|
|
+
|
|
|
+ # theenglishway @ time in ~/Documents/falcon [9:06:31]
|
|
|
+ $ python3 -m venv ./.venv
|
|
|
+
|
|
|
+ # theenglishway @ time in ~/Documents/falcon [9:06:47]
|
|
|
+ $ source .venv/bin/activate
|
|
|
+
|
|
|
+Then [the official page installation instructions][falcon-install] will be your
|
|
|
+best guide, and you might add the excellent [HTTPie][httpie] utility, which will
|
|
|
+be very convenient to chat with the API (and is recommended by Falcon developers).
|
|
|
+
|
|
|
+ :::sh
|
|
|
+ (.venv)
|
|
|
+ # theenglishway @ time in ~/Documents/falcon [9:22:10]
|
|
|
+ $ pip install falcon gunicorn httpie
|
|
|
+
|
|
|
+It's a good moment to also create a requirements.txt file
|
|
|
+
|
|
|
+ :::sh
|
|
|
+ (.venv)
|
|
|
+ # theenglishway @ time in ~/Documents/falcon [9:22:10]
|
|
|
+ $ pip freeze > ./requirements.txt
|
|
|
+
|
|
|
+... and initialize the git repo, the .gitignore, and so on. I like having a
|
|
|
+non-versioned `.envsetup` file with all the environment variables, and that allows
|
|
|
+activating the virtual environment through a simple `source .envsetup`.
|
|
|
+
|
|
|
+ :::sh
|
|
|
+ source .venv/bin/activate
|
|
|
+ # Variables such as DEBUG=1 will come here
|
|
|
+
|
|
|
+### Basic check
|
|
|
+
|
|
|
+The [official site examples][falcon-examples] are useful to check that
|
|
|
+everything is in order.
|
|
|
+
|
|
|
+ :::sh
|
|
|
+ (.venv)
|
|
|
+ # theenglishway @ time in ~/Documents/falcon on git:master x [9:58:33]
|
|
|
+ $ http :8000/things
|
|
|
+ HTTP/1.1 200 OK
|
|
|
+ Connection: close
|
|
|
+ Date: Sun, 08 Jul 2018 07:58:47 GMT
|
|
|
+ Server: gunicorn/19.9.0
|
|
|
+ content-length: 100
|
|
|
+ content-type: application/json; charset=UTF-8
|
|
|
+
|
|
|
+ Two things awe me most, the starry sky above me and the moral law within me.
|
|
|
+
|
|
|
+ ~ Immanuel Kant
|
|
|
+
|
|
|
+ (.venv)
|
|
|
+ # theenglishway @ time in ~/Documents/falcon on git:master x [10:03:16]
|
|
|
+ $ http localhost:8000/1/things authorization:custom-token
|
|
|
+ HTTP/1.0 200 OK
|
|
|
+ Date: Sun, 08 Jul 2018 08:03:40 GMT
|
|
|
+ Server: WSGIServer/0.2 CPython/3.5.3
|
|
|
+ content-length: 66
|
|
|
+ content-type: application/json; charset=UTF-8
|
|
|
+ powered-by: Falcon
|
|
|
+
|
|
|
+ [
|
|
|
+ {
|
|
|
+ "color": "green",
|
|
|
+ "id": "fc9aee6e-5f2c-46e7-bb5e-1535475f2220"
|
|
|
+ }
|
|
|
+ ]
|
|
|
+
|
|
|
+Well that seems OK ... what now ?
|
|
|
+
|
|
|
+## First steps
|
|
|
+
|
|
|
+The official site has a [nice little tutorial][falcon-tutorial] that seemed
|
|
|
+good enough to me and can be recommended.
|
|
|
+
|
|
|
+Several points stand out.
|
|
|
+
|
|
|
+**First** is that the baremetal aspect is no joke ! No need to invoke Django's
|
|
|
+black sorcery, the server can be launched from command line and debugged with
|
|
|
+your favorite tools :
|
|
|
+
|
|
|
+ :::sh
|
|
|
+ (.venv)
|
|
|
+ # theenglishway @ time in ~/Documents/falcon on git:master x [10:19:12] C:1
|
|
|
+ $ gunicorn --reload myapp/app.py
|
|
|
+ [2018-07-08 11:29:38 +0200] [13216] [INFO] Starting gunicorn 19.9.0
|
|
|
+ [2018-07-08 11:29:38 +0200] [13216] [INFO] Listening at: http://127.0.0.1:8000 (13216)
|
|
|
+ [2018-07-08 11:29:38 +0200] [13216] [INFO] Using worker: sync
|
|
|
+ [2018-07-08 11:29:38 +0200] [13219] [INFO] Booting worker with pid: 13219
|
|
|
+
|
|
|
+That allows setting up a nice and handy development environment (for instance
|
|
|
+using [Pycharm **Community Edition**][pycharm]) :
|
|
|
+
|
|
|
+![Pycharm et Falcon][pycharm-falcon]
|
|
|
+
|
|
|
+As for the rest you really feel "naked" ! The slightest unit test on an API that
|
|
|
+returns a simple JSON array requires you to write such code as
|
|
|
+`result = json.loads(response.content.decode())`.
|
|
|
+
|
|
|
+Server side, some basic features are included like
|
|
|
+[decoding content sent by the client][falcon-media], but only JSON is supported.
|
|
|
+For any other types, you'll need to decode the binary stream using your bare
|
|
|
+hands.
|
|
|
+
|
|
|
+**Second** is that even the tutorial points the importance of tests, and that's
|
|
|
+always a good point for me!
|
|
|
+
|
|
|
+**Third** is that everything seems clear enough and consistent, and only a few
|
|
|
+concepts are involved : **_requests_**, **_responses_**, **_routing_** (nothing
|
|
|
+unusual for a web developer), **_middleware_** (a common sight in backend). The
|
|
|
+central concept is that of the **_resource_** which as its name implies
|
|
|
+designates the object one wishes to get, modify or create (just as in RESTful
|
|
|
+terminology) ; **_routes_** will be directly connected to them. Last but not
|
|
|
+least, **_hooks_** can be defined to factorize code related to a specific
|
|
|
+resource or request type.
|
|
|
+
|
|
|
+Worth noting is that almost everything is implemented through duck-typing ; for
|
|
|
+instance, a middleware class will not need to inherit from any specific object
|
|
|
+(unlike Django, with [everything it implies][django-cbv] in terms of methods and
|
|
|
+classes you'll need to know like the back of your hand). It should only
|
|
|
+implement some specific methods.
|
|
|
+
|
|
|
+**Fourth and final point** is that there's some work ahead ! I'll need to get to
|
|
|
+know all the main Python libraries in order to handle everything that what was
|
|
|
+included in Django ... But that's all the benefit of such a minimalist framework
|
|
|
+to be able to browse through the Python ecosystem and pick solutions that are
|
|
|
+usually much more advanced than those from the Django ecosystem. And they are
|
|
|
+still easy to integrate, in contrast to other little frameworks that often
|
|
|
+require an adaptation layer for those libraries. With Falcon you can choose
|
|
|
+whatever you want and integrate it whichever way you want.
|
|
|
+
|
|
|
+Which means, many other articles are on their way !
|
|
|
+
|
|
|
+[erasing-all]: {filename}/content/on-efface-tout.md
|
|
|
+[falcon-logo]: {filename}/images/falcon_logo.svg
|
|
|
+[falcon-install]: https://falcon.readthedocs.io/en/stable/user/install.html#install
|
|
|
+[httpie]: https://github.com/jkbr/httpie
|
|
|
+[falcon-examples]: https://falcon.readthedocs.io/en/stable/user/quickstart.html
|
|
|
+[falcon-tutorial]: https://falcon.readthedocs.io/en/stable/user/tutorial.html
|
|
|
+[falcon]: https://falconframework.org/
|
|
|
+[falcon-media]: https://falcon.readthedocs.io/en/stable/api/media.html#media
|
|
|
+[pycharm-falcon]: {filename}/images/pycharm-falcon.png
|
|
|
+[django-cbv]: https://ccbv.co.uk/
|
|
|
+[django]: https://www.djangoproject.com/
|
|
|
+[pycharm]: https://www.jetbrains.com/pycharm/download/
|
|
|
+[flask]: http://flask.pocoo.org/
|
|
|
+[bottle]: https://bottlepy.org/docs/dev/
|