1. Panoramica
Questa serie di codelab (tutorial pratici e autonomi) ha lo scopo di aiutare gli sviluppatori a comprendere le varie opzioni a loro disposizione durante il deployment delle applicazioni. In questo codelab imparerai a utilizzare l'API Google Cloud Translation con Python ed eseguirla localmente o eseguirne il deployment su una piattaforma di calcolo serverless Cloud (App Engine, Cloud Functions o Cloud Run). L'app di esempio che si trova nel repository di questo tutorial può essere implementata (almeno) in otto modi diversi con solo piccole modifiche alla configurazione:
- Server Flask locale (Python 2)
- Server Flask locale (Python 3)
- App Engine (Python 2)
- App Engine (Python 3)
- Cloud Functions (Python 3)
- Cloud Run (Python 2 tramite Docker)
- Cloud Run (Python 3 tramite Docker)
- Cloud Run (Python 3 tramite Cloud Buildpacks)
Questo codelab si concentra sul deployment di questa app sulle piattaforme in grassetto sopra.
Imparerai come
- Utilizza le API Google Cloud, in particolare l'API Cloud Translation (avanzata/v3)
- Esegui un'applicazione web di base localmente o esegui il deployment su una piattaforma di computing serverless cloud.
Che cosa ti serve
- Un progetto Google Cloud con un account di fatturazione Cloud attivo
- Flask installato per l'esecuzione locale o una piattaforma di computing serverless Cloud abilitata per i deployment basati sul cloud
- Competenze di base di Python
- Conoscenza pratica dei comandi di base del sistema operativo
Sondaggio
Come utilizzerai questo tutorial?
Come valuteresti la tua esperienza con Python?
Come valuti la tua esperienza di utilizzo dei servizi Google Cloud?
2. Configurazione e requisiti
Configurazione dell'ambiente autonomo
- Accedi alla console Google Cloud e crea un nuovo progetto o riutilizzane uno esistente. Se non hai ancora un account Gmail o Google Workspace, devi crearne uno.



- Il nome del progetto è il nome visualizzato per i partecipanti a questo progetto. È una stringa di caratteri non utilizzata dalle API di Google e puoi aggiornarla in qualsiasi momento.
- L'ID progetto deve essere univoco in tutti i progetti Google Cloud ed è immutabile (non può essere modificato dopo essere stato impostato). Cloud Console genera automaticamente una stringa univoca, di solito non ti interessa di cosa si tratta. Nella maggior parte dei codelab, devi fare riferimento all'ID progetto (che in genere è identificato come
PROJECT_ID), quindi, se non ti piace, generane un altro casuale oppure puoi provare il tuo e vedere se è disponibile. Viene "congelato" dopo la creazione del progetto. - Esiste un terzo valore, un numero di progetto, utilizzato da alcune API. Scopri di più su tutti e tre questi valori nella documentazione.
- Successivamente, devi abilitare la fatturazione in Cloud Console per utilizzare le risorse/API Cloud. L'esecuzione di questo codelab non dovrebbe costare molto, se non nulla. Per arrestare le risorse in modo da non incorrere in costi di fatturazione al termine di questo tutorial, segui le istruzioni di "pulizia" riportate alla fine del codelab. I nuovi utenti di Google Cloud possono beneficiare del programma prova senza costi di 300$.
3. Abilita l'API Translation
Per la nostra app di esempio, attiverai l'API Cloud Translation e il servizio App Engine seguendo istruzioni simili a quelle riportate di seguito.
Attivazione delle API Cloud
Introduzione
Indipendentemente dall'API Google che vuoi utilizzare nella tua applicazione, deve essere abilitata. Il seguente esempio mostra due modi per abilitare l'API Cloud Vision. Dopo aver imparato ad abilitare un'API Cloud, potrai abilitare altre API perché la procedura è simile.
Opzione 1: da Cloud Shell o dall'interfaccia a riga di comando
Sebbene l'abilitazione delle API dalla console Cloud sia più comune, alcuni sviluppatori preferiscono fare tutto dalla riga di comando. Per farlo, devi cercare il "nome del servizio " di un'API. Sembra un URL: SERVICE_NAME.googleapis.com. Puoi trovarli nel grafico dei prodotti supportati oppure puoi eseguire query in modo programmatico con l'API Google Discovery.
Con queste informazioni, utilizzando Cloud Shell (o il tuo ambiente di sviluppo locale con lo strumento a riga di comando gcloud installato), puoi abilitare un'API nel seguente modo:
gcloud services enable SERVICE_NAME.googleapis.com
Ad esempio, questo comando abilita l'API Cloud Vision:
gcloud services enable vision.googleapis.com
Questo comando abilita App Engine:
gcloud services enable appengine.googleapis.com
Puoi anche attivare più API con una sola richiesta. Ad esempio, questa riga di comando abilita Cloud Run, Cloud Artifact Registry e l'API Cloud Translation:
gcloud services enable artifactregistry.googleapis.com run.googleapis.com translate.googleapis.com
Opzione 2: da Cloud Console
Puoi anche abilitare l'API Vision in API Manager. Nella console Cloud, vai a API Manager e seleziona Libreria.

