1. Wprowadzenie

Python to popularny język programowania open source, z którego korzystają m.in. analitycy danych, deweloperzy aplikacji internetowych i administratorzy systemów.
Cloud Functions to bezserwerowa platforma obliczeniowa oparta na zdarzeniach. Cloud Functions umożliwia pisanie kodu bez martwienia się o udostępnianie zasobów czy skalowanie w celu obsługi zmieniających się wymagań.
Istnieją 2 rodzaje funkcji Cloud Functions:
- Funkcje HTTP odpowiadają na żądania HTTP. W tym ćwiczeniu utworzysz kilka takich funkcji.
- Funkcje działające w tle są aktywowane przez zdarzenia, takie jak opublikowanie wiadomości w usłudze Cloud Pub/Sub lub przesłanie pliku do Cloud Storage. Nie zajmujemy się tym w tym laboratorium, ale więcej informacji znajdziesz w dokumentacji.

W tym samouczku dowiesz się, jak tworzyć własne funkcje w Cloud Functions w Pythonie.
Co utworzysz
W tym laboratorium opublikujesz funkcję Cloud Functions, która po wywołaniu przez HTTP wyświetla logo „Python Powered”:

Czego się nauczysz
- Jak napisać funkcję HTTP w Cloud Functions.
- Jak napisać funkcję HTTP w Cloud Functions, która przyjmuje argumenty.
- Jak przetestować funkcję HTTP w Cloud Functions.
- Jak uruchomić lokalny serwer HTTP w Pythonie, aby przetestować funkcję.
- Jak napisać funkcję HTTP w Cloud Functions, która zwraca obraz.
2. Konfiguracja i wymagania
Samodzielne konfigurowanie środowiska
- Zaloguj się w konsoli Google Cloud i utwórz nowy projekt lub użyj istniejącego. Jeśli nie masz jeszcze konta Gmail ani Google Workspace, musisz je utworzyć.



- Nazwa projektu to wyświetlana nazwa uczestników tego projektu. Jest to ciąg znaków, który nie jest używany przez interfejsy API Google. Zawsze możesz ją zaktualizować.
- Identyfikator projektu jest unikalny we wszystkich projektach Google Cloud i nie można go zmienić po ustawieniu. Konsola Cloud automatycznie generuje unikalny ciąg znaków. Zwykle nie musisz się nim przejmować. W większości ćwiczeń z programowania musisz odwoływać się do identyfikatora projektu (zwykle oznaczanego jako
PROJECT_ID). Jeśli wygenerowany identyfikator Ci się nie podoba, możesz wygenerować inny losowy identyfikator. Możesz też spróbować własnej nazwy i sprawdzić, czy jest dostępna. Po tym kroku nie można go zmienić i pozostaje on taki przez cały czas trwania projektu. - Warto wiedzieć, że istnieje też trzecia wartość, numer projektu, której używają niektóre interfejsy API. Więcej informacji o tych 3 wartościach znajdziesz w dokumentacji.
- Następnie musisz włączyć płatności w konsoli Cloud, aby korzystać z zasobów i interfejsów API Google Cloud. Wykonanie tego laboratorium nie będzie kosztować dużo, a może nawet nic. Aby wyłączyć zasoby i uniknąć naliczania opłat po zakończeniu tego samouczka, możesz usunąć utworzone zasoby lub projekt. Nowi użytkownicy Google Cloud mogą skorzystać z programu bezpłatnego okresu próbnego o wartości 300 USD.
Uruchamianie Cloud Shell
Z Google Cloud można korzystać zdalnie na laptopie, ale w tym module użyjemy Cloud Shell, czyli środowiska wiersza poleceń działającego w chmurze.
Aktywowanie Cloud Shell
- W konsoli Cloud kliknij Aktywuj Cloud Shell
.

Jeśli uruchamiasz Cloud Shell po raz pierwszy, zobaczysz ekran pośredni z opisem tego środowiska. Jeśli pojawił się ekran pośredni, kliknij Dalej.

Uzyskanie dostępu do środowiska Cloud Shell i połączenie się z nim powinno zająć tylko kilka chwil.

