Облачная функция в Google Cloud работает при тестировании, но не после развертывания

Я новичок в облачных платформах. Я пытаюсь создать облачную функцию в облаке Google с триггером HTTP, где, учитывая URL-адрес изображения в качестве аргумента, он должен загрузить его и получить результаты модели классификации изображений, которую я ранее обучил в Tensorflow, и это Я сохранил в корзину вместе с текстовым файлом, содержащим возможные выходные данные модели. Модель работает нормально и точно так же, как я хочу, когда я использую функцию тестирования в интерфейсе Google Cloud, как вы можете видеть здесь:

Однако после фактического развертывания облачной функции я не могу заставить ее работать должным образом при использовании браузера... Всегда выдается внутренняя ошибка 500, если я пишу что-то подобное, например, в адресную строку. моего браузера: https://myprojectandfunction.net/function-1?url=https://www.zooplus.pt/magazine/wp-content/uploads/2021/10/gatos_apartamento_1.jpeg (это не настоящая облачная функция URL, просто пример)

Несмотря на это, использование функции тестирования в интерфейсе Google Cloud по-прежнему работает должным образом даже после развертывания, когда я использую аргументы на изображении выше {'url': 'www.someimage.com'}

Код облачной функции следующий:

import functions_framework

import requests
import os
from PIL import Image
import tensorflow as tf
import numpy as np

from google.cloud import storage

client = storage.Client()
bucket_url = 'justsomebucketname'
model_file = 'model.tflite'
label_file = 'dict.txt'

bucket = client.get_bucket(bucket_url)
blob_model = bucket.blob(model_file)
blob_label = bucket.blob(label_file)
blob_model.download_to_filename("model.tflite")
blob_label.download_to_filename("dict.txt") # Getting the model and labels I will need from my bucket

# This class is just the model I need for classification
class Model:

    def __init__(self, model_file, dict_file):
        with open(dict_file, 'r') as f:
            self.labels = [line.strip().replace('_', ' ') for line in f.readlines()]
        self.interpreter = tf.lite.Interpreter(model_path=model_file)
        self.interpreter.allocate_tensors()
        self.input_details = self.interpreter.get_input_details()
        self.output_details = self.interpreter.get_output_details()
        self.floating_model = self.input_details[0]['dtype'] == np.float32
        self.height = self.input_details[0]['shape'][1]
        self.width = self.input_details[0]['shape'][2]

    def classify(self, file, min_confidence):
        with Image.open(file).convert('RGB').resize((self.width, self.height)) as img:
            input_data = np.expand_dims(img, axis=0)
            if self.floating_model:
                input_data = (np.float32(input_data) - 127.5) / 127.5
            self.interpreter.set_tensor(self.input_details[0]['index'], input_data)
            self.interpreter.invoke()
            output_data = self.interpreter.get_tensor(self.output_details[0]['index'])
            model_results = np.squeeze(output_data)
            top_categories = model_results.argsort()[::-1]
            results = []
            for i in top_categories:
                if self.floating_model:
                    confidence = float(model_results[i])
                else:
                    confidence = float(model_results[i] / 255.0)
                if min_confidence != None and confidence < min_confidence:
                    break
                results.append(dict(label=self.labels[i], confidence='%.2f'%confidence))
            return results

