zdravko7
zdravko7

Reputation: 11

I can't host my simple Flask app to Vercel

I'm learning Python and I'm trying to host a simple Flask application that shows the current temperature (pulled from an open source API) in Vercel.

I am able to run the app in my Visual Studio Code at 127.0.0.1:5000, but when I deploy it to Vercel, I'm getting an error message.

This is the error in Vercel:
Screenshot

My app has this structure:

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

This is the code in the app.py file:

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()

This is the code in the vercel.json file:

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

This is the code in the weather_controller.py file:

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'])}'

I noticed that the deployment works if I remove the weather_controller bits in the beginning (e.g. import weather_controller). Even just importing the weather_controller breaks the Vercel deployment.

Thanks in advance for your help!

Upvotes: 1

Views: 177

Answers (1)

Niusoski
Niusoski

Reputation: 167

You are making an API call at the module level in weather_controller.py. This means that the HTTP request is made as soon as the module is imported, which is not ideal for a serverless function that may have a cold start. Instead, you should make the API call within the print_current_temperature function, so it's executed when the route is accessed, not when the serverless function is initialized.

Try it with this updated version:

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)

I am unsure if this is the exact issue but if it's still not running you should considering checking out the expanded vercel logs to see if there are any further details regarding the error in there.

Consider updating your files as follows for better error handling.

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()

Upvotes: 1

Related Questions