impc-api 1.0.3__tar.gz → 1.0.4__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.
@@ -0,0 +1 @@
1
+ include impc_api/utils/core_fields.json
@@ -1,9 +1,10 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: impc_api
3
- Version: 1.0.3
4
- Summary: A package to facilitate making API request to the IMPC Solr API
3
+ Version: 1.0.4
4
+ Summary: A package to facilitate making API requests to the IMPC Solr API
5
5
  Home-page: https://github.com/mpi2/impc-data-api-workshop
6
6
  Author: MPI2, Marina Kan, Diego Pava
7
+ Project-URL: Homepage, https://github.com/mpi2/impc-data-api-workshop
7
8
  Requires-Python: >=3.10
8
9
  Description-Content-Type: text/markdown
9
10
  License-File: LICENSE
@@ -0,0 +1,194 @@
1
+ # IMPC_API
2
+
3
+ `impc_api` is a Python package.
4
+
5
+ The functions in this package are intended for use in a Jupyter Notebook.
6
+
7
+ ## Installation Instructions
8
+
9
+ 1. **Create a virtual environment (optional but recommended)**:
10
+ On Mac:
11
+ ```bash
12
+ python3 -m venv .venv
13
+ source .venv/bin/activate
14
+ ```
15
+
16
+ 2. **Install the package**: `pip install impc_api`
17
+ 3. **Install Jupyter**: `pip install jupyter`
18
+ 4. **Run the Jupyter Notebook**: `jupyter notebook`
19
+
20
+ After executing the command, the Jupyter interface should open in your browser. If it does not, follow the instructions provided in the terminal.
21
+
22
+ 5. **Try it out**:
23
+
24
+ Create a [Jupyter Notebook](https://jupyter-notebook.readthedocs.io/en/latest/) and try some of the examples below:
25
+
26
+ ## Available functions
27
+
28
+ The available functions can be imported as:
29
+
30
+ ```python
31
+ from impc_api import solr_request, batch_solr_request
32
+ ```
33
+
34
+ # 1. Solr request
35
+
36
+ The most basic request to the IMPC solr API
37
+
38
+ ```python
39
+ num_found, df = solr_request(
40
+ core='genotype-phenotype',
41
+ params={
42
+ 'q': '*:*',
43
+ 'rows': 10,
44
+ 'fl': 'marker_symbol,allele_symbol,parameter_stable_id'
45
+ }
46
+ )
47
+ ```
48
+
49
+ ## a. Facet request
50
+
51
+ `solr_request` allows facet requests
52
+
53
+ ```python
54
+ num_found, df = solr_request(
55
+ core="genotype-phenotype",
56
+ params={
57
+ "q": "*:*",
58
+ "rows": 0,
59
+ "facet": "on",
60
+ "facet.field": "zygosity",
61
+ "facet.limit": 15,
62
+ "facet.mincount": 1,
63
+ }
64
+ )
65
+ ```
66
+
67
+ ## b. Solr request validation
68
+
69
+ A common pitfall when writing a query is the misspelling of `core` and `fields` arguments. For this, we have included a `validate` argument that raises a warning when these values are not as expected. Note this does not prevent you from executing a query; it just alerts you to a potential issue.
70
+
71
+ ### Core validation
72
+
73
+ ```python
74
+ num_found, df = solr_request(
75
+ core='invalid_core',
76
+ params={
77
+ 'q': '*:*',
78
+ 'rows': 10
79
+ },
80
+ validate=True
81
+ )
82
+
83
+ > InvalidCoreWarning: Invalid core: "genotype-phenotyp", select from the available cores:
84
+ > dict_keys(['experiment', 'genotype-phenotype', 'impc_images', 'phenodigm', 'statistical-result'])
85
+ ```
86
+
87
+ ### Field list validation
88
+
89
+ ```python
90
+ num_found, df = solr_request(
91
+ core='genotype-phenotype',
92
+ params={
93
+ 'q': '*:*',
94
+ 'rows': 10,
95
+ 'fl': 'invalid_field,marker_symbol,allele_symbol'
96
+ },
97
+ validate=True
98
+ )
99
+ > InvalidFieldWarning: Unexpected field name: "invalid_field". Check the spelling of fields.
100
+ > To see expected fields check the documentation at: https://www.ebi.ac.uk/mi/impc/solrdoc/
101
+ ```
102
+
103
+ # 2. Batch Solr Request
104
+
105
+ `batch_solr_request` is available for large queries. This solves issues where a request is too large to fit into memory or where it puts a lot of strain on the API.
106
+
107
+ Use `batch_solr_request` for:
108
+
109
+ - Large queries (>1,000,000)
110
+ - Querying multiple items in a list
111
+ - Downloading data in `json` or `csv` format.
112
+
113
+ ## Large queries
114
+
115
+ For large queries you can choose between seeing them in a DataFrame or downloading them in `json` or `csv` format.
116
+
117
+ ## a. Large query - see in DataFrame
118
+
119
+ This will fetch your data using the API responsibly and return a Pandas DataFrame
120
+
121
+ When your request is larger than recommended and you have not opted for downloading the data, a warning will be presented and you should follow the instructions to proceed.
122
+
123
+ ```python
124
+ df = batch_solr_request(
125
+ core='genotype-phenotype',
126
+ params={
127
+ 'q':'*:*'
128
+ },
129
+ download=False,
130
+ batch_size=30000
131
+ )
132
+ print(df.head())
133
+ ```
134
+
135
+ ## b. Large query - Download
136
+
137
+ When using the `download=True` option, a file with the requested information will be saved as `filename`. The format is selected based on the `wt` parameter.
138
+ A DataFrame may be returned, provided it does not exceed the memory available on your laptop. If the DataFrame is too large, an error will be raised. For these cases, we recommend you read the downloaded file in batches/chunks.
139
+
140
+ ```python
141
+ df = batch_solr_request(
142
+ core='genotype-phenotype',
143
+ params={
144
+ 'q':'*:*',
145
+ 'wt':'csv'
146
+ },
147
+ download=True,
148
+ filename='geno_pheno_query',
149
+ batch_size=100000
150
+ )
151
+ print(df.head())
152
+ ```
153
+
154
+ ## c. Query by multiple values
155
+
156
+ `batch_solr_request` also allows to search multiple items in a list provided they belong to them same field.
157
+ Pass the list to the `field_list` param and specify the type of `fl` in `field_type`.
158
+
159
+ ```python
160
+ # List of gene symbols
161
+ genes = ["Zfp580", "Firrm", "Gpld1", "Mbip"]
162
+
163
+ df = batch_solr_request(
164
+ core='genotype-phenotype',
165
+ params={
166
+ 'q':'*:*',
167
+ 'fl': 'marker_symbol,mp_term_name,p_value',
168
+ 'field_list': genes,
169
+ 'field_type': 'marker_symbol'
170
+ },
171
+ download = False
172
+ )
173
+ print(df.head())
174
+ ```
175
+
176
+ This can be downloaded too:
177
+
178
+ ```python
179
+ # List of gene symbols
180
+ genes = ["Zfp580", "Firrm", "Gpld1", "Mbip"]
181
+
182
+ df = batch_solr_request(
183
+ core='genotype-phenotype',
184
+ params={
185
+ 'q':'*:*',
186
+ 'fl': 'marker_symbol,mp_term_name,p_value',
187
+ 'field_list': genes,
188
+ 'field_type': 'marker_symbol'
189
+ },
190
+ download = True,
191
+ filename='gene_list_query'
192
+ )
193
+ print(df.head())
194
+ ```
@@ -0,0 +1,6 @@
1
+ from .solr_request import solr_request
2
+ from .batch_solr_request import batch_solr_request
3
+ from .utils import validators, warnings
4
+
5
+ # Control what gets imported by client
6
+ __all__ = ["solr_request", "batch_solr_request"]
@@ -0,0 +1,266 @@
1
+ import json
2
+ import warnings
3
+ from pathlib import Path
4
+
5
+ import pandas as pd
6
+ import requests
7
+ from tqdm import tqdm
8
+ from IPython.display import display
9
+
10
+ from impc_api.utils.validators import DownloadFormatValidator
11
+ from impc_api.utils.warnings import (
12
+ warning_config,
13
+ RowsParamIgnored,
14
+ UnsupportedDownloadFormatError,
15
+ )
16
+ from .solr_request import solr_request
17
+
18
+ # Initialise warning config
19
+ warning_config()
20
+
21
+ def batch_solr_request(
22
+ core, params, download=False, batch_size=5000, filename="batch_request"
23
+ ):
24
+ """Function for large API requests (>1,000,000 results). Fetches the data in batches and
25
+ produces a Pandas DataFrame or downloads a file in json or csv formats.
26
+
27
+ Additionally, allows to search multiple items in a list provided they belong to them same field.
28
+
29
+ Args:
30
+ core (str): name of IMPC solr core.
31
+ params (dict): dictionary containing the API call parameters.
32
+ download (bool, optional): True for download a local file, False to display results as a DataFrame. Defaults to False.
33
+ batch_size (int, optional): Size of batches to fetch the data. Defaults to 5000.
34
+ filename (str, optional): When download=True, select the name of the file. Defaults to 'batch_request'.
35
+
36
+
37
+ Returns:
38
+ pd.DataFrame: if download=False, displays a DataFrame with the results.
39
+ None: if download=True, displays a statement on the console and returns None.
40
+ """
41
+
42
+ # If params["rows"] is passed, the user is warned about no effect
43
+ if params.get("rows") is not None:
44
+ warnings.warn(
45
+ message='The "rows" param will be ignored in batch_solr_request. To set a batch size, specify a "batch_size" argument.',
46
+ category=RowsParamIgnored,
47
+ )
48
+
49
+ # Set params for batch request
50
+ params["start"] = 0 # Start at the first result
51
+ # Override param rows in case there was input. Defines batch size to 5000 by default
52
+ params["rows"] = batch_size
53
+
54
+ # If user did not specify format, defaults to json.
55
+ if params.get("wt") is None:
56
+ params["wt"] = "json"
57
+
58
+ # Check if it's multiple request
59
+ if params.get("field_list") is not None:
60
+ # Extract entities_list and entity_type from params
61
+ field_list = params.pop("field_list")
62
+ field_type = params.pop("field_type")
63
+
64
+ # Construct the filter query with grouped model IDs
65
+ fq = "{}:({})".format(
66
+ field_type, " OR ".join(["{}".format(id) for id in field_list])
67
+ )
68
+ # Show users the field and field values they passed to the function
69
+ print("Queried field:", fq)
70
+ # Set internal params the users should not change
71
+ params["fq"] = fq
72
+
73
+ # Determine the total number of rows. Note that we do not request any data (rows = 0).
74
+ num_results, _ = solr_request(
75
+ core=core, params={**params, "start": 0, "rows": 0, "wt": "json"}, silent=True
76
+ )
77
+ print(f"Number of found documents: {num_results}")
78
+
79
+ # # Download only logic
80
+ # If user decides to download, a generator is used to fetch data in batches without storing results in memory.
81
+ if download:
82
+ try:
83
+ # Check if the format is supported
84
+ DownloadFormatValidator(wt=params["wt"])
85
+
86
+ # Implement loop behaviour
87
+ print("Downloading file...")
88
+ filename_path = Path(f"{filename}.{params['wt']}")
89
+ gen = _batch_solr_generator(core, params, num_results)
90
+ _solr_downloader(params, filename_path, gen)
91
+ print(f"File saved as: {filename_path}")
92
+ except UnsupportedDownloadFormatError as e:
93
+ raise e
94
+ except Exception as e:
95
+ raise (f"An error ocurred while downloading the data:{e}")
96
+
97
+ # Try to read the downloaded file
98
+ try:
99
+ print("Reading downloaded file...")
100
+ return _read_downloaded_file(filename_path, params["wt"])
101
+ except Exception as e:
102
+ raise Exception(f"An unexpected error occured:{e}")
103
+
104
+ # If the number of results is small enough and download is off, it's okay to show as df
105
+ if num_results < 1000000 and not download:
106
+ return _batch_to_df(core, params, num_results)
107
+
108
+ # If it's too big, warn the user and ask if they want to proceed.
109
+ else:
110
+ print(
111
+ "Your request might exceed the available memory. We suggest setting 'download=True' and reading the file in batches"
112
+ )
113
+ prompt = input(
114
+ "Do you wish to proceed anyway? press ('y' or enter to proceed) / type('n' or 'exit' to cancel)"
115
+ )
116
+ match prompt:
117
+ case "n" | "exit":
118
+ print("Exiting gracefully")
119
+ exit()
120
+ case "y" | "":
121
+ print("Fetching data...")
122
+ return _batch_to_df(core, params, num_results)
123
+
124
+
125
+ # Helper batch_to_df
126
+ def _batch_to_df(core, params, num_results):
127
+ """Helper function to fetch data in batches and display them in a DataFrame
128
+
129
+ Args:
130
+ core (str): name of IMPC solr core.
131
+ params (dict): dictionary containing the API call parameters.
132
+ num_results (int): Number of docs available
133
+
134
+ Returns:
135
+ pd.DataFrame: DataFrame with the results.
136
+ """
137
+ start = params["start"]
138
+ batch_size = params["rows"]
139
+ chunks = []
140
+ # If the 'wt' param was changed by error, we set it to 'json'
141
+ params["wt"] = "json"
142
+
143
+ # Request chunks until we have complete data.
144
+ with tqdm(total=num_results) as pbar:
145
+ while start < num_results:
146
+ # Request chunk. We don't need num_results anymore because it does not change.
147
+ _, df_chunk = solr_request(
148
+ core=core,
149
+ params={**params, "start": start, "rows": batch_size},
150
+ silent=True,
151
+ )
152
+
153
+ # Update progress bar with the number of rows requested.
154
+ pbar.update(batch_size)
155
+ pbar.refresh()
156
+ # Record chunk.
157
+ chunks.append(df_chunk)
158
+ # Increment start.
159
+ start += batch_size
160
+ # Prepare final dataframe.
161
+ return pd.concat(chunks, ignore_index=True)
162
+
163
+
164
+ def _batch_solr_generator(core, params, num_results):
165
+ """Generator function to fetch results from the SOLR API in batches using pagination.
166
+
167
+ Args:
168
+ core (str): name of IMPC solr core.
169
+ params (dict): dictionary containing the API call parameters.
170
+ num_results (int): Number of docs available
171
+
172
+ Raises:
173
+ Exception: If a problem occurs during the download, an exception is raised.
174
+
175
+ Yields:
176
+ ([dict, str]): A JSON object or plain text with the results.
177
+ """
178
+ base_url = "https://www.ebi.ac.uk/mi/impc/solr/"
179
+ solr_url = base_url + core + "/select"
180
+ start = params["start"]
181
+ batch_size = params["rows"]
182
+
183
+ with tqdm(total=num_results) as pbar:
184
+ while start <= num_results:
185
+ params["start"] = start
186
+ response = requests.get(solr_url, params=params, timeout=10)
187
+
188
+ if response.status_code == 200:
189
+ if params.get("wt") == "json":
190
+ data = response.json()["response"]["docs"]
191
+ else:
192
+ data = response.text
193
+
194
+ # Update and refresh the progress bar after getting the data
195
+ pbar.update(batch_size)
196
+ pbar.refresh()
197
+ yield data
198
+
199
+ else:
200
+ raise Exception(f"Request failed. Status code: {response.status_code}")
201
+
202
+ # pbar.update(batch_size)
203
+ start += batch_size
204
+ print(f"Your request URL after the last call:{response.url}")
205
+
206
+
207
+ # File writer
208
+ def _solr_downloader(params, filename, solr_generator):
209
+ """Function to write the data from the generator into the specified format.
210
+ Supports json and csv only.
211
+
212
+ Args:
213
+ params (dict): dictionary containing the API call parameters.
214
+ filename (Path): name for the file to be downloaded. Defaults to "core.format" as passed by parent function.
215
+ solr_generator ([dict, str]): Generator object with the results.
216
+ """
217
+ with open(filename, "w", encoding="UTF-8") as f:
218
+ if params.get("wt") == "json":
219
+ f.write("[\n")
220
+ first_chunk = True
221
+
222
+ for chunk in solr_generator:
223
+ for item in chunk:
224
+ if not first_chunk:
225
+ f.write(",\n")
226
+ json.dump(item, f, ensure_ascii=False)
227
+ first_chunk = False
228
+ f.write("\n]\n")
229
+
230
+ elif params.get("wt") == "csv":
231
+ first_chunk = True
232
+ for chunk in solr_generator:
233
+ lines = chunk.splitlines()
234
+ if first_chunk:
235
+ # Write all lines in the first chunk
236
+ f.write(chunk)
237
+ first_chunk = False
238
+ else:
239
+ # Skip the first line (header) in subsequent chunks
240
+ f.write("\n" + "\n".join(lines[1:]) + "\n")
241
+
242
+
243
+ # File reader
244
+ def _read_downloaded_file(filename: Path, request_format):
245
+ """Wrapper for reading files into Pandas DataFrames
246
+
247
+ Args:
248
+ filename (Path): Name of the file to read
249
+ request_format (str): Format of the file to read. Only 'json' and 'csv' are supported.
250
+
251
+ Raises:
252
+ MemoryError: When there is not enough memory to read the file.
253
+
254
+ Returns:
255
+ pd.DataFrame: Returns a pd.DataFrame with the data from the file.
256
+ """
257
+ try:
258
+ match request_format:
259
+ case "json":
260
+ return pd.read_json(filename)
261
+ case "csv":
262
+ return pd.read_csv(filename)
263
+ except MemoryError as exc:
264
+ raise MemoryError(
265
+ "MemoryError: Insuficient memory to read the file. Consider reading file in batches using Pandas or Polars."
266
+ ) from exc
@@ -0,0 +1,191 @@
1
+ import pandas as pd
2
+ import requests
3
+ from IPython.display import display
4
+ from tqdm import tqdm
5
+
6
+ from impc_api.utils.validators import CoreParamsValidator
7
+
8
+ # Display the whole dataframe <15
9
+ pd.set_option("display.max_rows", 15)
10
+ pd.set_option("display.max_columns", None)
11
+
12
+ # Create helper function
13
+ def solr_request(core, params, silent=False, validate=False):
14
+ """Performs a single Solr request to the IMPC Solr API.
15
+
16
+ Args:
17
+ core (str): name of IMPC solr core.
18
+ params (dict): dictionary containing the API call parameters.
19
+ silent (bool, optional): default False
20
+ If True, displays: URL of API call, the number of found docs
21
+ and a portion of the DataFrame.
22
+ validate (bool, optional): default False
23
+ If True, validates the parameters against the core schema and raises warnings
24
+ if any parameter seems invalid.
25
+
26
+
27
+ Returns:
28
+ num_found: Number of docs found.
29
+ pandas.DataFrame: Pandas.DataFrame object with the information requested.
30
+
31
+ Example query:
32
+ num_found, df = solr_request(
33
+ core='genotype-phenotype',
34
+ params={
35
+ 'q': '*:*', # Your query, '*' retrieves all documents.
36
+ 'rows': 10, # Number of rows to retrieve.
37
+ 'fl': 'marker_symbol,allele_symbol,parameter_stable_id', # Fields to retrieve.
38
+ }
39
+ )
40
+
41
+ Faceting query provides a summary of data distribution across the specified fields.
42
+ Example faceting query:
43
+ num_found, df = solr_request(
44
+ core='genotype-phenotype',
45
+ params={
46
+ 'q': '*:*', # Your query, '*' retrieves all documents.
47
+ 'rows': 0, # Number of rows to retrieve.
48
+ 'facet': 'on', # Enable facet counts in query response.
49
+ 'facet.field': 'zygosity', # Identifies a field to be treated as a facet.
50
+ 'facet.limit': 15, # Controls how many constraints should be returned for each facet.
51
+ 'facet.mincount': 1 # Specifies the minimum counts required be included in response.
52
+ }
53
+ )
54
+
55
+ When querying the phenodigm core, pass 'q': 'type:...'
56
+ Example phenodigm query:
57
+ num_found, df = solr_request(
58
+ core='phenodigm',
59
+ params={
60
+ 'q': 'type:disease_model_summary', # Pass the type within the core and filters.
61
+ 'rows': 5
62
+ }
63
+ )
64
+ """
65
+
66
+ if validate:
67
+ CoreParamsValidator(core=core, params=params)
68
+
69
+ base_url = "https://www.ebi.ac.uk/mi/impc/solr/"
70
+ solr_url = base_url + core + "/select"
71
+
72
+ response = requests.get(solr_url, params=params)
73
+ if not silent:
74
+ print(f"\nYour request:\n{response.request.url}\n")
75
+
76
+ # Check if the request was successful (status code 200).
77
+ if response.status_code == 200:
78
+ # Parse the JSON response.
79
+ data = response.json()
80
+ num_found = data["response"]["numFound"]
81
+ if not silent:
82
+ print(f"Number of found documents: {num_found}\n")
83
+
84
+ # For faceting query.
85
+ if params.get("facet") == "on":
86
+ df = _process_faceting(data, params)
87
+
88
+ # For regular query.
89
+ else:
90
+ # Extract and add search results to the list.
91
+ search_results = []
92
+ for doc in data["response"]["docs"]:
93
+ search_results.append(doc)
94
+
95
+ # Convert the list of dictionaries into a DataFrame and print the DataFrame.
96
+ df = pd.DataFrame(search_results)
97
+
98
+ if not silent:
99
+ display(df)
100
+ return num_found, df
101
+
102
+ else:
103
+ print("Error:", response.status_code, response.text)
104
+
105
+
106
+ def _process_faceting(data, params):
107
+ """Processes the faceting data from an API response.
108
+ Note: This function should not be used alone but only as a helper function for solr_request().
109
+
110
+ Args:
111
+ data (dict): The JSON response from the API containing faceting information.
112
+ params (dict): Dictionary containing the API call parameters, including the facet field.
113
+
114
+ Returns:
115
+ pandas.DataFrame: A DataFrame with the facet field values and their corresponding counts.
116
+ """
117
+
118
+ # Extract and add faceting query results to the list.
119
+ facet_counts = data["facet_counts"]["facet_fields"][params["facet.field"]]
120
+ # Initialize an empty dictionary.
121
+ faceting_dict = {}
122
+ # Iterate over the list, taking pairs of elements.
123
+ for i in range(0, len(facet_counts), 2):
124
+ # Assign label as key and count as value.
125
+ label = facet_counts[i]
126
+ count = facet_counts[i + 1]
127
+ faceting_dict[label] = [count]
128
+
129
+ # Convert the list of dictionaries into a DataFrame and print the DataFrame.
130
+ df = pd.DataFrame.from_dict(
131
+ faceting_dict, orient="index", columns=["counts"]
132
+ ).reset_index()
133
+ # Rename the columns.
134
+ df.columns = [params["facet.field"], "count_per_category"]
135
+ return df
136
+
137
+
138
+ # Batch request based on solr_request.
139
+ def batch_request(core, params, batch_size):
140
+ """Calls `solr_request` multiple times with `params`
141
+ to retrieve results in chunk `batch_size` rows at a time.
142
+
143
+ Passing parameter `rows` is ignored and replaced with `batch_size`
144
+
145
+ Args:
146
+ core (str): name of IMPC solr core.
147
+ params (dict): dictionary containing the API call parameters.
148
+ batch_size (int): Size of batches (number of docs) per request.
149
+
150
+ Returns:
151
+ pandas.DataFrame: Pandas.DataFrame object with the information requested.
152
+
153
+ Example query:
154
+ df = batch_request(
155
+ core="genotype-phenotype",
156
+ params={
157
+ 'q': 'top_level_mp_term_name:"cardiovascular system phenotype" AND effect_size:[* TO *] AND life_stage_name:"Late adult"',
158
+ 'fl': 'allele_accession_id,life_stage_name,marker_symbol,mp_term_name,p_value,parameter_name,parameter_stable_id,phenotyping_center,statistical_method,top_level_mp_term_name,effect_size'
159
+ },
160
+ batch_size=100
161
+ )
162
+ """
163
+
164
+ if "rows" in "params":
165
+ print(
166
+ "WARN: You have specified the `params` -> `rows` value. It will be ignored, because the data is retrieved `batch_size` rows at a time."
167
+ )
168
+ # Determine the total number of rows. Note that we do not request any data (rows = 0).
169
+ num_results, _ = solr_request(
170
+ core=core, params={**params, "start": 0, "rows": 0}, silent=True
171
+ )
172
+ # Initialise everything for data retrieval.
173
+ start = 0
174
+ chunks = []
175
+ # Request chunks until we have complete data.
176
+ with tqdm(total=num_results) as pbar: # Initialize tqdm progress bar.
177
+ while start < num_results:
178
+ # Update progress bar with the number of rows requested.
179
+ pbar.update(batch_size)
180
+ # Request chunk. We don't need num_results anymore because it does not change.
181
+ _, df_chunk = solr_request(
182
+ core=core,
183
+ params={**params, "start": start, "rows": batch_size},
184
+ silent=True,
185
+ )
186
+ # Record chunk.
187
+ chunks.append(df_chunk)
188
+ # Increment start.
189
+ start += batch_size
190
+ # Prepare final dataframe.
191
+ return pd.concat(chunks, ignore_index=True)
File without changes