Skip to content

feat(python): add typed metrics template package - #61

Merged
yordis merged 4 commits into
mainfrom
yordis/feat-python-metrics-template
Nov 1, 2026
Merged

yordis merged 4 commits into
mainfrom
yordis/feat-python-metrics-template

Conversation

@yordis

@yordis yordis commented Oct 30, 2026

Copy link
Copy Markdown
Member
  • Python code that records metrics by hand-typed name, unit and attribute keys drifts from the registry, and no package here renders a registry into Python.
  • Importing the generated code needs only opentelemetry-api, so scripts that report through another channel can still take names from the registry.
  • Spans, events and entities are left for a later version so the metrics surface can land and be consumed first.

Python services that record metrics by hand-typed name, unit, and attribute
keys drift from the registry. This package generates typed instruments on the
vanilla opentelemetry-api, so the registry stays the single source of truth
and importing the output needs no SDK.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
@cursor

cursor Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

PR Summary

Low Risk
New template package and CI only; no changes to existing language generators or runtime services.

Overview
Adds a Python Weaver template (templates/code/python) that generates __init__.py, attributes.py, and metrics.py from a semantic convention registry—typed attribute keys and enums, metric wrapper classes (sync + observable), refinements, and histogram explicit_bucket_boundaries_advisory from registry annotations or histogram_boundaries_by_unit.

Validation and CI: New buildscripts/check_python_output.sh (disposable venv via uv, hash-pinned deps) runs ruff format --check, ruff check, mypy --strict, and per-case test_consumer.py pytest against pinned OpenTelemetry API/SDK. Wired as mise run weaver:test:python in the default test aggregate and the GitHub Checks workflow; mise.toml pins Python 3.12 and uv.

Docs: README lists the Python package; AGENTS/CONTRIBUTING describe how to run and what generated Python must satisfy.

Tests: Broad fixture suite—happy paths (attributes, metrics, filtering, histogram boundaries, imports) and many expected-error.txt cases for collisions, reserved names, enum limits, aggregation rules, and param validation.

Reviewed by Cursor Bugbot for commit 04e009f. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitai Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 230 files, which is 130 over the limit of 100.

To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch.

Upgrade to a paid plan to raise the limit.

This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 901d6aa7-9dea-446f-91d2-ba458970c288
Commits

Reviewing files that changed from the base of the PR and between 2b5f430 and f8599ba.

