-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adds ISD Compression #606
Adds ISD Compression #606
Changes from all commits
bb9b9e8
c56638e
33d5d77
ac5d28f
0674abc
cba9259
5d02d26
4b3f9fc
13e460e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,9 @@ | |
import sys | ||
|
||
import ale | ||
import brotli | ||
import json | ||
from ale.drivers import AleJsonEncoder | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
@@ -57,6 +60,13 @@ def main(): | |
action="store_true", | ||
help="Display information as program runs." | ||
) | ||
parser.add_argument( | ||
"-c", "--compress", | ||
action="store_true", | ||
help="Output a compressed isd json file with .br file extension. " | ||
"Ale uses the brotli compression algorithm. " | ||
"To decompress an isd file run: python -c \"import ale.isd_generate as isdg; isdg.decompress_json('/path/to/isd.br')\"" | ||
) | ||
parser.add_argument( | ||
"-i", "--only_isis_spice", | ||
action="store_true", | ||
|
@@ -109,7 +119,7 @@ def main(): | |
|
||
if len(args.input) == 1: | ||
try: | ||
file_to_isd(args.input[0], args.out, kernels=k, log_level=log_level, only_isis_spice=args.only_isis_spice, only_naif_spice=args.only_naif_spice, local=args.local) | ||
file_to_isd(args.input[0], args.out, kernels=k, log_level=log_level, compress=args.compress, only_isis_spice=args.only_isis_spice, only_naif_spice=args.only_naif_spice, local=args.local) | ||
except Exception as err: | ||
# Seriously, this just throws a generic Exception? | ||
sys.exit(f"File {args.input[0]}: {err}") | ||
|
@@ -143,6 +153,7 @@ def file_to_isd( | |
out: os.PathLike = None, | ||
kernels: list = None, | ||
log_level=logging.WARNING, | ||
compress=False, | ||
only_isis_spice=False, | ||
only_naif_spice=False, | ||
local=False, | ||
|
@@ -185,11 +196,61 @@ def file_to_isd( | |
else: | ||
usgscsm_str = ale.loads(file, props=props, verbose=log_level>logging.INFO, only_isis_spice=only_isis_spice, only_naif_spice=only_naif_spice) | ||
|
||
logger.info(f"Writing: {isd_file}") | ||
isd_file.write_text(usgscsm_str) | ||
if compress: | ||
logger.info(f"Writing: {os.path.splitext(isd_file)[0] + '.br'}") | ||
compress_json(usgscsm_str, os.path.splitext(isd_file)[0] + '.br') | ||
else: | ||
logger.info(f"Writing: {isd_file}") | ||
isd_file.write_text(usgscsm_str) | ||
|
||
return | ||
|
||
def compress_json(json_data, output_file): | ||
""" | ||
Compresses inputted JSON data using brotli compression algorithm. | ||
|
||
Parameters | ||
---------- | ||
json_data : str | ||
JSON data | ||
|
||
output_file : str | ||
The output compressed file path with .br extension. | ||
|
||
""" | ||
binary_json = json.dumps(json_data).encode('utf-8') | ||
|
||
if not os.path.splitext(output_file)[1] == '.br': | ||
raise ValueError("Output file {} is not a valid .br file extension".format(output_file.split(".")[1])) | ||
|
||
with open(output_file, 'wb') as f: | ||
f.write(brotli.compress(binary_json)) | ||
|
||
|
||
def decompress_json(compressed_json_file): | ||
""" | ||
Decompresses inputted .br file. | ||
|
||
Parameters | ||
---------- | ||
compressed_json_file : str | ||
.br file path | ||
|
||
Returns | ||
------- | ||
str | ||
Decompressed .json file path | ||
""" | ||
if not os.path.splitext(compressed_json_file)[1] == '.br': | ||
raise ValueError("Inputted file {} is not a valid .br file extension".format(compressed_json_file)) | ||
with open(compressed_json_file, 'rb') as f: | ||
data = f.read() | ||
with open(compressed_json_file, 'wb') as f: | ||
f.write(brotli.decompress(data)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am confused by the decompression here. Is this read the compressed and then write the decompressed to disk? Would it make more sense to simply pipe the decompressed to stdout? That would be more bash-like. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is for situations where a user wants to revert to a readable JSON file saved locally. We could add a function to read the JSON from binary format, if you think that would be appropriate. |
||
|
||
os.rename(compressed_json_file, os.path.splitext(compressed_json_file)[0] + '.json') | ||
|
||
return os.path.splitext(compressed_json_file)[0] + '.json' | ||
|
||
if __name__ == "__main__": | ||
try: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,3 +22,4 @@ dependencies: | |
- pytest-cov | ||
- networkx | ||
- breathe | ||
- brotli |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import pytest | ||
import json | ||
import os | ||
|
||
import ale | ||
|
||
import ale.isd_generate as isdg | ||
|
||
from conftest import get_image_label, get_isd, compare_dicts | ||
|
||
|
||
def test_compress_decompress(): | ||
label = get_image_label("EN1072174528M") | ||
isd_str = get_isd("messmdis_isis") | ||
|
||
compressed_file = os.path.splitext(label)[0] + '.br' | ||
|
||
isdg.compress_json(isd_str, compressed_file) | ||
|
||
decompressed_file = isdg.decompress_json(compressed_file) | ||
|
||
with open(decompressed_file, 'r') as fp: | ||
isis_dict = json.load(fp) | ||
|
||
comparison = compare_dicts(isis_dict, isd_str) | ||
assert comparison == [] | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool! So using this, one could write directly to compressed. Then a SET could read the compressed ISD straight to memory and use it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think anything in ale takes in an isd file. I'm working on having knoten take in these compressed isds directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool! I didn't mean for this comment to spill into more work over there! Much appreciated.