Sviluppo di applicazioni serverless con Python: guida completa

Sviluppo di applicazioni serverless con Python: guida completa

Le applicazioni serverless stanno rapidamente guadagnando popolarità nel mondo dello sviluppo software, soprattutto grazie alla loro capacità di ridurre i costi di gestione e migliorare la scalabilità. In un'architettura serverless, lo sviluppatore non deve preoccuparsi della gestione dei server o dell'infrastruttura: tutto è gestito dal provider del cloud, che scala automaticamente l'applicazione in base alla domanda. Python, con la sua semplicità e versatilità, è una scelta eccellente per lo sviluppo di applicazioni serverless, specialmente in ambienti cloud come AWS Lambda, Google Cloud Functions e Azure Functions.

In questo articolo vedremo come Python può essere utilizzato per creare applicazioni serverless in ambienti cloud, con un focus su AWS Lambda. Esamineremo i principali concetti di serverless, i vantaggi di questa architettura e forniremo esempi pratici di come sviluppare, distribuire e scalare applicazioni serverless utilizzando Python.


1. Cos'è un'architettura serverless?

L'architettura serverless si riferisce a un modello di sviluppo applicativo in cui le applicazioni sono eseguite senza la necessità di gestire server fisici o virtuali. Invece di configurare e mantenere server, gli sviluppatori scrivono codice che viene eseguito in risposta a eventi, come chiamate API o modifiche nel database. L'infrastruttura sottostante è completamente gestita dal provider del cloud, che si occupa dell'allocazione delle risorse, della scalabilità e della gestione delle patch di sicurezza.

Vantaggi delle applicazioni serverless

L'approccio serverless offre una serie di vantaggi significativi rispetto alle architetture tradizionali:

  • Zero gestione dei server: non c'è bisogno di gestire, configurare o aggiornare server. Il cloud provider si occupa di tutto ciò.
  • Scalabilità automatica: le applicazioni serverless scalano automaticamente in risposta alla domanda. Non è necessario configurare manualmente i server o gestire l'auto-scaling.
  • Riduzione dei costi: si paga solo per il tempo di esecuzione del codice. Se un'applicazione non viene utilizzata, non ci sono costi di infrastruttura. Ciò rende le architetture serverless particolarmente vantaggiose in termini di costi, soprattutto per applicazioni con carichi variabili o incostanti.
  • Velocità di sviluppo: l'approccio serverless consente agli sviluppatori di concentrarsi sul codice piuttosto che sulla gestione dell'infrastruttura.

Casi d'uso comuni per applicazioni serverless

Alcuni dei casi d'uso più comuni per applicazioni serverless includono:

  • API RESTful: con AWS Lambda e API Gateway, è possibile costruire facilmente API scalabili.
  • Elaborazione di file: eseguire funzioni serverless in risposta a eventi come il caricamento di file in Amazon S3 per elaborare immagini, video o documenti.
  • Automazione e integrazione: le applicazioni serverless sono ideali per automatizzare flussi di lavoro, come notifiche, backup, o sincronizzazione di dati tra sistemi.
  • Analisi dei dati in tempo reale: con Lambda, è possibile eseguire analisi su flussi di dati in tempo reale provenienti da sensori IoT, applicazioni mobili o altre fonti.


2. Cos'è AWS Lambda?

AWS Lambda è uno dei servizi serverless più popolari forniti da Amazon Web Services (AWS). Permette di eseguire codice in risposta a eventi, senza dover gestire server. Il codice viene eseguito in piccole unità chiamate funzioni Lambda, che possono essere invocate tramite eventi come chiamate API, modifiche in un bucket S3 o messaggi in una coda SQS.

Come funziona AWS Lambda?

AWS Lambda è progettato per eseguire piccole unità di codice (le funzioni Lambda) in modo efficiente e scalabile. Ecco come funziona il ciclo di vita di una funzione Lambda:

  1. Creazione della funzione: scrivi il codice della funzione in un linguaggio supportato (Python è uno dei linguaggi più popolari) e caricalo su AWS Lambda.
  2. Trigger di un evento: la funzione viene invocata automaticamente quando si verifica un evento specifico, come una richiesta HTTP, una modifica a un file in S3 o un messaggio in una coda SQS.
  3. Esecuzione del codice: AWS Lambda esegue il codice della funzione utilizzando le risorse necessarie per gestire il carico. Se ci sono molte richieste simultanee, Lambda scala automaticamente.
  4. Risposta: la funzione Lambda restituisce una risposta, che può essere un output JSON, un file elaborato o una conferma dell'avvenuta esecuzione.

