ialirt-data-access 0.1.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.
- ialirt_data_access-0.1.0/LICENSE +21 -0
- ialirt_data_access-0.1.0/PKG-INFO +115 -0
- ialirt_data_access-0.1.0/README.md +81 -0
- ialirt_data_access-0.1.0/ialirt_data_access/__init__.py +25 -0
- ialirt_data_access-0.1.0/ialirt_data_access/cli.py +148 -0
- ialirt_data_access-0.1.0/ialirt_data_access/io.py +147 -0
- ialirt_data_access-0.1.0/pyproject.toml +68 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 IMAP Science Operations Center
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: ialirt-data-access
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: I-ALiRT Data Access
|
|
5
|
+
License: MIT
|
|
6
|
+
Keywords: IMAP,SDC,SOC,SDS,Science Operations
|
|
7
|
+
Author: IMAP SDC Developers
|
|
8
|
+
Author-email: imap-sdc@lists.lasp.colorado.edu
|
|
9
|
+
Requires-Python: >=3.9,<4
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Natural Language :: English
|
|
13
|
+
Classifier: Operating System :: MacOS
|
|
14
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
15
|
+
Classifier: Operating System :: POSIX
|
|
16
|
+
Classifier: Operating System :: Unix
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Topic :: Scientific/Engineering
|
|
24
|
+
Classifier: Topic :: Software Development
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Provides-Extra: test
|
|
27
|
+
Requires-Dist: pre-commit (>=3.3.3,<4.0.0) ; extra == "dev"
|
|
28
|
+
Requires-Dist: pytest (>=6.2.5) ; extra == "test"
|
|
29
|
+
Requires-Dist: pytest-cov (>=4.0.0,<5.0.0) ; extra == "test"
|
|
30
|
+
Requires-Dist: ruff (==0.2.1) ; extra == "dev"
|
|
31
|
+
Project-URL: homepage, https://github.com/IMAP-Science-Operations-Center
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
|
|
34
|
+
# I-ALiRT Data Access Package
|
|
35
|
+
|
|
36
|
+
This lightweight Python package allows users to query and download log data.
|
|
37
|
+
|
|
38
|
+
## Command Line Utility
|
|
39
|
+
|
|
40
|
+
### To install
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
pip install ialirt-data-access
|
|
44
|
+
ialirt-data-access -h
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Query / Search for logs
|
|
48
|
+
|
|
49
|
+
Find all files from a given year, day of year, and instance
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
$ ialirt_data_access --url <url> ialirt-log-query --year <year> --doy <doy> --instance <instance>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Download logs
|
|
56
|
+
|
|
57
|
+
Download a log and place in Downloads directory or optionally specify another local directory by appending --downloads_dir <directory> to the command
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
$ ialirt_data_access --url <url> ialirt-log-download ----filename <filename>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Importing as a package
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
import ialirt_data_access
|
|
67
|
+
|
|
68
|
+
# Search for files
|
|
69
|
+
results = ialirt_data_access.query(year="2024", doy="045", instance="1")
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Configuration
|
|
73
|
+
|
|
74
|
+
### Data Access URL
|
|
75
|
+
|
|
76
|
+
To change the default URL that the package accesses, you can set
|
|
77
|
+
the environment variable ``IALIRT_DATA_ACCESS_URL`` or within the
|
|
78
|
+
package ``ialirt_data_access.config["DATA_ACCESS_URL"]``. The default
|
|
79
|
+
is the development server ``https://ialirt.dev.imap-mission.com``.
|
|
80
|
+
|
|
81
|
+
## Troubleshooting
|
|
82
|
+
|
|
83
|
+
### Network issues
|
|
84
|
+
|
|
85
|
+
#### SSL
|
|
86
|
+
|
|
87
|
+
If you encounter SSL errors similar to the following:
|
|
88
|
+
|
|
89
|
+
```text
|
|
90
|
+
urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:997)>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
That generally means the Python environment you're using is not finding your system's root
|
|
94
|
+
certificates properly. This means you need to tell Python how to find those certificates
|
|
95
|
+
with the following potential solutions.
|
|
96
|
+
|
|
97
|
+
1. **Upgrade the certifi package**
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
pip install --upgrade certifi
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
2. **Install system certificates**
|
|
104
|
+
Depending on the Python version you installed the program with the command will look something like this:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
/Applications/Python\ 3.10/Install\ Certificates.command
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
#### HTTP Error 502: Bad Gateway
|
|
111
|
+
|
|
112
|
+
This could mean that the service is temporarily down. If you
|
|
113
|
+
continue to encounter this, reach out to the IMAP SDC at
|
|
114
|
+
<imap-sdc@lasp.colorado.edu>.
|
|
115
|
+
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# I-ALiRT Data Access Package
|
|
2
|
+
|
|
3
|
+
This lightweight Python package allows users to query and download log data.
|
|
4
|
+
|
|
5
|
+
## Command Line Utility
|
|
6
|
+
|
|
7
|
+
### To install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install ialirt-data-access
|
|
11
|
+
ialirt-data-access -h
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
### Query / Search for logs
|
|
15
|
+
|
|
16
|
+
Find all files from a given year, day of year, and instance
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
$ ialirt_data_access --url <url> ialirt-log-query --year <year> --doy <doy> --instance <instance>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Download logs
|
|
23
|
+
|
|
24
|
+
Download a log and place in Downloads directory or optionally specify another local directory by appending --downloads_dir <directory> to the command
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
$ ialirt_data_access --url <url> ialirt-log-download ----filename <filename>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Importing as a package
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
import ialirt_data_access
|
|
34
|
+
|
|
35
|
+
# Search for files
|
|
36
|
+
results = ialirt_data_access.query(year="2024", doy="045", instance="1")
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Configuration
|
|
40
|
+
|
|
41
|
+
### Data Access URL
|
|
42
|
+
|
|
43
|
+
To change the default URL that the package accesses, you can set
|
|
44
|
+
the environment variable ``IALIRT_DATA_ACCESS_URL`` or within the
|
|
45
|
+
package ``ialirt_data_access.config["DATA_ACCESS_URL"]``. The default
|
|
46
|
+
is the development server ``https://ialirt.dev.imap-mission.com``.
|
|
47
|
+
|
|
48
|
+
## Troubleshooting
|
|
49
|
+
|
|
50
|
+
### Network issues
|
|
51
|
+
|
|
52
|
+
#### SSL
|
|
53
|
+
|
|
54
|
+
If you encounter SSL errors similar to the following:
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:997)>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
That generally means the Python environment you're using is not finding your system's root
|
|
61
|
+
certificates properly. This means you need to tell Python how to find those certificates
|
|
62
|
+
with the following potential solutions.
|
|
63
|
+
|
|
64
|
+
1. **Upgrade the certifi package**
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
pip install --upgrade certifi
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
2. **Install system certificates**
|
|
71
|
+
Depending on the Python version you installed the program with the command will look something like this:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
/Applications/Python\ 3.10/Install\ Certificates.command
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
#### HTTP Error 502: Bad Gateway
|
|
78
|
+
|
|
79
|
+
This could mean that the service is temporarily down. If you
|
|
80
|
+
continue to encounter this, reach out to the IMAP SDC at
|
|
81
|
+
<imap-sdc@lasp.colorado.edu>.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""Data Access for I-ALiRT.
|
|
2
|
+
|
|
3
|
+
This package contains the data access tools for the I-ALiRT logs.
|
|
4
|
+
Provides a convenient way to query and download log files.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
|
|
9
|
+
from ialirt_data_access.io import download, query
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"query",
|
|
13
|
+
"download",
|
|
14
|
+
]
|
|
15
|
+
__version__ = "0.1.0"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
config = {
|
|
19
|
+
"DATA_ACCESS_URL": os.getenv("IALIRT_DATA_ACCESS_URL")
|
|
20
|
+
or "https://ialirt.dev.imap-mission.com",
|
|
21
|
+
}
|
|
22
|
+
"""Settings configuration dictionary.
|
|
23
|
+
|
|
24
|
+
DATA_ACCESS_URL : This is the URL of the data access API.
|
|
25
|
+
"""
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
"""Command line interface to query IALIRT logs in the s3 bucket.
|
|
4
|
+
|
|
5
|
+
Usage:
|
|
6
|
+
ialirt_data_access --debug --url <url> ialirt-log-query
|
|
7
|
+
--year <year> --doy <doy> --instance <instance>
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import argparse
|
|
11
|
+
import logging
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
|
|
14
|
+
import ialirt_data_access
|
|
15
|
+
|
|
16
|
+
logger = logging.getLogger(__name__)
|
|
17
|
+
logging.basicConfig(level=logging.INFO)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _download_parser(args: argparse.Namespace):
|
|
21
|
+
"""Download an I-ALiRT log.
|
|
22
|
+
|
|
23
|
+
Parameters
|
|
24
|
+
----------
|
|
25
|
+
args : argparse.Namespace
|
|
26
|
+
An object containing the parsed arguments and their values
|
|
27
|
+
"""
|
|
28
|
+
try:
|
|
29
|
+
ialirt_data_access.download(args.filename, args.downloads_dir)
|
|
30
|
+
except ialirt_data_access.io.IALIRTDataAccessError as e:
|
|
31
|
+
print(e)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _query_parser(args: argparse.Namespace):
|
|
35
|
+
"""Query the I-ALiRT log API.
|
|
36
|
+
|
|
37
|
+
Parameters
|
|
38
|
+
----------
|
|
39
|
+
args : argparse.Namespace
|
|
40
|
+
Parsed arguments including year, doy, and instance.
|
|
41
|
+
|
|
42
|
+
Returns
|
|
43
|
+
-------
|
|
44
|
+
None
|
|
45
|
+
"""
|
|
46
|
+
query_params = {
|
|
47
|
+
"year": args.year,
|
|
48
|
+
"doy": args.doy,
|
|
49
|
+
"instance": args.instance,
|
|
50
|
+
}
|
|
51
|
+
try:
|
|
52
|
+
query_results = ialirt_data_access.query(**query_params)
|
|
53
|
+
logger.info("Query results: %s", query_results)
|
|
54
|
+
print(query_results)
|
|
55
|
+
except ialirt_data_access.io.IALIRTDataAccessError as e:
|
|
56
|
+
logger.error("An error occurred: %s", e)
|
|
57
|
+
print(e)
|
|
58
|
+
return
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def main():
|
|
62
|
+
"""Parse the command line arguments.
|
|
63
|
+
|
|
64
|
+
Run the command line interface to the I-ALiRT Data Access API.
|
|
65
|
+
"""
|
|
66
|
+
url_help = (
|
|
67
|
+
"URL of the IALIRT API. "
|
|
68
|
+
"The default is https://ialirt.dev.imap-mission.com. This can also be "
|
|
69
|
+
"set using the IALIRT_DATA_ACCESS_URL environment variable."
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
parser = argparse.ArgumentParser(prog="ialirt-data-access")
|
|
73
|
+
parser.add_argument(
|
|
74
|
+
"--version",
|
|
75
|
+
action="version",
|
|
76
|
+
version=f"%(prog)s {ialirt_data_access.__version__}",
|
|
77
|
+
)
|
|
78
|
+
parser.add_argument("--url", type=str, required=False, help=url_help)
|
|
79
|
+
# Logging level
|
|
80
|
+
parser.add_argument(
|
|
81
|
+
"--vv",
|
|
82
|
+
"--debug",
|
|
83
|
+
help="Print lots of debugging statements",
|
|
84
|
+
action="store_const",
|
|
85
|
+
dest="loglevel",
|
|
86
|
+
const=logging.DEBUG,
|
|
87
|
+
default=logging.WARNING,
|
|
88
|
+
)
|
|
89
|
+
parser.add_argument(
|
|
90
|
+
"-v",
|
|
91
|
+
"--verbose",
|
|
92
|
+
help="Add verbose output",
|
|
93
|
+
action="store_const",
|
|
94
|
+
dest="loglevel",
|
|
95
|
+
const=logging.INFO,
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
subparsers = parser.add_subparsers(required=True)
|
|
99
|
+
|
|
100
|
+
# Query command
|
|
101
|
+
query_parser = subparsers.add_parser("ialirt-log-query")
|
|
102
|
+
query_parser.add_argument(
|
|
103
|
+
"--year", type=str, required=True, help="Year of the logs (e.g., 2024)."
|
|
104
|
+
)
|
|
105
|
+
query_parser.add_argument(
|
|
106
|
+
"--doy", type=str, required=True, help="Day of year of the logs (e.g., 045)."
|
|
107
|
+
)
|
|
108
|
+
query_parser.add_argument(
|
|
109
|
+
"--instance",
|
|
110
|
+
type=str,
|
|
111
|
+
required=True,
|
|
112
|
+
help="Instance number (e.g., 1).",
|
|
113
|
+
choices=[
|
|
114
|
+
"1",
|
|
115
|
+
"2",
|
|
116
|
+
],
|
|
117
|
+
)
|
|
118
|
+
query_parser.set_defaults(func=_query_parser)
|
|
119
|
+
|
|
120
|
+
# Download command
|
|
121
|
+
download_parser = subparsers.add_parser("ialirt-log-download")
|
|
122
|
+
download_parser.add_argument(
|
|
123
|
+
"--filename",
|
|
124
|
+
type=str,
|
|
125
|
+
required=True,
|
|
126
|
+
help="Example: flight_iois.log.YYYY-DOYTHH:MM:SS.ssssss",
|
|
127
|
+
)
|
|
128
|
+
download_parser.add_argument(
|
|
129
|
+
"--downloads_dir",
|
|
130
|
+
type=Path,
|
|
131
|
+
required=False,
|
|
132
|
+
help="Example: flight_iois.log.YYYY-DOYTHH:MM:SS.ssssss",
|
|
133
|
+
)
|
|
134
|
+
download_parser.set_defaults(func=_download_parser)
|
|
135
|
+
|
|
136
|
+
# Parse the arguments and set the values
|
|
137
|
+
args = parser.parse_args()
|
|
138
|
+
logging.basicConfig(level=args.loglevel)
|
|
139
|
+
|
|
140
|
+
if args.url:
|
|
141
|
+
# Explicit url from the command line
|
|
142
|
+
ialirt_data_access.config["DATA_ACCESS_URL"] = args.url
|
|
143
|
+
|
|
144
|
+
args.func(args)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
if __name__ == "__main__":
|
|
148
|
+
main()
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"""The ``io`` module."""
|
|
2
|
+
|
|
3
|
+
import contextlib
|
|
4
|
+
import json
|
|
5
|
+
import logging
|
|
6
|
+
import urllib.request
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import Optional
|
|
9
|
+
from urllib.error import HTTPError, URLError
|
|
10
|
+
from urllib.parse import urlencode
|
|
11
|
+
|
|
12
|
+
import ialirt_data_access
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class IALIRTDataAccessError(Exception):
|
|
18
|
+
"""Base class for exceptions in this module."""
|
|
19
|
+
|
|
20
|
+
pass
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@contextlib.contextmanager
|
|
24
|
+
def _get_url_response(request: urllib.request.Request):
|
|
25
|
+
"""Get the response from a URL request.
|
|
26
|
+
|
|
27
|
+
This is a helper function to make it easier to handle
|
|
28
|
+
the different types of errors that can occur when
|
|
29
|
+
opening a URL and write out the response body.
|
|
30
|
+
"""
|
|
31
|
+
try:
|
|
32
|
+
# Open the URL and yield the response
|
|
33
|
+
with urllib.request.urlopen(request) as response:
|
|
34
|
+
yield response
|
|
35
|
+
|
|
36
|
+
except HTTPError as e:
|
|
37
|
+
message = (
|
|
38
|
+
f"HTTP Error: {e.code} - {e.reason}\n"
|
|
39
|
+
f"Server Message: {e.read().decode('utf-8')}"
|
|
40
|
+
)
|
|
41
|
+
raise IALIRTDataAccessError(message) from e
|
|
42
|
+
except URLError as e:
|
|
43
|
+
message = f"URL Error: {e.reason}"
|
|
44
|
+
raise IALIRTDataAccessError(message) from e
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _validate_query_params(year: str, doy: str, instance: str):
|
|
48
|
+
"""Validate the query parameters for the IALIRT log API.
|
|
49
|
+
|
|
50
|
+
Parameters
|
|
51
|
+
----------
|
|
52
|
+
year : str
|
|
53
|
+
Year, must be a 4-digit string (e.g., '2024').
|
|
54
|
+
doy : str
|
|
55
|
+
Day of year, must be a string between '001' and '365'.
|
|
56
|
+
instance : str
|
|
57
|
+
Instance number, must be either '1' or '2'.
|
|
58
|
+
|
|
59
|
+
Raises
|
|
60
|
+
------
|
|
61
|
+
ValueError
|
|
62
|
+
If any parameter is invalid.
|
|
63
|
+
"""
|
|
64
|
+
if not (year.isdigit() and len(year) == 4):
|
|
65
|
+
raise ValueError("Year must be a 4-digit string (e.g., '2024').")
|
|
66
|
+
if not (doy.isdigit() and 1 <= int(doy) <= 366):
|
|
67
|
+
raise ValueError("DOY must be a string between '001' and '365'.")
|
|
68
|
+
if instance not in {"1", "2"}:
|
|
69
|
+
raise ValueError("Instance must be '1' or '2'.")
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def query(*, year: str, doy: str, instance: str) -> list[str]:
|
|
73
|
+
"""Query the logs.
|
|
74
|
+
|
|
75
|
+
Parameters
|
|
76
|
+
----------
|
|
77
|
+
year : str
|
|
78
|
+
Year
|
|
79
|
+
doy : str
|
|
80
|
+
Day of year
|
|
81
|
+
instance : str
|
|
82
|
+
Instance number
|
|
83
|
+
|
|
84
|
+
Returns
|
|
85
|
+
-------
|
|
86
|
+
list
|
|
87
|
+
List of files matching the query
|
|
88
|
+
"""
|
|
89
|
+
query_params = {
|
|
90
|
+
"year": year,
|
|
91
|
+
"doy": doy,
|
|
92
|
+
"instance": instance,
|
|
93
|
+
}
|
|
94
|
+
_validate_query_params(**query_params)
|
|
95
|
+
|
|
96
|
+
url = f"{ialirt_data_access.config['DATA_ACCESS_URL']}"
|
|
97
|
+
url += f"/ialirt-log-query?{urlencode(query_params)}"
|
|
98
|
+
|
|
99
|
+
logger.info("Querying for %s with url %s", query_params, url)
|
|
100
|
+
request = urllib.request.Request(url, method="GET")
|
|
101
|
+
with _get_url_response(request) as response:
|
|
102
|
+
# Retrieve the response as a list of files
|
|
103
|
+
items = response.read().decode("utf-8")
|
|
104
|
+
logger.debug("Received response: %s", items)
|
|
105
|
+
# Decode the JSON string into a list
|
|
106
|
+
items = json.loads(items)
|
|
107
|
+
logger.debug("Decoded JSON: %s", items)
|
|
108
|
+
return items
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def download(filename: str, downloads_dir: Optional[Path] = None) -> Path:
|
|
112
|
+
"""Download the logs.
|
|
113
|
+
|
|
114
|
+
Parameters
|
|
115
|
+
----------
|
|
116
|
+
filename : str
|
|
117
|
+
Filename
|
|
118
|
+
downloads_dir : Path
|
|
119
|
+
Directory to save the file
|
|
120
|
+
|
|
121
|
+
Returns
|
|
122
|
+
-------
|
|
123
|
+
destination: pathlib.Path
|
|
124
|
+
Path to the downloaded file
|
|
125
|
+
"""
|
|
126
|
+
if downloads_dir is None:
|
|
127
|
+
downloads_dir = Path.home() / "Downloads"
|
|
128
|
+
|
|
129
|
+
url = f"{ialirt_data_access.config['DATA_ACCESS_URL']}"
|
|
130
|
+
url += f"/ialirt-log-download/logs/{filename}"
|
|
131
|
+
|
|
132
|
+
downloads_dir.mkdir(parents=True, exist_ok=True)
|
|
133
|
+
destination = downloads_dir / filename
|
|
134
|
+
|
|
135
|
+
if destination.exists():
|
|
136
|
+
logger.info("File already exists: %s", destination)
|
|
137
|
+
return destination
|
|
138
|
+
|
|
139
|
+
logger.info("Downloading %s with url %s", filename, url)
|
|
140
|
+
request = urllib.request.Request(url, method="GET")
|
|
141
|
+
with _get_url_response(request) as response:
|
|
142
|
+
logger.debug("Received response: %s", response)
|
|
143
|
+
with open(destination, "wb") as local_file:
|
|
144
|
+
local_file.write(response.read())
|
|
145
|
+
print(f"Successfully downloaded the file to: {destination}")
|
|
146
|
+
|
|
147
|
+
return destination
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["poetry-core"]
|
|
3
|
+
build-backend = "poetry.core.masonry.api"
|
|
4
|
+
|
|
5
|
+
[tool.poetry]
|
|
6
|
+
name = "ialirt-data-access"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "I-ALiRT Data Access"
|
|
9
|
+
authors = ["IMAP SDC Developers <imap-sdc@lists.lasp.colorado.edu>"]
|
|
10
|
+
readme = "README.md"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
keywords = ["IMAP", "SDC", "SOC", "SDS", "Science Operations"]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Development Status :: 3 - Alpha",
|
|
15
|
+
"License :: OSI Approved :: MIT License",
|
|
16
|
+
"Natural Language :: English",
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Programming Language :: Python :: 3.9",
|
|
19
|
+
"Programming Language :: Python :: 3.10",
|
|
20
|
+
"Programming Language :: Python :: 3.11",
|
|
21
|
+
"Programming Language :: Python :: 3.12",
|
|
22
|
+
"Topic :: Software Development",
|
|
23
|
+
"Topic :: Scientific/Engineering",
|
|
24
|
+
"Operating System :: Microsoft :: Windows",
|
|
25
|
+
"Operating System :: POSIX",
|
|
26
|
+
"Operating System :: Unix",
|
|
27
|
+
"Operating System :: MacOS",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
[tool.poetry.scripts]
|
|
31
|
+
ialirt-data-access = "ialirt_data_access.cli:main"
|
|
32
|
+
|
|
33
|
+
[tool.poetry.urls]
|
|
34
|
+
homepage = "https://github.com/IMAP-Science-Operations-Center"
|
|
35
|
+
|
|
36
|
+
[tool.poetry.dependencies]
|
|
37
|
+
python = ">=3.9,<4"
|
|
38
|
+
# Optional dependencies
|
|
39
|
+
pre-commit = {version="^3.3.3", optional=true}
|
|
40
|
+
pytest = {version=">=6.2.5", optional=true}
|
|
41
|
+
pytest-cov = {version="^4.0.0", optional=true}
|
|
42
|
+
ruff = {version="==0.2.1", optional=true}
|
|
43
|
+
|
|
44
|
+
[tool.poetry.extras]
|
|
45
|
+
dev = ["pre-commit", "ruff"]
|
|
46
|
+
test = ["pytest", "pytest-cov"]
|
|
47
|
+
|
|
48
|
+
[tool.pytest.ini_options]
|
|
49
|
+
testpaths = [
|
|
50
|
+
"tests",
|
|
51
|
+
]
|
|
52
|
+
addopts = "-ra"
|
|
53
|
+
|
|
54
|
+
[tool.ruff]
|
|
55
|
+
target-version = "py39"
|
|
56
|
+
lint.select = ["B", "E", "D", "F", "I", "N", "S", "W", "PL", "PT", "UP", "RUF"]
|
|
57
|
+
# D104: Missing docstring in public package
|
|
58
|
+
# D203: 1 blank line required before class docstring
|
|
59
|
+
# D213: Multi-line docstring summary should start at the second line
|
|
60
|
+
# D413: Missing blank line after last section
|
|
61
|
+
# PLR2004: Magic value in comparison
|
|
62
|
+
lint.ignore = ["D104", "D203", "D213", "D413", "PLR2004"]
|
|
63
|
+
|
|
64
|
+
[tool.ruff.lint.per-file-ignores]
|
|
65
|
+
# S101: Use of assert detected
|
|
66
|
+
"tests/*" = ["S101"]
|
|
67
|
+
# S310: Audit URL open for permitted schemes.
|
|
68
|
+
"ialirt_data_access/*" = ["S310"]
|