> built 2026-10-13 14:52 UTC from a39040c (master) · umpyre 0.1.11. Details: build_info.json

# index.html.md

<!-- generated by epythet -->

# umpyre

Code analysis and quality metrics tracking system for CI/CD pipelines.

## Overview

`umpyre` provides automated code metrics collection and tracking for Python projects, designed to integrate seamlessly with GitHub Actions CI/CD pipelines. Track code quality trends over time with minimal overhead.

**Key Features:**

- 🎯 **Pluggable collectors**: Workflow status, complexity (wily), coverage, code statistics
- 📊 **Git-based storage**: Metrics stored in separate branch, no external dependencies
- ⚙️ **Config-driven**: Customize via YAML configuration
- 🚀 **Fast & lightweight**: Limited history tracking for speed
- 🔌 **GitHub Action**: Drop-in integration for existing workflows

## Installation

```bash
pip install umpyre
```

## Quick Start

### 1. Create Configuration

Create `.github/umpyre-config.yml`:

```yaml
schema_version: "1.0"

collectors:
  workflow_status:
    enabled: true
    lookback_runs: 10
  
  coverage:
    enabled: true
    source: pytest-cov
  
  umpyre_stats:
    enabled: true
    exclude_dirs: [tests, examples, scrap]

storage:
  branch: code-metrics
  formats: [json, csv]
```

### 2. Add to GitHub Actions

In your `.github/workflows/ci.yml` (after successful PyPI publish):

```yaml
- name: Track Code Metrics
  if: success()  # Only track metrics after successful publish
  uses: i2mint/umpyre/actions/track-metrics@master
  continue-on-error: true  # Never fails CI - see FAILURE_PROTECTION.md
  with:
    github-token: ${{ secrets.GITHUB_TOKEN }}
    config-path: .github/umpyre-config.yml  # Optional: defaults to this path
```

**Important**: Metrics collection has **triple-layer failure protection** and will never break your CI pipeline. See [FAILURE_PROTECTION.md]() for details.

### 3. View Metrics

Metrics are stored in the `code-metrics` branch:

- `metrics.json` - Latest snapshot
- `metrics.csv` - Flat format for analysis
- `history/` - Flat historical records (filename format: `YYYY_MM_DD_HH_MM_SS__commit__version.json`)

See [STORAGE_STRUCTURE.md]() for full details on storage design and querying.

## CLI Usage

```bash
# Collect and store metrics
python -m umpyre.cli collect

# Collect with custom config
python -m umpyre.cli collect --config my-config.yml

# Dry run (don't store)
python -m umpyre.cli collect --no-store

# Validate against thresholds (coming soon)
python -m umpyre.cli validate
```

## Querying Stored Metrics

Metrics are stored in a flat structure with parseable filenames: `YYYY_MM_DD_HH_MM_SS__shahash__version.json`

### Shell Queries

```bash
# Switch to metrics branch
git checkout code-metrics

# Get all metrics from November 14
ls history/2025_11_14_*

# Find metrics for specific commit
ls history/*__700e012__*

# Find all v0.1.0 metrics
ls history/*__0.1.0.json

# Get latest 10 metrics
ls -t history/ | head -10

# Exclude metrics without version
ls history/ | grep -v "__none.json"
```

### Python Queries

```python
from pathlib import Path
from umpyre.storage import (
    parse_metric_filename,
    find_metrics_by_commit,
    find_metrics_by_version,
    get_latest_metric_for_version,
    get_all_versions,
)

history_dir = Path("history")

# Parse filename
info = parse_metric_filename("2025_11_14_22_45_00__700e012__0.1.0.json")
print(info["commit_sha"])  # '700e012'
print(info["pypi_version"])  # '0.1.0'
print(info["timestamp"])  # datetime object

# Find by commit
metrics = find_metrics_by_commit(history_dir, "700e012")

# Find all metrics for a version
all_v0_1_0 = find_metrics_by_version(history_dir, "0.1.0")

# Get latest metric for a version
latest = get_latest_metric_for_version(history_dir, "0.1.0")

# List all versions
versions = get_all_versions(history_dir)
print(versions)  # ['0.1.0', '0.1.1', '0.2.0']
```

See `STORAGE_STRUCTURE.md` for detailed storage design documentation.

## Available Collectors

### WorkflowStatusCollector

Tracks GitHub CI/CD health via API:

- Last run status (success/failure)
- Recent failure count
- Last successful run timestamp

### CoverageCollector

Extracts test coverage from pytest-cov or coverage.py:

- Line coverage %
- Branch coverage %
- Supports JSON and XML formats

### WilyCollector

Complexity metrics using wily (requires installation):

- Cyclomatic complexity
- Maintainability index
- Limited to recent commits for speed

### UmpyreCollector

Code statistics using built-in analyzer:

- Function/class counts
- Line metrics (total, empty, comments, docs)
- Code ratios and averages

## Configuration Reference

See `.github/umpyre-config.yml` for full options:

```yaml
schema_version: "1.0"  # Required

collectors:
  workflow_status:
    enabled: true
    lookback_runs: 10  # Number of recent runs to analyze
  
  wily:
    enabled: true
    max_revisions: 5  # Limit for performance
    operators: [cyclomatic, maintainability]
  
  coverage:
    enabled: true
    source: pytest-cov  # or 'coverage'
  
  umpyre_stats:
    enabled: true
    exclude_dirs: [tests, examples, scrap]

storage:
  branch: code-metrics  # Branch name for metrics
  formats: [json, csv]  # Output formats
  retention:
    strategy: all  # or: last_n_days, last_n_commits

visualization:  # Coming in Phase 2
  generate_plots: true
  generate_readme: true
  plot_metrics: [maintainability, coverage, loc]

thresholds:  # Coming in Phase 3
  enabled: false

aggregation:  # Coming in Phase 2
  enabled: false
```

## Architecture

```default
umpyre/
├── collectors/          # Metric collectors (pluggable)
│   ├── base.py         # Abstract Collector with Mapping interface
│   ├── workflow_status.py
│   ├── wily_collector.py
│   ├── coverage_collector.py
│   └── umpyre_collector.py
├── storage/            # Persistence layer
│   ├── git_branch.py  # Git-based storage
│   └── formats.py     # JSON/CSV serialization
├── config.py           # YAML config loading
├── schema.py           # Versioned metric schema
└── cli.py              # Command-line interface
```

## Metric Schema (v1.0)

```json
{
  "schema_version": "1.0",
  "timestamp": "2025-01-15T10:30:00Z",
  "commit_sha": "abc123...",
  "commit_message": "Fix bug in parser",
  "python_version": "3.10",
  "workflow_status": {
    "last_run_status": "success",
    "recent_failure_count": 0
  },
  "metrics": {
    "complexity": {
      "cyclomatic_avg": 3.2,
      "maintainability_index": 75.3
    },
    "coverage": {
      "line_coverage": 87.5,
      "branch_coverage": 82.1
    },
    "code_stats": {
      "num_functions": 342,
      "num_classes": 28
    }
  },
  "collection_duration_seconds": 12.3
}
```

## Roadmap

**Phase 1 (✅ Complete)**: Core tracking system

- Config-driven collectors
- Git branch storage
- CLI and GitHub Action

**Phase 2 (Planned)**: Visualization & Aggregation

- Plot generation (matplotlib/plotly)
- Auto-generated README with charts
- Cross-repository aggregation
- Organization-wide dashboards

**Phase 3 (Planned)**: Advanced Features

- Security metrics (bandit)
- Docstring coverage (interrogate)
- Threshold validation with custom validators
- Data pruning and compression
- Schema migration utilities

## Contributing

Contributions welcome! See `misc/CHANGELOG.md` for recent changes.

## Original Code Statistics Feature

Get stats about packages (existing functionality preserved):

```python
from umpyre import modules_info_df, stats_of
import collections

# Analyze a single package
modules_info_df(collections)

# Compare multiple packages
stats_of(["urllib", "json", "collections"])
```

See original README examples above for detailed usage.

## License

Apache-2.0

<p class="epythet-aggregates">This documentation as a single file: <a href="umpyre.md">umpyre.md</a> (Markdown, for agents).</p>


# _autosummary/umpyre.cli.html.md

# umpyre.cli

Command-line interface for umpyre.

### Functions

