我已经成功使用 Python 中的 FastAPI 合并了两个代码。现在的挑战是通过 JSON 发送 Base64 格式的图像进行解释。但是,我遇到了问题,因为 C# 返回 System.Net.WebException:“远程服务器返回错误:(500) 内部服务器错误。”
有什么想法吗?
这是我的代码:
Python
import tensorflow as tf
from fastapi import FastAPI
import json
import base64
from PIL import Image
import io
#from flask import request
from fastapi import Request
app = FastAPI()
# Load the saved model
cnn = tf.keras.models.load_model('modelo_cnn.h5')
# Test functions to verify the connection
# @app.get('/prueba0/')
# def prueba0():
# return "Hello, I'm connecting..."
# Test function to sum two numbers
@app.get('/prueba1/{a}/{b}')
def prueba1(a: int, b: int):
return a + b
# Test function to display a message
@app.get('/prueba2/{text}')
def prueba2(text: str):
return "Hello, your message was... " + text
#########################################################################################
# Overlap identification function
@app.post('/traslape/')
def traslape(request: Request):
global cnn
# Get data from the request body
body = request.body()
# Decode JSON data
data = json.loads(body)
# # # Open the JSON file (image)
# with open(image) as f:
# img = json.load(f)
# # Decode the image
# image = base64.b64decode(img["image"])
# # Open the image from bytes using Pillow
# image = Image.open(io.BytesIO(image))
# # Concatenate images horizontally
# #imagen_completa = tf.concat([imagen_i, imagen_d], axis=1)
# # Apply gamma correction to the image
# gamma = tf.convert_to_tensor(0.6)
# gamma_corrected = tf.pow(imagen / 255.0, gamma) * 255.0 # imagen_completa
# image_bw = tf.cast(gamma_corrected, tf.uint8)
# # Convert the image to grayscale
# grayscale_image = tf.image.rgb_to_grayscale(image_bw)
# # Define new dimensions
# new_height = 360
# new_width = 500
# # Resize the image
# imagen_completa_resize = tf.image.resize(grayscale_image, [new_height, new_width])
# # Perform classification using the loaded model
# result = cnn.predict(imagen_completa_resize)
# if result[0][0] > result[0][1]:
# result = False # No mask
# else:
# result = True # With mask
return True
using System;
using System.IO;
using System.Net;
using System.Text;
namespace comunica_api
{
class Program
{
static void Main(string[] args)
{
// Path to the image in your local file system
string imagePath = @"C:\Users\VirtualImages[00]20240418_124751_028.jpg";
try
{
// Read the bytes of the image from the file
byte[] imageBytes = File.ReadAllBytes(imagePath);
// Convert the bytes to a Base64 formatted string
string base64String = Convert.ToBase64String(imageBytes);
// URL of the API
string url = "http://localhost:8000/traslape/";
// Data to send
string json = "{\"image\": \"" + base64String + "\"}";
// Create the HTTP request
var request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST"; // Use the POST method
request.ContentType = "application/json"; // Set content type as JSON
request.ContentLength = json.Length;
// Convert JSON string to bytes
byte[] jsonBytes = Encoding.UTF8.GetBytes(json);
// Print the request content before sending it
Console.WriteLine("Request:");
Console.WriteLine("URL: " + url);
Console.WriteLine("Method: " + request.Method);
Console.WriteLine("Headers:");
foreach (var header in request.Headers)
{
Console.WriteLine(header.ToString());
}
Console.WriteLine("Body:");
Console.WriteLine(json);
// Write bytes into the request body using StreamWriter
using (Stream requestStream = request.GetRequestStream())
using (StreamWriter writer = new StreamWriter(requestStream))
{
// Write JSON string into the request body
writer.Write(json);
}
// Send the request and get the response
// HERE IS THE ERROR
using (var response = (HttpWebResponse)request.GetResponse())
//
{
// Read the response from the server
using (var streamReader = new StreamReader(response.GetResponseStream()))
{
// Read the response as a string and display it in the console
string responseText = streamReader.ReadToEnd();
Console.WriteLine("API Response:");
Console.WriteLine(responseText);
}
}
}
catch (FileNotFoundException)
{
Console.WriteLine("The specified image could not be found.");
}
catch (WebException ex)
{
// Handle any communication error with the API
Console.WriteLine("API Communication Error:");
Console.WriteLine(ex.Message);
}
// Wait for the user to press Enter before exiting the program
Console.ReadLine();
}
}
}
我注释掉了几行试图达到预期的结果,但没有成功。
问题在于您在服务器端阅读
request
body
的方式。 request.body()
方法返回一个协程,因此,它应该是await
ed,这意味着端点也应该用async def
定义——有关def
与async def
的更多详细信息,请参阅
这个答案端点以及 FastAPI 如何处理它们。示例:
@app.post('/traslape/')
async def traslape(request: Request):
body = await request.body()
data = json.loads(body)
return "whatever"
请注意,由于您要将正文转换为 JSON,因此您可以直接使用以下命令来执行此操作:
data = await request.json()
当您想使用其他(可能更快)JSON 编码器(例如
orjson
)时,自行检索正文然后将其转换为 JSON 非常有用,如这个答案以及这个答案和这个答案(当涉及到在 FastAPI 中返回 JSON 数据时,您可能会发现 this 也很有帮助)。
如果您希望使用
def
定义端点,并且仍然能够获取 POST
请求的原始正文,可以在以下答案中找到解决方案:
以同步方式使用FastAPI,如何获取POST请求的原始正文?
演示如何在 FastAPI 中上传/处理 Base64 图像的相关帖子可以在 here、here 和 here 找到。请注意,您不一定需要在请求正文中将图像作为编码为
application/json
或 application/x-www-form-urlencoded
的 Base64 字符串发送;您可以将其编码为 multipart/form-data
上传,如 此答案 以及该答案中包含的相关参考文献所示。