databar 2.0.9__tar.gz → 2.2.0__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 (31) hide show
  1. {databar-2.0.9/src/databar.egg-info → databar-2.2.0}/PKG-INFO +163 -12
  2. {databar-2.0.9 → databar-2.2.0}/README.md +162 -11
  3. {databar-2.0.9 → databar-2.2.0}/pyproject.toml +1 -1
  4. {databar-2.0.9 → databar-2.2.0}/src/databar/__init__.py +94 -18
  5. {databar-2.0.9 → databar-2.2.0}/src/databar/cli/_guide.py +18 -0
  6. {databar-2.0.9 → databar-2.2.0}/src/databar/cli/app.py +2 -1
  7. databar-2.2.0/src/databar/cli/flows.py +122 -0
  8. databar-2.2.0/src/databar/client.py +1149 -0
  9. {databar-2.0.9 → databar-2.2.0}/src/databar/exceptions.py +1 -1
  10. databar-2.2.0/src/databar/models.py +777 -0
  11. {databar-2.0.9 → databar-2.2.0/src/databar.egg-info}/PKG-INFO +163 -12
  12. {databar-2.0.9 → databar-2.2.0}/src/databar.egg-info/SOURCES.txt +3 -1
  13. {databar-2.0.9 → databar-2.2.0}/tests/test_cli.py +45 -1
  14. {databar-2.0.9 → databar-2.2.0}/tests/test_client.py +38 -0
  15. databar-2.2.0/tests/test_new_features.py +489 -0
  16. databar-2.0.9/src/databar/client.py +0 -626
  17. databar-2.0.9/src/databar/models.py +0 -414
  18. {databar-2.0.9 → databar-2.2.0}/LICENSE +0 -0
  19. {databar-2.0.9 → databar-2.2.0}/setup.cfg +0 -0
  20. {databar-2.0.9 → databar-2.2.0}/src/databar/cli/__init__.py +0 -0
  21. {databar-2.0.9 → databar-2.2.0}/src/databar/cli/_auth.py +0 -0
  22. {databar-2.0.9 → databar-2.2.0}/src/databar/cli/_onboard.py +0 -0
  23. {databar-2.0.9 → databar-2.2.0}/src/databar/cli/_output.py +0 -0
  24. {databar-2.0.9 → databar-2.2.0}/src/databar/cli/enrichments.py +0 -0
  25. {databar-2.0.9 → databar-2.2.0}/src/databar/cli/tables.py +0 -0
  26. {databar-2.0.9 → databar-2.2.0}/src/databar/cli/tasks.py +0 -0
  27. {databar-2.0.9 → databar-2.2.0}/src/databar/cli/waterfalls.py +0 -0
  28. {databar-2.0.9 → databar-2.2.0}/src/databar.egg-info/dependency_links.txt +0 -0
  29. {databar-2.0.9 → databar-2.2.0}/src/databar.egg-info/entry_points.txt +0 -0
  30. {databar-2.0.9 → databar-2.2.0}/src/databar.egg-info/requires.txt +0 -0
  31. {databar-2.0.9 → databar-2.2.0}/src/databar.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: databar
3
- Version: 2.0.9
3
+ Version: 2.2.0
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
@@ -55,7 +55,7 @@ Dynamic: license-file
55
55
 
56
56
  # Databar Python SDK
57
57
 
