Reputation: 11
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:
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
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