# 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/be/b8/1a3867518608df0e6eccaf1a473a88e5c1fa6a435ec62eededf7189b5b5d/almanet-0.8.1.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.8.1",
"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": "b5257231f15862c0b1ebcbd378a6e6ef3c7cbfde4e4094e40800eddf83c9c8c5",
"md5": "dca4c6b2f1a7fe339315cb6dce909b3b",
"sha256": "5e56103665b892414d56c9d9f95d127018bc2ed855ab2450f3bd6dce48706a29"
},
"downloads": -1,
"filename": "almanet-0.8.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "dca4c6b2f1a7fe339315cb6dce909b3b",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.12",
"size": 17486,
"upload_time": "2024-10-04T16:08:48",
"upload_time_iso_8601": "2024-10-04T16:08:48.945720Z",
"url": "https://files.pythonhosted.org/packages/b5/25/7231f15862c0b1ebcbd378a6e6ef3c7cbfde4e4094e40800eddf83c9c8c5/almanet-0.8.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "beb81a3867518608df0e6eccaf1a473a88e5c1fa6a435ec62eededf7189b5b5d",
"md5": "4096afe55bf70fdb0581c87764fffa12",
"sha256": "9634c54f5fc1adc063550d67ea0b1ca8c0d4b9769c2a0567cec2d7d982a8f4e7"
},
"downloads": -1,
"filename": "almanet-0.8.1.tar.gz",
"has_sig": false,
"md5_digest": "4096afe55bf70fdb0581c87764fffa12",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.12",
"size": 14291,
"upload_time": "2024-10-04T16:08:51",
"upload_time_iso_8601": "2024-10-04T16:08:51.487363Z",
"url": "https://files.pythonhosted.org/packages/be/b8/1a3867518608df0e6eccaf1a473a88e5c1fa6a435ec62eededf7189b5b5d/almanet-0.8.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-10-04 16:08:51",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "aturkenov",
"github_project": "almanet",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "almanet"
}