databar 2.0.7__tar.gz → 2.0.9__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.
Files changed (28) hide show
  1. {databar-2.0.7/src/databar.egg-info → databar-2.0.9}/PKG-INFO +1 -1
  2. {databar-2.0.7 → databar-2.0.9}/pyproject.toml +1 -1
  3. {databar-2.0.7 → databar-2.0.9}/src/databar/__init__.py +1 -1
  4. databar-2.0.9/src/databar/cli/_guide.py +219 -0
  5. {databar-2.0.7 → databar-2.0.9}/src/databar/cli/_onboard.py +76 -5
  6. {databar-2.0.7 → databar-2.0.9}/src/databar/cli/app.py +4 -1
  7. {databar-2.0.7 → databar-2.0.9}/src/databar/client.py +8 -1
  8. {databar-2.0.7 → databar-2.0.9/src/databar.egg-info}/PKG-INFO +1 -1
  9. {databar-2.0.7 → databar-2.0.9}/tests/test_cli.py +1 -1
  10. databar-2.0.7/src/databar/cli/_guide.py +0 -237
  11. {databar-2.0.7 → databar-2.0.9}/LICENSE +0 -0
  12. {databar-2.0.7 → databar-2.0.9}/README.md +0 -0
  13. {databar-2.0.7 → databar-2.0.9}/setup.cfg +0 -0
  14. {databar-2.0.7 → databar-2.0.9}/src/databar/cli/__init__.py +0 -0
  15. {databar-2.0.7 → databar-2.0.9}/src/databar/cli/_auth.py +0 -0
  16. {databar-2.0.7 → databar-2.0.9}/src/databar/cli/_output.py +0 -0
  17. {databar-2.0.7 → databar-2.0.9}/src/databar/cli/enrichments.py +0 -0
  18. {databar-2.0.7 → databar-2.0.9}/src/databar/cli/tables.py +0 -0
  19. {databar-2.0.7 → databar-2.0.9}/src/databar/cli/tasks.py +0 -0
  20. {databar-2.0.7 → databar-2.0.9}/src/databar/cli/waterfalls.py +0 -0
  21. {databar-2.0.7 → databar-2.0.9}/src/databar/exceptions.py +0 -0
  22. {databar-2.0.7 → databar-2.0.9}/src/databar/models.py +0 -0
  23. {databar-2.0.7 → databar-2.0.9}/src/databar.egg-info/SOURCES.txt +0 -0
  24. {databar-2.0.7 → databar-2.0.9}/src/databar.egg-info/dependency_links.txt +0 -0
  25. {databar-2.0.7 → databar-2.0.9}/src/databar.egg-info/entry_points.txt +0 -0
  26. {databar-2.0.7 → databar-2.0.9}/src/databar.egg-info/requires.txt +0 -0
  27. {databar-2.0.7 → databar-2.0.9}/src/databar.egg-info/top_level.txt +0 -0
  28. {databar-2.0.7 → databar-2.0.9}/tests/test_client.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: databar
3
- Version: 2.0.7
3
+ Version: 2.0.9
4
4
  Summary: Official Databar.ai Python SDK and CLI — connect to enrichments, waterfalls, and tables via api.databar.ai
5
5
  Author-email: "Databar.ai Team" <info@databar.ai>
6
6
  License: MIT License
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "databar"
7
- version = "2.0.7"
7
+ version = "2.0.9"
8
8
  description = "Official Databar.ai Python SDK and CLI — connect to enrichments, waterfalls, and tables via api.databar.ai"
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
@@ -58,7 +58,7 @@ from .models import (
58
58
  WaterfallEnrichment,
59
59
  )
60
60
 
61
- __version__ = "2.0.7"
61
+ __version__ = "2.0.9"
62
62
  __all__ = [
63
63
  "DatabarClient",
64
64
  # exceptions
@@ -0,0 +1,219 @@
1
+ """Embedded agent guide — printed by `databar agent-guide`."""
2
+
3
+ AGENT_GUIDE = r"""# Databar — Agent Guide
4
+
5
+ Databar is a data enrichment platform. Given an input (email, LinkedIn URL, company
6
+ domain, etc.) it returns enriched data from dozens of providers. The `databar` package
7
+ ships three interfaces: a **CLI**, a **Python SDK**, and an **MCP server**.
8
+
9
+ Databar supports two enrichment workflows:
10
+
11
+ - **Direct** — submit inputs and get results back immediately. Best for one-off lookups
12
+ or bulk CSV processing where you just need the output.
13
+ - **Table-based** — create a table, upload rows, attach enrichments, run them. Results
14
+ appear as new columns on each row. Best when you want observability (see results in
15
+ the Databar UI), re-run enrichments on the same data, or build a persistent dataset.
16
+
17
+ ---
18
+
19
+ ## DECISION MATRIX — read this first
20
+
21
+ +----------------------------------+--------------------+
22
+ | Situation | Use |
23
+ +----------------------------------+--------------------+
24
+ | MCP tools available this session | MCP (best option) |
25
+ | Single operation, no branching | CLI |
26
+ | Conditional logic / loops / | Python SDK |
27
+ | multi-step pipeline with | |
28
+ | decisions per row | |
29
+ +----------------------------------+--------------------+
30
+
31
+ **Default: CLI.** Use Python SDK only when you need to branch on results or loop
32
+ with per-row decisions. Use MCP when it is configured — it requires zero setup.
33
+
34
+ ---
35
+
36
+ ## STEP 1 — Check authentication
37
+
38
+ ```bash
39
+ echo $DATABAR_API_KEY # check env var
40
+ cat ~/.databar/config # check saved config (file has no extension)
41
+ ```
42
+
43
+ If neither exists, ask the user in chat:
44
+ "Please provide your Databar API key (databar.ai → Settings → API Keys)."
45
+
46
+ Then save it non-interactively:
47
+
48
+ ```bash
49
+ databar login --api-key <key>
50
+ databar whoami --format json # verify
51
+ ```
52
+
53
+ Never run `databar onboard` — interactive wizard, not for agents.
54
+ Never run `databar login` without `--api-key` — will hang on terminal input.
55
+
56
+ ---
57
+
58
+ ## STEP 2 — Ask the user their preferred interface AND workflow
59
+
60
+ Unless ~/.databar/config already contains `preferred_interface=`, ask:
61
+
62
+ "Databar has three interfaces — which do you prefer?
63
+ - CLI (default) — terminal commands, no code, pipeable JSON. Best for single operations.
64
+ - Python SDK — required for conditional logic, loops, multi-step pipelines with branching.
65
+ - MCP — if configured in your Claude session, it's the most agent-native option.
66
+ Which do you prefer?"
67
+
68
+ Also ask about workflow preference:
69
+
70
+ "Databar supports two enrichment workflows — which fits your use case?
71
+ - Direct (default) — submit inputs, get results back immediately. Good for one-off
72
+ lookups or bulk CSV jobs where you just need the output fast.
73
+ - Table-based — create a table, upload rows, attach enrichments, then run them.
74
+ Results appear as new columns in the Databar UI. Best when you want observability,
75
+ plan to re-run enrichments, or want to pair with the Databar web interface.
76
+ Which do you prefer?"
77
+
78
+ Save their answers:
79
+ ```bash
80
+ echo "preferred_interface=cli" >> ~/.databar/config # or: python, mcp, both
81
+ echo "preferred_workflow=direct" >> ~/.databar/config # or: table
82
+ ```
83
+
84
+ ---
85
+
86
+ ## STEP 3 — Fix PATH before using the CLI
87
+
88
+ After `pip install databar`, the binary is NOT on PATH by default. Always check:
89
+
90
+ ```bash
91
+ which databar # empty = not on PATH
92
+ databar --version # "command not found" = fix PATH first
93
+ ```
94
+
95
+ Fix for this session:
96
+ ```bash
97
+ export PATH="$(python3 -m site --user-base)/bin:$PATH"
98
+ databar --version # should work now
99
+ ```
100
+
101
+ Make permanent:
102
+ ```bash
103
+ echo 'export PATH="$(python3 -m site --user-base)/bin:$PATH"' >> ~/.zshrc
104
+ ```
105
+
106
+ ---
107
+
108
+ ## CLI Quick Reference
109
+
110
+ **Always use `--format json` when parsing or piping output.**
111
+ The default `table` format uses Rich terminal markup — not machine-parseable.
112
+
113
+ ### Enrichments
114
+ ```bash
115
+ databar enrich list --format json
116
+ databar enrich list --query "email verifier" --format json
117
+ databar enrich get <id> --format json # params + response fields
118
+ databar enrich choices <id> <param> --format json
119
+ databar enrich run <id> --params '{"email": "a@b.com"}' --format json
120
+ databar enrich bulk <id> --input data.csv --out results.csv
121
+ ```
122
+
123
+ ### Waterfalls
124
+ ```bash
125
+ databar waterfall list --format json
126
+ databar waterfall get <identifier> --format json
127
+ databar waterfall run <identifier> --params '{"key": "value"}' --format json
128
+ databar waterfall bulk <identifier> --input data.csv --out results.csv
129
+ ```
130
+
131
+ ### Tables
132
+ ```bash
133
+ databar table list --format json
134
+ databar table create --name "My Table" --columns "email,name,company"
135
+ databar table columns <table-uuid> --format json
136
+ databar table rows <table-uuid> --format json
137
+
138
+ databar table insert <table-uuid> --data '[{"email":"a@b.com"}]'
139
+ databar table insert <table-uuid> --input data.csv --allow-new-columns
140
+
141
+ databar table enrichments <table-uuid> --format json
142
+ databar table add-enrichment <table-uuid> --enrichment-id <id> \
143
+ --mapping '{"param": "column_name"}'
144
+ databar table run-enrichment <table-uuid> --enrichment-id <TABLE-ENRICHMENT-ID>
145
+ ```
146
+
147
+ NOTE: `run-enrichment` takes the TABLE-ENRICHMENT ID (from `add-enrichment` or
148
+ `table enrichments`), NOT the catalog enrichment ID. These are different numbers.
149
+
150
+ ### Tasks
151
+ ```bash
152
+ databar task get <task-id> --format json # check once
153
+ databar task get <task-id> --poll # poll until complete
154
+ ```
155
+
156
+ ---
157
+
158
+ ## Python SDK Quick Reference
159
+
160
+ ```python
161
+ from databar import DatabarClient
162
+
163
+ client = DatabarClient() # reads DATABAR_API_KEY or ~/.databar/config automatically
164
+
165
+ # Enrichments
166
+ enrichments = client.list_enrichments(q="email verifier")
167
+ enrichment = client.get_enrichment(123)
168
+ # enrichment.params[i].name → param slug (key in params dict)
169
+ # enrichment.params[i].is_required → bool
170
+ # enrichment.params[i].description → human label
171
+ result = client.run_enrichment_sync(123, {"email": "alice@example.com"})
172
+
173
+ # Waterfalls
174
+ result = client.run_waterfall_sync("email_getter", {"linkedin_url": "..."})
175
+ # waterfall.identifier (also .slug) → slug like "email_getter"
176
+
177
+ # Tables
178
+ tables = client.list_tables()
179
+ # table.identifier (also .id, .uuid) → UUID string
180
+ table = client.create_table(name="Leads", columns=["email", "name"])
181
+ resp = client.get_rows(table.identifier)
182
+ # resp.data → list of row dicts keyed by column name
183
+ # resp.has_next_page → bool
184
+ # resp.total_count → int
185
+
186
+ from databar import InsertRow
187
+ client.create_rows(table.identifier, [InsertRow(fields={"email": "alice@example.com"})])
188
+ ```
189
+
190
+ ---
191
+
192
+ ## Key Concepts
193
+
194
+ - All runs are async. `*_sync` methods and `--poll` flag handle submit + poll automatically.
195
+ - `task_id` is the only task identifier. Results expire after 1 hour (status = "gone").
196
+ - Table enrichments: add-enrichment (configure) → run-enrichment (execute).
197
+ The ID from add is the TABLE-ENRICHMENT ID — different from the catalog ID.
198
+ - SDK auto-resolves column names to UUIDs in `add_enrichment()`.
199
+
200
+ ## Model Field Aliases (Python SDK)
201
+
202
+ - `Table`: `.id`, `.uuid` → `.identifier`
203
+ - `Waterfall`: `.slug` → `.identifier`
204
+ - `EnrichmentParam`: `.slug` → `.name`, `.label` → `.description`, `.required` → `.is_required`
205
+ - `EnrichmentResponseField`: `.slug` → `.name`
206
+
207
+ ## Error Handling (Python SDK)
208
+
209
+ ```python
210
+ from databar import (
211
+ DatabarAuthError, # 401/403
212
+ DatabarInsufficientCreditsError, # 406
213
+ DatabarNotFoundError, # 404
214
+ DatabarTaskFailedError, # task failed
215
+ DatabarTimeoutError, # polling timed out
216
+ DatabarGoneError, # results expired (>1 hour)
217
+ )
218
+ ```
219
+ """
@@ -6,7 +6,8 @@ Guides the user through:
6
6
  2. API key entry & verification
7
7
  3. PATH detection & optional auto-fix
8
8
  4. Usage preference (CLI / Python SDK / both)
9
- 5. Tailored next-steps cheatsheet
9
+ 5. Optional ~/.claude/CLAUDE.md registration for Claude Code
10
+ 6. Tailored next-steps cheatsheet
10
11
  """
11
12
 
12
13
  from __future__ import annotations
@@ -48,6 +49,12 @@ CONFIG_DIR = Path.home() / ".databar"
48
49
  CONFIG_FILE = CONFIG_DIR / "config"
49
50
  _KEY_PREFIX = "api_key="
50
51
  _PREF_PREFIX = "preferred_interface="
52
+ _WORKFLOW_PREFIX = "preferred_workflow="
53
+
54
+ CLAUDE_MD_DIR = Path.home() / ".claude"
55
+ CLAUDE_MD_FILE = CLAUDE_MD_DIR / "CLAUDE.md"
56
+ _CLAUDE_SENTINEL = "<!-- databar -->"
57
+ _CLAUDE_STUB = """\n<!-- databar -->\n## Databar\nWhen the user asks you to use Databar, always run `databar agent-guide` first\nto get the full usage guide before doing anything else.\n<!-- /databar -->\n"""
51
58
 
52
59
 
53
60
  def _save_key(api_key: str) -> None:
@@ -74,6 +81,17 @@ def _save_preference(pref: str) -> None:
74
81
  CONFIG_FILE.write_text("\n".join(lines) + "\n")
75
82
 
76
83
 
84
+ def _save_workflow(workflow: str) -> None:
85
+ lines: list[str] = []
86
+ if CONFIG_FILE.exists():
87
+ lines = [
88
+ l for l in CONFIG_FILE.read_text().splitlines()
89
+ if not l.startswith(_WORKFLOW_PREFIX)
90
+ ]
91
+ lines.append(f"{_WORKFLOW_PREFIX}{workflow}")
92
+ CONFIG_FILE.write_text("\n".join(lines) + "\n")
93
+
94
+
77
95
  def _get_bin_dir() -> Path:
78
96
  return Path(sys.executable).parent
79
97
 
@@ -210,20 +228,72 @@ def _step_path() -> None:
210
228
 
211
229
 
212
230
  def _step_preference() -> str:
213
- """Ask how the user plans to use Databar and return their choice."""
231
+ """Ask interface preference and workflow preference. Returns interface choice."""
214
232
  console.print("[bold]Step 3 — How do you plan to use Databar?[/bold]\n")
233
+ console.print(" [bold cyan]Interface[/bold cyan]\n")
215
234
  console.print(" [bold cyan]1[/bold cyan] CLI — terminal commands, scripts, AI agents (Claude Code etc.)")
216
235
  console.print(" [bold cyan]2[/bold cyan] Python — import DatabarClient in your Python code")
217
- console.print(" [bold cyan]3[/bold cyan] Both I'll use whichever fits the task\n")
236
+ console.print(" [bold cyan]3[/bold cyan] MCP — use Databar MCP tools if configured in your agent")
237
+ console.print(" [bold cyan]4[/bold cyan] Both/all — I'll use whichever fits the task\n")
218
238
 
219
- choice = Prompt.ask(" Your choice", choices=["1", "2", "3"], default="3")
220
- pref_map = {"1": "cli", "2": "python", "3": "both"}
239
+ choice = Prompt.ask(" Your choice", choices=["1", "2", "3", "4"], default="1")
240
+ pref_map = {"1": "cli", "2": "python", "3": "mcp", "4": "both"}
221
241
  pref = pref_map[choice]
222
242
  _save_preference(pref)
243
+
244
+ console.print()
245
+ console.print(" [bold cyan]Workflow[/bold cyan]\n")
246
+ console.print(" [bold cyan]1[/bold cyan] Direct — submit inputs, get results back immediately")
247
+ console.print(" Best for one-off lookups or bulk CSV jobs")
248
+ console.print(" [bold cyan]2[/bold cyan] Table-based — create a table, upload rows, attach + run enrichments")
249
+ console.print(" Results appear as columns in the Databar UI")
250
+ console.print(" Best for observability, re-running, or pairing with the web interface\n")
251
+
252
+ wf_choice = Prompt.ask(" Your choice", choices=["1", "2"], default="1")
253
+ workflow = "direct" if wf_choice == "1" else "table"
254
+ _save_workflow(workflow)
255
+
223
256
  console.print()
224
257
  return pref
225
258
 
226
259
 
260
+ def _step_claude_md() -> None:
261
+ """Optionally register Databar in the user's global ~/.claude/CLAUDE.md."""
262
+ console.print("[bold]Step 4 — Claude Code integration (optional)[/bold]\n")
263
+
264
+ already = (
265
+ CLAUDE_MD_FILE.exists()
266
+ and _CLAUDE_SENTINEL in CLAUDE_MD_FILE.read_text()
267
+ )
268
+ if already:
269
+ console.print(
270
+ " [bold green]✓[/bold green] Databar is already registered in "
271
+ f"[dim]{CLAUDE_MD_FILE}[/dim].\n"
272
+ )
273
+ return
274
+
275
+ console.print(
276
+ f" Adding a small entry to [bold]{CLAUDE_MD_FILE}[/bold] tells Claude Code\n"
277
+ " to always run [bold]databar agent-guide[/bold] first, so it knows exactly\n"
278
+ " how to use Databar without guessing.\n"
279
+ )
280
+ add = Confirm.ask(
281
+ " Add Databar to your global Claude Code config (~/.claude/CLAUDE.md)?",
282
+ default=True,
283
+ )
284
+ if add:
285
+ CLAUDE_MD_DIR.mkdir(parents=True, exist_ok=True)
286
+ with open(CLAUDE_MD_FILE, "a") as f:
287
+ f.write(_CLAUDE_STUB)
288
+ console.print(
289
+ f" [bold green]✓[/bold green] Added to {CLAUDE_MD_FILE}.\n"
290
+ " Claude Code will now pick up Databar instructions automatically "
291
+ "in every project.\n"
292
+ )
293
+ else:
294
+ console.print(" [dim]Skipped.[/dim]\n")
295
+
296
+
227
297
  def _step_next_steps(pref: str) -> None:
228
298
  """Print tailored next steps based on preference."""
229
299
  console.print(Rule(style="cyan"))
@@ -283,6 +353,7 @@ def onboard() -> None:
283
353
  _step_api_key()
284
354
  _step_path()
285
355
  pref = _step_preference()
356
+ _step_claude_md()
286
357
  _step_next_steps(pref)
287
358
  except (KeyboardInterrupt, typer.Abort):
288
359
  console.print("\n\n[dim]Onboarding cancelled. Run `databar onboard` any time to restart.[/dim]")
@@ -15,7 +15,10 @@ from ._auth import app as auth_app
15
15
 
16
16
  app = typer.Typer(
17
17
  name="databar",
18
- help="Official Databar.ai CLI — run enrichments, manage tables, and more.",
18
+ help=(
19
+ "Official Databar.ai CLI — run enrichments, manage tables, and more.\n\n"
20
+ "[dim]Agent (Claude Code, Cursor, etc.)? Run [bold]databar agent-guide[/bold] first.[/dim]"
21
+ ),
19
22
  no_args_is_help=True,
20
23
  rich_markup_mode="rich",
21
24
  )
@@ -87,10 +87,17 @@ class DatabarClient:
87
87
  ) -> None:
88
88
  resolved_key = api_key or os.environ.get("DATABAR_API_KEY")
89
89
  if not resolved_key:
90
- raise DatabarAuthError(
90
+ import shutil
91
+ msg = (
91
92
  "No API key provided. Pass api_key= or set the DATABAR_API_KEY "
92
93
  "environment variable. Run `databar login` to save your key."
93
94
  )
95
+ if shutil.which("databar") is not None:
96
+ msg += (
97
+ "\n\nUsing Databar with an AI agent (Claude Code, Cursor, etc.)? "
98
+ "Run `databar agent-guide` for agent-optimized setup instructions."
99
+ )
100
+ raise DatabarAuthError(msg)
94
101
  self._api_key = resolved_key
95
102
  self._base_url = base_url.rstrip("/")
96
103
  self._timeout = timeout
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: databar
3
- Version: 2.0.7
3
+ Version: 2.0.9
4
4
  Summary: Official Databar.ai Python SDK and CLI — connect to enrichments, waterfalls, and tables via api.databar.ai
5
5
  Author-email: "Databar.ai Team" <info@databar.ai>
6
6
  License: MIT License
@@ -329,4 +329,4 @@ def test_task_get_poll(monkeypatch):
329
329
  def test_version_flag():
330
330
  result = runner.invoke(app, ["--version"])
331
331
  assert result.exit_code == 0
332
- assert "2.0.7" in result.output
332
+ assert "2.0.9" in result.output
@@ -1,237 +0,0 @@
1
- """Embedded agent guide — printed by `databar agent-guide`."""
2
-
3
- AGENT_GUIDE = r"""# Databar — Agent Guide
4
-
5
- Databar is a data enrichment platform. The `databar` package ships both a
6
- **CLI** and a **Python SDK**. This guide tells you exactly how to set up and
7
- use each, including common pitfalls.
8
-
9
- ---
10
-
11
- ## STEP 1 — Check authentication
12
-
13
- Before doing anything else, check whether the user is already authenticated:
14
-
15
- ```bash
16
- # Check 1: env var
17
- echo $DATABAR_API_KEY
18
-
19
- # Check 2: saved config
20
- cat ~/.databar/config
21
- ```
22
-
23
- If neither exists, the user is not authenticated. Ask them in chat:
24
-
25
- "Please provide your Databar API key. You can find it at databar.ai → Settings → API Keys."
26
-
27
- Once they give it to you, save it non-interactively:
28
-
29
- ```bash
30
- databar login --api-key <key they provided>
31
- databar whoami --format json # verify it works
32
- ```
33
-
34
- Never run `databar onboard` — that is an interactive wizard for humans, not agents.
35
- Never run `databar login` without `--api-key` — it will hang waiting for terminal input.
36
-
37
- ---
38
-
39
- ## STEP 2 — Ask the user which interface they prefer
40
-
41
- **Always ask this before starting work** (unless ~/.databar/config already contains
42
- `preferred_interface=`):
43
-
44
- "Databar has two interfaces:
45
- - **CLI** — terminal commands, great for single operations, pipeable JSON output,
46
- no code to write. Best for straightforward tasks.
47
- - **Python SDK** — import DatabarClient, full control, required for conditional
48
- logic (e.g. 'only enrich rows where email is verified') and multi-step pipelines
49
- with branching.
50
- - **Both** — use CLI for simple lookups, Python for complex workflows.
51
-
52
- Which do you prefer? (default: CLI)"
53
-
54
- Save their preference:
55
-
56
- ```bash
57
- # After they answer, append to config:
58
- echo "preferred_interface=cli" >> ~/.databar/config # or: python, both
59
- ```
60
-
61
- Default to CLI if they don't answer or say they don't mind.
62
-
63
- ---
64
-
65
- ## STEP 3 — Set up the CLI (IMPORTANT — read carefully)
66
-
67
- ### The PATH problem
68
-
69
- After `pip install databar`, the `databar` binary is installed to the Python
70
- user bin directory — but this directory is NOT on PATH by default on most systems.
71
-
72
- **Always check this first:**
73
-
74
- ```bash
75
- which databar # if this prints nothing, databar is not on PATH
76
- databar --version # if this says "command not found", fix PATH before continuing
77
- ```
78
-
79
- **If databar is not on PATH, fix it:**
80
-
81
- ```bash
82
- # Find where it's installed
83
- python3 -m site --user-base # e.g. /Users/alice/Library/Python/3.9
84
-
85
- # The binary is at <user-base>/bin/databar
86
- # Add to PATH for this session:
87
- export PATH="$(python3 -m site --user-base)/bin:$PATH"
88
-
89
- # Verify it works now:
90
- databar --version
91
- ```
92
-
93
- Tell the user to add that export line to their `~/.zshrc` or `~/.bashrc` to make
94
- it permanent. You can offer to do it:
95
-
96
- ```bash
97
- echo 'export PATH="$(python3 -m site --user-base)/bin:$PATH"' >> ~/.zshrc
98
- ```
99
-
100
- ### CLI vs Python — when to use each
101
-
102
- Use CLI when:
103
- - Running a single enrichment or waterfall on known inputs
104
- - Listing/searching enrichments, waterfalls, or tables
105
- - Creating tables, inserting rows from CSV or JSON
106
- - Running table enrichments
107
- - The task is straightforward with no branching logic
108
-
109
- Use Python SDK when:
110
- - You need to branch on results (e.g. only process rows where a field matches)
111
- - You're building a multi-step pipeline where step N depends on step N-1's output
112
- - You need to loop over results and make decisions per row
113
- - The task requires data transformation between steps
114
-
115
- ---
116
-
117
- ## CLI Quick Reference
118
-
119
- All commands support `--format table|json|csv` (default: table).
120
- **Always use `--format json` when you need to parse or pipe the output.**
121
- The default `table` format uses Rich terminal formatting that is not machine-parseable.
122
-
123
- ### Enrichments
124
- ```bash
125
- databar enrich list --format json # list all enrichments
126
- databar enrich list --query "email verifier" --format json # search
127
- databar enrich get <id> --format json # params + response fields
128
- databar enrich choices <id> <param> --format json # choices for a select param
129
- databar enrich run <id> --params '{"email": "a@b.com"}' --format json
130
- databar enrich bulk <id> --input data.csv --out results.csv
131
- ```
132
-
133
- ### Waterfalls
134
- ```bash
135
- databar waterfall list --format json
136
- databar waterfall get <identifier> --format json
137
- databar waterfall run <identifier> --params '{"linkedin_url": "..."}' --format json
138
- databar waterfall bulk <identifier> --input data.csv --out results.csv
139
- ```
140
-
141
- ### Tables
142
- ```bash
143
- databar table list --format json
144
- databar table create --name "My Table" --columns "email,name,company"
145
- databar table columns <table-uuid> --format json
146
- databar table rows <table-uuid> --format json
147
-
148
- databar table insert <table-uuid> --data '[{"email":"a@b.com"}]'
149
- databar table insert <table-uuid> --input data.csv --allow-new-columns
150
-
151
- databar table enrichments <table-uuid> --format json
152
- databar table add-enrichment <table-uuid> --enrichment-id <id> --mapping '{"param": "col_name"}'
153
- databar table run-enrichment <table-uuid> --enrichment-id <TABLE-ENRICHMENT-ID>
154
- ```
155
-
156
- IMPORTANT: `run-enrichment` takes the TABLE-ENRICHMENT ID (from `add-enrichment` output or
157
- `table enrichments`), NOT the catalog enrichment ID. These are different numbers.
158
-
159
- ### Tasks
160
- ```bash
161
- databar task get <task-id> --format json # check status once
162
- databar task get <task-id> --poll # poll until complete
163
- ```
164
-
165
- ---
166
-
167
- ## Python SDK Quick Reference
168
-
169
- ```python
170
- from databar import DatabarClient
171
-
172
- client = DatabarClient() # reads DATABAR_API_KEY or ~/.databar/config automatically
173
-
174
- # Enrichments
175
- enrichments = client.list_enrichments(q="email verifier")
176
- enrichment = client.get_enrichment(123)
177
- # enrichment.params[i].name → parameter slug (use as key in params dict)
178
- # enrichment.params[i].is_required → bool
179
- # enrichment.params[i].description → human label
180
- # enrichment.response_fields[i].name → output field name
181
-
182
- result = client.run_enrichment_sync(123, {"email": "alice@example.com"})
183
- # result["data"] contains the enrichment output
184
-
185
- # Waterfalls
186
- waterfalls = client.list_waterfalls()
187
- # waterfall.identifier (also .slug) → slug like "email_getter"
188
- result = client.run_waterfall_sync("email_getter", {"linkedin_url": "..."})
189
-
190
- # Tables
191
- tables = client.list_tables()
192
- # table.identifier (also .id, .uuid) → UUID string
193
-
194
- table = client.create_table(name="Leads", columns=["email", "name"])
195
- resp = client.get_rows(table.identifier)
196
- # resp.data → list of row dicts keyed by column name
197
- # resp.has_next_page → bool
198
- # resp.total_count → int
199
- # resp.page → int
200
-
201
- from databar import InsertRow
202
- client.create_rows(table.identifier, [
203
- InsertRow(fields={"email": "alice@example.com", "name": "Alice"}),
204
- ])
205
- ```
206
-
207
- ---
208
-
209
- ## Key Concepts
210
-
211
- - All enrichment/waterfall runs are async. The `*_sync` CLI and SDK methods handle
212
- submit + poll automatically. For manual polling use `task get --poll` or `poll_task()`.
213
- - `task_id` is the only task identifier. Results expire after 1 hour (status = "gone").
214
- - Table enrichments are two steps: add (links enrichment to table) → run (triggers execution).
215
- The ID returned by add is the TABLE-ENRICHMENT ID — different from the catalog ID.
216
- - The SDK auto-resolves column names to UUIDs in `add_enrichment()`.
217
-
218
- ## Model Field Aliases (Python SDK)
219
-
220
- - `Table`: `.id`, `.uuid` → `.identifier`
221
- - `Waterfall`: `.slug` → `.identifier`
222
- - `EnrichmentParam`: `.slug` → `.name`, `.label` → `.description`, `.required` → `.is_required`
223
- - `EnrichmentResponseField`: `.slug` → `.name`
224
-
225
- ## Error Handling (Python SDK)
226
-
227
- ```python
228
- from databar import (
229
- DatabarAuthError, # 401/403 — bad or missing API key
230
- DatabarInsufficientCreditsError, # 406 — not enough credits
231
- DatabarNotFoundError, # 404 — enrichment/table not found
232
- DatabarTaskFailedError, # task completed with error
233
- DatabarTimeoutError, # polling timed out
234
- DatabarGoneError, # task data expired (>1 hour)
235
- )
236
- ```
237
- """
File without changes
File without changes
File without changes
File without changes
File without changes