Aerial Danger
Match Ukrainian aerial danger messages with regular expressions.
A match is not an official alert. A non-match does not mean that an area is safe.
Install
With uv:
uv add aerial-danger
With pip, inside your virtual environment:
python -m pip install aerial-danger
With Poetry:
poetry add aerial-danger
Usage
Detect danger for your region and locality:
from aerial_danger import DangerDetector, DangerType
detector = DangerDetector(
regions=[r"\bкиїв\b"],
localities=[r"\bнивк\w*"],
)
result = detector.danger("КИЇВ ШВИДКІСНА!")
assert result.danger
assert result.type == DangerType.BALLISTIC
assert result.matched_area == "КИЇВ"
assert result.message == "КИЇВ ШВИДКІСНА!"
assert detector.drone_danger("Шахед на Нивки!").danger
assert not detector.danger("Привіт").danger
Use built-in area presets instead of custom patterns:
from aerial_danger import DangerDetector
from aerial_danger.pattern_utils import (
resolve_locality_patterns,
resolve_region_patterns,
)
detector = DangerDetector(
regions=resolve_region_patterns([], ["kyiv"]),
localities=resolve_locality_patterns([], ["kyiv"], ["kyiv_nyvky"]),
)
assert detector.drone_danger("Шахед на Нивки!").danger
Preset IDs and patterns are in aerial_danger.location_presets.LOCATION_PRESETS.
The registry loads bundled JSON files, one per region,
into RegionPreset and LocalityPreset objects. Pattern sequences remain tuples.
Pass custom patterns as the first argument to each resolver to combine them with presets.
Each region and locality has an id matching its registry key, such as kyiv_nyvky.
Each preset exposes Ukrainian and English display names through names["uk"] and
names["en"]. Names are display metadata; matching still uses only patterns.
Methods
DangerDetector(regions: Iterable[str], localities: Iterable[str])
DangerDetector.validate_patterns(*pattern_groups: Iterable[str]) -> None
detector.danger(message: str) -> Detection
detector.irbm_danger(message: str) -> Detection
detector.mlrs_danger(message: str) -> Detection
detector.guided_bomb_danger(message: str) -> Detection
detector.ballistic_danger(message: str) -> Detection
detector.cruise_missile_danger(message: str) -> Detection
detector.drone_danger(message: str) -> Detection
detector.generic_danger(message: str) -> Detection
detector.is_safe(message: str) -> bool
detector.is_ignored(message: str) -> bool
danger() checks the danger types in the order listed above and returns the first match.
IRBM alerts need no location. Drones, MLRS, and guided bombs need a locality match.
Other alerts need a region or locality match.
Detection results
Each detector method returns a Detection with the original message, a
danger boolean, and a DetectionStatus:
| Status | danger |
Meaning | Source state |
|---|---|---|---|
DANGER |
True |
An active alert matched. | Store the detection. |
SAFE |
False |
Explicit all-clear wording matched. | Clear the detection. |
IGNORED |
False |
Excluded wording or no alert matched. | Keep the detection. |
Danger results include the threat type, matched text, and regex patterns. Other results have no match details. IRBM results have no matched area.
Detection(danger=..., message=...) accepts an optional keyword-only status,
which defaults to IGNORED. Detector methods set both values explicitly.
Wording checks
is_safe()checks explicit all-clear wording.is_ignored()checks historical, forecast, and reconnaissance exclusions.
Both checks can match one message. Detection checks exclusions first, so a
historical report quoting an all-clear stays IGNORED. Unmatched messages also
return IGNORED, even when is_ignored() is False.
These checks do not confirm real-world safety. Invalid regexes raise re.error.
Development
uv sync --locked
uv run pre-commit install
uv run pytest
uv run ruff check .
uv run ruff format --check .
uv build --no-sources
After installation, pre-commit runs Ruff on Python files, checks JSON/YAML/TOML, and formats Markdown and configuration files before each commit. See contribution guidelines for local integration setup.
License
Metadata
Release files for aerial-danger 0.4.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| aerial_danger-0.4.1.tar.gz | 38.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| aerial_danger-0.4.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 88.7 kB
Release files / aerial_danger-0.4.1.tar.gz
| Download URL | aerial_danger-0.4.1.tar.gz |
|---|---|
| Size | 38.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
91fb91b08b8383c4ba17fc60f8762b6924e26e9b179f8a0f4e60b9e155c74d2d
|
|
BLAKE2b-256 checksum How to use checksums |
7f80c50fe269450b417b4a44e9cacca81ce30aa7da2379dd4de9c5dd754fdfb5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / aerial_danger-0.4.1-py3-none-any.whl
| Download URL | aerial_danger-0.4.1-py3-none-any.whl |
|---|---|
| Size | 50.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
14f68920f1e41e219aa96bd14910dbfc661a8b00b90041643e7d02871f38fe87
|
|
BLAKE2b-256 checksum How to use checksums |
443fb71f97c1b6e5128cb0b07e9019a31a95d4695785e7ead03cae018fa7208b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|