Python: Creazione di un'API REST

Come creare un'API REST usando Flask

👋 Benvenuti nella documentazione di Stackhero!

Stackhero offre una soluzione cloud Python pronta all'uso che fornisce numerosi vantaggi, tra cui:

  • Distribuisci la tua applicazione in pochi secondi con un semplice git push.
  • Usa il tuo nome di dominio e beneficia della configurazione automatica dei certificati HTTPS per una sicurezza migliorata.
  • Goditi la tranquillità con backup automatici, aggiornamenti con un clic, e una tariffazione semplice, trasparente e prevedibile.
  • Ottieni prestazioni ottimali e una sicurezza robusta grazie a una VM privata e dedicata.

Risparmia tempo e semplificati la vita: ci vogliono solo 5 minuti per provare la soluzione di hosting cloud Python di Stackhero!

Questa documentazione è una guida amichevole per principianti sulla creazione di un'API REST in Python.

In questo esempio, utilizziamo Flask, un micro-framework leggero e facile da usare che consente di creare rapidamente applicazioni web.

Prima di iniziare, assicurati che il tuo computer sia dotato dei seguenti strumenti:

  1. Python
  2. pip
  3. git
  4. asdf

Se il tuo ambiente di sviluppo non è ancora configurato, consulta la guida Development platform per istruzioni dettagliate. In alternativa, puoi utilizzare la piattaforma online Code-Hero. Code-Hero fornisce un IDE e un terminale online, con tutti gli strumenti essenziali preinstallati, permettendoti di iniziare a programmare immediatamente senza alcuna installazione.

API REST Python in esecuzione su Code-Hero, accessibile direttamente dal browserAPI REST Python in esecuzione su Code-Hero, accessibile direttamente dal browser

Il primo passo è creare una nuova directory di progetto. Per questa guida, la chiameremo myRestApi:

mkdir myRestApi
cd myRestApi

Successivamente, imposta la versione di Python all'ultima disponibile usando asdf e inizializza il repository Git:

asdf install python latest \
  && asdf local python latest

echo "__pycache__/" >> .gitignore

git init
git add -A .
git commit -m "First commit"

Per questo esempio, abbiamo bisogno di una sola dipendenza: Flask.

Flask è un framework web leggero che consente uno sviluppo rapido delle applicazioni web. È progettato per essere semplice e facile da usare, permettendo agli sviluppatori di creare e distribuire servizi web rapidamente. Il supporto integrato per il routing, il templating e la gestione delle richieste HTTP rende Flask una scelta eccellente per creare API REST.

Installa Flask (e python-dotenv) usando pip:

pip install Flask python-dotenv

