Lesson 10: Frameworks

Homepage Content Slides Video

Warning

This lesson is under construction. Learn from it at your own risk. If you have any feedback, please fill out our General Feedback Survey.

Frameworks

Frameworks are collections of classes, functions, and constants designed to make completing a task easier. Examples include:

  • Web frameworks
  • Game frameworks
  • GUI frameworks

Frameworks dictate a specific look to an application and limit the design choices a developer can make in favor of making the code easier to read and write.

The job of a framework

To take care of the boring stuff.

Frameworks are meant to make the life of a developer easier by supplying programmers with tools and design patterns to accomplish a task in an expressive and relatively simple way.

Frameworks simplify a program by implementing tedious parts of a to let the programmer focus on the “Big Picture” and “Application Specific Needs”.

Frameworks tend to exist for commonly developed types of applications to reduce the amount of time spent on repeated development steps like recieving HTTP requests or drawing sprites to a screen.

Why and When to use a Framework

Use a framework if you are making a cookie cutter application.

Applications which lend themselves to frameworks are those which have been developed many times over. Web applications are a good example: There are hundreds of thousands of web applications, if each one had to reinvent the wheel in how they dealt with web requests and rendered HTML pages, the industry as a whole would be wasting a lot of time.

If a framework exists for what you’re doing, consider using it.

Types of Frameworks

  • Testing Frameworks
  • Web-app Frameworks
  • Game Frameworks

Things to keep in mind when looking for a framework:

  • There are many frameworks in the world, some are better than others so do your research.

  • Just because a framework does what you want doesn’t mean there isn’t a better tool for the job.

  • Most popular languages have at least two or three frameworks for common applications (listed above), so figure out which those are and which one looks best. Good frameworks usually have:

    • Good documentation
    • Active developers
    • A helpful community

Web Frameworks

The Flask logo

We’re going to focus on web frameworks because they are easy to demonstrate and used everywhere.

Static vs Dynamic Sites

There are two types of websites: Static and Dynamic.

A static site delivers the same content to anybody visiting. Static sites can either be written in pure HTML/CSS/Javascript, or a static site generator can be used to write content in another markup language to be compiled to HTML

A dynamic site changes as the user or users interact with it. Social networks and search engines are good examples of dynamic sites. Web Frameworks are primarily used in dynamic sites and rarely in static sites.

Static Site
Rarely changes, looks the same for all visitors (Blog, News, Document)
Dynamic Site
Changes based on who you are and what you do. (Search Engine, Login)

Security will be discussed further in Lesson 13, but static websites should be used in place of dynamic ones whenever possible. Dynamic websites are vulnerable to a much wider variety of attacks than static websites are.

The Model-View-Controller Pattern

model view controller diagram

Most webapps consist of three components:

Model
The data represented in some way, usually a database.
View
What the user sees i.e. the webpage you look at.
Controller
The code that manipulates the data in the database.

Understanding the MVC architecture isn’t that important at the moment, but it is something to be aware of. Many popular web frameworks are built around the MVC pattern, so knowing how to use it to its advantages can be userful.

URL Routing

A core component in every web framework is URL routing. This is where you tell a framework what to do when a user performs an action on a specific URL.

In the below pseudocode, using DELETE on the '/accounts/<account_name>' endpoint causes the application to call the delete_account method. For the purposes of this lesson, you don’t need to worry too much about things like what the ‘@’ syntax at the beginning of the function does or what DELETE is. If you want to learn more about the Flask framework or HTTP, check out our Further Reading section.

@app.route('/accounts/<account_name>', methods=['DELETE'])
def delete_account(account_name):
    if authenticated() and authorized():
        database.remove_account(account_name)
        return 'Success', 200
    else
        return 'Failure', 401

Templating Engines (mad-libs!)

Templating engines are the “Views” part of the MVC architecture. They take a string, or file, with places for variables and stick the specific values in.

For instance, take this template file:

<!DOCTYPE HTML>
<html>

    <head>
        <title>Template Example</title>
    </head>

    <body>
        <p>Your lucky number today is {{ number }}!</p>
    </body>

</html>

This template uses the Jinja2 templating engine, which is the default engine for the Flask framework. To render the template, you could use the render_template function like so:

render_template("template.html", number=random.randint(0, 99))
Your lucky number today is 42!

If you viewed the resulting HTML file in a web browser, the body of the page would contain a random number between 0 and 100 that was generated in the Python code and inserted into the template.

With templating engines, you can do more sophisticated things than simple string replacement. For example:

...
<body>
{% for message in messages %}
    <p>{{ message }}</p>
{% endfor %}
</body>
...
messages = ["Welcome!", "Test Message", "Vim > Emacs"]

render_template("template2.html", messages=messages)

This template evaluates just like a regular Python for loop. Jinja2 will render each entry in messages in its own paragraph on the webpage.