58
- Official Python SDK and CLI for [Databar.ai](https://databar.ai) — run data enrichments, waterfall lookups, and manage tables via `api.databar.ai/v1`.
58
+ Official Python SDK and CLI for [Databar.ai](https://databar.ai) — run data enrichments, waterfall lookups, flows, and manage tables via `api.databar.ai/v1`.
59
59
 
60
60
  [![PyPI](https://img.shields.io/pypi/v/databar-ai)](https://pypi.org/project/databar-ai/)
61
61
  [![Python](https://img.shields.io/pypi/pyversions/databar-ai)](https://pypi.org/project/databar-ai/)
@@ -132,6 +132,13 @@ enrichments = client.list_enrichments()
132
132
  # Search enrichments
133
133
  enrichments = client.list_enrichments(q="phone")
134
134
 
135
+ # Paginated list (returns EnrichmentListResponse)
136
+ page = client.list_enrichments(page=1, limit=50, category="Company Data")
137
+ for e in page.items:
138
+ print(f" [{e.id}] {e.name} — {e.price} credits")
139
+ if page.has_next_page:
140
+ page2 = client.list_enrichments(page=2, limit=50)
141
+
135
142
  # Get full details (params, response fields)
136
143
  enrichment = client.get_enrichment(123)
137
144
  for param in enrichment.params:
@@ -144,7 +151,11 @@ data = client.poll_task(task.task_id)
144
151
  # Run single enrichment (sync convenience wrapper)
145
152
  data = client.run_enrichment_sync(123, {"email": "alice@example.com"})
146
153
 
147
- # Bulk run
154
+ # Run with pagination (for list-style enrichments)
155
+ data = client.run_enrichment_sync(123, {"query": "CEO"}, pages=3)
156
+
157
+ # Bulk run — results are aligned to inputs: one element per input, in input
158
+ # order, with None for inputs that returned no data (len(data) == len(inputs)).
148
159
  data = client.run_enrichment_bulk_sync(123, [
149
160
  {"email": "alice@example.com"},
150
161
  {"email": "bob@example.com"},
@@ -182,20 +193,48 @@ results = client.run_waterfall_bulk_sync(
182
193
  )
183
194
  ```
184
195
 
196
+ ### Flows
197
+
198
+ ```python
199
+ # List saved flows
200
+ flows = client.list_flows()
201
+
202
+ # Inspect a flow's declared inputs
203
+ flow = client.get_flow("flow-uuid")
204
+ for inp in flow.inputs:
205
+ print(f" {inp.id} (required={inp.required}): {inp.description}")
206
+
207
+ # Run a flow (submit + poll in one call).
208
+ # inputs maps each flow input id → value.
209
+ result = client.run_flow_sync("flow-uuid", {"email": "alice@example.com"})
210
+
211
+ # Or submit and poll manually
212
+ task = client.run_flow("flow-uuid", {"email": "alice@example.com"})
213
+ result = client.poll_task(task.task_id)
214
+ ```
215
+
185
216
  ### Tables
186
217
 
187
218
  ```python
188
- # List tables
219
+ # List and manage tables
189
220
  tables = client.list_tables()
190
-
191
- # Create a table
192
221
  table = client.create_table(name="My Leads", columns=["email", "name", "company"])
222
+ client.rename_table(table.identifier, "Leads 2026")
223
+ client.delete_table(table.identifier)
193
224
 
194
- # Get columns
225
+ # Columns
195
226
  columns = client.get_columns(table.identifier)
227
+ col = client.create_column(table.identifier, "Phone", type="text")
228
+ client.rename_column(table.identifier, col.identifier, "Mobile")
229
+ client.delete_column(table.identifier, col.identifier)
196
230
 
197
- # Get rows (paginated)
231
+ # Get rows with optional server-side filter
232
+ import json
198
233
  data = client.get_rows(table.identifier, page=1, per_page=500)
234
+ filtered = client.get_rows(
235
+ table.identifier,
236
+ filter=json.dumps({"company": {"contains": "OpenAI"}}),
237
+ )
199
238
 
200
239
  # Insert rows (auto-batched at 50)
201
240
  from databar import InsertRow, InsertOptions, DedupeOptions
@@ -213,15 +252,112 @@ print(f"Created: {len([r for r in response.results if r.action == 'created'])}")
213
252
 
214
253
  # Update rows by UUID
215
254
  from databar import BatchUpdateRow
216
-
217
255
  rows = [BatchUpdateRow(id=row_id, fields={"name": "Updated Name"})]
218
- response = client.patch_rows(table.identifier, rows)
256
+ client.patch_rows(table.identifier, rows)
219
257
 
220
258
  # Upsert rows by key column
221
259
  from databar import UpsertRow
222
-
223
260
  rows = [UpsertRow(key={"email": "alice@example.com"}, fields={"name": "Alice"})]
224
- response = client.upsert_rows(table.identifier, rows)
261
+ client.upsert_rows(table.identifier, rows)
262
+
263
+ # Delete specific rows
264
+ client.delete_rows(table.identifier, ["row-uuid-1", "row-uuid-2"])
265
+ ```
266
+
267
+ ### Enrichments on tables
268
+
269
+ ```python
270
+ # Add an enrichment (with column mapping)
271
+ result = client.add_enrichment(
272
+ table.identifier,
273
+ enrichment_id=123,
274
+ mapping={
275
+ "email": {"type": "mapping", "value": "email_col"}, # from column
276
+ "country": {"type": "simple", "value": "US"}, # static value
277
+ },
278
+ launch_strategy="run_on_click", # or "run_on_update"
279
+ )
280
+ print(f"Added enrichment #{result.id}: {result.enrichment_name}")
281
+
282
+ # Run it (run_strategy: run_all | run_empty | run_errors)
283
+ status = client.run_table_enrichment(
284
+ table.identifier,
285
+ enrichment_id=str(result.id),
286
+ run_strategy="run_empty",
287
+ )
288
+ print(f"Processing {status.processing_rows} rows")
289
+ ```
290
+
291
+ ### Waterfalls on tables
292
+
293
+ ```python
294
+ # Add a waterfall
295
+ wf = client.add_waterfall(
296
+ table.identifier,
297
+ waterfall_identifier="email_getter",
298
+ enrichments=[833, 966],
299
+ mapping={"first_name": "first_name", "company": "company"},
300
+ email_verifier=10,
301
+ )
302
+ print(f"Added waterfall #{wf.id}: {wf.waterfall_name}")
303
+
304
+ # List installed waterfalls
305
+ installed = client.get_table_waterfalls(table.identifier)
306
+
307
+ # Run the waterfall
308
+ client.run_table_enrichment(table.identifier, enrichment_id=str(wf.id))
309
+ ```
310
+
311
+ ### Exporters
312
+
313
+ ```python
314
+ # List available exporters
315
+ exporters = client.list_exporters() # plain list
316
+ page = client.list_exporters(page=1, limit=50) # paginated envelope
317
+
318
+ # Get exporter details (params, authorization info)
319
+ detail = client.get_exporter(exporters[0].id)
320
+ print(detail.params, detail.authorization.required)
321
+
322
+ # Add an exporter to a table
323
+ result = client.add_exporter(
324
+ table.identifier,
325
+ exporter_id=detail.id,
326
+ mapping={"email": {"type": "mapping", "value": "email_col"}},
327
+ )
328
+ client.run_table_enrichment(table.identifier, enrichment_id=str(result.id))
329
+ ```
330
+
331
+ ### Connectors
332
+
333
+ ```python
334
+ # Create a custom HTTP API connector
335
+ connector = client.create_connector(
336
+ name="My Scoring API",
337
+ method="post",
338
+ url="https://api.example.com/v1/score",
339
+ headers=[{"name": "Authorization", "value": "Bearer sk-xxx"}],
340
+ body=[{"name": "domain", "value": ""}],
341
+ rate_limit=60,
342
+ )
343
+
344
+ # CRUD
345
+ connectors = client.list_connectors()
346
+ c = client.get_connector(connector.id)
347
+ client.update_connector(connector.id, name="Updated API", method="post", url="https://...")
348
+ client.delete_connector(connector.id)
349
+ ```
350
+
351
+ ### Folders
352
+
353
+ ```python
354
+ # Organize tables in folders
355
+ folder = client.create_folder("My Leads")
356
+ folders = client.list_folders()
357
+ client.rename_folder(folder.id, "Leads 2026")
358
+ client.move_table_to_folder(table.identifier, folder_id=folder.id)
359
+ client.move_table_to_folder(table.identifier) # remove from folder
360
+ client.delete_folder(folder.id) # tables move to root
225
361
  ```
226
362
 
227
363
  ### Error handling
@@ -312,6 +448,21 @@ databar waterfall run email_getter --params '{"linkedin_url": "https://linkedin.
312
448
  databar waterfall bulk email_getter --input leads.csv --out results.csv
313
449
  ```
314
450
 
451
+ ### Flows
452
+
453
+ ```bash
454
+ # List saved flows
455
+ databar flow list
456
+ databar flow list --query "buyer"
457
+
458
+ # Get flow details (declared inputs)
459
+ databar flow get <flow-id>
460
+
461
+ # Run a flow (--inputs maps each flow input id → value)
462
+ databar flow run <flow-id> --inputs '{"email": "alice@example.com"}'
463
+ databar flow run <flow-id> --inputs '{"email": "alice@example.com"}' --format json
464
+ ```
465
+
315
466
  ### Tables
316
467
 
317
468
  ```bash
@@ -1,6 +1,6 @@
1
1
  # Databar Python SDK
2
2
 
3
- Official Python SDK and CLI for [Databar.ai](https://databar.ai) — run data enrichments, waterfall lookups, and manage tables via `api.databar.ai/v1`.
3
+ Official Python SDK and CLI for [Databar.ai](https://databar.ai) — run data enrichments, waterfall lookups, flows, and manage tables via `api.databar.ai/v1`.
4
4
 
5
5
  [![PyPI](https://img.shields.io/pypi/v/databar-ai)](https://pypi.org/project/databar-ai/)
6
6
  [![Python](https://img.shields.io/pypi/pyversions/databar-ai)](https://pypi.org/project/databar-ai/)
@@ -77,6 +77,13 @@ enrichments = client.list_enrichments()
77
77
  # Search enrichments
78
78
  enrichments = client.list_enrichments(q="phone")
79
79
 
80
+ # Paginated list (returns EnrichmentListResponse)
81
+ page = client.list_enrichments(page=1, limit=50, category="Company Data")
82
+ for e in page.items:
83
+ print(f" [{e.id}] {e.name} — {e.price} credits")
84
+ if page.has_next_page:
85
+ page2 = client.list_enrichments(page=2, limit=50)
86
+
80
87
  # Get full details (params, response fields)
81
88
  enrichment = client.get_enrichment(123)
82
89
  for param in enrichment.params:
@@ -89,7 +96,11 @@ data = client.poll_task(task.task_id)
89
96
  # Run single enrichment (sync convenience wrapper)
90
97
  data = client.run_enrichment_sync(123, {"email": "alice@example.com"})
91
98
 
92
- # Bulk run
99
+ # Run with pagination (for list-style enrichments)
100
+ data = client.run_enrichment_sync(123, {"query": "CEO"}, pages=3)
101
+
102
+ # Bulk run — results are aligned to inputs: one element per input, in input
103
+ # order, with None for inputs that returned no data (len(data) == len(inputs)).
93
104
  data = client.run_enrichment_bulk_sync(123, [
94
105
  {"email": "alice@example.com"},
95
106
  {"email": "bob@example.com"},
@@ -127,20 +138,48 @@ results = client.run_waterfall_bulk_sync(
127
138
  )
128
139
  ```
129
140
 
141
+ ### Flows
142
+
143
+ ```python
144
+ # List saved flows
145
+ flows = client.list_flows()
146
+
147
+ # Inspect a flow's declared inputs
148
+ flow = client.get_flow("flow-uuid")
149
+ for inp in flow.inputs:
150
+ print(f" {inp.id} (required={inp.required}): {inp.description}")
151
+
152
+ # Run a flow (submit + poll in one call).
153
+ # inputs maps each flow input id → value.
154
+ result = client.run_flow_sync("flow-uuid", {"email": "alice@example.com"})
155
+
156
+ # Or submit and poll manually
157
+ task = client.run_flow("flow-uuid", {"email": "alice@example.com"})
158
+ result = client.poll_task(task.task_id)
159
+ ```
160
+
130
161
  ### Tables
131
162
 
132
163
  ```python
133
- # List tables
164
+ # List and manage tables
134
165
  tables = client.list_tables()
135
-
136
- # Create a table
137
166
  table = client.create_table(name="My Leads", columns=["email", "name", "company"])
167
+ client.rename_table(table.identifier, "Leads 2026")
168
+ client.delete_table(table.identifier)
138
169
 
139
- # Get columns
170
+ # Columns
140
171
  columns = client.get_columns(table.identifier)
172
+ col = client.create_column(table.identifier, "Phone", type="text")
173
+ client.rename_column(table.identifier, col.identifier, "Mobile")
174
+ client.delete_column(table.identifier, col.identifier)
141
175
 
142
- # Get rows (paginated)
176
+ # Get rows with optional server-side filter
177
+ import json
143
178
  data = client.get_rows(table.identifier, page=1, per_page=500)
179
+ filtered = client.get_rows(
180
+ table.identifier,
181
+ filter=json.dumps({"company": {"contains": "OpenAI"}}),
182
+ )
144
183
 
145
184
  # Insert rows (auto-batched at 50)
146
185
  from databar import InsertRow, InsertOptions, DedupeOptions
@@ -158,15 +197,112 @@ print(f"Created: {len([r for r in response.results if r.action == 'created'])}")
158
197
 
159
198
  # Update rows by UUID
160
199
  from databar import BatchUpdateRow
161
-
162
200
  rows = [BatchUpdateRow(id=row_id, fields={"name": "Updated Name"})]
163
- response = client.patch_rows(table.identifier, rows)
201
+ client.patch_rows(table.identifier, rows)
164
202
 
165
203
  # Upsert rows by key column
166
204
  from databar import UpsertRow
167
-
168
205
  rows = [UpsertRow(key={"email": "alice@example.com"}, fields={"name": "Alice"})]
169
- response = client.upsert_rows(table.identifier, rows)
206
+ client.upsert_rows(table.identifier, rows)
207
+
208
+ # Delete specific rows
209
+ client.delete_rows(table.identifier, ["row-uuid-1", "row-uuid-2"])
210
+ ```
211
+
212
+ ### Enrichments on tables
213
+
214
+ ```python
215
+ # Add an enrichment (with column mapping)
216
+ result = client.add_enrichment(
217
+ table.identifier,
218
+ enrichment_id=123,
219
+ mapping={
220
+ "email": {"type": "mapping", "value": "email_col"}, # from column
221
+ "country": {"type": "simple", "value": "US"}, # static value
222
+ },
223
+ launch_strategy="run_on_click", # or "run_on_update"
224
+ )
225
+ print(f"Added enrichment #{result.id}: {result.enrichment_name}")
226
+
227
+ # Run it (run_strategy: run_all | run_empty | run_errors)
228
+ status = client.run_table_enrichment(
229
+ table.identifier,
230
+ enrichment_id=str(result.id),
231
+ run_strategy="run_empty",
232
+ )
233
+ print(f"Processing {status.processing_rows} rows")
234
+ ```
235
+
236
+ ### Waterfalls on tables
237
+
238
+ ```python
239
+ # Add a waterfall
240
+ wf = client.add_waterfall(
241
+ table.identifier,
242
+ waterfall_identifier="email_getter",
243
+ enrichments=[833, 966],
244
+ mapping={"first_name": "first_name", "company": "company"},
245
+ email_verifier=10,
246
+ )
247
+ print(f"Added waterfall #{wf.id}: {wf.waterfall_name}")
248
+
249
+ # List installed waterfalls
250
+ installed = client.get_table_waterfalls(table.identifier)
251
+
252
+ # Run the waterfall
253
+ client.run_table_enrichment(table.identifier, enrichment_id=str(wf.id))
254
+ ```
255
+
256
+ ### Exporters
257
+
258
+ ```python
259
+ # List available exporters
260
+ exporters = client.list_exporters() # plain list
261
+ page = client.list_exporters(page=1, limit=50) # paginated envelope
262
+
263
+ # Get exporter details (params, authorization info)
264
+ detail = client.get_exporter(exporters[0].id)
265
+ print(detail.params, detail.authorization.required)
266
+
267
+ # Add an exporter to a table
268
+ result = client.add_exporter(
269
+ table.identifier,
270
+ exporter_id=detail.id,
271
+ mapping={"email": {"type": "mapping", "value": "email_col"}},
272
+ )
273
+ client.run_table_enrichment(table.identifier, enrichment_id=str(result.id))
274
+ ```
275
+
276
+ ### Connectors
277
+
278
+ ```python
279
+ # Create a custom HTTP API connector
280
+ connector = client.create_connector(
281
+ name="My Scoring API",
282
+ method="post",
283
+ url="https://api.example.com/v1/score",
284
+ headers=[{"name": "Authorization", "value": "Bearer sk-xxx"}],
285
+ body=[{"name": "domain", "value": ""}],
286
+ rate_limit=60,
287
+ )
288
+
289
+ # CRUD
290
+ connectors = client.list_connectors()
291
+ c = client.get_connector(connector.id)
292
+ client.update_connector(connector.id, name="Updated API", method="post", url="https://...")
293
+ client.delete_connector(connector.id)
294
+ ```
295
+
296
+ ### Folders
297
+
298
+ ```python
299
+ # Organize tables in folders
300
+ folder = client.create_folder("My Leads")
301
+ folders = client.list_folders()
302
+ client.rename_folder(folder.id, "Leads 2026")
303
+ client.move_table_to_folder(table.identifier, folder_id=folder.id)
304
+ client.move_table_to_folder(table.identifier) # remove from folder
305
+ client.delete_folder(folder.id) # tables move to root
170
306
  ```
171
307
 
172
308
  ### Error handling
@@ -257,6 +393,21 @@ databar waterfall run email_getter --params '{"linkedin_url": "https://linkedin.
257
393
  databar waterfall bulk email_getter --input leads.csv --out results.csv
258
394
  ```
259
395
 
396
+ ### Flows
397
+
398
+ ```bash
399
+ # List saved flows
400
+ databar flow list
401
+ databar flow list --query "buyer"
402
+
403
+ # Get flow details (declared inputs)
404
+ databar flow get <flow-id>
405
+
406
+ # Run a flow (--inputs maps each flow input id → value)
407
+ databar flow run <flow-id> --inputs '{"email": "alice@example.com"}'
408
+ databar flow run <flow-id> --inputs '{"email": "alice@example.com"}' --format json
409
+ ```
410
+
260
411
  ### Tables
261
412
 
262
413
  ```bash
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "databar"
7
- version = "2.0.9"
7
+ version = "2.2.0"
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" }
@@ -16,6 +16,11 @@ Quick start::
16
16
  # Work with tables
17
17
  tables = client.list_tables()
18
18
  rows = client.get_rows(tables[0].identifier)
19
+
20
+ # Manage exporters, connectors and folders
21
+ exporters = client.list_exporters()
22
+ folder = client.create_folder("My Leads")
23
+ client.move_table_to_folder(tables[0].identifier, folder.id)
19
24
  """
20
25
 
21
26
  from .client import DatabarClient
@@ -31,34 +36,70 @@ from .exceptions import (
31
36
  DatabarValidationError,
32
37
  )
33
38
  from .models import (
34
- BatchInsertResponse,
35
- BatchUpdateResponse,
36
- BatchUpdateRow,
39
+ # Pricing / Category
40
+ PricingInfo,
41
+ CategoryInfo,
42
+ # User
43
+ User,
44
+ # Enrichments
37
45
  ChoiceItem,
38
46
  Choices,
39
- ChoicesResponse,
40
- Column,
41
- DedupeOptions,
42
- Enrichment,
43
47
  EnrichmentParam,
44
48
  EnrichmentResponseField,
49
+ PaginationInfo,
50
+ PaginationOptions,
45
51
  EnrichmentSummary,
46
- InsertOptions,
47
- InsertRow,
48
- RowsResponse,
52
+ Enrichment,
53
+ EnrichmentListResponse,
54
+ ChoicesResponse,
55
+ # Tasks
49
56
  RunResponse,
50
- Table,
51
- TableEnrichment,
52
57
  TaskResponse,
53
58
  TaskStatus,
54
- UpsertResponse,
55
- UpsertRow,
56
- User,
59
+ # Waterfalls
57
60
  Waterfall,
58
61
  WaterfallEnrichment,
62
+ # Flows
63
+ Flow,
64
+ FlowInput,
65
+ FlowOutput,
66
+ # Tables
67
+ Table,
68
+ Column,
69
+ CreateColumnResponse,
70
+ TableEnrichment,
71
+ AddEnrichmentResponse,
72
+ AddWaterfallResponse,
73
+ InstalledWaterfall,
74
+ AddExporterResponse,
75
+ InstalledExporter,
76
+ RunEnrichmentResponse,
77
+ # Rows
78
+ RowsResponse,
79
+ InsertRow,
80
+ InsertOptions,
81
+ DedupeOptions,
82
+ BatchInsertResponse,
83
+ BatchUpdateRow,
84
+ BatchUpdateResponse,
85
+ UpsertRow,
86
+ UpsertResponse,
87
+ # Exporters
88
+ Exporter,
89
+ ExporterListResponse,
90
+ ExporterParam,
91
+ ExporterResponseField,
92
+ Connection,
93
+ AuthorizationInfo,
94
+ ExporterDetail,
95
+ # Connectors
96
+ NameValue,
97
+ Connector,
98
+ # Folders
99
+ Folder,
59
100
  )
60
101
 
61
- __version__ = "2.0.9"
102
+ __version__ = "2.2.0"
62
103
  __all__ = [
63
104
  "DatabarClient",
64
105
  # exceptions
@@ -71,23 +112,45 @@ __all__ = [
71
112
  "DatabarRateLimitError",
72
113
  "DatabarTaskFailedError",
73
114
  "DatabarTimeoutError",
74
- # models
115
+ # pricing / category
116
+ "PricingInfo",
117
+ "CategoryInfo",
118
+ # user
75
119
  "User",
76
- "Enrichment",
120
+ # enrichments
77
121
  "EnrichmentSummary",
122
+ "Enrichment",
123
+ "EnrichmentListResponse",
78
124
  "EnrichmentParam",
79
125
  "EnrichmentResponseField",
126
+ "PaginationInfo",
127
+ "PaginationOptions",
80
128
  "ChoiceItem",
81
129
  "Choices",
82
130
  "ChoicesResponse",
131
+ # tasks
83
132
  "RunResponse",
84
133
  "TaskResponse",
85
134
  "TaskStatus",
135
+ # waterfalls
86
136
  "Waterfall",
87
137
  "WaterfallEnrichment",
138
+ # flows
139
+ "Flow",
140
+ "FlowInput",
141
+ "FlowOutput",
142
+ # tables
88
143
  "Table",
89
144
  "Column",
145
+ "CreateColumnResponse",
90
146
  "TableEnrichment",
147
+ "AddEnrichmentResponse",
148
+ "AddWaterfallResponse",
149
+ "InstalledWaterfall",
150
+ "AddExporterResponse",
151
+ "InstalledExporter",
152
+ "RunEnrichmentResponse",
153
+ # rows
91
154
  "RowsResponse",
92
155
  "InsertRow",
93
156
  "InsertOptions",
@@ -97,4 +160,17 @@ __all__ = [
97
160
  "BatchUpdateResponse",
98
161
  "UpsertRow",
99
162
  "UpsertResponse",
163
+ # exporters
164
+ "Exporter",
165
+ "ExporterListResponse",
166
+ "ExporterParam",
167
+ "ExporterResponseField",
168
+ "Connection",
169
+ "AuthorizationInfo",
170
+ "ExporterDetail",
171
+ # connectors
172
+ "NameValue",
173
+ "Connector",
174
+ # folders
175
+ "Folder",
100
176
  ]
@@ -128,6 +128,16 @@ databar waterfall run <identifier> --params '{"key": "value"}' --format json
128
128
  databar waterfall bulk <identifier> --input data.csv --out results.csv
129
129
  ```
130
130
 
131
+ ### Flows
132
+ ```bash
133
+ databar flow list --format json
134
+ databar flow get <flow-id> --format json # declared inputs
135
+ databar flow run <flow-id> --inputs '{"input_id": "value"}' --format json
136
+ ```
137
+
138
+ NOTE: `flow run` uses `--inputs` (maps each flow input id → value), NOT `--params`.
139
+ See `flow get` for the list of declared inputs.
140
+
131
141
  ### Tables
132
142
  ```bash
133
143
  databar table list --format json
@@ -174,6 +184,13 @@ result = client.run_enrichment_sync(123, {"email": "alice@example.com"})
174
184
  result = client.run_waterfall_sync("email_getter", {"linkedin_url": "..."})
175
185
  # waterfall.identifier (also .slug) → slug like "email_getter"
176
186
 
187
+ # Flows
188
+ flows = client.list_flows()
189
+ flow = client.get_flow("flow-uuid")
190
+ # flow.id (also .identifier) → flow UUID
191
+ # flow.inputs[i].id → input key to use in the run inputs dict
192
+ result = client.run_flow_sync("flow-uuid", {"email": "alice@example.com"})
193
+
177
194
  # Tables
178
195
  tables = client.list_tables()
179
196
  # table.identifier (also .id, .uuid) → UUID string
@@ -201,6 +218,7 @@ client.create_rows(table.identifier, [InsertRow(fields={"email": "alice@example.
201
218
 
202
219
  - `Table`: `.id`, `.uuid` → `.identifier`
203
220
  - `Waterfall`: `.slug` → `.identifier`
221
+ - `Flow`: `.identifier` → `.id`
204
222
  - `EnrichmentParam`: `.slug` → `.name`, `.label` → `.description`, `.required` → `.is_required`
205
223
  - `EnrichmentResponseField`: `.slug` → `.name`
206
224
 
@@ -10,7 +10,7 @@ import typer
10
10
 
11
11
  from databar import __version__
12
12
 
13
- from . import enrichments, tables, tasks, waterfalls
13
+ from . import enrichments, flows, tables, tasks, waterfalls
14
14
  from ._auth import app as auth_app
15
15
 
16
16
  app = typer.Typer(
@@ -29,6 +29,7 @@ app.add_typer(auth_app, name=None) # merged at root level
29
29
  # Subcommand groups
30
30
  app.add_typer(enrichments.app, name="enrich")
31
31
  app.add_typer(waterfalls.app, name="waterfall")
32
+ app.add_typer(flows.app, name="flow")
32
33
  app.add_typer(tables.app, name="table")
33
34
  app.add_typer(tasks.app, name="task")
34
35