COMP1531

4.2 - Web - HTTP & Flask

 

Computer Networks

Web

Internet

Network

The network

This is not a networking course:

 

  • Network: A group of interconnected computers that can communicate
  • Internet: A global infrastructure for networking computers around the entire world together
  • World Wide Web: A system of documents and resources linked together, accessible via URLs

Network Protocols

  • Communication over networks must have a certain "structure" so everyone can understand
  • Different "structures" (protocols) are used for different types of communication

Network Protocols

Examples?

HTTP

Request

Response

HTTP: Hypertext Transfer Protocol

I.E. Protocol for sending and receiving HTML documents (nowadays much more)

Web browsers are applications to request and receive HTTP

HTTP Request & Response

GET /hello HTTP/1.1
Host: 127.0.0.1:5000
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Sec-Fetch-Site: none
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 12
Server: Werkzeug/0.16.0 Python/3.5.3
Date: Wed, 09 Oct 2019 13:21:51 GMT

Hello world!

HTTP Request

HTTP Response

Flask

from flask import Flask
APP = Flask(__name__)

@APP.route("/")
def hello():
    return "Hello World!"

if __name__ == "__main__":
    APP.run()

Lightweight HTTP web server built in python

$ python3 flask1.py

flask1.py

Server an image

from flask import Flask, send_file
APP = Flask(__name__)

@APP.route("/img")
def img():
    return send_file('./cat.jpg', mimetype='image/jpg')

if __name__ == "__main__":
    APP.run()

Time to serve an image via a flask server...

$ python3 flask2.py

flask2.py

Flask Reloading

from flask import Flask
APP = Flask(__name__)

@APP.route("/")
def hello():
    return "Hello World!"

if __name__ == "__main__":
    APP.run()

Lightweight HTTP web server built in python

$ export FLASK_APP=flask1.py
$ export FLASK_DEBUG=1
$ export FLASK_RUN_PORT=0
$ python3 -m flask run

flask1.py

Learn More

Some tutorials include:

  1. https://pythonspot.com/flask-web-app-with-python/
  2. https://blog.miguelgrinberg.com/post/designing-a-restful-api-with-python-and-flask

 

When it comes to online tutorials, note that:

  • Each "tutorial" may be using different python versions
  • Each "tutorial" may have different aims in mind

API

An API (Application Programming Interface) refers to an interface exposed by a particular piece of software.

 

The most common usage of "API" is for Web APIs, which refer to a "contract" that a particular service provides. The interface of the service acts as a black box and indicates that for particular endpoints, and given particular input, the client can expect to receive particular output.

 

Web API

Load Webpage (standard request)

Page loaded

Get extra data

Receive extra data

Submit form data

Form submission confirmed

Browser

(Client)

Server

Restful API & "CRUD"

A RESTful API is an application program interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data. These 4 methods describe the "nature" of different API requests.

 

GET, PUT, POST, DELETE are HTTP Methods

Method Operation
POST Create
GET Read
PUT Update
DELETE Delete

Input & Output

Different CRUD properties require different approaches for input. All output are the same.

from flask import Flask, request
from json import dumps

APP = Flask(__name__)

@APP.route("/one", methods=['GET'])
def one():
    return dumps({
    	'1': request.args.get('data1'),
    	'2': request.args.get('data1'),
    })

@APP.route("/two", methods=['POST'])
def two():
    data = request.get_json()
    return dumps({
    	'1': data['data1'],
    	'2': data['data2'],
    })

if __name__ == '__main__':
    APP.run()

crud.py

Inputs are either:

  • GET: via URL and "request.args"
  • PUT|POST|DELETE: via post-data and via "request.get_json()"
  • All outputs should be packaged up as JSON
  • (JSON discussed later)

Using CRUD and state

Task:


Create a web server that uses CRUD to allow you to create, update, read, and delete a point via HTTP requests

 

Use a global variable to manage the state.

 

point.py

Talking to Flask

How can we talk to flask?

  1. API client
  2. Web Browser
  3. URLLib via python

API Client (ARC/Postman/Insomnia)

How to download/install postman:

  • Open google chrome
  • Google "ARC client"
  • Install the addon and open it
  • Follow the demo in the lectures

 

You may need to use a tool like this in the final exam.

API Client (A R C)

Web Browser

requests - Python

requests is a python3 library that allows you to programmatically make HTTP requests to a web server.

 

You will use this extensively in iteration 2.

requests - Python

import json
import requests

def get_payload():
    response = requests.get('http://127.0.0.1:5000/echo', params={'data': 'hi'})
    payload = response.json()
    print(payload)

if __name__ == '__main__':
    get_payload()
from flask import Flask, request
from json import dumps

APP = Flask(__name__)

@APP.route("/echo", methods=['GET'])
def echo():
    return dumps({'data': request.args.get('data')})

if __name__ == '__main__':
    APP.run()

echo.py

echo_main.py

We expect you to do your own research for POST

Web server as a wrapper

Because you've written so many integration tests for iteration 1, it makes sense to:

  1. Implement all of the functions from iteration one
  2. Then wrap them in a flask server

Web server as a wrapper

iter2example/search.py

def search(token, query_str):
    return {
        'messages' : [
            'Hello ' + token + ' ' + query_str,
            # Not the right structure
        ]
    }
from json import dumps
from flask import Flask, request

from search import search_fn

APP = Flask(__name__)

@APP.route('/search', methods=['GET'])
def search_flask():
    return dumps(search(requests.args.get('token'), request.args.get('query_str')))

if __name__ == '__main__':
    APP.run()

iter2example/server.py

(Bonus) interesting question

 

How do companies track whether or not you've read an email they've sent you?

 

COMP1531 21T1 - 4.2 - Web - Flask

By haydensmith

COMP1531 21T1 - 4.2 - Web - Flask

  • 932