Skip to content

feat(python): add network= constructor kwarg (phase 1 of #1348) - #1489

Merged
chaliy merged 1 commit into
mainfrom
fix/issue-1348-python-network-config
Apr 30, 2026
Merged

chaliy merged 1 commit into
mainfrom
fix/issue-1348-python-network-config

Conversation

@chaliy

@chaliy chaliy commented Apr 30, 2026

Copy link
Copy Markdown
Contributor

Summary

Phase 1 of #1348. Exposes the existing Rust NetworkAllowlist through Python:

  • Bash(network=...) and BashTool(network=...) accept {"allow": [...], "block_private_ips": True} or {"allow_all": True}
  • Omitting network= keeps outbound HTTP disabled (unchanged secure default)
  • Empty {"allow": []} still blocks every URL but is distinct from omitted network=
  • Config persists across reset() and from_snapshot()
  • bashkit-python now compiles bashkit with the http_client feature so reqwest is built unconditionally; gating happens at the Python API layer
  • block_private_ips defaults to True (Rust parity)

Why

bashkit-python previously had no surface for outbound HTTP and the crate compiled without http_client, even though the Rust core has shipped NetworkAllowlist, credential injection, callbacks, and bot-auth for some time. This PR closes the easiest part of that gap (allowlist) so Python users can actually call curl/wget/http against allowlisted hosts.

Out of scope (later phases of #1348)

  • Credential injection (credentials, credential_placeholders)
  • Request/response callbacks (http_handler, before_http, after_http)
  • bot_auth

Tests

crates/bashkit-python/tests/test_network_config.py (15 tests, all green):

  • Default-deny on Bash and BashTool
  • Allowlist still blocks unlisted hosts
  • allow_all removes allowlist-block stderr
  • Empty allow blocks everything
  • Validation: unknown key, missing allow/allow_all, mutually exclusive, wrong type
  • reset() preserves both allowlist and allow_all
  • from_snapshot() accepts network= for both Bash and BashTool
  • block_private_ips default-true blocks loopback even when allowlisted; block_private_ips=False is accepted

Test plan

  • cargo fmt --check
  • cargo clippy --all-targets -- -D warnings
  • cargo test --features http_client (full workspace, all green)
  • pytest crates/bashkit-python/tests/ (623 pass, 2 skipped)
  • ruff check && ruff format --check (all green)
  • Manual smoke test of allowlist + reset + allow_all

Part of #1348


Generated by Claude Code

Expose `NetworkAllowlist` through `Bash(network=...)` and
`BashTool(network=...)`. Accepts a dict with `allow`, `allow_all`, and
`block_private_ips`; omitting `network=` keeps outbound HTTP disabled
(unchanged secure default). Config is preserved across `reset()` and
`from_snapshot()`.

Enables `http_client` in the bashkit-python crate so `reqwest` is built
unconditionally; gating happens at the Python API layer.

Phase 2-4 of the issue (credential injection, before/after/handler
callbacks, bot-auth) ship in follow-ups.

Part of #1348
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
bashkit 3b6b15d Commit Preview URL

Branch Preview URL
Apr 30 2026, 09:27 AM

@chaliy
chaliy merged commit 13dbed6 into main Apr 30, 2026
24 checks passed
@chaliy
chaliy deleted the fix/issue-1348-python-network-config branch April 30, 2026 09:38
@codecov

codecov Bot commented Apr 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

chaliy added a commit that referenced this pull request May 30, 2026
## Summary

Phase 1 of #1348. Exposes the existing Rust `NetworkAllowlist` through
Python:

- `Bash(network=...)` and `BashTool(network=...)` accept `{"allow":
[...], "block_private_ips": True}` or `{"allow_all": True}`
- Omitting `network=` keeps outbound HTTP disabled (unchanged secure
default)
- Empty `{"allow": []}` still blocks every URL but is distinct from
omitted `network=`
- Config persists across `reset()` and `from_snapshot()`
- `bashkit-python` now compiles bashkit with the `http_client` feature
so `reqwest` is built unconditionally; gating happens at the Python API
layer
- `block_private_ips` defaults to `True` (Rust parity)

## Why

`bashkit-python` previously had no surface for outbound HTTP and the
crate compiled without `http_client`, even though the Rust core has
shipped `NetworkAllowlist`, credential injection, callbacks, and
bot-auth for some time. This PR closes the easiest part of that gap
(allowlist) so Python users can actually call `curl`/`wget`/`http`
against allowlisted hosts.

## Out of scope (later phases of #1348)

- Credential injection (`credentials`, `credential_placeholders`)
- Request/response callbacks (`http_handler`, `before_http`,
`after_http`)
- `bot_auth`

## Tests

`crates/bashkit-python/tests/test_network_config.py` (15 tests, all
green):

- Default-deny on `Bash` and `BashTool`
- Allowlist still blocks unlisted hosts
- `allow_all` removes allowlist-block stderr
- Empty allow blocks everything
- Validation: unknown key, missing `allow`/`allow_all`, mutually
exclusive, wrong type
- `reset()` preserves both allowlist and `allow_all`
- `from_snapshot()` accepts `network=` for both `Bash` and `BashTool`
- `block_private_ips` default-true blocks loopback even when
allowlisted; `block_private_ips=False` is accepted

## Test plan

- [x] `cargo fmt --check`
- [x] `cargo clippy --all-targets -- -D warnings`
- [x] `cargo test --features http_client` (full workspace, all green)
- [x] `pytest crates/bashkit-python/tests/` (623 pass, 2 skipped)
- [x] `ruff check && ruff format --check` (all green)
- [x] Manual smoke test of allowlist + reset + allow_all

Part of #1348

---
_Generated by [Claude
Code](https://claude.ai/code/session_015E4TFL6EEnsG2GeLKbRYkJ)_
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant