本頁面說明如何搭配標準環境的 Python 3 執行階段,安裝及使用舊版套裝服務。應用程式必須透過 Python 3 適用的 App Engine 服務 SDK 存取套裝組合服務。
事前準備
- 請參閱可透過 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 2 環境中重構以 Python 3 環境編寫的 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
轉譯為 Unicode,方法是將 Python 3 string
解譯為 ASCII。如果值超出 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
範圍以外的實際 Unicode 資料 (例如從檔案讀取的資料),cPickle 就無法正確對應資料。因此,請務必更新 Python 2 程式碼,以保留含有 unicode
物件的 Unicode 資料,而非 string
物件,以供您 Pickle 的物件使用。如需必要更新的詳細資料,請參閱相容性指南。
先前說明的方法是將 Python 2 程式碼更新為產生與 Python 3 相容的序列化,適用於短期序列化,例如儲存在 Memcache 中的序列化。您可能需要更新或重寫長期存在的 Python 2 序列化,例如儲存在 Datastore 中的序列化 (這是遷移作業的一部分)。舉例來說,使用 google.appengine.ext.ndb.model.PickleProperty
撰寫的序列化可能需要升級。
如要進一步瞭解限制和較不常見的問題,請參閱相容性指南。
網路架構
Python 3 不會隨附或支援 webapp2
,因此任何應用程式都必須重新編寫,才能使用任何與 WSGI 相容的架構 (例如 Flask)。
建議的遷移策略是先在 Python 2.7 應用程式中,將 webapp2
的使用方式替換為 Flask (或替代的網路架構,例如 Django、Pyramid、Bottle 或 web.py),同時維持使用 Python 2.7。接著,在更新後的應用程式穩定運作後,將程式碼遷移至 Python 3,並使用 Python 3 適用的 App Engine 部署及測試。
如需將使用 webapp2
的 Python 2.7 應用程式轉換為使用 Flask 架構的範例,請參閱這些額外資源。
使用處理常式
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、Deferred 和 Mail 總覽。
執行緒安全
系統會假設應用程式具備執行緒安全特性。API 呼叫必須在要求執行緒上進行。如果應用程式啟動時使用舊版套裝服務 API,可能會導致安全性錯誤。
詳情請參閱「使用 Python 舊版套裝服務時發生安全性錯誤」。
使用網址擷取
如要使用 Python 適用的網址擷取服務,您必須明確呼叫網址擷取程式庫。
如果 Python 3 應用程式使用 URL Fetch API,當應用程式傳送要求至其他 App Engine 應用程式時,系統會加入 X-Appengine-Inbound-Appid
要求標頭。接收端應用程式可藉此驗證呼叫端應用程式的身分。詳情請參閱「遷移外送要求」。
範例 (App Engine ndb
)
以下是基本的 Python 2 應用程式,使用 App Engine ndb
存取 Datastore,記錄網頁造訪次數。這個應用程式的對應版本是 Python 3 應用程式,其中 webapp2
用途已由 Flask 取代,且已實作上述必要變更,以便在 Python 3 中存取隨附服務。
Python 2 (webapp2
)
Python 3 (Flask)
這兩款應用程式都位於 Python App Engine 遷移內容的開放原始碼存放區 (程式碼範例、影片、codelabs),分別位於 mod0
和 mod1b
資料夾中。