Skip to content

Commit cd3a053

Browse files
committed
cache catalog and capabilities
1 parent 646a99e commit cd3a053

9 files changed

Lines changed: 177 additions & 152 deletions

File tree

hapiclient/__init__.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,3 @@
2222
import warnings
2323
warnings.filterwarnings("ignore", message=".*urllib3.*OpenSSL.*")
2424

25-
if sys.version_info[0] < 3:
26-
# Python 2.7
27-
reload(sys)
28-
sys.setdefaultencoding('utf8')
29-

hapiclient/cache.py

Lines changed: 55 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,19 @@ def cachedir(*args):
3232
return os.path.join(args[0], server2dirname(args[1]))
3333

3434

35-
def request2path(*args):
36-
# request2path(server, dataset, parameters, start, stop)
37-
# request2path(server, dataset, parameters, start, stop, cachedir)
35+
def request2path(server, dataset=None, parameters=None, start=None, stop=None, cache_dir=None, endpoint=None):
36+
3837
import os
3938
import re
4039
import platform
4140

42-
if len(args) == 5:
43-
# Use default if cachedir not given.
41+
if cache_dir is None:
42+
# Use default if cache_dir not given.
4443
cachedirectory = cachedir()
4544
else:
46-
cachedirectory = args[5]
45+
cachedirectory = cache_dir
4746

48-
args = list(args)
47+
args = [server, dataset, parameters, start, stop]
4948

5049
# Replace forbidden characters in directory and filename
5150
# Replacements assume that there will be no name collisions,
@@ -68,36 +67,58 @@ def request2path(*args):
6867
)
6968

7069
for element in reps:
71-
args[1] = re.sub(element[0], element[1], args[1])
72-
args[2] = re.sub(element[0], element[1], args[2])
70+
if dataset is not None:
71+
dataset = re.sub(element[0], element[1], dataset)
72+
if parameters is not None:
73+
parameters = re.sub(element[0], element[1], parameters)
7374

7475
else:
75-
args[1] = re.sub('/','@forwardslash@',args[1])
76-
args[2] = re.sub('/','@forwardslash@',args[2])
76+
if dataset is not None:
77+
dataset = re.sub('/','@forwardslash@', dataset)
78+
if parameters is not None:
79+
parameters = re.sub('/','@forwardslash@', parameters)
7780

7881
# To shorten filenames.
79-
args[3] = re.sub(r'-|:|\.|Z', '', args[3])
80-
args[4] = re.sub(r'-|:|\.|Z', '', args[4])
82+
if start is not None:
83+
start = re.sub(r'-|:|\.|Z', '', start)
84+
if stop is not None:
85+
stop = re.sub(r'-|:|\.|Z', '', stop)
8186

8287
# URL subdirectory
8388
urldirectory = server2dirname(args[0])
84-
fname = '%s_%s_%s_%s' % (args[1], args[2], args[3], args[4])
8589

86-
return os.path.join(cachedirectory, urldirectory, fname)
90+
if not dataset and not endpoint:
91+
raise ValueError('Either dataset or endpoint must be specified.')
92+
93+
if endpoint is None:
94+
endpoint = ''
95+
96+
if dataset is None:
97+
fname = endpoint
98+
else:
99+
fname = dataset
100+
if parameters is not None:
101+
fname += '_' + parameters
102+
if start is not None:
103+
fname += '_' + start
104+
if stop is not None:
105+
fname += '_' + stop
106+
107+
return os.path.join(cachedirectory, urldirectory, endpoint, fname)
87108

88109

89-
def meta_cache_paths(SERVER, DATASET, cachedir):
110+
def meta_cache_paths(server, dataset, endpoint, cache_dir):
90111
"""Return dict with metadata cache directory and file names."""
91112

92-
fname_root = request2path(SERVER, DATASET, '', '', '', cachedir)
113+
fname_root = request2path(server, dataset, cache_dir=cache_dir, endpoint=endpoint)
93114

94115
return {
95116
'json': fname_root + '.json',
96117
'pkl': fname_root + '.pkl'
97118
}
98119

99120

100-
def meta_cache_read(SERVER, DATASET, opts):
121+
def meta_cache_read(server, dataset, endpoint, opts):
101122
"""Read metadata from PKL cache. Returns meta dict or None."""
102123

103124
import os
@@ -106,10 +127,13 @@ def meta_cache_read(SERVER, DATASET, opts):
106127
from hapiclient.log import log
107128

