Skip to content

refactor(core): replace __getattribute__ op magic with typed explicit… - #53

Merged
Datata1 merged 1 commit into
mainfrom
refactor/02-typed-operation-dispatch
Jul 12, 2026
Merged

refactor(core): replace __getattribute__ op magic with typed explicit…#53
Datata1 merged 1 commit into
mainfrom
refactor/02-typed-operation-dispatch

Conversation

@Datata1

Copy link
Copy Markdown
Owner

… dispatch

Implements plans/refactor/02-typed-operation-dispatch.md:

  • APIOperation/StreamOperation become frozen generic dataclasses; response_model drives both validation and the static return type (types.NoneType for void endpoints, replacing type(None) sentinels)
  • New execute_operation(client, op, *, data, params, path_params) frees the dispatch from executor state: endpoint templates are formatted from explicit path params instead of scraping executor dict/model_dump
  • input_model is now enforced: dict payloads are validated before the request is sent (previously declared but silently ignored)
  • Fix falsy-body bug: data={} is now sent as a JSON body (previously dropped by a truthiness check)
  • ResourceBase and new BoundModel (pydantic entity base carrying the bound HTTP client) each expose a typed generic _execute; entities (Team, Workspace, Domain) migrate from the executor mixin
  • Delete _APIOperationExecutor, APIRequestHandler, AsyncCallable and all Field(default=) wiring; domain ops are defined once with their final response models instead of model_copy overrides; Domain.verify_status return type fixed to DomainVerificationStatus
  • Remove src/codesphere/core and src/codesphere/resources from the ty ratchet; uv run ty check passes over both
  • CONTRIBUTING.md: new-resource recipe and public-API policy

Public user-facing API is unchanged; codesphere.core internals are declared private.

… dispatch
Implements plans/refactor/02-typed-operation-dispatch.md:
- APIOperation/StreamOperation become frozen generic dataclasses;
response_model drives both validation and the static return type
(types.NoneType for void endpoints, replacing type(None) sentinels)
- New execute_operation(client, op, *, data, params, path_params) frees
the dispatch from executor state: endpoint templates are formatted from
explicit path params instead of scraping executor __dict__/model_dump
- input_model is now enforced: dict payloads are validated before the
request is sent (previously declared but silently ignored)
- Fix falsy-body bug: data={} is now sent as a JSON body (previously
dropped by a truthiness check)
- ResourceBase and new BoundModel (pydantic entity base carrying the
bound HTTP client) each expose a typed generic _execute; entities
(Team, Workspace, Domain) migrate from the executor mixin
- Delete _APIOperationExecutor, APIRequestHandler, AsyncCallable and all
Field(default=<op>) wiring; domain ops are defined once with their
final response models instead of model_copy overrides;
Domain.verify_status return type fixed to DomainVerificationStatus
- Remove src/codesphere/core and src/codesphere/resources from the ty
ratchet; uv run ty check passes over both
- CONTRIBUTING.md: new-resource recipe and public-API policy
Public user-facing API is unchanged; codesphere.core internals are
declared private.
@Datata1Datata1 self-assigned this Jul 12, 2026
@Datata1
Datata1 merged commit 5ed602d into mainJul 12, 2026
3 of 4 checks passed
@github-actions

Copy link
Copy Markdown

🛡️ Bandit Security Scan Results

✅ No security issues found by Bandit.

@github-actions

Copy link
Copy Markdown

Coverage

Pytest Coverage Report
FileStmtsMissBranchBrPartCoverMissing
__init__.py9000100%
client.py22000100%
config.py9000100%
exceptions.py9435382356%25–26, 30, 40–42, 53->58, 54->55, 55, 73->74, 74, 85–87, 101–104, 106–107, 148–151, 158–160, 196->197, 197–199, 204->205, 205, 206->207, 207, 210->211, 211, 214, 215->216, 216, 217->218, 218–219, 222
http_client.py54610288%41->exit, 46->exit, 79–80, 82–83, 88–89
utils.py2716181531%12->13, 13–14, 27–33, 35–36, 41–44, 46
core
__init__.py4000100%
base.py47020100%
handler.py59318096%80–82
operations.py15000100%
resources
__init__.py0000100%
resources/metadata
__init__.py3000100%
operations.py6000100%
resources.py13000100%
schemas.py28000100%
resources/team
__init__.py5000100%
operations.py8000100%
resources.py11000100%
schemas.py27000100%
resources/team/domain
__init__.py0000100%
manager.py21000100%
operations.py12000100%
resources.py2650081%31, 33, 36, 39–40
schemas.py34000100%
resources/team/usage
__init__.py3000100%
manager.py4528292%99->102, 102, 162->165, 165
operations.py4000100%
schemas.py8515141372%69->70, 70, 84–85, 88, 96–99, 114–115, 118, 126–129
resources/workspace
__init__.py5000100%
operations.py12000100%
resources.py1624280%13->14, 14, 19->20, 20
schemas.py99146681%100–101, 103–109, 115–116, 118, 142, 161
resources/workspace/envVars
__init__.py3000100%
models.py30212486%34->36, 36–37, 39->exit
operations.py7000100%
schemas.py4000100%
resources/workspace/git
__init__.py3000100%
models.py20040100%
operations.py8000100%
schema.py4000100%
resources/workspace/landscape
__init__.py3000100%
models.py99736889%28->29, 29, 126->129, 132->135, 156->157, 157–158, 160->155, 163->164, 164, 168–170
operations.py11000100%
resources.py0000100%
schemas.py2972910489%122–123, 126, 131–132, 135–136, 139, 144–146, 149–150, 153, 260, 267–268, 343–345, 347–349, 351–352, 467–468, 475–476
resources/workspace/logs
__init__.py3000100%
models.py15586625435%41–42, 48, 50–52, 54, 57–58, 61, 64–65, 67–70, 72–73, 76–77, 79–80, 82–83, 85–87, 89–90, 92–96, 98–99, 101–103, 105–110, 123–124, 214–216, 225–227, 236–238, 248–257, 267–276, 286–295
operations.py5000100%
schemas.py19000100%
TOTAL147422224213379%

Test Execution Summary

TestsSkippedFailuresErrorsTime
2630 💤0 ❌0 🔥2.674s ⏱️

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@Datata1