Coverage for /usr/local/lib/python3.11/dist-packages/pyrocko/gf/ws.py: 64%
70 statements
« prev ^ index » next coverage.py v6.5.0, created at 2024-03-07 11:54 +0000
« prev ^ index » next coverage.py v6.5.0, created at 2024-03-07 11:54 +0000
1# http://pyrocko.org - GPLv3
2#
3# The Pyrocko Developers, 21st Century
4# ---|P------/S----------~Lg----------
6'''
7Web service to distribute precomputed GFs (:app:`fomosto server`).
8'''
10import time
11import requests
13import logging
15from pyrocko import util
16from pyrocko.util import DownloadError
19logger = logging.getLogger('pyrocko.gf.ws')
21g_url = '%(site)s/gfws/%(service)s/%(majorversion)i/%(method)s'
22g_url_static = '%(site)s/gfws/%(service)s'
24g_site_abbr = {
25 'localhost': 'http://localhost:8080',
26 'kinherd': 'http://kinherd.org:8080'}
28g_default_site = 'localhost'
31def sdatetime(t):
32 return util.time_to_str(t, format='%Y-%m-%dT%H:%M:%S')
35class EmptyResult(Exception):
36 def __init__(self, url):
37 Exception.__init__(self)
38 self._url = url
40 def __str__(self):
41 return 'No results for request %s' % self._url
44class RequestEntityTooLarge(Exception):
45 def __init__(self, url):
46 Exception.__init__(self)
47 self._url = url
49 def __str__(self):
50 return 'Request entity too large: %s' % self._url
53class InvalidRequest(Exception):
54 pass
57def _request(url, post=False, **kwargs):
58 logger.debug('Accessing URL %s' % url)
60 if post:
61 logger.debug('POST data: \n%s' % post)
62 req = requests.Request(
63 'POST',
64 url=url,
65 params=kwargs,
66 data=post)
67 else:
68 req = requests.Request(
69 'GET',
70 url=url,
71 params=kwargs)
73 ses = requests.Session()
75 prep = ses.prepare_request(req)
76 prep.headers['Accept'] = '*/*'
78 resp = ses.send(prep, stream=True)
79 resp.raise_for_status()
81 if resp.status_code == 204:
82 raise EmptyResult(url)
83 return resp.raw
86def fillurl(url, site, service, majorversion, method='query'):
87 return url % dict(
88 site=g_site_abbr.get(site, site),
89 service=service,
90 majorversion=majorversion,
91 method=method)
94def static(url=g_url_static, site=g_default_site, majorversion=1, **kwargs):
96 url = fillurl(url, site, 'static', majorversion)
97 return _request(url, **kwargs)
100def ujoin(*args):
101 return '/'.join(args)
104def rget(url, path, force=False, method='download', stats=None,
105 status_callback=None, entries_wanted=None):
107 return util._download(
108 url, path,
109 force=force,
110 method=method,
111 status_callback=status_callback,
112 entries_wanted=entries_wanted,
113 recursive=True)
116def download_gf_store(url=g_url_static, site=g_default_site, majorversion=1,
117 store_id=None, force=False, quiet=False):
119 url = fillurl(url, site, 'static', majorversion)
121 stores_url = ujoin(url, 'stores')
123 tlast = [time.time()]
125 if not quiet:
126 def status_callback(d):
127 i = d['nread_bytes_all_files']
128 n = d['ntotal_bytes_all_files']
129 tnow = time.time()
130 if n != 0 and ((tnow - tlast[0]) > 5 or i == n):
131 print('%s / %s [%.1f%%]' % (
132 util.human_bytesize(i), util.human_bytesize(n), i*100.0/n))
134 tlast[0] = tnow
135 else:
136 def status_callback(d):
137 pass
139 wanted = ['config', 'extra/', 'index', 'phases/', 'traces/']
141 try:
142 if store_id is None:
143 print(static(
144 url=stores_url+'/', format='text').read().decode('utf-8'))
146 else:
147 store_url = ujoin(stores_url, store_id)
148 stotal = rget(
149 store_url, store_id, force=force, method='calcsize',
150 entries_wanted=wanted)
152 rget(
153 store_url, store_id, force=force, stats=[0, stotal],
154 status_callback=status_callback, entries_wanted=wanted)
156 except Exception as e:
157 raise DownloadError('download failed. Original error was: %s, %s' % (
158 type(e).__name__, e))
160 import shutil
161 shutil.rmtree(store_id)
164def seismosizer(url=g_url, site=g_default_site, majorversion=1,
165 request=None):
167 url = fillurl(url, site, 'seismosizer', majorversion)
169 from pyrocko.gf import meta
171 return meta.load(stream=_request(url, post={'request': request.dump()}))