Skip to content

✨ Add get_status() method for comprehensive status reporting#141

Merged
sodre merged 7 commits intomainfrom
feat/115-stack-status
Jan 15, 2026
Merged

✨ Add get_status() method for comprehensive status reporting#141
sodre merged 7 commits intomainfrom
feat/115-stack-status

Conversation

@sodre
Copy link
Member

@sodre sodre commented Jan 15, 2026

Summary

  • Add Status dataclass with comprehensive status information
  • Add get_status() method to RateLimiter and SyncRateLimiter classes
  • Enhance CLI status command with rich formatted output showing all status fields

Changes

New Status Dataclass

The Status dataclass consolidates connectivity, infrastructure, identity, versions, and table metrics:

@dataclass
class Status:
    # Connectivity
    available: bool
    latency_ms: float | None

    # Infrastructure
    stack_status: str | None
    table_status: str | None
    aggregator_enabled: bool

    # Identity
    name: str
    region: str | None

    # Versions
    schema_version: str | None
    lambda_version: str | None
    client_version: str

    # Table metrics
    table_item_count: int | None
    table_size_bytes: int | None

New Methods

RateLimiter.get_status() (async):

status = await limiter.get_status()
if status.available and status.stack_status == "CREATE_COMPLETE":
    print(f"Ready! Latency: {status.latency_ms}ms")
    print(f"Schema: {status.schema_version}")
else:
    print("Not ready")

SyncRateLimiter.get_status() (sync):

status = limiter.get_status()

Enhanced CLI Output

The zae-limiter status command now shows rich formatted output:

Status: ZAEL-my-app
==================================================

Connectivity
  Available:     ✓ Yes
  Latency:       15ms
  Region:        us-east-1

Infrastructure
  Stack:         CREATE_COMPLETE
  Table:         ACTIVE
  Aggregator:    Enabled

Versions
  Client:        0.1.0
  Schema:        1.0.0
  Lambda:        0.1.0

Table Metrics
  Items:         ~1,234
  Size:          ~512 KB

✓ Infrastructure is ready

Test plan

  • Unit tests for RateLimiter.get_status() covering various states
  • Unit tests for SyncRateLimiter.get_status() matching async behavior
  • Unit tests for CLI status command with mocked responses
  • All 448 unit tests pass
  • Linting (ruff) passes
  • Type checking (mypy) passes

Closes #115

🤖 Generated with Claude Code

Add `get_stack_status()` method to both `RateLimiter` and `SyncRateLimiter`
classes to provide programmatic access to CloudFormation stack status,
matching the functionality of the `zae-limiter status` CLI command.

This change:
- Adds async `get_stack_status()` to `RateLimiter` returning stack status
  string or None if stack doesn't exist
- Adds sync `get_stack_status()` to `SyncRateLimiter` wrapping the async
  implementation
- Adds unit tests for both methods covering various CloudFormation states
- Updates docs/getting-started.md with tabbed Programmatic/CLI options
  for checking status
- Updates docs/infra/deployment.md with the new programmatic option

Closes #115

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@codecov
Copy link

codecov bot commented Jan 15, 2026

Codecov Report

❌ Patch coverage is 90.30303% with 16 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.15%. Comparing base (68a7381) to head (7e83ffd).
⚠️ Report is 2 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/zae_limiter/cli.py 88.99% 12 Missing ⚠️
src/zae_limiter/limiter.py 90.47% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #141      +/-   ##
==========================================
+ Coverage   87.64%   88.15%   +0.51%     
==========================================
  Files          19       19              
  Lines        2016     2162     +146     