2.2 Principali caratteristiche di AWS Lambda

  • Supporto per più linguaggi: AWS Lambda supporta diversi linguaggi di programmazione, tra cui Python, Node.js, Ruby, Java e Go.
  • Scalabilità automatica: le funzioni Lambda scalano automaticamente in base alla domanda, senza la necessità di configurare manualmente il dimensionamento delle risorse.
  • Costo in base all'uso: si paga solo per il tempo effettivo di esecuzione delle funzioni Lambda. Non ci sono costi fissi per le risorse non utilizzate.
  • Integrazione con altri servizi AWS: Lambda si integra perfettamente con molti altri servizi AWS, come S3, DynamoDB, API Gateway, SQS e Kinesis, facilitando la creazione di applicazioni complesse.


3. Creazione di una funzione serverless con AWS Lambda e Python

In questa sezione, vedremo come creare una semplice funzione AWS Lambda utilizzando Python. Questo esempio ti guiderà attraverso il processo di creazione, configurazione e distribuzione di una funzione Lambda che elabora un file caricato su S3.

Prerequisiti

Prima di iniziare, assicurati di avere:

  1. Un account AWS attivo.
  2. AWS CLI installata e configurata sul tuo computer.
  3. Python 3.x installato.

Scrivere una funzione Lambda in Python

