Python: Creazione di una REST API

Guida passo-passo per costruire una REST API con Flask in Python

👋 Benvenuto nella documentazione di Stackhero!

Stackhero offre una soluzione Python cloud pronta all'uso, progettata per semplificare il processo di deployment:

  • Distribuisci la tua applicazione in produzione in pochi secondi con un semplice git push.
  • Utilizza il tuo nome di dominio, con configurazione automatica del certificato HTTPS per connessioni sicure gestite direttamente da noi.
  • Affidati a backup automatici, aggiornamenti con un clic e prezzi prevedibili, così puoi concentrarti sul tuo codice invece che sulla gestione dell'infrastruttura.
  • Approfitta di elevate prestazioni e sicurezza su un'infrastruttura privata e dedicata. Il tuo ambiente è isolato e protetto.

Risparmia tempo e semplifica il tuo workflow: il tuo codice può essere operativo con il Python cloud hosting di Stackhero in soli 5 minuti.

Questa guida mostra come creare una semplice REST API utilizzando Python e Flask. Flask è un micro-framework leggero che consente di sviluppare rapidamente applicazioni web e API.

Prima di iniziare, assicuratevi di avere installato i seguenti strumenti:

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

Se avete bisogno di assistenza nella configurazione dell'ambiente, consultate la guida Development platform. In alternativa, potete iniziare subito a programmare con la piattaforma online Code-Hero. Code-Hero offre un IDE e un terminale online, con tutti gli strumenti essenziali già preinstallati. Questo vi permette di concentrarvi sul codice invece che sull'installazione e la configurazione.

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

Iniziate creando una nuova directory di progetto. In questo esempio, il progetto si chiama myRestApi:

mkdir myRestApi
cd myRestApi

Impostate la versione di Python all'ultima disponibile con asdf e inizializzate un 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 serve una sola dipendenza principale: Flask.

Flask è progettato per essere semplice e veloce, così potete creare e distribuire API web senza overhead aggiuntivo. Include il supporto integrato per routing, template e gestione delle richieste HTTP, permettendovi di passare dall'idea a una API funzionante in pochi minuti.

Potete installare Flask e python-dotenv tramite pip:

pip install Flask python-dotenv

Includiamo python-dotenv per gestire le variabili d'ambiente in modo sicuro e pratico. Vedrete come utilizzarlo nei passaggi successivi.

Dopo l'installazione, bloccate le dipendenze in un file requirements.txt:

pip freeze > requirements.txt

Bloccare le dipendenze garantisce che tutti utilizzino le stesse versioni dei pacchetti. Questo piccolo accorgimento può farvi risparmiare ore di troubleshooting in futuro.

Ora siete pronti a scrivere il codice della vostra API.

Create un file chiamato app.py e aggiungete questo codice:

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

# Carica le variabili d'ambiente da .env per ambienti non di produzione
if os.environ.get('ENV') != 'production':
    load_dotenv()

app = Flask(__name__)

# Esempio di dati tasks
tasks = [
    {
        'id': 1,
        'title': 'Buy groceries',
        'description': 'Milk, Cheese, Pizza, Fruits',
        'done': False
    },
    {
        'id': 2,
        'title': 'Learn Python',
        'description': 'Learn Python programming basics',
        'done': False
    }
]

@app.route('/api/tasks', methods=['GET'])
def get_tasks():
    return jsonify({'tasks': tasks})

@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 not task:
        return jsonify({'error': 'Task not found'}), 404
    return jsonify({'task': task[0]})

@app.route('/api/tasks', methods=['POST'])
def create_task():
    if not request.json or 'title' not in request.json:
        return jsonify({'error': 'Title is required'}), 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

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

Potete avviare il server con:

python app.py

Con host='0.0.0.0', la vostra API è accessibile dal browser quando utilizzate Code-Hero. Visitate http://<XXXXXX>.stackhero-network.com:8080/api/tasks, sostituendo <XXXXXX> con il vostro dominio Code-Hero.

Una volta che il server è in esecuzione, potete interagire con la vostra API usando cURL. Ecco alcuni comandi di esempio:

  • Recuperare tutte le tasks:

    curl -s http://localhost:8080/api/tasks
    # Output:
    # {
    #   "tasks": [
    #     ...
    #   ]
    # }
    
  • Recuperare una task specifica (ID 2):

    curl -s http://localhost:8080/api/tasks/2
    # Output:
    # {
    #   "task": {
    #     ...
    #   }
    # }
    
  • Creare una nuova task:

    curl -s -X POST -H "Content-Type: application/json" \
    -d '{"title": "New task", "description": "Created with cURL"}' \
    http://localhost:8080/api/tasks
    # Output:
    # {
    #   "task": {
    #     ...
    #   }
    # }
    

