Metadata-Version: 2.2
Name: decpython
Version: 1.0.1
Summary: 跨平台、支持 Web 通信的 Python 终端工具
Home-page: https://github.com/your-username/decpython_maskter
Author: decpython
Author-email: decrule@outlook.com
License: MIT
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.9.0
Description-Content-Type: text/markdown
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == "dev"
Requires-Dist: ruff>=0.1; extra == "dev"
Dynamic: author-email
Dynamic: home-page
Dynamic: requires-python

# DecPython

Run Python in a subprocess from your code and get string results, or open a Jupyter-style web terminal. Optional HTTP API with host/port/secret for remote execution. Cross-platform, stdlib only.

## Install

```bash
pip install -e .
```

## Quick start

```python
from decpython import DecPython

dp = DecPython(gui=False, python='python')
result = dp.send('a = 1\nb = 2\na + b')   # -> '3'
dp.close()
```

With a web UI: `gui=True`. Code and results from `send()` appear in the browser (Shift+Enter or Run).

## Host, port, secret (HTTP API)

When you pass `port` (or use `gui=True`), a web server is started. **`DecPython(...)` blocks until the server is bound and ready**, so you can call `send()` or the standalone `send()` immediately after.

- **host** — Bind address (default `'localhost'`). Use `'0.0.0.0'` to accept non-local requests.
- **port** — Port number, or `None` / `0` for auto.
- **secret** — If set, remote clients must send the same secret (timestamp + HMAC) to POST `/exec`. If `None`, no auth; client should use `send(..., secret=None)`.

```python
# Server with no auth
dp = DecPython(gui=False, host='127.0.0.1', port=0, secret=None)
port = dp.port   # ready after init
dp.close()
```

## Standalone `send()` (remote)

Send a command to a running DecPython server without holding the instance:

```python
from decpython import DecPython, send

dp = DecPython(gui=False, host='127.0.0.1', port=0, secret='key')
out = send('1 + 2', host='127.0.0.1', port=dp.port, secret='key')
# out == {'code': 200, 'data': '3', 'msg': ''}
dp.close()
```

- **Success:** `{'code': 200, 'data': '<result>', 'msg': ''}`  
- **Error:** `{'code': -1, 'data': '', 'msg': '<error>'}`  
Use `secret=None` when the server was started with `secret=None`.

See `examples/example_remote.py` for more.

## API

- **`DecPython(gui=..., python='python', host='localhost', port=None, secret=None)`** — Blocks until the web server (if any) is bound. `port` / `gui` control whether the server starts.
- **`dp.send(code)`** — Run code in the subprocess; returns the last expression as a string (or the error message).
- **`dp.port`** — Bound port (None if no server).
- **`dp.close()`** — Stop the subprocess and web server.
- **`send(command, host='localhost', port=..., secret=None)`** — POST to a running server; returns the dict above.

## License

MIT
