Memigrasikan permintaan keluar

Secara default, runtime Python 2.7 menggunakan layanan URL-fetch untuk menangani permintaan HTTP(S) keluar, bahkan jika Anda menggunakan urllib, urllib2 , atauhttplib library Python untuk mengeluarkan permintaan tersebut. URL Fetch tidak menangani permintaan dari library requests kecuali jika Anda secara eksplisit mengaktifkannya.

Runtime Python 3 tidak memerlukan layanan perantara untuk menangani permintaan keluar. Jika Anda ingin berhenti menggunakan URL Fetch API tetapi masih memerlukan fungsi yang serupa, Anda harus memigrasikan permintaan tersebut untuk menggunakan library Python standar seperti library requests.

Perbedaan utama antara URL Fetch dan library Python standar

  • Batas ukuran danquotas untuk permintaan yang ditangani oleh URL Fetch berbeda dengan batas ukuran danquotas untuk permintaan yang tidak ditangani oleh URL Fetch

  • Dengan URL Fetch, saat aplikasi Anda mengirimkan permintaan ke aplikasi App Engine lain, URL Fetch akan menambahkan header permintaan X-Appengine-Inbound-Appid untuk menegaskan identitas aplikasi. Aplikasi yang menerima permintaan tersebut dapat menggunakan identitas untuk menentukan apakah aplikasi harus memproses permintaan tersebut atau tidak.

    Header ini hanya tersedia dalam permintaan yang dikirim dari aplikasi Anda jika menggunakan URL Fetch. App Engine menghapus header jika Anda atau pihak ketiga menambahkannya ke permintaan.

    Untuk mengetahui informasi tentang cara menyatakan dan memverifikasi identitas tanpa menggunakan URL Fetch, baca Memigrasikan Identitas Aplikasi ke Token ID OIDC.

    Untuk mengetahui contoh cara menggunakan header permintaan guna memverifikasi identitas aplikasi panggilan saat permintaan dikirim antaraplikasi App Engine, lihat Contoh Permintaan App Engine ke App Engine.

  • Anda dapat menggunakan URL Fetch untuk menetapkan waktu tunggu default untuk semua permintaan. Sebagian besar library Python 3 seperti requests dan urllib menetapkan waktu tunggu default ke None, sehingga Anda harus mengupdate setiap permintaan yang dibuat oleh kode Anda untuk menentukan waktu tunggu.

Ringkasan proses migrasi

  1. Jika aplikasi Anda menggunakan URL Fetch API untuk membuat permintaan, update kode Anda agar menggunakan library Python standar. Sebaiknya tentukan waktu tunggu untuk setiap permintaan.

  2. Uji permintaan keluar Anda di server pengembangan lokal.

  3. Konfigurasikan aplikasi Anda agar mengabaikan URL Fetch saat dijalankan di App Engine.

  4. Men-deploy aplikasi Anda.

Mengganti URL Fetch API dengan library Python

  1. Jika Anda belum menggunakan library Python standar untuk mengeluarkan permintaan keluar, pilih library dan tambahkan ke dependensi aplikasi Anda.

    Misalnya, untuk menggunakan Meminta library, buat file requirements.txt di folder yang sama dengan file app.yaml Anda, lalu tambahkan baris berikut:

    requests==2.24.0
    

    Untuk kompatibilitas dengan Python 2, sebaiknya Anda menyematkan library requests ke versi 2.24.0. Saat Anda men-deploy aplikasi, App Engine akan mendownload semua dependensi yang ditentukan dalam file requirements.txt.

    Untuk pengembangan lokal, sebaiknya instal dependensi di lingkungan virtual seperti venv.

  2. Telusuri kode Anda untuk menemukan penggunaan modul google.appengine.api.urlfetch , lalu update kode untuk menggunakan library Python Anda.

Membuat permintaan HTTPS sederhana

Contoh berikut menunjukkan cara membuat permintaan HTTP standar menggunakan library requests:

# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import logging

from flask import Flask

import requests

app = Flask(__name__)

@app.route("/")
def index():
    url = "http://www.google.com/humans.txt"
    response = requests.get(url)
    response.raise_for_status()
    return response.text