Suggerimento: Per un output più leggibile, potete passare il risultato a jq. Ad esempio, curl -s http://localhost:8080/api/tasks/2 | jq rende il JSON più facile da leggere.

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

Le variabili d'ambiente aiutano a proteggere segreti come credenziali di database o chiavi API. Il loro utilizzo mantiene i dati sensibili fuori dal codice sorgente e dalla cronologia Git, e facilita la gestione di impostazioni diverse per ogni ambiente.

Per gestire le variabili d'ambiente, potete utilizzare il modulo python-dotenv. Se avete saltato il passaggio di installazione precedente, potete installarlo ora:

pip install python-dotenv
pip freeze > requirements.txt

Create un file .env nella root del progetto e aggiungete le variabili d'ambiente di sviluppo:

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

Aggiungete .env al vostro .gitignore per evitare che venga inserito in Git:

echo ".env" >> .gitignore

Potete accedere a queste variabili in Python tramite os.environ.get():

import os

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

Il file .env è solo per lo sviluppo. In produzione o staging, potete impostare le variabili d'ambiente direttamente dalla dashboard Stackhero, nella configurazione del vostro servizio Python.

Il server integrato di Flask è ottimo per lo sviluppo. In produzione, è consigliabile utilizzare un server WSGI robusto come Gunicorn. Ecco come potete prepararvi:

  1. Installate Gunicorn:

    pip install gunicorn
    pip freeze > requirements.txt
    
  2. Avviate la vostra app con Gunicorn:

    ENV=production gunicorn app:app \
      --error-logfile - \
      -b 0.0.0.0:8080
    

    Qui, app:app fa riferimento al vostro file (app.py) e all'istanza dell'applicazione Flask (app).

  3. Potete aggiungere un Makefile per passare facilmente dalla modalità sviluppo a quella produzione:

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

Potete avviare il server in modalità sviluppo con make dev (o semplicemente make), oppure in modalità produzione con make prod.

Stackhero rende il deployment cloud semplice e sicuro. Potete distribuire il vostro progetto Python tramite il servizio Python cloud hosting. Le funzionalità includono:

  • Deployment con un semplice git push
  • TLS (HTTPS) automatico con domini personalizzabili
  • Infrastruttura dedicata per la sicurezza
  • Supporto per HTTP/2, TLS 1.3, WebSockets, GZIP & Brotli, ETag e accesso sia a porte TCP che UDP

Per effettuare il deployment, seguite questi passaggi:

  1. Recuperate la vostra chiave pubblica SSH:

    cat ~/.ssh/id_*.pub
    
  2. Nella dashboard Stackhero, aprite il servizio "Stackhero for Python" e selezionate "Configure".

  3. Incollate la vostra chiave pubblica nel campo "SSH public keys" o "Key".

  4. Fate clic su "Validate" per confermare la configurazione.

Configurazione chiave pubblica per "Stackhero for Python"Configurazione chiave pubblica per "Stackhero for Python"

Se non avete ancora chiavi SSH, potete generarle con:

ssh-keygen -t ed25519

Aggiungete un remote Git al vostro progetto utilizzando il comando fornito dal servizio Stackhero (sostituite <XXXXXX> con il dominio del vostro servizio):

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

Comando Git remoteComando Git remote

Quando siete pronti a distribuire, inviate il codice con:

git push stackhero main

Ricordatevi di effettuare il commit delle modifiche prima del deployment. In Stackhero Code-Hero, potete usare la Command Palette (Ctrl+Shift+P o Cmd+Shift+P) e digitare Git: Commit per commit rapidi.

Dopo il deployment, la vostra API sarà disponibile all'indirizzo https://<XXXXXX>.stackhero-network.com/api/tasks. Sostituite <XXXXXX> con il dominio del vostro servizio per accedere alla vostra API Flask.

Ora disponete di una REST API funzionante realizzata con Flask. Con questa base, è semplice espandere l'applicazione, collegarla a database o integrarla con altri servizi. Flask vi offre la flessibilità per passare da un semplice prototipo a una API di produzione completa.