Se vuoi abilitare l'API Cloud Vision, inizia a digitare"vision" nella barra di ricerca e verranno visualizzati tutti i risultati corrispondenti a ciò che hai digitato finora:

Seleziona l'API che vuoi abilitare e fai clic su Abilita:

Costo
Sebbene molte API di Google possano essere utilizzate senza costi, l'utilizzo di prodotti e API Google Cloud non è senza costi. Quando abiliti le API Cloud, potrebbe esserti chiesto un account di fatturazione attivo. Tuttavia, è importante notare che alcuni prodotti Google Cloud includono un livello "Sempre senza costi" (giornaliero/mensile), che devi superare per incorrere in addebiti di fatturazione; in caso contrario, la tua carta di credito (o lo strumento di fatturazione specificato) non verrà addebitata.
Prima di abilitare un'API, gli utenti devono consultare le informazioni sui prezzi, in particolare per verificare se è disponibile un livello senza costi e, in caso affermativo, qual è. Se abilitassi l'API Cloud Vision, dovresti controllare la pagina con le informazioni sui prezzi. Cloud Vision ha una quota senza costi e, se rispetti i limiti complessivi (entro ogni mese), non dovresti sostenere alcun costo.
I prezzi e i livelli senza costi variano a seconda delle API di Google. Esempi:
- Google Cloud/GCP: ogni prodotto viene fatturato in modo diverso e generalmente si paga per ciclo di vCPU, consumer di spazio di archiviazione, utilizzo di memoria o in base al consumo; consulta le informazioni sul livello senza costi riportate sopra.
- Google Maps: offre una suite di API e un credito mensile senza costi di 200$.
- API Google Workspace (in precedenza G Suite): forniscono un utilizzo senza costi (fino a determinati limiti) coperto da una tariffa di abbonamento mensile a Workspace, pertanto non è prevista una fatturazione diretta per l'utilizzo delle API Gmail, Google Drive, Calendar, Documenti, Fogli e Presentazioni.
I diversi prodotti Google vengono fatturati in modo diverso, quindi assicurati di consultare la documentazione dell'API per queste informazioni.
Riepilogo
Ora che sai come attivare le API di Google in generale, vai a API Manager e attiva sia l'API Cloud Translation che il servizio App Engine (se non l'hai già fatto), la prima perché la nostra applicazione la utilizzerà e il secondo perché stai eseguendo il deployment di un'app App Engine. Se preferisci farlo dalla riga di comando, esegui questo comando:
gcloud services enable appengine.googleapis.com translate.googleapis.com
Sebbene la quota mensile non sia elencata nella pagina di riepilogo del livello "Sempre senza costi" complessivo, la pagina dei prezzi dell'API Translation indica che tutti gli utenti ricevono mensilmente un importo fisso di caratteri tradotti. Se rimani al di sotto di questa soglia, non dovresti sostenere alcun costo per l'API. Eventuali altri addebiti correlati a Google Cloud verranno discussi alla fine della sezione "Pulizia".
4. Ottieni il codice dell'app di esempio
Clona il codice nel repository in locale o in Cloud Shell (utilizzando il comando git clone) oppure scarica il file ZIP dal pulsante verde Code, come mostrato nello screenshot seguente:

