runic-py 0.4.0__tar.gz → 0.4.2__tar.gz
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.
- {runic_py-0.4.0 → runic_py-0.4.2}/PKG-INFO +59 -7
- {runic_py-0.4.0 → runic_py-0.4.2}/README.md +57 -5
- {runic_py-0.4.0 → runic_py-0.4.2}/packages/runic-rag-docling/pyproject.toml +11 -1
- {runic_py-0.4.0 → runic_py-0.4.2}/pyproject.toml +3 -3
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/config.py +4 -1
- {runic_py-0.4.0 → runic_py-0.4.2}/.gitignore +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/LICENSE.md +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/examples/rag/README.md +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/packages/runic-rag-docling/README.md +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/__init__.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/cypher.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/__init__.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/adapters/__init__.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/adapters/_base.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/adapters/age.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/adapters/arcadedb.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/adapters/falkordb.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/adapters/memgraph.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/adapters/neo4j.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/autogen.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/checksum.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/cli.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/config.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/context.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/exceptions.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/introspect.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/manifest.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/operations.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/schema.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/script.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/service.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/templates/env.py.mako +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/templates/script.py.mako +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/testing.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/migrate/version.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/__init__.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/core/__init__.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/core/descriptors.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/core/metadata.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/core/models.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/core/types.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/driver/__init__.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/driver/age.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/driver/arcadedb.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/driver/bolt.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/driver/factory.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/driver/falkordb.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/driver/memgraph.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/driver/neo4j.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/exceptions.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/mapper/__init__.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/mapper/mapper.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/mapper/relationship_loader.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/mapper/relationship_writer.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/operations.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/query/__init__.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/query/_compiler.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/query/_decoder.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/query/builder.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/query/expressions.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/query/specialised.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/query/traversal.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/repository/__init__.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/repository/_base.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/repository/async_repository.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/repository/cypher.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/repository/protocol.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/repository/repository.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/schema/__init__.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/schema/index_manager.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/session/__init__.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/session/_base.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/session/async_session.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/session/connection_pool.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/ogm/session/session.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/py.typed +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/__init__.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/__main__.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/adapters/__init__.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/adapters/_llm.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/adapters/chunking.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/adapters/documents.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/adapters/embedding.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/adapters/extraction.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/adapters/reranking.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/adapters/resolution.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/adapters/retrieval.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/adapters/synthesis.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/cli.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/concurrency.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/domain.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/exceptions.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/facade.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/models.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/ontology.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/ports.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/services/__init__.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/services/ingestion.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/services/retrieval.py +0 -0
- {runic_py-0.4.0 → runic_py-0.4.2}/runic/rag/store.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: runic-py
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.2
|
|
4
4
|
Summary: Graph schema migrations and OGM for Cypher-based graph databases.
|
|
5
5
|
Project-URL: Homepage, https://runic.rehpoehler.de
|
|
6
6
|
Project-URL: Repository, https://github.com/jenreh/runic
|
|
@@ -16,7 +16,7 @@ Requires-Python: >=3.14
|
|
|
16
16
|
Requires-Dist: mako<2.0.0,>=1.3.0
|
|
17
17
|
Requires-Dist: rich<16.0.0,>=14.0.0
|
|
18
18
|
Requires-Dist: shellingham<2.0.0,>=1.5.0
|
|
19
|
-
Requires-Dist: typer<
|
|
19
|
+
Requires-Dist: typer<0.27.0,>=0.24.0
|
|
20
20
|
Provides-Extra: age
|
|
21
21
|
Requires-Dist: psycopg<4.0.0,>=3.3.4; extra == 'age'
|
|
22
22
|
Provides-Extra: age-binary
|
|
@@ -47,12 +47,12 @@ Description-Content-Type: text/markdown
|
|
|
47
47
|
**A type-safe OGM for Cypher graph databases.<br>
|
|
48
48
|
Define your models once, run them on any backend.**
|
|
49
49
|
|
|
50
|
-

