Skip to content

v2.21.0 - Async Metadata API Phase 2

Latest

Choose a tag to compare

@btoron btoron released this 30 Dec 00:19
· 16 commits to master since this release
bcfe49d

pyOFSC v2.21.0 - Async Metadata API Phase 2

Release Date: December 30, 2025
Highlights: 9 new async API modules, 31 methods, comprehensive type safety improvements


🎯 Major Features

Async Metadata API - Phase 2 Implementation

This release completes Phase 2 of the async metadata API implementation, adding async support for 9 critical OFSC metadata modules.

1. Applications API

  • get_applications() - List all applications
  • get_application(label) - Get application details
  • get_application_api_accesses(label) - List API accesses
  • get_application_api_access(label, accessId) - Get specific API access

2. Capacity Areas API

  • get_capacity_areas() - List all capacity areas
  • get_capacity_area(label) - Get capacity area details

3. Capacity Categories API

  • get_capacity_categories(offset, limit) - List with pagination
  • get_capacity_category(label) - Get category details

4. Forms API

  • get_forms(offset, limit) - List forms with pagination
  • get_form(label) - Get form details

5. Map Layers API

  • get_map_layers(offset, limit) - List map layers with pagination
  • get_map_layer(label) - Get map layer details

6. Plugins API

  • import_plugin_file(file_path) - Import plugin from XML file
  • import_plugin(plugin_xml) - Import plugin from XML string

7. Routing Profiles API (Full CRUD)

  • get_routing_profiles(offset, limit) - List routing profiles
  • get_routing_plans(profile_label, offset, limit) - List plans
  • export_routing_plan(profile_label, plan_label) - Export plan
  • import_routing_plan(profile_label, plan_label, data) - Import plan
  • replace_routing_plan(profile_label, plan_label, data) - Replace plan
  • create_routing_plan(profile_label, plan_label, data) - Create plan
  • delete_routing_plan(profile_label, plan_label) - Delete plan

8. Shifts API

  • get_shifts(offset, limit) - List shifts with pagination
  • get_shift(label) - Get shift details

9. Work Skills API (Full CRUD)

  • get_work_skills(offset, limit) - List work skills
  • get_work_skill(label) - Get work skill details
  • create_or_replace_work_skill(workskill) - Create/update work skill
  • delete_work_skill(label) - Delete work skill
  • get_work_skill_conditions() - List all conditions
  • get_work_skill_groups(offset, limit) - List groups
  • get_work_skill_group(label) - Get group details
  • create_or_replace_work_skill_group(group) - Create/update group
  • delete_work_skill_group(label) - Delete group

πŸ”§ Code Quality Improvements

Type Safety Enhancements

  • βœ… Replaced List[] with list[] - 70 occurrences updated for modern Python typing
  • βœ… Added pyright to dev dependencies - Static type checking support
  • βœ… Fixed all pyright errors - Reduced from 13 errors to 0
  • βœ… Added type: ignore annotations - 7 RootModel classes properly annotated

Model Improvements

  • βœ… Fixed duplicate Link class - Renamed to DailyExtractLink
  • βœ… Made Application fields Optional - Proper type safety
  • βœ… Fixed baseUrl property - Correct type annotation
  • βœ… Removed invalid __next__() methods - From response list classes
  • βœ… Fixed enum type mismatch - In Recurrence model
  • βœ… Added None checks - For optional member access and iterables
  • βœ… Fixed Property.translations - Changed to Optional[TranslationList]

Documentation

  • βœ… PEP 287 docstrings - All async metadata methods converted to reStructuredText format
  • βœ… New scripts/README.md - 504 lines documenting utility scripts
  • βœ… Updated ENDPOINTS.md - Current implementation status for all 243 endpoints

Code Organization

  • βœ… Reorganized models.py - Application and Routing Profile models in alphabetical regions
  • βœ… Deleted empty regions - 4 regions removed for cleaner code
  • βœ… Consistent naming - Fixed Workskill/WorkskillGroup inconsistencies

πŸ§ͺ Testing

New Test Coverage

  • 9 new test files with 3,340 lines
  • 100+ test cases covering all new functionality
  • 50+ saved API responses for validation testing
  • All tests passing: 266/266 βœ…

Test Structure

  • Live tests with @pytest.mark.uses_real_data
  • Model validation tests
  • Saved response validation tests
  • Error handling tests (404, authentication, etc.)
  • Comprehensive CRUD operation tests

Coverage Metrics

  • Overall: 84% (exceeds 80% target)
  • async_client/metadata.py: 95%
  • models.py: 87%
  • exceptions.py: 100%

πŸ› Bug Fixes

Critical Fixes

  1. RoutingPlanData Validation - Made fields optional for varied API responses
  2. Optional Member Access - Added None checks before calling methods
  3. Import Naming - Fixed WorkskillConditionList typo
  4. Type Annotations - Standardized across all models

