Skip to content

Commit e180891

Browse files
committed
(docs) update comments, readme, add examples
1 parent 8c5d5d5 commit e180891

File tree

6 files changed

+143
-11
lines changed

6 files changed

+143
-11
lines changed

README.md

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,27 @@
11
# aiocarrot
22

3-
**aiocarrot** is fully asynchronous framework for working with <a href="https://www.rabbitmq.com/">RabbitMQ</a>
3+
**aiocarrot** is a fully asynchronous framework for working with the <a href="https://www.rabbitmq.com/">RabbitMQ</a> message broker
44

5-
Accelerate development with a message broker at times with **aiocarrot**
5+
___
6+
7+
**Source Code: https://github.com/d3nbr0/aiocarrot**
8+
9+
___
10+
11+
The key features are:
12+
13+
* **Completely asynchronous** - aiocarrot has the <a href="https://pypi.org/project/aio-pika/">aiopika</a> library running under the hood
14+
* **Fast to code** - the framework allows you to reduce the amount of code in your project, as well as speed up its development
15+
* **Fields validation** - aiocarrot supports field validation using <a href="https://pypi.org/project/pydantic/">pydantic</a>
16+
17+
## Requirements
18+
19+
The following dependencies are required for **aiocarrot** to work:
20+
21+
* <a href="https://pypi.org/project/aio-pika/">aio-pika</a> for working with RabbitMQ
22+
* <a href="https://pypi.org/project/pydantic/">pydantic</a> for fields validation
23+
* <a href="https://pypi.org/project/ujson/">ujson</a> for sending and receiving messages
24+
* <a href="https://pypi.org/project/loguru/">loguru</a> for logging :)
625

726
## Installation
827

@@ -68,4 +87,6 @@ if __name__ == '__main__':
6887
asyncio.run(main())
6988
```
7089

90+
**You can find more examples <a href="https://github.com/d3nbr0/aiocarrot/tree/main/examples">here</a>**
91+
7192
It's very simple to use. Enjoy!

aiocarrot/__meta__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '1.0.0'
1+
__version__ = '1.0.1'

aiocarrot/carrot.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@ def __init__(self, url: str, queue_name: str) -> None:
3434

3535
async def send(self, _cnm: str, **kwargs) -> 'ConfirmationFrameType':
3636
"""
37-
Send message with specified name
37+
Send a message with the specified type and the specified payload
3838
39-
:param _cnm: Message name
40-
:param kwargs: Message payload
39+
:param _cnm: The name of the message (used to determine the type of message being sent)
40+
:param kwargs: The payload transmitted in the message body
4141
:return:
4242
"""
4343

@@ -69,7 +69,7 @@ def setup_consumer(self, consumer: 'Consumer') -> None:
6969

7070
async def run(self) -> None:
7171
"""
72-
Start carrot listening
72+
Starts the main loop of the Carrot new message listener
7373
7474
:return:
7575
"""
@@ -100,7 +100,7 @@ async def run(self) -> None:
100100

101101
async def _consumer_loop(self) -> None:
102102
"""
103-
Consumer primary loop
103+
The main event loop used by Carrot to receive new messages and pass them on to the handler
104104
105105
:return:
106106
"""
@@ -161,7 +161,7 @@ async def _consumer_loop(self) -> None:
161161

162162
async def _get_queue(self) -> 'aio_pika.abc.AbstractQueue':
163163
"""
164-
Get active broker queue
164+
Retrieves the currently active aiopika queue object
165165
166166
:return: aiopika queue
167167
"""
@@ -174,7 +174,7 @@ async def _get_queue(self) -> 'aio_pika.abc.AbstractQueue':
174174

175175
async def _get_channel(self) -> 'aio_pika.abc.AbstractChannel':
176176
"""
177-
Get active broker channel
177+
Gets the current active object of the aiopika channel
178178
179179
:return: aiopika channel
180180
"""
@@ -187,7 +187,7 @@ async def _get_channel(self) -> 'aio_pika.abc.AbstractChannel':
187187

188188
async def _get_connection(self) -> 'aio_pika.abc.AbstractConnection':
189189
"""
190-
Get active connection to the broker
190+
Retrieves the object of an active connection with the broker using aiopika
191191
192192
:return: aiopika broker connection
193193
"""

examples/01_consumer.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# This is an example of a consumer whose task is to create new users and add points to their balance
2+
#
3+
# In a real project, you can use your own database instead of a dictionary.
4+
# For example, you can use SQLAlchemy ORM to work with SQL databases.
5+
6+
7+
from aiocarrot import Carrot, Consumer
8+
9+
10+
consumer = Consumer()
11+
users: dict[int, int] = {}
12+
13+
14+
@consumer.message(name='register_user')
15+
async def register_user_message(user_id: int) -> None:
16+
"""
17+
Example of a message handler for registering a new user
18+
19+
:param user_id: User identifier (this field is required and must be of the int type)
20+
:return:
21+
"""
22+
23+
if user_id in users:
24+
raise ValueError('This user is already registered')
25+
26+
users[user_id] = 0
27+
28+
29+
@consumer.message(name='add_points')
30+
async def add_points_message(user_id: int, amount: int = None) -> None:
31+
"""
32+
Adds the number of points to the user
33+
34+
:param user_id: User identifier
35+
:param amount: The number of points to be added
36+
:return:
37+
"""
38+
39+
if user_id not in users:
40+
raise ValueError('This user is not registered')
41+
42+
if amount is None:
43+
amount = 100
44+
45+
users[user_id] += amount
46+
47+
48+
async def main() -> None:
49+
""" Entrypoint of example application """
50+
51+
carrot = Carrot(url='amqp://guest:guest@localhost:5672/', queue_name='users')
52+
carrot.setup_consumer(consumer)
53+
54+
await carrot.run()
55+
56+
57+
if __name__ == '__main__':
58+
import asyncio
59+
60+
asyncio.run(main())

examples/02_publisher.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# In this example, we are sending messages so that the code from the first example can process them
2+
3+
from aiocarrot import Carrot
4+
5+
6+
async def main() -> None:
7+
""" Entrypoint of example application """
8+
9+
carrot = Carrot(url='amqp://guest:guest@localhost:5672/', queue_name='users')
10+
11+
await carrot.send('register_user', user_id=1)
12+
await carrot.send('add_points', user_id=1, amount=1000)
13+
await carrot.send('add_points', user_id=1)
14+
15+
# If you look at the example 01_consumer.py then you will see that the amount argument
16+
# is optional and by default the user is awarded 100 points
17+
18+
if __name__ == '__main__':
19+
import asyncio
20+
21+
asyncio.run(main())

examples/03_fastapi.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# This example shows an example of the code for sending data to a queue using FastAPI
2+
3+
4+
from fastapi import FastAPI, Body
5+
from aiocarrot import Carrot
6+
7+
8+
app = FastAPI()
9+
carrot = Carrot(url='amqp://guest:guest@localhost:5672/', queue_name='users')
10+
11+
12+
@app.post('/signup')
13+
async def register_user_view(user_id: int = Body(embed=True)):
14+
""" An example of an API method for creating a new user """
15+
16+
await carrot.send('register_user', user_id=user_id)
17+
18+
return {'status': True}
19+
20+
21+
@app.post('/reward')
22+
async def reward_view(user_id: int = Body(embed=True), amount: int = Body(embed=True)):
23+
"""
24+
An example of an API method for receiving a reward in
25+
the amount of the number of points passed in the request
26+
"""
27+
28+
await carrot.send('add_points', user_id=user_id, amount=amount)
29+
30+
return {'status': True}

0 commit comments

Comments
 (0)