Welcome!
Test Message
Vim > Emacs

There are many more such directives available. If you want to learn more in depth about Jinja2, check out its documentation.

HTTP

GET http://web.site/page.html HTTP/1.1

HTTP/1.1 200 OK
Content-Type: text/html
...
<!DOCTYPE HTML>
...

Even though web frameworks provide a very high level of abstraction, it’s vital to have at least a minimal understanding of HTTP, since HTTP (Hypertext Transfer Protocol) is the language of the World Wide Web. When you’re working inside a web framework, these are the most important concepts to understand:

HTTP Concepts
Resource A thing that exists and is accessible using HTTP
URI A string that is used to identify the location of a resource
Request Data that is sent by the client to the server, asking the server to perform some action
Method The part of the request specifying the action that the client wants the server to perform
Response The server’s response back to the client after processing the client’s request
Error Code The part of the response summarizing the server’s response to the request

HTTP Methods

HTTP methods are sent with requests, and they specify the action that the client wishes to take on the resource specified with the request URI. For example, a request to the server that used the GET method on a resource indicates that the client wants the server to respond with that resource. Then the client might send a PUT request to update that same resource or a DELETE request to delete it.

The most commonly used methods are GET, POST, PUT, and DELETE, but there are many others.

HTTP Methods
GET Retrieves a resource from the server
POST Create a new resource on the server
PUT Update a resource on the server
DELETE Delete a resource from the server
OPTIONS Get a list of methods that are allowed on a resource
PATCH Update (Patch) only one specific part of a resource

REST

REST (Representational State Transfer) is a web architecture that takes advantage of HTTP’s features by defining a set of rules for how servers handle client requests and format their responses. There are many of these rules, but the most important are:

  • Servers are stateless

In this context, the word “state” means “the way that the thing currently is”. If a server is stateless, then the way that it handles requests doesn’t change based on previous requests that have been made.

It can be a bit of a subtle distinction, since storing data and retreiving stored data is a common function that web apps perform. However, in that case, the web server isn’t the component that’s storing the data from the previous request. The web server stores and retrieves data by talking to a database, so the server retains its statelessness.

  • Resources are self-contained

A self-contained resource is a resource that can be fully parsed and updated by the client without requiring any external informtaion. For example, a resource might contain some metadata to inform the client that it’s encoded in JSON, or it might contain other URLs that the client can use to interact with the resource further.

  • HTTP methods have predictable side-effects

This one is fairly self-explanitory. GET requests don’t change anything on the server’s side, DELETE requests delete the requested resource, etc. The GET method is called nullipotent (no side effects), and the PUT and DELETE methods are called idempotent (no side effects if the request is repeated more than once).

TODO: Dynamic Website

Over the course of this exercise, you’re going to build upon the skeleton of a simple web app written using the Flask microframework. When it’s finished, our app will be a guestbook that stores data inside a SQLite database (More on databases in our Databases lesson) and allows people to both add themselves and view the guests that have already been added.

To get started, clone the Bootcamp-Exercises repository in the DevOps Bootcamp Github organization, and cd into the 2016-2017/frameworks directory. Follow the directions in README.md to set up and run the app. If you don’t have virtualenv installed already, you can install it from your distro’s package manager (It’s usually python-virtualenv). If everything goes smoothly, you should get output that looks something like this after python run.py:

(venv)$ python run.py
 * Running on http://0.0.0.0:8080/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger pin code: 861-918-611

You can now access the website in a web browser at http://localhost:8080.

Part One: Writing The Views

If you poke around the website as it is, you’ll quickly notice that things are broken. That’s because we haven’t added functionality to the website yet!

There are two views that we have to write: The view for adding guests (app/views/add_guest.py), and the view for looking at the guests that have already been added (app/views/view_guests.py). See the files for more information on how to complete this exercise. If you get stuck, you should consult the Flask documentation for help.

Part Two: Writing The Templates

Now that we’ve written the logic for each endpoint, it’s time to fill out the templates so that we can present our dynamic data to the user. It might be helpful to consult the Jinja2 documentation and the Flask-WTForms documentation here.

Just like before, there are two templates that we have to complete: The template for the add_guests view and the template for the view_guests view. The add_guests template is going to contain the form to add a guest (Hint: Use the HTML <form> tag), and the view_guests template is going to contain the list of guests in the database (Hint: Use the HTML <table> tag).

Further Reading

The Flask Microframework
Flask is a web framework that is simple enough for beginners to use but configurable enough to allow more advanced users to have full control over their application. It has a very active community and fantastic documentation.
Intro to HTTP and REST
HTTP is the protocol that web clients and web servers use to communicate with each other, and REST is a set of web design guidelines that is takes advantage of HTTP’s features and allows different applications to easily communicate with each other.