Python - Guida alla Programmazione CGI per Principianti

Ciao a tutti, futuri maghi Python! Sono entusiasta di essere il vostro guida in questo avventuroso viaggio nel mondo della programmazione CGI con Python. Come persona che ha insegnato scienze informatiche per anni, posso dirvi che CGI è come la salsa segreta che fa vivere le vostre applicazioni web. Allora, allacciamo le maniche e ci immergiamo!

Python - CGI Programming

Cos'è CGI?

CGI sta per Common Gateway Interface. So che suona un po' complicato, ma pensatelo come un traduttore tra il vostro server web e i vostri script Python. È come avere un interprete amichevole che aiuta il vostro server e il vostro codice a comunicare senza problemi.

CGI ci permette di creare pagine web dinamiche che possono rispondere all'input dell'utente. Immaginate un sito web che vi saluta per nome o vi mostra contenuti personalizzati: è la magia del CGI in azione!

Navigazione Web

Prima di entrare nei dettagli di CGI, diamo un'occhiata rapida a come funziona la navigazione web. Quando digitate un URL nel vostro browser, ecco cosa succede:

  1. Il vostro browser invia una richiesta al server web.
  2. Il server web elabora la richiesta.
  3. Il server invia una risposta, di solito sotto forma di una pagina HTML.
  4. Il vostro browser visualizza questa HTML, mostrando la pagina web che vedete.

CGI entra in gioco quando vogliamo generare contenuti dinamici al passo 3.

Diagramma dell'Architettura CGI

Ecco un diagramma semplice per visualizzare come CGI si inserisce nell'architettura web:

+-------------+    Richiesta HTTP    +-------------+
|   Browser   | -----------------> |  Server Web |
|             | <----------------- |             |
+-------------+    Risposta HTTP   +-------------+
|
| CGI
v
+-------------+
| Script CGI  |
| (Python)    |
+-------------+

Supporto e Configurazione del Server Web

La maggior parte dei server web supportano CGI, inclusi Apache e Nginx. Per utilizzare CGI con Python, dovete configurare il vostro server per eseguire script Python. Questo di solito implica impostare una directory speciale per gli script CGI e dire al server di trattare i file in questa directory come eseguibili.

Per esempio, in Apache, potresti aggiungere qualcosa come questo alla tua configurazione:

<Directory /var/www/cgi-bin>
Options ExecCGI
AddHandler cgi-script .py
</Directory>

Questo dice ad Apache di eseguire i file .py nella directory /var/www/cgi-bin come script CGI.

Primo Programma CGI

Scriviamo il nostro primo programma CGI! Iniziamo con l'esempio classico "Hello, World!". Crea un file chiamato hello.py nella tua directory CGI:

#!/usr/bin/env python3
print("Content-Type: text/html")
print()
print("<html>")
print("<head>")
print("<title>Hello World - Primo Programma CGI</title>")
print("</head>")
print("<body>")
print("<h2>Hello World! Questo è il mio primo programma CGI</h2>")
print("</body>")
print("</html>")

Spiegazione:

  1. La prima riga dice al server di usare Python per eseguire questo script.
  2. Content-Type: text/html è un'intestazione HTTP che dice al browser che stiamo inviando HTML.
  3. La riga vuota print() separa le intestazioni dal corpo della risposta.
  4. Il resto è solo HTML che stiamo generando dinamicamente.

Quando accedi a questo script tramite il tuo browser web, dovresti vedere una pagina che dice "Hello World! Questo è il mio primo programma CGI".

Intestazione HTTP

Nella programmazione CGI, è cruciale inviare le intestazioni HTTP corrette prima del tuo contenuto. L'intestazione più comune è Content-Type, che dice al browser che tipo di dati stai inviando. Ecco alcuni esempi:

Content Type Descrizione
text/html Contenuto HTML
text/plain Testo semplice
image/jpeg Immagine JPEG
application/json Dati JSON

Ricorda sempre di inviare l'intestazione Content-Type appropriata prima del tuo contenuto!

Variabili d'Ambiente CGI

Gli script CGI hanno accesso a varie variabili d'ambiente che forniscono informazioni sulla richiesta. Ecco uno script che visualizza alcune di queste variabili:

#!/usr/bin/env python3
import os

print("Content-Type: text/html")
print()
print("<html><body>")
print("<h2>Variabili d'Ambiente:</h2>")
for param in os.environ.keys():
print("<b>%20s</b>: %s<br>" % (param, os.environ[param]))
print("</body></html>")

Questo script ti mostrerà tutte le variabili d'ambiente disponibili per il tuo script CGI, inclusi cose come il tipo di browser dell'utente, il nome del server e altro ancora.

Metodi GET e POST

Ci sono due metodi principali per inviare dati a uno script CGI: GET e POST. Analizziamo entrambi:

Metodo GET

Il metodo GET invia dati come parte dell'URL. Ecco un esempio semplice:

#!/usr/bin/env python3
import cgi

print("Content-Type: text/html")
print()

form = cgi.FieldStorage()
name = form.getvalue('name', 'Mondo')

print("<html><body>")
print(f"<h2>Ciao, {name}!</h2>")
print("</body></html>")

Puoi accedere a questo script con un URL come http://ilservitore.com/cgi-bin/hello.py?name=Alice, e vedrai "Ciao, Alice!".

Metodo POST

