我无法将简单的Flask应用托管到Vercel

0 投票
1 回答
28 浏览
提问于 2025-04-13 01:26

我正在学习Python,想在Vercel上托管一个简单的Flask应用,这个应用可以显示当前的温度(从一个开源API获取)。

我可以在我的Visual Studio Code里通过127.0.0.1:5000运行这个应用,但当我把它部署到Vercel时,出现了错误信息。

这是在Vercel上出现的错误:截图

我的应用结构是这样的:

app.py
weather_controller.py
requirements.txt
vercel.json
templates/home.html

这是app.py文件里的代码

import requests
import weather_controller

from flask import Flask, render_template
app = Flask(__name__, template_folder='templates')


@app.route('/', methods=['GET'])
def home():
    temperature = weather_controller.print_current_temperature()
    return render_template('home.html', temperature=temperature)


@app.route('/contact', methods=['GET'])
def contact():
    return "Contact page"
    
if __name__ == "__main__":
    app.run()

这是vercel.json里的代码

{
    "builds": [
        {
            "src":"app.py",
            "use":"@vercel/python"
        }
    ],
    "routes": [
        {
            "src":"/(.*)", 
            "dest":"app.py"
        }
    ]
}

这是weather_controller.py里的代码

import requests

url = r"https://api.open-meteo.com/v1/forecast"

params = {
    "latitude": 42.69,
    "longitude": 23.32,
    "current": "temperature_2m,wind_speed_10m",


}

response = requests.get(url, params=params)

responseJSON = response.json()

def print_current_temperature():
    return f'The current temperature is {str(responseJSON['current']['temperature_2m'])}'

我注意到,如果我在开头去掉weather_controller的相关部分(比如import weather_controller),部署就能成功。即使只是导入weather_controller也会导致Vercel的部署失败。

谢谢你们的帮助!

1 个回答

0

你在weather_controller.py这个文件里,在模块级别发起了一个API请求。这意味着一旦这个模块被导入,HTTP请求就会立即发送,这对无服务器函数来说并不好,因为它可能会有冷启动的问题。更好的做法是把API请求放在print_current_temperature这个函数里,这样只有在访问这个路由的时候才会执行,而不是在无服务器函数初始化的时候就执行。

试试这个更新后的版本:

import requests

def print_current_temperature():
    url = "https://api.open-meteo.com/v1/forecast"
    params = {
        "latitude": 42.69,
        "longitude": 23.32,
        "current_weather": True
    }
    try:
        response = requests.get(url, params=params)
        response.raise_for_status()  # This will raise an exception for HTTP errors
        responseJSON = response.json()
        temperature = responseJSON['current_weather']['temperature']
        return f'The current temperature is {temperature}'
    except requests.RequestException as e:
        return str(e)

我不确定这是否就是问题所在,但如果它仍然无法运行,你可以考虑查看更详细的vercel日志,看看里面是否有关于错误的更多信息。

为了更好地处理错误,考虑按以下方式更新你的文件。

app.py:

from flask import Flask, render_template
import weather_controller

app = Flask(__name__, template_folder='templates')

@app.route('/', methods=['GET'])
def home():
    try:
        temperature = weather_controller.get_current_temperature()
        return render_template('home.html', temperature=temperature)
    except Exception as e:
        # You should probably log this error
        # For example: app.logger.error(f"Failed to get temperature: {e}")
        return f"An error occurred: {e}", 500

@app.route('/contact', methods=['GET'])
def contact():
    return "Contact page"

if __name__ == "__main__":
    app.run()

撰写回答