@@ -7,15 +7,17 @@ A Python client library for accessing the Elexon BMRS (Balancing Mechanism Repor
77
88## Features
99
10+ - 🎯 ** 95% Type Coverage** - 275/287 endpoints return fully typed Pydantic models
1011- 🔌 ** 287 API endpoints** - Complete coverage of all BMRS data
1112- 🔑 ** API key optional** (but recommended for higher rate limits)
12- - 📊 Access to comprehensive UK electricity market data
13- - 🔄 Support for multiple data streams (generation, demand, pricing, balancing, etc. )
14- - ⚡ ** Specific response type for each endpoint ** (SystemDemandResponse, GenerationResponse, etc.)
15- - 🛡️ Built-in error handling and validation
16- - 📝 Full type hints and IDE autocomplete
17- - 🤖 Auto-generated from OpenAPI specification (287 endpoints + 280 models - 100% coverage!)
13+ - 📊 ** 280 Pydantic models ** - Auto-generated with comprehensive validation
14+ - 🧩 ** 39 field mixins ** - Eliminate code duplication ( ~ 364+ lines saved )
15+ - ⚡ ** Full IDE autocomplete ** - Type-safe access to all response fields
16+ - 🛡️ Built-in error handling with Pydantic validation
17+ - 📝 ** Complete type hints** - Works with mypy, pyright, and IDE type checking
18+ - 🤖 Auto-generated from OpenAPI specification - Always up-to-date
1819- 🧪 Comprehensive test coverage
20+ - ⚠️ ** Clear warnings** for 12 untyped endpoints (OpenAPI spec limitation)
1921- 📚 ** Complete documentation** with examples for all endpoints
2022
2123## Installation
@@ -101,27 +103,44 @@ demand_data = client.get_system_demand(
101103)
102104```
103105
104- ### Type-Safe Usage (Recommended)
106+ ### Type-Safe Usage (Recommended - v0.3.0+)
107+
108+ The SDK now provides ** full type safety** with Pydantic models for 275/287 endpoints!
105109
106110``` python
107- from elexon_bmrs import BMRSClient, SystemDemandResponse
108- from elexon_bmrs.generated_models import DemandOutturnNational
111+ from elexon_bmrs import BMRSClient
112+ from elexon_bmrs.generated_models import (
113+ DynamicData_ResponseWithMetadata,
114+ AbucDatasetRow_DatasetResponse
115+ )
109116
110117# Initialize client
111118client = BMRSClient(api_key = " your-api-key-here" )
112119
113- # Each method returns its own specific response type!
114- response: SystemDemandResponse = client.get_system_demand(
115- from_date = " 2024-01-01" ,
116- to_date = " 2024-01-02"
120+ # ✨ Fully typed responses with automatic Pydantic parsing!
121+ result: DynamicData_ResponseWithMetadata = client.get_balancing_dynamic(
122+ bmUnit = " 2__CARR-1" ,
123+ snapshotAt = " 2024-01-01T12:00:00Z"
124+ )
125+
126+ # Full IDE autocomplete on all fields! 🎉
127+ for item in result.data:
128+ print (f " Dataset: { item.dataset} " )
129+ print (f " BMU: { item.bmUnit} " )
130+ print (f " Value: { item.value} " )
131+ print (f " Time: { item.time} " )
132+ # ↑ IDE knows all available fields - autocomplete everywhere!
133+
134+ # List responses are also typed
135+ demand_list = client.get_demand_outturn_summary(
136+ from_ = " 2024-01-01" ,
137+ to_ = " 2024-01-02"
117138)
118- # ↑ Returns SystemDemandResponse automatically - no manual parsing!
139+ # Returns: List[RollingSystemDemand] - each item is a typed model
119140
120- # response.data is already validated
121- for item in response.data:
122- demand = DemandOutturnNational(** item)
141+ for demand in demand_list:
123142 print (f " Date: { demand.settlement_date} , Demand: { demand.demand} MW " )
124- # ↑ Full IDE autocomplete for all fields !
143+ # ↑ Full type safety and validation !
125144```
126145
127146### Context Manager
@@ -407,6 +426,53 @@ data = rate_limited_client.request_with_backoff(
407426
408427For more details on responsible API usage, see the [ Elexon API Terms] ( https://www.elexon.co.uk/bsc/data/balancing-mechanism-reporting-agent/copyright-licence-use-bmrs-api/ ) .
409428
429+ ## Type Coverage
430+
431+ ### 95% Fully Typed (275/287 endpoints)
432+
433+ The SDK provides ** comprehensive type safety** with Pydantic models:
434+
435+ | Type Category | Count | Percentage | Status |
436+ | ---------------| -------| ------------| --------|
437+ | ** Fully Typed (Pydantic)** | 275 | 95% | ✅ |
438+ | Untyped (Empty Schema) | 11 | 4% | ⚠️ API limitation |
439+ | Untyped (Stream) | 1 | <1% | ⚠️ Expected |
440+
441+ ** Typed Response Types:**
442+ - ** Single Model** : 181 endpoints → Return ` Model_Response `
443+ - ** List of Models** : 90 endpoints → Return ` List[Model] `
444+ - ** List of Strings** : 4 endpoints → Return ` List[str] `
445+
446+ ### Untyped Endpoints
447+
448+ 12 endpoints return ` Dict[str, Any] ` because they have no schema in the OpenAPI specification:
449+
450+ ``` python
451+ # ⚠️ Untyped endpoints show clear warnings
452+ result = client.get_health()
453+ # IDE shows: "WARNING: This endpoint returns untyped Dict[str, Any]"
454+ ```
455+
456+ ** See [ UNTYPED_ENDPOINTS.md] ( UNTYPED_ENDPOINTS.md ) ** for:
457+ - Complete list of untyped endpoints
458+ - Explanation for each one
459+ - Best practices for handling them
460+ - Typed alternatives where available
461+
462+ ### Type Safety Benefits
463+
464+ ``` python
465+ # ✅ Typed endpoint - Great developer experience
466+ result = client.get_balancing_dynamic(... )
467+ for item in result.data:
468+ print (item.dataset, item.value) # ← Full autocomplete!
469+
470+ # ⚠️ Untyped endpoint - Manual handling required
471+ result = client.get_health()
472+ if ' status' in result: # ← No autocomplete
473+ print (result[' status' ])
474+ ```
475+
410476## Error Handling
411477
412478The library provides specific exceptions for different error scenarios:
@@ -464,7 +530,7 @@ python tools/download_schema.py
464530# Generate client methods from the spec
465531python tools/generate_client.py
466532
467- # Generate Pydantic models from the spec (142 models!)
533+ # Generate Pydantic models from the spec (280 models!)
468534python tools/generate_models.py
469535
470536# Or generate everything at once
@@ -484,31 +550,46 @@ python tools/validate_client.py
484550
485551See [ tools/README.md] ( tools/README.md ) for detailed documentation on code generation.
486552
487- ### Using Generated Pydantic Models
553+ ### Using Generated Pydantic Models (v0.3.0+)
488554
489- The SDK includes ** 142 auto-generated Pydantic models** from the OpenAPI spec:
555+ The SDK includes ** 280 auto-generated Pydantic models** from the OpenAPI spec with ** 39 field mixins ** for code reuse :
490556
491557``` python
492558# Import generated models
493559from elexon_bmrs.generated_models import (
494- DemandOutturnNational ,
495- DemandOutturnTransmission ,
496- ActualAggregatedGenerationPerTypeDatasetRow ,
497- WindGenerationForecast ,
498- # ... and 138 more!
560+ AbucDatasetRow_DatasetResponse ,
561+ DynamicData_ResponseWithMetadata ,
562+ RollingSystemDemand ,
563+ SystemFrequency_DatasetResponse ,
564+ # ... and 276 more!
499565)
500566
501- # Use with API responses for type safety
502- response = client.get_system_demand(from_date = " 2024-01-01" , to_date = " 2024-01-02" )
567+ # ✨ Models are automatically returned - no manual parsing needed!
568+ abuc_response = client.get_datasets_abuc(
569+ publishDateTimeFrom = " 2024-01-01T00:00:00Z" ,
570+ publishDateTimeTo = " 2024-01-02T00:00:00Z"
571+ )
572+
573+ # Response is already a Pydantic model with full validation
574+ for row in abuc_response.data:
575+ # IDE autocomplete shows: dataset, publishTime, psrType, quantity, etc.
576+ print (f " PSR: { row.psrType} , Quantity: { row.quantity} , Year: { row.year} " )
577+ # ↑ All fields validated and typed!
503578
504- # Parse with Pydantic for validation and type safety
505- for item in response[" data" ]:
506- demand = DemandOutturnNational(** item)
507- # Now you have full IDE autocomplete and type checking!
508- print (f " { demand.settlement_date} : { demand.demand} MW " )
579+ # Type checking works with mypy/pyright
580+ def analyze_abuc (data : AbucDatasetRow_DatasetResponse) -> float :
581+ """ Type-safe function with full IDE support."""
582+ return sum (row.quantity for row in data.data)
509583```
510584
511- See [ examples/typed_usage.py] ( examples/typed_usage.py ) for comprehensive type-safe usage examples.
585+ ** Benefits:**
586+ - ✅ ** 95% of endpoints** return typed models automatically
587+ - ✅ ** Zero manual parsing** required
588+ - ✅ ** Automatic validation** with clear error messages
589+ - ✅ ** Full IDE autocomplete** on all response fields
590+ - ✅ ** Type checking** with mypy/pyright
591+
592+ See [ examples/typed_usage.py] ( examples/typed_usage.py ) for comprehensive examples.
512593
513594### Running Tests
514595
@@ -604,15 +685,26 @@ This is an unofficial client library and is not affiliated with or endorsed by E
604685
605686See [ CHANGELOG.md] ( CHANGELOG.md ) for a detailed list of changes between versions.
606687
607- ### Version 0.1.0 (Upcoming)
688+ ### Latest Changes
689+
690+ See [ CHANGELOG.md] ( CHANGELOG.md ) for detailed version history.
691+
692+ ** Version 0.3.0** - Full Type Safety
693+ - 🎯 95% type coverage (275/287 endpoints fully typed)
694+ - 📦 280 Pydantic models with 39 field mixins
695+ - ⚠️ Clear warnings for 12 untyped endpoints
696+ - 🔧 Automatic response parsing
697+ - 📚 Comprehensive documentation
698+
699+ ** Version 0.2.0** - Enhanced Endpoints
700+ - Added BOALF, PN, BOD, B1610 support
701+ - Fixed API endpoint URLs
702+ - Improved error handling
608703
609- - Initial release with core functionality
610- - 280 auto-generated Pydantic models (100% coverage)
611- - Support for generation, demand, pricing, and system data
612- - API key optional but recommended
613- - Comprehensive error handling
614- - Full type hints and IDE autocomplete
615- - Extensive documentation and examples
704+ ** Version 0.1.0** - Initial Release
705+ - Core BMRS API client functionality
706+ - 287 endpoint coverage
707+ - Basic type support
616708
617709## Support
618710
0 commit comments