falkordb 1.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
falkordb/__init__.py ADDED
@@ -0,0 +1,7 @@
1
+ from .falkordb import FalkorDB
2
+ from .node import Node
3
+ from .edge import Edge
4
+ from .path import Path
5
+ from .graph import Graph
6
+ from .execution_plan import ExecutionPlan, Operation
7
+ from .query_result import QueryResult
@@ -0,0 +1 @@
1
+ from .falkordb import FalkorDB
@@ -0,0 +1,68 @@
1
+ from redis.asyncio.cluster import RedisCluster
2
+ import redis.exceptions as redis_exceptions
3
+ import redis.asyncio as redis
4
+ import redis as sync_redis
5
+ import socket
6
+
7
+
8
+ # detect if a connection is a cluster
9
+ def Is_Cluster(conn: redis.Redis):
10
+
11
+ pool = conn.connection_pool
12
+ kwargs = pool.connection_kwargs.copy()
13
+
14
+ # Check if the connection is using SSL and add it
15
+ # this propery is not kept in the connection_kwargs
16
+ kwargs["ssl"] = pool.connection_class is redis.SSLConnection
17
+
18
+ # Create a synchronous Redis client with the same parameters
19
+ # as the connection pool just to keep Is_Cluster synchronous
20
+ info = sync_redis.Redis(**kwargs).info(section="server")
21
+
22
+ return "redis_mode" in info and info["redis_mode"] == "cluster"
23
+
24
+
25
+ # create a cluster connection from a Redis connection
26
+ def Cluster_Conn(
27
+ conn,
28
+ ssl,
29
+ cluster_error_retry_attempts=3,
30
+ startup_nodes=None,
31
+ require_full_coverage=False,
32
+ reinitialize_steps=5,
33
+ read_from_replicas=False,
34
+ address_remap=None,
35
+ ):
36
+ connection_kwargs = conn.connection_pool.connection_kwargs
37
+ host = connection_kwargs.pop("host")
38
+ port = connection_kwargs.pop("port")
39
+ username = connection_kwargs.pop("username")
40
+ password = connection_kwargs.pop("password")
41
+
42
+ retry = connection_kwargs.pop("retry", None)
43
+ retry_on_error = connection_kwargs.pop(
44
+ "retry_on_error",
45
+ [
46
+ ConnectionRefusedError,
47
+ ConnectionError,
48
+ TimeoutError,
49
+ socket.timeout,
50
+ redis_exceptions.ConnectionError,
51
+ ],
52
+ )
53
+ return RedisCluster(
54
+ host=host,
55
+ port=port,
56
+ username=username,
57
+ password=password,
58
+ decode_responses=True,
59
+ ssl=ssl,
60
+ retry=retry,
61
+ retry_on_error=retry_on_error,
62
+ require_full_coverage=require_full_coverage,
63
+ reinitialize_steps=reinitialize_steps,
64
+ read_from_replicas=read_from_replicas,
65
+ address_remap=address_remap,
66
+ startup_nodes=startup_nodes,
67
+ cluster_error_retry_attempts=cluster_error_retry_attempts,
68
+ )
@@ -0,0 +1,201 @@
1
+ import redis.asyncio as redis
2
+ from .cluster import *
3
+ from .graph import AsyncGraph
4
+ from typing import List, Union
5
+
6
+ # config command
7
+ LIST_CMD = "GRAPH.LIST"
8
+ CONFIG_CMD = "GRAPH.CONFIG"
9
+
10
+ class FalkorDB():
11
+ """
12
+ Asynchronous FalkorDB Class for interacting with a FalkorDB server.
13
+
14
+ Usage example::
15
+ from falkordb.asyncio import FalkorDB
16
+ # connect to the database and select the 'social' graph
17
+ db = FalkorDB()
18
+ graph = db.select_graph("social")
19
+
20
+ # get a single 'Person' node from the graph and print its name
21
+ response = await graph.query("MATCH (n:Person) RETURN n LIMIT 1")
22
+ result = response.result_set
23
+ person = result[0][0]
24
+ print(node.properties['name'])
25
+ """
26
+
27
+ def __init__(
28
+ self,
29
+ host='localhost',
30
+ port=6379,
31
+ password=None,
32
+ socket_timeout=None,
33
+ socket_connect_timeout=None,
34
+ socket_keepalive=None,
35
+ socket_keepalive_options=None,
36
+ connection_pool=None,
37
+ unix_socket_path=None,
38
+ encoding='utf-8',
39
+ encoding_errors='strict',
40
+ retry_on_timeout=False,
41
+ retry_on_error=None,
42
+ ssl=False,
43
+ ssl_keyfile=None,
44
+ ssl_certfile=None,
45
+ ssl_cert_reqs='required',
46
+ ssl_ca_certs=None,
47
+ ssl_ca_data=None,
48
+ ssl_check_hostname=False,
49
+ max_connections=None,
50
+ single_connection_client=False,
51
+ health_check_interval=0,
52
+ client_name=None,
53
+ lib_name='FalkorDB',
54
+ lib_version='1.0.0',
55
+ username=None,
56
+ retry=None,
57
+ connect_func=None,
58
+ credential_provider=None,
59
+ protocol=2,
60
+ # FalkorDB Cluster Params
61
+ cluster_error_retry_attempts=3,
62
+ startup_nodes=None,
63
+ require_full_coverage=False,
64
+ reinitialize_steps=5,
65
+ read_from_replicas=False,
66
+ address_remap=None,
67
+ ):
68
+
69
+ conn = redis.Redis(host=host, port=port, db=0, password=password,
70
+ socket_timeout=socket_timeout,
71
+ socket_connect_timeout=socket_connect_timeout,
72
+ socket_keepalive=socket_keepalive,
73
+ socket_keepalive_options=socket_keepalive_options,
74
+ connection_pool=connection_pool,
75
+ unix_socket_path=unix_socket_path,
76
+ encoding=encoding, encoding_errors=encoding_errors,
77
+ decode_responses=True,
78
+ retry_on_timeout=retry_on_timeout,
79
+ retry_on_error=retry_on_error, ssl=ssl,
80
+ ssl_keyfile=ssl_keyfile, ssl_certfile=ssl_certfile,
81
+ ssl_cert_reqs=ssl_cert_reqs,
82
+ ssl_ca_certs=ssl_ca_certs,
83
+ ssl_ca_data=ssl_ca_data,
84
+ ssl_check_hostname=ssl_check_hostname,
85
+ max_connections=max_connections,
86
+ single_connection_client=single_connection_client,
87
+ health_check_interval=health_check_interval,
88
+ client_name=client_name, lib_name=lib_name,
89
+ lib_version=lib_version, username=username,
90
+ retry=retry, redis_connect_func=connect_func,
91
+ credential_provider=credential_provider,
92
+ protocol=protocol)
93
+
94
+ if Is_Cluster(conn):
95
+ conn = Cluster_Conn(
96
+ conn,
97
+ ssl,
98
+ cluster_error_retry_attempts,
99
+ startup_nodes,
100
+ require_full_coverage,
101
+ reinitialize_steps,
102
+ read_from_replicas,
103
+ address_remap,
104
+ )
105
+
106
+ self.connection = conn
107
+ self.flushdb = conn.flushdb
108
+ self.execute_command = conn.execute_command
109
+
110
+ @classmethod
111
+ def from_url(cls, url: str, **kwargs) -> "FalkorDB":
112
+ """
113
+ Creates a new FalkorDB instance from a URL.
114
+
115
+ Args:
116
+ cls: The class itself.
117
+ url (str): The URL.
118
+ kwargs: Additional keyword arguments to pass to the ``DB.from_url`` function.
119
+
120
+ Returns:
121
+ DB: A new DB instance.
122
+
123
+ Usage example::
124
+ db = FalkorDB.from_url("falkor://[[username]:[password]]@localhost:6379")
125
+ db = FalkorDB.from_url("falkors://[[username]:[password]]@localhost:6379")
126
+ db = FalkorDB.from_url("unix://[username@]/path/to/socket.sock?db=0[&password=password]")
127
+ """
128
+
129
+ db = cls()
130
+
131
+ # switch from redis:// to falkordb://
132
+ if url.startswith('falkor://'):
133
+ url = 'redis://' + url[len('falkor://'):]
134
+ elif url.startswith('falkors://'):
135
+ url = 'rediss://' + url[len('falkors://'):]
136
+
137
+ conn = redis.from_url(url, **kwargs)
138
+ db.connection = conn
139
+ db.flushdb = conn.flushdb
140
+ db.execute_command = conn.execute_command
141
+
142
+ return db
143
+
144
+ def select_graph(self, graph_id: str) -> AsyncGraph:
145
+ """
146
+ Selects a graph by creating a new Graph instance.
147
+
148
+ Args:
149
+ graph_id (str): The identifier of the graph.
150
+
151
+ Returns:
152
+ AsyncGraph: A new Graph instance associated with the selected graph.
153
+ """
154
+ if not isinstance(graph_id, str) or graph_id == "":
155
+ raise TypeError(f"Expected a string parameter, but received {type(graph_id)}.")
156
+
157
+ return AsyncGraph(self, graph_id)
158
+
159
+ async def list_graphs(self) -> List[str]:
160
+ """
161
+ Lists all graph names.
162
+ See: https://docs.falkordb.com/commands/graph.list.html
163
+
164
+ Returns:
165
+ List: List of graph names.
166
+
167
+ """
168
+
169
+ return await self.connection.execute_command(LIST_CMD)
170
+
171
+ async def config_get(self, name: str) -> Union[int, str]:
172
+ """
173
+ Retrieve a DB level configuration.
174
+ For a list of available configurations see: https://docs.falkordb.com/configuration.html#falkordb-configuration-parameters
175
+
176
+ Args:
177
+ name (str): The name of the configuration.
178
+
179
+ Returns:
180
+ int or str: The configuration value.
181
+
182
+ """
183
+
184
+ res = await self.connection.execute_command(CONFIG_CMD, "GET", name)
185
+ return res[1]
186
+
187
+ async def config_set(self, name: str, value=None) -> None:
188
+ """
189
+ Update a DB level configuration.
190
+ For a list of available configurations see: https://docs.falkordb.com/configuration.html#falkordb-configuration-parameters
191
+
192
+ Args:
193
+ name (str): The name of the configuration.
194
+ value: The value to set.
195
+
196
+ Returns:
197
+ None
198
+
199
+ """
200
+
201
+ return await self.connection.execute_command(CONFIG_CMD, "SET", name, value)