kiarina-lib-falkordb 1.0.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.
@@ -0,0 +1,27 @@
1
+ import logging
2
+ from importlib import import_module
3
+ from importlib.metadata import version
4
+ from typing import TYPE_CHECKING
5
+
6
+ if TYPE_CHECKING:
7
+ from ._sync.registry import get_falkordb
8
+ from .settings import settings_manager
9
+
10
+ __version__ = version("kiarina-lib-falkordb")
11
+
12
+ __all__ = ["get_falkordb", "settings_manager"]
13
+
14
+ logging.getLogger(__name__).addHandler(logging.NullHandler())
15
+
16
+
17
+ def __getattr__(name: str) -> object:
18
+ if name not in __all__:
19
+ raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
20
+
21
+ module_map = {
22
+ "get_falkordb": "._sync.registry",
23
+ "settings_manager": ".settings",
24
+ }
25
+
26
+ globals()[name] = getattr(import_module(module_map[name], __name__), name)
27
+ return globals()[name]
File without changes
@@ -0,0 +1,39 @@
1
+ from typing import Any
2
+
3
+ from falkordb.asyncio import FalkorDB # type: ignore
4
+
5
+ from .._core.registry import get_falkordb as _get_falkordb
6
+
7
+
8
+ def get_falkordb(
9
+ config_key: str | None = None,
10
+ *,
11
+ cache_key: str | None = None,
12
+ use_retry: bool | None = None,
13
+ url: str | None = None,
14
+ **kwargs: Any,
15
+ ) -> FalkorDB:
16
+ """
17
+ Get a FalkorDB client (async version - currently uses sync implementation).
18
+
19
+ Note: FalkorDB doesn't have native async support yet, so this currently
20
+ returns the same sync client. This is prepared for future async support.
21
+
22
+ Args:
23
+ config_key (str | None): The configuration key for the FalkorDB client.
24
+ cache_key (str | None): The cache key for the FalkorDB client.
25
+ use_retry (bool | None): Whether to use retry for the FalkorDB client.
26
+ url (str | None): The FalkorDB URL.
27
+ **kwargs: Additional keyword arguments for the FalkorDB client.
28
+
29
+ Returns:
30
+ FalkorDB: The FalkorDB client.
31
+ """
32
+ return _get_falkordb(
33
+ "async",
34
+ config_key,
35
+ cache_key=cache_key,
36
+ use_retry=use_retry,
37
+ url=url,
38
+ **kwargs,
39
+ )
File without changes
@@ -0,0 +1,103 @@
1
+ from typing import Any, Literal, overload
2
+
3
+ import falkordb # type: ignore
4
+ import falkordb.asyncio # type: ignore
5
+ import redis
6
+ import redis.asyncio
7
+ from redis.backoff import ExponentialBackoff
8
+ from redis.retry import Retry
9
+
10
+ from ..settings import settings_manager
11
+
12
+ _sync_cache: dict[str, falkordb.FalkorDB] = {}
13
+ """
14
+ Sync FalkorDB clients cache
15
+ """
16
+
17
+ _async_cache: dict[str, falkordb.asyncio.FalkorDB] = {}
18
+ """
19
+ Async FalkorDB clients cache
20
+ """
21
+
22
+
23
+ @overload
24
+ def get_falkordb(
25
+ mode: Literal["sync"],
26
+ config_key: str | None = None,
27
+ *,
28
+ cache_key: str | None = None,
29
+ use_retry: bool | None = None,
30
+ url: str | None = None,
31
+ **kwargs: Any,
32
+ ) -> falkordb.FalkorDB: ...
33
+
34
+
35
+ @overload
36
+ def get_falkordb(
37
+ mode: Literal["async"],
38
+ config_key: str | None = None,
39
+ *,
40
+ cache_key: str | None = None,
41
+ use_retry: bool | None = None,
42
+ url: str | None = None,
43
+ **kwargs: Any,
44
+ ) -> falkordb.asyncio.FalkorDB: ...
45
+
46
+
47
+ def get_falkordb(
48
+ mode: Literal["sync", "async"],
49
+ config_key: str | None = None,
50
+ *,
51
+ cache_key: str | None = None,
52
+ use_retry: bool | None = None,
53
+ url: str | None = None,
54
+ **kwargs: Any,
55
+ ) -> falkordb.FalkorDB | falkordb.asyncio.FalkorDB:
56
+ """
57
+ Get a FalkorDB client with shared logic.
58
+ """
59
+ settings = settings_manager.get_settings_by_key(config_key)
60
+
61
+ if url is None:
62
+ url = settings.url
63
+
64
+ if use_retry is None:
65
+ use_retry = settings.use_retry
66
+
67
+ params = {**settings.initialize_params, **kwargs}
68
+
69
+ if use_retry:
70
+ params.update(
71
+ {
72
+ "socket_timeout": settings.socket_timeout,
73
+ "socket_connect_timeout": settings.socket_connect_timeout,
74
+ "health_check_interval": settings.health_check_interval,
75
+ "retry": Retry(
76
+ ExponentialBackoff(cap=settings.retry_delay),
77
+ settings.retry_attempts,
78
+ ),
79
+ }
80
+ )
81
+
82
+ if mode == "sync":
83
+ params["retry_on_error"] = [redis.ConnectionError, redis.TimeoutError]
84
+ else:
85
+ params["retry_on_error"] = [
86
+ redis.asyncio.ConnectionError,
87
+ redis.asyncio.TimeoutError,
88
+ ]
89
+
90
+ if cache_key is None:
91
+ cache_key = url
92
+
93
+ if mode == "sync":
94
+ if cache_key not in _sync_cache:
95
+ _sync_cache[cache_key] = falkordb.FalkorDB.from_url(url, **params)
96
+
97
+ return _sync_cache[cache_key]
98
+
99
+ else:
100
+ if cache_key not in _async_cache:
101
+ _async_cache[cache_key] = falkordb.asyncio.FalkorDB.from_url(url, **params)
102
+
103
+ return _async_cache[cache_key]
File without changes
@@ -0,0 +1,36 @@
1
+ from typing import Any
2
+
3
+ from falkordb import FalkorDB # type: ignore
4
+
5
+ from .._core.registry import get_falkordb as _get_falkordb
6
+
7
+
8
+ def get_falkordb(
9
+ config_key: str | None = None,
10
+ *,
11
+ cache_key: str | None = None,
12
+ use_retry: bool | None = None,
13
+ url: str | None = None,
14
+ **kwargs: Any,
15
+ ) -> FalkorDB:
16
+ """
17
+ Get a FalkorDB client.
18
+
19
+ Args:
20
+ config_key (str | None): The configuration key for the FalkorDB client.
21
+ cache_key (str | None): The cache key for the FalkorDB client.
22
+ use_retry (bool | None): Whether to use retry for the FalkorDB client.
23
+ url (str | None): The FalkorDB URL.
24
+ **kwargs: Additional keyword arguments for the FalkorDB client.
25
+
26
+ Returns:
27
+ FalkorDB: The FalkorDB client.
28
+ """
29
+ return _get_falkordb(
30
+ "sync",
31
+ config_key,
32
+ cache_key=cache_key,
33
+ use_retry=use_retry,
34
+ url=url,
35
+ **kwargs,
36
+ )
@@ -0,0 +1,25 @@
1
+ import logging
2
+ from importlib import import_module
3
+ from typing import TYPE_CHECKING
4
+
5
+ if TYPE_CHECKING:
6
+ from ._async.registry import get_falkordb
7
+ from .settings import settings_manager
8
+
9
+ __all__ = ["get_falkordb", "settings_manager"]
10
+
11
+ logging.getLogger(__name__).addHandler(logging.NullHandler())
12
+
13
+
14
+ def __getattr__(name: str) -> object:
15
+ if name not in __all__:
16
+ raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
17
+
18
+ module_map = {
19
+ "get_falkordb": "._async.registry",
20
+ "settings_manager": ".settings",
21
+ }
22
+
23
+ parent = __name__.rsplit(".", 1)[0]
24
+ globals()[name] = getattr(import_module(module_map[name], parent), name)
25
+ return globals()[name]
File without changes
@@ -0,0 +1,70 @@
1
+ from typing import Any
2
+
3
+ from pydantic import Field
4
+ from pydantic_settings import BaseSettings, SettingsConfigDict
5
+ from pydantic_settings_manager import SettingsManager
6
+
7
+
8
+ class FalkorDBSettings(BaseSettings):
9
+ """
10
+ FalkorDB Settings
11
+ """
12
+
13
+ model_config = SettingsConfigDict(env_prefix="KIARINA_LIB_FALKORDB_")
14
+
15
+ url: str = "falkor://localhost:6379"
16
+ """
17
+ FalkorDB URL
18
+
19
+ Example:
20
+ - falkor://[[username]:[password]]@localhost:6379
21
+ - falkors://[[username]:[password]]@localhost:6379
22
+ """
23
+
24
+ initialize_params: dict[str, Any] = Field(default_factory=dict)
25
+ """
26
+ Additional parameters to initialize the FalkorDB client.
27
+ """
28
+
29
+ use_retry: bool = False
30
+ """
31
+ Whether to enable automatic retries
32
+
33
+ When enabled, it is configured to retry upon occurrence of
34
+ redis.ConnectionError or redis.TimeoutError.
35
+ """
36
+
37
+ socket_timeout: float = 6.0
38
+ """
39
+ Socket timeout in seconds
40
+
41
+ After sending a command, if this time is exceeded, a redis.TimeoutError will be raised.
42
+ """
43
+
44
+ socket_connect_timeout: float = 3.0
45
+ """
46
+ Socket connection timeout in seconds
47
+
48
+ If this time is exceeded when establishing a new connection, a redis.ConnectionError will occur.
49
+ """
50
+
51
+ health_check_interval: int = 60
52
+ """
53
+ Health check interval in seconds
54
+
55
+ When acquiring a connection from the pool,
56
+ if the time since last use has elapsed, execute a PING to verify the connection status.
57
+ """
58
+
59
+ retry_attempts: int = 3
60
+ """
61
+ Number of retry attempts
62
+ """
63
+
64
+ retry_delay: float = 1.0
65
+ """
66
+ Delay between retry attempts in seconds
67
+ """
68
+
69
+
70
+ settings_manager = SettingsManager(FalkorDBSettings, multi=True)
@@ -0,0 +1,280 @@
1
+ Metadata-Version: 2.4
2
+ Name: kiarina-lib-falkordb
3
+ Version: 1.0.0
4
+ Summary: FalkorDB client library for kiarina namespace
5
+ Project-URL: Homepage, https://github.com/kiarina/kiarina-python
6
+ Project-URL: Repository, https://github.com/kiarina/kiarina-python
7
+ Project-URL: Issues, https://github.com/kiarina/kiarina-python/issues
8
+ Project-URL: Changelog, https://github.com/kiarina/kiarina-python/blob/main/packages/kiarina-lib-falkordb/CHANGELOG.md
9
+ Project-URL: Documentation, https://github.com/kiarina/kiarina-python/tree/main/packages/kiarina-lib-falkordb#readme
10
+ Author-email: kiarina <kiarinadawa@gmail.com>
11
+ Maintainer-email: kiarina <kiarinadawa@gmail.com>
12
+ License: MIT
13
+ Keywords: client,database,falkordb,graph,pydantic,redis,settings
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Database
22
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
+ Classifier: Typing :: Typed
24
+ Requires-Python: >=3.12
25
+ Requires-Dist: falkordb
26
+ Requires-Dist: pydantic-settings-manager>=2.1.0
27
+ Requires-Dist: pydantic-settings>=2.10.1
28
+ Requires-Dist: redis>=6.4.0
29
+ Description-Content-Type: text/markdown
30
+
31
+ # kiarina-lib-falkordb
32
+
33
+ A Python client library for [FalkorDB](https://falkordb.com/) with configuration management and connection pooling.
34
+
35
+ ## Features
36
+
37
+ - **Configuration Management**: Use `pydantic-settings-manager` for flexible configuration
38
+ - **Connection Pooling**: Automatic connection caching and reuse
39
+ - **Retry Support**: Built-in retry mechanism for connection failures
40
+ - **Sync & Async**: Support for both synchronous and asynchronous operations
41
+ - **Type Safety**: Full type hints and Pydantic validation
42
+
43
+ ## Installation
44
+
45
+ ```bash
46
+ pip install kiarina-lib-falkordb
47
+ ```
48
+
49
+ ## Quick Start
50
+
51
+ ### Basic Usage (Sync)
52
+
53
+ ```python
54
+ from kiarina.lib.falkordb import get_falkordb
55
+
56
+ # Get a FalkorDB client with default settings
57
+ db = get_falkordb()
58
+
59
+ # Select a graph and run a query
60
+ graph = db.select_graph("social")
61
+ result = graph.query("CREATE (p:Person {name: 'Alice', age: 30}) RETURN p")
62
+ print(result.result_set)
63
+ ```
64
+
65
+ ### Async Usage
66
+
67
+ ```python
68
+ from kiarina.lib.falkordb.asyncio import get_falkordb
69
+
70
+ async def main():
71
+ # Get an async FalkorDB client
72
+ db = get_falkordb()
73
+
74
+ # Select a graph and run a query
75
+ graph = db.select_graph("social")
76
+ result = await graph.query("CREATE (p:Person {name: 'Bob', age: 25}) RETURN p")
77
+ print(result.result_set)
78
+ ```
79
+
80
+ ## Configuration
81
+
82
+ This library uses [pydantic-settings-manager](https://github.com/kiarina/pydantic-settings-manager) for flexible configuration management.
83
+
84
+ ### Environment Variables
85
+
86
+ Configure the FalkorDB connection using environment variables:
87
+
88
+ ```bash
89
+ # FalkorDB connection URL
90
+ export KIARINA_LIB_FALKORDB_URL="falkor://localhost:6379"
91
+
92
+ # Enable retry mechanism
93
+ export KIARINA_LIB_FALKORDB_USE_RETRY="true"
94
+
95
+ # Timeout settings
96
+ export KIARINA_LIB_FALKORDB_SOCKET_TIMEOUT="6.0"
97
+ export KIARINA_LIB_FALKORDB_SOCKET_CONNECT_TIMEOUT="3.0"
98
+
99
+ # Retry settings
100
+ export KIARINA_LIB_FALKORDB_RETRY_ATTEMPTS="3"
101
+ export KIARINA_LIB_FALKORDB_RETRY_DELAY="1.0"
102
+ ```
103
+
104
+ ### Programmatic Configuration
105
+
106
+ ```python
107
+ from kiarina.lib.falkordb import settings_manager
108
+
109
+ # Configure for multiple environments
110
+ settings_manager.user_config = {
111
+ "development": {
112
+ "url": "falkor://localhost:6379",
113
+ "use_retry": True,
114
+ "retry_attempts": 3
115
+ },
116
+ "production": {
117
+ "url": "falkor://prod-server:6379",
118
+ "use_retry": True,
119
+ "retry_attempts": 5,
120
+ "socket_timeout": 10.0
121
+ }
122
+ }
123
+
124
+ # Switch to production configuration
125
+ settings_manager.active_key = "production"
126
+ db = get_falkordb()
127
+ ```
128
+
129
+ ### Runtime Overrides
130
+
131
+ ```python
132
+ from kiarina.lib.falkordb import get_falkordb
133
+
134
+ # Override settings at runtime
135
+ db = get_falkordb(
136
+ url="falkor://custom-server:6379",
137
+ use_retry=True
138
+ )
139
+ ```
140
+
141
+ ## Advanced Usage
142
+
143
+ ### Connection Caching
144
+
145
+ ```python
146
+ from kiarina.lib.falkordb import get_falkordb
147
+
148
+ # These will return the same cached connection
149
+ db1 = get_falkordb()
150
+ db2 = get_falkordb()
151
+ assert db1 is db2
152
+
153
+ # Use different cache keys for separate connections
154
+ db3 = get_falkordb(cache_key="secondary")
155
+ assert db1 is not db3
156
+ ```
157
+
158
+ ### Custom Configuration Keys
159
+
160
+ ```python
161
+ from kiarina.lib.falkordb import settings_manager, get_falkordb
162
+
163
+ # Configure multiple named configurations
164
+ settings_manager.user_config = {
165
+ "analytics": {
166
+ "url": "falkor://analytics-db:6379",
167
+ "socket_timeout": 30.0
168
+ },
169
+ "cache": {
170
+ "url": "falkor://cache-db:6379",
171
+ "socket_timeout": 5.0
172
+ }
173
+ }
174
+
175
+ # Use specific configurations
176
+ analytics_db = get_falkordb("analytics")
177
+ cache_db = get_falkordb("cache")
178
+ ```
179
+
180
+ ### Error Handling and Retries
181
+
182
+ ```python
183
+ from kiarina.lib.falkordb import get_falkordb
184
+
185
+ # Enable automatic retries for connection issues
186
+ db = get_falkordb(use_retry=True)
187
+
188
+ try:
189
+ graph = db.select_graph("mydata")
190
+ result = graph.query("MATCH (n) RETURN count(n)")
191
+ except Exception as e:
192
+ print(f"Query failed: {e}")
193
+ ```
194
+
195
+ ## Configuration Reference
196
+
197
+ | Setting | Environment Variable | Default | Description |
198
+ |---------|---------------------|---------|-------------|
199
+ | `url` | `KIARINA_LIB_FALKORDB_URL` | `"falkor://localhost:6379"` | FalkorDB connection URL |
200
+ | `use_retry` | `KIARINA_LIB_FALKORDB_USE_RETRY` | `false` | Enable automatic retries |
201
+ | `socket_timeout` | `KIARINA_LIB_FALKORDB_SOCKET_TIMEOUT` | `6.0` | Socket timeout in seconds |
202
+ | `socket_connect_timeout` | `KIARINA_LIB_FALKORDB_SOCKET_CONNECT_TIMEOUT` | `3.0` | Connection timeout in seconds |
203
+ | `health_check_interval` | `KIARINA_LIB_FALKORDB_HEALTH_CHECK_INTERVAL` | `60` | Health check interval in seconds |
204
+ | `retry_attempts` | `KIARINA_LIB_FALKORDB_RETRY_ATTEMPTS` | `3` | Number of retry attempts |
205
+ | `retry_delay` | `KIARINA_LIB_FALKORDB_RETRY_DELAY` | `1.0` | Delay between retries in seconds |
206
+
207
+ ## URL Formats
208
+
209
+ FalkorDB URLs support the following formats:
210
+
211
+ - `falkor://localhost:6379` - Basic connection
212
+ - `falkor://username:password@localhost:6379` - With authentication
213
+ - `falkors://localhost:6379` - SSL/TLS connection
214
+ - `falkors://username:password@localhost:6379` - SSL/TLS with authentication
215
+
216
+ ## Development
217
+
218
+ ### Prerequisites
219
+
220
+ - Python 3.12+
221
+ - Docker (for running FalkorDB in tests)
222
+
223
+ ### Setup
224
+
225
+ ```bash
226
+ # Clone the repository
227
+ git clone https://github.com/kiarina/kiarina-python.git
228
+ cd kiarina-python
229
+
230
+ # Setup development environment (installs tools, syncs dependencies, downloads test data)
231
+ mise run setup
232
+
233
+ # Start FalkorDB for testing
234
+ docker compose up -d falkordb
235
+ ```
236
+
237
+ ### Running Tests
238
+
239
+ ```bash
240
+ # Run format, lint, type checks and tests
241
+ mise run package kiarina-lib-falkordb
242
+
243
+ # Coverage report
244
+ mise run package:test kiarina-lib-falkordb --coverage
245
+
246
+ # Run specific tests
247
+ uv run --group test pytest packages/kiarina-lib-falkordb/tests/test_sync.py
248
+ uv run --group test pytest packages/kiarina-lib-falkordb/tests/test_async.py
249
+ ```
250
+
251
+ ## Dependencies
252
+
253
+ - [falkordb](https://github.com/kiarina/falkordb-py) - FalkorDB Python client (fork with redis-py 6.x support and async bug fixes)
254
+ - [pydantic-settings](https://docs.pydantic.dev/latest/concepts/pydantic_settings/) - Settings management
255
+ - [pydantic-settings-manager](https://github.com/kiarina/pydantic-settings-manager) - Advanced settings management
256
+ - [redis](https://github.com/redis/redis-py) - Redis client (FalkorDB is Redis-compatible)
257
+
258
+ ### Note on FalkorDB Client
259
+
260
+ This library uses a [fork of the official FalkorDB Python client](https://github.com/kiarina/falkordb-py) instead of the [upstream version](https://github.com/FalkorDB/falkordb-py). The fork includes:
261
+
262
+ - **Redis-py 6.x compatibility**: Support for redis-py 6.4.0+ (upstream only supports 5.x)
263
+ - **Async client bug fixes**: Fixes for issues in the asynchronous client implementation
264
+ - **Enhanced stability**: Additional improvements for production use
265
+
266
+ The fork is based on the upstream `develop` branch and will be synchronized with upstream changes. Once these improvements are merged upstream, this library will migrate back to the official client.
267
+
268
+ ## License
269
+
270
+ This project is licensed under the MIT License - see the [LICENSE](../../LICENSE) file for details.
271
+
272
+ ## Contributing
273
+
274
+ This is a personal project, but contributions are welcome! Please feel free to submit issues or pull requests.
275
+
276
+ ## Related Projects
277
+
278
+ - [kiarina-python](https://github.com/kiarina/kiarina-python) - The main monorepo containing this package
279
+ - [FalkorDB](https://www.falkordb.com/) - The graph database this library connects to
280
+ - [pydantic-settings-manager](https://github.com/kiarina/pydantic-settings-manager) - Configuration management library used by this package
@@ -0,0 +1,13 @@
1
+ kiarina/lib/falkordb/__init__.py,sha256=6R2-ayazk1ijNbsB3U4lpPcp1a_ZgwU92m2vyFDaxBE,752
2
+ kiarina/lib/falkordb/asyncio.py,sha256=XcYevSI3xtwNZzecfcs4foc0_WQU__o_iZasM2z8xo0,706
3
+ kiarina/lib/falkordb/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ kiarina/lib/falkordb/settings.py,sha256=b1ktZqBKF-5cW_vALbhCK2uVIlE8xm4oqDnnjEcnknU,1696
5
+ kiarina/lib/falkordb/_async/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ kiarina/lib/falkordb/_async/registry.py,sha256=VsyriOprYjllNrfZnX0q_uC8OKiZKWvNo4HrcFQo3Xc,1153
7
+ kiarina/lib/falkordb/_core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ kiarina/lib/falkordb/_core/registry.py,sha256=b3ch2JMWLvcyELQQCnOyF28u2ckzKwp5-Y8cTER4Zms,2633
9
+ kiarina/lib/falkordb/_sync/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ kiarina/lib/falkordb/_sync/registry.py,sha256=SEnCMjOaOtu_5rNkv7DKxq4KGGnH3o0xtjbePdVc7s8,937
11
+ kiarina_lib_falkordb-1.0.0.dist-info/METADATA,sha256=xS9OxhdzVQqh9s2iGVbJUswkkXlg7q8PoWy4NQajQVs,8855
12
+ kiarina_lib_falkordb-1.0.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
13
+ kiarina_lib_falkordb-1.0.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.27.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any