Ambiente di runtime Python 2

Con App Engine, puoi creare applicazioni web utilizzando il linguaggio di programmazione Python e sfruttare i numerosi strumenti, librerie e framework per Python che gli sviluppatori professionisti utilizzano per creare applicazioni web di altissimo livello. L'applicazione Python viene eseguita nell'infrastruttura scalabile di Google e utilizza servizi e archiviazione permanente su larga scala.

Introduzione

App Engine esegue il codice dell'applicazione Python utilizzando un interprete Python precaricato in un ambiente sicuro con sandbox. La tua app riceve richieste web, esegue il lavoro e invia risposte interagendo con questo ambiente.

Un'app web Python interagisce con il server web App Engine utilizzando il protocollo WSGI, quindi le app possono utilizzare qualsiasi framework di applicazioni web compatibile con WSGI. App Engine include un semplice framework per applicazioni web, chiamato webapp2, che semplifica l'avvio. Per applicazioni più grandi, i framework di terze parti maturi, come Django, funzionano bene con App Engine.

L'interprete Python può eseguire qualsiasi codice Python, inclusi i moduli Python che includi nell'applicazione, nonché la libreria standard Python. L'interprete non è in grado di caricare i moduli Python con codice C, ma è un ambiente Python "puro".

L'ambiente "sandbox" protetto isola l'applicazione dal punto di vista del servizio e della sicurezza. Garantisce che le app possano eseguire solo azioni che non interferiscono con le prestazioni e la scalabilità di altre app. Ad esempio, un'app non può scrivere dati nel file system locale o stabilire connessioni di rete arbitrarie. Utilizzano invece i servizi scalabili forniti da App Engine per archiviare i dati e comunicare su internet. L'interprete Python segnala un'eccezione quando un'app tenta di importare un modulo Python dalla libreria standard che è noto per non funzionare entro le restrizioni della sandbox.

La piattaforma App Engine fornisce molti servizi che il codice può chiamare. L'applicazione può anche configurare attività pianificate da eseguire a intervalli specifici.

Selezione del runtime Python 2

Devi specificare l'ambiente di runtime Python nel file di configurazione app.yaml, che viene utilizzato per eseguire il deployment dell'applicazione in App Engine. Ad esempio, aggiungi quanto segue al file app.yaml per utilizzare la versione 2.7 di Python:

runtime: python27
api_version: 1
threadsafe: true
...

Il primo elemento, runtime, seleziona l'ambiente di runtime Python.

Il secondo elemento, api_version, seleziona la versione dell'ambiente di runtime Python da utilizzare. Al momento della stesura del presente documento, App Engine ha solo una versione dell'ambiente Python, 1. Se il team di App Engine ha bisogno di rilasciare modifiche all'ambiente che potrebbero non essere compatibili con il codice esistente, lo farà con un nuovo identificatore di versione. L'app continuerà a utilizzare la versione selezionata finché non modificherai l'impostazione api_version e non caricherai l'app.

Per ulteriori informazioni sul file app.yaml e su come eseguire il deployment dell'app in App Engine, consulta gli argomenti Riferimento app.yaml, Migrazione a Python 2.7 e Deployment di un'app Python.

Sabbiera

Per consentire ad App Engine di distribuire le richieste per le applicazioni su più server web e per evitare che un'applicazione interferisca con un'altra, l'applicazione viene eseguita in un ambiente "sandbox" limitato. In questo ambiente, l'applicazione può eseguire codice, archiviare ed eseguire query sui dati in Datastore, utilizzare i servizi utenti e di posta, recupero URL di App Engine, esaminare la richiesta web dell'utente e preparare la risposta.

Un'applicazione App Engine non può:

  • scrivere nel file system. Le applicazioni devono utilizzare Datastore per l'archiviazione di dati permanenti. La lettura dal file system è consentita e tutti i file dell'applicazione caricati con l'applicazione sono disponibili.

  • rispondono lentamente. Una richiesta web a un'applicazione deve essere gestita entro pochi secondi. I processi che richiedono molto tempo per rispondere vengono terminati per evitare di sovraccaricare il server web.

  • effettuare altri tipi di chiamate di sistema.

