Alerts.in.ua Python Client
A comprehensive Python library for accessing the alerts.in.ua API service. Provides real-time information about air raid alerts and other potential threats across Ukraine.
Features
- 🚨 Real-time alerts - Get active air raid and other security alerts
- 🟡 Alert levels and threats - Red / yellow alert level and the specific threats (drones, missiles, ...) behind each alert
- 📍 Location-based filtering - Filter by oblasts, raions, hromadas, and cities
- 🎯 Air raid statuses - Efficient bulk status retrieval for all regions, with red / yellow levels via the v2 IoT API
- ⚡ Async support - Both synchronous and asynchronous clients
- 🔄 Caching - Built-in request caching for better performance
- 🛡️ Error handling - Comprehensive error handling and rate limiting
- 📊 Data containers - Rich data objects with filtering and lookup methods
Installation
pip install alerts_in_ua
Quick Start
⚠️ API Token Required: You need to obtain an API token by submitting an API request form.
Basic Usage
from alerts_in_ua import Client
# Initialize client
client = Client("your_api_token")
# Get detailed active alerts
alerts = client.get_active_alerts()
# Red / yellow alert levels and open threats
for alert in alerts.get_red_alerts():
print(alert.location_title, [threat.threat_type for threat in alert.threats])
# Get air raid statuses for all regions
statuses = client.get_air_raid_alert_statuses()
# Check specific region
kyiv_status = statuses.get_status(14) # Київська область
if kyiv_status and kyiv_status.status == 'active':
print(f"Alert in {kyiv_status.location_title}!")
Async Usage
import asyncio
from alerts_in_ua import AsyncClient
async def main():
client = AsyncClient("your_api_token")
# Get detailed alerts and statuses
alerts = await client.get_active_alerts()
statuses = await client.get_air_raid_alert_statuses()
return alerts, statuses
# Run async function
alerts, statuses = asyncio.run(main())
API Reference
Client Methods
Active Alerts
get_active_alerts(use_cache=True) -> Alerts
Get all currently active alerts across Ukraine.
Parameters:
use_cache(bool): Use cached data if available (default: True)
Returns:
Alerts: Container with all active alerts
Example:
alerts = client.get_active_alerts()
print(f"Total active alerts: {len(alerts)}")
# Iterate through alerts
for alert in alerts:
print(f"{alert.location_title}: {alert.alert_type} ({alert.alert_level})")
Air Raid Alert Statuses
get_air_raid_alert_statuses(use_cache=True, include_alert_level=False) -> AirRaidAlertStatuses
Get air raid alert statuses for all regions using a single efficient API call.
Parameters:
use_cache(bool): Use cached data if available (default: True)include_alert_level(bool): Also return the red / yellow level of active alerts inalert_level(default: False), see Alert levels in IoT statuses
Returns:
AirRaidAlertStatuses: Container with all air raid alert statuses
Example:
statuses = client.get_air_raid_alert_statuses()
# Get specific region status
kyiv_status = statuses.get_status(14) # Київська область
if kyiv_status:
print(f"Kyiv status: {kyiv_status.status}")
# Filter by status type
active_alerts = statuses.get_active_alert_statuses()
print(f"Active alerts: {len(active_alerts)}")
# Get all statuses
for status in statuses:
print(f"{status.location_title}: {status.status}")
# Red / yellow alert levels
statuses = client.get_air_raid_alert_statuses(include_alert_level=True)
red = statuses.get_red_alert_statuses()
yellow = statuses.get_yellow_alert_statuses()
Individual Region Status
get_air_raid_alert_status(oblast_uid_or_location_title, oblast_level_only=False, use_cache=True, include_alert_level=False) -> AirRaidAlertOblastStatus
Get air raid alert status for a specific region.
Parameters:
oblast_uid_or_location_title(Union[int, str]): UID or location titleoblast_level_only(bool): Return oblast-level data only (default: False)use_cache(bool): Use cached data if available (default: True)include_alert_level(bool): Also return the red / yellow alert level (default: False)
Returns:
AirRaidAlertOblastStatus: Status object for the specified region
Example:
# By UID
status = client.get_air_raid_alert_status(14) # Київська область
# By location title
status = client.get_air_raid_alert_status("Київська область")
print(f"Status: {status.status}")
print(f"Location: {status.location_title}")
# Alert level
status = client.get_air_raid_alert_status(31, include_alert_level=True) # м. Київ
if status.is_red():
print("Red level alert in Kyiv")
Oblast-Level Statuses
get_air_raid_alert_statuses_by_oblast(oblast_level_only=False, use_cache=True, include_alert_level=False) -> AirRaidAlertOblastStatuses
Get air raid alert statuses for all oblasts.
Parameters:
oblast_level_only(bool): Return oblast-level data only (default: False)use_cache(bool): Use cached data if available (default: True)include_alert_level(bool): Also return the red / yellow alert level (default: False)
Returns:
AirRaidAlertOblastStatuses: Container with oblast statuses
Example:
oblast_statuses = client.get_air_raid_alert_statuses_by_oblast()
for status in oblast_statuses:
print(f"{status.location_title}: {status.status}")
# Oblasts with red / yellow alerts
oblast_statuses = client.get_air_raid_alert_statuses_by_oblast(include_alert_level=True)
red_oblasts = oblast_statuses.get_red_alert_oblasts()
yellow_oblasts = oblast_statuses.get_yellow_alert_oblasts()
Historical Alerts
get_alerts_history(oblast_uid_or_location_title, period='week_ago', use_cache=True) -> Alerts
Get historical alerts for a specific region and time period.
Parameters:
oblast_uid_or_location_title(Union[int, str]): UID or location titleperiod(str): Time period ('week_ago', 'month_ago', etc.)use_cache(bool): Use cached data if available (default: True)
Returns:
Alerts: Container with historical alerts
Example:
# Get week-old alerts for Kyiv
kyiv_history = client.get_alerts_history("Київська область", "week_ago")
for alert in kyiv_history:
print(f"{alert.location_title}: {alert.alert_type} at {alert.started_at}")
Data Containers
Alerts Container
The Alerts class provides rich filtering and access methods for alert collections.
Filtering Methods:
alerts = client.get_active_alerts()
# Filter by multiple criteria
filtered = alerts.filter('location_oblast', 'Донецька область', 'alert_type', 'air_raid')
# Filter by location title
kyiv_alerts = alerts.get_alerts_by_location_title('м. Київ')
# Filter by alert type
air_raid_alerts = alerts.get_air_raid_alerts()
artillery_alerts = alerts.get_artillery_shelling_alerts()
nuclear_alerts = alerts.get_nuclear_alerts()
chemical_alerts = alerts.get_chemical_alerts()
urban_fights_alerts = alerts.get_urban_fights_alerts()
# Filter by location type
oblast_alerts = alerts.get_oblast_alerts()
raion_alerts = alerts.get_raion_alerts()
hromada_alerts = alerts.get_hromada_alerts()
city_alerts = alerts.get_city_alerts()
# Filter by specific criteria
donetsk_alerts = alerts.get_alerts_by_oblast('Донецька область')
artillery_by_type = alerts.get_alerts_by_alert_type('artillery_shelling')
raion_by_type = alerts.get_alerts_by_location_type('raion')
by_uid = alerts.get_alerts_by_location_uid('123456')
# Filter by alert level ('red' / 'yellow')
red_alerts = alerts.get_red_alerts()
yellow_alerts = alerts.get_yellow_alerts()
yellow_by_level = alerts.get_alerts_by_alert_level('yellow')
red_air_raids = alerts.filter('alert_level', 'red', 'alert_type', 'air_raid')
# Alerts with a specific open threat
drone_alerts = alerts.get_alerts_with_threat_type('drones')
Utility Methods:
# Get all alerts
all_alerts = alerts.get_all_alerts()
# Get metadata
last_updated = alerts.get_last_updated_at() # datetime object
disclaimer = alerts.get_disclaimer() # str
# Iteration
for alert in alerts:
print(alert)
AirRaidAlertStatuses Container
The AirRaidAlertStatuses class provides efficient access to air raid status data.
Lookup Methods:
statuses = client.get_air_raid_alert_statuses()
# Get status by UID (fast cached lookup)
kyiv_status = statuses.get_status(14) # Київська область
kyiv_city_status = statuses.get_status(31) # м. Київ
# Get status by location title
kyiv_status = statuses.get_status("Київська область")
Filtering Methods:
# Filter by status type
active_alerts = statuses.get_active_alert_statuses()
partly_alerts = statuses.get_partly_active_alert_statuses()
no_alerts = statuses.get_no_alert_statuses()
# Custom filtering
custom_filtered = statuses.filter_by_status('active')
# Filter by alert level (include_alert_level=True only)
red_alerts = statuses.get_red_alert_statuses()
yellow_alerts = statuses.get_yellow_alert_statuses()
red_alerts = statuses.filter_by_alert_level('red')
Container Features:
# Iteration
for status in statuses:
print(f"{status.location_title}: {status.status}")
# Length
print(f"Total regions: {len(statuses)}")
# Indexing
first_status = statuses[0]
kyiv_status = statuses.get_status(14)
Data Objects
Alert Object
Each alert contains:
id(int): Alert IDlocation_title(str): Location namelocation_title_en(str): Location name in Englishalert_type(str): Type of alert ('air_raid', 'artillery_shelling', etc.)alert_level(str): Alert level ('red', 'yellow')threats(List[Threat]): Threats currently open within the alert (empty list if none)location_type(str): Type of location ('oblast', 'raion', 'hromada', 'city')location_oblast(str): Oblast namelocation_oblast_uid(str): Oblast UIDlocation_raion(str): Raion namelocation_uid(str): Location UIDstarted_at(datetime): When the alert startedfinished_at(datetime): When the alert ended (if applicable)updated_at(datetime): When the alert was last updatednotes(str): Notescountry(str): Country
Methods: is_finished(), is_red(), is_yellow(), has_threats(), get_threats_by_type(threat_type).
Threat Object
Each item of alert.threats contains:
threat_type(str): Type of threat ('tactic_aircraft_activity', 'strategic_aircraft_activity', 'mig31k_departure', 'ballistic_missiles', 'cruise_missiles', 'unspecified_missiles', 'drones', 'guided_aerial_bombs', 'air_defense', 'unknown')level(str): Level of this threat ('red', 'yellow')started_at(datetime): When the threat startedsource_message(str): Original wording from the source, orNone
Methods: is_red(), is_yellow().
for alert in client.get_active_alerts():
if alert.is_yellow():
print(f"{alert.location_title} is on yellow level")
for threat in alert.get_threats_by_type('drones'):
print(f" drones since {threat.started_at}: {threat.source_message}")
A threat's level is independent of its alert's level: a yellow alert can carry a red threat.
Alerts from get_alerts_history() have alert_level but no threats, since threats only list what is open right now.
AirRaidAlertStatus Object
Each status contains:
location_title(str): Location namestatus(str): Alert status ('no_alert', 'active', 'partly')uid(int): Location UIDalert_level(Optional[str]):'red'or'yellow'for active alerts fetched withinclude_alert_level=True, otherwiseNoneis_red()/is_yellow(): level checks
AirRaidAlertOblastStatus Object
Each oblast status contains:
location_title(str): Oblast namestatus(str): Alert status ('no_alert', 'active', 'partly')alert_level(Optional[str]):'red'or'yellow'for active alerts fetched withinclude_alert_level=True, otherwiseNoneis_active_on_all_oblast()/is_partly_active()/is_no_alert()/is_red()/is_yellow(): status checks
AirRaidAlertOblastStatuses (from get_air_raid_alert_statuses_by_oblast) supports iteration, len(), get_active_alert_oblasts(), get_partly_active_alert_oblasts(), get_no_alert_oblasts(), get_red_alert_oblasts() and get_yellow_alert_oblasts().
Status Values
The API uses character codes that are mapped to meaningful values:
N→no_alert(Немає тривоги)A→active(Активна тривога), withoutinclude_alert_levelR→active,alert_level='red'(Активна тривога, червоний рівень), withinclude_alert_level=TrueY→active,alert_level='yellow'(Активна тривога, жовтий рівень), withinclude_alert_level=TrueP→partly(Часткова тривога)(space)→undefined(Немає даних для регіону) - automatically filtered out
Alert levels in IoT statuses
Pass include_alert_level=True to any IoT status method to also get the red / yellow level of active alerts (the library then calls the /v2/iot/... endpoints, which return R / Y instead of A). status stays 'active' for both levels, so existing code keeps working, and alert_level tells them apart. In repr, yellow-level active alerts show as 🟠 (🔴 red, 🟡 partly, 🟢 no alert). Responses with and without levels are cached separately.
statuses = client.get_air_raid_alert_statuses(include_alert_level=True)
for status in statuses.get_active_alert_statuses():
print(status.location_title, status.alert_level) # 'red' or 'yellow'
Error Handling
The library provides comprehensive error handling:
from alerts_in_ua import Client, UnauthorizedError, RateLimitError, ApiError
try:
client = Client("invalid_token")
alerts = client.get_active_alerts()
except UnauthorizedError:
print("Invalid API token")
except RateLimitError:
print("Rate limit exceeded")
except ApiError as e:
print(f"API error: {e}")
Configuration
Timeout Settings
# Default timeout is 5 seconds
client = Client("your_token")
# You can modify timeout if needed
client.REQUEST_TIMEOUT = 10
Caching
# Use cache (default)
alerts = client.get_active_alerts(use_cache=True)
# Skip cache
alerts = client.get_active_alerts(use_cache=False)
Advanced Examples
Monitor Multiple Regions
def monitor_regions(client, region_uids):
statuses = client.get_air_raid_alert_statuses()
for uid in region_uids:
status = statuses.get_status(uid)
if status and status.status == 'active':
print(f"🚨 ALERT: {status.location_title}")
elif status:
print(f"✅ Clear: {status.location_title}")
# Monitor key regions
key_regions = [14, 31, 8, 9] # Київська область, м. Київ, Волинська область, Дніпропетровська область
monitor_regions(client, key_regions)
Async Monitoring
import asyncio
from alerts_in_ua import AsyncClient
async def monitor_alerts():
client = AsyncClient("your_token")
while True:
try:
alerts = await client.get_active_alerts()
statuses = await client.get_air_raid_alert_statuses()
print(f"Active alerts: {len(alerts)}")
print(f"Active air raid regions: {len(statuses.get_active_alert_statuses())}")
await asyncio.sleep(60) # Check every minute
except Exception as e:
print(f"Error: {e}")
await asyncio.sleep(30)
# Run monitoring
asyncio.run(monitor_alerts())
Historical Analysis
def analyze_alert_history(client, location, days=7):
history = client.get_alerts_history(location, "week_ago")
alert_types = {}
for alert in history:
alert_type = alert.alert_type
alert_types[alert_type] = alert_types.get(alert_type, 0) + 1
print(f"Alert history for {location}:")
for alert_type, count in alert_types.items():
print(f" {alert_type}: {count} alerts")
analyze_alert_history(client, "Київська область")
Running Tests
python -m unittest discover -s tests -t .
Live tests against the API are skipped unless a token is provided:
ALERTS_IN_UA_TOKEN=your_token python -m unittest tests.test_live
Changelog
0.4.0
Alert.alert_level(red/yellow) withis_red()/is_yellow().Alert.threats: list ofThreatobjects (threat_type,level,started_at,source_message), plushas_threats()andget_threats_by_type().Alerts.get_alerts_by_alert_level(),get_red_alerts(),get_yellow_alerts(),get_alerts_with_threat_type().Alert.location_title_enandAlert.country.- Alert levels in IoT statuses:
include_alert_level=True(uses the v2 IoT endpoints) onget_air_raid_alert_statuses(),get_air_raid_alert_status()andget_air_raid_alert_statuses_by_oblast()(sync and async). Statuses gainalert_levelandis_red()/is_yellow(); containers gainget_red_alert_statuses()/get_yellow_alert_statuses()/filter_by_alert_level()andget_red_alert_oblasts()/get_yellow_alert_oblasts(). Off by default, so existing code is unchanged. len()onAirRaidAlertOblastStatuses.Threat,InvalidParameterExceptionand the error classes are exported fromalerts_in_ua.- Unit tests and opt-in live API tests.
License
MIT License - see LICENSE file for details.
Support
For API access and support, contact api@alerts.in.ua or visit alerts.in.ua.
Metadata
Release files for alerts-in-ua 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| alerts_in_ua-0.4.0.tar.gz | 26.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| alerts_in_ua-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 48.1 kB
Release files / alerts_in_ua-0.4.0.tar.gz
| Download URL | alerts_in_ua-0.4.0.tar.gz |
|---|---|
| Size | 26.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4a66b7b5634470ede42c943da3e13c8677ee123b8984c5490db83dbc19d779d2
|
|
BLAKE2b-256 checksum How to use checksums |
07b2c1939656c1e574766c187581fe371e34a97b4464cda8efb783b924f7d836
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.6
|
Release files / alerts_in_ua-0.4.0-py3-none-any.whl
| Download URL | alerts_in_ua-0.4.0-py3-none-any.whl |
|---|---|
| Size | 21.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f58c9e68cf5d50302575b704e87b16270b652ace650eed9863a27d305d334c82
|
|
BLAKE2b-256 checksum How to use checksums |
9826fd9fc8c083a651209353a87078812cce57d47d3a1232df9e387b50f7aab3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.6
|