Skip to content

Release 2.23.0#133

Merged
btoron merged 22 commits intomasterfrom
release/2.23.0
Mar 4, 2026
Merged

Release 2.23.0#133
btoron merged 22 commits intomasterfrom
release/2.23.0

Conversation

@btoron
Copy link
Owner

@btoron btoron commented Mar 3, 2026

Summary

  • Async Core Users API with package refactor and mixin pattern (Async Core API: Users #120)
  • Async activity write/delete operations (Async Core API: Activities (Write/Delete Operations) #122)
  • Async resource write/delete operations with model extraction (Async Core API: Resources (Write/Delete Operations) #118)
  • Async standalone inventory CRUD and custom actions (Async Core API: Inventories #126)
  • Fix sync test_inventory_types_create_replace to dynamically discover inventory type
  • ResourceCreate model for validated resource creation
  • Pyright fixes for resources mixin Protocol
  • Comprehensive metadata models refactor (activity types, applications, capacity areas, etc.)
  • Extract base types into ofsc/models/_base.py
  • Add uses_real_data markers to all sync tests requiring API credentials
  • Fix flaky live API tests (position history 404, subscription eventual consistency)
  • Common test pattern extraction into fixtures
  • Async Capacity API with 10 methods (Async Capacity API #128)
  • Fix OAuth token caching bug (OFSOAuthRequest frozen=True for hashability)

Closes

Closes #118
Closes #120
Closes #122
Closes #126
Closes #128

Test plan

  • uv run pytest tests/async/ -v — all async tests pass
  • uv run pytest tests/async/ -m serial -v — serial tests pass
  • uv run pytest -m "not uses_real_data" -v — mocked tests pass
  • uv run pytest tests/async/test_async_inventories.py -v — inventory tests pass
  • uv run pytest tests/test_token.py -v — token caching tests pass

🤖 Generated with Claude Code

btoron and others added 13 commits March 3, 2026 10:51
Add 14 async methods to AsyncOFSCore for activity write/delete operations:
- create_activity, update_activity, delete_activity (core CRUD)
- set/delete_resource_preferences, set/delete_required_inventories
- create_customer_inventory, link/unlink_activities
- set/delete_activity_link, set/delete_file_property
Update README with [Sync & Async] tags and regenerate ENDPOINTS.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… leaks

- Add bucket_activity_type, fresh_activity, and fresh_activity_pair fixtures
  to conftest.py to replace 9+ repeated setup blocks across activity tests
- Add KNOWN_ACTIVITY_ID constant and _load_saved_response() helper to
  eliminate 19 hardcoded IDs and 10 copy-pasted file-loading blocks
- Fix 2 activity-leak bugs in create tests by wrapping assertions in
  try/finally before delete_activity calls
- Fix set_activity_link and link_activities to handle HATEOAS-only responses
  from the API that omit LinkedActivity fields

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Refactor async_client/core.py into a package (core/__init__.py, _base.py,
users.py) using a mixin pattern, then implement all 11 async user methods:

CRUD: get_users, get_user, create_user, update_user, delete_user
File properties: get_user_property, set_user_property, delete_user_property
Collaboration groups: get_user_collab_groups, set_user_collab_groups, delete_user_collab_groups

Add User, UserCreate, UserListResponse, CollaborationGroup, CollaborationGroupsResponse
models. 27 new mocked tests cover all methods, model validation, and exception handling.
Update ENDPOINTS.md, README, and scripts for package discovery.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…eate model

Replace bare annotations + TYPE_CHECKING stub in AsyncOFSCoreUsersMixin with
a Protocol self-type pattern for sound type checking. The mixin now declares
its base class contract via _CoreBaseProtocol and annotates all 11 methods
with `self: _CoreBaseProtocol`, so misuse (instantiating the mixin alone) is
correctly flagged by type checkers.

Also make UserCreate.password a required field, fix live tests to avoid
hardcoded logins, and use IANA timezone identifiers.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Introduced User model for full user response with optional fields.
- Added UserCreate model to enforce required fields for user creation.
- Created UserListResponse for paginated user responses.
- Defined CollaborationGroup model for collaboration group representation.
- Implemented CollaborationGroupsResponse to handle lists of collaboration groups.
…id-file import

Move the Generic Models region (OFSResponseList, OFSConfig, OFSApi, enums,
Translation, etc.) into a dedicated _base.py module. This breaks the circular
dependency that forced a mid-file `from .users import ... # noqa: E402` in
__init__.py. Both __init__.py and users.py now import from _base independently,
allowing all imports to live at the top of the file.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ncluding activity types, applications, capacity areas, and more

- Introduced models for ActivityTypeGroup, ActivityType, Application, CapacityArea, and others to represent metadata structures.
- Implemented response models for lists of these entities to facilitate API interactions.
- Added validation and parsing logic for API access configurations.
- Enhanced existing models with additional fields and validation rules to ensure data integrity.
…criptions

test_get_position_history now gracefully skips on 404 when no route is
activated for today's date. test_get_events_workflow adds a brief delay
after create_subscription to account for API eventual consistency.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add missing @pytest.mark.uses_real_data markers to all sync tests that
require API credentials (core, metadata, capacity, token). Apply ruff
formatting fixes across all affected test files.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…on (#118)

- Extract 35 resource models from models/__init__.py to models/resources.py
- Create AsyncOFSCoreResourcesMixin with 18 GET methods (moved from _base.py)
  and 20 new write/delete methods following the established mixin pattern
- Add Group A (sync equivalents): create_resource, create_resource_from_obj,
  update_resource, set_resource_users, delete_resource_users,
  set_resource_workschedules, bulk_update_resource_workzones/workskills/workschedules,
  create_resource_location, delete_resource_location, set_assigned_locations
- Add Group B (async-only): create_resource_inventory, install_resource_inventory,
  set_resource_workskills, delete_resource_workskill, set_resource_workzones,
  delete_resource_workzone, delete_resource_workschedule, update_resource_location
- Remove NotImplementedError stubs from _base.py Resources region
- Update __init__.py composition to include AsyncOFSCoreResourcesMixin
- Add 37 mocked tests + 3 live CRUD tests in test_async_resources_write.py
- Update ENDPOINTS.md and README.md with [Sync & Async] / [Async] tags

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Introduces ResourceCreate model enforcing required fields (parentResourceId,
resourceType, name, language, timeZone) so invalid payloads are caught
client-side before reaching the API. Updates create_resource to validate
all inputs through ResourceCreate and fixes live tests to use the new model.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Change baseUrl/headers to @Property stubs to match actual base class
- Add _build_expand_param to Protocol so mixin self-calls type-check
- Annotate params dicts as dict[str, Any] to allow mixed int/str values

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@btoron
Copy link
Owner Author

btoron commented Mar 3, 2026

Closes #118 — Async Core API: Resources (Write/Delete Operations)

Commits merged:

  • e240dc7 feat(core): async resource write/delete operations and model extraction (Async Core API: Resources (Write/Delete Operations) #118)
  • 3f06dbd fix(core): add ResourceCreate model for validated resource creation
  • 0bd478c fix(types): resolve pyright errors in resources mixin Protocol

btoron and others added 9 commits March 3, 2026 18:05
Implement 12 async methods for standalone inventory operations under
/rest/ofscCore/v1/inventories/ — CRUD, file properties, and custom
actions (install/deinstall/undoInstall/undoDeinstall).

- Extract inventory models to ofsc/models/inventories.py with 2 new
  models: InventoryCreate and InventoryCustomAction
- Add AsyncOFSCoreInventoriesMixin with 12 methods following the
  users.py mixin pattern
- Compose mixin into AsyncOFSCore alongside resources and users mixins
- Add 38 tests covering model validation, mocked CRUD, file properties,
  custom actions, exceptions, and live test lifecycle
- Update ENDPOINTS.md (7 new async endpoints, 95 remaining unimplemented)
- Add Core / Inventories section to README with [Async] tags
- Add inventory capture endpoints to scripts/capture_api_responses.py

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace hardcoded "NS" inventoryType with dynamic lookup via
  metadata.get_inventory_types(limit=1) to avoid demo-env failures
- Remove get_inventories method (not supported by standalone inventory API)
- Add model_validator to InventoryCreate requiring at least one context
  field (resourceId, resourceInternalId, or activityId)
- Update related tests and mocks to satisfy the new validator

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Extract capacity models from models/__init__.py into new ofsc/models/capacity.py
- Add ~20 new Pydantic models for 8 new capacity endpoints
- Implement AsyncOFSCapacity with full error handling replacing NotImplementedError stubs:
  - get_available_capacity / getAvailableCapacity (alias)
  - get_quota / getQuota (alias)
  - update_quota (PATCH /rest/ofscCapacity/v2/quota)
  - get_activity_booking_options (GET with 15 optional params)
  - get_booking_closing_schedule / update_booking_closing_schedule
  - get_booking_statuses / update_booking_statuses
  - show_booking_grid (POST)
  - get_booking_fields_dependencies
- Add 32 mocked + 9 live tests in tests/async/test_async_capacity.py
- Add capacity endpoints to capture_api_responses.py
- Update ENDPOINTS.md and README with [Sync & Async] / [Async] tags

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add frozen=True to OFSOAuthRequest for hashability with cachetools TTLCache
- Remove stale assert False from test_token_assertion

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@btoron btoron merged commit f2cd60e into master Mar 4, 2026
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant