Skip to main content

Twisted Klein: Basics

Basics: Routes, Methods, Variables


This section contains many similarities with Flask.  So if you know how to perform basic Flask-style routing, this section can be skipped.  Just keep in mind that a request parameter must be passed in all route functions.  Example::

      app.route('/')
   def example(
request):
       #...


Web frameworks have come a long way, especially in Python.  A major contributing factor is the dead simple routing syntax from Flask, Bottle, Hug, etc.  Klein shares syntactical similarities with those frameworks for the most part.  The only key difference is the request parameter that gets passed into the functions after specifying the route.  However we won't worry about that for now.  Let’s dive into Klein with a simple Hello World application.

Routes *aka* Hello World


helloworld.py



from klein import Klein

app = Klein()

@app.route('/')
def root(request):
    return 'Welcome'

@app.route('/hello')
def hello(request):
    return 'Hello World' 

app.run(host='localhost', port=9000)

To start the Klein application, simply execute the Python script:
python helloworld.py
The app.run() function will create a web server listening on the localhost interface on port 9000.  Change the host and ports according to your requirements.  app.route() creates the endpoints for your application, so in our snippet, there's the default route and a route for /hello.  A quick test can be done in a web browser by navigating to http://localhost:9000 or by using the curl utility:
curl localhost:9000
curl localhost:9000/hello

Return Types


Klein accepts bytes, ASCII encoded string, Twisted Resource, Twisted Renderable, or Deferred objects as return types.  Ensure the route functions only return one of these types.

HTTP Methods


The HTTP methods GET, POST, PUT, DELETE are common amongst web applications.  In Klein, routes can be explicitly tied to HTTP methods by passing in a list of the methods names via a parameter aptly called methods.  If no explicit method is specified, then all methods will be accepted.


import json
from klein import Klein

app = Klein()
@app.route('/')
def root(request):
    return 'Welcome'

@app.route('/methods', methods=['POST', 'delete'])
def specificMethods(request):
    return json.dumps({
        'boolean': True,
        'int': 1,
        'list': [1,2,3]
    })

The /methods endpoint will output JSON data if and only if the endpoint is accessed using the POST or DELETE methods (note that methods are not case sensitive).  Where as the "/" route can be accessed by any method since no explicit methods are specified.
curl -X POST localhost:9000/methods
curl -X DELETE localhost:9000/methods
curl -X POST localhost:9000

# this will fail
curl -X GET localhost:9000/methods
Speaking of “any method”, custom methods can also be used.  For instance, let’s say your application requires a method called “GOOGLE”.  All that needs to be done is to add “GOOGLE” to the list of methods then check using curl -X GOOGLE.


@app.route('/methods', methods=['POST', 'delete', 'GOOGLE'])

Variables

Variables works by simply appending a variable name surrounded by angle brackets to the URL string.  Variables allow for your app to take in any string parameter and use it in the function corresponding to the route.  As an example, the following will display a message followed by a name passed in from the URL:


@app.route('/hello/<name>')
def helloName(request, name):
    return 'Hello %s!' % name

Optionally, a type specifier can be supplied so that the string variable will be cast to a specified type.  This allows variables to be validated without extraneous code.  Out of the box, the specifiers are int, float, and path.


@app.route('/hello/<name>/<int:age>')
def helloNameAge(request, name, age):
    if age <= 1:
        return '%s is just starting life.' % name
    elif age >= 2 and age <= 29:
        return 'Name: %s. Age: %d. So young!' % (name, age)
    return 'Name: %s. Age: %d! So old!' % (name, age)

Final Example


import json
from klein import Klein

app = Klein()

@app.route('/')
def root(request):
    return 'Welcome'

@app.route('/hello')
def hello(request):
    return 'Hello World'

@app.route('/hello/<name>')
def helloName(request, name):
    return 'Hello %s!' % name

@app.route('/hello/<name>/<int:age>')
def helloNameAge(request, name, age):
    if age <= 1:
        return '%s is just starting life.' % name
    elif age >= 2 and age <= 29:
        return '%s is %d years old. You are so young!' % (name, age)
    return '%s is %d years old! You are so old!' % (name, age)

@app.route('/methods', methods=['POST', 'delete', 'Google'])
def specificMethods(request):
    return json.dumps({
                      'boolean': True,
                      'int': 1,
                      'list': [1,2,3]
                    })

Comments

Popular posts from this blog

Twisted Klein: Non-Blocking Recipes

Non-Blocking Recipes Do you like expressjs , but don’t want to switch to Node.js? Want non-blocking execution in Python? Then look no further! Asynchronous execution is the very essence of what makes Klein a contender in todays web framework landscape. It’s also the most difficult concept to grasp since most Pythonistas are not accustomed to asynchronous programming. Hopefully with the addition asyncio to Python’s standard library, this will change. Klein is built atop Twisted and developers can expose Deferred objects for asynchronous behavior. A very brief overview will be given on Twisted Deferred , afterwards aspiring developers are encouraged to read the Twisted documents on the subject (provided in the links near the bottom). Deferred Overview To demonstrate how Deferred objects work, we will create a chain of callback functions that execute after a result is available. Don’t worry if this confuses you right now, the code will clear things up. from __future_

Simple self signed TLS server and client using Twisted

Self signed TLS server and client using Twisted Prerequisites openssl twisted & pyOpenSSL modules- pip install twisted[tls] treq module - pip install treq Basic knowledge of Twisted TCP servers/clients Generate self signed certificate Generate the server's private key using a secret, which is SuperSecretPassword in this case. openssl genrsa -aes256 -passout pass:SuperSecretPassword -out server.key 2048 Perform a CSR (certificate signing request). Ensure the FQDN (fully qualified domain name) matches the hostname of the server, otherwise the server won't be properly validated. openssl req -new -key server.key -passin pass:SuperSecretPassword -out server.csr # Common Name (e.g. server FQDN or YOUR name) []:localhost openssl x509 -req -passin pass:SuperSecretPassword -days 1024 -in server.csr -signkey server.key -out server.crt For development purposes, remove the password from the certificate. openssl rsa -in server.key -out server_no_pass.key -passin pas

Python alias commands that play nice with virtualenv

There are plenty of predefined Python executables, symlinks, and aliases that come bundled with your operating system. These commands come in very handy because it saves you from typing out long commands or chain of scripts. However the downfall of operating system aliases is that they don’t always play nice with virtualenv (or venv if you’re on Python 3). Most predefined aliases use the system’s default Python as the interpreter, which is next to useless when your application runs in a virtual environment. Over the years, I’ve come up with my own Python aliases that play nice with virtual environments. For this post, I tried to stay as generic as possible such that any alias here can be used by every Pythonista. In other words, there will be no aliases for specific frameworks such as running a Django server or starting a Scrappy spider. The following is one of my bash scripts I source: .py-aliases #----- Pip -----# alias pip-list="pip freeze | less" alias pip-search