| [`cmd_collect`](_autosummary/umpyre.cli.html.md#umpyre.cli.cmd_collect)(args)   | Collect and store metrics.           |
|----------------------------------------------------------------------|--------------------------------------|
| [`cmd_validate`](_autosummary/umpyre.cli.html.md#umpyre.cli.cmd_validate)(args)  | Validate metrics against thresholds. |
| [`main`](_autosummary/umpyre.cli.html.md#umpyre.cli.main)()              | Main CLI entry point.                |

### umpyre.cli.cmd_collect(args)

Collect and store metrics.

### umpyre.cli.cmd_validate(args)

Validate metrics against thresholds.

### umpyre.cli.main()

Main CLI entry point.


# _autosummary/umpyre.collectors.base.html.md

# umpyre.collectors.base

Base collector class with Mapping interface.

### Classes

| [`CollectorRegistry`](_autosummary/umpyre.collectors.base.html.md#umpyre.collectors.base.CollectorRegistry)()   | Registry for managing available collectors.                  |
|------------------------------------------------------------------------|--------------------------------------------------------------|
| [`MetricCollector`](_autosummary/umpyre.collectors.base.html.md#umpyre.collectors.base.MetricCollector)()     | Abstract base for metric collectors using Mapping interface. |

### *class* umpyre.collectors.base.CollectorRegistry

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Registry for managing available collectors.

#### get(name)

Get collector class by name.

* **Return type:**
  [`type`](https://docs.python.org/3/builtins/functions.html#type)[[`MetricCollector`](_autosummary/umpyre.collectors.base.html.md#umpyre.collectors.base.MetricCollector)]

#### list_collectors()

List all registered collector names.

* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]

#### register(name, collector_class)

Register a collector class.

* **Parameters:**
  * **name** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Collector identifier
  * **collector_class** ([`type`](https://docs.python.org/3/builtins/functions.html#type)[[`MetricCollector`](_autosummary/umpyre.collectors.base.html.md#umpyre.collectors.base.MetricCollector)]) – MetricCollector subclass

### *class* umpyre.collectors.base.MetricCollector

Bases: [`Mapping`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Mapping), [`ABC`](https://docs.python.org/3/library/abc.html#abc.ABC)

Abstract base for metric collectors using Mapping interface.

Collectors implement the Mapping protocol to provide dict-like access
to collected metrics, enabling flexible composition and iteration.

### Example

```pycon
>>> class SimpleCollector(MetricCollector):
...     def collect(self) -> dict:
...         return {'lines': 100, 'functions': 10}
>>> collector = SimpleCollector()
>>> collector['lines']
100
>>> list(collector)
['lines', 'functions']
```

#### *abstractmethod* collect()

Collect metrics and return as dictionary.

* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)
* **Returns:**
  Dictionary of metric names to values

#### refresh()

Force re-collection of metrics.

#### to_dict()

Export all metrics as dictionary.

* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)


# _autosummary/umpyre.collectors.coverage_collector.html.md

# umpyre.collectors.coverage_collector

Collector for test coverage metrics.

### Classes

| [`CoverageCollector`](_autosummary/umpyre.collectors.coverage_collector.html.md#umpyre.collectors.coverage_collector.CoverageCollector)([repo_path, source, ...])   | Collect test coverage metrics from coverage reports.   |
|------------------------------------------------------------------------------------------------|--------------------------------------------------------|

### *class* umpyre.collectors.coverage_collector.CoverageCollector(repo_path=None, source='pytest-cov', coverage_file=None)

Bases: [`MetricCollector`](_autosummary/umpyre.collectors.base.html.md#umpyre.collectors.base.MetricCollector)

Collect test coverage metrics from coverage reports.

Supports:

- coverage.py JSON reports
- coverage.py XML reports (Cobertura format)

Tracks:

- Line coverage percentage
- Branch coverage percentage (if available)
- Statements covered/total

### Example

```pycon
>>> # This requires coverage report files
>>> # Skip in doctest as it requires actual test runs
>>> True
```

#### collect()

Collect coverage metrics from report files.

* **Returns:**
  - line_coverage: Line coverage percentage
  - branch_coverage: Branch coverage percentage (may be 0 if not tracked)
  - statements_covered: Number of statements covered
  - statements_total: Total number of statements
* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)


# _autosummary/umpyre.collectors.html.md

# umpyre.collectors

Collectors package - metric collection implementations.

### Classes

| [`MetricCollector`](_autosummary/umpyre.collectors.html.md#umpyre.collectors.MetricCollector)()                              | Abstract base for metric collectors using Mapping interface.   |
|-------------------------------------------------------------------------------------------------|----------------------------------------------------------------|
| [`CollectorRegistry`](_autosummary/umpyre.collectors.html.md#umpyre.collectors.CollectorRegistry)()                            | Registry for managing available collectors.                    |
| [`UmpyreCollector`](_autosummary/umpyre.collectors.html.md#umpyre.collectors.UmpyreCollector)([root_path, exclude_dirs])     | Collect code statistics using AST parsing (no code execution). |
| [`WorkflowStatusCollector`](_autosummary/umpyre.collectors.html.md#umpyre.collectors.WorkflowStatusCollector)(repo[, token, ...])    | Collect GitHub workflow status using GitHub API.               |
| [`WilyCollector`](_autosummary/umpyre.collectors.html.md#umpyre.collectors.WilyCollector)([repo_path, max_revisions, ...]) | Collect complexity metrics using wily.                         |
| [`CoverageCollector`](_autosummary/umpyre.collectors.html.md#umpyre.collectors.CoverageCollector)([repo_path, source, ...])    | Collect test coverage metrics from coverage reports.           |

### *class* umpyre.collectors.CollectorRegistry

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Registry for managing available collectors.

#### get(name)

Get collector class by name.

* **Return type:**
  [`type`](https://docs.python.org/3/builtins/functions.html#type)[[`MetricCollector`](_autosummary/umpyre.collectors.base.html.md#umpyre.collectors.base.MetricCollector)]

#### list_collectors()

List all registered collector names.

* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]

#### register(name, collector_class)

Register a collector class.

* **Parameters:**
  * **name** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Collector identifier
  * **collector_class** ([`type`](https://docs.python.org/3/builtins/functions.html#type)[[`MetricCollector`](_autosummary/umpyre.collectors.base.html.md#umpyre.collectors.base.MetricCollector)]) – MetricCollector subclass

### *class* umpyre.collectors.CoverageCollector(repo_path=None, source='pytest-cov', coverage_file=None)

Bases: [`MetricCollector`](_autosummary/umpyre.collectors.base.html.md#umpyre.collectors.base.MetricCollector)

Collect test coverage metrics from coverage reports.

Supports:

- coverage.py JSON reports
- coverage.py XML reports (Cobertura format)

Tracks:

- Line coverage percentage
- Branch coverage percentage (if available)
- Statements covered/total

### Example

```pycon
>>> # This requires coverage report files
>>> # Skip in doctest as it requires actual test runs
>>> True
```

#### collect()

Collect coverage metrics from report files.

* **Returns:**
  - line_coverage: Line coverage percentage
  - branch_coverage: Branch coverage percentage (may be 0 if not tracked)
  - statements_covered: Number of statements covered
  - statements_total: Total number of statements
* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)

### *class* umpyre.collectors.MetricCollector

Bases: [`Mapping`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Mapping), [`ABC`](https://docs.python.org/3/library/abc.html#abc.ABC)

Abstract base for metric collectors using Mapping interface.

Collectors implement the Mapping protocol to provide dict-like access
to collected metrics, enabling flexible composition and iteration.

### Example

```pycon
>>> class SimpleCollector(MetricCollector):
...     def collect(self) -> dict:
...         return {'lines': 100, 'functions': 10}
>>> collector = SimpleCollector()
>>> collector['lines']
100
>>> list(collector)
['lines', 'functions']
```

#### *abstractmethod* collect()

Collect metrics and return as dictionary.

* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)
* **Returns:**
  Dictionary of metric names to values

#### refresh()

Force re-collection of metrics.

#### to_dict()

Export all metrics as dictionary.

* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)

### *class* umpyre.collectors.UmpyreCollector(root_path=None, exclude_dirs=None)

Bases: [`MetricCollector`](_autosummary/umpyre.collectors.base.html.md#umpyre.collectors.base.MetricCollector)

Collect code statistics using AST parsing (no code execution).

Provides metrics like:

- Number of functions and classes
- Lines of code (total, empty, comments, docs)
- Code ratios (comment/empty/function lines)
- Mean lines per function

Uses AST parsing instead of dynamic imports for safety.

### Example

```pycon
>>> import tempfile
>>> from pathlib import Path
>>> # Create a simple Python file for testing
>>> with tempfile.TemporaryDirectory() as tmpdir:
...     test_file = Path(tmpdir) / "test.py"
...     test_file.write_text('''def hello():
...     """Say hello."""
...     return "hello"
...
... class Greeter:
...     """A greeter."""
...     pass
... ''')
...     collector = UmpyreCollector(tmpdir)
...     metrics = collector.collect()
...     metrics['num_functions'] >= 1 and metrics['num_classes'] >= 1
True
```

#### collect()

Collect code statistics from root directory using AST parsing.

* **Returns:**
  - num_functions: Total number of functions
  - num_classes: Total number of classes
  - total_lines: Total lines of code
  - empty_lines: Number of empty lines
  - comment_lines: Number of comment lines
  - docs_lines: Number of documentation lines
  - function_lines: Lines in functions
  - empty_lines_ratio: Ratio of empty lines
  - comment_lines_ratio: Ratio of comment lines
  - function_lines_ratio: Ratio of function lines
  - mean_lines_per_function: Average lines per function
  - files_analyzed: Number of files successfully analyzed
* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)

### *class* umpyre.collectors.WilyCollector(repo_path=None, max_revisions=5, operators=None)

Bases: [`MetricCollector`](_autosummary/umpyre.collectors.base.html.md#umpyre.collectors.base.MetricCollector)

Collect complexity metrics using wily.

Tracks:

- Cyclomatic complexity (average)
- Maintainability index
- Total lines of code
- Files analyzed

#### NOTE
Limited to recent commits (max_revisions) for performance.

### Example

```pycon
>>> # This requires wily to be installed and a git repo
>>> # Skip in doctest as it requires git setup
>>> True
```

#### collect()

Collect complexity metrics using wily.

* **Returns:**
  - cyclomatic_avg: Average cyclomatic complexity
  - maintainability_index: Maintainability index score
  - total_loc: Total lines of code
  - files_analyzed: Number of files analyzed
* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)

### *class* umpyre.collectors.WorkflowStatusCollector(repo, token=None, lookback_runs=10, workflow_name=None)

Bases: [`MetricCollector`](_autosummary/umpyre.collectors.base.html.md#umpyre.collectors.base.MetricCollector)

Collect GitHub workflow status using GitHub API.

Tracks:

- Last workflow run status (success/failure)
- Last successful run timestamp
- Recent failure count
- Workflow run URL

### Example

```pycon
>>> # Mock test (requires actual GitHub API)
>>> import os
>>> if os.getenv('GITHUB_TOKEN'):
...     collector = WorkflowStatusCollector(
...         repo="thorwhalen/astate",
...         token=os.getenv('GITHUB_TOKEN')
...     )
...     metrics = collector.collect()
...     'last_run_status' in metrics
... else:
...     True  # Skip if no token
True
```

#### collect()

Collect workflow status from GitHub API.

* **Returns:**
  - last_run_status: ‘success’, ‘failure’, or ‘other’
  - last_success_timestamp: ISO timestamp or None
  - recent_failure_count: Number of failures in lookback window
  - run_url: URL of last run
  - total_runs_analyzed: Number of runs examined
* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)

### Modules

| [`base`](_autosummary/umpyre.collectors.base.html.md#module-umpyre.collectors.base)                             | Base collector class with Mapping interface.                       |
|-----------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------|
| [`coverage_collector`](_autosummary/umpyre.collectors.coverage_collector.html.md#module-umpyre.collectors.coverage_collector) | Collector for test coverage metrics.                               |
| [`umpyre_collector`](_autosummary/umpyre.collectors.umpyre_collector.html.md#module-umpyre.collectors.umpyre_collector)     | Collector using AST-based code analysis (safe, no code execution). |
| [`wily_collector`](_autosummary/umpyre.collectors.wily_collector.html.md#module-umpyre.collectors.wily_collector)         | Collector for complexity metrics using wily.                       |
| [`workflow_status`](_autosummary/umpyre.collectors.workflow_status.html.md#module-umpyre.collectors.workflow_status)       | Collector for GitHub workflow status using GitHub API.             |


# _autosummary/umpyre.collectors.umpyre_collector.html.md

# umpyre.collectors.umpyre_collector

Collector using AST-based code analysis (safe, no code execution).

### Classes

| [`UmpyreCollector`](_autosummary/umpyre.collectors.umpyre_collector.html.md#umpyre.collectors.umpyre_collector.UmpyreCollector)([root_path, exclude_dirs])   | Collect code statistics using AST parsing (no code execution).   |
|-----------------------------------------------------------------------------------------------|------------------------------------------------------------------|

### *class* umpyre.collectors.umpyre_collector.UmpyreCollector(root_path=None, exclude_dirs=None)

Bases: [`MetricCollector`](_autosummary/umpyre.collectors.base.html.md#umpyre.collectors.base.MetricCollector)

Collect code statistics using AST parsing (no code execution).

Provides metrics like:

- Number of functions and classes
- Lines of code (total, empty, comments, docs)
- Code ratios (comment/empty/function lines)
- Mean lines per function

Uses AST parsing instead of dynamic imports for safety.

### Example

```pycon
>>> import tempfile
>>> from pathlib import Path
>>> # Create a simple Python file for testing
>>> with tempfile.TemporaryDirectory() as tmpdir:
...     test_file = Path(tmpdir) / "test.py"
...     test_file.write_text('''def hello():
...     """Say hello."""
...     return "hello"
...
... class Greeter:
...     """A greeter."""
...     pass
... ''')
...     collector = UmpyreCollector(tmpdir)
...     metrics = collector.collect()
...     metrics['num_functions'] >= 1 and metrics['num_classes'] >= 1
True
```

#### collect()

Collect code statistics from root directory using AST parsing.

* **Returns:**
  - num_functions: Total number of functions
  - num_classes: Total number of classes
  - total_lines: Total lines of code
  - empty_lines: Number of empty lines
  - comment_lines: Number of comment lines
  - docs_lines: Number of documentation lines
  - function_lines: Lines in functions
  - empty_lines_ratio: Ratio of empty lines
  - comment_lines_ratio: Ratio of comment lines
  - function_lines_ratio: Ratio of function lines
  - mean_lines_per_function: Average lines per function
  - files_analyzed: Number of files successfully analyzed
* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)


# _autosummary/umpyre.collectors.wily_collector.html.md

# umpyre.collectors.wily_collector

Collector for complexity metrics using wily.

### Classes

| [`WilyCollector`](_autosummary/umpyre.collectors.wily_collector.html.md#umpyre.collectors.wily_collector.WilyCollector)([repo_path, max_revisions, ...])   | Collect complexity metrics using wily.   |
|---------------------------------------------------------------------------------------------------|------------------------------------------|

### *class* umpyre.collectors.wily_collector.WilyCollector(repo_path=None, max_revisions=5, operators=None)

Bases: [`MetricCollector`](_autosummary/umpyre.collectors.base.html.md#umpyre.collectors.base.MetricCollector)

Collect complexity metrics using wily.

Tracks:

- Cyclomatic complexity (average)
- Maintainability index
- Total lines of code
- Files analyzed

#### NOTE
Limited to recent commits (max_revisions) for performance.

### Example

```pycon
>>> # This requires wily to be installed and a git repo
>>> # Skip in doctest as it requires git setup
>>> True
```

#### collect()

Collect complexity metrics using wily.

* **Returns:**
  - cyclomatic_avg: Average cyclomatic complexity
  - maintainability_index: Maintainability index score
  - total_loc: Total lines of code
  - files_analyzed: Number of files analyzed
* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)


# _autosummary/umpyre.collectors.workflow_status.html.md

# umpyre.collectors.workflow_status

Collector for GitHub workflow status using GitHub API.

### Classes

| [`WorkflowStatusCollector`](_autosummary/umpyre.collectors.workflow_status.html.md#umpyre.collectors.workflow_status.WorkflowStatusCollector)(repo[, token, ...])   | Collect GitHub workflow status using GitHub API.   |
|------------------------------------------------------------------------------------------------|----------------------------------------------------|

### *class* umpyre.collectors.workflow_status.WorkflowStatusCollector(repo, token=None, lookback_runs=10, workflow_name=None)

Bases: [`MetricCollector`](_autosummary/umpyre.collectors.base.html.md#umpyre.collectors.base.MetricCollector)

Collect GitHub workflow status using GitHub API.

Tracks:

- Last workflow run status (success/failure)
- Last successful run timestamp
- Recent failure count
- Workflow run URL

### Example

```pycon
>>> # Mock test (requires actual GitHub API)
>>> import os
>>> if os.getenv('GITHUB_TOKEN'):
...     collector = WorkflowStatusCollector(
...         repo="thorwhalen/astate",
...         token=os.getenv('GITHUB_TOKEN')
...     )
...     metrics = collector.collect()
...     'last_run_status' in metrics
... else:
...     True  # Skip if no token
True
```

#### collect()

Collect workflow status from GitHub API.

* **Returns:**
  - last_run_status: ‘success’, ‘failure’, or ‘other’
  - last_success_timestamp: ISO timestamp or None
  - recent_failure_count: Number of failures in lookback window
  - run_url: URL of last run
  - total_runs_analyzed: Number of runs examined
* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)


# _autosummary/umpyre.config.html.md

# umpyre.config

Configuration loading and validation for umpyre.

### Classes

| [`Config`](_autosummary/umpyre.config.html.md#umpyre.config.Config)([config_path, config_dict])   | Configuration manager for umpyre metrics collection.   |
|---------------------------------------------------------------------------------------|--------------------------------------------------------|

### Exceptions

| [`ConfigError`](_autosummary/umpyre.config.html.md#umpyre.config.ConfigError)   | Raised when configuration is invalid.   |
|----------------------------------------------------------------|-----------------------------------------|

### *class* umpyre.config.Config(config_path=None, config_dict=None)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Configuration manager for umpyre metrics collection.

#### collector_config(collector_name)

Get configuration for a specific collector.

* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)

#### *classmethod* from_dict(config)

Create config from dictionary.

* **Return type:**
  [`Config`](_autosummary/umpyre.config.html.md#umpyre.config.Config)

#### *classmethod* from_file(path)

Load config from YAML file.

* **Return type:**
  [`Config`](_autosummary/umpyre.config.html.md#umpyre.config.Config)

#### get(\*keys, default=None)

Get nested config value.

* **Parameters:**
  * **\*keys** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Nested keys (e.g., ‘collectors’, ‘wily’, ‘enabled’)
  * **default** ([`Any`](https://docs.python.org/3/library/typing.html#typing.Any)) – Default value if key not found
* **Return type:**
  [`Any`](https://docs.python.org/3/library/typing.html#typing.Any)
* **Returns:**
  Config value or default

```pycon
>>> config = Config(config_dict={'collectors': {'wily': {'enabled': True}}})
>>> config.get('collectors', 'wily', 'enabled')
True
>>> config.get('collectors', 'missing', default='default_value')
'default_value'
```

#### is_collector_enabled(collector_name)

Check if a collector is enabled.

* **Return type:**
  [`bool`](https://docs.python.org/3/builtins/functions.html#bool)

#### *property* retention_strategy *: [str](https://docs.python.org/3/builtins/stdtypes.html#str)*

Get data retention strategy.

#### *property* storage_branch *: [str](https://docs.python.org/3/builtins/stdtypes.html#str)*

Get the storage branch name.

#### *property* storage_formats *: [list](https://docs.python.org/3/builtins/stdtypes.html#list)[[str](https://docs.python.org/3/builtins/stdtypes.html#str)]*

Get enabled storage formats.

#### to_dict()

Export config as dictionary.

* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)

### *exception* umpyre.config.ConfigError

Bases: [`Exception`](https://docs.python.org/3/builtins/exceptions.html#Exception)

Raised when configuration is invalid.


# _autosummary/umpyre.html.md

# umpyre

Umpyre - Code analysis and quality metrics tracking.

### Functions

| [`modules_info_gen`](_autosummary/umpyre.html.md#umpyre.modules_info_gen)(root[, filepath_filt, on_error])   | Yields statistics (as dicts) of modules under the root module or directory of a python package.   |
|------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------|
| [`modules_info_df`](_autosummary/umpyre.html.md#umpyre.modules_info_df)(root[, filepath_filt, ...])         | A pandas DataFrame of stats of the root (package or directory thereof).                           |
| [`modules_info_df_stats`](_autosummary/umpyre.html.md#umpyre.modules_info_df_stats)(root[, filepath_filt, ...])   | A pandas Series of statistics over all modules of some root (package or directory thereof).       |
| [`stats_of`](_autosummary/umpyre.html.md#umpyre.stats_of)(modules[, filepath_filt, ...])             | A dataframe of stats of the input modules.                                                        |
| `get_objs`(root, k)                                                                                  |                                                                                                   |
| [`serialize_metrics`](_autosummary/umpyre.html.md#umpyre.serialize_metrics)(data, output_path[, format])      | Serialize metrics to file.                                                                        |
| [`deserialize_metrics`](_autosummary/umpyre.html.md#umpyre.deserialize_metrics)(file_path[, format])            | Deserialize metrics from file.                                                                    |

### Classes

| [`Config`](_autosummary/umpyre.html.md#umpyre.Config)([config_path, config_dict])             | Configuration manager for umpyre metrics collection.           |
|-------------------------------------------------------------------------------------------------|----------------------------------------------------------------|
| [`MetricSchema`](_autosummary/umpyre.html.md#umpyre.MetricSchema)([version])                        | Versioned schema for metrics storage with migration support.   |
| [`MetricCollector`](_autosummary/umpyre.html.md#umpyre.MetricCollector)()                              | Abstract base for metric collectors using Mapping interface.   |
| [`CollectorRegistry`](_autosummary/umpyre.html.md#umpyre.CollectorRegistry)()                            | Registry for managing available collectors.                    |
| [`UmpyreCollector`](_autosummary/umpyre.html.md#umpyre.UmpyreCollector)([root_path, exclude_dirs])     | Collect code statistics using AST parsing (no code execution). |
| [`WorkflowStatusCollector`](_autosummary/umpyre.html.md#umpyre.WorkflowStatusCollector)(repo[, token, ...])    | Collect GitHub workflow status using GitHub API.               |
| [`WilyCollector`](_autosummary/umpyre.html.md#umpyre.WilyCollector)([repo_path, max_revisions, ...]) | Collect complexity metrics using wily.                         |
| [`CoverageCollector`](_autosummary/umpyre.html.md#umpyre.CoverageCollector)([repo_path, source, ...])    | Collect test coverage metrics from coverage reports.           |
| [`GitBranchStorage`](_autosummary/umpyre.html.md#umpyre.GitBranchStorage)(repo_path[, remote, token])   | Store metrics in a separate git branch.                        |

### *class* umpyre.CollectorRegistry

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Registry for managing available collectors.

#### get(name)

Get collector class by name.

* **Return type:**
  [`type`](https://docs.python.org/3/builtins/functions.html#type)[[`MetricCollector`](_autosummary/umpyre.collectors.base.html.md#umpyre.collectors.base.MetricCollector)]

#### list_collectors()

List all registered collector names.

* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]

#### register(name, collector_class)

Register a collector class.

* **Parameters:**
  * **name** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Collector identifier
  * **collector_class** ([`type`](https://docs.python.org/3/builtins/functions.html#type)[[`MetricCollector`](_autosummary/umpyre.collectors.base.html.md#umpyre.collectors.base.MetricCollector)]) – MetricCollector subclass

### *class* umpyre.Config(config_path=None, config_dict=None)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Configuration manager for umpyre metrics collection.

#### collector_config(collector_name)

Get configuration for a specific collector.

* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)

#### *classmethod* from_dict(config)

Create config from dictionary.

* **Return type:**
  [`Config`](_autosummary/umpyre.config.html.md#umpyre.config.Config)

#### *classmethod* from_file(path)

Load config from YAML file.

* **Return type:**
  [`Config`](_autosummary/umpyre.config.html.md#umpyre.config.Config)

#### get(\*keys, default=None)

Get nested config value.

* **Parameters:**
  * **\*keys** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Nested keys (e.g., ‘collectors’, ‘wily’, ‘enabled’)
  * **default** ([`Any`](https://docs.python.org/3/library/typing.html#typing.Any)) – Default value if key not found
* **Return type:**
  [`Any`](https://docs.python.org/3/library/typing.html#typing.Any)
* **Returns:**
  Config value or default

```pycon
>>> config = Config(config_dict={'collectors': {'wily': {'enabled': True}}})
>>> config.get('collectors', 'wily', 'enabled')
True
>>> config.get('collectors', 'missing', default='default_value')
'default_value'
```

#### is_collector_enabled(collector_name)

Check if a collector is enabled.

* **Return type:**
  [`bool`](https://docs.python.org/3/builtins/functions.html#bool)

#### *property* retention_strategy *: [str](https://docs.python.org/3/builtins/stdtypes.html#str)*

Get data retention strategy.

#### *property* storage_branch *: [str](https://docs.python.org/3/builtins/stdtypes.html#str)*

Get the storage branch name.

#### *property* storage_formats *: [list](https://docs.python.org/3/builtins/stdtypes.html#list)[[str](https://docs.python.org/3/builtins/stdtypes.html#str)]*

Get enabled storage formats.

#### to_dict()

Export config as dictionary.

* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)

### *class* umpyre.CoverageCollector(repo_path=None, source='pytest-cov', coverage_file=None)

Bases: [`MetricCollector`](_autosummary/umpyre.collectors.base.html.md#umpyre.collectors.base.MetricCollector)

Collect test coverage metrics from coverage reports.

Supports:

- coverage.py JSON reports
- coverage.py XML reports (Cobertura format)

Tracks:

- Line coverage percentage
- Branch coverage percentage (if available)
- Statements covered/total

### Example

```pycon
>>> # This requires coverage report files
>>> # Skip in doctest as it requires actual test runs
>>> True
```

#### collect()

Collect coverage metrics from report files.

* **Returns:**
  - line_coverage: Line coverage percentage
  - branch_coverage: Branch coverage percentage (may be 0 if not tracked)
  - statements_covered: Number of statements covered
  - statements_total: Total number of statements
* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)

### *class* umpyre.GitBranchStorage(repo_path, remote='origin', , token=None)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Store metrics in a separate git branch.

This provides versioned, branch-based storage without polluting
the main branch or requiring external artifacts.

### Example

```pycon
>>> storage = GitBranchStorage(repo_path="/path/to/repo")
>>> metrics = {"lines": 100, "functions": 10}
>>> storage.store_metrics(metrics, "abc123", branch="code-metrics")
```

#### store_metrics(metrics, commit_sha, branch='code-metrics', formats=None)

Store metrics to git branch.

* **Parameters:**
  * **metrics** ([`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)) – Metric dictionary to store
  * **commit_sha** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Git commit SHA
  * **branch** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Target branch name
  * **formats** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]]) – List of formats (‘json’, ‘csv’)

### *class* umpyre.MetricCollector

Bases: [`Mapping`](https://docs.python.org/3/library/collections.abc.html#collections.abc.Mapping), [`ABC`](https://docs.python.org/3/library/abc.html#abc.ABC)

Abstract base for metric collectors using Mapping interface.

Collectors implement the Mapping protocol to provide dict-like access
to collected metrics, enabling flexible composition and iteration.

### Example

```pycon
>>> class SimpleCollector(MetricCollector):
...     def collect(self) -> dict:
...         return {'lines': 100, 'functions': 10}
>>> collector = SimpleCollector()
>>> collector['lines']
100
>>> list(collector)
['lines', 'functions']
```

#### *abstractmethod* collect()

Collect metrics and return as dictionary.

* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)
* **Returns:**
  Dictionary of metric names to values

#### refresh()

Force re-collection of metrics.

#### to_dict()

Export all metrics as dictionary.

* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)

### *class* umpyre.MetricSchema(version='1.0')

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Versioned schema for metrics storage with migration support.

#### *classmethod* create_metric_data(commit_sha, metrics, commit_message=None, python_version=None, workflow_status=None, collection_duration=None)

Create a standardized metric data structure.

* **Parameters:**
  * **commit_sha** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Git commit SHA
  * **metrics** ([`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)) – Dictionary of collected metrics
  * **commit_message** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]) – Optional commit message
  * **python_version** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]) – Optional Python version string
  * **workflow_status** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)]) – Optional workflow status dict
  * **collection_duration** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`float`](https://docs.python.org/3/builtins/functions.html#float)]) – Optional collection time in seconds
* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)
* **Returns:**
  Standardized metric dictionary

#### *classmethod* current_version()

Return the current schema version.

* **Return type:**
  [`str`](https://docs.python.org/3/builtins/stdtypes.html#str)

#### *classmethod* migrate(data, from_version)

Migrate data from old schema version to current version.

* **Parameters:**
  * **data** ([`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)) – Metric data in old format
  * **from_version** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Version of the input data
* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)
* **Returns:**
  Migrated data in current schema format

#### *classmethod* validate(data)

Validate that data conforms to schema.

* **Parameters:**
  **data** ([`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)) – Metric data to validate
* **Return type:**
  [`bool`](https://docs.python.org/3/builtins/functions.html#bool)
* **Returns:**
  True if valid, raises ValueError otherwise

### *class* umpyre.UmpyreCollector(root_path=None, exclude_dirs=None)

Bases: [`MetricCollector`](_autosummary/umpyre.collectors.base.html.md#umpyre.collectors.base.MetricCollector)

Collect code statistics using AST parsing (no code execution).

Provides metrics like:

- Number of functions and classes
- Lines of code (total, empty, comments, docs)
- Code ratios (comment/empty/function lines)
- Mean lines per function

Uses AST parsing instead of dynamic imports for safety.

### Example

```pycon
>>> import tempfile
>>> from pathlib import Path
>>> # Create a simple Python file for testing
>>> with tempfile.TemporaryDirectory() as tmpdir:
...     test_file = Path(tmpdir) / "test.py"
...     test_file.write_text('''def hello():
...     """Say hello."""
...     return "hello"
...
... class Greeter:
...     """A greeter."""
...     pass
... ''')
...     collector = UmpyreCollector(tmpdir)
...     metrics = collector.collect()
...     metrics['num_functions'] >= 1 and metrics['num_classes'] >= 1
True
```

#### collect()

Collect code statistics from root directory using AST parsing.

* **Returns:**
  - num_functions: Total number of functions
  - num_classes: Total number of classes
  - total_lines: Total lines of code
  - empty_lines: Number of empty lines
  - comment_lines: Number of comment lines
  - docs_lines: Number of documentation lines
  - function_lines: Lines in functions
  - empty_lines_ratio: Ratio of empty lines
  - comment_lines_ratio: Ratio of comment lines
  - function_lines_ratio: Ratio of function lines
  - mean_lines_per_function: Average lines per function
  - files_analyzed: Number of files successfully analyzed
* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)

### *class* umpyre.WilyCollector(repo_path=None, max_revisions=5, operators=None)

Bases: [`MetricCollector`](_autosummary/umpyre.collectors.base.html.md#umpyre.collectors.base.MetricCollector)

Collect complexity metrics using wily.

Tracks:

- Cyclomatic complexity (average)
- Maintainability index
- Total lines of code
- Files analyzed

#### NOTE
Limited to recent commits (max_revisions) for performance.

### Example

```pycon
>>> # This requires wily to be installed and a git repo
>>> # Skip in doctest as it requires git setup
>>> True
```

#### collect()

Collect complexity metrics using wily.

* **Returns:**
  - cyclomatic_avg: Average cyclomatic complexity
  - maintainability_index: Maintainability index score
  - total_loc: Total lines of code
  - files_analyzed: Number of files analyzed
* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)

### *class* umpyre.WorkflowStatusCollector(repo, token=None, lookback_runs=10, workflow_name=None)

Bases: [`MetricCollector`](_autosummary/umpyre.collectors.base.html.md#umpyre.collectors.base.MetricCollector)

Collect GitHub workflow status using GitHub API.

Tracks:

- Last workflow run status (success/failure)
- Last successful run timestamp
- Recent failure count
- Workflow run URL

### Example

```pycon
>>> # Mock test (requires actual GitHub API)
>>> import os
>>> if os.getenv('GITHUB_TOKEN'):
...     collector = WorkflowStatusCollector(
...         repo="thorwhalen/astate",
...         token=os.getenv('GITHUB_TOKEN')
...     )
...     metrics = collector.collect()
...     'last_run_status' in metrics
... else:
...     True  # Skip if no token
True
```

#### collect()

Collect workflow status from GitHub API.

* **Returns:**
  - last_run_status: ‘success’, ‘failure’, or ‘other’
  - last_success_timestamp: ISO timestamp or None
  - recent_failure_count: Number of failures in lookback window
  - run_url: URL of last run
  - total_runs_analyzed: Number of runs examined
* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)

### umpyre.deserialize_metrics(file_path, format='json')

Deserialize metrics from file.

* **Parameters:**
  * **file_path** ([`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) – Path to input file
  * **format** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Format (‘json’ or ‘csv’)
* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)
* **Returns:**
  Metric dictionary

### umpyre.modules_info_df(root, filepath_filt=<function <lambda>>, index_field=None, on_error='ignore')

A pandas DataFrame of stats of the root (package or directory thereof).

* **Parameters:**
  * **root** – module or directory path
  * **filepath_filt** – filepath filter function or regular expression
  * **index_field** – function or field string that should be used for the indexing of modules
  * **on_error** – What to do when an error occurs when extracting information from a module.
    Values are ‘ignore’, ‘print’, or ‘raise’
* **Returns:**
  A DataFrame whose rows contain information for each module

```pycon
>>> import urllib
>>> df = modules_info_df(urllib)
>>> df
                    lines  empty_lines  ...  num_of_functions  num_of_classes
urllib.error           78           18  ...                 0               3
urllib.request       2774          410  ...                23              28
urllib.__init__         1            1  ...                 0               0
urllib.response        81           24  ...                 0               4
urllib.robotparser    274           36  ...                 0               4
urllib.parse         1166          199  ...                46              16

[6 rows x 7 columns]
```

### umpyre.modules_info_df_stats(root, filepath_filt=<function <lambda>>, index_field=None, on_error='ignore')

A pandas Series of statistics over all modules of some root (package or directory thereof).

* **Parameters:**
  * **root** – module or directory path
  * **filepath_filt** – filepath filter function or regular expression
  * **index_field** – function or field string that should be used for the indexing of modules
  * **on_error** – What to do when an error occurs when extracting information from a module.
    Values are ‘ignore’, ‘print’, or ‘raise’
* **Returns:**
  A Series whose rows containing statistics

```pycon
>>> import json
>>> df = modules_info_df_stats(json)
>>> df
lines                      1301.000000
empty_lines                 178.000000
comment_lines                50.000000
docs_lines                  218.000000
function_lines              585.000000
num_of_functions             14.000000
num_of_classes                3.000000
empty_lines_ratio             0.136818
comment_lines_ratio           0.038432
function_lines_ratio          0.449654
mean_lines_per_function      41.785714
dtype: float64
>>> modules_info_df_stats('collections.abc')
lines                      1276.000000
empty_lines                 190.000000
comment_lines                73.000000
docs_lines                  133.000000
function_lines              138.000000
num_of_functions              1.000000
num_of_classes               34.000000
empty_lines_ratio             0.148903
comment_lines_ratio           0.057210
function_lines_ratio          0.108150
mean_lines_per_function     138.000000
dtype: float64
```

### umpyre.modules_info_gen(root, filepath_filt=<function <lambda>>, on_error='ignore')

Yields statistics (as dicts) of modules under the root module or directory of a python package.

* **Parameters:**
  * **root** – module instance, dot path, or directory path
  * **filepath_filt** – filepath filter function or regular expression
  * **on_error** – What to do when an error occurs when extracting information from a module.
    Values are ‘ignore’, ‘print’, ‘raise’, or ‘yield’
* **Returns:**
  A generator of dicts

### umpyre.serialize_metrics(data, output_path, format='json')

Serialize metrics to file.

* **Parameters:**
  * **data** ([`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)) – Metric dictionary
  * **output_path** ([`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) – Path to output file
  * **format** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Format (‘json’ or ‘csv’)

### umpyre.stats_of(modules, filepath_filt=<function <lambda>>, index_field=None, on_error='ignore')

A dataframe of stats of the input modules.

* **Parameters:**
  * **modules** – list of importable names
  * **root** – module or directory path
  * **filepath_filt** – filepath filter function or regular expression
  * **index_field** – function or field string that should be used for the indexing of modules
  * **on_error** – What to do when an error occurs when extracting information from a module.
    Values are ‘ignore’, ‘print’, or ‘raise’
* **Returns:**

```pycon
>>> df = stats_of(['urllib', 'json', 'collections'])
>>> assert set(df.index.values).issuperset(
...     {'empty_lines_ratio', 'comment_lines_ratio', 'function_lines_ratio', 'mean_lines_per_function'})
>>> stats_of(['urllib', 'json', 'collections'])
                              urllib         json  collections
empty_lines_ratio           0.157293     0.136503     0.148090
comment_lines_ratio         0.075217     0.038344     0.061574
function_lines_ratio        0.212391     0.448620     0.107560
mean_lines_per_function    13.463768    41.785714   138.000000
lines                    4374.000000  1304.000000  1283.000000
empty_lines               688.000000   178.000000   190.000000
comment_lines             329.000000    50.000000    79.000000
docs_lines                425.000000   218.000000   133.000000
function_lines            929.000000   585.000000   138.000000
num_of_functions           69.000000    14.000000     1.000000
num_of_classes             55.000000     3.000000    34.000000
```

### Modules

| [`cli`](_autosummary/umpyre.cli.html.md#module-umpyre.cli)                             | Command-line interface for umpyre.                          |
|----------------------------------------------------------------------------------------------------|-------------------------------------------------------------|
| [`collectors`](_autosummary/umpyre.collectors.html.md#module-umpyre.collectors)               | Collectors package - metric collection implementations.     |
| [`config`](_autosummary/umpyre.config.html.md#module-umpyre.config)                       | Configuration loading and validation for umpyre.            |
| [`python_code_stats`](_autosummary/umpyre.python_code_stats.html.md#module-umpyre.python_code_stats) | Get stats about packages.                                   |
| [`schema`](_autosummary/umpyre.schema.html.md#module-umpyre.schema)                       | Versioned schema for metrics storage and migration support. |
| [`storage`](_autosummary/umpyre.storage.html.md#module-umpyre.storage)                     | Storage operations for metrics.                             |


# _autosummary/umpyre.python_code_stats.html.md

# umpyre.python_code_stats

Get stats about packages. Your own, or other’s.
Things like…
(Note that these will probably not work as doctests, since results are sensisitive to other slight system differences
(such as python version etc.))

```pycon
>>> import collections
>>> modules_info_df(collections)
                      lines  empty_lines  ...  num_of_functions  num_of_classes
collections.__init__   1280          189  ...                 1               9
collections.abc           3            1  ...                 0              25

[2 rows x 7 columns]
>>> modules_info_df_stats(collections.abc)
lines                      1283.000000
empty_lines                 190.000000
comment_lines                79.000000
docs_lines                  133.000000
function_lines              138.000000
num_of_functions              1.000000
num_of_classes               34.000000
empty_lines_ratio             0.148090
comment_lines_ratio           0.061574
function_lines_ratio          0.107560
mean_lines_per_function     138.000000
dtype: float64
>>> stats_of(['urllib', 'json', 'collections'])
                              urllib         json  collections
empty_lines_ratio           0.157293     0.136503     0.148090
comment_lines_ratio         0.075217     0.038344     0.061574
function_lines_ratio        0.212391     0.448620     0.107560
mean_lines_per_function    13.463768    41.785714   138.000000
lines                    4374.000000  1304.000000  1283.000000
empty_lines               688.000000   178.000000   190.000000
comment_lines             329.000000    50.000000    79.000000
docs_lines                425.000000   218.000000   133.000000
function_lines            929.000000   585.000000   138.000000
num_of_functions           69.000000    14.000000     1.000000
num_of_classes             55.000000     3.000000    34.000000
```

### Functions

| `get_objs`(root, k)                                                                                |                                                                                                 |
|----------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------|
| `lines`(string)                                                                                    |                                                                                                 |
| [`modules_info_df`](_autosummary/umpyre.python_code_stats.html.md#umpyre.python_code_stats.modules_info_df)(root[, filepath_filt, ...])       | A pandas DataFrame of stats of the root (package or directory thereof).                         |
| [`modules_info_df_stats`](_autosummary/umpyre.python_code_stats.html.md#umpyre.python_code_stats.modules_info_df_stats)(root[, filepath_filt, ...]) | A pandas Series of statistics over all modules of some root (package or directory thereof).     |
| [`modules_info_gen`](_autosummary/umpyre.python_code_stats.html.md#umpyre.python_code_stats.modules_info_gen)(root[, filepath_filt, on_error]) | Yields statistics (as dicts) of modules under the root module or directory of a python package. |
| `no_test_folder`(path)                                                                             |                                                                                                 |
| `only_py_ext`(path)                                                                                |                                                                                                 |
| [`stats_of`](_autosummary/umpyre.python_code_stats.html.md#umpyre.python_code_stats.stats_of)(modules[, filepath_filt, ...])           | A dataframe of stats of the input modules.                                                      |

### umpyre.python_code_stats.modules_info_df(root, filepath_filt=<function <lambda>>, index_field=None, on_error='ignore')

A pandas DataFrame of stats of the root (package or directory thereof).

* **Parameters:**
  * **root** – module or directory path
  * **filepath_filt** – filepath filter function or regular expression
  * **index_field** – function or field string that should be used for the indexing of modules
  * **on_error** – What to do when an error occurs when extracting information from a module.
    Values are ‘ignore’, ‘print’, or ‘raise’
* **Returns:**
  A DataFrame whose rows contain information for each module

```pycon
>>> import urllib
>>> df = modules_info_df(urllib)
>>> df
                    lines  empty_lines  ...  num_of_functions  num_of_classes
urllib.error           78           18  ...                 0               3
urllib.request       2774          410  ...                23              28
urllib.__init__         1            1  ...                 0               0
urllib.response        81           24  ...                 0               4
urllib.robotparser    274           36  ...                 0               4
urllib.parse         1166          199  ...                46              16

[6 rows x 7 columns]
```

### umpyre.python_code_stats.modules_info_df_stats(root, filepath_filt=<function <lambda>>, index_field=None, on_error='ignore')

A pandas Series of statistics over all modules of some root (package or directory thereof).

* **Parameters:**
  * **root** – module or directory path
  * **filepath_filt** – filepath filter function or regular expression
  * **index_field** – function or field string that should be used for the indexing of modules
  * **on_error** – What to do when an error occurs when extracting information from a module.
    Values are ‘ignore’, ‘print’, or ‘raise’
* **Returns:**
  A Series whose rows containing statistics

```pycon
>>> import json
>>> df = modules_info_df_stats(json)
>>> df
lines                      1301.000000
empty_lines                 178.000000
comment_lines                50.000000
docs_lines                  218.000000
function_lines              585.000000
num_of_functions             14.000000
num_of_classes                3.000000
empty_lines_ratio             0.136818
comment_lines_ratio           0.038432
function_lines_ratio          0.449654
mean_lines_per_function      41.785714
dtype: float64
>>> modules_info_df_stats('collections.abc')
lines                      1276.000000
empty_lines                 190.000000
comment_lines                73.000000
docs_lines                  133.000000
function_lines              138.000000
num_of_functions              1.000000
num_of_classes               34.000000
empty_lines_ratio             0.148903
comment_lines_ratio           0.057210
function_lines_ratio          0.108150
mean_lines_per_function     138.000000
dtype: float64
```

### umpyre.python_code_stats.modules_info_gen(root, filepath_filt=<function <lambda>>, on_error='ignore')

Yields statistics (as dicts) of modules under the root module or directory of a python package.

* **Parameters:**
  * **root** – module instance, dot path, or directory path
  * **filepath_filt** – filepath filter function or regular expression
  * **on_error** – What to do when an error occurs when extracting information from a module.
    Values are ‘ignore’, ‘print’, ‘raise’, or ‘yield’
* **Returns:**
  A generator of dicts

### umpyre.python_code_stats.stats_of(modules, filepath_filt=<function <lambda>>, index_field=None, on_error='ignore')

A dataframe of stats of the input modules.

* **Parameters:**
  * **modules** – list of importable names
  * **root** – module or directory path
  * **filepath_filt** – filepath filter function or regular expression
  * **index_field** – function or field string that should be used for the indexing of modules
  * **on_error** – What to do when an error occurs when extracting information from a module.
    Values are ‘ignore’, ‘print’, or ‘raise’
* **Returns:**

```pycon
>>> df = stats_of(['urllib', 'json', 'collections'])
>>> assert set(df.index.values).issuperset(
...     {'empty_lines_ratio', 'comment_lines_ratio', 'function_lines_ratio', 'mean_lines_per_function'})
>>> stats_of(['urllib', 'json', 'collections'])
                              urllib         json  collections
empty_lines_ratio           0.157293     0.136503     0.148090
comment_lines_ratio         0.075217     0.038344     0.061574
function_lines_ratio        0.212391     0.448620     0.107560
mean_lines_per_function    13.463768    41.785714   138.000000
lines                    4374.000000  1304.000000  1283.000000
empty_lines               688.000000   178.000000   190.000000
comment_lines             329.000000    50.000000    79.000000
docs_lines                425.000000   218.000000   133.000000
function_lines            929.000000   585.000000   138.000000
num_of_functions           69.000000    14.000000     1.000000
num_of_classes             55.000000     3.000000    34.000000
```


# _autosummary/umpyre.schema.html.md

# umpyre.schema

Versioned schema for metrics storage and migration support.

### Classes

| [`MetricSchema`](_autosummary/umpyre.schema.html.md#umpyre.schema.MetricSchema)([version])   | Versioned schema for metrics storage with migration support.   |
|----------------------------------------------------------------------------|----------------------------------------------------------------|

### *class* umpyre.schema.MetricSchema(version='1.0')

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Versioned schema for metrics storage with migration support.

#### *classmethod* create_metric_data(commit_sha, metrics, commit_message=None, python_version=None, workflow_status=None, collection_duration=None)

Create a standardized metric data structure.

* **Parameters:**
  * **commit_sha** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Git commit SHA
  * **metrics** ([`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)) – Dictionary of collected metrics
  * **commit_message** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]) – Optional commit message
  * **python_version** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]) – Optional Python version string
  * **workflow_status** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)]) – Optional workflow status dict
  * **collection_duration** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`float`](https://docs.python.org/3/builtins/functions.html#float)]) – Optional collection time in seconds
* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)
* **Returns:**
  Standardized metric dictionary

#### *classmethod* current_version()

Return the current schema version.

* **Return type:**
  [`str`](https://docs.python.org/3/builtins/stdtypes.html#str)

#### *classmethod* migrate(data, from_version)

Migrate data from old schema version to current version.

* **Parameters:**
  * **data** ([`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)) – Metric data in old format
  * **from_version** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Version of the input data
* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)
* **Returns:**
  Migrated data in current schema format

#### *classmethod* validate(data)

Validate that data conforms to schema.

* **Parameters:**
  **data** ([`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)) – Metric data to validate
* **Return type:**
  [`bool`](https://docs.python.org/3/builtins/functions.html#bool)
* **Returns:**
  True if valid, raises ValueError otherwise


# _autosummary/umpyre.storage.formats.html.md

# umpyre.storage.formats

JSON and CSV serialization for metrics.

### Functions

| [`deserialize_metrics`](_autosummary/umpyre.storage.formats.html.md#umpyre.storage.formats.deserialize_metrics)(file_path[, format])       | Deserialize metrics from file.   |
|-------------------------------------------------------------------------------------------------|----------------------------------|
| [`serialize_metrics`](_autosummary/umpyre.storage.formats.html.md#umpyre.storage.formats.serialize_metrics)(data, output_path[, format]) | Serialize metrics to file.       |

### umpyre.storage.formats.deserialize_metrics(file_path, format='json')

Deserialize metrics from file.

* **Parameters:**
  * **file_path** ([`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) – Path to input file
  * **format** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Format (‘json’ or ‘csv’)
* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)
* **Returns:**
  Metric dictionary

### umpyre.storage.formats.serialize_metrics(data, output_path, format='json')

Serialize metrics to file.

* **Parameters:**
  * **data** ([`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)) – Metric dictionary
  * **output_path** ([`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) – Path to output file
  * **format** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Format (‘json’ or ‘csv’)


# _autosummary/umpyre.storage.git_branch.html.md

# umpyre.storage.git_branch

Git branch-based storage operations.

### Classes

| [`GitBranchStorage`](_autosummary/umpyre.storage.git_branch.html.md#umpyre.storage.git_branch.GitBranchStorage)(repo_path[, remote, token])   | Store metrics in a separate git branch.   |
|-------------------------------------------------------------------------------------------------|-------------------------------------------|

### Exceptions

| [`GitBranchStorageError`](_autosummary/umpyre.storage.git_branch.html.md#umpyre.storage.git_branch.GitBranchStorageError)   | Raised when git branch storage operations fail.   |
|--------------------------------------------------------------------------|---------------------------------------------------|

### *class* umpyre.storage.git_branch.GitBranchStorage(repo_path, remote='origin', , token=None)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Store metrics in a separate git branch.

This provides versioned, branch-based storage without polluting
the main branch or requiring external artifacts.

### Example

```pycon
>>> storage = GitBranchStorage(repo_path="/path/to/repo")
>>> metrics = {"lines": 100, "functions": 10}
>>> storage.store_metrics(metrics, "abc123", branch="code-metrics")
```

#### store_metrics(metrics, commit_sha, branch='code-metrics', formats=None)

Store metrics to git branch.

* **Parameters:**
  * **metrics** ([`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)) – Metric dictionary to store
  * **commit_sha** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Git commit SHA
  * **branch** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Target branch name
  * **formats** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]]) – List of formats (‘json’, ‘csv’)

### *exception* umpyre.storage.git_branch.GitBranchStorageError

Bases: [`Exception`](https://docs.python.org/3/builtins/exceptions.html#Exception)

Raised when git branch storage operations fail.


# _autosummary/umpyre.storage.html.md

# umpyre.storage

Storage operations for metrics.

### Functions

| [`serialize_metrics`](_autosummary/umpyre.storage.html.md#umpyre.storage.serialize_metrics)(data, output_path[, format])   | Serialize metrics to file.                          |
|---------------------------------------------------------------------------------------------------|-----------------------------------------------------|
| [`deserialize_metrics`](_autosummary/umpyre.storage.html.md#umpyre.storage.deserialize_metrics)(file_path[, format])         | Deserialize metrics from file.                      |
| [`parse_metric_filename`](_autosummary/umpyre.storage.html.md#umpyre.storage.parse_metric_filename)(filename)                  | Parse metric filename into components.              |
| [`find_metrics_by_commit`](_autosummary/umpyre.storage.html.md#umpyre.storage.find_metrics_by_commit)(history_dir, commit_sha)  | Find metrics file for a specific commit.            |
| [`find_metrics_by_version`](_autosummary/umpyre.storage.html.md#umpyre.storage.find_metrics_by_version)(history_dir, version)    | Find all metrics files for a specific PyPI version. |
| [`get_latest_metric_for_version`](_autosummary/umpyre.storage.html.md#umpyre.storage.get_latest_metric_for_version)(history_dir, ...)  | Get the most recent metrics file for a version.     |
| [`get_all_versions`](_autosummary/umpyre.storage.html.md#umpyre.storage.get_all_versions)(history_dir)                    | Get all unique PyPI versions found in metrics.      |
| [`filter_by_date_range`](_autosummary/umpyre.storage.html.md#umpyre.storage.filter_by_date_range)(history_dir[, ...])         | Get metrics files within a date range.              |

### Classes

| [`GitBranchStorage`](_autosummary/umpyre.storage.html.md#umpyre.storage.GitBranchStorage)(repo_path[, remote, token])   | Store metrics in a separate git branch.   |
|-------------------------------------------------------------------------------------------------|-------------------------------------------|

### Exceptions

| [`GitBranchStorageError`](_autosummary/umpyre.storage.html.md#umpyre.storage.GitBranchStorageError)   | Raised when git branch storage operations fail.   |
|--------------------------------------------------------------------------|---------------------------------------------------|

### *class* umpyre.storage.GitBranchStorage(repo_path, remote='origin', , token=None)

Bases: [`object`](https://docs.python.org/3/builtins/functions.html#object)

Store metrics in a separate git branch.

This provides versioned, branch-based storage without polluting
the main branch or requiring external artifacts.

### Example

```pycon
>>> storage = GitBranchStorage(repo_path="/path/to/repo")
>>> metrics = {"lines": 100, "functions": 10}
>>> storage.store_metrics(metrics, "abc123", branch="code-metrics")
```

#### store_metrics(metrics, commit_sha, branch='code-metrics', formats=None)

Store metrics to git branch.

* **Parameters:**
  * **metrics** ([`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)) – Metric dictionary to store
  * **commit_sha** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Git commit SHA
  * **branch** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Target branch name
  * **formats** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]]) – List of formats (‘json’, ‘csv’)

### *exception* umpyre.storage.GitBranchStorageError

Bases: [`Exception`](https://docs.python.org/3/builtins/exceptions.html#Exception)

Raised when git branch storage operations fail.

### umpyre.storage.deserialize_metrics(file_path, format='json')

Deserialize metrics from file.

* **Parameters:**
  * **file_path** ([`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) – Path to input file
  * **format** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Format (‘json’ or ‘csv’)
* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)
* **Returns:**
  Metric dictionary

### umpyre.storage.filter_by_date_range(history_dir, start_date=None, end_date=None)

Get metrics files within a date range.

* **Parameters:**
  * **history_dir** ([`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) – Path to history directory
  * **start_date** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`datetime`](https://docs.python.org/3/library/datetime.html#datetime.datetime)]) – Start datetime (inclusive)
  * **end_date** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`datetime`](https://docs.python.org/3/library/datetime.html#datetime.datetime)]) – End datetime (inclusive)
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)]
* **Returns:**
  List of paths within date range (sorted chronologically)

### Example

```pycon
>>> from datetime import datetime, timedelta
>>> end = datetime.now()
>>> start = end - timedelta(days=7)
>>> recent = filter_by_date_range(Path("history"), start, end)
>>> print(f"Found {len(recent)} metrics from last 7 days")
```

### umpyre.storage.find_metrics_by_commit(history_dir, commit_sha)

Find metrics file for a specific commit.

* **Parameters:**
  * **history_dir** ([`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) – Path to history directory
  * **commit_sha** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Commit SHA (7 chars or full)
* **Return type:**
  [`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)]
* **Returns:**
  Path to metrics file or None

### Example

```pycon
>>> metrics = find_metrics_by_commit(Path("history"), "700e012")
>>> print(metrics.name)
2025_11_14_22_45_00__700e012__0.1.0.json
```

### umpyre.storage.find_metrics_by_version(history_dir, version)

Find all metrics files for a specific PyPI version.

* **Parameters:**
  * **history_dir** ([`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) – Path to history directory
  * **version** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – PyPI version string (e.g., “0.1.0”)
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)]
* **Returns:**
  List of paths (sorted by timestamp, latest first)

### Example

```pycon
>>> metrics = find_metrics_by_version(Path("history"), "0.1.0")
>>> for m in metrics:
...     print(m.name)
2025_11_14_22_50_00__abc1234__0.1.0.json
2025_11_14_22_45_00__700e012__0.1.0.json
```

### umpyre.storage.get_all_versions(history_dir)

Get all unique PyPI versions found in metrics.

* **Parameters:**
  **history_dir** ([`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) – Path to history directory
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]
* **Returns:**
  Sorted list of versions (excluding ‘none’)

### Example

```pycon
>>> versions = get_all_versions(Path("history"))
>>> print(versions)
['0.1.0', '0.1.1', '0.2.0']
```

### umpyre.storage.get_latest_metric_for_version(history_dir, version)

Get the most recent metrics file for a version.

* **Parameters:**
  * **history_dir** ([`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) – Path to history directory
  * **version** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – PyPI version string
* **Return type:**
  [`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)]
* **Returns:**
  Path to latest metrics file or None

### Example

```pycon
>>> latest = get_latest_metric_for_version(Path("history"), "0.1.0")
>>> info = parse_metric_filename(latest.name)
>>> print(f"Latest 0.1.0 metrics from {info['timestamp_str']}")
```

### umpyre.storage.parse_metric_filename(filename)

Parse metric filename into components.

* **Parameters:**
  **filename** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Filename like “2025_11_14_22_45_00_\_700e012_\_0.1.0.json”
* **Returns:**
  {
  : “timestamp”: datetime object,
    “timestamp_str”: “2025-11-14T22:45:00”,
    “commit_sha”: “700e012”,
    “pypi_version”: “0.1.0” or None,
    “has_version”: bool,

  }
* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)

### Example

```pycon
>>> info = parse_metric_filename("2025_11_14_22_45_00__700e012__0.1.0.json")
>>> info['commit_sha']
'700e012'
>>> info['pypi_version']
'0.1.0'
```

### umpyre.storage.serialize_metrics(data, output_path, format='json')

Serialize metrics to file.

* **Parameters:**
  * **data** ([`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)) – Metric dictionary
  * **output_path** ([`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) – Path to output file
  * **format** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Format (‘json’ or ‘csv’)

### Modules

| [`formats`](_autosummary/umpyre.storage.formats.html.md#module-umpyre.storage.formats)         | JSON and CSV serialization for metrics.                   |
|------------------------------------------------------------------------------------------------|-----------------------------------------------------------|
| [`git_branch`](_autosummary/umpyre.storage.git_branch.html.md#module-umpyre.storage.git_branch)   | Git branch-based storage operations.                      |
| [`query_utils`](_autosummary/umpyre.storage.query_utils.html.md#module-umpyre.storage.query_utils) | Helper utilities for working with umpyre metrics storage. |


# _autosummary/umpyre.storage.query_utils.html.md

# umpyre.storage.query_utils

Helper utilities for working with umpyre metrics storage.

### Functions

| [`filter_by_date_range`](_autosummary/umpyre.storage.query_utils.html.md#umpyre.storage.query_utils.filter_by_date_range)(history_dir[, ...])        | Get metrics files within a date range.              |
|--------------------------------------------------------------------------------------------------|-----------------------------------------------------|
| [`find_metrics_by_commit`](_autosummary/umpyre.storage.query_utils.html.md#umpyre.storage.query_utils.find_metrics_by_commit)(history_dir, commit_sha) | Find metrics file for a specific commit.            |
| [`find_metrics_by_version`](_autosummary/umpyre.storage.query_utils.html.md#umpyre.storage.query_utils.find_metrics_by_version)(history_dir, version)   | Find all metrics files for a specific PyPI version. |
| [`get_all_versions`](_autosummary/umpyre.storage.query_utils.html.md#umpyre.storage.query_utils.get_all_versions)(history_dir)                   | Get all unique PyPI versions found in metrics.      |
| [`get_latest_metric_for_version`](_autosummary/umpyre.storage.query_utils.html.md#umpyre.storage.query_utils.get_latest_metric_for_version)(history_dir, ...) | Get the most recent metrics file for a version.     |
| [`parse_metric_filename`](_autosummary/umpyre.storage.query_utils.html.md#umpyre.storage.query_utils.parse_metric_filename)(filename)                 | Parse metric filename into components.              |

### umpyre.storage.query_utils.filter_by_date_range(history_dir, start_date=None, end_date=None)

Get metrics files within a date range.

* **Parameters:**
  * **history_dir** ([`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) – Path to history directory
  * **start_date** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`datetime`](https://docs.python.org/3/library/datetime.html#datetime.datetime)]) – Start datetime (inclusive)
  * **end_date** ([`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`datetime`](https://docs.python.org/3/library/datetime.html#datetime.datetime)]) – End datetime (inclusive)
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)]
* **Returns:**
  List of paths within date range (sorted chronologically)

### Example

```pycon
>>> from datetime import datetime, timedelta
>>> end = datetime.now()
>>> start = end - timedelta(days=7)
>>> recent = filter_by_date_range(Path("history"), start, end)
>>> print(f"Found {len(recent)} metrics from last 7 days")
```

### umpyre.storage.query_utils.find_metrics_by_commit(history_dir, commit_sha)

Find metrics file for a specific commit.

* **Parameters:**
  * **history_dir** ([`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) – Path to history directory
  * **commit_sha** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Commit SHA (7 chars or full)
* **Return type:**
  [`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)]
* **Returns:**
  Path to metrics file or None

### Example

```pycon
>>> metrics = find_metrics_by_commit(Path("history"), "700e012")
>>> print(metrics.name)
2025_11_14_22_45_00__700e012__0.1.0.json
```

### umpyre.storage.query_utils.find_metrics_by_version(history_dir, version)

Find all metrics files for a specific PyPI version.

* **Parameters:**
  * **history_dir** ([`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) – Path to history directory
  * **version** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – PyPI version string (e.g., “0.1.0”)
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)]
* **Returns:**
  List of paths (sorted by timestamp, latest first)

### Example

```pycon
>>> metrics = find_metrics_by_version(Path("history"), "0.1.0")
>>> for m in metrics:
...     print(m.name)
2025_11_14_22_50_00__abc1234__0.1.0.json
2025_11_14_22_45_00__700e012__0.1.0.json
```

### umpyre.storage.query_utils.get_all_versions(history_dir)

Get all unique PyPI versions found in metrics.

* **Parameters:**
  **history_dir** ([`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) – Path to history directory
* **Return type:**
  [`list`](https://docs.python.org/3/builtins/stdtypes.html#list)[[`str`](https://docs.python.org/3/builtins/stdtypes.html#str)]
* **Returns:**
  Sorted list of versions (excluding ‘none’)

### Example

```pycon
>>> versions = get_all_versions(Path("history"))
>>> print(versions)
['0.1.0', '0.1.1', '0.2.0']
```

### umpyre.storage.query_utils.get_latest_metric_for_version(history_dir, version)

Get the most recent metrics file for a version.

* **Parameters:**
  * **history_dir** ([`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)) – Path to history directory
  * **version** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – PyPI version string
* **Return type:**
  [`Optional`](https://docs.python.org/3/library/typing.html#typing.Optional)[[`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)]
* **Returns:**
  Path to latest metrics file or None

### Example

```pycon
>>> latest = get_latest_metric_for_version(Path("history"), "0.1.0")
>>> info = parse_metric_filename(latest.name)
>>> print(f"Latest 0.1.0 metrics from {info['timestamp_str']}")
```

### umpyre.storage.query_utils.parse_metric_filename(filename)

Parse metric filename into components.

* **Parameters:**
  **filename** ([`str`](https://docs.python.org/3/builtins/stdtypes.html#str)) – Filename like “2025_11_14_22_45_00_\_700e012_\_0.1.0.json”
* **Returns:**
  {
  : “timestamp”: datetime object,
    “timestamp_str”: “2025-11-14T22:45:00”,
    “commit_sha”: “700e012”,
    “pypi_version”: “0.1.0” or None,
    “has_version”: bool,

  }
* **Return type:**
  [`dict`](https://docs.python.org/3/builtins/stdtypes.html#dict)

### Example

```pycon
>>> info = parse_metric_filename("2025_11_14_22_45_00__700e012__0.1.0.json")
>>> info['commit_sha']
'700e012'
>>> info['pypi_version']
'0.1.0'
```


# about-this-build.html.md

<!-- generated by epythet -->

# About this build

This documentation was built on **2026-10-13 14:52 UTC** from commit <a href="https://github.com/i2mint/umpyre/commit/a39040cf7d371b360ef8dab7dc3ed6fa3a14d8d1"><code>a39040c</code></a> on branch <code>master</code>, for **umpyre 0.1.11** (from <code>pyproject.toml</code>).

#### WARNING
The documentation and the package may be misaligned:

- The documented version (0.1.11) is behind the latest release on PyPI (0.1.12): `pip install umpyre` gives newer code than these docs describe.

## Source

|                     |                                                                                                                                                      |
|---------------------|------------------------------------------------------------------------------------------------------------------------------------------------------|
| Commit              | <a href="https://github.com/i2mint/umpyre/commit/a39040cf7d371b360ef8dab7dc3ed6fa3a14d8d1"><code>a39040cf7d371b360ef8dab7dc3ed6fa3a14d8d1</code></a> |
| Branch              | <code>master</code>                                                                                                                                  |
| Tags at this commit | none                                                                                                                                                 |
| Working tree        | clean                                                                                                                                                |
| Remote              | <code>https://github.com/i2mint/umpyre</code>                                                                                                        |

## Continuous integration

|              |                                                                                            |
|--------------|--------------------------------------------------------------------------------------------|
| Repository   | <code>i2mint/umpyre</code>                                                                 |
| Run          | <a href="https://github.com/i2mint/umpyre/actions/runs/38416743757">38416743757</a>        |
| Ref          | <code>refs/heads/master</code>                                                             |
| Event commit | <code>a39040cf7d371b360ef8dab7dc3ed6fa3a14d8d1</code> (in the history of the built commit) |

## Tools

|          |         |
|----------|---------|
| epythet  | 0.2.16  |
| Sphinx   | 9.1.0   |
| docutils | 0.22.4  |
| Python   | 3.12.15 |

## Configuration as resolved

|               |                                                                   |
|---------------|-------------------------------------------------------------------|
| theme         | <code>auto</code> (Sphinx theme <code>pydata_sphinx_theme</code>) |
| accent        | <code>#005c9b</code>                                              |
| api_generator | <code>autosummary</code>                                          |
| ignore        | <code>tests/</code>, <code>scrap/</code>, <code>examples/</code>  |
| agent_outputs | <code>true</code>                                                 |
| aggregates    | <code>md</code>                                                   |
| ai_artifacts  | <code>true</code>                                                 |

## Package on PyPI

Latest release: <a href="https://pypi.org/project/umpyre/0.1.12/">0.1.12</a>, newer than the documented version (0.1.11).

## Reproduce

```bash
git clone https://github.com/i2mint/umpyre && cd umpyre
git checkout a39040cf7d371b360ef8dab7dc3ed6fa3a14d8d1
pip install "epythet==0.2.16"
epythet quickstart . --ignore tests/ scrap/ examples/
```

The same data, for machines: <a href="build_info.json"><code>build_info.json</code></a> (schema version 1).


# api.html.md

# API reference

| [`umpyre`](_autosummary/umpyre.html.md#module-umpyre)   | Umpyre - Code analysis and quality metrics tracking.   |
|-------------------------------------------------------------------------|--------------------------------------------------------|


