Metadata-Version: 2.4
Name: larzrpc
Version: 0.1.0
Summary: JSON-RPC 2.0 over HTTP, client and server, in pure Python. Decorator to expose functions, attribute-style client, batches, notifications. Zero dependencies.
Author: larz-scripter
License: MIT
Project-URL: Homepage, https://github.com/larz-scripter/larzrpc
Project-URL: Repository, https://github.com/larz-scripter/larzrpc
Project-URL: Documentation, https://github.com/larz-scripter/larzrpc#readme
Project-URL: Issues, https://github.com/larz-scripter/larzrpc/issues
Keywords: rpc,json-rpc,jsonrpc,http,api,microservices,client,server,remote-procedure-call,zero-dependency,pure-python
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# larzrpc

**JSON-RPC 2.0 over HTTP — client and server, in pure Python. Zero dependencies.**

Expose Python functions as a network API and call them from anywhere, using the
standard JSON-RPC 2.0 protocol — no framework, no code generation, no
dependencies. The server is one decorator and one `serve()` call; the client
calls remote methods as if they were local attributes.

```python
# server.py
from larzrpc import RPCServer
app = RPCServer()

@app.method
def add(a, b):
    return a + b

app.serve("127.0.0.1", 8080)
```

```python
# client.py
from larzrpc import RPCClient
api = RPCClient("http://127.0.0.1:8080")

api.add(2, 3)                  # 5      (attribute access -> remote call)
api.call("add", a=10, b=1)     # 11     (keyword params)
api.notify("log", "hi")        # fire-and-forget notification
```

## Why

- **Zero dependencies.** The client is `urllib`, the server is `http.server` —
  both standard library. Nothing to install.
- **Standard protocol.** Real JSON-RPC 2.0: positional *and* named params,
  batch requests, notifications, and the canonical error codes — so it
  interoperates with any compliant peer, not just itself.
- **Ergonomic.** Register a method with a decorator; call it as `client.method(...)`.
  Server errors surface as a real `RPCError` on the client with the code and data
  intact.
- **Testable & embeddable.** The dispatch core is a pure `request -> response`
  function (no sockets), and both client and server take a pluggable transport,
  so you can wire them together in-process — no network needed.
- **Mount anywhere.** Use the built-in threaded server, or the included WSGI app
  under gunicorn/waitress/[larz](https://github.com/larz-scripter/larz).

## Install

```bash
pip install larzrpc
```

## Server

```python
from larzrpc import RPCServer, RPCError

app = RPCServer()

@app.method                       # exposed as "transfer"
def transfer(src, dst, amount):
    if amount <= 0:
        raise RPCError("amount must be positive", code=1001, data={"amount": amount})
    ...
    return {"ok": True}

@app.method(name="account.balance")
def balance(account_id):
    ...

app.methods()                     # ["account.balance", "transfer"]
app.serve("0.0.0.0", 8080)        # threaded HTTP server
```

Or embed it:

```python
app.dispatch(request_dict)        # -> response dict (pure, no transport)
app.handle_json(raw_json_string)  # -> response JSON (handles batch + parse errors)
app.wsgi                          # a WSGI application
```

## Client

```python
from larzrpc import RPCClient, RPCError

api = RPCClient("http://127.0.0.1:8080")

try:
    api.transfer("a", "b", 100)
except RPCError as e:
    e.code, e.message, e.data     # structured error from the server
```

## Tests

```bash
python -m unittest discover -s tests -v   # 20 tests incl. a live localhost round-trip
```

## The Larz stack

Pure-Python, zero-dependency building blocks:

- **[larz](https://github.com/larz-scripter/larz)** — money-native web framework
- **[larzchain](https://github.com/larz-scripter/larzchain)** — from-scratch PoW blockchain
- **[larzmoney](https://github.com/larz-scripter/larzmoney)** — exact, penny-perfect money
- **[larzcrypt](https://github.com/larz-scripter/larzcrypt)** — pure-Python cryptography toolkit
- **[larzdb](https://github.com/larz-scripter/larzdb)** — crash-safe embedded database
- **[larzagent](https://github.com/larz-scripter/larzagent)** — zero-dep AI agent framework
- **[larzchart](https://github.com/larz-scripter/larzchart)** — data to inline SVG charts
- **[larzmark](https://github.com/larz-scripter/larzmark)** — Markdown + SEO static sites
- **[larztask](https://github.com/larz-scripter/larztask)** — durable background job queue
- **[larzvault](https://github.com/larz-scripter/larzvault)** — encrypted secrets manager
- **[larzvm](https://github.com/larz-scripter/larzvm)** — deterministic gas-metered VM
- **[larzcache](https://github.com/larz-scripter/larzcache)** — LRU/TTL/tiered caching
- **[larzvalidate](https://github.com/larz-scripter/larzvalidate)** — schema validation
- **[larzid](https://github.com/larz-scripter/larzid)** — decentralized identity
- **larzrpc** — this library

## License

MIT © larz-scripter