Ta maszyna wirtualna zawiera wszystkie potrzebne narzędzia dla programistów. Zawiera również stały katalog domowy o pojemności 5 GB i działa w Google Cloud, co znacznie zwiększa wydajność sieci i usprawnia proces uwierzytelniania. Większość zadań w tym module, a być może wszystkie, możesz wykonać w przeglądarce.
Po połączeniu z Cloud Shell zobaczysz, że uwierzytelnianie zostało już przeprowadzone, a projekt jest już ustawiony na Twój identyfikator projektu.
- Aby potwierdzić, że uwierzytelnianie zostało przeprowadzone, uruchom w Cloud Shell to polecenie:
gcloud auth list
Wynik polecenia
Credentialed Accounts
ACTIVE ACCOUNT
* <my_account>@<my_domain.com>
To set the active account, run:
$ gcloud config set account `ACCOUNT`
- Aby potwierdzić, że polecenie gcloud zna Twój projekt, uruchom w Cloud Shell to polecenie:
gcloud config list project
Wynik polecenia
[core] project = <PROJECT_ID>
Jeśli nie, możesz go ustawić za pomocą tego polecenia:
gcloud config set project <PROJECT_ID>
Wynik polecenia
Updated property [core/project].
Sprawdź, czy interfejsy Cloud Functions API i Cloud Build API są włączone.
Aby sprawdzić, czy interfejsy Cloud Functions API i Cloud Build API są włączone, uruchom w Cloud Shell to polecenie:
gcloud services enable \ cloudfunctions.googleapis.com \ cloudbuild.googleapis.com
Uwaga: polecenie gcloud functions deploy wywoła Cloud Build, który automatycznie skompiluje Twój kod do obrazu kontenera.
Pobieranie kodu źródłowego
W terminalu Cloud Shell uruchom te polecenia:
REPO_NAME="codelabs" REPO_URL="https://github.com/GoogleCloudPlatform/$REPO_NAME" SOURCE_DIR="cloud-functions-python-http" git clone --no-checkout --filter=blob:none --depth=1 $REPO_URL cd $REPO_NAME git sparse-checkout set $SOURCE_DIR git checkout cd $SOURCE_DIR
Sprawdź zawartość katalogu źródłowego:
ls
Powinny pojawić się te pliki:
main.py python-powered.png test_main.py web_app.py
3. Przedstawiamy funkcje HTTP Cloud Functions
Funkcje HTTP w Cloud Functions w Pythonie są pisane jako zwykłe funkcje Pythona. Funkcja musi przyjmować jeden argument flask.Request, który zwykle ma nazwę request.
main.py
import flask
def hello_world(request: flask.Request) -> flask.Response:
"""HTTP Cloud Function.
Returns:
- "Hello World! 👋"
"""
response = "Hello World! 👋"
return flask.Response(response, mimetype="text/plain")
# ...
Możesz otworzyć plik w wybranym edytorze wiersza poleceń (nano, vim lub emacs). Możesz też otworzyć go w edytorze Cloud Shell po ustawieniu katalogu źródłowego jako obszaru roboczego:
cloudshell open-workspace .
Wdróżmy tę funkcję jako funkcję HTTP w Cloud Functions za pomocą polecenia gcloud functions deploy:
FUNCTION_NAME="hello_world" gcloud functions deploy $FUNCTION_NAME \ --runtime python312 \ --trigger-http \ --allow-unauthenticated
Wynik polecenia:
... Deploying function (may take a while - up to 2 minutes)...done. availableMemoryMb: 256 ... entryPoint: FUNCTION_NAME httpsTrigger: url: https://REGION-PROJECT_ID.cloudfunctions.net/FUNCTION_NAME ...
Uwagi dotyczące opcji gcloud functions deploy:
--runtime: Określa środowisko wykonawcze języka. W przypadku Pythona może to być obecniepython37,python38,python39,python310lubpython312. Zobacz Środowiska wykonawcze.--trigger-http: Funkcja zostanie przypisana do punktu końcowego. Żądania HTTP (POST, PUT, GET, DELETE i OPTIONS) wysyłane do punktu końcowego będą wywoływać wykonanie funkcji.--allow-unauthenticated: funkcja będzie publiczna, co oznacza, że będzie dostępna dla wszystkich wywołujących bez sprawdzania uwierzytelniania.- Więcej informacji znajdziesz w artykule gcloud functions deploy.
Aby przetestować funkcję, możesz kliknąć adres URL httpsTrigger.url wyświetlany w wyniku polecenia powyżej. Adres URL możesz też pobrać programowo i wywołać funkcję za pomocą tych poleceń:
URL=$(gcloud functions describe $FUNCTION_NAME --format "value(httpsTrigger.url)") curl -w "\n" $URL
Powinien pojawić się następujący wynik:
Hello World! 👋
4. Pisanie funkcji HTTP w Cloud Functions, która przyjmuje argumenty
Funkcje są bardziej wszechstronne, gdy akceptują argumenty. Zdefiniujmy nową funkcję hello_name, która obsługuje parametr name:
main.py
# ...
def hello_name(request: flask.Request) -> flask.Response:
"""HTTP Cloud Function.
Returns:
- "Hello {NAME}! 🚀" if "name=NAME" is defined in the GET request
- "Hello World! 🚀" otherwise
"""
name = request.args.get("name", "World")
response = f"Hello {name}! 🚀"
return flask.Response(response, mimetype="text/plain")
# ...
Wdróżmy tę nową funkcję:
FUNCTION_NAME="hello_name" gcloud functions deploy $FUNCTION_NAME \ --runtime python312 \ --trigger-http \ --allow-unauthenticated
Wynik polecenia:
... Deploying function (may take a while - up to 2 minutes)...done. availableMemoryMb: 256 ... entryPoint: FUNCTION_NAME httpsTrigger: url: https://REGION-PROJECT_ID.cloudfunctions.net/FUNCTION_NAME ...
Aby przetestować funkcję, możesz kliknąć adres URL httpsTrigger.url wyświetlany w wyniku polecenia powyżej. Adres URL możesz też pobrać programowo i wywołać funkcję za pomocą tych poleceń:
URL=$(gcloud functions describe $FUNCTION_NAME --format "value(httpsTrigger.url)") curl -w "\n" $URL
Powinien pojawić się domyślny wynik:
Hello World! 🚀
Otrzymujesz domyślny wynik, ponieważ argument name nie jest ustawiony. Dodaj parametr do adresu URL:
curl -w "\n" $URL?name=YOUR%20NAME
Tym razem otrzymasz niestandardową odpowiedź:
Hello YOUR NAME! 🚀
Następnym krokiem jest dodanie testów jednostkowych, aby mieć pewność, że funkcje będą działać zgodnie z przeznaczeniem po zaktualizowaniu kodu źródłowego.
5. Testy pisemne
Funkcje HTTP w Cloud Functions w Pythonie są testowane za pomocą modułu unittest z biblioteki standardowej. Aby przetestować funkcję, nie musisz uruchamiać emulatora ani innej symulacji – wystarczy zwykły kod w Pythonie.
Oto jak wygląda test funkcji hello_world i hello_name:
test_main.py
import unittest
import unittest.mock
import main
class TestHello(unittest.TestCase):
def test_hello_world(self):
request = unittest.mock.Mock()
response = main.hello_world(request)
assert response.status_code == 200
assert response.get_data(as_text=True) == "Hello World! 👋"
def test_hello_name_no_name(self):
request = unittest.mock.Mock(args={})
response = main.hello_name(request)
assert response.status_code == 200
assert response.get_data(as_text=True) == "Hello World! 🚀"
def test_hello_name_with_name(self):
name = "FirstName LastName"
request = unittest.mock.Mock(args={"name": name})
response = main.hello_name(request)
assert response.status_code == 200
assert response.get_data(as_text=True) == f"Hello {name}! 🚀"
- Testy w Pythonie są pisane w taki sam sposób jak inne pliki w tym języku. Zaczynają się od zestawu importów, a następnie definiują klasy i funkcje.
- Deklaracja testu ma postać
class TestHello(TestCase). Musi to być klasa dziedzicząca po klasieunittest.TestCase. - Klasa testowa zawiera metody, z których każda musi zaczynać się od
test_i reprezentować pojedynczy element testowania. - Każdy przypadek testowy sprawdza jedną z naszych funkcji, symulując parametr
request(czyli zastępując go fałszywym obiektem z danymi wymaganymi do testu). - Po wywołaniu każdej funkcji test sprawdza odpowiedź HTTP, aby upewnić się, że jest zgodna z oczekiwaniami.
Ponieważ main.py zależy od flask, upewnij się, że w środowisku testowym jest zainstalowany framework Flask:
pip install flask
Instalacja Flaska daje wynik podobny do tego:
Collecting flask ... Successfully installed ... flask-3.0.2 ...
Przeprowadź te testy lokalnie:
python -m unittest
Trzy testy jednostkowe powinny zakończyć się powodzeniem:
... ---------------------------------------------------------------------- Ran 3 tests in 0.001s OK
Następnie utworzysz nową funkcję, która zwraca logo „Python Powered”.
6. Pisanie funkcji HTTP w Cloud Functions „Python Powered”
Sprawmy, aby nowa funkcja była nieco bardziej rozrywkowa, zwracając obraz „Python Powered” w przypadku każdego żądania:

