Skip to content

feat: Add Python debugger and publishing - #13

Merged
Pijukatel merged 6 commits into
masterfrom
claude/python-actors-debug-hyt8ip
Sep 8, 2026
Merged

Pijukatel merged 6 commits into
masterfrom
claude/python-actors-debug-hyt8ip

Conversation

@Pijukatel

Copy link
Copy Markdown
Collaborator

How to use in Python Actors:

RUN pip install actor-debugger
# Swap the entrypoint for the debug launcher (revert this line to disable debugging):
CMD ["python3", "-m", "actor_debugger", "--brk"] 

Python sibling of the Node/TS actor-debugger, same architecture and the
same constraints (no infrastructure changes, browser-only debugging
machine): a one-line CMD change launches the Actor under debugpy, and one
HTTP server on ACTOR_WEB_SERVER_PORT serves a bundled browser debugger UI
and bridges a WebSocket at /dap to the adapter's DAP-over-TCP socket.

- python/: pip package (only runtime dep: debugpy; server + RFC6455
  WebSocket are stdlib). The bridge translates framing, injects the
  adapter's loopback address into attach requests (enables re-attach),
  and synthesizes a disconnect when the browser drops without one so
  page reloads don't kill the adapter.
- frontend: single-file DAP client - gutter breakpoints (persisted in
  localStorage), stepping, call stack, variables tree, in-frame REPL,
  exception breakpoints; --brk maps to --wait-for-client plus a synthetic
  first-line breakpoint for a Node-like entry stop.
- example-actor-python/: sample Actor mirroring the Apify Python template.
- python/README.md documents the design and the alternatives considered
  (GraalPy --inspect/CDP, DAP-to-CDP shim, code-server, web-pdb, Jupyter).
- publish-python.yml: PyPI release on py-v* tags, mirroring the npm flow.

Verified end-to-end: full DAP session through the bridge (protocol test)
and headless Chromium driving the served UI - entry pause, breakpoint
hit, step, variables, evaluate, resume, re-attach after reload.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0194oFPjsTxztgsPhyB4Wq7G
The example previously required the unpublished actor-debugger PyPI
package, so `apify push` failed at pip install. It now vendors the
actor_debugger package (copied from python/src) and its requirements are
only apify + debugpy - buildable and runnable on the platform today.
The demo code is restructured to be worth debugging: nested calls, rich
locals, a handled KeyError for the exception-breakpoint demo, slow ticks
so there is always time to attach, plus an input schema and a README
walkthrough (push, run, open the printed URL, what to try).

Also fixes a real bug this surfaced: socket.create_connection(timeout=5)
left a 5-second timeout on the established bridge-to-adapter socket, so
any debug session idle for 5+ seconds was torn down by the pump thread's
recv timeout. The timeout is now cleared after connect; sessions survive
arbitrary idle (verified 45s+, plus the full protocol and headless-
Chromium suites re-pass).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0194oFPjsTxztgsPhyB4Wq7G
The previous apify<3.0.0 pin resolved to apify 2.x/crawlee 0.x, whose
pydantic models fail to import under current pydantic 2.12+ ("cannot
specify both default and default_factory") - the crash seen on the
platform the moment the debugged run resumed past --brk. Reproduced
locally with apify<3 and verified apify 4.0.2 imports cleanly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0194oFPjsTxztgsPhyB4Wq7G
…ackage

The Python debugger is now delivered only as the pip package in python/,
injected into any Python Actor the same way as the npm version:

    RUN pip install actor-debugger
    CMD ["python3", "-m", "actor_debugger", "--brk"]

Docs rewritten injection-first: python/README.md leads with the two-line
Dockerfile change (plus a git-install line until the PyPI release), keeps
the CLI forms, architecture, security notes and design alternatives, and
records that the stack is verified on the Apify platform (UI and
DAP-over-WebSocket through the run ingress against a live run). Root
README pointer updated; pyproject homepage moved to apify/actor-debugger.

Verified: wheel builds with the frontend bundled, installs into a clean
venv, and the full DAP bridge test suite passes against that install.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0194oFPjsTxztgsPhyB4Wq7G
Replaces the token-based publish-python.yml with publish_to_pypi.yml,
matching the trusted publisher configured on PyPI (project
actor-debugger, repository apify/actor-debugger, workflow
publish_to_pypi.yml - the file name must match exactly). The publish job
authenticates with OIDC (id-token: write) through
pypa/gh-action-pypi-publish, so no PYPI_TOKEN secret is needed. The
pre-publish checks are unchanged: tag/version match plus CLI and
served-UI smoke tests. Docs updated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0194oFPjsTxztgsPhyB4Wq7G
Adds workflow_dispatch so the release can be started from the Actions
tab (e.g. for the first upload that claims the actor-debugger name). The
tag/version check only runs on tag pushes; a manual run publishes the
version pyproject.toml carries on the chosen ref, and PyPI's refusal of
re-uploads makes repeated runs safe.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0194oFPjsTxztgsPhyB4Wq7G
@github-actions github-actions Bot added this to the 149th sprint - Tooling team milestone Sep 8, 2026
@github-actions github-actions Bot added the t-tooling Issues with this label are in the ownership of the tooling team. label Sep 8, 2026
@Pijukatel
Pijukatel merged commit f450b59 into master Sep 8, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

t-tooling Issues with this label are in the ownership of the tooling team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants