Navegador

navegador / docs / guide / sdk.md
1
# Python SDK
2
3
The navegador Python SDK lets you drive ingestion, query the graph, and load context from your own scripts and tools — without going through the CLI.
4
5
---
6
7
## Installation
8
9
```bash
10
pip install navegador
11
```
12
13
For Redis (production/team) support:
14
15
```bash
16
pip install "navegador[redis]"
17
```
18
19
---
20
21
## Connecting to the graph
22
23
=== "SQLite (local)"
24
25
```python
26
from navegador.graph import GraphStore
27
28
store = GraphStore.sqlite(".navegador/navegador.db")
29
```
30
31
=== "Redis (production)"
32
33
```python
34
from navegador.graph import GraphStore
35
36
store = GraphStore.redis("redis://localhost:6379")
37
```
38
39
Both backends implement the same interface. All examples below work with either.
40
41
Use the context manager to ensure the connection is closed:
42
43
```python
44
with GraphStore.sqlite(".navegador/navegador.db") as store:
45
results = store.query("MATCH (n) RETURN count(n) AS total")
46
print(results[0]["total"])
47
```
48
49
---
50
51
## Ingestion
52
53
### Ingest a repo
54
55
```python
56
from navegador.graph import GraphStore
57
from navegador.ingest import RepoIngester
58
59
store = GraphStore.sqlite(".navegador/navegador.db")
60
ingester = RepoIngester(store)
61
62
result = ingester.ingest("./src")
63
print(f"{result.nodes_created} nodes, {result.edges_created} edges in {result.duration_seconds:.2f}s")
64
```
65
66
### Incremental ingest (single file)
67
68
```python
69
result = ingester.ingest_file("./src/auth/service.py")
70
```
71
72
### Wipe and rebuild
73
74
```python
75
result = ingester.ingest("./src", clear=True)
76
```
77
78
### Add knowledge programmatically
79
80
```python
81
from navegador.ingest import KnowledgeIngester
82
83
ki = KnowledgeIngester(store)
84
85
ki.add_domain("Payments", description="Payment processing and billing")
86
ki.add_concept("Idempotency", domain="Payments",
87
description="Operations safe to retry without side effects")
88
ki.add_rule("RequireIdempotencyKey",
89
domain="Payments", severity="critical",
90
rationale="Card networks retry on timeout")
91
ki.annotate("process_payment", node_type="Function",
92
concept="Idempotency", rule="RequireIdempotencyKey")
93
```
94
95
---
96
97
## Loading context
98
99
`ContextLoader` builds structured context bundles from the graph. Each method corresponds to a CLI command.
100
101
```python
102
from navegador.graph import GraphStore
103
from navegador.context import ContextLoader
104
105
store = GraphStore.sqlite(".navegador/navegador.db")
106
loader = ContextLoader(store)
107
```
108
109
### File context
110
111
```python
112
bundle = loader.load_file("src/auth/service.py")
113
print(bundle.to_markdown())
114
```
115
116
### Function with call graph
117
118
```python
119
# depth controls how many hops of callers/callees to include
120
bundle = loader.load_function("validate_token", depth=2)
121
print(bundle.to_json())
122
```
123
124
### Class hierarchy
125
126
```python
127
bundle = loader.load_class("PaymentProcessor", file="src/payments/processor.py")
128
data = bundle.to_dict()
129
```
130
131
### Universal explain
132
133
```python
134
# works for any node type: function, class, file, concept, rule, decision
135
bundle = loader.explain("AuthService")
136
bundle = loader.explain("PaymentsMustBeIdempotent")
137
```
138
139
### Concept and domain
140
141
```python
142
bundle = loader.load_concept("Idempotency")
143
bundle = loader.load_domain("Payments")
144
```
145
146
---
147
148
## Search
149
150
```python
151
# search function and class names (default)
152
nodes = loader.search("rate limit")
153
154
# search all layers including knowledge and docs
155
nodes = loader.search("rate limit", all_layers=True, limit=50)
156
157
# search docstrings and wiki content only
158
nodes = loader.search_by_docstring("retry logic")
159
160
# find all functions using a specific decorator
161
nodes = loader.decorated_by("login_required")
162
163
for node in nodes:
164
print(f"{node.label}: {node.name} ({node.properties.get('file', '')})")
165
```
166
167
---
168
169
## Knowledge queries
170
171
```python
172
# everything in the Payments domain
173
bundle = loader.load_domain("Payments")
174
for node in bundle.nodes:
175
print(f" [{node.label}] {node.name}")
176
177
# all code annotated with a concept
178
bundle = loader.load_concept("Idempotency")
179
for node in bundle.nodes:
180
if node.layer == "code":
181
print(f" {node.name} {node.properties.get('file', '')}")
182
```
183
184
---
185
186
## Exporting output
187
188
Every `ContextBundle` supports three output formats:
189
190
```python
191
bundle = loader.load_function("process_payment")
192
193
# JSON string — for agents, APIs, CI
194
json_str = bundle.to_json()
195
196
# Markdown — readable by humans and LLMs
197
md_str = bundle.to_markdown()
198
199
# Python dict — for further processing
200
data = bundle.to_dict()
201
print(data["root"]["name"])
202
print(len(data["nodes"]))
203
```
204
205
---
206
207
## Raw Cypher queries
208
209
Drop to raw Cypher for anything the built-in methods don't cover:
210
211
```python
212
results = store.query(
213
"MATCH (f:Function)-[:CALLS]->(g:Function) "
214
"WHERE f.file = $file "
215
"RETURN f.name, g.name",
216
params={"file": "src/payments/processor.py"}
217
)
218
for row in results:
219
print(f"{row['f.name']} -> {row['g.name']}")
220
```
221
222
!!! warning
223
`store.query()` executes writes as well as reads. Stick to `MATCH` / `RETURN` for inspection queries.
224
225
---
226
227
## Wiki ingestion
228
229
```python
230
import os
231
from navegador.ingest import WikiIngester
232
233
ingester = WikiIngester(store)
234
235
# from GitHub API
236
result = ingester.ingest_repo("myorg/myrepo", token=os.environ["GITHUB_TOKEN"])
237
238
# from a locally cloned wiki directory
239
result = ingester.ingest_dir("./myrepo.wiki")
240
```
241
242
---
243
244
## Error handling
245
246
All ingesters return an `IngestionResult` dataclass. Check `errors` for per-file failures without crashing the whole run:
247
248
```python
249
result = ingester.ingest("./src")
250
if result.errors:
251
for err in result.errors:
252
print(f"Warning: {err}")
253
print(f"Processed {result.files_processed} files, {result.nodes_created} nodes created")
254
```
255

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button