feat(cli): add opt-in uipath-ipc transport to uipath server [ROBO-5779]#1786
Draft
eduard-dumitru wants to merge 2 commits into
Draft
feat(cli): add opt-in uipath-ipc transport to uipath server [ROBO-5779]#1786eduard-dumitru wants to merge 2 commits into
eduard-dumitru wants to merge 2 commits into
Conversation
348498e to
bbf3dc8
Compare
bbf3dc8 to
27e57dc
Compare
f61db5d to
c99debc
Compare
`uipath server` now supports two transports behind one shared job core; HTTP
stays the DEFAULT and IPC is opt-in via an env var, so the switch is reversible
and backward compatible.
- Transport = the UIPATH_SERVER_IPC env var: its presence selects uipath-ipc,
gated by _ipc_capability_available() (an isolated, non-failing seam — today
"is uipath_ipc importable") so an env var set against a runtime without IPC
support falls back to HTTP instead of failing. Unset ⇒ HTTP.
- The endpoint arg is shared: --server-socket is the pipe name under IPC and the
UDS path under HTTP. The executor never changes how it spawns, and an older
runtime that predates IPC just ignores the env var and treats it as a UDS path.
- HTTP edge (default, unchanged): create_app / /health / /jobs/{job_key}/start,
Unix socket or TCP, ready-ACK, host-header validation.
- IPC edge (opt-in): IPythonRuntimeServer (Ping / StartJob) over
NamedPipeServerTransport, Windows Proactor loop.
Both edges run jobs through _run_command_isolated (per-job env/cwd isolation,
serialized by _state.lock). Cancellation is out of scope for Phase 1
(StopJobAsync stays a no-op); a future phase can add it.
`uipath-ipc` stays a hard dependency (internal Azure Artifacts feed for now).
Publishing it to public PyPI is a prerequisite for a public `pip install uipath`.
Tests: test_server.py (HTTP), test_server_ipc.py (IPC), test_server_transport.py
(env-var selection, capability fallback, endpoint guard).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
c99debc to
44f22cb
Compare
🚨 Heads up:
|
🚨 Heads up:
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


What
Adds a
uipath-ipcnamed-pipe transport touipath serveras an opt-in, second transport — HTTP-over-socket stays the default. Transport is chosen by theUIPATH_SERVER_IPCenv var (its presence selects IPC); the--server-socketarg is shared — a pipe name under IPC, a UDS path under HTTP. So the .NET executor never changes how it spawns the server, and an older runtime that predates IPC simply ignores the env var and keeps doing HTTP.This is intentionally additive and reversible: the
uipath servercommand is internal and consumed only by the .NET executor (SDK users, coded workflows, and agent frameworks never call it), so IPC can be validated on Linux + Windows with real jobs while HTTP remains a kill-switch. Retiring HTTP is a later phase.Changes
cli_server.py— one shared, transport-agnostic job core (_run_command_isolated: per-jobos.environ/cwd save-set-restore, serialized by_state.lock), fronted by two edges:create_app/GET /health/POST /jobs/{job_key}/start, Unix socket or TCP (--client-socket/--server-socket/--port/--tcp), ready-ACK, host-header validation.IPythonRuntimeServer(Ping / StartJob) +PythonRuntimeServiceoverNamedPipeServerTransport, on a Windows Proactor loop. DTOs cross as PascalCase dicts (matching the .NET DTOs)._should_use_ipc()=UIPATH_SERVER_IPCpresent AND_ipc_capability_available()— an isolated, non-failing capability seam (today: isuipath_ipcimportable) so an env var set against a runtime without IPC support falls back to HTTP instead of failing.--server-socketis the pipe name in IPC mode (required there).pyproject.toml— addsuipath-ipcas a dependency, pinned via[tool.uv.sources]+[[tool.uv.index]]to the (anonymously accessible) UiPath-Internal Azure Artifacts feed souv/CI can resolve it.test_server.py) and addstest_server_ipc.py(IPC: Ping / StartJob, env isolation) +test_server_transport.py(env-var selection, capability fallback, endpoint guard).Verified locally
uv syncinstalls everything (incl.uipath-ipcfrom the anonymous feed). All three server test suites pass — HTTP, IPC, and transport-selection.ruff check,ruff format --check, andmypyare clean on the changed files. (The twotest_start_job_successcases need the runtime factory the CLI registers via_ensure_runtime_initialized, which the in-process test harness bypasses — a pre-existing test-isolation quirk, green in the full suite / when the factory is registered.)Open items / follow-ups (why this is a draft)
uipath-ipcis a hard dependency but currently lives only on the UiPath-Internal feed (not PyPI). A publicpip install uipathneeds it resolvable, so publishinguipath-ipcto PyPI is a GA prerequisite. The[tool.uv.*]config only unblocksuv/CI resolution — it is not baked into the wheel.UIPATH_SERVER_IPCto opt into IPC, connects anIpcClientproxy, usesPingfor readiness, and auto-falls back to HTTP against an older Python (behind a capability seam mirroring_ipc_capability_available). Required for full end-to-end.StopJobAsyncstays a no-op. A future phase can add it.execution.log); moving them onto IPC is Phase 2.🤖 Generated with Claude Code