bigdata-smart-batching 1.2.1__tar.gz → 1.3.1__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.
- {bigdata_smart_batching-1.2.1 → bigdata_smart_batching-1.3.1}/CHANGELOG.md +13 -0
- {bigdata_smart_batching-1.2.1 → bigdata_smart_batching-1.3.1}/PKG-INFO +45 -2
- {bigdata_smart_batching-1.2.1 → bigdata_smart_batching-1.3.1}/README.md +44 -1
- {bigdata_smart_batching-1.2.1 → bigdata_smart_batching-1.3.1}/examples/example.py +4 -3
- bigdata_smart_batching-1.3.1/plan.json +20473 -0
- {bigdata_smart_batching-1.2.1 → bigdata_smart_batching-1.3.1}/pyproject.toml +1 -1
- {bigdata_smart_batching-1.2.1 → bigdata_smart_batching-1.3.1}/src/bigdata_smart_batching/__init__.py +8 -0
- {bigdata_smart_batching-1.2.1 → bigdata_smart_batching-1.3.1}/src/bigdata_smart_batching/search_function.py +98 -2
- {bigdata_smart_batching-1.2.1 → bigdata_smart_batching-1.3.1}/src/bigdata_smart_batching/smart_batching.py +23 -0
- {bigdata_smart_batching-1.2.1 → bigdata_smart_batching-1.3.1}/tests/test_validation.py +63 -0
- {bigdata_smart_batching-1.2.1 → bigdata_smart_batching-1.3.1}/uv.lock +1 -1
- {bigdata_smart_batching-1.2.1 → bigdata_smart_batching-1.3.1}/.gitignore +0 -0
- {bigdata_smart_batching-1.2.1 → bigdata_smart_batching-1.3.1}/LICENSE +0 -0
- {bigdata_smart_batching-1.2.1 → bigdata_smart_batching-1.3.1}/Makefile +0 -0
- {bigdata_smart_batching-1.2.1 → bigdata_smart_batching-1.3.1}/docs/smart-batching-architecture.md +0 -0
- {bigdata_smart_batching-1.2.1 → bigdata_smart_batching-1.3.1}/examples/example_overlapping.py +0 -0
- {bigdata_smart_batching-1.2.1 → bigdata_smart_batching-1.3.1}/src/bigdata_smart_batching/output_converter.py +0 -0
- {bigdata_smart_batching-1.2.1 → bigdata_smart_batching-1.3.1}/src/bigdata_smart_batching/smart_batching_config.py +0 -0
- {bigdata_smart_batching-1.2.1 → bigdata_smart_batching-1.3.1}/tests/__init__.py +0 -0
- {bigdata_smart_batching-1.2.1 → bigdata_smart_batching-1.3.1}/tests/test_config.py +0 -0
- {bigdata_smart_batching-1.2.1 → bigdata_smart_batching-1.3.1}/tests/test_output_converter.py +0 -0
- {bigdata_smart_batching-1.2.1 → bigdata_smart_batching-1.3.1}/tests/test_rate_limiter.py +0 -0
|
@@ -5,6 +5,19 @@ All notable changes to this project are documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
|
|
9
|
+
## [1.3.1] - 2026-05-18
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Document-level **source** filters: `INCLUDE` / `EXCLUDE` with a non-empty list of source ID strings, validated with `validate_source_filter`, modeled as `SourceFilter` / `SourceFilterInput` with `SourceMode` (type alias of `CategoryMode`). Serialized to `query.filters.source` on co-mention, volume, and search payloads. `plan_search(..., source=...)` and `source_filter` plumbed through `SmartBatchingPlanner` co-mention and volume flows. Payload builders `build_comention_payload`, `build_volume_payload`, and `build_search_query` accept optional `source_filter`. Types and validator re-exported from the package root.
|
|
14
|
+
|
|
15
|
+
## [1.3.0] - 2026-05-12
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- Document-level **source** filters: `INCLUDE` / `EXCLUDE` with a non-empty list of source ID strings, validated with `validate_source_filter`, modeled as `SourceFilter` / `SourceFilterInput` with `SourceMode` (type alias of `CategoryMode`). Serialized to `query.filters.source` on co-mention, volume, and search payloads. `plan_search(..., source=...)` and `source_filter` plumbed through `SmartBatchingPlanner` co-mention and volume flows. Payload builders `build_comention_payload`, `build_volume_payload`, and `build_search_query` accept optional `source_filter`. Types and validator re-exported from the package root.
|
|
20
|
+
|
|
8
21
|
## [1.2.1] - 2026-05-12
|
|
9
22
|
|
|
10
23
|
### Fixed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bigdata-smart-batching
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.1
|
|
4
4
|
Summary: High-performance semantic search with intelligent company grouping and parallel execution
|
|
5
5
|
Project-URL: homepage, https://bigdata.com/api
|
|
6
6
|
Author-email: "Bigdata.com" <support@ravenpack.com>
|
|
@@ -29,6 +29,7 @@ This module provides a two-step pipeline for efficient semantic search:
|
|
|
29
29
|
- **Parallel execution** -- rate-limited concurrent requests with semaphore-controlled concurrency.
|
|
30
30
|
- **Proportional sampling** -- retrieve a percentage of results while preserving the distribution across baskets.
|
|
31
31
|
- **Category filtering** -- restrict searches to specific document categories (news, transcripts, filings, ...).
|
|
32
|
+
- **Source filtering** -- include or exclude documents by source identifiers (`INCLUDE` / `EXCLUDE` plus a list of source IDs).
|
|
32
33
|
- **Sentiment filtering** -- restrict searches to one or more inclusive document-level sentiment ranges.
|
|
33
34
|
- **Throughput controls** -- shared sliding-window rate limiter and concurrency semaphore across all planning HTTP work, with shared exponential backoff on `429` / `403` / timeout retries.
|
|
34
35
|
- **Deterministic plans** -- every request stays within service limits; plans can be saved and replayed.
|
|
@@ -164,6 +165,43 @@ Valid category values are exposed via `VALID_CATEGORY_VALUES` and include:
|
|
|
164
165
|
`news_public`, `podcasts`, `research`, `research_academic_journals`,
|
|
165
166
|
`research_investment_research`, `transcripts`.
|
|
166
167
|
|
|
168
|
+
### Source Filtering
|
|
169
|
+
|
|
170
|
+
Restrict searches by **source** (document source IDs) using the `source` argument.
|
|
171
|
+
It accepts either a `SourceFilter` dataclass or a plain dict with `mode`
|
|
172
|
+
(`INCLUDE` or `EXCLUDE`) and `values` (a non-empty list of source ID strings).
|
|
173
|
+
The filter is serialized to `query.filters.source` on co-mention, volume, and
|
|
174
|
+
search payloads during planning.
|
|
175
|
+
|
|
176
|
+
```python
|
|
177
|
+
from bigdata_smart_batching import SourceFilter, SourceMode, plan_search
|
|
178
|
+
|
|
179
|
+
plan = plan_search(
|
|
180
|
+
universe="id_name_mapping_us_top_3000.csv",
|
|
181
|
+
start_date="2023-01-01",
|
|
182
|
+
end_date="2023-12-31",
|
|
183
|
+
text="merger acquisition",
|
|
184
|
+
source=SourceFilter(
|
|
185
|
+
mode=SourceMode.INCLUDE,
|
|
186
|
+
values=("source-id-1", "source-id-2"),
|
|
187
|
+
),
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
# Equivalent dict form:
|
|
191
|
+
plan = plan_search(
|
|
192
|
+
universe="id_name_mapping_us_top_3000.csv",
|
|
193
|
+
start_date="2023-01-01",
|
|
194
|
+
end_date="2023-12-31",
|
|
195
|
+
text="merger acquisition",
|
|
196
|
+
source={"mode": "EXCLUDE", "values": ["source-id-to-drop"]},
|
|
197
|
+
)
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
`SourceMode` is the same `INCLUDE` / `EXCLUDE` enum as `CategoryMode`. String
|
|
201
|
+
values are trimmed; empty strings are rejected. Use
|
|
202
|
+
`validate_source_filter(source)` to validate and normalize input into the API
|
|
203
|
+
dict shape.
|
|
204
|
+
|
|
167
205
|
### Sentiment Filtering
|
|
168
206
|
|
|
169
207
|
Restrict searches to documents whose sentiment falls inside one or more
|
|
@@ -263,6 +301,7 @@ Step 2: EXECUTION
|
|
|
263
301
|
| `min_period_days` | `int` | `30` | Minimum days per sub-period |
|
|
264
302
|
| `min_entities_per_basket` | `int` | `1` | Lower bound on entities per basket |
|
|
265
303
|
| `category` | `CategoryFilter \| dict \| None` | `None` | Optional category filter (`mode` + `values`) |
|
|
304
|
+
| `source` | `SourceFilter \| dict \| None` | `None` | Optional source filter by source IDs (`mode` + `values`) |
|
|
266
305
|
| `sentiment` | `SentimentRange \| dict \| list \| None` | `None` | Optional sentiment filter: one inclusive `{min, max}` range or a list of disjoint ranges |
|
|
267
306
|
| `content_diversification` | `bool` | `True` | Enable/disable content diversification in ranking |
|
|
268
307
|
| `requests_per_minute` | `int` | `100` | Global rate limit shared across all planning HTTP work (co-mention + volume) |
|
|
@@ -289,14 +328,18 @@ Step 2: EXECUTION
|
|
|
289
328
|
- `load_universe_from_csv(csv_path)` -- load entity IDs from a CSV only.
|
|
290
329
|
- `save_plan(plan, path)` / `load_plan(path)` -- persist plans as JSON.
|
|
291
330
|
- `validate_category_filter(category)` -- validate and normalize a category filter to the API dict shape.
|
|
331
|
+
- `validate_source_filter(source)` -- validate and normalize a source filter to the API dict shape (`filters.source`).
|
|
292
332
|
- `validate_sentiment_range(sentiment)` -- validate and normalize sentiment range(s) into the list-of-`{min, max}` dicts emitted as `filters.sentiment.ranges`.
|
|
293
|
-
- `build_comention_payload(...)`, `build_volume_payload(...)`, `build_search_query(...)` -- low-level payload builders used by the planner;
|
|
333
|
+
- `build_comention_payload(...)`, `build_volume_payload(...)`, `build_search_query(...)` -- low-level payload builders used by the planner; each accepts optional `category_filter`, `source_filter`, and `sentiment_filter` alongside entities and dates. Useful if you need to construct custom requests.
|
|
294
334
|
|
|
295
335
|
### Public Types
|
|
296
336
|
|
|
297
337
|
- `CategoryFilter` -- frozen dataclass with `mode: CategoryMode` and `values: tuple[str, ...]`.
|
|
298
338
|
- `CategoryMode` -- `StrEnum` with `INCLUDE` and `EXCLUDE` values.
|
|
299
339
|
- `CategoryFilterInput` -- type alias: `CategoryFilter | dict[str, str | list[str]]`.
|
|
340
|
+
- `SourceFilter` -- frozen dataclass with `mode: SourceMode` and `values: tuple[str, ...]` (source IDs).
|
|
341
|
+
- `SourceMode` -- type alias of `CategoryMode` (`INCLUDE`, `EXCLUDE`).
|
|
342
|
+
- `SourceFilterInput` -- type alias: `SourceFilter | dict[str, str | list[str]]`.
|
|
300
343
|
- `SentimentRange` -- frozen dataclass with inclusive `min: float` and `max: float`.
|
|
301
344
|
- `SentimentRangeInput` -- type alias for one `SentimentRange` / `{min, max}` dict, or a non-empty list of either.
|
|
302
345
|
- `UniverseInput` -- type alias: `str | list[str]`.
|
|
@@ -13,6 +13,7 @@ This module provides a two-step pipeline for efficient semantic search:
|
|
|
13
13
|
- **Parallel execution** -- rate-limited concurrent requests with semaphore-controlled concurrency.
|
|
14
14
|
- **Proportional sampling** -- retrieve a percentage of results while preserving the distribution across baskets.
|
|
15
15
|
- **Category filtering** -- restrict searches to specific document categories (news, transcripts, filings, ...).
|
|
16
|
+
- **Source filtering** -- include or exclude documents by source identifiers (`INCLUDE` / `EXCLUDE` plus a list of source IDs).
|
|
16
17
|
- **Sentiment filtering** -- restrict searches to one or more inclusive document-level sentiment ranges.
|
|
17
18
|
- **Throughput controls** -- shared sliding-window rate limiter and concurrency semaphore across all planning HTTP work, with shared exponential backoff on `429` / `403` / timeout retries.
|
|
18
19
|
- **Deterministic plans** -- every request stays within service limits; plans can be saved and replayed.
|
|
@@ -148,6 +149,43 @@ Valid category values are exposed via `VALID_CATEGORY_VALUES` and include:
|
|
|
148
149
|
`news_public`, `podcasts`, `research`, `research_academic_journals`,
|
|
149
150
|
`research_investment_research`, `transcripts`.
|
|
150
151
|
|
|
152
|
+
### Source Filtering
|
|
153
|
+
|
|
154
|
+
Restrict searches by **source** (document source IDs) using the `source` argument.
|
|
155
|
+
It accepts either a `SourceFilter` dataclass or a plain dict with `mode`
|
|
156
|
+
(`INCLUDE` or `EXCLUDE`) and `values` (a non-empty list of source ID strings).
|
|
157
|
+
The filter is serialized to `query.filters.source` on co-mention, volume, and
|
|
158
|
+
search payloads during planning.
|
|
159
|
+
|
|
160
|
+
```python
|
|
161
|
+
from bigdata_smart_batching import SourceFilter, SourceMode, plan_search
|
|
162
|
+
|
|
163
|
+
plan = plan_search(
|
|
164
|
+
universe="id_name_mapping_us_top_3000.csv",
|
|
165
|
+
start_date="2023-01-01",
|
|
166
|
+
end_date="2023-12-31",
|
|
167
|
+
text="merger acquisition",
|
|
168
|
+
source=SourceFilter(
|
|
169
|
+
mode=SourceMode.INCLUDE,
|
|
170
|
+
values=("source-id-1", "source-id-2"),
|
|
171
|
+
),
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
# Equivalent dict form:
|
|
175
|
+
plan = plan_search(
|
|
176
|
+
universe="id_name_mapping_us_top_3000.csv",
|
|
177
|
+
start_date="2023-01-01",
|
|
178
|
+
end_date="2023-12-31",
|
|
179
|
+
text="merger acquisition",
|
|
180
|
+
source={"mode": "EXCLUDE", "values": ["source-id-to-drop"]},
|
|
181
|
+
)
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
`SourceMode` is the same `INCLUDE` / `EXCLUDE` enum as `CategoryMode`. String
|
|
185
|
+
values are trimmed; empty strings are rejected. Use
|
|
186
|
+
`validate_source_filter(source)` to validate and normalize input into the API
|
|
187
|
+
dict shape.
|
|
188
|
+
|
|
151
189
|
### Sentiment Filtering
|
|
152
190
|
|
|
153
191
|
Restrict searches to documents whose sentiment falls inside one or more
|
|
@@ -247,6 +285,7 @@ Step 2: EXECUTION
|
|
|
247
285
|
| `min_period_days` | `int` | `30` | Minimum days per sub-period |
|
|
248
286
|
| `min_entities_per_basket` | `int` | `1` | Lower bound on entities per basket |
|
|
249
287
|
| `category` | `CategoryFilter \| dict \| None` | `None` | Optional category filter (`mode` + `values`) |
|
|
288
|
+
| `source` | `SourceFilter \| dict \| None` | `None` | Optional source filter by source IDs (`mode` + `values`) |
|
|
250
289
|
| `sentiment` | `SentimentRange \| dict \| list \| None` | `None` | Optional sentiment filter: one inclusive `{min, max}` range or a list of disjoint ranges |
|
|
251
290
|
| `content_diversification` | `bool` | `True` | Enable/disable content diversification in ranking |
|
|
252
291
|
| `requests_per_minute` | `int` | `100` | Global rate limit shared across all planning HTTP work (co-mention + volume) |
|
|
@@ -273,14 +312,18 @@ Step 2: EXECUTION
|
|
|
273
312
|
- `load_universe_from_csv(csv_path)` -- load entity IDs from a CSV only.
|
|
274
313
|
- `save_plan(plan, path)` / `load_plan(path)` -- persist plans as JSON.
|
|
275
314
|
- `validate_category_filter(category)` -- validate and normalize a category filter to the API dict shape.
|
|
315
|
+
- `validate_source_filter(source)` -- validate and normalize a source filter to the API dict shape (`filters.source`).
|
|
276
316
|
- `validate_sentiment_range(sentiment)` -- validate and normalize sentiment range(s) into the list-of-`{min, max}` dicts emitted as `filters.sentiment.ranges`.
|
|
277
|
-
- `build_comention_payload(...)`, `build_volume_payload(...)`, `build_search_query(...)` -- low-level payload builders used by the planner;
|
|
317
|
+
- `build_comention_payload(...)`, `build_volume_payload(...)`, `build_search_query(...)` -- low-level payload builders used by the planner; each accepts optional `category_filter`, `source_filter`, and `sentiment_filter` alongside entities and dates. Useful if you need to construct custom requests.
|
|
278
318
|
|
|
279
319
|
### Public Types
|
|
280
320
|
|
|
281
321
|
- `CategoryFilter` -- frozen dataclass with `mode: CategoryMode` and `values: tuple[str, ...]`.
|
|
282
322
|
- `CategoryMode` -- `StrEnum` with `INCLUDE` and `EXCLUDE` values.
|
|
283
323
|
- `CategoryFilterInput` -- type alias: `CategoryFilter | dict[str, str | list[str]]`.
|
|
324
|
+
- `SourceFilter` -- frozen dataclass with `mode: SourceMode` and `values: tuple[str, ...]` (source IDs).
|
|
325
|
+
- `SourceMode` -- type alias of `CategoryMode` (`INCLUDE`, `EXCLUDE`).
|
|
326
|
+
- `SourceFilterInput` -- type alias: `SourceFilter | dict[str, str | list[str]]`.
|
|
284
327
|
- `SentimentRange` -- frozen dataclass with inclusive `min: float` and `max: float`.
|
|
285
328
|
- `SentimentRangeInput` -- type alias for one `SentimentRange` / `{min, max}` dict, or a non-empty list of either.
|
|
286
329
|
- `UniverseInput` -- type alias: `str | list[str]`.
|
|
@@ -67,6 +67,7 @@ def main() -> None:
|
|
|
67
67
|
# Optional: filter by category to restrict document sources.
|
|
68
68
|
# Accepts a CategoryFilter instance or a plain dict:
|
|
69
69
|
category={"mode": "INCLUDE", "values": ["news_premium"]},
|
|
70
|
+
source={"mode": "INCLUDE", "values": ["5A5702"]},
|
|
70
71
|
content_diversification=False,
|
|
71
72
|
sentiment=[{"min": -1, "max": -0.5},{"min": 0.5, "max": 1}],
|
|
72
73
|
)
|
|
@@ -80,12 +81,12 @@ def main() -> None:
|
|
|
80
81
|
print(f"Plan execution time: {plan_elapsed_s:.3f}s")
|
|
81
82
|
|
|
82
83
|
# Step 2: Execute search with 10% of total chunks (preserves distribution)
|
|
83
|
-
if
|
|
84
|
+
if True:
|
|
84
85
|
search_t0 = time.perf_counter()
|
|
85
86
|
results_raw = execute_search(
|
|
86
87
|
search_plan=plan,
|
|
87
|
-
chunk_percentage=1,
|
|
88
|
-
requests_per_minute=
|
|
88
|
+
chunk_percentage=0.1,
|
|
89
|
+
requests_per_minute=450,
|
|
89
90
|
)
|
|
90
91
|
search_elapsed_s = time.perf_counter() - search_t0
|
|
91
92
|
print(f"Search execution time: {search_elapsed_s:.3f}s")
|