memorygraphMCP 0.11.7__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.
Files changed (65) hide show
  1. memorygraph/__init__.py +50 -0
  2. memorygraph/__main__.py +12 -0
  3. memorygraph/advanced_tools.py +509 -0
  4. memorygraph/analytics/__init__.py +46 -0
  5. memorygraph/analytics/advanced_queries.py +727 -0
  6. memorygraph/backends/__init__.py +21 -0
  7. memorygraph/backends/base.py +179 -0
  8. memorygraph/backends/cloud.py +75 -0
  9. memorygraph/backends/cloud_backend.py +858 -0
  10. memorygraph/backends/factory.py +577 -0
  11. memorygraph/backends/falkordb_backend.py +749 -0
  12. memorygraph/backends/falkordblite_backend.py +746 -0
  13. memorygraph/backends/ladybugdb_backend.py +242 -0
  14. memorygraph/backends/memgraph_backend.py +327 -0
  15. memorygraph/backends/neo4j_backend.py +298 -0
  16. memorygraph/backends/sqlite_fallback.py +463 -0
  17. memorygraph/backends/turso.py +448 -0
  18. memorygraph/cli.py +743 -0
  19. memorygraph/cloud_database.py +297 -0
  20. memorygraph/config.py +295 -0
  21. memorygraph/database.py +933 -0
  22. memorygraph/graph_analytics.py +631 -0
  23. memorygraph/integration/__init__.py +69 -0
  24. memorygraph/integration/context_capture.py +426 -0
  25. memorygraph/integration/project_analysis.py +583 -0
  26. memorygraph/integration/workflow_tracking.py +492 -0
  27. memorygraph/intelligence/__init__.py +59 -0
  28. memorygraph/intelligence/context_retrieval.py +447 -0
  29. memorygraph/intelligence/entity_extraction.py +386 -0
  30. memorygraph/intelligence/pattern_recognition.py +420 -0
  31. memorygraph/intelligence/temporal.py +374 -0
  32. memorygraph/migration/__init__.py +27 -0
  33. memorygraph/migration/manager.py +579 -0
  34. memorygraph/migration/models.py +142 -0
  35. memorygraph/migration/scripts/__init__.py +17 -0
  36. memorygraph/migration/scripts/bitemporal_migration.py +595 -0
  37. memorygraph/migration/scripts/multitenancy_migration.py +452 -0
  38. memorygraph/migration_tools_module.py +146 -0
  39. memorygraph/models.py +684 -0
  40. memorygraph/proactive/__init__.py +46 -0
  41. memorygraph/proactive/outcome_learning.py +444 -0
  42. memorygraph/proactive/predictive.py +410 -0
  43. memorygraph/proactive/session_briefing.py +399 -0
  44. memorygraph/relationships.py +668 -0
  45. memorygraph/server.py +883 -0
  46. memorygraph/sqlite_database.py +1876 -0
  47. memorygraph/tools/__init__.py +59 -0
  48. memorygraph/tools/activity_tools.py +262 -0
  49. memorygraph/tools/memory_tools.py +315 -0
  50. memorygraph/tools/migration_tools.py +181 -0
  51. memorygraph/tools/relationship_tools.py +147 -0
  52. memorygraph/tools/search_tools.py +406 -0
  53. memorygraph/tools/temporal_tools.py +339 -0
  54. memorygraph/utils/__init__.py +10 -0
  55. memorygraph/utils/context_extractor.py +429 -0
  56. memorygraph/utils/error_handling.py +151 -0
  57. memorygraph/utils/export_import.py +425 -0
  58. memorygraph/utils/graph_algorithms.py +200 -0
  59. memorygraph/utils/pagination.py +149 -0
  60. memorygraph/utils/project_detection.py +133 -0
  61. memorygraphmcp-0.11.7.dist-info/METADATA +970 -0
  62. memorygraphmcp-0.11.7.dist-info/RECORD +65 -0
  63. memorygraphmcp-0.11.7.dist-info/WHEEL +4 -0
  64. memorygraphmcp-0.11.7.dist-info/entry_points.txt +2 -0
  65. memorygraphmcp-0.11.7.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,577 @@
