You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js作物病害检测网站无法获取FastAPI接口数据问题求助

问题描述

我正在开发一个基于Next.js的作物病害检测网站,该网站会将作物照片及环境因子发送至FastAPI Python后端进行处理,后续还将基于处理后的数据通过Mistral AI API生成文本提示并在组件中展示。目前后端已成功完成数据处理,可通过localhost:8000/final的GET接口返回JSON格式结果,但我的Next.js网站无法在对应组件中展示该数据:

  • 测试时控制台显示undefined
  • UI提示“Error loading data”
  • 使用fetchdata.tsx时甚至没有发起GET请求

不过使用Postman和curl请求该接口均能正常返回数据。

相关代码

prediction_server.py

from fastapi import FastAPI, File, UploadFile
from fastapi.responses import JSONResponse
import numpy as np
import tensorflow as tf
from tensorflow.keras.preprocessing import image
import io
from PIL import Image
import geocoder
import openmeteo_requests
import requests_cache
import pandas as pd
from retry_requests import retry
import joblib

def get_current_location():
    g = geocoder.ip('me')
    return g.latlng

# Get current location
location = get_current_location()
if location:
    print(f"Latitude: {location[0]}, Longitude: {location[1]}")
else:
    print("Unable to determine the location.")

# Set up caching and retry mechanisms for weather data requests
cache_session = requests_cache.CachedSession('.cache', expire_after=3600)
retry_session = retry(cache_session, retries=5, backoff_factor=0.2)
openmeteo = openmeteo_requests.Client(session=retry_session)

# Define weather API parameters
url = "https://api.open-meteo.com/v1/forecast"
params = {
    "latitude": location[0],
    "longitude": location[1],
    "current_weather": True,
}

# Fetch weather data
responses = openmeteo.weather_api(url, params=params)
response = responses[0]

# Extract current weather variables
current = response.Current()
current_temperature_2m = current.Variables(0).Value()
current_relative_humidity_2m = current.Variables(1).Value()
current_precipitation = current.Variables(2).Value()
current_wind_speed_10m = current.Variables(3).Value()

# Load models and encoders
pipeline = joblib.load('linear_regression_model.pkl')
encoder_severity = joblib.load('encoder_severity.pkl')
encoder_fertilizer = joblib.load('encoder_fertilizer.pkl')
load_disease_classification_model = tf.keras.models.load_model('disease_classification_model.h5')

# Define FastAPI app
app = FastAPI()

# Define labels for disease classification
labels = {
    0: 'Apple Scab',
    1: 'Apple Black Rot',
    2: 'Cedar Apple Rust',
    3: 'Healthy Apple',
    4: 'Healthy Blueberry',
    5: 'Cherry Powdery Mildew',
    6: 'Healthy Cherry',
    7: 'Corn Cercospora Leaf Spot',
    8: 'Maize Common Rust',
    9: 'Corn Northern Leaf Blight',
    10: 'Healthy Corn',
    11: 'Grape Black Rot',
    12: 'Grape Black Measles',
    13: 'Grape Leaf Blight',
    14: 'Healthy Grape',
    15: 'Orange Citrus Greening',
    16: 'Peach Bacterial Spot',
    17: 'Healthy Peach',
    18: 'Pepper Bell Bacterial Spot',
    19: 'Healthy Pepper Bell',
    20: 'Potato Early Blight',
    21: 'Potato Late Blight',
    22: 'Healthy Potato',
    23: 'Healthy Raspberry',
    24: 'Healthy Soybean',
    25: 'Squash Powdery Mildew',
    26: 'Strawberry Leaf Scorch',
    27: 'Healthy Strawberry',
    28: 'Tomato Bacterial Spot',
    29: 'Tomato Early Blight',
    30: 'Tomato Late Blight',
    31: 'Tomato Leaf Mold',
    32: 'Tomato Septoria Leaf Spot',
    33: 'Tomato Spider Mites',
    34: 'Tomato Target Spot',
    35: 'Tomato Yellow Leaf Curl Virus',
    36: 'Tomato Mosaic Virus',
    37: 'Healthy Tomato'
}

# Predict the disease class from an image
def predict_image(model, img):
    img = img.resize((224, 224))
    img_array = np.array(img) / 255.0
    img_array = np.expand_dims(img_array, axis=0)
    preds = model.predict(img_array)
    predicted_class = labels[np.argmax(preds[0])]
    return predicted_class

# Global variable to store the final prediction
final_prediction = {}

@app.post("/predict")
async def predict(file: UploadFile = File(...)):
    contents = await file.read()
    image_stream = io.BytesIO(contents)
    img = Image.open(image_stream).convert("RGB")

    # Predict the disease using the model
    disease_prediction = predict_image(load_disease_classification_model, img)

    # Prepare input data for severity and fertilizer prediction
    input_data = [disease_prediction, current_temperature_2m, current_relative_humidity_2m, current_precipitation, current_wind_speed_10m]
    input_df = pd.DataFrame([input_data], columns=['Class', 'Temperature (°C)', 'Humidity (%)', 'Precipitation (mm)', 'Wind Speed (m/s)'])
    prediction = pipeline.predict(input_df)

    # Extract predictions
    severity_encoded = prediction[0, :encoder_severity.categories_[0].size]
    severity_percentage = prediction[0, encoder_severity.categories_[0].size]
    fertilizer_encoded = prediction[0, encoder_severity.categories_[0].size + 1:-1]
    fertilizer_amount = prediction[0, -1]

    # Decode categorical predictions
    severity = encoder_severity.inverse_transform([severity_encoded])[0][0]
    fertilizer = encoder_fertilizer.inverse_transform([fertilizer_encoded])[0][0]

    # Store the final prediction globally
    global final_prediction
    final_prediction = {
        'Disease Prediction': disease_prediction,
        'Severity': severity,
        'Severity Percentage': severity_percentage,
        'Fertilizer': fertilizer,
        'Fertilizer Amount (kg/acre)': fertilizer_amount
    }

    return final_prediction

@app.get("/final")
async def final_output():
    return JSONResponse(content=final_prediction)

fetchdata.tsx

import Image from "next/image";

export default function FetchData({ myprops }) {
    console.log("Props received:", myprops); // Debug: Check what is logged

    if (!myprops || Object.keys(myprops).length === 0) {
        return <div>Error loading data</div>; // Handle the case where myprops is null or undefined
    }

    return (
        <main className="flex min-h-screen flex-col items-center justify-between p-24">
            <div>{JSON.stringify(myprops, null, 2)}</div> {/* Display the JSON data */}
        </main>
    );
}

export async function getServerSideProps(context) {
    try {
        const response = await fetch('http://localhost:8000/final');
        
        // Check if the response is successful
        if (!response.ok) {
            throw new Error('Network response was not ok');
        }
        
        const myprops = await response.json();
        console.log("Fetched data:", myprops); // Debug: Check what is logged
        
        return {
            props: { myprops } // Pass myprops directly to the FetchData component
        };
    } catch (error) {
        console.error('Error fetching data:', error);
        return {
            props: { myprops: null } // Handle errors gracefully
        };
    }
}

内容的提问来源于stack exchange,提问作者Warrior

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 06:05:03