# Here I just edited the basic template for HTTP cloud functions, given by google cloud
@functions_framework.http
def hello_http(request):
    """HTTP Cloud Function.
    Args:
        request (flask.Request): The request object.
        <https://flask.palletsprojects.com/en/1.1.x/api/#incoming-request-data>
    Returns:
        The response text, or any set of values that can be turned into a
        Response object using `make_response`
        <https://flask.palletsprojects.com/en/1.1.x/api/#flask.make_response>.
    """
    request_json = request.get_json(silent=True)
    request_args = request.args

    if request_json and 'url' in request_json:
        url = request_json['url'] # extract the url from the request
        response = requests.get(url) # get the image data from the url
        with open('image.jpg', 'wb') as imagem:
          imagem.write(response.content) # create a jpg file with the data
        tf_classifier = Model(model_file, label_file) # instantiate the classifier
        results = tf_classifier.classify('image.jpg', min_confidence=0.01) # get the model results
        string = "According to the model, your image corresponds to, in descending order of confidence:\n"
        for r in results:
          string += f"\t {r['label']}, with a confidence of {r['confidence']};\n" # Generate a sentence that summarizes the classification results
    elif request_args and 'url' in request_args:
        url = request_json['url']
        response = requests.get(url)
        with open('image.jpg', 'wb') as imagem:
          imagem.write(response.content)
        tf_classifier = Model(model_file, label_file)
        results = tf_classifier.classify('image.jpg', min_confidence=0.01)
        string = "According to the model, your image corresponds to, in descending order of confidence:\n"
        for r in results:
          string += f"\t {r['label']}, with a confidence of {r['confidence']};\n"
    else:
        string = 'You didn't supply a url... Try again!'
    return string

Согласно журналам Google Cloud, при использовании браузера внутренняя ошибка 500 возникает из-за TypeError, где url = request_json['url'] имеет значение None Type и не подлежит подписке. Но при тестировании этого не происходит...

Какой запрос мне нужно сделать, чтобы получить те же результаты, что и в интерфейсе Google Cloud Testing? Неправильно ли использовать ?url="..." в адресной строке? Есть ли другой способ получить ожидаемые результаты, например, используя завиток или пакет запросов Python?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
63
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Неправильно ли использовать ?url="..." в адресной строке?

Да, это неправильно для вашего кода.

Ваше тестирование отправляет в функцию полезную нагрузку JSON, а ваш код анализирует эту полезную нагрузку с помощью request.get_json(silent=True). Это не то же самое, что использование параметра строки запроса URL.

Если вы хотите принять параметр строки запроса URL, прочитайте это:

Для этого вам следует использовать request.args.get('url').

Если вы хотите продолжать использовать полезную нагрузку JSON в запросе, вы не сможете легко работать в браузере, поскольку он не предоставит простой способ ввода JSON, который вы хотите отправить. Но вы можете использовать Curl, чтобы указать полезную нагрузку JSON, аналогичную той, которая используется в вашем существующем тестировании:

Ага, понятно. Как вы и сказали, я использовал cURL, и он действительно работает! Я также развернул новую облачную функцию, которая вместо этого использует request.args.get('url'), и это именно то, что я пытался (и не смог) сделать. Большое спасибо! Точная команда cURL, которая сработала для меня, была Curl -X POST myprojectandfunction/function-1 -H "Content-Type: application/json" -d '{"url": " Zooplus.pt/magazine/wp -content/uploads/2021/10/…"}'

Filipe Gomes 06.04.2024 07:15

Другие вопросы по теме

Похожие вопросы

Как загрузить данные в html из базы данных?
При использовании pandas для чтения файла Excel любые ячейки, использующие поиск в другой таблице, читаются как NaN, есть ли обходной путь?
Почему в Visual Studio Code v1.88.0 и расширении Python v2024.4.0 вокруг моей виртуальной среды Python заключены двойные круглые скобки?
Python- pytorch.compile() выдает ошибку во время выполнения, говорящую, что Dynamo не поддерживается на Python 3.12+
Необычная ошибка при использовании nn.Sequential в классе модели в PyTorch
Pandas: сортировка многоуровневых столбцов
Openpyxl, деактивировать вкладку, поэтому, когда пользователь открывает в Excel, активна только одна вкладка
Передайте «self» в функцию, определенную с помощью python exec в методе класса
Почему я получаю несовместимый указатель на преобразование целых чисел, инициализирующее «Py_ssize_t» на Mac M1?
Как установить gst-python в macOS для работы с рекомендуемыми установщиками GStreamer?