Sandboxing in Python

Puoi caricare e utilizzare file .pyc con il runtime Python 2.7, ma non puoi caricare una versione .py e .pyc dello stesso file. Puoi caricare file ZIP contenenti .py o .pyc file (o una combinazione). Se carichi file .pyc, devi rispettare una serie di importanti avvertenze:

  • Per uno script CGI, il gestore di script deve comunque utilizzare l'estensione del file .py, anche se carichi un file .pyc.
  • Per impostazione predefinita, i file .pyc vengono ignorati durante il deployment. Devi sostituire l'elemento skip_files nel file app.yaml in modo che il nuovo valore non causi l'ignoramento dei file .pyc.
  • Devi usare Python 2.7 per creare il file .pyc. Se disponi di una versione diversa di Python (ad esempio Python 2.6) sulla macchina di sviluppo, dovrai ottenere la versione 2.7 per creare un file .pyc compatibile.

Puro Python 2

Tutto il codice per l'ambiente di runtime Python deve essere Python puro e non includere estensioni C o altro codice che deve essere compilato.

L'ambiente include la libreria standard Python. Alcuni moduli sono stati disabilitati perché le loro funzioni di base non sono supportate da App Engine, come il networking o la scrittura nel file system. Inoltre, il modulo os è disponibile, ma con le funzionalità non supportate disattivate. Il tentativo di importare un modulo non supportato o di utilizzare una funzionalità non supportata genererà un'eccezione.

Alcuni moduli della libreria standard sono stati sostituiti o personalizzati per funzionare con App Engine. Questi moduli variano tra i due runtime di Python, come descritto di seguito.

Librerie personalizzate in Python versione 2.7

Nel runtime della versione 2.7 di Python, i seguenti moduli sono stati sostituiti o personalizzati:

  • tempfile è disabilitato, tranne TemporaryFile che ha un alias in StringIO.

  • logging è disponibile e il suo utilizzo è vivamente consigliato. Consulta Logging.

Oltre alla libreria standard Python e alle librerie di App Engine, il runtime Python della versione 2.7 include diverse librerie di terze parti.

Aggiunta di librerie Python di terze parti

Puoi includere librerie Python di terze parti nell'applicazione inserendo il codice nella directory dell'applicazione. Se crei un link simbolico alla directory di una libreria nella directory dell'applicazione, questo link viene seguito e la libreria viene inclusa nell'app di cui esegui il deployment in App Engine.

Il percorso di inclusione del modulo Python include la directory principale dell'applicazione, ovvero la directory contenente il file app.yaml. I moduli Python che crei nella directory radice della tua applicazione sono disponibili utilizzando un percorso dalla radice. Non dimenticare di creare i file __init__.py richiesti nelle tue sottodirectory, in modo che Python riconosca queste sottodirectory come pacchetti. Assicurati inoltre che le librerie non abbiano bisogno di estensioni C.

Thread

I thread possono essere creati in Python versione 2.7 utilizzando i moduli thread o threading. Tieni presente che i thread verranno uniti dal runtime al termine della richiesta, quindi i thread non potranno essere eseguiti dopo la fine della richiesta.

Thread in background

Il codice in esecuzione su un'istanza con scalabilità manuale o di base può avviare un thread in background che può durare più a lungo della richiesta che lo genera. Ciò consente a un'istanza di eseguire attività periodiche o pianificate arbitrarie o di continuare a lavorare in background dopo che una richiesta è stata restituita all'utente.

L'elemento os.environ e le voci di logging di un thread in background sono indipendenti da quelli del thread di generazione.

Devi importare il modulo google.appengine.api.background_thread dall'SDK per App Engine.

from google.appengine.api import background_thread

La classe BackgroundThread è simile al normale threading.Threadclass di Python, ma può "sopravvivere" alla richiesta che la genera. Esiste anche la funzione start_new_background_thread(), che crea un thread in background e lo avvia:

# sample function to run in a background thread
def change_val(arg):
    global val
    val = arg

if auto:
    # Start the new thread in one command
    background_thread.start_new_background_thread(change_val, ['Cat'])
else:
    # create a new thread and start it
    t = background_thread.BackgroundThread(
        target=change_val, args=['Cat'])
    t.start()
Il numero massimo di thread simultanei in background creati dall'API App Engine è 10 per istanza. Questo limite non si applica ai normali thread Java non correlati all'API App Engine.

Strumenti

L'SDK per App Engine include strumenti per testare l'applicazione, caricare i file dell'applicazione, gestire gli indici di Datastore, scaricare i dati di log e caricare grandi quantità di dati in Datastore.

Il server di sviluppo esegue l'applicazione sul tuo computer locale per testarla. Il server simula i servizi Datastore e le restrizioni della sandbox. Il server di sviluppo può anche generare la configurazione per gli indici Datastore in base alle query eseguite dall'app durante il test.

Lo strumento gcloud gestisce tutte le interazioni dalla riga di comando con l'applicazione in esecuzione su App Engine. Puoi utilizzare gcloud app deploy per caricare la tua applicazione in App Engine o per aggiornare singoli file di configurazione come la configurazione dell'indice di Datastore, in modo da poter creare nuovi indici prima di eseguire il deployment del codice. Puoi anche visualizzare i dati di log dell'app per analizzarne le prestazioni con gli strumenti che preferisci.

Contemporaneità e latenza

La latenza della tua applicazione ha l'impatto maggiore sul numero di istanze necessarie per gestire il tuo traffico. Se elabori le richieste rapidamente, una singola istanza può gestire molte richieste.

Le istanze a thread singolo possono gestire una richiesta in parallelo. Esiste quindi una relazione diretta tra la latenza e il numero di richieste che possono essere gestite sull'istanza al secondo. Ad esempio, una latenza di 10 ms è uguale a 100 richieste/secondi/istanza.

Le istanze multi-thread possono gestire molte richieste in parallelo. Pertanto, esiste una relazione diretta tra la CPU utilizzata e il numero di richieste al secondo.

Le app Python versione 2.7 supportano le richieste simultanee, quindi una singola istanza può gestire nuove richieste in attesa del completamento di altre richieste. La contemporaneità riduce notevolmente il numero di istanze richieste dalla tua app, ma devi progettare l'app per il multithreading.

Ad esempio, se un'istanza B4 (circa 2,4 GHz) utilizza 10 Mcicli per richiesta, è possibile elaborare 240 richieste al secondo per istanza. Se utilizza 100 Mcicli per richiesta, puoi elaborare 24 richieste al secondo per istanza. Questi numeri sono ideali ma sono abbastanza realistici in termini di ciò che puoi ottenere su un'istanza.

Variabili di ambiente

Le seguenti variabili di ambiente sono impostate dal runtime:

Variabile di ambiente Descrizione
GAE_APPLICATION L'ID della tua applicazione App Engine. Questo ID è preceduto dal prefisso "region code~", ad esempio "e~" per le applicazioni di cui è stato eseguito il deployment in Europa.
GAE_DEPLOYMENT_ID L'ID del deployment attuale.
GAE_ENV L'ambiente App Engine. Impostata su standard.
GAE_INSTANCE L'ID dell'istanza su cui è attualmente in esecuzione il servizio.
GAE_RUNTIME Il tempo di esecuzione specificato nel file app.yaml.
GAE_SERVICE Il nome del servizio specificato nel file app.yaml. Se non viene specificato alcun nome di servizio, viene impostato su default.
GAE_VERSION L'etichetta della versione corrente del servizio.
GOOGLE_CLOUD_PROJECT L'ID progetto Google Cloud associato alla tua applicazione.
PORT La porta che riceve le richieste HTTP.

Puoi definire variabili di ambiente aggiuntive nel file app.yaml, ma i valori precedenti non possono essere sostituiti.