|
|
51
51
|
[](https://pypi.org/project/runic-py/)
|
|
52
52
|
[](https://www.python.org)
|
|
53
53
|
[](LICENSE.md)
|
|
54
54
|
|
|
55
|
-
[Why Runic](#why-runic) • [The OGM](#the-ogm) • [Migrations](#migrations) • [Installation](#installation) • [Docs](https://runic.rehpoehler.de)
|
|
55
|
+
[Why Runic](#why-runic) • [The OGM](#the-ogm) • [Migrations](#migrations) • [Graph-RAG](#graph-rag) • [Installation](#installation) • [Docs](https://runic.rehpoehler.de)
|
|
56
56
|
|
|
57
57
|
</div>
|
|
58
58
|
|
|
@@ -61,7 +61,8 @@ Define your models once, run them on any backend.**
|
|
|
61
61
|
Runic maps Python classes to graph nodes and edges. You declare typed `Node` and `Edge` models
|
|
62
62
|
and get change tracking, lazy and eager relationships, a composable query API, and schema
|
|
63
63
|
migrations — on top of a pluggable driver layer that runs the same model code on FalkorDB,
|
|
64
|
-
Neo4j, Memgraph, ArcadeDB, and Apache AGE.
|
|
64
|
+
Neo4j, Memgraph, ArcadeDB, and Apache AGE. A built-in [Graph-RAG SDK](#graph-rag) layers
|
|
65
|
+
document ingestion and cited, knowledge-graph-grounded question answering on top of the OGM.
|
|
65
66
|
|
|
66
67
|
## Why Runic
|
|
67
68
|
|
|
@@ -303,6 +304,55 @@ print("current:", runic.migrate.current())
|
|
|
303
304
|
|
|
304
305
|
---
|
|
305
306
|
|
|
307
|
+
## Graph-RAG
|
|
308
|
+
|
|
309
|
+
`runic.rag` turns unstructured text into a knowledge graph and answers questions over it with
|
|
310
|
+
citations — chunking, entity/relation extraction, embedding, storage, and hybrid (vector +
|
|
311
|
+
fulltext + graph-expansion) retrieval are handled for you. It builds on the same OGM and driver
|
|
312
|
+
layer, so it runs on any supported backend. OpenAI is the default for the LLM and embeddings;
|
|
313
|
+
point it at Ollama for a fully local run.
|
|
314
|
+
|
|
315
|
+
```python
|
|
316
|
+
from runic.ogm import create_driver
|
|
317
|
+
from runic.rag import GraphRAG, Ontology, RagSettings
|
|
318
|
+
|
|
319
|
+
settings = RagSettings()
|
|
320
|
+
driver = create_driver(
|
|
321
|
+
"falkordb", host="localhost", port=6379, graph=settings.falkordb_graph
|
|
322
|
+
)
|
|
323
|
+
|
|
324
|
+
# with_defaults() wires the full adapter stack from your environment:
|
|
325
|
+
# paragraph chunker, extractor, embedder, resolver, retrievers, reranker, synthesizer.
|
|
326
|
+
rag = GraphRAG.with_defaults(driver, settings=settings, ontology=Ontology.default())
|
|
327
|
+
rag.bootstrap_schema() # create entity types + indexes (idempotent)
|
|
328
|
+
|
|
329
|
+
# Ingest: chunk -> extract entities/relations -> embed -> resolve -> write the graph.
|
|
330
|
+
rag.ingest_text(
|
|
331
|
+
"Ada Lovelace worked with Charles Babbage on the Analytical Engine in London.",
|
|
332
|
+
source="inline-demo",
|
|
333
|
+
)
|
|
334
|
+
|
|
335
|
+
# mode="auto" classifies the question and picks the retrieval strategy automatically.
|
|
336
|
+
answer = rag.query("Who worked on the Analytical Engine?")
|
|
337
|
+
print(answer.text)
|
|
338
|
+
for citation in answer.citations:
|
|
339
|
+
print(f" - [{citation.source}] {citation.text[:80]}...")
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
Every stage is a port with a default adapter you can swap — custom ontologies, chunkers,
|
|
343
|
+
extractors, or retrievers — and the optional **`runic-rag-docling`** add-on plugs Docling in for
|
|
344
|
+
layout-aware parsing and chunking of PDFs and office documents.
|
|
345
|
+
|
|
346
|
+
```bash
|
|
347
|
+
uv add "runic-py[graphrag,falkordb]" # Graph-RAG extras + a backend driver
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
> [!NOTE]
|
|
351
|
+
> Set `OPENAI_API_KEY` (or place it in a local `.env`) before running, or set
|
|
352
|
+
> `RUNIC_RAG_LLM_PROVIDER=ollama` and `RUNIC_RAG_EMBEDDING_PROVIDER=ollama` to run fully local.
|
|
353
|
+
|
|
354
|
+
---
|
|
355
|
+
|
|
306
356
|
## Installation
|
|
307
357
|
|
|
308
358
|
Install the core package plus the extra for your backend. The core has **no graph-driver
|
|
@@ -316,6 +366,7 @@ dependency** — you only pull in what you use.
|
|
|
316
366
|
| ArcadeDB | `arcadedb` | `neo4j` (Bolt) |
|
|
317
367
|
| Apache AGE | `age` | `psycopg[binary]` |
|
|
318
368
|
| All backends | `all` | all of the above |
|
|
369
|
+
| Graph-RAG | `graphrag` | `pydantic-ai`, `pymupdf` (combine with a backend) |
|
|
319
370
|
|
|
320
371
|
```bash
|
|
321
372
|
uv add "runic-py[falkordb]" # FalkorDB
|
|
@@ -324,6 +375,7 @@ uv add "runic-py[memgraph]" # Memgraph (Bolt)
|
|
|
324
375
|
uv add "runic-py[arcadedb]" # ArcadeDB (Bolt)
|
|
325
376
|
uv add "runic-py[age]" # Apache AGE (PostgreSQL extension)
|
|
326
377
|
uv add "runic-py[all]" # everything
|
|
378
|
+
uv add "runic-py[graphrag,falkordb]" # Graph-RAG SDK + a backend driver
|
|
327
379
|
```
|
|
328
380
|
|
|
329
381
|
> [!NOTE]
|
|
@@ -333,8 +385,8 @@ uv add "runic-py[all]" # everything
|
|
|
333
385
|
|
|
334
386
|
## Documentation
|
|
335
387
|
|
|
336
|
-
Full conceptual overview, async usage, advanced CLI flags,
|
|
337
|
-
at the **[Runic Documentation](https://runic.rehpoehler.de)**.
|
|
388
|
+
Full conceptual overview, async usage, advanced CLI flags, the Graph-RAG guides, and the
|
|
389
|
+
complete API reference live at the **[Runic Documentation](https://runic.rehpoehler.de)**.
|
|
338
390
|
|
|
339
391
|
## License
|
|
340
392
|
|
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
**A type-safe OGM for Cypher graph databases.<br>
|
|
7
7
|
Define your models once, run them on any backend.**
|
|
8
8
|
|
|
9
|
-

|
|
10
10
|
[](https://pypi.org/project/runic-py/)
|
|
11
11
|
[](https://www.python.org)
|
|
12
12
|
[](LICENSE.md)
|
|
13
13
|
|
|
14
|
-
[Why Runic](#why-runic) • [The OGM](#the-ogm) • [Migrations](#migrations) • [Installation](#installation) • [Docs](https://runic.rehpoehler.de)
|
|
14
|
+
[Why Runic](#why-runic) • [The OGM](#the-ogm) • [Migrations](#migrations) • [Graph-RAG](#graph-rag) • [Installation](#installation) • [Docs](https://runic.rehpoehler.de)
|
|
15
15
|
|
|
16
16
|
</div>
|
|
17
17
|
|
|
@@ -20,7 +20,8 @@ Define your models once, run them on any backend.**
|
|
|
20
20
|
Runic maps Python classes to graph nodes and edges. You declare typed `Node` and `Edge` models
|
|
21
21
|
and get change tracking, lazy and eager relationships, a composable query API, and schema
|
|
22
22
|
migrations — on top of a pluggable driver layer that runs the same model code on FalkorDB,
|
|
23
|
-
Neo4j, Memgraph, ArcadeDB, and Apache AGE.
|
|
23
|
+
Neo4j, Memgraph, ArcadeDB, and Apache AGE. A built-in [Graph-RAG SDK](#graph-rag) layers
|
|
24
|
+
document ingestion and cited, knowledge-graph-grounded question answering on top of the OGM.
|
|
24
25
|
|
|
25
26
|
## Why Runic
|
|
26
27
|
|
|
@@ -262,6 +263,55 @@ print("current:", runic.migrate.current())
|
|
|
262
263
|
|
|
263
264
|
---
|
|
264
265
|
|
|
266
|
+
## Graph-RAG
|
|
267
|
+
|
|
268
|
+
`runic.rag` turns unstructured text into a knowledge graph and answers questions over it with
|
|
269
|
+
citations — chunking, entity/relation extraction, embedding, storage, and hybrid (vector +
|
|
270
|
+
fulltext + graph-expansion) retrieval are handled for you. It builds on the same OGM and driver
|
|
271
|
+
layer, so it runs on any supported backend. OpenAI is the default for the LLM and embeddings;
|
|
272
|
+
point it at Ollama for a fully local run.
|
|
273
|
+
|
|
274
|
+
```python
|
|
275
|
+
from runic.ogm import create_driver
|
|
276
|
+
from runic.rag import GraphRAG, Ontology, RagSettings
|
|
277
|
+
|
|
278
|
+
settings = RagSettings()
|
|
279
|
+
driver = create_driver(
|
|
280
|
+
"falkordb", host="localhost", port=6379, graph=settings.falkordb_graph
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
# with_defaults() wires the full adapter stack from your environment:
|
|
284
|
+
# paragraph chunker, extractor, embedder, resolver, retrievers, reranker, synthesizer.
|
|
285
|
+
rag = GraphRAG.with_defaults(driver, settings=settings, ontology=Ontology.default())
|
|
286
|
+
rag.bootstrap_schema() # create entity types + indexes (idempotent)
|
|
287
|
+
|
|
288
|
+
# Ingest: chunk -> extract entities/relations -> embed -> resolve -> write the graph.
|
|
289
|
+
rag.ingest_text(
|
|
290
|
+
"Ada Lovelace worked with Charles Babbage on the Analytical Engine in London.",
|
|
291
|
+
source="inline-demo",
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
# mode="auto" classifies the question and picks the retrieval strategy automatically.
|
|
295
|
+
answer = rag.query("Who worked on the Analytical Engine?")
|
|
296
|
+
print(answer.text)
|
|
297
|
+
for citation in answer.citations:
|
|
298
|
+
print(f" - [{citation.source}] {citation.text[:80]}...")
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
Every stage is a port with a default adapter you can swap — custom ontologies, chunkers,
|
|
302
|
+
extractors, or retrievers — and the optional **`runic-rag-docling`** add-on plugs Docling in for
|
|
303
|
+
layout-aware parsing and chunking of PDFs and office documents.
|
|
304
|
+
|
|
305
|
+
```bash
|
|
306
|
+
uv add "runic-py[graphrag,falkordb]" # Graph-RAG extras + a backend driver
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
> [!NOTE]
|
|
310
|
+
> Set `OPENAI_API_KEY` (or place it in a local `.env`) before running, or set
|
|
311
|
+
> `RUNIC_RAG_LLM_PROVIDER=ollama` and `RUNIC_RAG_EMBEDDING_PROVIDER=ollama` to run fully local.
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
265
315
|
## Installation
|
|
266
316
|
|
|
267
317
|
Install the core package plus the extra for your backend. The core has **no graph-driver
|
|
@@ -275,6 +325,7 @@ dependency** — you only pull in what you use.
|
|
|
275
325
|
| ArcadeDB | `arcadedb` | `neo4j` (Bolt) |
|
|
276
326
|
| Apache AGE | `age` | `psycopg[binary]` |
|
|
277
327
|
| All backends | `all` | all of the above |
|
|
328
|
+
| Graph-RAG | `graphrag` | `pydantic-ai`, `pymupdf` (combine with a backend) |
|
|
278
329
|
|
|
279
330
|
```bash
|
|
280
331
|
uv add "runic-py[falkordb]" # FalkorDB
|
|
@@ -283,6 +334,7 @@ uv add "runic-py[memgraph]" # Memgraph (Bolt)
|
|
|
283
334
|
uv add "runic-py[arcadedb]" # ArcadeDB (Bolt)
|
|
284
335
|
uv add "runic-py[age]" # Apache AGE (PostgreSQL extension)
|
|
285
336
|
uv add "runic-py[all]" # everything
|
|
337
|
+
uv add "runic-py[graphrag,falkordb]" # Graph-RAG SDK + a backend driver
|
|
286
338
|
```
|
|
287
339
|
|
|
288
340
|
> [!NOTE]
|
|
@@ -292,8 +344,8 @@ uv add "runic-py[all]" # everything
|
|
|
292
344
|
|
|
293
345
|
## Documentation
|
|
294
346
|
|
|
295
|
-
Full conceptual overview, async usage, advanced CLI flags,
|
|
296
|
-
at the **[Runic Documentation](https://runic.rehpoehler.de)**.
|
|
347
|
+
Full conceptual overview, async usage, advanced CLI flags, the Graph-RAG guides, and the
|
|
348
|
+
complete API reference live at the **[Runic Documentation](https://runic.rehpoehler.de)**.
|
|
297
349
|
|
|
298
350
|
## License
|
|
299
351
|
|
|
@@ -41,7 +41,10 @@ dev = [
|
|
|
41
41
|
commit = false
|
|
42
42
|
current_version = "0.2.0"
|
|
43
43
|
tag = false
|
|
44
|
-
|
|
44
|
+
# This package lives in the shared ``runic`` monorepo, whose working tree
|
|
45
|
+
# routinely carries unrelated sibling changes and whose ``v*`` tags belong to
|
|
46
|
+
# ``runic-py``; allow a dirty tree so the package-scoped bump isn't blocked.
|
|
47
|
+
allow_dirty = true
|
|
45
48
|
|
|
46
49
|
[[tool.bumpversion.files]]
|
|
47
50
|
filename = "pyproject.toml"
|
|
@@ -72,6 +75,13 @@ build-backend = "hatchling.build"
|
|
|
72
75
|
[tool.hatch.build.targets.wheel]
|
|
73
76
|
packages = ["runic_rag_docling"]
|
|
74
77
|
|
|
78
|
+
[tool.hatch.build.targets.sdist]
|
|
79
|
+
# Ship only the source package and metadata; never the local virtualenv
|
|
80
|
+
# (``.venv.mac``), caches, or build artefacts, which break ``uv build`` with
|
|
81
|
+
# "external symlinks are not allowed".
|
|
82
|
+
include = ["/runic_rag_docling", "/README.md", "/pyproject.toml"]
|
|
83
|
+
exclude = [".venv*"]
|
|
84
|
+
|
|
75
85
|
[tool.pytest.ini_options]
|
|
76
86
|
# ``tests`` is a package; put the package root on the path so ``tests.fakes``
|
|
77
87
|
# imports resolve regardless of the invocation directory.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "runic-py"
|
|
3
|
-
version = "0.4.
|
|
3
|
+
version = "0.4.2"
|
|
4
4
|
description = "Graph schema migrations and OGM for Cypher-based graph databases."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.14"
|
|
@@ -16,7 +16,7 @@ classifiers = [
|
|
|
16
16
|
]
|
|
17
17
|
|
|
18
18
|
dependencies = [
|
|
19
|
-
"typer>=0.
|
|
19
|
+
"typer>=0.24.0,<0.27.0",
|
|
20
20
|
"rich>=14.0.0,<16.0.0",
|
|
21
21
|
"mako>=1.3.0,<2.0.0",
|
|
22
22
|
"shellingham>=1.5.0,<2.0.0",
|
|
@@ -101,7 +101,7 @@ exclude = [
|
|
|
101
101
|
|
|
102
102
|
[tool.bumpversion]
|
|
103
103
|
commit = false
|
|
104
|
-
current_version = "0.4.
|
|
104
|
+
current_version = "0.4.2"
|
|
105
105
|
tag = false
|
|
106
106
|
allow-dirty = false
|
|
107
107
|
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
All ``RUNIC_RAG_*`` environment variables map onto :class:`RagSettings`
|
|
4
4
|
field names (env_prefix ``RUNIC_RAG_``). ``OPENAI_API_KEY`` and
|
|
5
5
|
``OLLAMA_BASE_URL`` are read UNPREFIXED so they match the conventions of the
|
|
6
|
-
underlying OpenAI / Ollama clients
|
|
6
|
+
underlying OpenAI / Ollama clients (the ``RUNIC_RAG_``-prefixed form and direct
|
|
7
|
+
keyword init are also accepted via ``populate_by_name``). Defaults mirror
|
|
8
|
+
``.env.example`` exactly.
|
|
7
9
|
"""
|
|
8
10
|
|
|
9
11
|
from __future__ import annotations
|
|
@@ -37,6 +39,7 @@ class RagSettings(BaseSettings):
|
|
|
37
39
|
env_file_encoding="utf-8",
|
|
38
40
|
extra="ignore",
|
|
39
41
|
case_sensitive=False,
|
|
42
|
+
populate_by_name=True,
|
|
40
43
|
)
|
|
41
44
|
|
|
42
45
|
# ── LLM provider ────────────────────────────────────────────────────────
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|