Files selected for processing: 230
  • .config/mise/tasks/weaver/test/_default
  • .config/mise/tasks/weaver/test/python
  • .github/workflows/checks.yml
  • AGENTS.md
  • CONTRIBUTING.md
  • README.md
  • buildscripts/check_python_output.sh
  • buildscripts/python/mypy.ini
  • buildscripts/python/requirements.in
  • buildscripts/python/requirements.txt
  • buildscripts/python/ruff.toml
  • mise.toml
  • templates/code/python/README.md
  • templates/code/python/__init__.py.j2
  • templates/code/python/attributes.py.j2
  • templates/code/python/header.j2
  • templates/code/python/metrics.py.j2
  • templates/code/python/tests/attributes/expected/__init__.py
  • templates/code/python/tests/attributes/expected/attributes.py
  • templates/code/python/tests/attributes/registry/manifest.yaml
  • templates/code/python/tests/attributes/registry/model.yaml
  • templates/code/python/tests/attributes/test_consumer.py
  • templates/code/python/tests/empty/expected/__init__.py
  • templates/code/python/tests/empty/registry/manifest.yaml
  • templates/code/python/tests/empty/registry/model.yaml
  • templates/code/python/tests/empty/test_consumer.py
  • templates/code/python/tests/error_aggregation_counter/expected-error.txt
  • templates/code/python/tests/error_aggregation_counter/registry/manifest.yaml
  • templates/code/python/tests/error_aggregation_counter/registry/myapp.yaml
  • templates/code/python/tests/error_aggregation_fields/expected-error.txt
  • templates/code/python/tests/error_aggregation_fields/registry/manifest.yaml
  • templates/code/python/tests/error_aggregation_fields/registry/model.yaml
  • templates/code/python/tests/error_aggregation_method/expected-error.txt
  • templates/code/python/tests/error_aggregation_method/registry/manifest.yaml
  • templates/code/python/tests/error_aggregation_method/registry/myapp.yaml
  • templates/code/python/tests/error_aggregation_unsorted/expected-error.txt
  • templates/code/python/tests/error_aggregation_unsorted/registry/manifest.yaml
  • templates/code/python/tests/error_aggregation_unsorted/registry/myapp.yaml
  • templates/code/python/tests/error_attribute_collision/expected-error.txt
  • templates/code/python/tests/error_attribute_collision/registry/manifest.yaml
  • templates/code/python/tests/error_attribute_collision/registry/model.yaml
  • templates/code/python/tests/error_boundaries_empty/expected-error.txt
  • templates/code/python/tests/error_boundaries_empty/registry/manifest.yaml
  • templates/code/python/tests/error_boundaries_empty/registry/model.yaml
  • templates/code/python/tests/error_cross_namespace_collision/expected-error.txt
  • templates/code/python/tests/error_cross_namespace_collision/registry/manifest.yaml
  • templates/code/python/tests/error_cross_namespace_collision/registry/model.yaml
  • templates/code/python/tests/error_duplicate_enum_value/expected-error.txt
  • templates/code/python/tests/error_duplicate_enum_value/registry/manifest.yaml
  • templates/code/python/tests/error_duplicate_enum_value/registry/model.yaml
  • templates/code/python/tests/error_enum_class_collision/expected-error.txt
  • templates/code/python/tests/error_enum_class_collision/registry/manifest.yaml
  • templates/code/python/tests/error_enum_class_collision/registry/model.yaml
  • templates/code/python/tests/error_enum_collision/expected-error.txt
  • templates/code/python/tests/error_enum_collision/registry/manifest.yaml
  • templates/code/python/tests/error_enum_collision/registry/model.yaml
  • templates/code/python/tests/error_enum_member_identifier/expected-error.txt
  • templates/code/python/tests/error_enum_member_identifier/registry/manifest.yaml
  • templates/code/python/tests/error_enum_member_identifier/registry/model.yaml
  • templates/code/python/tests/error_enum_without_members/expected-error.txt
  • templates/code/python/tests/error_enum_without_members/params.yaml
  • templates/code/python/tests/error_enum_without_members/registry/manifest.yaml
  • templates/code/python/tests/error_enum_without_members/registry/model.yaml
  • templates/code/python/tests/error_filtered_required/expected-error.txt
  • templates/code/python/tests/error_filtered_required/params.yaml
  • templates/code/python/tests/error_filtered_required/registry/manifest.yaml
  • templates/code/python/tests/error_filtered_required/registry/myapp.yaml
  • templates/code/python/tests/error_histogram_boundaries_by_unit/expected-error.txt
  • templates/code/python/tests/error_histogram_boundaries_by_unit/params.yaml
  • templates/code/python/tests/error_histogram_boundaries_by_unit/registry/manifest.yaml
  • templates/code/python/tests/error_histogram_boundaries_by_unit/registry/myapp.yaml
  • templates/code/python/tests/error_instrumentation_name_empty/expected-error.txt
  • templates/code/python/tests/error_instrumentation_name_empty/params.yaml
  • templates/code/python/tests/error_instrumentation_name_empty/registry/manifest.yaml
  • templates/code/python/tests/error_instrumentation_name_empty/registry/model.yaml
  • templates/code/python/tests/error_instrumentation_name_type/expected-error.txt
  • templates/code/python/tests/error_instrumentation_name_type/params.yaml
  • templates/code/python/tests/error_instrumentation_name_type/registry/manifest.yaml
  • templates/code/python/tests/error_instrumentation_name_type/registry/model.yaml
  • templates/code/python/tests/error_instrumentation_version_type/expected-error.txt
  • templates/code/python/tests/error_instrumentation_version_type/params.yaml
  • templates/code/python/tests/error_instrumentation_version_type/registry/manifest.yaml
  • templates/code/python/tests/error_instrumentation_version_type/registry/model.yaml
  • templates/code/python/tests/error_integer_enum_overflow/expected-error.txt
  • templates/code/python/tests/error_integer_enum_overflow/registry/manifest.yaml
  • templates/code/python/tests/error_integer_enum_overflow/registry/model.yaml
  • templates/code/python/tests/error_invalid_name/expected-error.txt
  • templates/code/python/tests/error_invalid_name/registry/manifest.yaml
  • templates/code/python/tests/error_invalid_name/registry/model.yaml
  • templates/code/python/tests/error_keyword_parameter/expected-error.txt
  • templates/code/python/tests/error_keyword_parameter/registry/manifest.yaml
  • templates/code/python/tests/error_keyword_parameter/registry/model.yaml
  • templates/code/python/tests/error_metric_collision/expected-error.txt
  • templates/code/python/tests/error_metric_collision/registry/manifest.yaml
  • templates/code/python/tests/error_metric_collision/registry/model.yaml
  • templates/code/python/tests/error_metric_reserved_class/expected-error.txt
  • templates/code/python/tests/error_metric_reserved_class/registry/manifest.yaml
  • templates/code/python/tests/error_metric_reserved_class/registry/model.yaml
  • templates/code/python/tests/error_metric_value_type/expected-error.txt
  • templates/code/python/tests/error_metric_value_type/registry/manifest.yaml
  • templates/code/python/tests/error_metric_value_type/registry/model.yaml
  • templates/code/python/tests/error_missing_metric_value_type/expected-error.txt
  • templates/code/python/tests/error_missing_metric_value_type/registry/manifest.yaml
  • templates/code/python/tests/error_missing_metric_value_type/registry/model.yaml
  • templates/code/python/tests/error_missing_schema/expected-error.txt
  • templates/code/python/tests/error_missing_schema/registry/manifest.yaml
  • templates/code/python/tests/error_missing_schema/registry/model.yaml
  • templates/code/python/tests/error_mixed_enum/expected-error.txt
  • templates/code/python/tests/error_mixed_enum/registry/manifest.yaml
  • templates/code/python/tests/error_mixed_enum/registry/model.yaml
  • templates/code/python/tests/error_observable_collision/expected-error.txt
  • templates/code/python/tests/error_observable_collision/registry/manifest.yaml
  • templates/code/python/tests/error_observable_collision/registry/model.yaml
  • templates/code/python/tests/error_parameter_collision/expected-error.txt
  • templates/code/python/tests/error_parameter_collision/registry/manifest.yaml
  • templates/code/python/tests/error_parameter_collision/registry/model.yaml
  • templates/code/python/tests/error_refinement_value_type/expected-error.txt
  • templates/code/python/tests/error_refinement_value_type/registry/manifest.yaml
  • templates/code/python/tests/error_refinement_value_type/registry/model.yaml
  • templates/code/python/tests/error_reserved_parameter/expected-error.txt
  • templates/code/python/tests/error_reserved_parameter/registry/manifest.yaml
  • templates/code/python/tests/error_reserved_parameter/registry/model.yaml
  • templates/code/python/tests/error_unsupported_attribute_type/expected-error.txt
  • templates/code/python/tests/error_unsupported_attribute_type/registry/manifest.yaml
  • templates/code/python/tests/error_unsupported_attribute_type/registry/model.yaml
  • templates/code/python/tests/error_unversioned_schema/expected-error.txt
  • templates/code/python/tests/error_unversioned_schema/registry/manifest.yaml
  • templates/code/python/tests/error_unversioned_schema/registry/model.yaml
  • templates/code/python/tests/filtering_both/expected/__init__.py
  • templates/code/python/tests/filtering_both/expected/attributes.py
  • templates/code/python/tests/filtering_both/expected/metrics.py
  • templates/code/python/tests/filtering_both/params.yaml
  • templates/code/python/tests/filtering_both/registry/manifest.yaml
  • templates/code/python/tests/filtering_both/registry/model.yaml
  • templates/code/python/tests/filtering_both/test_consumer.py
  • templates/code/python/tests/filtering_exclude_deprecated/expected/__init__.py
  • templates/code/python/tests/filtering_exclude_deprecated/expected/attributes.py
  • templates/code/python/tests/filtering_exclude_deprecated/expected/metrics.py
  • templates/code/python/tests/filtering_exclude_deprecated/params.yaml
  • templates/code/python/tests/filtering_exclude_deprecated/registry/manifest.yaml
  • templates/code/python/tests/filtering_exclude_deprecated/registry/model.yaml
  • templates/code/python/tests/filtering_exclude_deprecated/test_consumer.py
  • templates/code/python/tests/filtering_stable_only/expected/__init__.py
  • templates/code/python/tests/filtering_stable_only/expected/attributes.py
  • templates/code/python/tests/filtering_stable_only/expected/metrics.py
  • templates/code/python/tests/filtering_stable_only/params.yaml
  • templates/code/python/tests/filtering_stable_only/registry/manifest.yaml
  • templates/code/python/tests/filtering_stable_only/registry/model.yaml
  • templates/code/python/tests/filtering_stable_only/test_consumer.py
  • templates/code/python/tests/filtering_unfiltered/expected/__init__.py
  • templates/code/python/tests/filtering_unfiltered/expected/attributes.py
  • templates/code/python/tests/filtering_unfiltered/expected/metrics.py
  • templates/code/python/tests/filtering_unfiltered/registry/manifest.yaml
  • templates/code/python/tests/filtering_unfiltered/registry/model.yaml
  • templates/code/python/tests/filtering_unfiltered/test_consumer.py
  • templates/code/python/tests/histogram_boundaries/expected/__init__.py
  • templates/code/python/tests/histogram_boundaries/expected/metrics.py
  • templates/code/python/tests/histogram_boundaries/registry/manifest.yaml
  • templates/code/python/tests/histogram_boundaries/registry/model.yaml
  • templates/code/python/tests/histogram_boundaries/test_consumer.py
  • templates/code/python/tests/histogram_boundaries_none/expected/__init__.py
  • templates/code/python/tests/histogram_boundaries_none/expected/metrics.py
  • templates/code/python/tests/histogram_boundaries_none/params.yaml
  • templates/code/python/tests/histogram_boundaries_none/registry/manifest.yaml
  • templates/code/python/tests/histogram_boundaries_none/registry/model.yaml
  • templates/code/python/tests/histogram_boundaries_none/test_consumer.py
  • templates/code/python/tests/histogram_boundaries_params/expected/__init__.py
  • templates/code/python/tests/histogram_boundaries_params/expected/metrics.py
  • templates/code/python/tests/histogram_boundaries_params/params.yaml
  • templates/code/python/tests/histogram_boundaries_params/registry/manifest.yaml
  • templates/code/python/tests/histogram_boundaries_params/registry/model.yaml
  • templates/code/python/tests/histogram_boundaries_params/test_consumer.py
  • templates/code/python/tests/imported/dependency/manifest.yaml
  • templates/code/python/tests/imported/dependency/model.yaml
  • templates/code/python/tests/imported/expected/__init__.py
  • templates/code/python/tests/imported/expected/attributes.py
  • templates/code/python/tests/imported/expected/metrics.py
  • templates/code/python/tests/imported/registry/manifest.yaml
  • templates/code/python/tests/imported/registry/model.yaml
  • templates/code/python/tests/imported/test_consumer.py
  • templates/code/python/tests/literal_escaping/expected/__init__.py
  • templates/code/python/tests/literal_escaping/expected/attributes.py
  • templates/code/python/tests/literal_escaping/expected/metrics.py
  • templates/code/python/tests/literal_escaping/registry/manifest.yaml
  • templates/code/python/tests/literal_escaping/registry/model.yaml
  • templates/code/python/tests/literal_escaping/test_consumer.py
  • templates/code/python/tests/long_names/expected/__init__.py
  • templates/code/python/tests/long_names/expected/attributes.py
  • templates/code/python/tests/long_names/expected/metrics.py
  • templates/code/python/tests/long_names/registry/manifest.yaml
  • templates/code/python/tests/long_names/registry/model.yaml
  • templates/code/python/tests/long_names/test_consumer.py
  • templates/code/python/tests/metric_attributes/expected/__init__.py
  • templates/code/python/tests/metric_attributes/expected/attributes.py
  • templates/code/python/tests/metric_attributes/expected/metrics.py
  • templates/code/python/tests/metric_attributes/registry/manifest.yaml
  • templates/code/python/tests/metric_attributes/registry/model.yaml
  • templates/code/python/tests/metric_attributes/test_consumer.py
  • templates/code/python/tests/metrics/expected/__init__.py
  • templates/code/python/tests/metrics/expected/attributes.py
  • templates/code/python/tests/metrics/expected/metrics.py
  • templates/code/python/tests/metrics/registry/manifest.yaml
  • templates/code/python/tests/metrics/registry/model.yaml
  • templates/code/python/tests/metrics/test_consumer.py
  • templates/code/python/tests/naming/expected/__init__.py
  • templates/code/python/tests/naming/expected/attributes.py
  • templates/code/python/tests/naming/expected/metrics.py
  • templates/code/python/tests/naming/registry/manifest.yaml
  • templates/code/python/tests/naming/registry/model.yaml
  • templates/code/python/tests/naming/test_consumer.py
  • templates/code/python/tests/params/expected/__init__.py
  • templates/code/python/tests/params/expected/attributes.py
  • templates/code/python/tests/params/expected/metrics.py
  • templates/code/python/tests/params/params.yaml
  • templates/code/python/tests/params/registry/manifest.yaml
  • templates/code/python/tests/params/registry/model.yaml
  • templates/code/python/tests/params/test_consumer.py
  • templates/code/python/tests/unsupported_signals/expected/__init__.py
  • templates/code/python/tests/unsupported_signals/expected/attributes.py
  • templates/code/python/tests/unsupported_signals/expected/metrics.py
  • templates/code/python/tests/unsupported_signals/registry/manifest.yaml
  • templates/code/python/tests/unsupported_signals/registry/model.yaml
  • templates/code/python/tests/unsupported_signals/test_consumer.py
  • templates/code/python/tests/vendor_prefix_off/expected/__init__.py
  • templates/code/python/tests/vendor_prefix_off/expected/attributes.py
  • templates/code/python/tests/vendor_prefix_off/expected/metrics.py
  • templates/code/python/tests/vendor_prefix_off/registry/manifest.yaml
  • templates/code/python/tests/vendor_prefix_off/registry/model.yaml
  • templates/code/python/tests/vendor_prefix_off/test_consumer.py
  • templates/code/python/weaver.yaml

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Unit, description, kind and bucket boundaries stay inside the instrument, as the Go, Rust and TypeScript packages keep them, so callers have one registry constant to depend on.

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit f8599ba. Configure here.

Comment thread templates/code/python/weaver.yaml Resolved
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
@yordis
yordis merged commit fc667b3 into main Nov 1, 2026
6 checks passed
@yordis
yordis deleted the yordis/feat-python-metrics-template branch November 1, 2026 05:45
Sign up for free to 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