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 2023-10-06 06:59 +0000

1# http://pyrocko.org - GPLv3 

2# 

3# The Pyrocko Developers, 21st Century 

4# ---|P------/S----------~Lg---------- 

5 

6''' 

7Web service to distribute precomputed GFs (:app:`fomosto server`). 

8''' 

9 

10import time 

11import requests 

12 

13import logging 

14 

15from pyrocko import util 

16from pyrocko.util import DownloadError 

17 

18 

19logger = logging.getLogger('pyrocko.gf.ws') 

20 

21g_url = '%(site)s/gfws/%(service)s/%(majorversion)i/%(method)s' 

22g_url_static = '%(site)s/gfws/%(service)s' 

23 

24g_site_abbr = { 

25 'localhost': 'http://localhost:8080', 

26 'kinherd': 'http://kinherd.org:8080'} 

27 

28g_default_site = 'localhost' 

29 

30 

31def sdatetime(t): 

32 return util.time_to_str(t, format='%Y-%m-%dT%H:%M:%S') 

33 

34 

35class EmptyResult(Exception): 

36 def __init__(self, url): 

37 Exception.__init__(self) 

38 self._url = url 

39 

40 def __str__(self): 

41 return 'No results for request %s' % self._url 

42 

43 

44class RequestEntityTooLarge(Exception): 

45 def __init__(self, url): 

46 Exception.__init__(self) 

47 self._url = url 

48 

49 def __str__(self): 

50 return 'Request entity too large: %s' % self._url 

51 

52 

53class InvalidRequest(Exception): 

54 pass 

55 

56 

57def _request(url, post=False, **kwargs): 

58 logger.debug('Accessing URL %s' % url) 

59 

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) 

72 

73 ses = requests.Session() 

74 

75 prep = ses.prepare_request(req) 

76 prep.headers['Accept'] = '*/*' 

77 

78 resp = ses.send(prep, stream=True) 

79 resp.raise_for_status() 

80 

81 if resp.status_code == 204: 

82 raise EmptyResult(url) 

83 return resp.raw 

84 

85 

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) 

92 

93 

94def static(url=g_url_static, site=g_default_site, majorversion=1, **kwargs): 

95 

96 url = fillurl(url, site, 'static', majorversion) 

97 return _request(url, **kwargs) 

98 

99 

100def ujoin(*args): 

101 return '/'.join(args) 

102 

103 

104def rget(url, path, force=False, method='download', stats=None, 

105 status_callback=None, entries_wanted=None): 

106 

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) 

114 

115 

116def download_gf_store(url=g_url_static, site=g_default_site, majorversion=1, 

117 store_id=None, force=False, quiet=False): 

118 

119 url = fillurl(url, site, 'static', majorversion) 

120 

121 stores_url = ujoin(url, 'stores') 

122 

123 tlast = [time.time()] 

124 

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)) 

133 

134 tlast[0] = tnow 

135 else: 

136 def status_callback(d): 

137 pass 

138 

139 wanted = ['config', 'extra/', 'index', 'phases/', 'traces/'] 

140 

141 try: 

142 if store_id is None: 

143 print(static( 

144 url=stores_url+'/', format='text').read().decode('utf-8')) 

145 

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) 

151 

152 rget( 

153 store_url, store_id, force=force, stats=[0, stotal], 

154 status_callback=status_callback, entries_wanted=wanted) 

155 

156 except Exception as e: 

157 raise DownloadError('download failed. Original error was: %s, %s' % ( 

158 type(e).__name__, e)) 

159 

160 import shutil 

161 shutil.rmtree(store_id) 

162 

163 

164def seismosizer(url=g_url, site=g_default_site, majorversion=1, 

165 request=None): 

166 

167 url = fillurl(url, site, 'seismosizer', majorversion) 

168 

169 from pyrocko.gf import meta 

170 

171 return meta.load(stream=_request(url, post={'request': request.dump()}))