Description
The Python binding's IggyClient accepts only a connection string, so no client
configuration can be set from Python — in particular neither reconnection nor auto-login.
On master, foreign/python/src/client.rs:
#[new]
#[pyo3(signature = (conn=None))]
fn new(conn: Option<String>) -> PyResult<Self>
let client = IggyClientBuilder::new()
.with_tcp()
.with_server_address(conn.unwrap_or("127.0.0.1:8090".to_string()))
.build()
The generated stub confirms the surface: the only exported types are AutoCommit,
AutoCommitAfter, AutoCommitWhen, IggyClient, IggyConsumer, PollingStrategy,
ReceiveMessage, SendMessage, StreamDetails, TopicDetails. There is no config or
builder type.
Why this matters — the SDK's own session recovery becomes unreachable from Python
#2880 added Unauthenticated, Disconnected, EmptyResponse and StaleClient to the
reconnect match in send_raw_with_response, so the client reconnects and replays the
stored login. That recovery is gated on the client having reconnection enabled and an
AutoLogin credential to replay — and #3651 documents the other half:
"login_user / logout_user … never touch the state. The only writer of the session
values is connect()'s auto-login block, so a manual connect() + login_user() flow
stays at Connected"
A Python user has only the manual connect() + login_user() flow available. So the
combination is: no auto-login to replay, and a flow that does not own session state. The
practical result is that a session lost shortly after login is not recovered — it surfaces as
Unauthenticated on the next call, and the application must handle it by hand.
Observed impact
A long-running Python consumer on a restart loop, against iggy-server 0.8.0 over TCP
loopback. login_user() returned successfully; the very next call raised:
File ".../core/iggy_bus.py", line 229, in ensure_topology
if await self._client.get_stream(self._stream) is None:
RuntimeError: Unauthenticated
Ten seconds later the same startup failed differently, then succeeded on the third attempt
and ran for ~2h48m:
File ".../core/iggy_bus.py", line 206, in connect
await self._client.login_user(...)
RuntimeError: Disconnected
Both are errors #2880 already classifies as reconnectable — but with no reconnection/
auto-login configurable from Python, they terminate the process instead, leaving restart
supervision (systemd) as the only recovery.
Workaround a Python caller has to hand-roll today
Because login_user() returning is not sufficient evidence of an authenticated session, we
now re-verify it explicitly and re-login on failure — effectively reimplementing auto_login
plus reconnection in Python:
for attempt in range(MAX_ATTEMPTS):
try:
await client.connect()
await client.login_user(username, password)
await client.get_stream(stream) # probe: raises Unauthenticated if the session is dead
except Exception:
await sleep_with_backoff(attempt) # then retry the whole connect+login
else:
break
Parity — other foreign SDKs already expose this
- Go:
foreign/go/client/tcp/tcp_core.go — autoLogin AutoLogin
- C#:
foreign/csharp/Iggy_SDK/Configuration/AutoLoginSettings.cs
Python is the outlier.
Suggested direction
Everything needed already exists on the Rust side; this is about exposing it:
core/common/src/types/configuration/tcp_config/tcp_client_config.rs — TcpClientConfig
.../tcp_client_config_builder.rs — with_auto_sign_in(AutoLogin)
.../tcp_client_reconnection_config.rs — TcpClientReconnectionConfig
core/common/src/types/configuration/auth_config/auto_login.rs — AutoLogin
core/sdk/src/clients/client_builder.rs — IggyClientBuilder::with_auto_sign_in
Minimal version: optional keyword arguments on IggyClient(...) for reconnection settings
and auto-login credentials, passed through to IggyClientBuilder. Fuller version: expose a
config/builder object mirroring TcpClientConfigBuilder, which would also give the Python
SDK somewhere to hang the QUIC/HTTP/WebSocket options from #2835.
Happy to open a PR if a maintainer indicates the preferred shape (kwargs vs. exposed builder).
Affected area / component
Python SDK (foreign/python)
Related
#3651 — SDK client state conflates transport and session dimensions (explains why the
manual connect() + login_user() flow does not own session state). Related, not a
duplicate: that issue is about the state enum being unreliable; this one is about the
configuration surface being absent in Python.
#2880 — added the reconnect-and-replay-login behavior that this config would unlock.
#1453 — with_auto_sign_in for the Rust builders.
#2835 — Python SDK transports; a config object would be the natural home for those too.
Versions
Server 0.8.0 (DockerHub apache/iggy:0.8.0), apache-iggy 0.8.0 (PyPI wheel, cp312,
manylinux), Python 3.12.13, TCP on loopback. Python constructor and builder call quoted above
were read on master, so the gap is present there too.
Scope note
This issue is deliberately limited to the missing configuration surface in the Python
binding. Whether a session can still be lost immediately after a successful login_user()
even with auto-login and reconnection enabled is a separate Rust/server question that we
have not isolated, and it is not claimed here.
Description
The Python binding's
IggyClientaccepts only a connection string, so no clientconfiguration can be set from Python — in particular neither reconnection nor auto-login.
On
master,foreign/python/src/client.rs:The generated stub confirms the surface: the only exported types are
AutoCommit,AutoCommitAfter,AutoCommitWhen,IggyClient,IggyConsumer,PollingStrategy,ReceiveMessage,SendMessage,StreamDetails,TopicDetails. There is no config orbuilder type.
Why this matters — the SDK's own session recovery becomes unreachable from Python
#2880addedUnauthenticated,Disconnected,EmptyResponseandStaleClientto thereconnect match in
send_raw_with_response, so the client reconnects and replays thestored login. That recovery is gated on the client having
reconnectionenabled and anAutoLogincredential to replay — and#3651documents the other half:A Python user has only the manual
connect()+login_user()flow available. So thecombination is: no auto-login to replay, and a flow that does not own session state. The
practical result is that a session lost shortly after login is not recovered — it surfaces as
Unauthenticatedon the next call, and the application must handle it by hand.Observed impact
A long-running Python consumer on a restart loop, against
iggy-server0.8.0 over TCPloopback.
login_user()returned successfully; the very next call raised:Ten seconds later the same startup failed differently, then succeeded on the third attempt
and ran for ~2h48m:
Both are errors
#2880already classifies as reconnectable — but with no reconnection/auto-login configurable from Python, they terminate the process instead, leaving restart
supervision (systemd) as the only recovery.
Workaround a Python caller has to hand-roll today
Because
login_user()returning is not sufficient evidence of an authenticated session, wenow re-verify it explicitly and re-login on failure — effectively reimplementing
auto_loginplus reconnection in Python:
Parity — other foreign SDKs already expose this
foreign/go/client/tcp/tcp_core.go—autoLogin AutoLoginforeign/csharp/Iggy_SDK/Configuration/AutoLoginSettings.csPython is the outlier.
Suggested direction
Everything needed already exists on the Rust side; this is about exposing it:
core/common/src/types/configuration/tcp_config/tcp_client_config.rs—TcpClientConfig.../tcp_client_config_builder.rs—with_auto_sign_in(AutoLogin).../tcp_client_reconnection_config.rs—TcpClientReconnectionConfigcore/common/src/types/configuration/auth_config/auto_login.rs—AutoLogincore/sdk/src/clients/client_builder.rs—IggyClientBuilder::with_auto_sign_inMinimal version: optional keyword arguments on
IggyClient(...)for reconnection settingsand auto-login credentials, passed through to
IggyClientBuilder. Fuller version: expose aconfig/builder object mirroring
TcpClientConfigBuilder, which would also give the PythonSDK somewhere to hang the QUIC/HTTP/WebSocket options from
#2835.Happy to open a PR if a maintainer indicates the preferred shape (kwargs vs. exposed builder).
Affected area / component
Python SDK (
foreign/python)Related
#3651— SDK client state conflates transport and session dimensions (explains why themanual
connect()+login_user()flow does not own session state). Related, not aduplicate: that issue is about the state enum being unreliable; this one is about the
configuration surface being absent in Python.
#2880— added the reconnect-and-replay-login behavior that this config would unlock.#1453—with_auto_sign_infor the Rust builders.#2835— Python SDK transports; a config object would be the natural home for those too.Versions
Server
0.8.0(DockerHubapache/iggy:0.8.0),apache-iggy0.8.0 (PyPI wheel, cp312,manylinux), Python 3.12.13, TCP on loopback. Python constructor and builder call quoted above
were read on
master, so the gap is present there too.Scope note
This issue is deliberately limited to the missing configuration surface in the Python
binding. Whether a session can still be lost immediately after a successful
login_user()even with auto-login and reconnection enabled is a separate Rust/server question that we
have not isolated, and it is not claimed here.