Il metodo POST invia dati nel corpo della richiesta HTTP. È tipicamente usato per i moduli. Ecco un esempio:

#!/usr/bin/env python3
import cgi

print("Content-Type: text/html")
print()

form = cgi.FieldStorage()
name = form.getvalue('name', 'Mondo')
email = form.getvalue('email', 'Non fornito')

print("<html><body>")
print(f"<h2>Ciao, {name}!</h2>")
print(f"<p>La tua email è: {email}</p>")
print("</body></html>")

Questo script potrebbe essere usato con un modulo HTML che utilizza il metodo POST.

Gestione di Diversi Elementi del Modulo

CGI può gestire vari elementi del modulo. Ecco alcuni esempi:

Caselle di Controllo

#!/usr/bin/env python3
import cgi

print("Content-Type: text/html")
print()

form = cgi.FieldStorage()
hobbies = form.getlist('hobby')

print("<html><body>")
print("<h2>I tuoi hobby:</h2>")
for hobby in hobbies:
print(f"<p>{hobby}</p>")
print("</body></html>")

Pulsanti di Opzione

#!/usr/bin/env python3
import cgi

print("Content-Type: text/html")
print()

form = cgi.FieldStorage()
gender = form.getvalue('gender', 'Non specificato')

print("<html><body>")
print(f"<h2Il tuo genere: {gender}</h2>")
print("</body></html>")

Area di Testo

#!/usr/bin/env python3
import cgi

print("Content-Type: text/html")
print()

form = cgi.FieldStorage()
message = form.getvalue('message', 'Nessun messaggio fornito')

print("<html><body>")
print("<h2Il tuo messaggio:</h2>")
print(f"<p>{message}</p>")
print("</body></html>")

Casella a Discesa

#!/usr/bin/env python3
import cgi

print("Content-Type: text/html")
print()

form = cgi.FieldStorage()
country = form.getvalue('country', 'Non selezionato')

print("<html><body>")
print(f"<h2Il tuo paese: {country}</h2>")
print("</body></html>")

Uso dei Cookie in CGI

I cookie sono un modo per memorizzare piccoli pezzi di dati sul lato client. Sono utili per ricordare le preferenze dell'utente o mantenere informazioni di sessione. Ecco come puoi lavorare con i cookie in CGI:

Impostazione dei Cookie

#!/usr/bin/env python3
import cgi
from http import cookies
import datetime

# Crea un cookie
c = cookies.SimpleCookie()
c['lastvisit'] = str(datetime.datetime.now())
c['lastvisit']['expires'] = 365 * 24 * 60 * 60  # scade in un anno

print(c)  # Questo stampa l'intestazione Set-Cookie
print("Content-Type: text/html")
print()

print("<html><body>")
print("<h2>Cookie impostato!</h2>")
print("</body></html>")

Recupero dei Cookie

#!/usr/bin/env python3
import os
from http import cookies

print("Content-Type: text/html")
print()

if 'HTTP_COOKIE' in os.environ:
cookie_string = os.environ.get('HTTP_COOKIE')
c = cookies.SimpleCookie()
c.load(cookie_string)
lastvisit = c.get('lastvisit')
if lastvisit:
print(f"<h2La tua ultima visita è stata: {lastvisit.value}</h2>")
else:
print("<h2Questa è la tua prima visita!</h2>")
else:
print("<h2Questa è la tua prima visita!</h2>")

Esempio di Caricamento dei File

Gestire il caricamento dei file è un po' più complesso, ma ecco un esempio semplice:

#!/usr/bin/env python3
import cgi, os
import cgitb; cgitb.enable()

print("Content-Type: text/html")
print()

form = cgi.FieldStorage()

# Ottieni il nome del file qui.
fileitem = form['filename']

# Testa se il file è stato caricato
if fileitem.filename:
# rimuovi il percorso iniziale dal nome del file per
# evitare attacchi di directory traversal
fn = os.path.basename(fileitem.filename)
open('/tmp/' + fn, 'wb').write(fileitem.file.read())
message = fIl file "{fn}" è stato caricato con successo
else:
message = Nessun file è stato caricato

print(f"""\
<html>
<body>
<p>{message}</p>
</body>
</html>
""")

Come Sollevare una Finestra di Dialogo "Scarica File"?

Per innescare lo scaricamento di un file, devi impostare le intestazioni appropriate:

#!/usr/bin/env python3
import os

filename = "example.txt"  # Questo sarebbe il nome del tuo file
filepath = "/percorso/al/tuo/file"  # Questo sarebbe il percorso del tuo file

print("Content-Type: application/octet-stream")
print(f"Content-Disposition: attachment; filename={filename}")
print()  # Riga vuota, fine delle intestazioni

# Ora invia il contenuto del file
with open(os.path.join(filepath, filename), 'rb') as f:
print(f.read())

Questo script imposta il Content-Type a application/octet-stream, che dice al browser di scaricare il file piuttosto che visualizzarlo. L'intestazione Content-Disposition suggerisce un nome file per lo scaricamento.

Ed eccoci qua, ragazzi! Abbiamo coperto i fondamenti della programmazione CGI con Python. Ricorda, la pratica fa il maestro, quindi non esitare a sperimentare con questi esempi e a creare i tuoi. Buon coding, e che i tuoi script CGI funzionino sempre liscamente!

Credits: Image by storyset