impc-api 1.0.6__tar.gz → 2.0.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.
- {impc_api-1.0.6 → impc_api-2.0.0}/PKG-INFO +70 -19
- impc_api-1.0.6/impc_api.egg-info/PKG-INFO → impc_api-2.0.0/README.md +61 -27
- {impc_api-1.0.6 → impc_api-2.0.0}/impc_api/__init__.py +2 -1
- {impc_api-1.0.6 → impc_api-2.0.0}/impc_api/batch_solr_request.py +34 -28
- impc_api-2.0.0/impc_api/get_core_fields.py +22 -0
- {impc_api-1.0.6 → impc_api-2.0.0}/impc_api/solr_request.py +47 -6
- impc_api-2.0.0/impc_api/utils/core_fields.json +463 -0
- {impc_api-1.0.6 → impc_api-2.0.0}/impc_api/utils/validators.py +10 -7
- {impc_api-1.0.6 → impc_api-2.0.0}/impc_api/utils/warnings.py +13 -2
- {impc_api-1.0.6 → impc_api-2.0.0}/pyproject.toml +12 -9
- impc_api-1.0.6/MANIFEST.in +0 -1
- impc_api-1.0.6/README.md +0 -194
- impc_api-1.0.6/impc_api/utils/core_fields.json +0 -15
- impc_api-1.0.6/impc_api.egg-info/SOURCES.txt +0 -19
- impc_api-1.0.6/impc_api.egg-info/dependency_links.txt +0 -1
- impc_api-1.0.6/impc_api.egg-info/requires.txt +0 -7
- impc_api-1.0.6/impc_api.egg-info/top_level.txt +0 -1
- impc_api-1.0.6/setup.cfg +0 -4
- impc_api-1.0.6/tests/test_batch_solr_request.py +0 -746
- impc_api-1.0.6/tests/test_helpers.py +0 -33
- impc_api-1.0.6/tests/test_solr_request.py +0 -318
- {impc_api-1.0.6 → impc_api-2.0.0}/LICENSE +0 -0
- {impc_api-1.0.6 → impc_api-2.0.0}/impc_api/utils/__init__.py +0 -0
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: impc_api
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0
|
|
4
4
|
Summary: A package to facilitate making API requests to the IMPC Solr API
|
|
5
5
|
Author: MPI2, Marina Kan, Diego Pava
|
|
6
|
-
|
|
7
|
-
Requires-Python: >=3.10
|
|
8
|
-
Description-Content-Type: text/markdown
|
|
6
|
+
License-Expression: Apache-2.0
|
|
9
7
|
License-File: LICENSE
|
|
8
|
+
Requires-Dist: ipykernel>=6.29.5
|
|
9
|
+
Requires-Dist: notebook>=7.2.2
|
|
10
10
|
Requires-Dist: pandas>=2.2.0
|
|
11
|
-
Requires-Dist: requests>=2.
|
|
11
|
+
Requires-Dist: requests>=2.33.0
|
|
12
12
|
Requires-Dist: tqdm>=4.66.4
|
|
13
13
|
Requires-Dist: pydantic>=2.9
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
Requires-Python: >=3.10
|
|
15
|
+
Project-URL: Homepage, https://github.com/mpi2/impc-api
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
16
17
|
|
|
17
18
|
# IMPC_API
|
|
18
19
|
|
|
19
|
-
`impc_api` is a Python package which provides several helper functions that wrap around the IMPC SOLR API.
|
|
20
|
-
|
|
21
|
-
The functions in this package are intended for use in a Jupyter Notebook.
|
|
20
|
+
`impc_api` is a Python package which provides several helper functions that wrap around the IMPC SOLR API. The functions in this package are intended for use in a Jupyter Notebook.
|
|
22
21
|
|
|
23
22
|
## Installation Instructions
|
|
24
23
|
|
|
24
|
+
0. Ensure that Python is installed on your system. The minimum required version is 3.10.
|
|
25
|
+
|
|
25
26
|
1. **Create a virtual environment (optional but recommended)**:
|
|
26
|
-
On Mac:
|
|
27
|
+
On Mac or Linux:
|
|
27
28
|
```bash
|
|
28
29
|
python3 -m venv .venv
|
|
29
30
|
source .venv/bin/activate
|
|
30
31
|
```
|
|
31
32
|
|
|
32
33
|
2. **Install the package**: `pip install impc_api`
|
|
33
|
-
3. **
|
|
34
|
-
4. **Run the Jupyter Notebook**: `jupyter notebook`
|
|
34
|
+
3. **Run the Jupyter Notebook**: `jupyter notebook`
|
|
35
35
|
|
|
36
36
|
After executing the command, the Jupyter interface should open in your browser. If it does not, follow the instructions provided in the terminal.
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
4. **Try it out**:
|
|
39
39
|
|
|
40
40
|
Create a [Jupyter Notebook](https://jupyter-notebook.readthedocs.io/en/latest/) and try some of the examples below:
|
|
41
41
|
|
|
@@ -44,7 +44,7 @@ Create a [Jupyter Notebook](https://jupyter-notebook.readthedocs.io/en/latest/)
|
|
|
44
44
|
The available functions can be imported as:
|
|
45
45
|
|
|
46
46
|
```python
|
|
47
|
-
from impc_api import
|
|
47
|
+
from impc_api import batch_solr_request, get_core_fields, solr_request
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
# 1. Solr request
|
|
@@ -62,6 +62,20 @@ num_found, df = solr_request(
|
|
|
62
62
|
)
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
+
By default, `solr_request` uses a 10 second request timeout. To use a different timeout, pass the optional `timeout` argument:
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
num_found, df = solr_request(
|
|
69
|
+
core='genotype-phenotype',
|
|
70
|
+
params={
|
|
71
|
+
'q': '*:*',
|
|
72
|
+
'rows': 10,
|
|
73
|
+
'fl': 'marker_symbol,allele_symbol,parameter_stable_id'
|
|
74
|
+
},
|
|
75
|
+
timeout=30
|
|
76
|
+
)
|
|
77
|
+
```
|
|
78
|
+
|
|
65
79
|
## a. Facet request
|
|
66
80
|
|
|
67
81
|
`solr_request` allows facet requests
|
|
@@ -96,7 +110,7 @@ num_found, df = solr_request(
|
|
|
96
110
|
validate=True
|
|
97
111
|
)
|
|
98
112
|
|
|
99
|
-
> InvalidCoreWarning: Invalid core: "
|
|
113
|
+
> InvalidCoreWarning: Invalid core: "invalid_core", select from the available cores:
|
|
100
114
|
> dict_keys(['experiment', 'genotype-phenotype', 'impc_images', 'phenodigm', 'statistical-result'])
|
|
101
115
|
```
|
|
102
116
|
|
|
@@ -116,13 +130,33 @@ num_found, df = solr_request(
|
|
|
116
130
|
> To see expected fields check the documentation at: https://www.ebi.ac.uk/mi/impc/solrdoc/
|
|
117
131
|
```
|
|
118
132
|
|
|
133
|
+
## c. URL only
|
|
134
|
+
|
|
135
|
+
Users might want help producing the URL to fetch the data without the need of a DataFrame. Use the flag `url_only=True` to print or return the URL for your query.
|
|
136
|
+
|
|
137
|
+
```python
|
|
138
|
+
url, _ = solr_request(
|
|
139
|
+
core='genotype-phenotype',
|
|
140
|
+
params={
|
|
141
|
+
'q': '*:*',
|
|
142
|
+
'rows': 10,
|
|
143
|
+
'fl': 'marker_symbol,allele_symbol'
|
|
144
|
+
},
|
|
145
|
+
url_only=True
|
|
146
|
+
)
|
|
147
|
+
> "https://www.ebi.ac.uk/mi/impc/solr/genotype-phenotype/select?q=%2A%3A%2A&rows=10&fl=marker_symbol%2Callele_symbol"
|
|
148
|
+
|
|
149
|
+
print(url)
|
|
150
|
+
> "https://www.ebi.ac.uk/mi/impc/solr/genotype-phenotype/select?q=%2A%3A%2A&rows=10&fl=marker_symbol%2Callele_symbol"
|
|
151
|
+
```
|
|
152
|
+
|
|
119
153
|
# 2. Batch Solr Request
|
|
120
154
|
|
|
121
155
|
`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.
|
|
122
156
|
|
|
123
157
|
Use `batch_solr_request` for:
|
|
124
158
|
|
|
125
|
-
- Large queries (>1,000,000)
|
|
159
|
+
- Large queries (>1,000,000 rows)
|
|
126
160
|
- Querying multiple items in a list
|
|
127
161
|
- Downloading data in `json` or `csv` format.
|
|
128
162
|
|
|
@@ -134,7 +168,7 @@ For large queries you can choose between seeing them in a DataFrame or downloadi
|
|
|
134
168
|
|
|
135
169
|
This will fetch your data using the API responsibly and return a Pandas DataFrame
|
|
136
170
|
|
|
137
|
-
When your request is larger than recommended and you have not opted
|
|
171
|
+
When your request is larger than recommended and you have not opted to download the data, a warning will be presented suggesting that you retry your request and download the data.
|
|
138
172
|
|
|
139
173
|
```python
|
|
140
174
|
df = batch_solr_request(
|
|
@@ -208,3 +242,20 @@ df = batch_solr_request(
|
|
|
208
242
|
)
|
|
209
243
|
print(df.head())
|
|
210
244
|
```
|
|
245
|
+
# 3.Get Core Fields
|
|
246
|
+
|
|
247
|
+
## Retrieve valid fields for a core
|
|
248
|
+
|
|
249
|
+
Use `get_core_fields` before constructing a request to discover the documented
|
|
250
|
+
fields available for a public IMPC Solr core. The function uses the same source
|
|
251
|
+
of truth as request validation and does not make a network request.
|
|
252
|
+
|
|
253
|
+
```python
|
|
254
|
+
from impc_api import get_core_fields
|
|
255
|
+
|
|
256
|
+
get_core_fields("genotype-phenotype")
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
The complete list is returned. An unknown core returns an empty list. Skills and
|
|
260
|
+
other integrations should call this function instead of maintaining their own
|
|
261
|
+
copies of core field names.
|
|
@@ -1,41 +1,24 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: impc_api
|
|
3
|
-
Version: 1.0.6
|
|
4
|
-
Summary: A package to facilitate making API requests to the IMPC Solr API
|
|
5
|
-
Author: MPI2, Marina Kan, Diego Pava
|
|
6
|
-
Project-URL: Homepage, https://github.com/mpi2/impc-data-api-workshop
|
|
7
|
-
Requires-Python: >=3.10
|
|
8
|
-
Description-Content-Type: text/markdown
|
|
9
|
-
License-File: LICENSE
|
|
10
|
-
Requires-Dist: pandas>=2.2.0
|
|
11
|
-
Requires-Dist: requests>=2.31.0
|
|
12
|
-
Requires-Dist: tqdm>=4.66.4
|
|
13
|
-
Requires-Dist: pydantic>=2.9
|
|
14
|
-
Provides-Extra: dev
|
|
15
|
-
Requires-Dist: pytest>=8.2.2; extra == "dev"
|
|
16
|
-
|
|
17
1
|
# IMPC_API
|
|
18
2
|
|
|
19
|
-
`impc_api` is a Python package which provides several helper functions that wrap around the IMPC SOLR API.
|
|
20
|
-
|
|
21
|
-
The functions in this package are intended for use in a Jupyter Notebook.
|
|
3
|
+
`impc_api` is a Python package which provides several helper functions that wrap around the IMPC SOLR API. The functions in this package are intended for use in a Jupyter Notebook.
|
|
22
4
|
|
|
23
5
|
## Installation Instructions
|
|
24
6
|
|
|
7
|
+
0. Ensure that Python is installed on your system. The minimum required version is 3.10.
|
|
8
|
+
|
|
25
9
|
1. **Create a virtual environment (optional but recommended)**:
|
|
26
|
-
On Mac:
|
|
10
|
+
On Mac or Linux:
|
|
27
11
|
```bash
|
|
28
12
|
python3 -m venv .venv
|
|
29
13
|
source .venv/bin/activate
|
|
30
14
|
```
|
|
31
15
|
|
|
32
16
|
2. **Install the package**: `pip install impc_api`
|
|
33
|
-
3. **
|
|
34
|
-
4. **Run the Jupyter Notebook**: `jupyter notebook`
|
|
17
|
+
3. **Run the Jupyter Notebook**: `jupyter notebook`
|
|
35
18
|
|
|
36
19
|
After executing the command, the Jupyter interface should open in your browser. If it does not, follow the instructions provided in the terminal.
|
|
37
20
|
|
|
38
|
-
|
|
21
|
+
4. **Try it out**:
|
|
39
22
|
|
|
40
23
|
Create a [Jupyter Notebook](https://jupyter-notebook.readthedocs.io/en/latest/) and try some of the examples below:
|
|
41
24
|
|
|
@@ -44,7 +27,7 @@ Create a [Jupyter Notebook](https://jupyter-notebook.readthedocs.io/en/latest/)
|
|
|
44
27
|
The available functions can be imported as:
|
|
45
28
|
|
|
46
29
|
```python
|
|
47
|
-
from impc_api import
|
|
30
|
+
from impc_api import batch_solr_request, get_core_fields, solr_request
|
|
48
31
|
```
|
|
49
32
|
|
|
50
33
|
# 1. Solr request
|
|
@@ -62,6 +45,20 @@ num_found, df = solr_request(
|
|
|
62
45
|
)
|
|
63
46
|
```
|
|
64
47
|
|
|
48
|
+
By default, `solr_request` uses a 10 second request timeout. To use a different timeout, pass the optional `timeout` argument:
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
num_found, df = solr_request(
|
|
52
|
+
core='genotype-phenotype',
|
|
53
|
+
params={
|
|
54
|
+
'q': '*:*',
|
|
55
|
+
'rows': 10,
|
|
56
|
+
'fl': 'marker_symbol,allele_symbol,parameter_stable_id'
|
|
57
|
+
},
|
|
58
|
+
timeout=30
|
|
59
|
+
)
|
|
60
|
+
```
|
|
61
|
+
|
|
65
62
|
## a. Facet request
|
|
66
63
|
|
|
67
64
|
`solr_request` allows facet requests
|
|
@@ -96,7 +93,7 @@ num_found, df = solr_request(
|
|
|
96
93
|
validate=True
|
|
97
94
|
)
|
|
98
95
|
|
|
99
|
-
> InvalidCoreWarning: Invalid core: "
|
|
96
|
+
> InvalidCoreWarning: Invalid core: "invalid_core", select from the available cores:
|
|
100
97
|
> dict_keys(['experiment', 'genotype-phenotype', 'impc_images', 'phenodigm', 'statistical-result'])
|
|
101
98
|
```
|
|
102
99
|
|
|
@@ -116,13 +113,33 @@ num_found, df = solr_request(
|
|
|
116
113
|
> To see expected fields check the documentation at: https://www.ebi.ac.uk/mi/impc/solrdoc/
|
|
117
114
|
```
|
|
118
115
|
|
|
116
|
+
## c. URL only
|
|
117
|
+
|
|
118
|
+
Users might want help producing the URL to fetch the data without the need of a DataFrame. Use the flag `url_only=True` to print or return the URL for your query.
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
url, _ = solr_request(
|
|
122
|
+
core='genotype-phenotype',
|
|
123
|
+
params={
|
|
124
|
+
'q': '*:*',
|
|
125
|
+
'rows': 10,
|
|
126
|
+
'fl': 'marker_symbol,allele_symbol'
|
|
127
|
+
},
|
|
128
|
+
url_only=True
|
|
129
|
+
)
|
|
130
|
+
> "https://www.ebi.ac.uk/mi/impc/solr/genotype-phenotype/select?q=%2A%3A%2A&rows=10&fl=marker_symbol%2Callele_symbol"
|
|
131
|
+
|
|
132
|
+
print(url)
|
|
133
|
+
> "https://www.ebi.ac.uk/mi/impc/solr/genotype-phenotype/select?q=%2A%3A%2A&rows=10&fl=marker_symbol%2Callele_symbol"
|
|
134
|
+
```
|
|
135
|
+
|
|
119
136
|
# 2. Batch Solr Request
|
|
120
137
|
|
|
121
138
|
`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.
|
|
122
139
|
|
|
123
140
|
Use `batch_solr_request` for:
|
|
124
141
|
|
|
125
|
-
- Large queries (>1,000,000)
|
|
142
|
+
- Large queries (>1,000,000 rows)
|
|
126
143
|
- Querying multiple items in a list
|
|
127
144
|
- Downloading data in `json` or `csv` format.
|
|
128
145
|
|
|
@@ -134,7 +151,7 @@ For large queries you can choose between seeing them in a DataFrame or downloadi
|
|
|
134
151
|
|
|
135
152
|
This will fetch your data using the API responsibly and return a Pandas DataFrame
|
|
136
153
|
|
|
137
|
-
When your request is larger than recommended and you have not opted
|
|
154
|
+
When your request is larger than recommended and you have not opted to download the data, a warning will be presented suggesting that you retry your request and download the data.
|
|
138
155
|
|
|
139
156
|
```python
|
|
140
157
|
df = batch_solr_request(
|
|
@@ -208,3 +225,20 @@ df = batch_solr_request(
|
|
|
208
225
|
)
|
|
209
226
|
print(df.head())
|
|
210
227
|
```
|
|
228
|
+
# 3.Get Core Fields
|
|
229
|
+
|
|
230
|
+
## Retrieve valid fields for a core
|
|
231
|
+
|
|
232
|
+
Use `get_core_fields` before constructing a request to discover the documented
|
|
233
|
+
fields available for a public IMPC Solr core. The function uses the same source
|
|
234
|
+
of truth as request validation and does not make a network request.
|
|
235
|
+
|
|
236
|
+
```python
|
|
237
|
+
from impc_api import get_core_fields
|
|
238
|
+
|
|
239
|
+
get_core_fields("genotype-phenotype")
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
The complete list is returned. An unknown core returns an empty list. Skills and
|
|
243
|
+
other integrations should call this function instead of maintaining their own
|
|
244
|
+
copies of core field names.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from .solr_request import solr_request
|
|
2
2
|
from .batch_solr_request import batch_solr_request
|
|
3
|
+
from .get_core_fields import get_core_fields
|
|
3
4
|
from .utils import validators, warnings
|
|
4
5
|
|
|
5
6
|
# Control what gets imported by client
|
|
6
|
-
__all__ = ["solr_request", "batch_solr_request"]
|
|
7
|
+
__all__ = ["solr_request", "batch_solr_request", "get_core_fields"]
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import warnings
|
|
3
|
+
from collections.abc import Iterator
|
|
3
4
|
from pathlib import Path
|
|
5
|
+
from typing import Any, Dict, Iterable, List, Union
|
|
4
6
|
|
|
5
7
|
import pandas as pd
|
|
6
8
|
import requests
|
|
@@ -12,15 +14,23 @@ from impc_api.utils.warnings import (
|
|
|
12
14
|
warning_config,
|
|
13
15
|
RowsParamIgnored,
|
|
14
16
|
UnsupportedDownloadFormatError,
|
|
17
|
+
LargeRequestMemoryWarning
|
|
15
18
|
)
|
|
16
19
|
from .solr_request import solr_request
|
|
17
20
|
|
|
18
21
|
# Initialise warning config
|
|
19
22
|
warning_config()
|
|
20
23
|
|
|
24
|
+
BatchSolrChunk = Union[List[Dict[str, Any]], str]
|
|
25
|
+
|
|
26
|
+
|
|
21
27
|
def batch_solr_request(
|
|
22
|
-
core
|
|
23
|
-
|
|
28
|
+
core: str,
|
|
29
|
+
params: Dict[str, Any],
|
|
30
|
+
download: bool = False,
|
|
31
|
+
batch_size: int = 5000,
|
|
32
|
+
filename: str = "batch_request",
|
|
33
|
+
) -> pd.DataFrame:
|
|
24
34
|
"""Function for large API requests (>1,000,000 results). Fetches the data in batches and
|
|
25
35
|
produces a Pandas DataFrame or downloads a file in json or csv formats.
|
|
26
36
|
|
|
@@ -36,7 +46,6 @@ def batch_solr_request(
|
|
|
36
46
|
|
|
37
47
|
Returns:
|
|
38
48
|
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
49
|
"""
|
|
41
50
|
|
|
42
51
|
# If params["rows"] is passed, the user is warned about no effect
|
|
@@ -92,38 +101,28 @@ def batch_solr_request(
|
|
|
92
101
|
except UnsupportedDownloadFormatError as e:
|
|
93
102
|
raise e
|
|
94
103
|
except Exception as e:
|
|
95
|
-
raise (f"An error
|
|
104
|
+
raise Exception(f"An error occurred while downloading the data:{e}")
|
|
96
105
|
|
|
97
106
|
# Try to read the downloaded file
|
|
98
107
|
try:
|
|
99
108
|
print("Reading downloaded file...")
|
|
100
109
|
return _read_downloaded_file(filename_path, params["wt"])
|
|
101
110
|
except Exception as e:
|
|
102
|
-
raise Exception(f"An unexpected error
|
|
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)
|
|
111
|
+
raise Exception(f"An unexpected error occurred:{e}")
|
|
107
112
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
"Do you wish to proceed anyway? press ('y' or enter to proceed) / type('n' or 'exit' to cancel)"
|
|
113
|
+
|
|
114
|
+
# If a request is too large, warn the user to use download=true.
|
|
115
|
+
if num_results > 1000000 and not download:
|
|
116
|
+
warnings.warn(
|
|
117
|
+
message="This request may exceed available memory. If the download fails, set 'download=True' and try again.",
|
|
118
|
+
category=LargeRequestMemoryWarning,
|
|
115
119
|
)
|
|
116
|
-
|
|
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
|
-
|
|
120
|
+
return _batch_to_df(core, params, num_results)
|
|
124
121
|
|
|
125
122
|
# Helper batch_to_df
|
|
126
|
-
def _batch_to_df(
|
|
123
|
+
def _batch_to_df(
|
|
124
|
+
core: str, params: Dict[str, Any], num_results: int
|
|
125
|
+
) -> pd.DataFrame:
|
|
127
126
|
"""Helper function to fetch data in batches and display them in a DataFrame
|
|
128
127
|
|
|
129
128
|
Args:
|
|
@@ -161,7 +160,9 @@ def _batch_to_df(core, params, num_results):
|
|
|
161
160
|
return pd.concat(chunks, ignore_index=True)
|
|
162
161
|
|
|
163
162
|
|
|
164
|
-
def _batch_solr_generator(
|
|
163
|
+
def _batch_solr_generator(
|
|
164
|
+
core: str, params: Dict[str, Any], num_results: int
|
|
165
|
+
) -> Iterator[BatchSolrChunk]:
|
|
165
166
|
"""Generator function to fetch results from the SOLR API in batches using pagination.
|
|
166
167
|
|
|
167
168
|
Args:
|
|
@@ -205,7 +206,11 @@ def _batch_solr_generator(core, params, num_results):
|
|
|
205
206
|
|
|
206
207
|
|
|
207
208
|
# File writer
|
|
208
|
-
def _solr_downloader(
|
|
209
|
+
def _solr_downloader(
|
|
210
|
+
params: Dict[str, Any],
|
|
211
|
+
filename: Path,
|
|
212
|
+
solr_generator: Iterable[BatchSolrChunk],
|
|
213
|
+
) -> None:
|
|
209
214
|
"""Function to write the data from the generator into the specified format.
|
|
210
215
|
Supports json and csv only.
|
|
211
216
|
|
|
@@ -230,6 +235,7 @@ def _solr_downloader(params, filename, solr_generator):
|
|
|
230
235
|
elif params.get("wt") == "csv":
|
|
231
236
|
first_chunk = True
|
|
232
237
|
for chunk in solr_generator:
|
|
238
|
+
assert isinstance(chunk, str)
|
|
233
239
|
lines = chunk.splitlines()
|
|
234
240
|
if first_chunk:
|
|
235
241
|
# Write all lines in the first chunk
|
|
@@ -241,7 +247,7 @@ def _solr_downloader(params, filename, solr_generator):
|
|
|
241
247
|
|
|
242
248
|
|
|
243
249
|
# File reader
|
|
244
|
-
def _read_downloaded_file(filename: Path, request_format):
|
|
250
|
+
def _read_downloaded_file(filename: Path, request_format: str) -> pd.DataFrame:
|
|
245
251
|
"""Wrapper for reading files into Pandas DataFrames
|
|
246
252
|
|
|
247
253
|
Args:
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from .utils.validators import ValidationJson
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def get_core_fields(core: str) -> list[str]:
|
|
5
|
+
"""Return the documented fields available for an IMPC Solr core.
|
|
6
|
+
|
|
7
|
+
Fields are read from the same source of truth used to validate requests.
|
|
8
|
+
This function does not make a request to the IMPC Solr API.
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
core: Name of a public IMPC Solr core.
|
|
12
|
+
|
|
13
|
+
Returns:
|
|
14
|
+
The documented field names, or an empty list when ``core`` is unknown.
|
|
15
|
+
|
|
16
|
+
Example:
|
|
17
|
+
>>> from impc_api import get_core_fields
|
|
18
|
+
>>> fields = get_core_fields("genotype-phenotype")
|
|
19
|
+
>>> fields[:3]
|
|
20
|
+
['doc_id', 'ontology_db_id', 'assertion_type']
|
|
21
|
+
"""
|
|
22
|
+
return ValidationJson().valid_fields(core)
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from typing import Any, Dict, Optional, Tuple, Union
|
|
2
|
+
|
|
1
3
|
import pandas as pd
|
|
2
4
|
import requests
|
|
3
5
|
from IPython.display import display
|
|
@@ -5,12 +7,26 @@ from tqdm import tqdm
|
|
|
5
7
|
|
|
6
8
|
from impc_api.utils.validators import CoreParamsValidator
|
|
7
9
|
|
|
10
|
+
RequestTimeout = Union[float, Tuple[float, float]]
|
|
11
|
+
SolrRequestResult = Optional[
|
|
12
|
+
Union[Tuple[int, pd.DataFrame], Tuple[Optional[str], None]]
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
DEFAULT_REQUEST_TIMEOUT: RequestTimeout = 10.0
|
|
16
|
+
|
|
8
17
|
# Display the whole dataframe <15
|
|
9
18
|
pd.set_option("display.max_rows", 15)
|
|
10
19
|
pd.set_option("display.max_columns", None)
|
|
11
20
|
|
|
12
21
|
# Create helper function
|
|
13
|
-
def solr_request(
|
|
22
|
+
def solr_request(
|
|
23
|
+
core: str,
|
|
24
|
+
params: Dict[str, Any],
|
|
25
|
+
silent: bool = False,
|
|
26
|
+
validate: bool = False,
|
|
27
|
+
url_only: bool = False,
|
|
28
|
+
timeout: RequestTimeout = DEFAULT_REQUEST_TIMEOUT,
|
|
29
|
+
) -> SolrRequestResult:
|
|
14
30
|
"""Performs a single Solr request to the IMPC Solr API.
|
|
15
31
|
|
|
16
32
|
Args:
|
|
@@ -22,11 +38,24 @@ def solr_request(core, params, silent=False, validate=False):
|
|
|
22
38
|
validate (bool, optional): default False
|
|
23
39
|
If True, validates the parameters against the core schema and raises warnings
|
|
24
40
|
if any parameter seems invalid.
|
|
41
|
+
url_only (bool, optional): default False
|
|
42
|
+
If true, returns the request URL but no data.
|
|
43
|
+
timeout (int or float, optional): default 10
|
|
44
|
+
Number of seconds to wait for the API request before timing out.
|
|
25
45
|
|
|
26
46
|
|
|
27
47
|
Returns:
|
|
28
|
-
|
|
29
|
-
|
|
48
|
+
Union[Tuple[int, pandas.DataFrame], Tuple[str, None]]:
|
|
49
|
+
- If url_only is False:
|
|
50
|
+
A tuple containing:
|
|
51
|
+
num_found (int): Number of documents found.
|
|
52
|
+
df (pandas.DataFrame): DataFrame object with the information requested.
|
|
53
|
+
|
|
54
|
+
- If url_only is True:
|
|
55
|
+
A tuple containing:
|
|
56
|
+
url (str): The URL of the request if status_code is 200, otherwise None.
|
|
57
|
+
None: Placeholder for consistency.
|
|
58
|
+
|
|
30
59
|
|
|
31
60
|
Example query:
|
|
32
61
|
num_found, df = solr_request(
|
|
@@ -69,7 +98,17 @@ def solr_request(core, params, silent=False, validate=False):
|
|
|
69
98
|
base_url = "https://www.ebi.ac.uk/mi/impc/solr/"
|
|
70
99
|
solr_url = base_url + core + "/select"
|
|
71
100
|
|
|
72
|
-
response = requests.get(solr_url, params=params)
|
|
101
|
+
response = requests.get(solr_url, params=params, timeout=timeout)
|
|
102
|
+
|
|
103
|
+
if url_only:
|
|
104
|
+
if response.status_code == 200:
|
|
105
|
+
print(response.request.url)
|
|
106
|
+
return response.request.url, None
|
|
107
|
+
else:
|
|
108
|
+
print(f"Error: {response.status_code}\n{response.text}")
|
|
109
|
+
return None, None
|
|
110
|
+
|
|
111
|
+
|
|
73
112
|
if not silent:
|
|
74
113
|
print(f"\nYour request:\n{response.request.url}\n")
|
|
75
114
|
|
|
@@ -103,7 +142,7 @@ def solr_request(core, params, silent=False, validate=False):
|
|
|
103
142
|
print("Error:", response.status_code, response.text)
|
|
104
143
|
|
|
105
144
|
|
|
106
|
-
def _process_faceting(data, params):
|
|
145
|
+
def _process_faceting(data: Dict[str, Any], params: Dict[str, Any]) -> pd.DataFrame:
|
|
107
146
|
"""Processes the faceting data from an API response.
|
|
108
147
|
Note: This function should not be used alone but only as a helper function for solr_request().
|
|
109
148
|
|
|
@@ -136,7 +175,9 @@ def _process_faceting(data, params):
|
|
|
136
175
|
|
|
137
176
|
|
|
138
177
|
# Batch request based on solr_request.
|
|
139
|
-
def batch_request(
|
|
178
|
+
def batch_request(
|
|
179
|
+
core: str, params: Dict[str, Any], batch_size: int
|
|
180
|
+
) -> pd.DataFrame:
|
|
140
181
|
"""Calls `solr_request` multiple times with `params`
|
|
141
182
|
to retrieve results in chunk `batch_size` rows at a time.
|
|
142
183
|
|