Metadata-Version: 2.4
Name: deepx-client
Version: 0.2.0
Summary: Python client for a DeepH-serve instance, part of the DeepX ecosystem.
Author-email: DeepH team <deeph-pack@outlook.com>
License-Expression: GPL-3.0-or-later
Project-URL: Canonical package, https://pypi.org/project/deepx-client/
Keywords: DeepX,DeepH,Hamiltonian,band structure,client
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Physics
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx>=0.27
Requires-Dist: pydantic>=2.8
Requires-Dist: click>=8.1
Requires-Dist: tomli>=2.0; python_version < "3.11"
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-cov>=5.0; extra == "dev"
Requires-Dist: ruff>=0.6; extra == "dev"
Requires-Dist: black>=24.0; extra == "dev"
Dynamic: license-file

# deepx-client

`deepx-client` is the Python client for a DeepH-serve instance. It submits
POSCAR files, watches asynchronous jobs and downloads the predicted Hamiltonian,
band structure and DOS artifacts.

The client only speaks the public `/v1` HTTP API. It does not import the server,
JAX or DeepH-pack, so installing it is lightweight. It is a Python SDK; no
console command is installed yet.

## Install

From PyPI (after release):

```bash
pip install deepx-client
```

From this repository:

```bash
uv pip install -e "./client[dev]"
# or
pip install -e ./client
```

The import package is `deepx_client`. `DeepHClient` remains available as a
class alias. The old `deeph_client` import path is provided by the separate
`deeph-client` compatibility distribution. New code should use `DeepXClient`
and `deepx_client`.

## Python API

```python
from deepx_client import DeepXClient

with DeepXClient("http://127.0.0.1:8000", api_key="...") as client:
    job = client.submit(
        open("POSCAR").read(),
        tasks=["hamiltonian", "band"],
        band={"npoints": 200, "energy_window": [-5, 5]},
    )
    job = client.wait(job.id, on_update=lambda item: print(item.stage, item.progress))
    paths = client.download_all(job.id, "./results")
    print(paths)

    account = client.me()
    print(account.plan, account.daily_used, account.hop_available)
    receipt = client.exchange_hop("structures.zip")
    print(receipt.credited_hop, receipt.review_status)
```

Structure exchanges require a server with the shared `/v1/me/hop/exchanges`
endpoint (DeepH-serve API 0.2.5 or newer).

The optional internal CLI runs as `python -m deepx_client`:

```bash
python -m deepx_client account
python -m deepx_client hop exchange structures.zip
python -m deepx_client hop list
```

A complete runnable example is
[`examples/python_client.py`](examples/python_client.py):

```bash
export DEEPH_SERVE_URL=http://127.0.0.1:8000
export DEEPH_SERVE_API_KEY=...
python examples/python_client.py POSCAR --tasks hamiltonian --out results
```

## Configure

Each API key is bound to one account; the owner can copy it from the web
console's **API access** page. The server URL and API key can be supplied with
environment variables:

```bash
export DEEPH_SERVE_URL=http://127.0.0.1:8000
export DEEPH_SERVE_API_KEY=...
```

or in `~/.config/deepx/client.toml`:

```toml
default = "lab"

[profiles.lab]
server = "https://deeph.example.com"
api_key = "..."
timeout = 30.0
verify = true
```

The old `~/.config/deeph/client.toml` path is still read when the new path does
not exist. Precedence: explicitly passed values > environment > selected
profile > defaults.

## Python API reference

```python
from deepx_client import DeepXClient

with DeepXClient("http://127.0.0.1:8000", api_key="...") as client:
    job = client.submit(
        open("POSCAR").read(),
        tasks=["hamiltonian", "band"],
        band={"npoints": 200, "energy_window": [-5, 5]},
    )
    job = client.wait(job.id)
    paths = client.download_all(job.id, "./results")
```

`DeepXClient` exposes `health()`, `me()`, `usage()`, `hop_exchanges()`,
`exchange_hop()`, `models()`, `random_structure()`, `analyze_structure()`,
`submit()`, `submit_request()`, `submit_and_wait()`, `get()`, `list()`,
`artifacts()`, `wait()`, `cancel()`, `delete()`, `download()` and
`download_all()`.

## Errors

- `APIError`: non-success response; carries `status_code`, `code`, `details`
  and `request_id`.
- `JobFailedError`: job ended as `failed`, `canceled` or `expired`.
- `JobTimeoutError`: local wait timeout elapsed.
- `ArtifactVerificationError`: downloaded file did not match the manifest
  sha256.
- `ConfigError`: invalid local profile or configuration.

All errors derive from `DeepHClientError`.

## Compatibility aliases

The distribution `deeph-client` is a compatibility alias that depends on
`deepx-client`. It keeps old imports working:

```python
from deeph_client import DeepHClient
```

New code should use `deepx_client` and `DeepXClient`.

## Development

```bash
cd client
uv venv .venv
uv pip install --python .venv/bin/python -e ".[dev]"
.venv/bin/python -m pytest
.venv/bin/python -m ruff check src tests
.venv/bin/python -m black --check src tests
```

## License

GPL-3.0-or-later, matching DeepH-serve. See `LICENSE`.
