Always set a timeout
Without a timeout, a request can wait indefinitely and tie up a worker. Choose a value that matches the service and user experience.
Raise on HTTP errors
A 404 or 500 response is not valid data. Check the status before reading fields so the program fails at the right layer.
Validate the response shape
A successful HTTP status does not guarantee the JSON contains the keys you need. Treat external data as untrusted input and check it.
Return useful domain data
Keep HTTP details inside one function. The rest of the application should receive a simple value or a meaningful application error.
Working example
import requests
class WeatherError(RuntimeError):
pass
def current_temperature(city: str) -> float:
try:
response = requests.get(
"https://api.example.com/weather",
params={"city": city},
timeout=10,
)
response.raise_for_status()
payload = response.json()
except requests.RequestException as exc:
raise WeatherError("Weather service is unavailable") from exc
except ValueError as exc:
raise WeatherError("Weather service returned invalid JSON") from exc
value = payload.get("temperature_c")
if not isinstance(value, (int, float)):
raise WeatherError("Temperature is missing")
return float(value)