Как запустить функцию Azure с параметрами из POST-запроса

#python #azure #post #azure-functions #serverless

#python #azure #Публикация #azure-функции #бессерверный

Вопрос:

Мне нужно отправить POST-запрос (с захваченными пользователем данными) в функцию Azure, и я хотел бы, чтобы функция Azure использовала это в качестве параметров и запускалась.

Я вижу, что существует много способов запуска функции Azure в документации, однако я не смог понять, как выполнить вышеуказанное при вводе пользовательского ввода.

Для большего контекста я разрабатываю простую пользовательскую форму, в которую пользователь вводит некоторые данные. Как только пользователь нажмет кнопку отправки, мне нужно будет запустить POST-запрос к функции Azure для выполнения некоторой обработки.

Ответ №1:

Данные из отправленной формы будут объектом Bytes. Вы должны преобразовать его в строку, а затем проанализировать параметры. Этот пример кода обрабатывает отправку базовой формы контактной информации.

 import logging

import azure.functions as func

from urllib.parse import parse_qs


def main(req: func.HttpRequest) -> func.HttpResponse:
    # This function will parse the response of a form submitted using the POST method
    # The request body is a Bytes object
    # You must first decode the Bytes object to a string
    # Then you can parse the string using urllib parse_qs

    logging.info("Python HTTP trigger function processed a request.")
    req_body_bytes = req.get_body()
    logging.info(f"Request Bytes: {req_body_bytes}")
    req_body = req_body_bytes.decode("utf-8")
    logging.info(f"Request: {req_body}")

    first_name = parse_qs(req_body)["first_name"][0]
    last_name = parse_qs(req_body)["last_name"][0]
    email = parse_qs(req_body)["email"][0]
    cell_phone = parse_qs(req_body)["cell_phone"][0]

    return func.HttpResponse(
        f"You submitted this information: {first_name} {last_name} {email} 
        {cell_phone}",
        status_code=200,
    )
  

Ответ №2:

Ниже приведен пример кода для приложения функции, запускаемой HTTP POST-запросом.

functions.json:

 {
  "scriptFile": "__init__.py",
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "$return"
    }
  ]
}
  

__init__.py:

 import logging
import azure.functions as func
import onnxruntime
from PIL import Image
import numpy as np
import io

def main(req: func.HttpRequest, context: func.Context) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    body = req.get_body()

    try:
        image = Image.open(io.BytesIO(body))
    except IOError:
        return func.HttpResponse(
                "Bad input. Unable to cast request body to an image format.",
                status_code=400
        )

    result = run_inference(image, context)

    return func.HttpResponse(result)

def run_inference(image, context):
    # See https://github.com/onnx/models/tree/master/vision/style_transfer/fast_neural_style
    # for implementation details
    model_path = f'{context.function_directory}/rain_princess.onnx'
    session = onnxruntime.InferenceSession(model_path)
    metadata = session.get_modelmeta()
    logging.info(f'Model metadata:n'  
        f'    Graph name: {metadata.graph_name}n'  
        f'    Model version: {metadata.version}n'  
        f'    Producer: {metadata.producer_name}')

    # Preprocess image
    original_image_size = image.size[0], image.size[1]
    logging.info('Preprocessing image...')
    # Model expects a 224x224 shape input
    image = image.resize((224, 224), Image.LANCZOS)
    bands = image.getbands()
    if bands == ('R', 'G', 'B'):
        logging.info(f'Image is RGB. No conversion necessary.')
    else:
        logging.info(f'Image is {bands}, converting to RGB...')
        image = image.convert('RGB')

    x = np.array(image).astype('float32')
    x = np.transpose(x, [2, 0, 1])
    x = np.expand_dims(x, axis=0)

    output_name = session.get_outputs()[0].name
    input_name = session.get_inputs()[0].name
    logging.info('Running inference on ONNX model...')
    result = session.run([output_name], {input_name: x})[0][0]

    # Postprocess image
    result = np.clip(result, 0, 255)
    result = result.transpose(1,2,0).astype("uint8")
    img = Image.fromarray(result)
    max_width  = 800
    height = int(max_width * original_image_size[1] / original_image_size[0])
    # Upsample and correct aspect ratio for final image
    img = img.resize((max_width, height), Image.BICUBIC)
    
    # Store inferred image as in memory byte array
    img_byte_arr = io.BytesIO()
    # Convert composite to RGB so we can return JPEG
    img.convert('RGB').save(img_byte_arr, format='JPEG')
    final_image = img_byte_arr.getvalue()

    return final_image
  

Ознакомьтесь с этим примером POST-запроса Python на GitHub: https://github.com/yokawasa/azure-functions-python-samples/tree/master/v2functions/http-trigger-onnx-model

Комментарии:

1. Я искал это решение в течение нескольких дней. Большое спасибо, чувак!

Ответ №3:

Этот фрагмент может работать: https://github.com/yuenci/Azure-Functions-Request-CORS

 # post
import logging

import azure.functions as func
import json


def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    req_body_bytes = req.get_body()
    req_body = req_body_bytes.decode("utf-8")

    logging.info(f"Request: {req_body}")

    content = json.loads(req_body)

    first_name = content["first_name"]
    last_name = content["last_name"]

    return func.HttpResponse(
        f"Hello, {first_name} {last_name}. This HTTP triggered function executed successfully.",
        status_code=200
    )
  

Убедитесь, что разрешен метод post

 // function.json

{
  "scriptFile": "__init__.py",
  "bindings": [
    {
      "authLevel": "anonymous",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get",
        "post" // notice
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "$return"
    }
  ]
}