A small, dependency-free developer CLI for validating paper payloads, running a synthetic local mock, checking read-only API access, verifying signed webhooks, and tailing a bounded SSE stream.
The CLI has no order placement, modification, close, cancellation, withdrawal,
broker-login, or other live-trading command. Its mock binds only to loopback and
accepts only paper or sandbox signal fixtures.
This tool is integration software, not investment advice or a trading signal. It never promises or evaluates trading performance.
- Python 3.11 or newer
- no runtime dependencies
For development:
python -m venv .venv
. .venv/bin/activate
python -m pip install --no-deps -e .
pipsync --versionYou can also run directly from a checkout:
PYTHONPATH=src python -m pipsync_cli --versionValidate the intentionally small paper-signal or event contract:
pipsync validate examples/paper-signal.json
pipsync --json validate --kind event examples/paper-event.json
cat examples/paper-signal.json | pipsync validate -mode=live is rejected. Validation has no network side effect.
Run the loopback-only synthetic service:
pipsync mockIt exposes:
GET /api/v1/health(GET /healthremains a local compatibility alias)GET /api/v1/meGET /api/v1/signalsGET /api/trading/streamPOST /webhooks/customfor paper fixture validation only
The custom webhook returns an in-memory receipt with
"execution":"disabled". PUT, PATCH, DELETE, and all other POST paths return
HTTP 405. Binding to 0.0.0.0 or any non-loopback interface is rejected.
Try the fixture:
curl --fail-with-body \
-H 'Content-Type: application/json' \
--data-binary @examples/paper-signal.json \
http://127.0.0.1:8788/webhooks/customCheck configuration and the unauthenticated public health endpoint. --base-url
is the origin URL; the CLI appends the documented /api/v1 paths:
pipsync doctor
pipsync --json doctor --base-url https://app.pipsync.ioTo additionally call read-only /api/v1/me, name an environment variable:
export PIPSYNC_API_KEY='replace-with-your-scoped-read-key'
pipsync doctor --base-url https://app.pipsync.io \
--api-key-env PIPSYNC_API_KEYThe value is read from the environment and is never printed. Remote HTTP is rejected; remote endpoints require HTTPS. URLs containing credentials, paths, query strings, or fragments are rejected, and redirects are not followed.
Verification reads the exact file bytes, checks the timestamp freshness window,
computes HMAC-SHA256 over <timestamp>.<raw-body>, and uses a constant-time
comparison. Multiple v1 values are accepted for key rotation when at least one
matches. Neither secret nor signature is printed.
export PIPSYNC_WEBHOOK_SECRET='your-local-or-managed-secret'
export PIPSYNC_WEBHOOK_SIGNATURE='t=...,v1=...'
pipsync webhook verify webhook-body.jsonSecrets can only be loaded from an environment variable. Passing a literal signature is supported for debugging, but the environment option avoids shell history. See docs/WEBHOOKS.md.
Tail the bounded SSE stream exposed by the local synthetic mock. This command is loopback-only, has no API-key option, and cannot connect to a remote endpoint:
pipsync tail --base-url http://127.0.0.1:8788 --max-events 3
pipsync --json tail --base-url http://localhost:8788 --max-events 10Each event is redacted before display. The command sends GET only and exits after at most 100 events.
| Code | Meaning |
|---|---|
0 |
validation/check/verification succeeded |
1 |
payload, signature, local configuration, or mock startup failed |
2 |
command-line usage error (argparse) |
3 |
read-only network diagnostic or SSE operation failed |
Read docs/SAFETY.md before extending the CLI. Highlights:
- no live-trading commands or broker credentials
- mock server limited to loopback and synthetic paper data
- remote diagnostics limited to the documented GET-only HTTPS API paths
- SSE tailing limited to the loopback-only synthetic mock, without credentials
- bearer keys and webhook secrets loaded by environment-variable name
- recursive key-based and token-pattern redaction
- bounded JSON, webhook, response, SSE line, and event counts
- raw-body webhook authentication before payload trust
The mock's duplicate set is process-local. Production systems need a durable, tenant-scoped idempotency key and atomic uniqueness gate before side effects.
PYTHONPATH=src python -m compileall -q src tests
PYTHONPATH=src python -m unittest discover -s tests -vSee CONTRIBUTING.md, SECURITY.md, and CHANGELOG.md.
Use the CLI to validate locally before adding credentials. For the documented hosted read-only API, key scopes, and rate-limit behavior, see the PipSync API reference.