Products and API¶
dpc_radar.products ¶
The DPC radar products, and the requests and answers of the open radar API.
Pure: nothing here does I/O. A client sends the requests built here and hands the answers back to the parsers.
The API (radar-api.protezionecivile.it) has two calls that matter:
GET /findLastProductByType?type=<product>gives the time of the latest frame and its period;POST /downloadProductwith{"productType", "productDate"}gives a short-lived S3 link to the GeoTIFF of one frame.
A frame the DPC no longer keeps (about five months back) does not answer 404:
it answers 500 with S3's 403 Forbidden in the body. :func:is_expired
tells the two failures apart, because an expired frame must not be retried.
Product
dataclass
¶
One DPC radar product.
period
property
¶
period: timedelta
How often a new frame comes out: 30 minutes for the «Merging», 5 for radar only.
The same as the period the API returns (PT30M, PT5M): the
frame before one issued at t is the one issued at t - period.
LastProduct
dataclass
¶
What findLastProductByType says about the latest frame.
last_product_url ¶
last_product_url(name: str | Product, *, base: str = API_BASE) -> tuple[str, dict[str, str]]
URL and query parameters of the latest-frame request.
download_body ¶
download_body(name: str | Product, at: datetime) -> dict[str, Any]
JSON body of the download-link request for the frame issued at.
to_epoch_ms ¶
to_epoch_ms(at: datetime) -> int
at as the API's milliseconds since the epoch; at must be aware.
from_epoch_ms ¶
from_epoch_ms(ms: int | float | str) -> datetime
The API's milliseconds since the epoch as an aware UTC datetime.
parse_period ¶
parse_period(text: str) -> timedelta
An ISO 8601 period of hours and minutes (PT5M, PT30M, PT1H).
parse_last_product ¶
parse_last_product(payload: dict[str, Any]) -> LastProduct | None
The latest frame, or None when the API lists none.
parse_download ¶
parse_download(payload: dict[str, Any]) -> str
The S3 link of a frame, from the download-link answer.
is_expired ¶
is_expired(status: int, body: str) -> bool
True when the API says the frame is no longer kept.
That is a 500 carrying S3's 403 in the body, not a 404. Any other failure is worth retrying; this one never is.