108129
if not opts["usecache"]:
109-
log('Not checking metadata cache because usecache is False.')
130+
if endpoint in ['', 'info']:
131+
log(f'Not checking metadata cache for /info?dataset={dataset} response because usecache is False.')
132+
else:
133+
log(f'Not checking metadata cache for /{endpoint} response because usecache is False.')
110134
return None
111135

112-
fnamepkl = meta_cache_paths(SERVER, DATASET, opts['cachedir'])['pkl']
136+
fnamepkl = meta_cache_paths(server, dataset, endpoint, opts['cachedir'])['pkl']
113137
if os.path.isfile(fnamepkl):
114138
log('Reading %s' % os.path.basename(fnamepkl))
115139
with open(fnamepkl, 'rb') as f:
@@ -121,7 +145,7 @@ def meta_cache_read(SERVER, DATASET, opts):
121145
return None
122146

123147

124-
def meta_cache_write(meta, SERVER, DATASET, opts):
148+
def meta_cache_write(meta, server, dataset, endpoint, opts):
125149
"""Write metadata to JSON and PKL cache files."""
126150

127151
import os
@@ -132,7 +156,7 @@ def meta_cache_write(meta, SERVER, DATASET, opts):
132156
if not opts["cache"]:
133157
return
134158

135-
paths = meta_cache_paths(SERVER, DATASET, opts['cachedir'])
159+
paths = meta_cache_paths(server, dataset, endpoint, opts['cachedir'])
136160
fnamejson, fnamepkl = paths['json'], paths['pkl']
137161

138162
log('Writing %s ' % os.path.basename(fnamejson))
@@ -142,10 +166,10 @@ def meta_cache_write(meta, SERVER, DATASET, opts):
142166
write_atomic(fnamepkl, meta)
143167

144168

145-
def data_cache_paths(SERVER, DATASET, PARAMETERS, START, STOP, cachedir):
169+
def data_cache_paths(server, dataset, parameters, start, stop, cache_dir):
146170
"""Return dict with data cache file names."""
147171

148-
fname_root = request2path(SERVER, DATASET, PARAMETERS, START, STOP, cachedir)
172+
fname_root = request2path(server, dataset, parameters, start, stop, cache_dir, 'data')
149173

150174
return {
151175
'csv': fname_root + '.csv',
@@ -155,7 +179,7 @@ def data_cache_paths(SERVER, DATASET, PARAMETERS, START, STOP, cachedir):
155179
}
156180

157181

158-
def data_cache_read_metax(SERVER, DATASET, PARAMETERS, START, STOP, opts):
182+
def data_cache_read_metax(server, dataset, parameters, start, stop, opts):
159183
"""Read extended request metadata from PKL cache. Returns meta dict or None."""
160184

161185
import os
@@ -167,7 +191,7 @@ def data_cache_read_metax(SERVER, DATASET, PARAMETERS, START, STOP, opts):
167191
log('Not checking subsetted metadata cache because usecache is False.')
168192
return None
169193

170-
fnamepklx = data_cache_paths(SERVER, DATASET, PARAMETERS, START, STOP, opts['cachedir'])['pkl']
194+
fnamepklx = data_cache_paths(server, dataset, parameters, start, stop, opts['cachedir'])['pkl']
171195
if os.path.isfile(fnamepklx):
172196
log('Reading subsetted metadata cache %s' % os.path.basename(fnamepklx))
173197
with open(fnamepklx, 'rb') as f:
@@ -178,7 +202,7 @@ def data_cache_read_metax(SERVER, DATASET, PARAMETERS, START, STOP, opts):
178202
return None
179203

180204

181-
def data_cache_read_npy(SERVER, DATASET, PARAMETERS, START, STOP, opts):
205+
def data_cache_read_npy(server, dataset, parameters, start, stop, opts):
182206
"""Read cached numpy data array. Returns None if not cached."""
183207

184208
import os
@@ -189,7 +213,7 @@ def data_cache_read_npy(SERVER, DATASET, PARAMETERS, START, STOP, opts):
189213
if not opts["usecache"]:
190214
return None
191215

192-
fnamenpy = data_cache_paths(SERVER, DATASET, PARAMETERS, START, STOP, opts['cachedir'])['npy']
216+
fnamenpy = data_cache_paths(server, dataset, parameters, start, stop, opts['cachedir'])['npy']
193217