Minor Fixes

  • Updated capacity area validation test label
  • Updated Status enum usage in CapacityArea and Workzone
  • Corrected endpoint statuses in documentation
  • Removed deprecated routing profiles capture script

πŸ“¦ New Dependencies

Development

  • pyright>=1.1.390,<2 - Static type checker for Python

πŸ“Š Statistics

Metric Count
Issues Resolved 9 (#92, #93, #94, #95, #99, #102, #105, #106, #108)
API Methods Added 31
Models Created/Updated 18
Test Files Created 9
Test Cases Added 100+
Saved Responses 50+
Documentation Lines 1,050+
Net Lines Added +5,253

πŸ”„ Migration Guide

Breaking Changes

None - All changes are backward compatible.

New Features Usage

from ofsc import AsyncOFSC

async with AsyncOFSC(
    clientID="your_client_id",
    companyName="your_company",
    secret="your_secret"
) as client:
    # Applications API
    apps = await client.metadata.get_applications()
    app = await client.metadata.get_application("app_label")
    
    # Routing Profiles API
    profiles = await client.metadata.get_routing_profiles()
    plans = await client.metadata.get_routing_plans("profile_label")
    plan_data = await client.metadata.export_routing_plan(
        "profile_label", "plan_label"
    )
    
    # Work Skills API (CRUD)
    skills = await client.metadata.get_work_skills()
    skill = await client.metadata.get_work_skill("skill_label")
    await client.metadata.create_or_replace_work_skill(workskill)
    await client.metadata.delete_work_skill("skill_label")
    
    # All other new APIs follow the same pattern
    forms = await client.metadata.get_forms()
    shifts = await client.metadata.get_shifts()
    capacity_areas = await client.metadata.get_capacity_areas()

Type Checking Support

# Models now fully support modern Python typing
from ofsc.models import (
    Application,
    RoutingProfileList,
    Workskill,
    Form
)

# Use with mypy or pyright for static type checking
apps: list[Application] = []  # Modern syntax supported

πŸ“ Documentation

New Documentation

  • scripts/README.md - Comprehensive guide for utility scripts
    • capture_api_responses.py - How to capture API responses
    • update_endpoints_doc.py - How to update endpoint documentation
    • Usage examples, best practices, troubleshooting

Updated Documentation

  • ENDPOINTS.md - Current implementation status (89 sync, 53 async endpoints)
  • All async metadata docstrings - Now in PEP 287 reStructuredText format

πŸš€ What's Next

Phase 3 (Upcoming)

  • Remaining metadata endpoints (see issue #109)
  • Additional CRUD operations
  • Batch operations support

Future Releases

  • Async Core API implementation
  • Async Capacity API implementation
  • OAuth token-based authentication for async client
  • Enhanced error handling and retries
  • Rate limiting support

πŸ™ Contributors

  • Borja Toron (@btoron) - Primary development
  • Claude Sonnet 4.5 - AI pair programming assistance

πŸ“‹ Full Changelog

Features

  • feat: implement async routing profiles API methods and add tests (86db72c)
  • feat: implement async methods for capacity areas and add comprehensive tests (3448768)
  • feat: implement async methods for capacity categories and add comprehensive tests (3dc52d1)
  • feat: implement async methods for map layers and add comprehensive tests (aafcf98)
  • feat: implement async methods for forms and add comprehensive tests (503377d)
  • feat: implement async methods for shifts and add comprehensive tests (9671b40)
  • feat: implement async methods for work skills and conditions with comprehensive tests (f87e963)
  • feat: Add async applications and plugins API implementation (5db8cf1)
  • feat: Add comprehensive README for utility scripts (5ead113)
  • feat: add endpoints for work skills in API capture script (52bdbbc)
  • feat: add live and model tests for CRUD operations (a7fd98b)
  • feat: Update RoutingPlanData model for optional fields (f48d935)
  • feat: Refactor metadata models for applications and routing profiles (5383307)
  • feat: Add pyright to development dependencies (b9ad391)
  • feat: update status fields to use Status enum (f2a77d0)

Bug Fixes

  • fix: correct naming inconsistencies for Workskill and WorkskillGroup (7018dfa)
  • fix: Correct typo in import statement for WorkskillConditionList (6e64aaa)
  • fix: Update endpoint statuses in documentation (5557984)
  • test: update expected label for capacity area validation (ff18bed)

Refactoring

  • refactor: Replace List with built-in list type (202049d)
  • refactor: Simplify model classes and update type hints (de8086f)
  • refactor: Docstrings to use reStructuredText (35440fd)
  • feat: remove deprecated routing profiles capture script (e2f569e)

Version Updates

  • chore: Update version to 2.21.0 (01dfffe)

πŸ”— Links


Install/Upgrade:

pip install --upgrade ofsc==2.21.0

Verify Installation:

import ofsc
print(ofsc.__version__)  # Should print: 2.21.0