Ora che hai tutto, crea una copia completa della cartella per seguire questo tutorial specifico, perché probabilmente dovrai eliminare o modificare i file. Se vuoi eseguire un deployment diverso, puoi ricominciare copiando l'originale, in modo da non doverlo clonare o scaricare di nuovo.
5. Tour dell'app di esempio
L'app di esempio è un semplice derivato di Google Traduttore che chiede agli utenti di inserire un testo in inglese e di ricevere la traduzione equivalente in spagnolo. Ora apri il file main.py per vedere come funziona. Omettendo le righe commentate relative alle licenze, la parte superiore e inferiore ha questo aspetto:
from flask import Flask, render_template, request
import google.auth
from google.cloud import translate
app = Flask(__name__)
_, PROJECT_ID = google.auth.default()
TRANSLATE = translate.TranslationServiceClient()
PARENT = 'projects/{}'.format(PROJECT_ID)
SOURCE, TARGET = ('en', 'English'), ('es', 'Spanish')
# . . . [translate() function definition] . . .
if __name__ == '__main__':
import os
app.run(debug=True, threaded=True, host='0.0.0.0',
port=int(os.environ.get('PORT', 8080)))
- Le importazioni includono la funzionalità Flask, il modulo
google.authe la libreria client dell'API Cloud Translation. - Le variabili globali rappresentano l'app Flask, l'ID progetto Cloud, il client API Translation, il "percorso della posizione" principale per le chiamate all'API Translation e le lingue di origine e di destinazione. In questo caso, si tratta di inglese (
en) e spagnolo (es), ma puoi modificare questi valori con altri codici lingua supportati dall'API Cloud Translation. - Il blocco
ifdi grandi dimensioni in basso viene utilizzato nel tutorial per eseguire questa app localmente: utilizza il server di sviluppo Flask per gestire la nostra app. Questa sezione è presente anche per i tutorial sul deployment di Cloud Run nel caso in cui il server web non sia incluso nel contenitore. Ti viene chiesto di attivare il bundling del server nel container, ma se lo trascuri, il codice dell'app torna a utilizzare il server di sviluppo Flask. Non si tratta di un problema di App Engine o Cloud Functions, perché si tratta di piattaforme basate sull'origine, il che significa che Google Cloud fornisce ed esegue un web server predefinito.
Infine, al centro di main.py si trova il cuore dell'applicazione, la funzione translate():
@app.route('/', methods=['GET', 'POST'])
def translate(gcf_request=None):
"""
main handler - show form and possibly previous translation
"""
# Flask Request object passed in for Cloud Functions
# (use gcf_request for GCF but flask.request otherwise)
local_request = gcf_request if gcf_request else request
# reset all variables (GET)
text = translated = None
# if there is data to process (POST)
if local_request.method == 'POST':
text = local_request.form['text']
data = {
'contents': [text],
'parent': PARENT,
'target_language_code': TARGET[0],
}
# handle older call for backwards-compatibility
try:
rsp = TRANSLATE.translate_text(request=data)
except TypeError:
rsp = TRANSLATE.translate_text(**data)
translated = rsp.translations[0].translated_text
# create context & render template
context = {
'orig': {'text': text, 'lc': SOURCE},
'trans': {'text': translated, 'lc': TARGET},
}
return render_template('index.html', **context)
La funzione principale si occupa di prendere l'input dell'utente e chiamare l'API Translation per svolgere il lavoro più pesante. Analizziamo la questione nel dettaglio:
- Verifica se le richieste provengono da Cloud Functions utilizzando la variabile
local_request. Cloud Functions invia il proprio oggetto Flask Request, mentre tutti gli altri (in esecuzione in locale o deployment su App Engine o Cloud Run) ricevono l'oggetto richiesta direttamente da Flask. - Reimposta le variabili di base per il modulo. Questo vale principalmente per le richieste GET, poiché le richieste POST avranno dati che li sostituiranno.
- Se si tratta di un POST, prendi il testo da tradurre e crea una struttura JSON che rappresenti il requisito dei metadati dell'API. Quindi chiama l'API, tornando a una versione precedente dell'API se l'utente utilizza una libreria precedente.
- In ogni caso, formatta i risultati effettivi (POST) o nessun dato (GET) nel contesto del modello ed esegui il rendering.
La parte visiva dell'applicazione si trova nel file modello index.html. Mostra i risultati tradotti in precedenza (altrimenti vuoti), seguiti dal modulo che chiede di tradurre qualcosa:
<!doctype html>
<html><head><title>My Google Translate 1990s</title><body>
<h2>My Google Translate (1990s edition)</h2>
{% if trans['text'] %}
<h4>Previous translation</h4>
<li><b>Original</b>: {{ orig['text'] }} (<i>{{ orig['lc'][0] }}</i>)</li>
<li><b>Translated</b>: {{ trans['text'] }} (<i>{{ trans['lc'][0] }}</i>)</li>
{% endif %}
<h4>Enter <i>{{ orig['lc'][1] }}</i> text to translate to <i>{{ trans['lc'][1] }}</i>:</h4>
<form method="POST"><input name="text"><input type="submit"></form>
</body></html>
6. Installa pacchetti/dipendenze locali (in lib)
Come accennato in precedenza, l'app di esempio utilizza il micro framework web Flask e la libreria client dell'API Google Cloud Translation per Python. Installa e aggiorna pip più questa coppia di pacchetti con questo comando pip (o pip3):
pip install -t lib -r requirements.txt
Dopo aver eseguito il commento precedente, vedrai l'output dell'installazione, che potrebbe essere simile al seguente:
$ pip install -t lib -r requirements.txt
DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. pip 21.0 will drop support for Python 2.7 in January 2021. More details about Python 2 support in pip can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support pip 21.0 will remove support for this functionality.
Collecting flask>=1.1.2
Using cached Flask-1.1.4-py2.py3-none-any.whl (94 kB)
Collecting google-cloud-translate>=2.0.1
Using cached google_cloud_translate-2.0.2-py2.py3-none-any.whl (91 kB)
Collecting click<8.0,>=5.1
Using cached click-7.1.2-py2.py3-none-any.whl (82 kB)
Collecting Jinja2<3.0,>=2.10.1
Using cached Jinja2-2.11.3-py2.py3-none-any.whl (125 kB)
Collecting Werkzeug<2.0,>=0.15
Using cached Werkzeug-1.0.1-py2.py3-none-any.whl (298 kB)
Collecting itsdangerous<2.0,>=0.24
Using cached itsdangerous-1.1.0-py2.py3-none-any.whl (16 kB)
Collecting google-api-core[grpc]<2.0.0dev,>=1.15.0
Downloading google_api_core-1.29.0-py2.py3-none-any.whl (93 kB)
|████████████████████████████████| 93 kB 2.1 MB/s
Collecting google-cloud-core<2.0dev,>=1.1.0
Using cached google_cloud_core-1.6.0-py2.py3-none-any.whl (28 kB)
Collecting MarkupSafe>=0.23
Using cached MarkupSafe-1.1.1-cp27-cp27m-macosx_10_6_intel.whl (17 kB)
Collecting protobuf>=3.12.0
Downloading protobuf-3.17.2-cp27-cp27m-macosx_10_9_x86_64.whl (958 kB)
|████████████████████████████████| 958 kB 21.6 MB/s
Collecting futures>=3.2.0; python_version < "3.2"
Using cached futures-3.3.0-py2-none-any.whl (16 kB)
Collecting six>=1.13.0
Using cached six-1.16.0-py2.py3-none-any.whl (11 kB)
Collecting packaging>=14.3
Using cached packaging-20.9-py2.py3-none-any.whl (40 kB)
Collecting googleapis-common-protos<2.0dev,>=1.6.0
Using cached googleapis_common_protos-1.52.0-py2.py3-none-any.whl (100 kB)
Collecting requests<3.0.0dev,>=2.18.0
Using cached requests-2.25.1-py2.py3-none-any.whl (61 kB)
Collecting google-auth<2.0dev,>=1.25.0
Using cached google_auth-1.30.1-py2.py3-none-any.whl (146 kB)
Collecting pytz
Using cached pytz-2021.1-py2.py3-none-any.whl (510 kB)
Collecting setuptools>=40.3.0
Using cached setuptools-44.1.1-py2.py3-none-any.whl (583 kB)
Collecting grpcio<2.0dev,>=1.29.0; extra == "grpc"
Using cached grpcio-1.38.0-cp27-cp27m-macosx_10_10_x86_64.whl (3.8 MB)
Collecting pyparsing>=2.0.2
Using cached pyparsing-2.4.7-py2.py3-none-any.whl (67 kB)
Collecting chardet<5,>=3.0.2
Using cached chardet-4.0.0-py2.py3-none-any.whl (178 kB)
Collecting urllib3<1.27,>=1.21.1
Using cached urllib3-1.26.5-py2.py3-none-any.whl (138 kB)
Collecting idna<3,>=2.5
Using cached idna-2.10-py2.py3-none-any.whl (58 kB)
Collecting certifi>=2017.4.17
Downloading certifi-2021.5.30-py2.py3-none-any.whl (145 kB)
|████████████████████████████████| 145 kB 61.1 MB/s
Collecting pyasn1-modules>=0.2.1
Using cached pyasn1_modules-0.2.8-py2.py3-none-any.whl (155 kB)
Collecting rsa<4.6; python_version < "3.6"
Using cached rsa-4.5-py2.py3-none-any.whl (36 kB)
Collecting cachetools<5.0,>=2.0.0
Using cached cachetools-3.1.1-py2.py3-none-any.whl (11 kB)
Collecting enum34>=1.0.4; python_version < "3.4"
Using cached enum34-1.1.10-py2-none-any.whl (11 kB)
Collecting pyasn1<0.5.0,>=0.4.6
Using cached pyasn1-0.4.8-py2.py3-none-any.whl (77 kB)
Installing collected packages: click, MarkupSafe, Jinja2, Werkzeug, itsdangerous, flask, six, protobuf, futures, pyparsing, packaging, googleapis-common-protos, chardet, urllib3, idna, certifi, requests, pyasn1, pyasn1-modules, rsa, cachetools, setuptools, google-auth, pytz, enum34, grpcio, google-api-core, google-cloud-core, google-cloud-translate
ERROR: pip's legacy dependency resolver does not consider dependency conflicts when selecting packages. This behaviour is the source of the following dependency conflicts.
matplotlib 1.3.1 requires nose, which is not installed.
matplotlib 1.3.1 requires tornado, which is not installed.
Successfully installed Jinja2-2.11.3 MarkupSafe-1.1.1 Werkzeug-1.0.1 cachetools-3.1.1 certifi-2021.5.30 chardet-4.0.0 click-7.1.2 enum34-1.1.10 flask-1.1.4 futures-3.3.0 google-api-core-1.29.0 google-auth-1.30.1 google-cloud-core-1.6.0 google-cloud-translate-2.0.2 googleapis-common-protos-1.52.0 grpcio-1.38.0 idna-2.10 itsdangerous-1.1.0 packaging-20.9 protobuf-3.17.2 pyasn1-0.4.8 pyasn1-modules-0.2.8 pyparsing-2.4.7 pytz-2021.1 requests-2.25.1 rsa-4.5 setuptools-44.1.1 six-1.16.0 urllib3-1.26.5
7. Esegui il deployment del servizio
Per eseguire il deployment del servizio di traduzione in Python 2 App Engine, esegui questo comando:
gcloud app deploy
L'output dovrebbe essere simile al seguente e fornire alcuni suggerimenti per i passaggi successivi:
$ gcloud app deploy Services to deploy: descriptor: [/private/tmp/nebulous-serverless-python/app.yaml] source: [/private/tmp/nebulous-serverless-python] target project: [PROJECT_ID] target service: [default] target version: [20210422t161025] target url: [https://PROJECT_ID.appspot.com] Do you want to continue (Y/n)? Beginning deployment of service [default]... ╔════════════════════════════════════════════════════════════╗ ╠═ Uploading 1290 files to Google Cloud Storage ═╣ ╚════════════════════════════════════════════════════════════╝ File upload done. Updating service [default]...done. Setting traffic split for service [default]...done. Deployed service [default] to [https://PROJECT_ID.appspot.com] You can stream logs from the command line by running: $ gcloud app logs tail -s default To view your application in the web browser run: $ gcloud app browse
Ora che la tua app è disponibile a livello globale in tutto il mondo, dovresti essere in grado di raggiungerla all'URL (contenente l'ID progetto) fornito nell'output della distribuzione:

