Skip to content

Getting started

Install

pip install copernicus-ems

Python 3.12 or newer. No key to create, nothing to configure.

The floods of an activation

import asyncio

from copernicus_ems import RapidMapping


async def main() -> None:
    async with RapidMapping() as ems:
        italy = await ems.activations(country="Italy", categories=["Flood", "Storm"])
        print(len(italy), "activations in Italy, first", italy[0].code, italy[0].event_time.date())

        events = await ems.observed_events("EMSR664")
        for e in events[:3]:
            print(e.product.label, e.product.observed_time, len(e.features), "polygons")
        print(sum(len(e.features) for e in events), "flood polygons in", len(events), "products")
        print("saved in", ems.directory)


asyncio.run(main())
14 activations in Italy, first EMSR659 2023-05-02
AOI01_DEL_MONIT01 2023-05-18 16:55:00+00:00 462 polygons
AOI01_GRA_PRODUCT 2023-05-22 10:27:00+00:00 92 polygons
AOI01_DEL_PRODUCT 2023-05-17 16:56:00+00:00 1153 polygons
6334 flood polygons in 11 products
saved in /home/you/.cache/copernicus-ems

Run it again: the 11 layers are read from disk and the only request left is the activation detail (12.7 s the first time, 2.1 s the second, on EMSR664).

From the command line

The package installs a copernicus-ems command (also python -m copernicus_ems):

copernicus-ems list --country Italy --since 2025-01-01        # code, date, category, name
copernicus-ems list --category Flood --json                   # one JSON object per line
copernicus-ems fetch EMSR762 EMSR664                          # layers into the cache
copernicus-ems export --country Italy -o italy.geojson --masks italy_masks.geojson
copernicus-ems export EMSR762 -o emsr762.geojson --all-events # landslides too
copernicus-ems export EMSR664 -o emsr664.parquet              # GeoParquet ([parquet] extra)

export tags every feature with its activation, product, aoi_name and observed_time; --masks writes the observation mask of each product as a second GeoJSON. By country it reads the Flood and Storm activations (--category to change it), and keeps the flood features. --dir sets where the layers are saved.

A .parquet output (or --masks) is written as GeoParquet 1.1, with the parquet extra (pip install 'copernicus-ems[parquet]'): EMSR664 is 17.5 MB instead of 68 MB of GeoJSON, opens in GeoPandas, DuckDB and QGIS, and observed_time is a real UTC timestamp.

Every flood of a country, from Python

examples/italy_floods.py writes one GeoJSON with every flood polygon of a country, each tagged with its activation, product and observation time:

uv run python examples/italy_floods.py              # -> italy_floods.geojson
uv run python examples/italy_floods.py Spain spain.geojson

Open the result in QGIS or drop it on geojson.io.

Where downloads are saved

The GeoJSON layers are saved in a directory, which is also the cache. If you don't pass one (RapidMapping(directory=...), or directory= on the functions):

  1. COPERNICUS_EMS_DATA_DIR, if set;
  2. otherwise ~/.cache/copernicus-ems (or $XDG_CACHE_HOME/copernicus-ems).
$COPERNICUS_EMS_DATA_DIR/
├── EMSR664/
│   ├── EMSR664_AOI01_DEL_PRODUCT_observedEventA_v1.geojson
│   └── …
└── EMSR762/
    └── EMSR762_AOI01_DEL_PRODUCT_observedEventA_v1.geojson

Every flood mapped in Italy since 2023 takes about 200 MB (14 activations, November 2026).

In Docker

Point the variable at a persistent volume, or the cache is lost with the container:

services:
  app:
    environment:
      COPERNICUS_EMS_DATA_DIR: /data/copernicus-ems
    volumes:
      - ems-data:/data/copernicus-ems
volumes:
  ems-data: