feat(python): expose get_stats on IggyClient - #4018
Conversation
The Python SDK had no way to reach the server's headline diagnostic call, exposed by every other SDK. Wrap Stats, CacheMetrics and CacheMetricsKey in a new stats module following the user.rs pattern. CacheMetricsKey is frozen, hashable and comparable so cache_metrics maps to dict[CacheMetricsKey, CacheMetrics]. Byte sizes are exposed as integer bytes, times as microseconds, matching the existing getters. Closes apache#4016
|
Thanks for the PR. It is labeled Slash commands (own line, regular comment) move it around the queue:
See CONTRIBUTING.md for details. |
Codecov Report❌ Patch coverage is
❌ Your patch check has failed because the patch coverage (43.75%) is below the target coverage (50.00%). You can increase the patch coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## master #4018 +/- ##
============================================
- Coverage 85.00% 84.97% -0.03%
Complexity 1402 1402
============================================
Files 1225 1226 +1
Lines 180283 180411 +128
Branches 146587 146587
============================================
+ Hits 153248 153304 +56
- Misses 22993 23065 +72
Partials 4042 4042
🚀 New features to boost your workflow:
|
|
Nice addition, follows the existing
This review was drafted by an AI-assisted tool (Apache Magpie), so it may contain mistakes. If you think one of them is misapplied, please reply on the PR, and a maintainer will weigh in. |
ethanlin01x
left a comment
There was a problem hiding this comment.
Three small things, mostly about matching the SDK's existing conventions.
|
|
||
| /// The run time of the server process, in microseconds. | ||
| #[getter] | ||
| pub fn run_time(&self) -> u64 { |
There was a problem hiding this comment.
run_time is an IggyDuration, and this SDK already exposes durations as datetime.timedelta. Returning raw microseconds here is inconsistent.
There was a problem hiding this comment.
Done in 7a28235 — run_time now returns datetime.timedelta via the shared iggy_duration_to_py_delta helper, and the stub is regenerated.
| /// The numeric semantic version of the Iggy server, or `None` when unknown. | ||
| /// E.g. 1.2.3 -> 100200300 (major * 1000000 + minor * 1000 + patch). | ||
| #[getter] | ||
| #[gen_stub(override_return_type(type_repr = "int | None"))] |
There was a problem hiding this comment.
Nit: the other overrides write builtins.int | None (e.g. config.rs:191). Same meaning here, but this string is copied verbatim into the generated stub, so it stays as the only hand-written bare int across every future regen.
There was a problem hiding this comment.
Fixed in 7a28235 — the override now reads builtins.int | None, and the regenerated stub carries it.
| """ | ||
|
|
||
| @typing.final | ||
| class Stats: |
There was a problem hiding this comment.
CacheMetrics and CacheMetricsKey both define __repr__, but Stats does not. Since get_stats is a diagnostic call, print(stats) showing an object address is not great. A short repr with a few key fields would help.
There was a problem hiding this comment.
Added in 7a28235 — Stats.__repr__ now prints hostname, server version and the headline counters (streams/topics/partitions/messages/clients).
|
/author |
- CacheMetricsKey gets a #[new] constructor so a key built in Python can address a cache_metrics dict entry directly. - cache_metrics is converted once in From<RustStats> and stored as a Py<PyDict>; every access returns the same dict instead of re-collecting the whole map. - run_time is exposed as datetime.timedelta via the shared duration helper, matching the SDK's other duration surfaces. - The semver stub override uses the builtins.int | None convention, and Stats gains a __repr__ with the headline fields. - The numeric semver docstring example is corrected to 1.2.3 -> 1002003 here and in core/common (get_numeric_version pads minor/patch to three digits). - Tests compare server-global counters with >= (pytest-xdist safe), drop assertions that could not fail, and cover key construction, hashing and dict addressing without a server. The cache metrics map itself stays empty for now: the server replies with a hardcoded empty map. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Thanks for the thorough pass — all addressed, point by point:
Also merged master to catch the branch up. |
|
/ready |
Which issue does this PR address?
Closes #4016
Rationale
get_statsis the server's headline diagnostic call and is exposed by every other SDK; the Python SDK could not reach it.What changed?
The Python SDK had no binding for
get_stats, so server counts, host/version details and cache metrics were unreachable from Python.A new
foreign/python/src/stats.rswrapsStats,CacheMetricsandCacheMetricsKeyfollowing theuser.rspattern.CacheMetricsKeyis frozen with__eq__/__hash__, soStats.cache_metricsconverts todict[CacheMetricsKey, CacheMetrics].IggyClient.get_statsreturns an awaitable resolving toStats; byte sizes are exposed as integer bytes and times as microseconds, matching the existing getters. Stubs were regenerated withcargo run --bin stub_gen(purely additive diff after ruff).tests/test_stats.pycreates a stream/topic, sends messages, and asserts the stream/topic/partition/message counts moved, the version string is non-empty, and the cache-metrics dict round-trips through key lookup.Local Execution
Ran against a locally built
iggy-serverfrom this branch:pytest tests/gives 323 passed (onlytest_tlserrors locally for lack of a Docker daemon, unrelated).cargo fmt,cargo clippy --all-features --all-targets, ruff check/format and pyrefly are clean.AI Usage