Traduci qualcosa per vedere come funziona.

8. Conclusione
Complimenti! Hai imparato ad abilitare l'API Cloud Translation, a ottenere le credenziali necessarie e a eseguire il deployment di una semplice app web in Python 2 App Engine. Puoi scoprire di più su questo deployment in questa tabella nel repository.
Esegui la pulizia
L'API Cloud Translation ti consente di eseguire una quantità fissa di caratteri tradotti al mese senza costi. Anche App Engine ha una quota senza costi, così come Cloud Functions e Cloud Run. Se uno dei due viene superato, ti verranno addebitati dei costi. Se prevedi di continuare con il codelab successivo, non devi chiudere l'app.
Tuttavia, se non sei ancora pronto per passare al tutorial successivo o temi che internet possa scoprire l'app che hai appena eseguito il deployment, disattiva l'app App Engine, elimina la tua Cloud Function o disattiva il servizio Cloud Run per evitare addebiti. Quando vuoi passare al codelab successivo, puoi riattivarlo. D'altra parte, se non intendi continuare con questa applicazione o con altri codelab e vuoi eliminare tutto completamente, puoi chiudere il progetto.
Inoltre, il deployment su una piattaforma di serverless computing di Google Cloud comporta costi minimi di build e archiviazione. Cloud Build ha una propria quota senza costi, così come Cloud Storage. Per una maggiore trasparenza, Cloud Build crea l'immagine dell'applicazione, che viene poi archiviata in Cloud Container Registry o in Artifact Registry, il suo successore. L'archiviazione di questa immagine utilizza parte della quota, così come l'uscita di rete durante il trasferimento dell'immagine al servizio. Tuttavia, potresti vivere in una regione che non dispone di un livello senza costi, quindi tieni sotto controllo l'utilizzo dello spazio di archiviazione per ridurre al minimo i potenziali costi.
9. Risorse aggiuntive
Nelle sezioni seguenti puoi trovare materiale di lettura aggiuntivo ed esercizi consigliati per approfondire le conoscenze acquisite completando questo tutorial.
Ulteriori studi
Ora che hai un po' di esperienza con l'API Translation, facciamo altri esercizi per sviluppare ulteriormente le tue competenze. Per continuare il tuo percorso di apprendimento, modifica la nostra app di esempio per eseguire le seguenti operazioni:
- Completa tutte le altre versioni di questo codelab per l'esecuzione locale o il deployment sulle piattaforme di serverless computing di Google Cloud (vedi il file README del repository).
- Completa questo tutorial utilizzando un altro linguaggio di programmazione.
- Modifica questa applicazione per supportare lingue di origine o di destinazione diverse.
- Esegui l'upgrade di questa applicazione per poter tradurre il testo in più di una lingua; modifica il file del modello in modo che contenga un menu a discesa delle lingue di destinazione supportate.
Scopri di più
Google App Engine
- Home page di App Engine
- Documentazione di App Engine
- Guida rapida di Python 3 App Engine
- Service account predefiniti per App Engine
- Runtime Python 2 App Engine (standard)
- Runtime Python 3 App Engine (standard)
- Differenze tra i runtime Python 2 e 3 di App Engine (standard)
- Guida alla migrazione da Python 2 a 3 di App Engine (standard)
Google Cloud Functions
- Home page di Cloud Functions
- Documentazione di Cloud Functions
- Guida rapida di Python Cloud Functions
- Service account predefiniti per Cloud Functions
Google Cloud Run
- Home page di Cloud Run
- Documentazione di Cloud Run
- Guida rapida di Cloud Run per Python
- Service account predefiniti per Cloud Run
Google Cloud Buildpacks, Container Registry, Artifact Registry
- Annuncio dei buildpack Cloud
- Repository Cloud Buildpacks
- Home page di Cloud Artifact Registry
- Documentazione di Cloud Artifact Registry
- Home page di Cloud Container Registry
- Documentazione di Container Registry
Google Cloud Translation e Google ML Kit
- Home page di Cloud Translation
- Documentazione di Cloud Translation
- Pagina dei prezzi dell'API Translation
- Tutte le API "building block" di Cloud AI/ML
- Google ML Kit (sottoinsieme di API Cloud AI/ML per dispositivi mobili)
- API Google ML Kit Translation
Altre pagine/altri prodotti Google Cloud
- Supporto Python di Google Cloud
- Librerie client Google Cloud
- Livello "Sempre senza costi" di Google Cloud
- Tutta la documentazione di Google Cloud
Python e Flask
Licenza
Questo tutorial è concesso in licenza ai sensi di una licenza Creative Commons Attribution 2.0 Generic, mentre il codice sorgente nel repository è concesso in licenza ai sensi di Apache 2.