@app.errorhandler(500)
def server_error(e):
    logging.exception("An error occurred during a request.")
    return (
        """
    An internal error occurred: <pre>{}</pre>
    See logs for full stacktrace.
    """.format(
            e
        ),
        500,
    )

if __name__ == "__main__":
    # This is used when running locally.
    app.run(host="127.0.0.1", port=8080, debug=True)

Membuat permintaan HTTPS asinkron

Contoh berikut menunjukkan cara membuat permintaan HTTPS asinkron menggunakan library requests:

# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import logging

from flask import Flask, make_response

from requests_futures.sessions import FuturesSession
from time import sleep

TIMEOUT = 10  # Wait this many seconds for background calls to finish
app = Flask(__name__)

@app.route("/")  # Fetch and return remote page asynchronously
def get_async():
    session = FuturesSession()
    url = "http://www.google.com/humans.txt"

    rpc = session.get(url)

    # ... do other things ...

    resp = make_response(rpc.result().text)
    resp.headers["Content-type"] = "text/plain"
    return resp

@app.route("/callback")  # Fetch and return remote pages using callback
def get_callback():
    global response_text
    global counter

    response_text = ""
    counter = 0

    def cb(resp, *args, **kwargs):
        global response_text
        global counter

        if 300 <= resp.status_code < 400:
            return  # ignore intermediate redirection responses

        counter += 1
        response_text += "Response number {} is {} bytes from {}\n".format(
            counter, len(resp.text), resp.url
        )

    session = FuturesSession()
    urls = [
        "https://google.com/",
        "https://www.google.com/humans.txt",
        "https://www.github.com",
        "https://www.travis-ci.org",
    ]

    futures = [session.get(url, hooks={"response": cb}) for url in urls]

    # No wait functionality in requests_futures, so check every second to
    # see if all callbacks are done, up to TIMEOUT seconds
    for elapsed_time in range(TIMEOUT + 1):
        all_done = True
        for future in futures:
            if not future.done():
                all_done = False
                break
        if all_done:
            break
        sleep(1)

    resp = make_response(response_text)
    resp.headers["Content-type"] = "text/plain"
    return resp

@app.errorhandler(500)
def server_error(e):
    logging.exception("An error occurred during a request.")
    return (
        """
    An internal error occurred: <pre>{}</pre>
    See logs for full stacktrace.
    """.format(
            e
        ),
        500,
    )

Menguji secara lokal

Jika Anda mengupdate permintaan keluar, jalankan aplikasi Anda di server pengembangan lokal dan konfirmasi bahwa permintaan berhasil.

Mengabaikan URL Fetch

Agar URL Fetch tidak menangani permintaan saat Anda men-deploy aplikasi ke App Engine:

  1. Di file app.yaml, tetapkan variabel lingkungan GAE_USE_SOCKETS_HTTPLIB ke nilai apa pun. Nilainya dapat berupa nilai apa pun, termasuk string kosong. Contoh:

    env_variables:
      GAE_USE_SOCKETS_HTTPLIB : ''
    
  2. Jika Anda mengaktifkan URL Fetch untuk menangani permintaan yang dikirim dari library requests, Anda dapat menghapus Permintaan AppEngineAdapter dari aplikasi.

    Misalnya, hapus requests_toolbelt.adapters.appengine dari file appengine_config.py dan requests_toolbelt.adapters.appengine.monkeypatch() dari file Python Anda.

Perlu diketahui bahwa meskipun Anda mengabaikan URL Fetch seperti yang dijelaskan dalam langkah sebelumnya, aplikasi masih dapat menggunakan URL Fetch API secara langsung.

Men-deploy aplikasi Anda

Setelah siap men-deploy aplikasi, Anda harus:

  1. Uji aplikasi di App Engine.

    Lihat halaman App Engine Quotas di konsol Google Cloud untuk mengonfirmasi bahwa aplikasi Anda tidak melakukan Panggilan Url Fetch API.

    Melihat Panggilan URL Fetch API

  2. Jika aplikasi berjalan tanpa error, gunakan pemisahan traffic untuk meningkatkan traffic aplikasi yang diupdate secara perlahan. Pantau aplikasi dengan cermat untuk menemukan masalah sebelum memilih rute lebih banyak traffic ke aplikasi yang telah diupdate.