REST API with Flask

The goal of the lab is to introduce students to developing REST API applications in Python using the Flask library and containerizing them with Docker.

You will learn:

import subprocess
import requests
%%file app1.py

from flask import Flask

# Create a flask
app = Flask(__name__)

# Create an API end point
@app.route('/hello')
def say_hello():
    return "Hello World"

@app.route('/')
def say_he():
    return "Hello from main site"

if __name__ == '__main__':
    app.run()
p = subprocess.Popen(["python", "app1.py"])
adres_url = "http://127.0.0.1:5000/hello"
response = requests.get(adres_url)
# take content field from response object
# YOUR CODE
# take bad adress

adres_url = " "

response = requests.get(adres_url)

# Check if status_code field is 200
# YOUR CODE

run kill() method for p object

# YOUR CODE

Check any request and raspone whe your serwer is down

# YOUR CODE
response = ...

URL Adress with GET method for a sanding data

%%file app2.py

from flask import Flask
from flask import request

# Create a flask
app = Flask(__name__)

# Create an API end point
@app.route('/hello', methods=['GET'])
def say_hello():
    name = request.args.get("name", "") # tutaj leci str
    title = request.args.get("title", "")
    if name:
        resp = f"Hello {title} {name}" if title else f"Hello {name}"
    else:
        resp = f"Hello {title}" if title else "Hello"
    return resp

if __name__ == '__main__':
    app.run(port=5005)
p = subprocess.Popen(["python", "app2.py"])
response = requests.get("http://127.0.0.1:5005/hello")
response.content

add variables for url adress ?name=....

response = requests.get("http://127.0.0.1:5005/hello?name=Sebastian")
response.content

Try json answear

from flask import jsonify

def moja_f():
    ...
    return jsonify(reponse=resp)

An interesting and more functional solution for ML models is the [litServe](https://lightning.ai/litserve) library.

Notice the pipeline, which is written in a functional style.

::: {#389512cc-55fe-43e6-b0d5-a627e60399a7 .cell execution_count=4}
``` {.python .cell-code}
%%file app_lit.py
import litserve as ls

class SimpleLitAPI(ls.LitAPI):
    def setup(self, device):
        self.model1 = lambda x: x**2
        self.model2 = lambda x: x**3

    def decode_request(self, request):
        return request["input"]

    def predict(self, x):
        squared = self.model1(x)
        cubed = self.model2(x)
        output = squared + cubed
        return {"output": output}

    def encode_response(self, output):
        return {"output": output}

if __name__ == "__main__":
    api = SimpleLitAPI()
    server = ls.LitServer(api)
    server.run(port=5001)
Overwriting app_lit.py

:::

import subprocess

p = subprocess.Popen(["python", "app_lit.py"])
import requests

response = requests.post("http://127.0.0.1:5001/predict", json={"input": 4.0})
print(f"Status: {response.status_code}\nResponse:\n {response.text}")
Status: 200
Response:
 {"output":{"output":80.0}}
p.kill()

Docker container

Plik aplikacji app.py

%%file app.py

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    return "<h1>hello world</h1>"

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

plik requirements.txt w którym zamieścimy potrzebne biblioteki

%%file requirements.txt
Flask==3.0.1

Dockerfile

  • pobranie obrazu systemu z pythonem
  • kopia pliku z wymaganymi bibliotekami
  • instalacja wymaganych bibliotek w środowisku
  • skopiowanie pliku aplikacji
  • uruchomienie aplikacji
%%file Dockerfile
FROM python:3.11-slim-buster

WORKDIR /app

COPY requirements.txt requirements.txt

RUN pip install -r requirements.txt

COPY app.py .

ENV FLASK_APP=app

EXPOSE 5000
CMD ["flask", "run", "--host", "0.0.0.0", "--port", "5000"]
docker build -t test_hello .

docker run -p 5000:5000 test_hello