Configurazione di un'API utilizzando Flask, Cloud SQL di Google e App Engine
Pubblicato: 2022-03-10Alcuni framework Python possono essere utilizzati per creare API, due delle quali sono Flask e Django. Frameworks viene fornito con funzionalità che semplificano agli sviluppatori l'implementazione delle funzionalità di cui gli utenti hanno bisogno per interagire con le loro applicazioni. La complessità di un'applicazione Web potrebbe essere un fattore decisivo nella scelta del framework con cui lavorare.
Django
Django è un framework robusto che ha una struttura predefinita con funzionalità integrate. Lo svantaggio della sua robustezza, tuttavia, è che potrebbe rendere il quadro troppo complesso per alcuni progetti. È più adatto per applicazioni Web complesse che devono sfruttare le funzionalità avanzate di Django.
Borraccia
Flask, d'altra parte, è un framework leggero per la creazione di API. Iniziare con esso è facile e sono disponibili pacchetti per renderlo robusto mentre procedi. Questo articolo si concentrerà sulla definizione delle funzioni di visualizzazione e del controller e sulla connessione a un database su Google Cloud e sulla distribuzione in Google Cloud.
Ai fini dell'apprendimento, creeremo un'API Flask con alcuni endpoint per gestire una raccolta dei nostri brani preferiti. Gli endpoint saranno per le richieste GET
e POST
: recupero e creazione di risorse. Inoltre, utilizzeremo la suite di servizi sulla piattaforma Google Cloud. Imposteremo Cloud SQL di Google per il nostro database e avvieremo la nostra app distribuendola ad App Engine. Questo tutorial è rivolto ai principianti che stanno provando per la prima volta a utilizzare Google Cloud per la loro app.
Impostazione di un progetto Flask
Questo tutorial presuppone che tu abbia installato Python 3.x. In caso contrario, vai al sito Web ufficiale per scaricarlo e installarlo.
Per verificare se Python è installato, avvia l'interfaccia della riga di comando (CLI) ed esegui il comando seguente:
python -V
Il nostro primo passo è creare la directory in cui vivrà il nostro progetto. Lo chiameremo flask-app
:
mkdir flask-app && cd flask-app
La prima cosa da fare quando si avvia un progetto Python è creare un ambiente virtuale. Gli ambienti virtuali isolano il tuo sviluppo Python funzionante. Ciò significa che questo progetto può avere le proprie dipendenze, diverse da altri progetti sulle tue macchine. venv è un modulo fornito con Python 3.
Creiamo un ambiente virtuale nella nostra directory flask-app
:
python3 -m venv env
Questo comando crea una cartella env
nella nostra directory. Il nome (in questo caso, env
) è un alias per l'ambiente virtuale e può essere denominato in qualsiasi modo.
Ora che abbiamo creato l'ambiente virtuale, dobbiamo dire al nostro progetto di usarlo. Per attivare il nostro ambiente virtuale, usa il seguente comando:
source env/bin/activate
Vedrai che il tuo prompt CLI ora ha env
all'inizio, a indicare che il nostro ambiente è attivo.
Ora installiamo il nostro pacchetto Flask:
pip install flask
Crea una directory denominata api
nella nostra directory corrente. Stiamo creando questa directory in modo da avere una cartella in cui risiederanno le altre cartelle della nostra app.
mkdir api && cd api
Quindi, crea un file main.py
, che fungerà da punto di accesso alla nostra app:
touch main.py
Apri main.py
e inserisci il codice seguente:
#main.py from flask import Flask app = Flask(__name__) @app.route('/') def home(): return 'Hello World' if __name__ == '__main__': app.run()
Capiamo cosa abbiamo fatto qui. Per prima cosa abbiamo importato la classe Flask
dal pacchetto Flask. Quindi, abbiamo creato un'istanza della classe e l'abbiamo assegnata ad app
. Successivamente, abbiamo creato il nostro primo endpoint, che punta alla radice della nostra app. In sintesi, questa è una funzione di visualizzazione che invoca la /
route — restituisce Hello World
.
Eseguiamo l'app:
python main.py
Questo avvia il nostro server locale e serve la nostra app su https://127.0.0.1:5000/
. Inserisci l'URL nel tuo browser e vedrai la risposta di Hello World
stampata sullo schermo.
E voilà! La nostra app è attiva e funzionante. Il prossimo compito è renderlo funzionale.
Per chiamare i nostri endpoint, utilizzeremo Postman, un servizio che aiuta gli sviluppatori a testare gli endpoint. Puoi scaricarlo dal sito ufficiale.
Facciamo in modo che main.py
restituisca alcuni dati:
#main.py from flask import Flask, jsonify app = Flask(__name__) songs = [ { "title": "Rockstar", "artist": "Dababy", "genre": "rap", }, { "title": "Say So", "artist": "Doja Cat", "genre": "Hiphop", }, { "title": "Panini", "artist": "Lil Nas X", "genre": "Hiphop" } ] @app.route('/songs') def home(): return jsonify(songs) if __name__ == '__main__': app.run()
Qui, abbiamo incluso un elenco di brani, inclusi il titolo del brano e il nome dell'artista. Abbiamo quindi cambiato la root /
route in /songs
. Questo percorso restituisce l'array di brani che abbiamo specificato. Per ottenere il nostro elenco come valore JSON, abbiamo JSONificato l'elenco passandolo tramite jsonify
. Ora, invece di vedere un semplice Hello world
, vediamo un elenco di artisti quando accediamo https://127.0.0.1:5000/songs
://127.0.0.1:5000/songs endpoint.
Potresti aver notato che dopo ogni modifica dovevamo riavviare il nostro server. Per abilitare il ricaricamento automatico quando il codice cambia, abilitiamo l'opzione di debug. Per fare ciò, cambia app.run
in questo:
app.run(debug=True)
Successivamente, aggiungiamo una canzone utilizzando una richiesta di post al nostro array. Innanzitutto, importa l'oggetto della request
, in modo che possiamo elaborare la richiesta in arrivo dai nostri utenti. In seguito utilizzeremo l'oggetto request
nella funzione di visualizzazione per ottenere l'input dell'utente in JSON.
#main.py from flask import Flask, jsonify, request app = Flask(__name__) songs = [ { "title": "Rockstar", "artist": "Dababy", "genre": "rap", }, { "title": "Say So", "artist": "Doja Cat", "genre": "Hiphop", }, { "title": "Panini", "artist": "Lil Nas X", "genre": "Hiphop" } ] @app.route('/songs') def home(): return jsonify(songs) @app.route('/songs', methods=['POST']) def add_songs(): song = request.get_json() songs.append(song) return jsonify(songs) if __name__ == '__main__': app.run(debug=True)
La nostra funzione di visualizzazione add_songs
prende un brano inviato dall'utente e lo aggiunge al nostro elenco di brani esistente.
Finora, abbiamo restituito i nostri dati da un elenco Python. Questo è solo sperimentale, perché in un ambiente più robusto, i nostri dati appena aggiunti andrebbero persi se riavviassimo il server. Ciò non è fattibile, quindi avremo bisogno di un database live per archiviare e recuperare i dati. Arriva Cloud SQL.
Perché utilizzare un'istanza Cloud SQL?
Secondo il sito ufficiale:
“Google Cloud SQL è un servizio di database completamente gestito che semplifica la configurazione, la manutenzione, la gestione e l'amministrazione dei database relazionali MySQL e PostgreSQL nel cloud. Ospitato su Google Cloud Platform, Cloud SQL fornisce un'infrastruttura di database per applicazioni in esecuzione ovunque".
Ciò significa che possiamo esternalizzare la gestione dell'infrastruttura di un database interamente a Google, a prezzi flessibili.
Differenza tra Cloud SQL e un motore di calcolo autogestito
Su Google Cloud, possiamo far girare una macchina virtuale sull'infrastruttura Compute Engine di Google e installare la nostra istanza SQL. Ciò significa che saremo responsabili della scalabilità verticale, della replica e di una serie di altre configurazioni. Con Cloud SQL, otteniamo molte configurazioni pronte all'uso, così possiamo dedicare più tempo al codice e meno tempo alla configurazione.
Prima di iniziare:
- Iscriviti a Google Cloud. Google offre $ 300 di credito gratuito ai nuovi utenti.
- Crea un progetto. Questo è abbastanza semplice e può essere fatto direttamente dalla console.
Crea un'istanza Cloud SQL
Dopo esserti registrato a Google Cloud, nel pannello di sinistra, scorri fino alla scheda "SQL" e fai clic su di essa.
Innanzitutto, ci viene richiesto di scegliere un motore SQL. Andremo con MySQL per questo articolo.
Successivamente, creeremo un'istanza. Per impostazione predefinita, la nostra istanza verrà creata negli Stati Uniti e la zona verrà selezionata automaticamente per noi.
Imposta la password di root e assegna un nome all'istanza, quindi fai clic sul pulsante "Crea". Puoi configurare ulteriormente l'istanza facendo clic sul menu a discesa "Mostra opzioni di configurazione". Le impostazioni consentono di configurare le dimensioni dell'istanza, la capacità di archiviazione, la sicurezza, la disponibilità, i backup e altro ancora. Per questo articolo, andremo con le impostazioni predefinite. Non preoccuparti, queste variabili possono essere modificate in seguito.
Il completamento del processo potrebbe richiedere alcuni minuti. Saprai che l'istanza è pronta quando vedrai un segno di spunta verde. Fai clic sul nome della tua istanza per andare alla pagina dei dettagli.
Ora che siamo operativi, faremo alcune cose:
- Crea un database.
- Crea un nuovo utente.
- Inserisci nella lista bianca il nostro indirizzo IP.
Crea un database
Passare alla scheda "Database" per creare un database.
Crea un nuovo utente
Nella sezione "Nome host", impostalo per consentire "% (qualsiasi host)".
Whitelist indirizzo IP
Puoi connetterti all'istanza del database in due modi. Un indirizzo IP privato richiede un cloud privato virtuale (VPC). Se scegli questa opzione, Google Cloud creerà un VPC gestito da Google e collocherà la tua istanza al suo interno. Per questo articolo, utilizzeremo l'indirizzo IP pubblico , che è l'impostazione predefinita. È pubblico nel senso che solo le persone i cui indirizzi IP sono stati inseriti nella whitelist possono accedere al database.
Per inserire nella whitelist il tuo indirizzo IP, digita my ip
in una ricerca su Google per ottenere il tuo IP. Quindi, vai alla scheda "Connessioni" e "Aggiungi rete".
Connetti all'istanza
Quindi, vai al pannello "Panoramica" e connettiti utilizzando la shell cloud.
Il comando per connettersi alla nostra istanza Cloud SQL sarà pre-digitato nella console.
È possibile utilizzare l'utente root o l'utente creato in precedenza. Nel comando seguente, diciamo: Connettiti all'istanza flask-demo
come utente USERNAME
. Ti verrà chiesto di inserire la password dell'utente.
gcloud sql connect flask-demo --user=USERNAME
Se ricevi un errore che dice che non hai un ID progetto, puoi ottenere l'ID del tuo progetto eseguendo questo:
gcloud projects list
Prendi l'ID progetto che è stato emesso dal comando sopra e inseriscilo nel comando seguente, sostituendo PROJECT_ID
con esso.
gcloud config set project PROJECT_ID
Quindi, esegui il comando gcloud sql connect
e saremo connessi.
Esegui questo comando per vedere i database attivi:
> show databases;
Il mio database si chiama db_demo
e eseguirò il comando seguente per utilizzare il database db_demo
. Potresti vedere altri database, come information_schema
e performance_schema
. Questi sono lì per memorizzare i metadati della tabella.
> use db_demo;
Quindi, crea una tabella che rispecchi l'elenco dalla nostra app Flask. Digita il codice qui sotto su un blocco note e incollalo nella tua shell cloud:
create table songs( song_id INT NOT NULL AUTO_INCREMENT, title VARCHAR(255), artist VARCHAR(255), genre VARCHAR(255), PRIMARY KEY(song_id) );
Questo codice è un comando SQL che crea una tabella denominata songs
, con quattro colonne ( song_id
, title
, artist
e genre
). Abbiamo anche indicato che la tabella dovrebbe definire song_id
come chiave primaria e incrementare automaticamente da 1.
Ora, esegui show tables;
per confermare che la tabella è stata creata.
E proprio così, abbiamo creato un database e la nostra tabella delle songs
.
Il nostro prossimo compito è configurare Google App Engine in modo da poter distribuire la nostra app.
Motore per app di Google
App Engine è una piattaforma completamente gestita per lo sviluppo e l'hosting di applicazioni Web su larga scala. Un vantaggio della distribuzione in App Engine è che consente a un'app di ridimensionarsi automaticamente per soddisfare il traffico in entrata.
Il sito web di App Engine dice:
"Con zero gestione del server e zero installazioni di configurazione, gli sviluppatori possono concentrarsi solo sulla creazione di grandi applicazioni senza il sovraccarico di gestione".
Configura App Engine
Esistono diversi modi per configurare App Engine: tramite l'interfaccia utente di Google Cloud Console o tramite Google Cloud SDK. Useremo l'SDK per questa sezione. Ci consente di distribuire, gestire e monitorare la nostra istanza Google Cloud dalla nostra macchina locale.
Installa Google Cloud SDK
Segui le istruzioni per scaricare e installare l'SDK per Mac o Windows. La guida ti mostrerà anche come inizializzare l'SDK nella tua CLI e come scegliere un progetto Google Cloud.
Ora che l'SDK è stato installato, aggiorneremo il nostro script Python con le credenziali del nostro database e lo distribuiremo su App Engine.
Configurazione locale
Nel nostro ambiente locale, aggiorneremo la configurazione per adattarla alla nostra nuova architettura, che include Cloud SQL e App Engine.
Innanzitutto, aggiungi un file app.yaml
alla nostra cartella principale. Questo è un file di configurazione che App Engine richiede per ospitare ed eseguire la nostra app. Indica ad App Engine il nostro runtime e altre variabili che potrebbero essere necessarie. Per la nostra app, dovremo aggiungere le credenziali del nostro database come variabili di ambiente, in modo che App Engine sia a conoscenza dell'istanza del nostro database.
Nel file app.yaml
, aggiungi lo snippet di seguito. Avrai ottenuto le variabili di runtime e del database dalla configurazione del database. Sostituisci i valori con il nome utente, la password, il nome del database e il nome della connessione che hai utilizzato durante la configurazione di Cloud SQL.
#app.yaml runtime: python37 env_variables: CLOUD_SQL_USERNAME: YOUR-DB-USERNAME CLOUD_SQL_PASSWORD: YOUR-DB-PASSWORD CLOUD_SQL_DATABASE_NAME: YOUR-DB-NAME CLOUD_SQL_CONNECTION_NAME: YOUR-CONN-NAME
Ora installeremo PyMySQL. Questo è un pacchetto Python MySQL che si connette ed esegue query su un database MySQL. Installa il pacchetto PyMySQL eseguendo questa riga nella tua CLI:
pip install pymysql
A questo punto, siamo pronti per utilizzare PyMySQL per connetterci al nostro database Cloud SQL dall'app. Questo ci consentirà di ottenere e inserire query nel nostro database.
Inizializza il connettore del database
Innanzitutto, crea un file db.py
nella nostra cartella principale e aggiungi il codice di seguito:
#db.py import os import pymysql from flask import jsonify db_user = os.environ.get('CLOUD_SQL_USERNAME') db_password = os.environ.get('CLOUD_SQL_PASSWORD') db_name = os.environ.get('CLOUD_SQL_DATABASE_NAME') db_connection_name = os.environ.get('CLOUD_SQL_CONNECTION_NAME') def open_connection(): unix_socket = '/cloudsql/{}'.format(db_connection_name) try: if os.environ.get('GAE_ENV') == 'standard': conn = pymysql.connect(user=db_user, password=db_password, unix_socket=unix_socket, db=db_name, cursorclass=pymysql.cursors.DictCursor ) except pymysql.MySQLError as e: print(e) return conn def get_songs(): conn = open_connection() with conn.cursor() as cursor: result = cursor.execute('SELECT * FROM songs;') songs = cursor.fetchall() if result > 0: got_songs = jsonify(songs) else: got_songs = 'No Songs in DB' conn.close() return got_songs def add_songs(song): conn = open_connection() with conn.cursor() as cursor: cursor.execute('INSERT INTO songs (title, artist, genre) VALUES(%s, %s, %s)', (song["title"], song["artist"], song["genre"])) conn.commit() conn.close()
Abbiamo fatto alcune cose qui.
Innanzitutto, abbiamo recuperato le credenziali del database dal file app.yaml
utilizzando il metodo os.environ.get
. App Engine è in grado di rendere disponibili nell'app le variabili di ambiente definite in app.yaml
.
In secondo luogo, abbiamo creato una funzione open_connection
. Si collega al nostro database MySQL con le credenziali.
In terzo luogo, abbiamo aggiunto due funzioni: get_songs
e add_songs
. Il primo avvia una connessione al database chiamando la funzione open_connection
. Quindi interroga la tabella dei songs
per ogni riga e, se vuota, restituisce "Nessun brano nel DB". La funzione add_songs
inserisce un nuovo record nella tabella dei songs
.
Infine, torniamo al punto di partenza, il nostro file main.py
Ora, invece di ottenere le nostre canzoni da un oggetto, come abbiamo fatto prima, chiamiamo la funzione add_songs
per inserire un record e chiamiamo la funzione get_songs
per recuperare i record dal database.
Facciamo il refactoring main.py
:
#main.py from flask import Flask, jsonify, request from db import get_songs, add_songs app = Flask(__name__) @app.route('/', methods=['POST', 'GET']) def songs(): if request.method == 'POST': if not request.is_json: return jsonify({"msg": "Missing JSON in request"}), 400 add_songs(request.get_json()) return 'Song Added' return get_songs() if __name__ == '__main__': app.run()
Abbiamo importato le funzioni get_songs
e add_songs
e le abbiamo chiamate nella nostra funzione di visualizzazione di songs()
. Se stiamo facendo una richiesta di post
, chiamiamo la funzione add_songs
, e se stiamo facendo una richiesta get
, chiamiamo la funzione get_songs
.
E la nostra app è fatta.
Il prossimo passo è l'aggiunta di un file requirements.txt
. Questo file contiene un elenco di pacchetti necessari per eseguire l'app. App Engine controlla questo file e installa i pacchetti elencati.
pip freeze | grep "Flask\|PyMySQL" > requirements.txt
Questa riga ottiene i due pacchetti che stiamo usando per l'app (Flask e requirements.txt
), crea un file Requirements.txt e aggiunge i pacchetti e le relative versioni al file.
A questo punto, abbiamo aggiunto tre nuovi file: db.py
, app.yaml
e requirements.txt
.
Distribuisci su Google App Engine
Esegui il comando seguente per distribuire la tua app:
gcloud app deploy
Se è andato bene, la tua console produrrà questo:
La tua app è ora in esecuzione su App Engine. Per vederlo nel browser, esegui la gcloud app browse
nella tua CLI.
Possiamo lanciare Postman per testare il nostro post
e get
richieste.
La nostra app è ora ospitata sull'infrastruttura di Google e possiamo modificare la configurazione per ottenere tutti i vantaggi di un'architettura serverless. In futuro, puoi basarti su questo articolo per rendere più robusta la tua applicazione serverless.
Conclusione
L'utilizzo di un'infrastruttura Platform-as-a-Service (PaaS) come App Engine e Cloud SQL sostanzialmente astrae il livello dell'infrastruttura e ci consente di creare più rapidamente. In qualità di sviluppatori, non dobbiamo preoccuparci della configurazione, del backup e del ripristino, del sistema operativo, della scalabilità automatica, dei firewall, della migrazione del traffico e così via. Tuttavia, se è necessario controllare la configurazione sottostante, potrebbe essere meglio utilizzare un servizio personalizzato.
Riferimenti
- "Scarica Python"
- “venv — Creazione di ambienti virtuali”, Python (documentazione)
- "Scarica postino"
- "Cloud SQL", Google Cloud
- Google Cloud
- "Livello gratuito di Google Cloud", Google Cloud
- "Creazione e gestione dei progetti", Google Cloud
- "Panoramica VPC" (virtual private cloud), Google Cloud
- "App Engine", Google Cloud
- "Avviamenti rapidi" (scarica Google Cloud SDK), Google Cloud
- Documentazione PyMySQL