本頁面說明如何在標準環境中,使用 Python 3 執行階段安裝及使用舊版套裝服務。您的應用程式必須透過 Python 3 專用的 App Engine 服務 SDK 存取套裝組合服務。
事前準備
- 請參閱舊版服務套裝組合 API 清單,瞭解您可以在 Python 執行階段呼叫哪些 API。
- 開始將專案遷移至 Python 3 前,請參閱執行階段遷移總覽和使用舊版套裝組合服務時的遷移考量。
安裝 App Engine 服務 SDK
如要安裝 App Engine 服務 SDK,請按照下列步驟操作:
在
requirements.txt
檔案中加入下列程式碼,即可將 SDK 納入應用程式:appengine-python-standard>=1.0.0
您可以在 GitHub 的
appengine-python-standard
存放區和 PyPI 中找到 SDK。在主要 Python 指令碼中加入下列程式碼。這段程式碼會建立 WSGI 中介軟體,設定啟用 API 呼叫所需的變數。
Flask
from flask import Flask from google.appengine.api import wrap_wsgi_app app = Flask(__name__) app.wsgi_app = wrap_wsgi_app(app.wsgi_app)
Django
from DJANGO_PROJECT_NAME.wsgi import application from google.appengine.api import wrap_wsgi_app app = wrap_wsgi_app(application)
金字塔
from pyramid.config import Configurator from google.appengine.api import wrap_wsgi_app config = Configurator() # make configuration settings app = config.make_wsgi_app() app = wrap_wsgi_app(app)
WSGI
import google.appengine.api def app(environ, start_response): start_response('200 OK', [('Content-Type', 'text/plain')]) yield b'Hello world!\n' app = google.appengine.api.wrap_wsgi_app(app)
在部署應用程式前,請將下列程式碼新增至
app.yaml
檔案:app_engine_apis: true
如要部署應用程式,請使用
gcloud app deploy
指令。
遷移注意事項
如果您要遷移至 Python 3 執行階段,且應用程式使用舊版套裝服務,請注意下列考量事項。
測試
如要在本機測試 Python 3 應用程式中的舊版套裝服務功能,請使用本機開發伺服器。執行 dev_appserver.py
指令時,您必須設定 --runtime_python_path
引數,以便加入 Python 3 解譯器的路徑。例如:
python3 CLOUD_SDK_ROOT/bin/dev_appserver.py --runtime_python_path=/usr/bin/python3
您也可以將引數設為以半形逗號分隔的 [RUNTIME_ID]=[PYTHON_INTERPRETER_PATH]
組合清單。例如:
python3 CLOUD_SDK_ROOT/bin/dev_appserver.py --runtime_python_path="python27=/user/bin/python2.7,python3=/usr/bin/python3"
Pickle 相容性
共用服務 (包括 Memcache、Cloud NDB 和延遲) 會使用 pickle 模組來序列化和共用 Python 物件。如果您的 App Engine 環境同時使用 Python 2 和 Python 3 (這是遷移期間常見的情況),您必須確保由一個 Python 版本編寫的共用序列化物件可由另一個版本重建。如要瞭解如何實作跨版本的 pickle 相容性,請參閱指南。
根據預設,Python 3 會使用 Python 2 不支援的醃製通訊協定。當應用程式嘗試在以 Python 3 環境編寫的 Python 2 環境中重建 Python 物件時,可能會發生失敗。為避免發生這個問題,請視需要在 Python 3 應用程式的 app.yaml
檔案中設定下列環境變數:
- 針對使用 Memcache 的應用程式 (包括使用 NDB 的應用程式),請設定:
MEMCACHE_USE_CROSS_COMPATIBLE_PROTOCOL: 'True'
- 針對使用 NDB 連線至 Datastore 的應用程式,請設定:
NDB_USE_CROSS_COMPATIBLE_PICKLE_PROTOCOL: 'True'
- 如果應用程式使用延後處理,請設定:
DEFERRED_USE_CROSS_COMPATIBLE_PICKLE_PROTOCOL: 'True'
在 Python 2 中,string
物件會保留 8 位元位元組值的序列。在 Python 3 中,string
物件會保留一系列的 Unicode 字元。根據預設,Python 3 pickle 會將 Python 2 string
解讀為 ASCII,進而將其轉譯為 Unicode。string
這可能會導致值超出 ASCII 字元範圍 0 到 127 的錯誤。Memcache 支援覆寫此預設對應項目。
from google.appengine.api import memcache
import six.moves.cPickle as pickle
def _unpickle_factory(file):
return pickle.Unpickler(file, encoding='latin1')
memcache.setup_client(memcache.Client(unpickler=_unpickle_factory))
latin1
編碼會為 Python 2 string
中每個位元組的 256 個可能值定義對應關係。這麼做可避免解碼錯誤。不過,如果 Python 2 string
包含 latin1
範圍以外的實際萬用字元資料 (例如從檔案讀取的資料),cPickle 就無法正確對應資料。因此,請務必更新 Python 2 程式碼,以便使用 unicode
物件 (而非 string
物件) 儲存您要醃製的物件。相容性指南會詳細說明所需的更新。
先前所述的更新 Python 2 程式碼方法,可產生與 Python 3 相容的序列化,解決短暫序列化問題,例如儲存在 Memcache 中的序列化。您可能需要更新或重寫長期存在的 Python 2 序列化作業,例如在遷移作業中儲存在 Datastore 中的序列化作業。舉例來說,使用 google.appengine.ext.ndb.model.PickleProperty
編寫的序列化作業可能需要升級。
請參閱相容性指南,進一步瞭解限制和較不常見的問題。
網路架構
webapp2
並未在 Python 3 中隨附或支援,因此任何應用程式都必須重新編寫,才能使用任何與 WSGI 相容的架構 (例如 Flask)。
建議的遷移策略是先將 Python 2.7 應用程式中的 webapp2
使用方式替換為 Flask (或其他網路架構,例如 Django、Pyramid、Bottle 或 web.py),同時保留 Python 2.7。接著,在更新後的應用程式穩定後,將程式碼遷移至 Python 3,並使用 App Engine for Python 3 部署及測試。
如需使用 webapp2
轉換使用 Flask 架構的 Python 2.7 應用程式範例,請參閱這些額外資源。
使用處理常式
Python 3 應用程式只能與一個指令碼相關聯,因此如果您的 app.yaml
有多個 script
處理常式,將網址對應至不同的指令碼,您就需要將這些指令碼合併為一個處理網址路由的指令碼。
以下範例顯示 app.yaml
檔案中各個執行階段的處理常式差異。
Python 2
runtime: python27 api_version: 1 threadsafe: true handlers: - url: / script: home.app - url: /index\.html script: home.app - url: /stylesheets static_dir: stylesheets - url: /(.*\.(gif|png|jpg))$ static_files: static/\1 upload: static/.*\.(gif|png|jpg)$ - url: /admin/.* script: admin.app login: admin - url: /.* script: not_found.app
Python 3
runtime: python313
app_engine_apis: true
handlers:
- url: /stylesheets
static_dir: stylesheets
- url: /(.*\.(gif|png|jpg))$
static_files: static/\1
upload: static/.*\.(gif|png|jpg)$
- url: /admin/.*
script: auto
login: admin
Python 3 應用程式必須處理網址路由 (例如使用 Flask 裝飾函式)。
如果您想使用多個 script
處理常式,或在處理常式中使用其他屬性,則每個處理常式都必須指定 script: auto
。
您也可以在 app.yaml
檔案中指定 entrypoint
欄位,藉此覆寫預設的啟動行為。
如要進一步瞭解如何使用特定處理常式,請參閱 Blobstore、延遲和 Mail 的總覽。
執行緒安全性
系統會假設應用程式具備執行緒安全性。必須在要求執行緒上發出 API 呼叫。如果您在應用程式啟動時使用舊版內含服務 API,可能會導致安全性錯誤。
如需更多資訊,請參閱「使用 Python 的舊版套裝服務時發生安全性錯誤」。
使用網址擷取
如要使用 Python 適用的網址擷取功能,您必須明確呼叫網址擷取程式庫。
如果 Python 3 應用程式使用網址擷取 API,當應用程式向其他 App Engine 應用程式傳送要求時,系統會新增 X-Appengine-Inbound-Appid
要求標頭,讓接收應用程式驗證呼叫應用程式的身分。詳情請參閱「遷移外送要求」。
範例 (App Engine ndb
)
以下是使用 App Engine ndb
存取 Datastore 的 Python 2 應用程式,用於註冊網頁瀏覽次數。其伴隨應用程式是 Python 3 等同應用程式,其中 webapp2
用法已由 Flask 取代,且已實作上述在 Python 3 中存取套件服務所需的變更。
Python 2 (webapp2
)
Python 3 (Flask)
這兩個應用程式皆可在 Python App Engine 遷移內容的開放原始碼存放區中找到 (程式碼範例、影片、codelabs),具體來說,分別位於 mod0
和 mod1b
資料夾中。