Stiamo installando i moduli Flask e python-dotenv. Presto vedrai perché usiamo python-dotenv (spoiler: è per gestire le variabili d'ambiente).

Dopo l'installazione, congela le versioni dei pacchetti in un file requirements.txt:

pip freeze > requirements.txt

Congelare le tue dipendenze garantisce che il tuo server di produzione o i tuoi colleghi utilizzino le stesse versioni che usi tu. Pochi secondi di lavoro possono prevenire molti mal di testa futuri.

Ora, passiamo al codice!

Crea un file chiamato app.py e inserisci il seguente codice:

import os
from dotenv import load_dotenv
from flask import Flask, jsonify, request

# Carica le variabili d'ambiente dal file .env quando non siamo in produzione
if os.environ.get('ENV') != 'production':
    load_dotenv()

# Crea l'app Flask
app = Flask(__name__)

# Set di dati di esempio
tasks = [
    {
        'id': 1,
        'title': 'Comprare generi alimentari',
        'description': 'Latte, Formaggio, Pizza, Frutta',
        'done': False
    },
    {
        'id': 2,
        'title': 'Imparare Python',
        'description': 'Imparare le basi della programmazione Python',
        'done': False
    }
]

# Route '/api/tasks' (GET) per elencare tutte le attività
@app.route('/api/tasks', methods=['GET'])
def get_tasks():
    return jsonify({'tasks': tasks})

# Route '/api/tasks/<task_id>' (GET) per ottenere un'attività specifica tramite ID
@app.route('/api/tasks/<int:task_id>', methods=['GET'])
def get_task(task_id):
    task = [task for task in tasks if task['id'] == task_id]
    if len(task) == 0:
        return jsonify({'error': 'Attività non trovata'}), 404
    return jsonify({'task': task[0]})

# Route '/api/tasks' (POST) per creare una nuova attività
@app.route('/api/tasks', methods=['POST'])
def create_task():
    if not request.json or 'title' not in request.json:
        return jsonify({'error': 'Il titolo è richiesto'}), 400
    task = {
        'id': tasks[-1]['id'] + 1,
        'title': request.json['title'],
        'description': request.json.get('description', ""),
        'done': False
    }
    tasks.append(task)
    return jsonify({'task': task}), 201

# Avvia il server API
if __name__ == '__main__':
    if os.environ.get('ENV') == 'production':
        app.run()
    else:
        app.run(host='0.0.0.0', port=8080, debug=True)

Per avviare il server, esegui:

python app.py

Con l'opzione host='0.0.0.0', puoi anche accedere alla tua API utilizzando il browser quando usi Code-Hero. Basta navigare su http://<XXXXXX>.stackhero-network.com:8080/api/tasks, sostituendo <XXXXXX> con il tuo dominio Code-Hero.

Una volta che il server è in esecuzione, puoi interagire con esso usando cURL. Ecco alcuni esempi:

  • Recupera tutte le attività:

    curl -s http://localhost:8080/api/tasks
    {
      "tasks": [
        {
          "description": "Latte, Formaggio, Pizza, Frutta",
          "done": false,
          "id": 1,
          "title": "Comprare generi alimentari"
        },
        {
          "description": "Imparare le basi della programmazione Python",
          "done": false,
          "id": 2,
          "title": "Imparare Python"
        }
      ]
    }
    
  • Recupera l'attività con ID 2:

    curl -s http://localhost:8080/api/tasks/2
    {
      "task": {
        "description": "Imparare le basi della programmazione Python",
        "done": false,
        "id": 2,
        "title": "Imparare Python"
      }
    }
    
  • Crea una nuova attività:

    curl -s -X POST -H "Content-Type: application/json" \
    -d '{"title": "Nuova attività", "description": "Creata con cURL"}' \
    http://localhost:8080/api/tasks
    {
      "task": {
        "description": "Creata con cURL",
        "done": false,
        "id": 3,
        "title": "Nuova attività"
      }
    }
    

Suggerimento: Invia l'output a jq per abbellire il JSON. Ad esempio, curl -s http://localhost:8080/api/tasks/2 | jq produce un risultato più leggibile.

Esempio di API REST Python usando Flask, in esecuzione su Stackhero Code-Hero, con il server (1) e il client usando cURL (2)Esempio di API REST Python usando Flask, in esecuzione su Stackhero Code-Hero, con il server (1) e il client usando cURL (2)

Le variabili d'ambiente sono vitali per proteggere informazioni sensibili, come le credenziali del database o le chiavi API. Ci sono due principali vantaggi nell'usare le variabili d'ambiente:

  1. I tuoi segreti non sono memorizzati nel tuo repository Git, garantendo che persone non autorizzate non possano accedere ai tuoi dati sensibili anche se accedono al tuo codice sorgente.
  2. Puoi usare credenziali diverse per ambienti diversi (ad esempio, produzione contro sviluppo).

Per gestire le variabili d'ambiente, utilizziamo il modulo python-dotenv. Prima di tutto, installalo se non l'hai già fatto:

pip install python-dotenv
pip freeze > requirements.txt

Successivamente, crea un file .env alla radice del tuo progetto e aggiungi le tue variabili d'ambiente di sviluppo. Ad esempio:

ENV="development"
DATABASE_PASSWORD="secretPassword"
THIRD_API_PRIVATE_KEY="secretKey"

Infine, aggiungi il file .env al tuo .gitignore per mantenere la sicurezza:

echo ".env" >> .gitignore

Per accedere a queste variabili d'ambiente in Python, usa semplicemente os.environ.get():

import os

print(os.environ.get('ENV'))

Il file .env è usato solo per l'ambiente di sviluppo. Per staging o produzione, imposta le variabili d'ambiente sulla dashboard di Stackhero nella configurazione del tuo servizio Python.

Sebbene questa guida utilizzi il server di sviluppo integrato di Flask, per la produzione è essenziale utilizzare un server WSGI pronto per la produzione come Gunicorn. Segui questi passaggi:

  1. Installa Gunicorn:

    pip install gunicorn
    pip freeze > requirements.txt
    
  2. Avvia la tua app usando Gunicorn con l'argomento app:app (dove il primo app è il nome del file e il secondo app è l'istanza Flask):

    ENV=production gunicorn app:app \
      --error-logfile - \
      -b 0.0.0.0:8080
    
  3. Crea un Makefile per semplificare il passaggio tra modalità sviluppo e produzione:

    .DEFAULT_GOAL := dev
    
    # Di default, Stackhero per Python esegue la regola "run". La sovrascriviamo per eseguire la regola 'prod'.
    run: prod
    
    prod:
     	ENV=production gunicorn app:app \
     	  --error-logfile - \
     	  -b 0.0.0.0:8080
    
    dev:
     	python app.py
    

