bigdata-smart-batching 1.2.0__tar.gz → 1.3.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.
- {bigdata_smart_batching-1.2.0 → bigdata_smart_batching-1.3.0}/CHANGELOG.md +12 -0
- {bigdata_smart_batching-1.2.0 → bigdata_smart_batching-1.3.0}/PKG-INFO +89 -3
- {bigdata_smart_batching-1.2.0 → bigdata_smart_batching-1.3.0}/README.md +88 -2
- {bigdata_smart_batching-1.2.0 → bigdata_smart_batching-1.3.0}/examples/example.py +4 -3
- bigdata_smart_batching-1.3.0/plan.json +20473 -0
- {bigdata_smart_batching-1.2.0 → bigdata_smart_batching-1.3.0}/pyproject.toml +1 -1
- {bigdata_smart_batching-1.2.0 → bigdata_smart_batching-1.3.0}/src/bigdata_smart_batching/__init__.py +8 -0
- {bigdata_smart_batching-1.2.0 → bigdata_smart_batching-1.3.0}/src/bigdata_smart_batching/search_function.py +94 -0
- {bigdata_smart_batching-1.2.0 → bigdata_smart_batching-1.3.0}/src/bigdata_smart_batching/smart_batching.py +23 -0
- {bigdata_smart_batching-1.2.0 → bigdata_smart_batching-1.3.0}/tests/test_validation.py +63 -0
- {bigdata_smart_batching-1.2.0 → bigdata_smart_batching-1.3.0}/uv.lock +1 -1
- {bigdata_smart_batching-1.2.0 → bigdata_smart_batching-1.3.0}/.gitignore +0 -0
- {bigdata_smart_batching-1.2.0 → bigdata_smart_batching-1.3.0}/LICENSE +0 -0
- {bigdata_smart_batching-1.2.0 → bigdata_smart_batching-1.3.0}/Makefile +0 -0
- {bigdata_smart_batching-1.2.0 → bigdata_smart_batching-1.3.0}/docs/smart-batching-architecture.md +0 -0
- {bigdata_smart_batching-1.2.0 → bigdata_smart_batching-1.3.0}/examples/example_overlapping.py +0 -0
- {bigdata_smart_batching-1.2.0 → bigdata_smart_batching-1.3.0}/src/bigdata_smart_batching/output_converter.py +0 -0
- {bigdata_smart_batching-1.2.0 → bigdata_smart_batching-1.3.0}/src/bigdata_smart_batching/smart_batching_config.py +0 -0
- {bigdata_smart_batching-1.2.0 → bigdata_smart_batching-1.3.0}/tests/__init__.py +0 -0
- {bigdata_smart_batching-1.2.0 → bigdata_smart_batching-1.3.0}/tests/test_config.py +0 -0
- {bigdata_smart_batching-1.2.0 → bigdata_smart_batching-1.3.0}/tests/test_output_converter.py +0 -0
- {bigdata_smart_batching-1.2.0 → bigdata_smart_batching-1.3.0}/tests/test_rate_limiter.py +0 -0
|
@@ -5,6 +5,18 @@ 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
|
+
## [1.3.0] - 2026-05-12
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- 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.
|
|
13
|
+
|
|
14
|
+
## [1.2.1] - 2026-05-12
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- Modified README.md file to add latest changes
|
|
19
|
+
|
|
8
20
|
## [1.2.0] - 2026-05-12
|
|
9
21
|
|
|
10
22
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bigdata-smart-batching
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.0
|
|
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,9 @@ 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).
|
|
33
|
+
- **Sentiment filtering** -- restrict searches to one or more inclusive document-level sentiment ranges.
|
|
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.
|
|
32
35
|
- **Deterministic plans** -- every request stays within service limits; plans can be saved and replayed.
|
|
33
36
|
- **Scalable** -- handles universes with 10,000+ companies efficiently.
|
|
34
37
|
|
|
@@ -162,6 +165,78 @@ Valid category values are exposed via `VALID_CATEGORY_VALUES` and include:
|
|
|
162
165
|
`news_public`, `podcasts`, `research`, `research_academic_journals`,
|
|
163
166
|
`research_investment_research`, `transcripts`.
|
|
164
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
|
+
|
|
205
|
+
### Sentiment Filtering
|
|
206
|
+
|
|
207
|
+
Restrict searches to documents whose sentiment falls inside one or more
|
|
208
|
+
inclusive `min` / `max` ranges using the `sentiment` argument. It accepts a
|
|
209
|
+
single `SentimentRange` / dict, or a list of them (multiple disjoint ranges).
|
|
210
|
+
The filter is emitted as `query.filters.sentiment.ranges` on co-mention,
|
|
211
|
+
volume, and search payloads.
|
|
212
|
+
|
|
213
|
+
```python
|
|
214
|
+
from bigdata_smart_batching import SentimentRange, plan_search
|
|
215
|
+
|
|
216
|
+
plan = plan_search(
|
|
217
|
+
universe="id_name_mapping_us_top_3000.csv",
|
|
218
|
+
start_date="2023-01-01",
|
|
219
|
+
end_date="2023-12-31",
|
|
220
|
+
text="earnings revenue profit",
|
|
221
|
+
sentiment=SentimentRange(min=0.3, max=1.0),
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
plan = plan_search(
|
|
225
|
+
universe="id_name_mapping_us_top_3000.csv",
|
|
226
|
+
start_date="2023-01-01",
|
|
227
|
+
end_date="2023-12-31",
|
|
228
|
+
text="earnings revenue profit",
|
|
229
|
+
sentiment=[
|
|
230
|
+
{"min": -1.0, "max": -0.5},
|
|
231
|
+
{"min": 0.5, "max": 1.0},
|
|
232
|
+
],
|
|
233
|
+
)
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Each range must satisfy `min <= max`. Use
|
|
237
|
+
`validate_sentiment_range(sentiment)` to validate and normalize input into the
|
|
238
|
+
list-of-dicts shape the API expects.
|
|
239
|
+
|
|
165
240
|
### Save and Load Plans
|
|
166
241
|
|
|
167
242
|
```python
|
|
@@ -226,7 +301,11 @@ Step 2: EXECUTION
|
|
|
226
301
|
| `min_period_days` | `int` | `30` | Minimum days per sub-period |
|
|
227
302
|
| `min_entities_per_basket` | `int` | `1` | Lower bound on entities per basket |
|
|
228
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`) |
|
|
305
|
+
| `sentiment` | `SentimentRange \| dict \| list \| None` | `None` | Optional sentiment filter: one inclusive `{min, max}` range or a list of disjoint ranges |
|
|
229
306
|
| `content_diversification` | `bool` | `True` | Enable/disable content diversification in ranking |
|
|
307
|
+
| `requests_per_minute` | `int` | `100` | Global rate limit shared across all planning HTTP work (co-mention + volume) |
|
|
308
|
+
| `max_workers` | `int` | `40` | Maximum concurrent in-flight planning requests (shared semaphore) |
|
|
230
309
|
|
|
231
310
|
### `execute_search()`
|
|
232
311
|
|
|
@@ -249,13 +328,20 @@ Step 2: EXECUTION
|
|
|
249
328
|
- `load_universe_from_csv(csv_path)` -- load entity IDs from a CSV only.
|
|
250
329
|
- `save_plan(plan, path)` / `load_plan(path)` -- persist plans as JSON.
|
|
251
330
|
- `validate_category_filter(category)` -- validate and normalize a category filter to the API dict shape.
|
|
252
|
-
- `
|
|
331
|
+
- `validate_source_filter(source)` -- validate and normalize a source filter to the API dict shape (`filters.source`).
|
|
332
|
+
- `validate_sentiment_range(sentiment)` -- validate and normalize sentiment range(s) into the list-of-`{min, max}` dicts emitted as `filters.sentiment.ranges`.
|
|
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.
|
|
253
334
|
|
|
254
335
|
### Public Types
|
|
255
336
|
|
|
256
337
|
- `CategoryFilter` -- frozen dataclass with `mode: CategoryMode` and `values: tuple[str, ...]`.
|
|
257
338
|
- `CategoryMode` -- `StrEnum` with `INCLUDE` and `EXCLUDE` values.
|
|
258
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]]`.
|
|
343
|
+
- `SentimentRange` -- frozen dataclass with inclusive `min: float` and `max: float`.
|
|
344
|
+
- `SentimentRangeInput` -- type alias for one `SentimentRange` / `{min, max}` dict, or a non-empty list of either.
|
|
259
345
|
- `UniverseInput` -- type alias: `str | list[str]`.
|
|
260
346
|
- `VALID_CATEGORY_VALUES` -- `frozenset[str]` of allowed category strings.
|
|
261
347
|
|
|
@@ -331,7 +417,7 @@ Ties are resolved using `VOLUME_BUCKET_PRIORITY`: `high > medium > low > very_lo
|
|
|
331
417
|
## Changelog
|
|
332
418
|
|
|
333
419
|
See [CHANGELOG.md](CHANGELOG.md) for release notes. The package is currently at
|
|
334
|
-
version **1.0
|
|
420
|
+
version **1.2.0**.
|
|
335
421
|
|
|
336
422
|
## License
|
|
337
423
|
|
|
@@ -13,6 +13,9 @@ 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).
|
|
17
|
+
- **Sentiment filtering** -- restrict searches to one or more inclusive document-level sentiment ranges.
|
|
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.
|
|
16
19
|
- **Deterministic plans** -- every request stays within service limits; plans can be saved and replayed.
|
|
17
20
|
- **Scalable** -- handles universes with 10,000+ companies efficiently.
|
|
18
21
|
|
|
@@ -146,6 +149,78 @@ Valid category values are exposed via `VALID_CATEGORY_VALUES` and include:
|
|
|
146
149
|
`news_public`, `podcasts`, `research`, `research_academic_journals`,
|
|
147
150
|
`research_investment_research`, `transcripts`.
|
|
148
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
|
+
|
|
189
|
+
### Sentiment Filtering
|
|
190
|
+
|
|
191
|
+
Restrict searches to documents whose sentiment falls inside one or more
|
|
192
|
+
inclusive `min` / `max` ranges using the `sentiment` argument. It accepts a
|
|
193
|
+
single `SentimentRange` / dict, or a list of them (multiple disjoint ranges).
|
|
194
|
+
The filter is emitted as `query.filters.sentiment.ranges` on co-mention,
|
|
195
|
+
volume, and search payloads.
|
|
196
|
+
|
|
197
|
+
```python
|
|
198
|
+
from bigdata_smart_batching import SentimentRange, plan_search
|
|
199
|
+
|
|
200
|
+
plan = plan_search(
|
|
201
|
+
universe="id_name_mapping_us_top_3000.csv",
|
|
202
|
+
start_date="2023-01-01",
|
|
203
|
+
end_date="2023-12-31",
|
|
204
|
+
text="earnings revenue profit",
|
|
205
|
+
sentiment=SentimentRange(min=0.3, max=1.0),
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
plan = plan_search(
|
|
209
|
+
universe="id_name_mapping_us_top_3000.csv",
|
|
210
|
+
start_date="2023-01-01",
|
|
211
|
+
end_date="2023-12-31",
|
|
212
|
+
text="earnings revenue profit",
|
|
213
|
+
sentiment=[
|
|
214
|
+
{"min": -1.0, "max": -0.5},
|
|
215
|
+
{"min": 0.5, "max": 1.0},
|
|
216
|
+
],
|
|
217
|
+
)
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
Each range must satisfy `min <= max`. Use
|
|
221
|
+
`validate_sentiment_range(sentiment)` to validate and normalize input into the
|
|
222
|
+
list-of-dicts shape the API expects.
|
|
223
|
+
|
|
149
224
|
### Save and Load Plans
|
|
150
225
|
|
|
151
226
|
```python
|
|
@@ -210,7 +285,11 @@ Step 2: EXECUTION
|
|
|
210
285
|
| `min_period_days` | `int` | `30` | Minimum days per sub-period |
|
|
211
286
|
| `min_entities_per_basket` | `int` | `1` | Lower bound on entities per basket |
|
|
212
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`) |
|
|
289
|
+
| `sentiment` | `SentimentRange \| dict \| list \| None` | `None` | Optional sentiment filter: one inclusive `{min, max}` range or a list of disjoint ranges |
|
|
213
290
|
| `content_diversification` | `bool` | `True` | Enable/disable content diversification in ranking |
|
|
291
|
+
| `requests_per_minute` | `int` | `100` | Global rate limit shared across all planning HTTP work (co-mention + volume) |
|
|
292
|
+
| `max_workers` | `int` | `40` | Maximum concurrent in-flight planning requests (shared semaphore) |
|
|
214
293
|
|
|
215
294
|
### `execute_search()`
|
|
216
295
|
|
|
@@ -233,13 +312,20 @@ Step 2: EXECUTION
|
|
|
233
312
|
- `load_universe_from_csv(csv_path)` -- load entity IDs from a CSV only.
|
|
234
313
|
- `save_plan(plan, path)` / `load_plan(path)` -- persist plans as JSON.
|
|
235
314
|
- `validate_category_filter(category)` -- validate and normalize a category filter to the API dict shape.
|
|
236
|
-
- `
|
|
315
|
+
- `validate_source_filter(source)` -- validate and normalize a source filter to the API dict shape (`filters.source`).
|
|
316
|
+
- `validate_sentiment_range(sentiment)` -- validate and normalize sentiment range(s) into the list-of-`{min, max}` dicts emitted as `filters.sentiment.ranges`.
|
|
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.
|
|
237
318
|
|
|
238
319
|
### Public Types
|
|
239
320
|
|
|
240
321
|
- `CategoryFilter` -- frozen dataclass with `mode: CategoryMode` and `values: tuple[str, ...]`.
|
|
241
322
|
- `CategoryMode` -- `StrEnum` with `INCLUDE` and `EXCLUDE` values.
|
|
242
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]]`.
|
|
327
|
+
- `SentimentRange` -- frozen dataclass with inclusive `min: float` and `max: float`.
|
|
328
|
+
- `SentimentRangeInput` -- type alias for one `SentimentRange` / `{min, max}` dict, or a non-empty list of either.
|
|
243
329
|
- `UniverseInput` -- type alias: `str | list[str]`.
|
|
244
330
|
- `VALID_CATEGORY_VALUES` -- `frozenset[str]` of allowed category strings.
|
|
245
331
|
|
|
@@ -315,7 +401,7 @@ Ties are resolved using `VOLUME_BUCKET_PRIORITY`: `high > medium > low > very_lo
|
|
|
315
401
|
## Changelog
|
|
316
402
|
|
|
317
403
|
See [CHANGELOG.md](CHANGELOG.md) for release notes. The package is currently at
|
|
318
|
-
version **1.0
|
|
404
|
+
version **1.2.0**.
|
|
319
405
|
|
|
320
406
|
## License
|
|
321
407
|
|
|
@@ -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")
|