1
+ """
2
+ Backend factory for automatic backend selection.
3
+
4
+ This module provides a factory class that automatically selects the best available
5
+ graph database backend based on environment configuration and availability.
6
+ """
7
+
8
+ import logging
9
+ import os
10
+ from typing import Optional
11
+
12
+ from .base import GraphBackend
13
+ from ..models import DatabaseConnectionError
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+
18
+ class BackendFactory:
19
+ """
20
+ Factory class for creating and selecting graph database backends.
21
+
22
+ Default: SQLite (zero-config)
23
+
24
+ Selection priority:
25
+ 1. If MEMORY_BACKEND env var is set, use that specific backend
26
+ 2. Default to SQLite for frictionless installation
27
+ 3. "auto" mode tries: Neo4j → Memgraph → SQLite
28
+ """
29
+
30
+ @staticmethod
31
+ async def create_backend() -> GraphBackend:
32
+ """
33
+ Create and connect to the best available backend.
34
+
35
+ Returns:
36
+ Connected GraphBackend instance
37
+
38
+ Raises:
39
+ DatabaseConnectionError: If no backend can be connected
40
+
41
+ Selection logic:
42
+ - Default: SQLite (zero-config, no external dependencies)
43
+ - Explicit: Use MEMORY_BACKEND env var if set (neo4j, memgraph, falkordb, falkordblite, sqlite, ladybugdb, auto)
44
+ - Auto: Try backends in order until one connects successfully
45
+ """
46
+ backend_type = os.getenv("MEMORY_BACKEND", "sqlite").lower()
47
+
48
+ if backend_type == "neo4j":
49
+ logger.info("Explicit backend selection: Neo4j")
50
+ return await BackendFactory._create_neo4j()
51
+
52
+ elif backend_type == "memgraph":
53
+ logger.info("Explicit backend selection: Memgraph")
54
+ return await BackendFactory._create_memgraph()
55
+
56
+ elif backend_type == "falkordb":
57
+ logger.info("Explicit backend selection: FalkorDB")
58
+ return await BackendFactory._create_falkordb()
59
+
60
+ elif backend_type == "falkordblite":
61
+ logger.info("Explicit backend selection: FalkorDBLite")
62
+ return await BackendFactory._create_falkordblite()
63
+
64
+ elif backend_type == "sqlite":
65
+ logger.info("Explicit backend selection: SQLite")
66
+ return await BackendFactory._create_sqlite()
67
+
68
+ elif backend_type == "turso":
69
+ logger.info("Explicit backend selection: Turso")
70
+ return await BackendFactory._create_turso()
71
+
72
+ elif backend_type == "cloud":
73
+ logger.info("Explicit backend selection: Cloud (MemoryGraph Cloud)")
74
+ return await BackendFactory._create_cloud()
75
+
76
+ elif backend_type == "ladybugdb":
77
+ logger.info("Explicit backend selection: LadybugDB")
78
+ return await BackendFactory._create_ladybugdb()
79
+
80
+ elif backend_type == "auto":
81
+ logger.info("Auto-selecting backend...")
82
+ return await BackendFactory._auto_select_backend()
83
+
84
+ else:
85
+ raise DatabaseConnectionError(
86
+ f"Unknown backend type: {backend_type}. "
87
+ f"Valid options: neo4j, memgraph, falkordb, falkordblite, sqlite, turso, ladybugdb, cloud, auto"
88
+ )
89
+
90
+ @staticmethod
91
+ async def _auto_select_backend() -> GraphBackend:
92
+ """
93
+ Automatically select the best available backend.
94
+
95
+ Returns:
96
+ Connected GraphBackend instance
97
+
98
+ Raises:
99
+ DatabaseConnectionError: If no backend can be connected
100
+ """
101
+ # Try Neo4j first (if password is configured)
102
+ neo4j_password = os.getenv("MEMORY_NEO4J_PASSWORD") or os.getenv("NEO4J_PASSWORD")
103
+ if neo4j_password:
104
+ try:
105
+ logger.info("Attempting to connect to Neo4j...")
106
+ backend = await BackendFactory._create_neo4j()
107
+ logger.info("✓ Successfully connected to Neo4j backend")
108
+ return backend
109
+ except DatabaseConnectionError as e:
110
+ logger.warning(f"Neo4j connection failed: {e}")
111
+
112
+ # Try Memgraph (Community Edition typically has no auth)
113
+ memgraph_uri = os.getenv("MEMORY_MEMGRAPH_URI")
114
+ if memgraph_uri:
115
+ try:
116
+ logger.info("Attempting to connect to Memgraph...")
117
+ backend = await BackendFactory._create_memgraph()
118
+ logger.info("✓ Successfully connected to Memgraph backend")
119
+ return backend
120
+ except DatabaseConnectionError as e:
121
+ logger.warning(f"Memgraph connection failed: {e}")
122
+
123
+ # Fall back to SQLite
124
+ try:
125
+ logger.info("Falling back to SQLite backend...")
126
+ backend = await BackendFactory._create_sqlite()
127
+ logger.info("✓ Successfully connected to SQLite backend")
128
+ return backend
129
+ except DatabaseConnectionError as e:
130
+ logger.error(f"SQLite backend failed: {e}")
131
+ raise DatabaseConnectionError(
132
+ "Could not connect to any backend. "
133
+ "Please configure Neo4j, Memgraph, or ensure NetworkX is installed for SQLite fallback."
134
+ )
135
+
136
+ @staticmethod
137
+ async def _create_neo4j() -> GraphBackend:
138
+ """
139
+ Create and connect to Neo4j backend.
140
+
141
+ Returns:
142
+ Connected Neo4jBackend instance
143
+
144
+ Raises:
145
+ DatabaseConnectionError: If connection fails
146
+ """
147
+ # Lazy import - only load neo4j backend when needed
148
+ from .neo4j_backend import Neo4jBackend
149
+
150
+ uri = os.getenv("MEMORY_NEO4J_URI") or os.getenv("NEO4J_URI")
151
+ user = os.getenv("MEMORY_NEO4J_USER") or os.getenv("NEO4J_USER")
152
+ password = os.getenv("MEMORY_NEO4J_PASSWORD") or os.getenv("NEO4J_PASSWORD")
153
+
154
+ if not password:
155
+ raise DatabaseConnectionError(
156
+ "Neo4j password not configured. "
157
+ "Set MEMORY_NEO4J_PASSWORD or NEO4J_PASSWORD environment variable."
158
+ )
159
+
160
+ backend = Neo4jBackend(uri=uri, user=user, password=password)
161
+ await backend.connect()
162
+ return backend
163
+
164
+ @staticmethod
165
+ async def _create_memgraph() -> GraphBackend:
166
+ """
167
+ Create and connect to Memgraph backend.
168
+
169
+ Returns:
170
+ Connected MemgraphBackend instance
171
+
172
+ Raises:
173
+ DatabaseConnectionError: If connection fails
174
+ """
175
+ # Lazy import - only load memgraph backend when needed
176
+ from .memgraph_backend import MemgraphBackend
177
+
178
+ uri = os.getenv("MEMORY_MEMGRAPH_URI")
179
+ user = os.getenv("MEMORY_MEMGRAPH_USER", "")
180
+ password = os.getenv("MEMORY_MEMGRAPH_PASSWORD", "")
181
+
182
+ backend = MemgraphBackend(uri=uri, user=user, password=password)
183
+ await backend.connect()
184
+ return backend
185
+
186
+ @staticmethod
187
+ async def _create_falkordb() -> GraphBackend:
188
+ """
189
+ Create and connect to FalkorDB backend.
190
+
191
+ Returns:
192
+ Connected FalkorDBBackend instance
193
+
194
+ Raises:
195
+ DatabaseConnectionError: If connection fails
196
+ """
197
+ # Lazy import - only load falkordb backend when needed
198
+ from .falkordb_backend import FalkorDBBackend
199
+
200
+ host = os.getenv("MEMORY_FALKORDB_HOST") or os.getenv("FALKORDB_HOST")
201
+ port_str = os.getenv("MEMORY_FALKORDB_PORT") or os.getenv("FALKORDB_PORT")
202
+ port = int(port_str) if port_str else None
203
+ password = os.getenv("MEMORY_FALKORDB_PASSWORD") or os.getenv("FALKORDB_PASSWORD")
204
+
205
+ backend = FalkorDBBackend(host=host, port=port, password=password)
206
+ await backend.connect()
207
+ return backend
208
+
209
+ @staticmethod
210
+ async def _create_falkordblite() -> GraphBackend:
211
+ """
212
+ Create and connect to FalkorDBLite backend.
213
+
214
+ Returns:
215
+ Connected FalkorDBLiteBackend instance
216
+
217
+ Raises:
218
+ DatabaseConnectionError: If connection fails
219
+ """
220
+ # Lazy import - only load falkordblite backend when needed
221
+ from .falkordblite_backend import FalkorDBLiteBackend
222
+
223
+ db_path = os.getenv("MEMORY_FALKORDBLITE_PATH") or os.getenv("FALKORDBLITE_PATH")
224
+
225
+ backend = FalkorDBLiteBackend(db_path=db_path)
226
+ await backend.connect()
227
+ return backend
228
+
229
+ @staticmethod
230
+ async def _create_ladybugdb() -> GraphBackend:
231
+ """
232
+ Create and connect to LadybugDB backend.
233
+
234
+ Returns:
235
+ Connected LadybugDBBackend instance
236
+
237
+ Raises:
238
+ DatabaseConnectionError: If connection fails
239
+ """
240
+ # Lazy import - only load ladybugdb backend when needed
241
+ from .ladybugdb_backend import LadybugDBBackend
242
+
243
+ db_path = os.getenv("MEMORY_LADYBUGDB_PATH") or os.getenv("LADYBUGDB_PATH")
244
+
245
+ backend = LadybugDBBackend(db_path=db_path)
246
+ await backend.connect()
247
+ return backend
248
+
249
+ @staticmethod
250
+ async def _create_sqlite() -> GraphBackend:
251
+ """
252
+ Create and connect to SQLite fallback backend.
253
+
254
+ Returns:
255
+ Connected SQLiteFallbackBackend instance
256
+
257
+ Raises:
258
+ DatabaseConnectionError: If connection fails
259
+ """
260
+ # Lazy import - only load sqlite backend when needed
261
+ from .sqlite_fallback import SQLiteFallbackBackend
262
+
263
+ db_path = os.getenv("MEMORY_SQLITE_PATH")
264
+ backend = SQLiteFallbackBackend(db_path=db_path)
265
+ await backend.connect()
266
+ await backend.initialize_schema()
267
+ return backend
268
+
269
+ @staticmethod
270
+ async def _create_turso() -> GraphBackend:
271
+ """
272
+ Create and connect to Turso backend.
273
+
274
+ Returns:
275
+ Connected TursoBackend instance
276
+
277
+ Raises:
278
+ DatabaseConnectionError: If connection fails
279
+ """
280
+ # Lazy import - only load turso backend when needed
281
+ from .turso import TursoBackend
282
+
283
+ db_path = os.getenv("MEMORY_TURSO_PATH")
284
+ sync_url = os.getenv("TURSO_DATABASE_URL") or os.getenv("MEMORYGRAPH_TURSO_URL")
285
+ auth_token = os.getenv("TURSO_AUTH_TOKEN") or os.getenv("MEMORYGRAPH_TURSO_TOKEN")
286
+
287
+ backend = TursoBackend(
288
+ db_path=db_path,
289
+ sync_url=sync_url,
290
+ auth_token=auth_token
291
+ )
292
+ await backend.connect()
293
+ await backend.initialize_schema()
294
+ return backend
295
+
296
+ @staticmethod
297
+ async def _create_cloud() -> GraphBackend:
298
+ """
299
+ Create and connect to MemoryGraph Cloud backend.
300
+
301
+ Returns:
302
+ Connected CloudBackend instance
303
+
304
+ Raises:
305
+ DatabaseConnectionError: If connection fails or API key not configured
306
+ """
307
+ # Lazy import - only load cloud backend when needed
308
+ from .cloud_backend import CloudBackend
309
+
310
+ api_key = os.getenv("MEMORYGRAPH_API_KEY")
311
+ api_url = os.getenv("MEMORYGRAPH_API_URL")
312
+ timeout_str = os.getenv("MEMORYGRAPH_TIMEOUT")
313
+ timeout = int(timeout_str) if timeout_str else None
314
+
315
+ if not api_key:
316
+ raise DatabaseConnectionError(
317
+ "MEMORYGRAPH_API_KEY is required for cloud backend. "
318
+ "Get your API key at https://app.memorygraph.dev"
319
+ )
320
+
321
+ backend = CloudBackend(
322
+ api_key=api_key,
323
+ api_url=api_url,
324
+ timeout=timeout
325
+ )
326
+ await backend.connect()
327
+ return backend
328
+
329
+ @staticmethod
330
+ async def create_from_config(config: 'BackendConfig') -> GraphBackend:
331
+ """
332
+ Create backend from explicit configuration without using environment variables.
333
+
334
+ This is a thread-safe alternative to create_backend() that doesn't mutate
335
+ global environment variables.
336
+
337
+ Args:
338
+ config: BackendConfig with backend type and connection details
339
+
340
+ Returns:
341
+ Connected GraphBackend instance
342
+
343
+ Raises:
344
+ DatabaseConnectionError: If backend creation or connection fails
345
+
346
+ Example:
347
+ config = BackendConfig(
348
+ backend_type=BackendType.SQLITE,
349
+ path="/path/to/db.sqlite"
350
+ )
351
+ backend = await BackendFactory.create_from_config(config)
352
+ """
353
+ from ..migration.models import BackendConfig # Import here to avoid circular dependency
354
+
355
+ backend_type = config.backend_type.value
356
+
357
+ try:
358
+ if backend_type == "sqlite":
359
+ return await BackendFactory._create_sqlite_with_path(config.path)
360
+
361
+ elif backend_type == "falkordblite":
362
+ return await BackendFactory._create_falkordblite_with_path(config.path)
363
+
364
+ elif backend_type == "ladybugdb":
365
+ return await BackendFactory._create_ladybugdb_with_path(config.path)
366
+
367
+ elif backend_type == "neo4j":
368
+ return await BackendFactory._create_neo4j_with_config(
369
+ uri=config.uri,
370
+ user=config.username,
371
+ password=config.password
372
+ )
373
+
374
+ elif backend_type == "memgraph":
375
+ return await BackendFactory._create_memgraph_with_config(
376
+ uri=config.uri,
377
+ user=config.username or "",
378
+ password=config.password or ""
379
+ )
380
+
381
+ elif backend_type == "falkordb":
382
+ # Parse host and port from URI (format: redis://host:port)
383
+ import re
384
+ if config.uri:
385
+ match = re.match(r'redis://([^:]+):(\d+)', config.uri)
386
+ if match:
387
+ host, port_str = match.groups()
388
+ port = int(port_str)
389
+ else:
390
+ raise DatabaseConnectionError(f"Invalid FalkorDB URI format: {config.uri}")
391
+ else:
392
+ raise DatabaseConnectionError("FalkorDB requires URI")
393
+
394
+ return await BackendFactory._create_falkordb_with_config(
395
+ host=host,
396
+ port=port,
397
+ password=config.password
398
+ )
399
+
400
+ elif backend_type == "turso":
401
+ return await BackendFactory._create_turso_with_config(
402
+ db_path=config.path,
403
+ sync_url=config.uri,
404
+ auth_token=config.password
405
+ )
406
+
407
+ elif backend_type == "cloud":
408
+ return await BackendFactory._create_cloud_with_config(
409
+ api_key=config.password, # Use password field for API key
410
+ api_url=config.uri
411
+ )
412
+
413
+ else:
414
+ raise DatabaseConnectionError(
415
+ f"Unknown backend type: {backend_type}. "
416
+ f"Valid options: neo4j, memgraph, falkordb, falkordblite, sqlite, turso, cloud"
417
+ )
418
+
419
+ except Exception as e:
420
+ logger.error(f"Failed to create backend from config: {e}")
421
+ raise DatabaseConnectionError(f"Failed to create backend: {e}")
422
+
423
+ @staticmethod
424
+ async def _create_sqlite_with_path(db_path: Optional[str] = None) -> GraphBackend:
425
+ """Create SQLite backend with explicit path (thread-safe)."""
426
+ from .sqlite_fallback import SQLiteFallbackBackend
427
+
428
+ backend = SQLiteFallbackBackend(db_path=db_path)
429
+ await backend.connect()
430
+ await backend.initialize_schema()
431
+ return backend
432
+
433
+ @staticmethod
434
+ async def _create_falkordblite_with_path(db_path: Optional[str] = None) -> GraphBackend:
435
+ """Create FalkorDBLite backend with explicit path (thread-safe)."""
436
+ from .falkordblite_backend import FalkorDBLiteBackend
437
+
438
+ backend = FalkorDBLiteBackend(db_path=db_path)
439
+ await backend.connect()
440
+ return backend
441
+
442
+ @staticmethod
443
+ async def _create_ladybugdb_with_path(db_path: Optional[str] = None) -> GraphBackend:
444
+ """Create LadybugDB backend with explicit path (thread-safe)."""
445
+ from .ladybugdb_backend import LadybugDBBackend
446
+
447
+ backend = LadybugDBBackend(db_path=db_path)
448
+ await backend.connect()
449
+ return backend
450
+
451
+ @staticmethod
452
+ async def _create_neo4j_with_config(
453
+ uri: Optional[str] = None,
454
+ user: Optional[str] = None,
455
+ password: Optional[str] = None
456
+ ) -> GraphBackend:
457
+ """Create Neo4j backend with explicit config (thread-safe)."""
458
+ from .neo4j_backend import Neo4jBackend
459
+
460
+ if not password:
461
+ raise DatabaseConnectionError("Neo4j password is required")
462
+
463
+ backend = Neo4jBackend(uri=uri, user=user, password=password)
464
+ await backend.connect()
465
+ return backend
466
+
467
+ @staticmethod
468
+ async def _create_memgraph_with_config(
469
+ uri: Optional[str] = None,
470
+ user: str = "",
471
+ password: str = ""
472
+ ) -> GraphBackend:
473
+ """Create Memgraph backend with explicit config (thread-safe)."""
474
+ from .memgraph_backend import MemgraphBackend
475
+
476
+ backend = MemgraphBackend(uri=uri, user=user, password=password)
477
+ await backend.connect()
478
+ return backend
479
+
480
+ @staticmethod
481
+ async def _create_falkordb_with_config(
482
+ host: Optional[str] = None,
483
+ port: Optional[int] = None,
484
+ password: Optional[str] = None
485
+ ) -> GraphBackend:
486
+ """Create FalkorDB backend with explicit config (thread-safe)."""
487
+ from .falkordb_backend import FalkorDBBackend
488
+
489
+ backend = FalkorDBBackend(host=host, port=port, password=password)
490
+ await backend.connect()
491
+ return backend
492
+
493
+ @staticmethod
494
+ async def _create_turso_with_config(
495
+ db_path: Optional[str] = None,
496
+ sync_url: Optional[str] = None,
497
+ auth_token: Optional[str] = None
498
+ ) -> GraphBackend:
499
+ """Create Turso backend with explicit config (thread-safe)."""
500
+ from .turso import TursoBackend
501
+
502
+ backend = TursoBackend(
503
+ db_path=db_path,
504
+ sync_url=sync_url,
505
+ auth_token=auth_token
506
+ )
507
+ await backend.connect()
508
+ await backend.initialize_schema()
509
+ return backend
510
+
511
+ @staticmethod
512
+ async def _create_cloud_with_config(
513
+ api_key: Optional[str] = None,
514
+ api_url: Optional[str] = None,
515
+ timeout: Optional[int] = None
516
+ ) -> GraphBackend:
517
+ """Create Cloud backend with explicit config (thread-safe)."""
518
+ from .cloud_backend import CloudBackend
519
+
520
+ if not api_key:
521
+ raise DatabaseConnectionError("MEMORYGRAPH_API_KEY is required for cloud backend")
522
+
523
+ backend = CloudBackend(
524
+ api_key=api_key,
525
+ api_url=api_url,
526
+ timeout=timeout
527
+ )
528
+ await backend.connect()
529
+ return backend
530
+
531
+ @staticmethod
532
+ def get_configured_backend_type() -> str:
533
+ """
534
+ Get the configured backend type without connecting.
535
+
536
+ Returns:
537
+ Backend type string: "neo4j", "memgraph", "sqlite", or "auto"
538
+ """
539
+ return os.getenv("MEMORY_BACKEND", "auto").lower()
540
+
541
+ @staticmethod
542
+ def is_backend_configured(backend_type: str) -> bool:
543
+ """
544
+ Check if a specific backend is configured via environment variables.
545
+
546
+ Args:
547
+ backend_type: Backend type to check ("neo4j", "memgraph", "falkordb", "falkordblite", "sqlite")
548
+
549
+ Returns:
550
+ True if backend appears to be configured
551
+ """
552
+ if backend_type == "neo4j":
553
+ return bool(
554
+ os.getenv("MEMORY_NEO4J_PASSWORD") or
555
+ os.getenv("NEO4J_PASSWORD")
556
+ )
557
+ elif backend_type == "memgraph":
558
+ return bool(os.getenv("MEMORY_MEMGRAPH_URI"))
559
+ elif backend_type == "falkordb":
560
+ return bool(
561
+ os.getenv("MEMORY_FALKORDB_HOST") or
562
+ os.getenv("FALKORDB_HOST")
563
+ )
564
+ elif backend_type == "falkordblite":
565
+ return True # FalkorDBLite is always available (embedded, like SQLite)
566
+ elif backend_type == "sqlite":
567
+ return True # SQLite is always available if NetworkX is installed
568
+ elif backend_type == "turso":
569
+ return bool(
570
+ os.getenv("TURSO_DATABASE_URL") or
571
+ os.getenv("MEMORYGRAPH_TURSO_URL") or
572
+ os.getenv("MEMORY_TURSO_PATH")
573
+ )
574
+ elif backend_type == "cloud":
575
+ return bool(os.getenv("MEMORYGRAPH_API_KEY"))
576
+ else:
577
+ return False