Supponiamo di voler creare una funzione Lambda che viene eseguita ogni volta che un file viene caricato in un bucket S3 e che elabora il file (ad esempio, ridimensiona un'immagine).

Ecco un esempio di codice per la funzione Lambda:

import boto3
from PIL import Image
import io

s3 = boto3.client('s3')

def lambda_handler(event, context):
    # Ottenere le informazioni sul file caricato
    bucket_name = event['Records'][0]['s3']['bucket']['name']
    file_key = event['Records'][0]['s3']['object']['key']
    
    # Scaricare il file da S3
    response = s3.get_object(Bucket=bucket_name, Key=file_key)
    file_content = response['Body'].read()
    
    # Caricare l'immagine utilizzando PIL
    image = Image.open(io.BytesIO(file_content))
    
    # Ridimensionare l'immagine
    image = image.resize((128, 128))
    
    # Salvare l'immagine ridimensionata in memoria
    buffer = io.BytesIO()
    image.save(buffer, format="JPEG")
    buffer.seek(0)
    
    # Caricare l'immagine ridimensionata in un nuovo file S3
    new_file_key = f"resized-{file_key}"
    s3.put_object(Bucket=bucket_name, Key=new_file_key, Body=buffer, ContentType="image/jpeg")
    
    return {
        'statusCode': 200,
        'body': f"File {file_key} processato e salvato come {new_file_key}"
    }        

Passi per distribuire la funzione Lambda

  1. Creare un bucket S3: Per testare la funzione Lambda, crea un bucket S3 che conterrà i file da elaborare.

aws s3 mb s3://bucket-lambda-python        

  1. Creare la funzione Lambda: Vai alla console AWS Lambda e clicca su "Create Function". Scegli "Author from scratch" e seleziona Python come runtime.
  2. Caricare il codice Lambda: Puoi incollare direttamente il codice Python nell'editor Lambda o caricare un file ZIP con il codice.
  3. Impostare i trigger: Aggiungi un trigger per il bucket S3 creato in precedenza. Configura il trigger in modo che la funzione venga eseguita ogni volta che un file viene caricato nel bucket.
  4. Testare la funzione: Carica un file nel bucket S3 e controlla i log nella console AWS CloudWatch per verificare che la funzione Lambda sia stata eseguita correttamente.


4. API Serverless con AWS Lambda e API Gateway

Uno degli utilizzi più comuni di AWS Lambda è la creazione di API serverless scalabili. AWS API Gateway è un servizio che consente di creare e gestire API RESTful, instradando le richieste a funzioni Lambda in background.

Creare un'API serverless

In questo esempio, creeremo un'API che consente agli utenti di inviare richieste HTTP (GET e POST) e di eseguire azioni tramite Lambda.

  1. Creare la funzione Lambda: Scrivi una funzione Lambda che gestisca le richieste API.

def lambda_handler(event, context):
    method = event['httpMethod']
    
    if method == 'GET':
        return {
            'statusCode': 200,
            'body': 'GET request ricevuta!'
        }
    
    if method == 'POST':
        data = event['body']
        return {
            'statusCode': 200,
            'body': f'Dati ricevuti: {data}'
        }        

  1. Configurare API Gateway: Vai alla console di API Gateway e crea una nuova API. Collega l'API alla funzione Lambda. Configura i metodi GET e POST per la tua API e distribuisci l'API.
  2. Testare l'API: Utilizza uno strumento come Postman o curl per inviare richieste alla tua API e verificare che la funzione Lambda risponda correttamente.


5. Migliorare la scalabilità e ottimizzare i costi con AWS Lambda

Migliorare le prestazioni con il multi-threading

Le funzioni Lambda, per impostazione predefinita, eseguono il codice in modalità single-threaded. Tuttavia, è possibile migliorare le prestazioni delle funzioni Lambda abilitando l'elaborazione multi-threading in Python.

Ecco un esempio di come eseguire un'attività parallela in una funzione Lambda utilizzando il modulo concurrent.futures:

import concurrent.futures
import boto3

s3 = boto3.client('s3')

def process_file(file_key):
    # Logica per processare il file
    pass

def lambda_handler(event, context):
    file_keys = ['file1.csv', 'file2.csv', 'file3.csv']
    
    with concurrent.futures.ThreadPoolExecutor() as executor:
        executor.map(process_file, file_keys)
    
    return {
        'statusCode': 200,
        'body': 'Elaborazione completata!'
    }        

Ridurre i costi con le funzioni Lambda

  • Ottimizzare i tempi di esecuzione: Riduci il tempo di esecuzione della tua funzione Lambda ottimizzando il codice ed evitando operazioni non necessarie.
  • Utilizzare il giusto livello di memoria: AWS Lambda ti consente di configurare la quantità di memoria allocata per la tua funzione. Una maggiore memoria può migliorare le prestazioni, ma aumenta i costi.
  • Monitorare i log e gli errori: Utilizza CloudWatch per monitorare i log e identificare eventuali errori o problemi che rallentano l'esecuzione della funzione.


6. Best practices per lo sviluppo di applicazioni serverless con Python

  • Gestione degli errori: Assicurati di gestire correttamente gli errori nella tua funzione Lambda. Utilizza blocchi try-except e registra gli errori in CloudWatch per il debugging.
  • Test locali: Utilizza strumenti come AWS SAM (Serverless Application Model) per testare localmente le tue funzioni Lambda prima di distribuirle su AWS.
  • Ottimizzare il cold start: Le funzioni Lambda hanno un tempo di avvio (cold start) che può influire sulle prestazioni. Utilizza dipendenze leggere e cerca di ridurre l'inizializzazione non necessaria.


Lo sviluppo di applicazioni serverless con Python offre vantaggi significativi in termini di scalabilità, riduzione dei costi e semplificazione della gestione dell'infrastruttura. Utilizzando servizi come AWS Lambda, gli sviluppatori possono concentrarsi sul codice e sui risultati, senza preoccuparsi della gestione dei server.

In questo articolo, abbiamo esplorato come creare applicazioni serverless utilizzando Python e AWS Lambda. Abbiamo visto esempi pratici di come scrivere, distribuire e ottimizzare funzioni Lambda, nonché come utilizzare AWS API Gateway per creare API scalabili e senza server.

Le architetture serverless stanno diventando sempre più popolari grazie alla loro capacità di gestire carichi di lavoro variabili in modo efficiente e conveniente. Python, con il suo ecosistema di librerie e strumenti, è la scelta perfetta per costruire applicazioni serverless potenti e flessibili.

Per visualizzare o aggiungere un commento, accedi

Altri articoli di Ivano Pezzoli