refactor: de-pydantic the vendored charm libs#2557
Conversation
Replace the pydantic models in the two charm libraries vendored under tracing/ops_tracing/vendor/ with stdlib dataclasses plus manual validation, removing pydantic (and its pydantic-core, annotated-types and typing-inspection transitive deps) from ops_tracing's dependency tree. These vendored copies have exactly one consumer (ops_tracing itself) and are already a fork, so this also drops the upstream API surface ops_tracing never exercises: the provider-side classes, the charmhub publish metadata, the redundant relation-direction validation helper, the charm_tracing_config convenience wrapper, and the pydantic-v1 compatibility branches. Each vendored file gains a fork-marker header comment documenting what was dropped vs upstream. - tempo_coordinator_k8s/v0/tracing.py and certificate_transfer_interface/v1/certificate_transfer.py: pydantic BaseModel databag models become @DataClass with file-local load/dump helpers (sets serialise as sorted lists; unknown databag keys are ignored; missing required fields raise the lib-local DataValidationError). - tracing/pyproject.toml: drop the pydantic dependency; re-lock. - tracing/test: drop the now-obsolete pydantic importorskip guards and add round-trip / validation tests for the dataclass models. https://claude.ai/code/session_011fFFqf3gLogCYJk95YCwFW
… modules
The two forked-and-tuned files no longer match the 'vendored copy kept
in sync with upstream' framing — they are ops_tracing's own modules now.
Move them next to the other private modules and rename to the project's
underscore convention:
vendor/charms/.../certificate_transfer.py -> _cert_transfer_models.py
vendor/charms/.../tracing.py -> _tracing_models.py
test/test_vendor_models.py -> test/test_models.py
vendor/otlp_json/ stays where it is (still genuinely vendored).
The fork-marker headers ('Forked from … de-pydantic'd … do not re-sync')
are unchanged — the file is still a fork, the path is just honest now.
Tests: 26 passed, 1 skipped (same as 993c942 baseline).
|
Driveby comment -- there's a larger discussion to be had here as to how we want to handle this long term. With the tracing charm library migrating to charmlibs this cycle, we could in principle depend on it a as a regular Python dependency instead of vendoring. On the other hand, if our needs really do diverge, then maybe we'd prefer to switch to vendoring our own tracing logic in a more first-class way (with this PR being one step on that road). |
Yes, that's one of the reasons this is in draft. I'll address it before moving it out.
We obviously should do that when it happens, if we're still vendoring. But that's not the point of the issue. The point is to get rid of large dependencies that are not really needed, and slim down the code to only what is actually required. |
:)
It's not entirely clear to me that we should, given the desire to keep Ops as dependency free as possible, and given the trickiness introduced by the mutual dependency between Ops and the tracing library. If we can feasibly maintain our own slim subset of the functionality the library provides instead, I think that's worth considering.
The more our vendored copy drifts (e.g. dropping Pydantic), the more involved migrating to the But I fully support the idea of exploring how slim we can make this, that's definitely an important point in the dependency vs own-our-own discussion. |
What's currently here is not a vendored copy that drops Pydantic, it's a library built for just ops-tracing. It's not in a vendor folder, and it doesn't have anything in it that isn't used by ops-tracing. It might be too similar to the old version and need reworking - it's a draft and I haven't looked very closely at the code yet, just given instructions to an agent.
My understanding was that we definitely intend to not use the regular library, wherever it is hosted. I thought when we'd discussed this previously everyone was in favour of doing that, just not of allocating roadmap time to it.
My understanding was we are doing that because it's the library charms should use for workload tracing, and we want to accelerate getting people away from Charmhub hosted libraries, rather than anything to do with our own use. Did I miss something?
If this is more of an open question than I understood, I don't mind that. The direction here will be more-or-less the same either way. I am aware of the love for keeping Pydantic in charms and wouldn't be surprised if, even though my understanding is we already agreed to it, this gets rejected. |
|
I'm definitely in favour of the 'maintain our own slim, Pydantic-free tracing stuff' direction, so that's music to my ears. I must have forgotten the previous discussion where we agreed to that, and gotten confused by the PR description (I haven't looked at the code). |
This PR replaces the pydantic models in the two charm libraries vendored under tracing/ops_tracing/vendor/ with stdlib dataclasses plus manual validation, removing pydantic (and its pydantic-core, annotated-types and typing-inspection transitive deps) from ops_tracing's dependency tree.
These vendored copies have exactly one consumer (ops_tracing itself) and are already a fork, so this also drops the upstream API surface ops_tracing never exercises: the provider-side classes, the charmhub publish metadata, the redundant relation-direction validation helper, the charm_tracing_config convenience wrapper, and the pydantic-v1 compatibility branches. Each vendored file gains a fork-marker header comment documenting what was dropped vs upstream.