Puoi eseguire il tuo server in modalità sviluppo usando make dev (o semplicemente make), e in modalità produzione usando make prod.

Il modo più semplice per distribuire il tuo progetto Python è utilizzare il servizio di hosting cloud Python di Stackhero. Le caratteristiche principali includono:

  • Deployment con un semplice git push
  • Dominio personalizzabile con gestione automatica dei certificati TLS (HTTPS)
  • Funziona su una VM privata e dedicata per la massima sicurezza
  • Supporta HTTP/2, TLS 1.3 (HTTPS), WebSockets, compressione GZIP & Brotli, ETag, e accesso alle porte TCP/UDP

Per distribuire il tuo codice su Stackhero, segui questi passaggi:

  1. Recupera la tua chiave pubblica usando:

    cat ~/.ssh/id_*.pub
    
  2. Nella dashboard di Stackhero, vai al tuo servizio "Stackhero for Python" e clicca sul pulsante "Configura".

  3. Copia la chiave pubblica dal primo passaggio e incollala nel campo "SSH public keys" o "Key".

  4. Valida la configurazione cliccando sul pulsante "Valida" in fondo alla pagina.

Configurazione della chiave pubblica "Stackhero for Python"Configurazione della chiave pubblica "Stackhero for Python"

Non hai chiavi SSH? Creale eseguendo:

ssh-keygen -t ed25519

Infine, configura il tuo repository per distribuire su Stackhero. Nella tua cartella di progetto, aggiungi un remote Git usando il comando fornito nel tuo servizio Stackhero (sostituisci <XXXXXX> con il dominio del tuo servizio):

git remote add stackhero ssh://stackhero@<XXXXXX>.stackhero-network.com:222/project.git

Comando Git remoteComando Git remote

Una volta che tutto è configurato, distribuisci il tuo codice in produzione con un solo comando:

git push stackhero main

Assicurati di aggiungere e confermare le tue modifiche prima di inviare il tuo codice in produzione. In Stackhero Code-Hero, puoi rapidamente confermare le modifiche usando la Command Palette (premi Ctrl+Shift+P su Windows/Linux o Cmd+Shift+P su macOS e digita Git: Commit).

Dopo il deployment, visita il tuo URL API su https://<XXXXXX>.stackhero-network.com/api/tasks (sostituisci <XXXXXX> con il dominio del tuo servizio) per vedere la tua API Flask in azione.

Seguendo questa guida, ora comprendi come creare un'API REST usando Flask. Con queste conoscenze, puoi sviluppare ed espandere le tue applicazioni RESTful con fiducia, integrandole con vari servizi front-end e back-end.