==========================================
+ Hits         1767     1906     +139     
- Misses        249      256       +7     
Flag Coverage Δ
e2e 56.01% <81.21%> (+3.13%) ⬆️
integration 61.42% <81.21%> (+2.59%) ⬆️
unit 87.00% <90.30%> (+0.84%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@claude
Copy link

claude bot commented Jan 15, 2026

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

1 similar comment
@claude
Copy link

claude bot commented Jan 15, 2026

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.30.

Benchmark suite Current: 7e83ffd Previous: 68a7381 Ratio
tests/benchmark/test_operations.py::TestCascadeOverheadBenchmarks::test_acquire_with_cascade 32.62154801721996 iter/sec (stddev: 0.03942879027594723) 137.69645669844323 iter/sec (stddev: 0.0003761862040854996) 4.22

This comment was automatically generated by workflow using github-action-benchmark.

Copy link
Member Author

@sodre sodre left a comment

Choose a reason for hiding this comment

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

This should have been a property, not a getter. Also would ti be possible for the CLI to invoke limiter.stack_status() instead what it is doing? What are the tradeoffs?

@sodre
Copy link
Member Author

sodre commented Jan 15, 2026

Thanks for the feedback! A few considerations:

Property vs Method

For async operations, a property isn't straightforward because properties can't be awaited. We have a few options:

  1. Keep as async method (await limiter.get_stack_status()) - Current approach, explicit about async nature
  2. Cached property with lazy load - Would require caching the status, which might be stale
  3. Sync property that calls asyncio.run internally - Would block and doesn't work well in existing async contexts

Given that stack_status involves a CloudFormation API call (network I/O), making it an async method feels appropriate. The get_ prefix is consistent with other query methods in the class.

However, if you prefer, I could rename it to just stack_status() (dropping the get_ prefix) while keeping it as an async method.

CLI using limiter.stack_status

The current CLI uses StackManager directly, which is lighter since it doesn't set up the DynamoDB connection.

Trade-offs of using RateLimiter in CLI:

  • Pro: Single source of truth, true API/CLI parity
  • Con: Creates unnecessary DynamoDB session context just to check CloudFormation status

If we keep the current approach (CLI uses StackManager directly), they're still semantically equivalent - both call manager.get_stack_status() under the hood.

What's your preference?

  1. Keep get_stack_status() method as-is
  2. Rename to stack_status() method (drop get_ prefix)
  3. Something else?

@sodre
Copy link
Member Author

sodre commented Jan 15, 2026

Thanks for the feedback! A few considerations:

Property vs Method

For async operations, a property isn't straightforward because properties can't be awaited. We have a few options:

  1. Keep as async method (await limiter.get_stack_status()) - Current approach, explicit about async nature
  2. Cached property with lazy load - Would require caching the status, which might be stale
  3. Sync property that calls asyncio.run internally - Would block and doesn't work well in existing async contexts

Given that stack_status involves a CloudFormation API call (network I/O), making it an async method feels appropriate. The get_ prefix is consistent with other query methods in the class.

However, if you prefer, I could rename it to just stack_status() (dropping the get_ prefix) while keeping it as an async method.

Keep get_stack_status.

CLI using limiter.stack_status

The current CLI uses StackManager directly, which is lighter since it doesn't set up the DynamoDB connection.

Trade-offs of using RateLimiter in CLI:

  • Pro: Single source of truth, true API/CLI parity
  • Con: Creates unnecessary DynamoDB session context just to check CloudFormation status

If we keep the current approach (CLI uses StackManager directly), they're still semantically equivalent - both call manager.get_stack_status() under the hood.

What's your preference?

Let the CLI use StackManager on its own.

sodre and others added 2 commits January 15, 2026 03:21
Address review feedback:
- Rename `get_stack_status()` to `stack_status()` on RateLimiter (async method)
- Rename `get_stack_status()` to `stack_status` property on SyncRateLimiter
- Add `*.local.md` to .gitignore
- Remove accidentally committed ralph-loop.local.md file
- Update tests and documentation accordingly

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…orting

Add Status dataclass and get_status() method to provide unified status
information across API and CLI:

- Status dataclass with connectivity, infrastructure, identity, versions,
  and table metrics fields
- Async get_status() in RateLimiter
- Sync get_status() in SyncRateLimiter
- Enhanced CLI status command with rich formatted output

Closes #115

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@sodre sodre changed the title ✨ Add get_stack_status() method to RateLimiter for API/CLI parity ✨ Add get_status() method for comprehensive status reporting Jan 15, 2026
sodre and others added 2 commits January 15, 2026 03:56
Add integration tests for RateLimiter.get_status() and
SyncRateLimiter.get_status() to verify comprehensive status
reporting works against real LocalStack infrastructure.

Tests verify:
- Connectivity: available flag and latency measurement
- Infrastructure: table status reporting
- Identity: ZAEL-prefixed name and region
- Versions: client version populated
- Metrics: table item count available

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove stack_status() method from RateLimiter and SyncRateLimiter
  (superseded by get_status() which is more comprehensive)
- Refactor CLI status command to use StackManager and Repository
  directly instead of RateLimiter, making it truly read-only
- Update CLI tests to mock Repository and StackManager
- Remove stack_status tests from unit tests
- Enhance e2e CLI output tests to verify all output sections

The CLI status command is now a read-only operation that won't
trigger any infrastructure upgrades or modifications.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@sodre sodre added documentation Improvements or additions to documentation area/limiter Core rate limiting logic labels Jan 15, 2026
@sodre sodre added this to the v0.9.0 milestone Jan 15, 2026
Deploy command now creates the version record in DynamoDB after
stack creation, so `zae-limiter status` shows schema/lambda versions
immediately instead of N/A.

- Add version record initialization step to deploy command
- Update docs to use get_status() instead of removed stack_status()
- Update CLI status output example in docs
- Add e2e test verifying schema version after deploy
- Update unit tests to mock Repository for version record

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@sodre sodre merged commit d11c28f into main Jan 15, 2026
15 checks passed
@sodre sodre deleted the feat/115-stack-status branch January 16, 2026 00:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/limiter Core rate limiting logic documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

✨ Add get_status() method and enhance CLI status output

1 participant