194218
if not os.path.isfile(fnamenpy):
195219
return None
@@ -201,7 +225,7 @@ def data_cache_read_npy(SERVER, DATASET, PARAMETERS, START, STOP, opts):
201225
return data
202226

203227

204-
def data_cache_write(data_result, meta, SERVER, DATASET, PARAMETERS, START, STOP, opts):
228+
def data_cache_write(data_result, meta, server, dataset, parameters, start, stop, opts):
205229
"""Write data array and extended metadata to cache files.
206230
207231
Also updates meta with file-related x_ fields before writing.
@@ -212,10 +236,10 @@ def data_cache_write(data_result, meta, SERVER, DATASET, PARAMETERS, START, STOP
212236
from hapiclient.log import log
213237
from hapiclient.util import write_atomic
214238

215-
data_paths = data_cache_paths(SERVER, DATASET, PARAMETERS, START, STOP, opts['cachedir'])
239+
data_paths = data_cache_paths(server, dataset, parameters, start, stop, opts['cachedir'])
216240
fnamecsv, fnamebin, fnamenpy, fnamepklx = data_paths['csv'], data_paths['bin'], data_paths['npy'], data_paths['pkl']
217241

218-
meta_paths = meta_cache_paths(SERVER, DATASET, opts['cachedir'])
242+
meta_paths = meta_cache_paths(server, dataset, 'info', opts['cachedir'])
219243
fnamejson, fnamepkl = meta_paths['json'], meta_paths['pkl']
220244

221245
meta.update({"x_metaFileParsed": fnamepkl})

hapiclient/capabilities.py

Lines changed: 9 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,22 @@
11

2-
def capabilities(SERVER):
3-
"""Return the capabilities of a HAPI server.
2+
def capabilities(SERVER, opts):
3+
"""Return the /capabilities response from a HAPI server.
44
55
Args:
66
SERVER (str): The base URL of the HAPI server.
77
88
Returns:
99
dict: A dictionary containing the capabilities of the server.
1010
"""
11-
from hapiclient.util import urlopen
1211

13-
caps = urlopen(SERVER + '/capabilities', parse_json=True)
12+
import hapiclient as hc
1413

15-
return caps
16-
17-
18-
def get_format(SERVER, format):
19-
"""Return the transport format to use, accounting for server capabilities.
20-
21-
If the requested format is not supported by the server, falls back to 'csv'.
22-
"""
14+
caps = hc.cache.meta_cache_read(SERVER, None, 'capabilities', opts)
15+
if caps is not None:
16+
return caps
2317

24-
from hapiclient.util import error
18+
caps = hc.util.urlopen(SERVER + '/capabilities', parse_json=True)
2519

26-
cformats = ['csv', 'binary'] # client formats
27-
if format not in cformats:
28-
msg = 'This client does not handle streaming format "%s". Available options: %s'
29-
error(msg % (format, ', '.join(cformats)))
20+
hc.cache.meta_cache_write(caps, SERVER, None, 'capabilities', opts)
3021

31-
if format != 'csv':
32-
caps = capabilities(SERVER)
33-
if "outputFormats" not in caps:
34-
return 'csv'
35-
36-
formats = caps.get("outputFormats", []) # Server formats
37-
if len(formats) == 0:
38-
return 'csv'
39-
40-
if format not in formats:
41-
#from hapiclient.util import warning
42-
#msg = 'Requested streaming format "%s" not available from %s. Will use "csv". Available options: %s'
43-
#warning(msg % (format, SERVER, ', '.join(formats)))
44-
format = 'csv'
45-
46-
if 'binary' not in formats:
47-
format = 'csv'
48-
49-
return format
22+
return caps

hapiclient/catalog.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1-
from hapiclient.log import log
2-
from hapiclient.util import urlopen
1+
def catalog(SERVER, opts):
32

3+
import hapiclient as hc
4+
5+
cat = hc.cache.meta_cache_read(SERVER, None, 'catalog', opts)
6+
if cat is not None:
7+
return cat
48

5-
def catalog(SERVER):
6-
# TODO: Cache
79
url = SERVER + '/catalog'
8-
meta = urlopen(url, parse_json=True)
10+
cat = hc.util.urlopen(url, parse_json=True)
11+
12+
hc.cache.meta_cache_write(cat, SERVER, None, 'catalog', opts)
913

10-
return meta
14+
return cat

0 commit comments

Comments
 (0)