Poniżej znajdziesz kod, który to umożliwia:
main.py
# ...
def python_powered(request: flask.Request) -> flask.Response:
"""HTTP Cloud Function.
Returns:
- The official "Python Powered" logo
"""
return flask.send_file("python-powered.png")
Wdróż nową funkcję python_powered:
FUNCTION_NAME="python_powered" gcloud functions deploy $FUNCTION_NAME \ --runtime python312 \ --trigger-http \ --allow-unauthenticated
Wynik polecenia:
... Deploying function (may take a while - up to 2 minutes)...done. availableMemoryMb: 256 ... entryPoint: FUNCTION_NAME httpsTrigger: url: https://REGION-PROJECT_ID.cloudfunctions.net/FUNCTION_NAME ...
Aby przetestować funkcję, kliknij adres URL httpsTrigger.url wyświetlany w wyniku polecenia powyżej. Jeśli wszystko działa prawidłowo, w nowej karcie przeglądarki zobaczysz logo „Python Powered”.
Następnie utworzysz aplikację, aby móc uruchomić i wypróbować funkcję lokalnie przed wdrożeniem.
7. Lokalne uruchamianie funkcji
Funkcję HTTP możesz uruchomić lokalnie, tworząc aplikację internetową i wywołując funkcję w ścieżce. Możesz go dodać w tym samym katalogu co funkcja. Plik o nazwie web_app.py zawiera te treści:
web_app.py
import flask
import main
app = flask.Flask(__name__)
@app.get("/")
def index():
return main.python_powered(flask.request)
if __name__ == "__main__":
# Local development only
# Run "python web_app.py" and open http://localhost:8080
app.run(host="localhost", port=8080, debug=True)
- Ten plik tworzy aplikację Flask.
- Rejestruje ona ścieżkę w podstawowym adresie URL, która jest obsługiwana przez funkcję o nazwie
index(). - Funkcja
index()wywołuje następnie funkcjępython_powered, przekazując jej bieżące żądanie.
Sprawdź, czy w środowisku programistycznym jest zainstalowany framework Flask:
pip install flask
Instalacja Flaska daje wynik podobny do tego:
Collecting flask ... Successfully installed ... flask-3.0.2 ...
Aby uruchomić tę aplikację lokalnie, wpisz to polecenie:
python web_app.py
Teraz użyj podglądu Cloud Shell w przeglądarce, aby przetestować aplikację internetową. W Cloud Shell kliknij przycisk „Podgląd w przeglądarce” i wybierz „Podejrzyj na porcie 8080”:

Cloud Shell otworzy adres URL umożliwiający podgląd w nowym oknie przeglądarki, korzystając z własnej usługi pośredniczącej. Podgląd w przeglądarce ogranicza dostęp przez HTTPS tylko do Twojego konta użytkownika. Jeśli wszystko działa prawidłowo, zobaczysz logo „Python Powered”.

8. Gratulacje!

Wdrożono funkcje HTTP Cloud Functions, używając idiomatycznych funkcji, które obsługują żądania sieciowe za pomocą platformy Flask.
Cennik Cloud Functions zależy od tego, jak często wywoływana jest funkcja, i obejmuje poziom bezpłatny dla funkcji, które nie są często uruchamiane. Po zakończeniu testowania funkcji w Cloud Functions możesz je usunąć, wykonując te czynności:gcloud
gcloud functions delete hello_world --quiet gcloud functions delete hello_name --quiet gcloud functions delete python_powered --quiet
Funkcje możesz też usunąć z konsoli Google Cloud.
Mamy nadzieję, że dobrze Ci się pracuje z Cloud Functions w Pythonie.