DEV Community

Cover image for Get real weather data into Python in 12 lines
Petrichor
Petrichor

Posted on

Get real weather data into Python in 12 lines

Most "weather in Python" tutorials end at printing a temperature. That's rarely what you actually need. Usually you want a time series you can join to your own data: sales, sensor readings, energy output, whatever.

Here's the shortest path I know to get there.

Install

pip install 'pymeteosource[pandas]'
Enter fullscreen mode Exit fullscreen mode

The [pandas] extra is optional. Without it the library only needs requests and pytz. The quotes matter on macOS, where zsh treats bare square brackets as a filename pattern and refuses the command.

You'll need an API key. Meteosource has a free tier that's enough for this, and it's the API I work with, so that's what the examples use.

The 12 lines

from pymeteosource.api import Meteosource
from pymeteosource.types import tiers, sections, units

meteosource = Meteosource('YOUR_API_KEY', tiers.FREE)

forecast = meteosource.get_point_forecast(
    lat=50.088,
    lon=14.420,
    sections=[sections.CURRENT, sections.HOURLY],
    tz='Europe/Prague',
    units=units.METRIC,
)

df = forecast.hourly.to_pandas()
print(df.head())
Enter fullscreen mode Exit fullscreen mode

That's Prague. Swap the coordinates for wherever you care about.

What you get

to_pandas() gives you a flat DataFrame indexed by datetime. Nested fields get flattened with underscores, so wind.angle becomes a wind_angle column. That means you can resample or merge immediately:

df['temperature'].resample('3h').mean()
Enter fullscreen mode Exit fullscreen mode

If you'd rather work with the objects directly, attributes take either dot or bracket access:

forecast.hourly[0]['temperature']
forecast.hourly[0].wind.speed
Enter fullscreen mode Exit fullscreen mode

Handy when you're building keys dynamically.

What the free tier actually gives you

Worth knowing before you plan around it: 400 calls per day, capped at 10 per minute, and the hourly forecast runs one day ahead (the daily section goes out seven). So the code above returns roughly 24 rows, not a week. Enough to build and test against, but daily aggregates need a paid tier.

Three things that will bite you

Timezones. The library defaults to UTC regardless of where your point is, and note that this is the opposite of the raw API, which defaults to the point's local time. So if you're porting working code from curl or requests, your timestamps silently shift. The library does this deliberately, to dodge ambiguous datetimes around DST. Just set tz explicitly and stop thinking about it.

Units. The units parameter defaults to auto, which picks based on location. Fine for a UI, bad for a dataset: loop over a list of cities and you'll get metric for Prague and imperial for Denver in the same DataFrame, with nothing in the column names to tell you which is which. Pin it to units.METRIC or units.US and be done.

Section names. Ask for only the sections you need (current, minutely, hourly, daily, alerts). Requesting minutely when you're building daily aggregates just makes the response bigger and slower to parse. On the free tier the minute-by-minute data isn't included anyway.

That's it

Twelve lines to a DataFrame. From here the interesting part is what you join it to.

Library and full docs: github.com/Meteosource/pymeteosource

If you've built something with weather data, I'd like to hear what. I collect these.

Top comments (0)