import subprocess
import requestsREST 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:
- How to create a simple REST API,
- How to handle HTTP requests and manage errors in the API,
- How to test the API using pytest,
- How to deploy the application into a Docker container.
%%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 CODErun kill() method for p object
# YOUR CODECheck 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.contentadd variables for url adress ?name=....
response = requests.get("http://127.0.0.1:5005/hello?name=Sebastian")
response.contentTry 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.1Dockerfile
- 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