Metadata-Version: 2.4
Name: telepact
Version: 1.0.0a326
Summary: The Python Telepact library
Author-email: Telepact Authors <telepact@googlegroups.com>
License-Expression: Apache-2.0
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Operating System :: OS Independent
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE
Requires-Dist: msgpack<2,>=1.1.1
Requires-Dist: PyYAML<7,>=6.0.2
Dynamic: license-file

## Telepact Library for Python

### Installation

```
pip install --pre telepact
```

Published PyPI releases are currently prereleases. To pin a specific release,
use the exact version from [doc/04-operate/03-versions.md](https://github.com/Telepact/telepact/blob/main/doc/04-operate/03-versions.md).

### Usage

API:

```yaml
- fn.greet:
    subject: string
  ->:
    Ok_:
      message: string
```

Server:

```py
from telepact import Client, FunctionRouter, Message, Serializer, Server, TelepactSchema

schema = TelepactSchema.from_directory('/directory/containing/api/files')

# The schema directory may contain multiple *.telepact.yaml and
# *.telepact.json files. Subdirectories are rejected.

async def greet(function_name: str, request_message: 'Message') -> 'Message':
    arguments = request_message.body[function_name]
    subject = arguments['subject']
    return Message({}, {'Ok_': {'message': f'Hello {subject}!'}})


async def middleware(request_message: 'Message', function_router) -> 'Message':
    function_name = request_message.get_body_target()
    try:
        log.info("Function started", {'function': function_name})
        return await function_router.route(request_message)
    finally:
        log.info("Function finished", {'function': function_name})


options = Server.Options()
# Set this to False when your schema does not define union.Auth_.
options.auth_required = False
options.middleware = middleware
function_router = FunctionRouter({'fn.greet': greet})
server = Server(schema, function_router, options)


# Wire up request/response bytes from your transport of choice
async def transport_handler(request_bytes: bytes) -> bytes:
    response = await server.process(request_bytes)
    return response.bytes

transport.receive(transport_handler)
```

Client:

```py
async def adapter(m: Message, s: Serializer) -> Message:
    request_bytes = s.serialize(m)

    # Wire up request/response bytes to your transport of choice
    response_bytes = await transport.send(request_bytes)

    return s.deserialize(response_bytes)

options = Client.Options()
client = Client(adapter, options)

# Inside your async application code:
request = Message({}, {'fn.greet': {'subject': 'World'}})
response = await client.request(request)
if response.get_body_target() == 'Ok_':
    ok_payload = response.get_body_payload()
    print(ok_payload['message'])
else:
    raise RuntimeError(f"Unexpected response: {response.body}")
```

For more concrete usage examples,
[see the tests](https://github.com/Telepact/telepact/blob/main/test/lib/py/telepact_test/test_server.py).
