Zbudowanie webowego API w języku Python z wykorzystaniem Flask API nie jest skomplikowane. W poniższym poście przedstawię podstawowe przykłady użycia framework’a, a także proste sposoby jego przetestowania. Gotowe API można uruchomić np. na UWSGI, o czym pisałem miesiąc temu.
Import modułów
Szkielet przykładowej aplikacji jest prosty i składa się z importu modułów oraz uruchomienia programu:
from flask import Flask
from flask import request
from flask import render_template
from flask import abort, redirect, url_for,
make_response
# ...
app = Flask(__name__)
Flask
jest głównym modułem framework’a, request
umożliwia dostęp do żądania otrzymanego przez serwer, render_template
pozwala wykorzystywać szablony w plikach HTML, abort
, redirect
, url_for
oraz make_response
są użytecznymi modułami do obsługi błędów, przekierowania oraz modyfikowania nagłówka odpowiedzi HTTP.
Obsługa żądań HTTP GET
Najprostszy kod obsługujący żądania HTTP GET składa się z 3 elementów – dekoratora route
defniującego URL, pod którym dostępny jest serwis, nazwy funkcji oraz jej logiki (w tym przypadku zwrócenie ciągu znaków):
@app.route('/')
def index():
return 'HTTP GET index Page'
Obsługa żądań HTTP POST
Poniższy przykład jest bardziej skomplikowany, ponieważ został rozbudowany o:
- parametry przekazywane w URL,
- określenie typów żądań HTTP, które są obsługiwane (GET, POST),
- odczyt danych przekazanych jako parametry URL oraz dane z formularza.
@app.route('/user/<username>', methods=['GET', 'POST'])
def show_user_profile(username):
if request.method == 'POST':
return 'HTTP POST for user %s with password %s' % (username, request.form['password'])
else:
return 'HTTP GET for user %s' % username
Wykorzystanie szablonów stron HTML
W przypadku bardziej rozbudowanych odpowiedzi warto skorzystać z szablonów, do których możemy przekazać parametry jak w przykładzie poniżej:
@app.route('/template/<name>')
def template(name=None):
return render_template('template.html', name=name)
Obsługa błędów
Kody błędów zwracane przez API można w prosty sposób generować przez funkcję abort()
, wykorzystać szablony, czy też dodatkowo modyfikować dane w nagłówku HTTP:
@app.route('/error_denied')
def error_denied():
abort(401)
@app.route('/error_internal')
def error_internal():
return render_template('template.html', name='ERROR 505'), 505
@app.route('/error_not_found')
def error_not_found():
response = make_response(render_template('template.html', name='ERROR 404'), 404)
response.headers['X-Something'] = 'A value'
return response
Testowanie API
Najprostrzym sposobem przetestowania API jest jego uruchomienie za pomocą poleceń:
export FLASK_APP=example.py
export FLASK_DEBUG=1
flask run
a następnie wygenerowanie żądań za pomocą curl
:
curl http://127.0.0.1:5000/
curl http://127.0.0.1:5000/user/seba
curl -X POST http://127.0.0.1:5000/user/seba -d "password=secret"
curl http://127.0.0.1:5000/template/test
curl http://127.0.0.1:5000/error_denied
curl http://127.0.0.1:5000/error_internal
curl http://127.0.0.1:5000/error_not_found