Configurazione di un'API utilizzando Flask, Cloud SQL di Google e App Engine

Pubblicato: 2022-03-10
Riepilogo rapido ↬ Flask consente agli sviluppatori di creare un'API per qualsiasi caso d'uso che potrebbero avere. In questo tutorial impareremo come configurare Google Cloud, Cloud SQL e App Engine per creare un'API Flask. (Cloud SQL è un motore di database PaaS (Platform-as-a-Service) completamente gestito e App Engine è un PaaS completamente gestito per l'hosting di applicazioni.)

Alcuni 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.

Altro dopo il salto! Continua a leggere sotto ↓

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.

Mostra il prompt env per indicare che un ambiente è attivo
(env) viene visualizzato prima del prompt (Anteprima grande)

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.

Questa immagine mostra la risposta da una richiesta get
Una risposta di get da Postman (anteprima grande)

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.

Questa immagine mostra una richiesta di post utilizzando Postman
Invia richiesta da postino (anteprima grande)

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:

  1. Iscriviti a Google Cloud. Google offre $ 300 di credito gratuito ai nuovi utenti.
  2. 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.

Questa immagine mostra una sottosezione dei servizi GCP
Istantanea dei servizi GCP (anteprima grande)
Questa immagine mostra i tre motori di database offerti per Cloud SQL
Pagina della console di Cloud SQL (anteprima grande)

Innanzitutto, ci viene richiesto di scegliere un motore SQL. Andremo con MySQL per questo articolo.

Questa immagine mostra la pagina per la creazione di un'istanza Cloud SQL
Creazione di una nuova istanza Cloud SQL (anteprima grande)

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:

  1. Crea un database.
  2. Crea un nuovo utente.
  3. Inserisci nella lista bianca il nostro indirizzo IP.

Crea un database

Passare alla scheda "Database" per creare un database.

Questa immagine mostra la creazione di un nuovo utente su Cloud SQL
Creazione di un nuovo database su Cloud SQL (Anteprima grande)

Crea un nuovo utente

Creazione di un nuovo utente su Cloud SQL (Anteprima grande)

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".

Questa immagine mostra la pagina per la whitelist IP
Inserisci nella whitelist il tuo indirizzo IP (anteprima grande)

Connetti all'istanza

Quindi, vai al pannello "Panoramica" e connettiti utilizzando la shell cloud.

Questa immagine mostra il dashboard di Cloud SQL
Dashboard Cloud SQL (anteprima grande)

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; 
Questa immagine mostra l'output della shell per quando eseguiamo show database nella shell cloud
Output della shell per "mostra database" (anteprima grande)

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.

Questa immagine mostra l'output della shell per quando eseguiamo le tabelle di visualizzazione nella shell cloud
Output della shell per "mostra tabelle" (anteprima grande)

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:

Questa immagine mostra l'output durante la distribuzione in App Engine
Output dell'interfaccia della riga di comando per la distribuzione di App Engine (anteprima grande)

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.

Questa immagine mostra una richiesta di post alla nostra app distribuita
Dimostrazione di una richiesta di post (anteprima grande)
Questa immagine mostra una richiesta di get alla nostra app distribuita
Dimostrazione di una richiesta get (Anteprima grande)

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