eywa-client


Nameeywa-client JSON
Version 0.3.1 PyPI version JSON
download
home_pageNone
SummaryEYWA client library for Python providing JSON-RPC communication, GraphQL queries, and task management for EYWA robots
upload_time2025-07-21 08:49:18
maintainerNone
docs_urlNone
authorNone
requires_python>=3.7
licenseNone
keywords eywa client json-rpc graphql robotics automation
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # EYWA Client for Python

[![PyPI version](https://badge.fury.io/py/eywa-client.svg)](https://badge.fury.io/py/eywa-client)
[![Python Versions](https://img.shields.io/pypi/pyversions/eywa-client.svg)](https://pypi.org/project/eywa-client/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

EYWA client library for Python providing JSON-RPC communication, GraphQL queries, and task management for EYWA robots.

## Installation

```bash
pip install eywa-client
```

## Quick Start

```python
import asyncio
import eywa

async def main():
    # Initialize the client
    eywa.open_pipe()
    
    # Log messages
    eywa.info("Robot started")
    
    # Execute GraphQL queries
    result = await eywa.graphql("""
        query {
            searchUser(_limit: 10) {
                euuid
                name
                type
            }
        }
    """)
    
    # Update task status
    eywa.update_task(eywa.PROCESSING)
    
    # Complete the task
    eywa.close_task(eywa.SUCCESS)

asyncio.run(main())
```

## Features

- 🚀 **Async/Await Support** - Modern Python async programming
- 📊 **GraphQL Integration** - Execute queries and mutations against EYWA datasets
- 📝 **Comprehensive Logging** - Multiple log levels with metadata support
- 🔄 **Task Management** - Update status, report progress, handle task lifecycle
- 🎯 **Type Hints** - Full type annotations for better IDE support
- 📋 **Table/Sheet Classes** - Built-in data structures for reports

## API Reference

### Initialization

#### `open_pipe()`
Initialize stdin/stdout communication with EYWA runtime. Must be called before using other functions.

```python
eywa.open_pipe()
```

### Logging Functions

#### `log(event="INFO", message="", data=None, duration=None, coordinates=None, time=None)`
Log a message with full control over all parameters.

```python
eywa.log(
    event="INFO",
    message="Processing item",
    data={"itemId": 123},
    duration=1500,
    coordinates={"x": 10, "y": 20}
)
```

#### `info()`, `error()`, `warn()`, `debug()`, `trace()`, `exception()`
Convenience methods for different log levels.

```python
eywa.info("User logged in", {"userId": "abc123"})
eywa.error("Failed to process", {"error": str(e)})
eywa.exception("Unhandled error", {"stack": traceback.format_exc()})
```

### Task Management

#### `async get_task()`
Get current task information. Returns a coroutine.

```python
task = await eywa.get_task()
print(f"Processing: {task['message']}")
```

#### `update_task(status="PROCESSING")`
Update the current task status.

```python
eywa.update_task(eywa.PROCESSING)
```

#### `close_task(status="SUCCESS")`
Close the task with a final status and exit the process.

```python
try:
    # Do work...
    eywa.close_task(eywa.SUCCESS)
except Exception as e:
    eywa.error("Task failed", {"error": str(e)})
    eywa.close_task(eywa.ERROR)
```

#### `return_task()`
Return control to EYWA without closing the task.

```python
eywa.return_task()
```

### Reporting

#### `report(message, data=None, image=None)`
Send a task report with optional data and image.

```python
eywa.report("Analysis complete", {
    "accuracy": 0.95,
    "processed": 1000
}, chart_image_base64)
```

### GraphQL

#### `async graphql(query, variables=None)`
Execute a GraphQL query against the EYWA server.

```python
result = await eywa.graphql("""
    mutation CreateUser($input: UserInput!) {
        syncUser(data: $input) {
            euuid
            name
        }
    }
""", {
    "input": {
        "name": "John Doe",
        "active": True
    }
})
```

### JSON-RPC

#### `async send_request(data)`
Send a JSON-RPC request and wait for response.

```python
result = await eywa.send_request({
    "method": "custom.method",
    "params": {"foo": "bar"}
})
```

#### `send_notification(data)`
Send a JSON-RPC notification without expecting a response.

```python
eywa.send_notification({
    "method": "custom.event",
    "params": {"status": "ready"}
})
```

#### `register_handler(method, func)`
Register a handler for incoming JSON-RPC method calls.

```python
def handle_ping(data):
    print(f"Received ping: {data['params']}")
    eywa.send_notification({
        "method": "custom.pong",
        "params": {"timestamp": time.time()}
    })

eywa.register_handler("custom.ping", handle_ping)
```

## Data Structures

### Sheet Class
For creating structured tabular data:

```python
sheet = eywa.Sheet("UserReport")
sheet.set_columns(["Name", "Email", "Status"])
sheet.add_row({"Name": "John", "Email": "john@example.com", "Status": "Active"})
sheet.add_row({"Name": "Jane", "Email": "jane@example.com", "Status": "Active"})
```

### Table Class
For creating multi-sheet reports:

```python
table = eywa.Table("MonthlyReport")
table.add_sheet(users_sheet)
table.add_sheet(stats_sheet)

# Convert to JSON for reporting
eywa.report("Monthly report", {"table": json.loads(table.toJSON())})
```

## Constants

- `SUCCESS` - Task completed successfully
- `ERROR` - Task failed with error
- `PROCESSING` - Task is currently processing
- `EXCEPTION` - Task failed with exception

## Complete Example

```python
import asyncio
import eywa
import traceback

async def process_data():
    # Initialize
    eywa.open_pipe()
    
    try:
        # Get task info
        task = await eywa.get_task()
        eywa.info("Starting task", {"taskId": task["euuid"]})
        
        # Update status
        eywa.update_task(eywa.PROCESSING)
        
        # Query data with GraphQL
        result = await eywa.graphql("""
            query GetActiveUsers {
                searchUser(_where: {active: {_eq: true}}) {
                    euuid
                    name
                    email
                }
            }
        """)
        
        users = result["data"]["searchUser"]
        
        # Create report
        sheet = eywa.Sheet("ActiveUsers")
        sheet.set_columns(["ID", "Name", "Email"])
        
        for user in users:
            eywa.debug("Processing user", {"userId": user["euuid"]})
            sheet.add_row({
                "ID": user["euuid"],
                "Name": user["name"],
                "Email": user.get("email", "N/A")
            })
        
        # Report results
        eywa.report("Found active users", {
            "count": len(users),
            "sheet": sheet.__dict__
        })
        
        # Success!
        eywa.info("Task completed")
        eywa.close_task(eywa.SUCCESS)
        
    except Exception as e:
        eywa.error("Task failed", {
            "error": str(e),
            "traceback": traceback.format_exc()
        })
        eywa.close_task(eywa.ERROR)

if __name__ == "__main__":
    asyncio.run(process_data())
```

## Type Hints

The library includes comprehensive type hints via `.pyi` file:

```python
from typing import Dict, Any, Optional
import eywa

async def process() -> None:
    task: Dict[str, Any] = await eywa.get_task()
    result: Dict[str, Any] = await eywa.graphql(
        "query { searchUser { name } }", 
        variables={"limit": 10}
    )
```

## Error Handling

The client includes custom exception handling:

```python
try:
    result = await eywa.graphql("{ invalid }")
except eywa.JSONRPCException as e:
    eywa.error(f"GraphQL failed: {e.message}", {"error": e.data})
```

## Testing

Test your robot locally using the EYWA CLI:

```bash
eywa run -c 'python my_robot.py'
```

## Examples

To run examples, position terminal to root project folder and run:

```bash
# Test all features
python -m examples.test_eywa_client

# Run a simple GraphQL query
python -m examples.raw_graphql

# WebDriver example
python -m examples.webdriver
```

## Requirements

- Python 3.7+
- No external dependencies (uses only standard library)

## License

MIT

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## Support

For issues and questions, please visit the [EYWA repository](https://github.com/neyho/eywa).

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "eywa-client",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": null,
    "keywords": "eywa, client, json-rpc, graphql, robotics, automation",
    "author": null,
    "author_email": "Robert Gersak <robi@neyho.com>",
    "download_url": "https://files.pythonhosted.org/packages/9a/be/3b496dc170d2c241dca4d07ea8c0b36a36244d93e77f983d412ddbad9d93/eywa_client-0.3.1.tar.gz",
    "platform": null,
    "description": "# EYWA Client for Python\n\n[![PyPI version](https://badge.fury.io/py/eywa-client.svg)](https://badge.fury.io/py/eywa-client)\n[![Python Versions](https://img.shields.io/pypi/pyversions/eywa-client.svg)](https://pypi.org/project/eywa-client/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nEYWA client library for Python providing JSON-RPC communication, GraphQL queries, and task management for EYWA robots.\n\n## Installation\n\n```bash\npip install eywa-client\n```\n\n## Quick Start\n\n```python\nimport asyncio\nimport eywa\n\nasync def main():\n    # Initialize the client\n    eywa.open_pipe()\n    \n    # Log messages\n    eywa.info(\"Robot started\")\n    \n    # Execute GraphQL queries\n    result = await eywa.graphql(\"\"\"\n        query {\n            searchUser(_limit: 10) {\n                euuid\n                name\n                type\n            }\n        }\n    \"\"\")\n    \n    # Update task status\n    eywa.update_task(eywa.PROCESSING)\n    \n    # Complete the task\n    eywa.close_task(eywa.SUCCESS)\n\nasyncio.run(main())\n```\n\n## Features\n\n- \ud83d\ude80 **Async/Await Support** - Modern Python async programming\n- \ud83d\udcca **GraphQL Integration** - Execute queries and mutations against EYWA datasets\n- \ud83d\udcdd **Comprehensive Logging** - Multiple log levels with metadata support\n- \ud83d\udd04 **Task Management** - Update status, report progress, handle task lifecycle\n- \ud83c\udfaf **Type Hints** - Full type annotations for better IDE support\n- \ud83d\udccb **Table/Sheet Classes** - Built-in data structures for reports\n\n## API Reference\n\n### Initialization\n\n#### `open_pipe()`\nInitialize stdin/stdout communication with EYWA runtime. Must be called before using other functions.\n\n```python\neywa.open_pipe()\n```\n\n### Logging Functions\n\n#### `log(event=\"INFO\", message=\"\", data=None, duration=None, coordinates=None, time=None)`\nLog a message with full control over all parameters.\n\n```python\neywa.log(\n    event=\"INFO\",\n    message=\"Processing item\",\n    data={\"itemId\": 123},\n    duration=1500,\n    coordinates={\"x\": 10, \"y\": 20}\n)\n```\n\n#### `info()`, `error()`, `warn()`, `debug()`, `trace()`, `exception()`\nConvenience methods for different log levels.\n\n```python\neywa.info(\"User logged in\", {\"userId\": \"abc123\"})\neywa.error(\"Failed to process\", {\"error\": str(e)})\neywa.exception(\"Unhandled error\", {\"stack\": traceback.format_exc()})\n```\n\n### Task Management\n\n#### `async get_task()`\nGet current task information. Returns a coroutine.\n\n```python\ntask = await eywa.get_task()\nprint(f\"Processing: {task['message']}\")\n```\n\n#### `update_task(status=\"PROCESSING\")`\nUpdate the current task status.\n\n```python\neywa.update_task(eywa.PROCESSING)\n```\n\n#### `close_task(status=\"SUCCESS\")`\nClose the task with a final status and exit the process.\n\n```python\ntry:\n    # Do work...\n    eywa.close_task(eywa.SUCCESS)\nexcept Exception as e:\n    eywa.error(\"Task failed\", {\"error\": str(e)})\n    eywa.close_task(eywa.ERROR)\n```\n\n#### `return_task()`\nReturn control to EYWA without closing the task.\n\n```python\neywa.return_task()\n```\n\n### Reporting\n\n#### `report(message, data=None, image=None)`\nSend a task report with optional data and image.\n\n```python\neywa.report(\"Analysis complete\", {\n    \"accuracy\": 0.95,\n    \"processed\": 1000\n}, chart_image_base64)\n```\n\n### GraphQL\n\n#### `async graphql(query, variables=None)`\nExecute a GraphQL query against the EYWA server.\n\n```python\nresult = await eywa.graphql(\"\"\"\n    mutation CreateUser($input: UserInput!) {\n        syncUser(data: $input) {\n            euuid\n            name\n        }\n    }\n\"\"\", {\n    \"input\": {\n        \"name\": \"John Doe\",\n        \"active\": True\n    }\n})\n```\n\n### JSON-RPC\n\n#### `async send_request(data)`\nSend a JSON-RPC request and wait for response.\n\n```python\nresult = await eywa.send_request({\n    \"method\": \"custom.method\",\n    \"params\": {\"foo\": \"bar\"}\n})\n```\n\n#### `send_notification(data)`\nSend a JSON-RPC notification without expecting a response.\n\n```python\neywa.send_notification({\n    \"method\": \"custom.event\",\n    \"params\": {\"status\": \"ready\"}\n})\n```\n\n#### `register_handler(method, func)`\nRegister a handler for incoming JSON-RPC method calls.\n\n```python\ndef handle_ping(data):\n    print(f\"Received ping: {data['params']}\")\n    eywa.send_notification({\n        \"method\": \"custom.pong\",\n        \"params\": {\"timestamp\": time.time()}\n    })\n\neywa.register_handler(\"custom.ping\", handle_ping)\n```\n\n## Data Structures\n\n### Sheet Class\nFor creating structured tabular data:\n\n```python\nsheet = eywa.Sheet(\"UserReport\")\nsheet.set_columns([\"Name\", \"Email\", \"Status\"])\nsheet.add_row({\"Name\": \"John\", \"Email\": \"john@example.com\", \"Status\": \"Active\"})\nsheet.add_row({\"Name\": \"Jane\", \"Email\": \"jane@example.com\", \"Status\": \"Active\"})\n```\n\n### Table Class\nFor creating multi-sheet reports:\n\n```python\ntable = eywa.Table(\"MonthlyReport\")\ntable.add_sheet(users_sheet)\ntable.add_sheet(stats_sheet)\n\n# Convert to JSON for reporting\neywa.report(\"Monthly report\", {\"table\": json.loads(table.toJSON())})\n```\n\n## Constants\n\n- `SUCCESS` - Task completed successfully\n- `ERROR` - Task failed with error\n- `PROCESSING` - Task is currently processing\n- `EXCEPTION` - Task failed with exception\n\n## Complete Example\n\n```python\nimport asyncio\nimport eywa\nimport traceback\n\nasync def process_data():\n    # Initialize\n    eywa.open_pipe()\n    \n    try:\n        # Get task info\n        task = await eywa.get_task()\n        eywa.info(\"Starting task\", {\"taskId\": task[\"euuid\"]})\n        \n        # Update status\n        eywa.update_task(eywa.PROCESSING)\n        \n        # Query data with GraphQL\n        result = await eywa.graphql(\"\"\"\n            query GetActiveUsers {\n                searchUser(_where: {active: {_eq: true}}) {\n                    euuid\n                    name\n                    email\n                }\n            }\n        \"\"\")\n        \n        users = result[\"data\"][\"searchUser\"]\n        \n        # Create report\n        sheet = eywa.Sheet(\"ActiveUsers\")\n        sheet.set_columns([\"ID\", \"Name\", \"Email\"])\n        \n        for user in users:\n            eywa.debug(\"Processing user\", {\"userId\": user[\"euuid\"]})\n            sheet.add_row({\n                \"ID\": user[\"euuid\"],\n                \"Name\": user[\"name\"],\n                \"Email\": user.get(\"email\", \"N/A\")\n            })\n        \n        # Report results\n        eywa.report(\"Found active users\", {\n            \"count\": len(users),\n            \"sheet\": sheet.__dict__\n        })\n        \n        # Success!\n        eywa.info(\"Task completed\")\n        eywa.close_task(eywa.SUCCESS)\n        \n    except Exception as e:\n        eywa.error(\"Task failed\", {\n            \"error\": str(e),\n            \"traceback\": traceback.format_exc()\n        })\n        eywa.close_task(eywa.ERROR)\n\nif __name__ == \"__main__\":\n    asyncio.run(process_data())\n```\n\n## Type Hints\n\nThe library includes comprehensive type hints via `.pyi` file:\n\n```python\nfrom typing import Dict, Any, Optional\nimport eywa\n\nasync def process() -> None:\n    task: Dict[str, Any] = await eywa.get_task()\n    result: Dict[str, Any] = await eywa.graphql(\n        \"query { searchUser { name } }\", \n        variables={\"limit\": 10}\n    )\n```\n\n## Error Handling\n\nThe client includes custom exception handling:\n\n```python\ntry:\n    result = await eywa.graphql(\"{ invalid }\")\nexcept eywa.JSONRPCException as e:\n    eywa.error(f\"GraphQL failed: {e.message}\", {\"error\": e.data})\n```\n\n## Testing\n\nTest your robot locally using the EYWA CLI:\n\n```bash\neywa run -c 'python my_robot.py'\n```\n\n## Examples\n\nTo run examples, position terminal to root project folder and run:\n\n```bash\n# Test all features\npython -m examples.test_eywa_client\n\n# Run a simple GraphQL query\npython -m examples.raw_graphql\n\n# WebDriver example\npython -m examples.webdriver\n```\n\n## Requirements\n\n- Python 3.7+\n- No external dependencies (uses only standard library)\n\n## License\n\nMIT\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## Support\n\nFor issues and questions, please visit the [EYWA repository](https://github.com/neyho/eywa).\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "EYWA client library for Python providing JSON-RPC communication, GraphQL queries, and task management for EYWA robots",
    "version": "0.3.1",
    "project_urls": {
        "Homepage": "https://github.com/neyho/eywa",
        "Issues": "https://github.com/neyho/eywa/issues",
        "Repository": "https://github.com/neyho/eywa.git"
    },
    "split_keywords": [
        "eywa",
        " client",
        " json-rpc",
        " graphql",
        " robotics",
        " automation"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "23cdf4582372a2685b00c95b7d44a7388ed268a0667fa215f4e41a25d0c0ce12",
                "md5": "4840f6c0d7d60206323a6e784db5020e",
                "sha256": "e1ae0dba03d2b99e655deab20079b5f25544dac9b25445d271db2e53c268e3a1"
            },
            "downloads": -1,
            "filename": "eywa_client-0.3.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "4840f6c0d7d60206323a6e784db5020e",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 8512,
            "upload_time": "2025-07-21T08:49:16",
            "upload_time_iso_8601": "2025-07-21T08:49:16.635565Z",
            "url": "https://files.pythonhosted.org/packages/23/cd/f4582372a2685b00c95b7d44a7388ed268a0667fa215f4e41a25d0c0ce12/eywa_client-0.3.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "9abe3b496dc170d2c241dca4d07ea8c0b36a36244d93e77f983d412ddbad9d93",
                "md5": "5fd542b7d55ea55cb43264858cf06392",
                "sha256": "170e2c3e3ced254574275c8f9ea05732eaaa2a494fb38a4d10bcc28f65cb9171"
            },
            "downloads": -1,
            "filename": "eywa_client-0.3.1.tar.gz",
            "has_sig": false,
            "md5_digest": "5fd542b7d55ea55cb43264858cf06392",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 20103,
            "upload_time": "2025-07-21T08:49:18",
            "upload_time_iso_8601": "2025-07-21T08:49:18.395261Z",
            "url": "https://files.pythonhosted.org/packages/9a/be/3b496dc170d2c241dca4d07ea8c0b36a36244d93e77f983d412ddbad9d93/eywa_client-0.3.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-21 08:49:18",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "neyho",
    "github_project": "eywa",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "eywa-client"
}
        
Elapsed time: 0.63808s