Name | eywa-client JSON |
Version |
0.3.1
JSON |
| download |
home_page | None |
Summary | EYWA client library for Python providing JSON-RPC communication, GraphQL queries, and task management for EYWA robots |
upload_time | 2025-07-21 08:49:18 |
maintainer | None |
docs_url | None |
author | None |
requires_python | >=3.7 |
license | None |
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
[](https://badge.fury.io/py/eywa-client)
[](https://pypi.org/project/eywa-client/)
[](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[](https://badge.fury.io/py/eywa-client)\n[](https://pypi.org/project/eywa-client/)\n[](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"
}