# almanet
Web Messaging Protocol is an open application level protocol that provides two messaging patterns:
- Routed Remote Procedure Calls (RPC)
- Produce & Consume
[NSQ](https://nsq.io/) is a realtime distributed queue like message broker.
Almanet uses NSQ to exchange messages between different sessions.
## Quick Start
Before install and run NSQD instance [using this instruction](https://nsq.io/overview/quick_start.html).
Then install [`almanet` PyPI package](https://pypi.org/project/almanet/)
```sh
pip install almanet
```
or
```sh
poetry add almanet
```
Create a new file and
```python
import almanet
```
### Create your own Microservice
<details>
<summary>Explanation of the code that defines and runs a simple microservice</summary>
#### Define your instance of microservice
```python
example_service = almanet.new_service(
"localhost:4150",
prepath="net.example"
)
```
_Arguments_:
- the TCP addresses of the NSQ instances
- prepath for the service's procedures, helping in identifying and organizing them
#### Define your custom exception
```python
class denied(almanet.rpc_error):
"""Custom RPC exception"""
```
This custom exception can be raised within procedures to signal specific error conditions to the caller.
#### Define your remote procedure to call
```python
@example_service.procedure
async def greeting(
session: almanet.Almanet,
payload: str,
) -> str:
"""Procedure that returns greeting message"""
if payload == "guest":
raise denied()
return f"Hello, {payload}!"
```
Decorator `@example_service.procedure` registers the `greeting` function as a remote procedure for the `example_service`.
Arguments:
- payload is a data that was passed during invocation.
- session is a joined service, instance of `almanet.Almanet`
It raises the custom denied exception, indicating that this payload is not allowed if `payload` is `"guest"`.
Otherwise, it returns a greeting message.
#### At the end of the file
```python
if __name__ == "__main__":
example_service.serve()
```
Starts the service, making it ready to handle incoming RPC requests.
#### Finally
Run your module using the python command
</details>
### Call your Microservice
<details>
<summary>Explanation of the code for creating a new session, calling a remote procedure, and handling potential exceptions during the invocation.</summary>
#### Create a new session
```python
session = almanet.new_session("localhost:4150")
```
_Arguments_:
- the TCP addresses of the NSQ instances
#### Calling the Remote Procedure
```python
async with session:
result = await session.call("net.example.greeting", "Aidar")
print(result.payload)
```
`async with session` ensures that the session is properly managed and closed after use.
Calls the remote procedure `net.example.greeting` with the payload `"Aidar"`.
Raises `TimeoutError` if procedure not found or request timed out.
`result.payload` contains the result of the procedure execution.
#### Catching remote procedure exceptions
```python
async with session:
try:
await session.call("net.example.greeting", "guest")
except almanet.rpc_error as e:
print("during call net.example.greeting('guest'):", e)
```
The `try` block attempts to call the `net.example.greeting` procedure with the payload `"guest"`.
If an exception occurs during the call, specifically an `almanet.rpc_error`,
it is caught by the `except` block.
#### Finally
Run your module using the python command
</details>
<br />
See the full examples in [`./examples`](/examples) directory.
Raw data
{
"_id": null,
"home_page": "https://github.com/aturkenov/almanet",
"name": "almanet",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.12",
"maintainer_email": null,
"keywords": "Almanet, PubSub, RPC",
"author": "aturkenov",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/9d/5e/5b1e113fbee59ba8c94e6e5b1cfc0f9d14c0fd50653c14f6ed3e71adb73c/almanet-0.7.0.tar.gz",
"platform": null,
"description": "# almanet\n\nWeb Messaging Protocol is an open application level protocol that provides two messaging patterns:\n- Routed Remote Procedure Calls (RPC)\n- Produce & Consume\n\n[NSQ](https://nsq.io/) is a realtime distributed queue like message broker.\n\nAlmanet uses NSQ to exchange messages between different sessions.\n\n## Quick Start\n\nBefore install and run NSQD instance [using this instruction](https://nsq.io/overview/quick_start.html).\n\nThen install [`almanet` PyPI package](https://pypi.org/project/almanet/)\n\n```sh\npip install almanet\n```\n\nor\n\n```sh\npoetry add almanet\n```\n\nCreate a new file and\n\n```python\nimport almanet\n```\n\n### Create your own Microservice\n\n<details>\n<summary>Explanation of the code that defines and runs a simple microservice</summary>\n\n#### Define your instance of microservice\n```python\nexample_service = almanet.new_service(\n \"localhost:4150\",\n prepath=\"net.example\"\n)\n```\n\n_Arguments_:\n- the TCP addresses of the NSQ instances\n- prepath for the service's procedures, helping in identifying and organizing them\n\n#### Define your custom exception\n```python\nclass denied(almanet.rpc_error):\n \"\"\"Custom RPC exception\"\"\"\n```\n\nThis custom exception can be raised within procedures to signal specific error conditions to the caller.\n\n#### Define your remote procedure to call\n```python\n@example_service.procedure\nasync def greeting(\n session: almanet.Almanet,\n payload: str,\n) -> str:\n \"\"\"Procedure that returns greeting message\"\"\"\n if payload == \"guest\":\n raise denied()\n return f\"Hello, {payload}!\"\n```\n\nDecorator `@example_service.procedure` registers the `greeting` function as a remote procedure for the `example_service`.\n\nArguments:\n- payload is a data that was passed during invocation.\n- session is a joined service, instance of `almanet.Almanet`\n\nIt raises the custom denied exception, indicating that this payload is not allowed if `payload` is `\"guest\"`.\nOtherwise, it returns a greeting message.\n\n#### At the end of the file\n```python\nif __name__ == \"__main__\":\n example_service.serve()\n```\n\nStarts the service, making it ready to handle incoming RPC requests.\n\n#### Finally\n\nRun your module using the python command\n</details>\n\n### Call your Microservice\n\n<details>\n<summary>Explanation of the code for creating a new session, calling a remote procedure, and handling potential exceptions during the invocation.</summary>\n\n#### Create a new session\n```python\nsession = almanet.new_session(\"localhost:4150\")\n```\n\n_Arguments_:\n- the TCP addresses of the NSQ instances\n\n#### Calling the Remote Procedure\n```python\nasync with session:\n result = await session.call(\"net.example.greeting\", \"Aidar\")\n print(result.payload)\n```\n\n`async with session` ensures that the session is properly managed and closed after use.\nCalls the remote procedure `net.example.greeting` with the payload `\"Aidar\"`.\nRaises `TimeoutError` if procedure not found or request timed out.\n`result.payload` contains the result of the procedure execution.\n\n#### Catching remote procedure exceptions\n```python\nasync with session:\n try:\n await session.call(\"net.example.greeting\", \"guest\")\n except almanet.rpc_error as e:\n print(\"during call net.example.greeting('guest'):\", e)\n```\n\nThe `try` block attempts to call the `net.example.greeting` procedure with the payload `\"guest\"`.\nIf an exception occurs during the call, specifically an `almanet.rpc_error`,\nit is caught by the `except` block.\n\n#### Finally\n\nRun your module using the python command\n</details>\n\n<br />\n\nSee the full examples in [`./examples`](/examples) directory.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Web Messaging Protocol",
"version": "0.7.0",
"project_urls": {
"Documentation": "https://github.com/aturkenov/almanet",
"Homepage": "https://github.com/aturkenov/almanet",
"Repository": "https://github.com/aturkenov/almanet"
},
"split_keywords": [
"almanet",
" pubsub",
" rpc"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "5e5c066e19ca525722891d8cde955d96e827876c4ffc37ea04b4d22ee099efa0",
"md5": "c68257d1c71f9d6d7319c576604ef71a",
"sha256": "b38cdfaaa2ff55656d61c3cba18d11a79cde9c7c8d9b216a71ec07a96cafeabe"
},
"downloads": -1,
"filename": "almanet-0.7.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "c68257d1c71f9d6d7319c576604ef71a",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.12",
"size": 17257,
"upload_time": "2024-08-21T07:44:36",
"upload_time_iso_8601": "2024-08-21T07:44:36.264970Z",
"url": "https://files.pythonhosted.org/packages/5e/5c/066e19ca525722891d8cde955d96e827876c4ffc37ea04b4d22ee099efa0/almanet-0.7.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "9d5e5b1e113fbee59ba8c94e6e5b1cfc0f9d14c0fd50653c14f6ed3e71adb73c",
"md5": "716d384983e9e462f0de25a8e3a24a0a",
"sha256": "693ad6f292c4642e9cac3ad4796fee8e51b3ff46cd8aae65d8806dfaa4ce338c"
},
"downloads": -1,
"filename": "almanet-0.7.0.tar.gz",
"has_sig": false,
"md5_digest": "716d384983e9e462f0de25a8e3a24a0a",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.12",
"size": 14145,
"upload_time": "2024-08-21T07:44:37",
"upload_time_iso_8601": "2024-08-21T07:44:37.793702Z",
"url": "https://files.pythonhosted.org/packages/9d/5e/5b1e113fbee59ba8c94e6e5b1cfc0f9d14c0fd50653c14f6ed3e71adb73c/almanet-0.7.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-08-21 07:44:37",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "aturkenov",
"github_project": "almanet",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "almanet"
}