Skip to content

Commit aa28841

Browse files
yuceRob-Hazelcast
andauthored
[HZ-5318] Asyncio docs (hazelcast#770)
Co-authored-by: Rob Swain <[email protected]>
1 parent c89c2f3 commit aa28841

File tree

5 files changed

+337
-21
lines changed

5 files changed

+337
-21
lines changed

docs/copyright.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Copyright
22
=========
33

4-
Copyright (c) 2008-2023, Hazelcast, Inc. All Rights Reserved.
4+
Copyright (c) 2008-2026, Hazelcast, Inc. All Rights Reserved.
55

66
Visit `hazelcast.com <https://hazelcast.com>`__ for more
77
information.

docs/features.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,4 @@ features:
5151
- Global Serialization
5252
- Connection Strategy
5353
- Connection Retry
54+
- Vector Collection (BETA)

docs/getting_started.rst

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@ Hazelcast Python client. It outlines the requirements, installation and
66
configuration of the client, setting up a cluster, and provides a simple
77
application that uses a distributed map in Python client.
88

9+
.. Note:: See :ref:`getting_started_asyncio:getting started - asyncio api (beta)` for getting started with the the asyncio API.
10+
11+
912
Requirements
1013
------------
1114

1215
- Windows, Linux/UNIX or Mac OS X
13-
- Python 3.7 or newer
14-
- Hazelcast 4.0 or newer
15-
- `Supported Java virtual machine <https://docs.hazelcast.com/hazelcast/latest/deploy/versioning-compatibility#supported-java-virtual-machines>`
16+
- Python 3.11 or newer
17+
- Hazelcast 5.0 or newer
18+
- `Supported Java virtual machine <https://docs.hazelcast.com/hazelcast/latest/deploy/versioning-compatibility#supported-java-virtual-machines>`__
1619
- Latest Hazelcast Python client
1720

1821
Working with Hazelcast Clusters
@@ -48,7 +51,7 @@ There are following options to start a Hazelcast cluster easily:
4851

4952
.. code:: bash
5053
51-
docker run -p 5701:5701 hazelcast/hazelcast:5.5.0
54+
docker run -p 5701:5701 hazelcast/hazelcast:latest
5255
5356
- You can use `Hazelcast CLI
5457
<https://docs.hazelcast.com/hazelcast/latest/getting-started/install-hazelcast#use-a-package-manager>`__.
@@ -393,9 +396,9 @@ on a cluster using the client.
393396
client = hazelcast.HazelcastClient()
394397
395398
personnel_map = client.get_map("personnel-map")
396-
personnel_map.put("Alice", "IT")
397-
personnel_map.put("Bob", "IT")
398-
personnel_map.put("Clark", "IT")
399+
personnel_map.put("Alice", "IT").result()
400+
personnel_map.put("Bob", "IT").result()
401+
personnel_map.put("Clark", "IT").result()
399402
400403
print("Added IT personnel. Printing all known personnel")
401404
@@ -425,9 +428,9 @@ Now, run the following code.
425428
client = hazelcast.HazelcastClient()
426429
427430
personnel_map = client.get_map("personnel-map")
428-
personnel_map.put("Denise", "Sales")
429-
personnel_map.put("Erwing", "Sales")
430-
personnel_map.put("Faith", "Sales")
431+
personnel_map.put("Denise", "Sales").result()
432+
personnel_map.put("Erwing", "Sales").result()
433+
personnel_map.put("Faith", "Sales").result()
431434
432435
print("Added Sales personnel. Printing all known personnel")
433436
@@ -461,7 +464,7 @@ our map lives in the cluster and no matter which client we use, we can
461464
access the whole map.
462465

463466
You may wonder why we have used ``result()`` method over the
464-
``entry_set()`` method of the ``personnel_map``. This is because the
467+
``put()`` and ``entry_set()`` methods of the ``personnel_map``. This is because the
465468
Hazelcast Python client is designed to be fully asynchronous. Every
466469
method call over distributed objects such as ``put()``, ``get()``,
467470
``entry_set()``, etc. will return a ``Future`` object that is similar to

docs/getting_started_asyncio.rst

Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
Getting Started - Asyncio API (BETA)
2+
====================================
3+
4+
.. warning::
5+
6+
Hazelcast's asyncio API is BETA. Do not use it in production.
7+
8+
This chapter provides information on how to get started with the Hazelcast Python client using its asyncio API.
9+
It provides the requirements, installation instructions, and a simple application that uses a distributed map in a Python client.
10+
11+
Requirements
12+
------------
13+
14+
- Windows, Linux, macOS
15+
- Python 3.11 or newer
16+
- Hazelcast 5.6 or newer
17+
- `Supported Java virtual machine <https://docs.hazelcast.com/hazelcast/latest/deploy/versioning-compatibility#supported-java-virtual-machines>`__
18+
- Latest Hazelcast Python client
19+
20+
Working with Hazelcast Clusters
21+
-------------------------------
22+
23+
The Hazelcast Python client requires a working Hazelcast cluster to run.
24+
The cluster handles storage and manipulation of user data.
25+
26+
There are several options to run a Hazelcast cluster:
27+
28+
- `Docker <https://docs.hazelcast.com/hazelcast/latest/getting-started/get-started-docker>`__
29+
- `Hazelcast CLI (hz) <https://docs.hazelcast.com/hazelcast/latest/getting-started/get-started-cli>`__
30+
- `Binary <https://docs.hazelcast.com/hazelcast/latest/getting-started/get-started-binary>`__
31+
- `Hazelcast Enterprise <https://docs.hazelcast.com/hazelcast/latest/getting-started/get-started-enterprise>`__
32+
33+
Once the Hazelcast cluster is running, you can carry on with creating and starting the Hazelcast client.
34+
35+
Working with the Hazelcast Client
36+
---------------------------------
37+
38+
Creating and Starting Client
39+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
40+
41+
The asyncio client-specific public API is exposed in the ``hazelcast.asyncio`` package.
42+
Call the ``create_and_start`` method of the ``HazelcastClient`` class to create an instance and connect it to the cluster.
43+
44+
.. code:: python
45+
46+
import asyncio
47+
48+
from hazelcast.asyncio import HazelcastClient
49+
50+
async def amain():
51+
client = await HazelcastClient.create_and_start()
52+
# ... use the client ...
53+
54+
asyncio.run(amain())
55+
56+
The Hazelcast client requires an event loop to be running.
57+
Additionally, any code that uses the ``await`` keyword must be put in an ``async`` function.
58+
59+
Configuring the Client
60+
~~~~~~~~~~~~~~~~~~~~~~
61+
62+
You must pass configuration options as keyword arguments to your client at startup.
63+
64+
This section describes some network options to cover common use cases for connecting the client to a cluster.
65+
See the :ref:`configuration_overview:configuration overview` section for information.
66+
67+
You can omit the keyword arguments to use the default settings:
68+
69+
.. code:: python
70+
71+
client = await HazelcastClient.create_and_start()
72+
73+
Cluster Name Setting
74+
^^^^^^^^^^^^^^^^^^^^
75+
76+
If the cluster was configured with a name other than the default ``dev``, the same name must be used in the client configuration:
77+
78+
.. code:: python
79+
80+
client = await hazelcast.HazelcastClient(
81+
cluster_name="name-of-your-cluster",
82+
)
83+
84+
Network Settings
85+
^^^^^^^^^^^^^^^^
86+
87+
You need to provide the IP address and port of at least one member in
88+
your cluster so the client can find it.
89+
90+
.. code:: python
91+
92+
client = await hazelcast.HazelcastClient.create_and_start(
93+
cluster_members=["some-ip-address:port"]
94+
)
95+
96+
Basic Usage
97+
-----------
98+
99+
Run a simple program to use a distributed map in the Python client:
100+
101+
.. code:: python
102+
103+
import asyncio
104+
import logging
105+
106+
from hazelcast.asyncio import HazelcastClient
107+
108+
# Enable logging to see the logs
109+
logging.basicConfig(level=logging.INFO)
110+
111+
async def amain():
112+
# Connect to Hazelcast cluster
113+
client = await HazelcastClient.create_and_start()
114+
await client.shutdown()
115+
116+
asyncio.run(amain())
117+
118+
This should print logs about the cluster members such as address, port
119+
and UUID to the ``stderr``.
120+
121+
.. code:: text
122+
123+
INFO:hazelcast.lifecycle:HazelcastClient 5.6.0 is STARTING
124+
INFO:hazelcast.lifecycle:HazelcastClient 5.6.0 is STARTED
125+
INFO:hazelcast.internal.asyncio_connection:Trying to connect to Address(host=127.0.0.1, port=5701)
126+
INFO:hazelcast.lifecycle:HazelcastClient 5.6.0 is CONNECTED
127+
INFO:hazelcast.internal.asyncio_connection:Authenticated with server Address(host=127.0.0.1, port=5701):49c5407d-78f4-4611-a025-95f7afd0ab68, server version: 5.5.2, local address: Address(host=127.0.0.1, port=56134)
128+
INFO:hazelcast.internal.asyncio_cluster:
129+
130+
Members [1] {
131+
Member [127.0.0.1]:5701 - 49c5407d-78f4-4611-a025-95f7afd0ab68
132+
}
133+
134+
INFO:hazelcast.internal.asyncio_client:Client started
135+
INFO:hazelcast.lifecycle:HazelcastClient 5.6.0 is SHUTTING_DOWN
136+
INFO:hazelcast.internal.asyncio_connection:Removed connection to Address(host=127.0.0.1, port=5701):49c5407d-78f4-4611-a025-95f7afd0ab68, connection: <hazelcast.internal.asyncio_reactor.AsyncioConnection object at 0x7605c4aa8d70>
137+
INFO:hazelcast.lifecycle:HazelcastClient 5.6.0 is DISCONNECTED
138+
INFO:hazelcast.lifecycle:HazelcastClient 5.6.0 is SHUTDOWN
139+
140+
Congratulations!
141+
You just started a Hazelcast Python client instance.
142+
143+
**Using a Map**
144+
145+
Let's manipulate a distributed map on a cluster using the client.
146+
147+
.. code:: python
148+
149+
import asyncio
150+
151+
from hazelcast.asyncio import HazelcastClient
152+
153+
async def amain():
154+
client = await HazelcastClient.create_and_start()
155+
156+
personnel_map = await client.get_map("personnel-map")
157+
await personnel_map.put("Alice", "IT")
158+
await personnel_map.put("Bob", "IT")
159+
await personnel_map.put("Clark", "IT")
160+
161+
print("Added IT personnel. Printing all known personnel")
162+
163+
entries = await personnel_map.entry_set()
164+
for person, department in entries:
165+
print("%s is in %s department" % (person, department))
166+
167+
await client.shutdown()
168+
169+
asyncio.run(amain())
170+
171+
**Output**
172+
173+
.. code:: text
174+
175+
Added IT personnel. Printing all known personnel
176+
Alice is in IT department
177+
Clark is in IT department
178+
Bob is in IT department
179+
180+
You see this example puts all the IT personnel into a cluster-wide
181+
``personnel-map`` and then prints all the known personnel.
182+
183+
Now, run the following code.
184+
185+
.. code:: python
186+
187+
import asyncio
188+
189+
from hazelcast.asyncio import HazelcastClient
190+
191+
async def amain():
192+
client = await HazelcastClient.create_and_start()
193+
personnel_map = await client.get_map("personnel-map")
194+
await personnel_map.put("Denise", "Sales")
195+
await personnel_map.put("Erwing", "Sales")
196+
await personnel_map.put("Faith", "Sales")
197+
198+
print("Added Sales personnel. Printing all known personnel")
199+
200+
entries = await personnel_map.entry_set()
201+
for person, department in entries:
202+
print("%s is in %s department" % (person, department))
203+
204+
await client.shutdown()
205+
206+
asyncio.run(amain())
207+
208+
**Output**
209+
210+
.. code:: text
211+
212+
Added Sales personnel. Printing all known personnel
213+
Denise is in Sales department
214+
Erwing is in Sales department
215+
Faith is in Sales department
216+
Alice is in IT department
217+
Clark is in IT department
218+
Bob is in IT department
219+
220+
This time you added only the sales employees but you got the list of all known employees including the ones in IT.
221+
That is because the map lives in the cluster and no matter which client you use, you can access the whole map.
222+
223+
Note that the ``await`` keyword causes the ``put`` methods to run serially.
224+
To run them concurrently, you can wrap them in tasks.
225+
Running the tasks in a ``TaskGroup`` makes sure the errors are handled, and all tasks are done:
226+
227+
.. code:: python
228+
229+
import asyncio
230+
231+
from hazelcast.asyncio import HazelcastClient
232+
233+
async def amain():
234+
client = await HazelcastClient.create_and_start()
235+
personnel_map = await client.get_map("personnel-map")
236+
237+
# update the map concurrently
238+
async with asyncio.TaskGroup() as tg:
239+
tg.create_task(personnel_map.put("Denise", "Sales"))
240+
tg.create_task(personnel_map.put("Erwing", "Sales"))
241+
tg.create_task(personnel_map.put("Faith", "Sales"))
242+
243+
# all items are added to the map at this stage
244+
245+
print("Added Sales personnel. Printing all known personnel")
246+
247+
entries = await personnel_map.entry_set()
248+
for person, department in entries:
249+
print("%s is in %s department" % (person, department))
250+
251+
await client.shutdown()
252+
253+
asyncio.run(amain())
254+
255+
Using tasks, method calls over the distributed objects are executed asynchronously without blocking the execution order of your program.
256+
257+
Code Samples
258+
------------
259+
260+
See the Hazelcast Python
261+
`examples <https://github.com/hazelcast/hazelcast-python-client/tree/master/examples/asyncio>`__
262+
for more code samples.

0 commit comments

Comments
 (0)