17
17
# %% ../nbs/03b_net.ipynb 1
18
18
from .utils import *
19
19
from .parallel import *
20
- from functools import wraps
21
20
21
+ from functools import wraps
22
22
import json ,urllib ,contextlib
23
23
import socket ,urllib .request ,http ,urllib
24
24
from contextlib import contextmanager ,ExitStack
25
- from urllib .request import Request ,urlretrieve ,install_opener
25
+ from urllib .request import Request ,urlretrieve ,install_opener , HTTPErrorProcessor
26
26
from urllib .error import HTTPError ,URLError
27
27
from urllib .parse import urlencode ,urlparse ,urlunparse
28
28
from http .client import InvalidURL
@@ -104,28 +104,31 @@ def urlopen(url, data=None, headers=None, timeout=None, **kwargs):
104
104
if data is not None :
105
105
if not isinstance (data , (str ,bytes )): data = urlencode (data )
106
106
if not isinstance (data , bytes ): data = data .encode ('ascii' )
107
- return urlopener ().open (urlwrap (url , data = data , headers = headers ), timeout = timeout )
107
+ try : return urlopener ().open (urlwrap (url , data = data , headers = headers ), timeout = timeout )
108
+ except HTTPError as e :
109
+ e .msg += f"\n ====Error Body====\n { e .read ().decode (errors = 'ignore' )} "
110
+ raise
108
111
109
- # %% ../nbs/03b_net.ipynb 18
112
+ # %% ../nbs/03b_net.ipynb 20
110
113
def urlread (url , data = None , headers = None , decode = True , return_json = False , return_headers = False , timeout = None , ** kwargs ):
111
114
"Retrieve `url`, using `data` dict or `kwargs` to `POST` if present"
112
115
try :
113
116
with urlopen (url , data = data , headers = headers , timeout = timeout , ** kwargs ) as u : res ,hdrs = u .read (),u .headers
114
117
except HTTPError as e :
115
- if 400 <= e .code < 500 : raise ExceptionsHTTP [e .code ](e .url , e .hdrs , e .fp ) from None
118
+ if 400 <= e .code < 500 : raise ExceptionsHTTP [e .code ](e .url , e .hdrs , e .fp , msg = e . msg ) from None
116
119
else : raise
117
120
118
121
if decode : res = res .decode ()
119
122
if return_json : res = loads (res )
120
123
return (res ,dict (hdrs )) if return_headers else res
121
124
122
- # %% ../nbs/03b_net.ipynb 19
125
+ # %% ../nbs/03b_net.ipynb 21
123
126
def urljson (url , data = None , timeout = None ):
124
127
"Retrieve `url` and decode json"
125
128
res = urlread (url , data = data , timeout = timeout )
126
129
return json .loads (res ) if res else {}
127
130
128
- # %% ../nbs/03b_net.ipynb 21
131
+ # %% ../nbs/03b_net.ipynb 23
129
132
def urlcheck (url , timeout = 10 ):
130
133
if not url : return True
131
134
try :
@@ -134,12 +137,12 @@ def urlcheck(url, timeout=10):
134
137
except socket .timeout : return False
135
138
except InvalidURL : return False
136
139
137
- # %% ../nbs/03b_net.ipynb 22
140
+ # %% ../nbs/03b_net.ipynb 24
138
141
def urlclean (url ):
139
142
"Remove fragment, params, and querystring from `url` if present"
140
143
return urlunparse (urlparse (str (url ))[:3 ]+ ('' ,'' ,'' ))
141
144
142
- # %% ../nbs/03b_net.ipynb 24
145
+ # %% ../nbs/03b_net.ipynb 26
143
146
def urlretrieve (url , filename = None , reporthook = None , data = None , timeout = None ):
144
147
"Same as `urllib.request.urlretrieve` but also works with `Request` objects"
145
148
with contextlib .closing (urlopen (url , data , timeout = timeout )) as fp :
@@ -165,43 +168,43 @@ def urlretrieve(url, filename=None, reporthook=None, data=None, timeout=None):
165
168
raise ContentTooShortError (f"retrieval incomplete: got only { read } out of { size } bytes" , headers )
166
169
return filename ,headers
167
170
168
- # %% ../nbs/03b_net.ipynb 25
171
+ # %% ../nbs/03b_net.ipynb 27
169
172
def urldest (url , dest = None ):
170
173
name = urlclean (Path (url ).name )
171
174
if dest is None : dest = name
172
175
dest = Path (dest )
173
176
return dest / name if dest .is_dir () else dest
174
177
175
- # %% ../nbs/03b_net.ipynb 26
178
+ # %% ../nbs/03b_net.ipynb 28
176
179
def urlsave (url , dest = None , reporthook = None , timeout = None ):
177
180
"Retrieve `url` and save based on its name"
178
181
dest = urldest (url , dest )
179
182
dest .parent .mkdir (parents = True , exist_ok = True )
180
183
nm ,msg = urlretrieve (url , dest , reporthook , timeout = timeout )
181
184
return nm
182
185
183
- # %% ../nbs/03b_net.ipynb 28
186
+ # %% ../nbs/03b_net.ipynb 30
184
187
def urlvalid (x ):
185
188
"Test if `x` is a valid URL"
186
189
return all (getattrs (urlparse (str (x )), 'scheme' , 'netloc' ))
187
190
188
- # %% ../nbs/03b_net.ipynb 30
191
+ # %% ../nbs/03b_net.ipynb 32
189
192
def urlrequest (url , verb , headers = None , route = None , query = None , data = None , json_data = True ):
190
193
"`Request` for `url` with optional route params replaced by `route`, plus `query` string, and post `data`"
191
194
if route : url = url .format (** route )
192
195
if query : url += '?' + urlencode (query )
193
196
if isinstance (data ,dict ): data = (json .dumps if json_data else urlencode )(data ).encode ('ascii' )
194
197
return Request (url , headers = headers or {}, data = data or None , method = verb .upper ())
195
198
196
- # %% ../nbs/03b_net.ipynb 33
199
+ # %% ../nbs/03b_net.ipynb 35
197
200
@patch
198
201
def summary (self :Request , skip = None )-> dict :
199
202
"Summary containing full_url, headers, method, and data, removing `skip` from headers"
200
203
res = L ('full_url' ,'method' ,'data' ).map_dict (partial (getattr ,self ))
201
204
res ['headers' ] = {k :v for k ,v in self .headers .items () if k not in listify (skip )}
202
205
return res
203
206
204
- # %% ../nbs/03b_net.ipynb 35
207
+ # %% ../nbs/03b_net.ipynb 37
205
208
def urlsend (url , verb , headers = None , route = None , query = None , data = None , json_data = True ,
206
209
return_json = True , return_headers = False , debug = None ):
207
210
"Send request with `urlrequest`, converting result to json if `return_json`"
@@ -213,7 +216,7 @@ def urlsend(url, verb, headers=None, route=None, query=None, data=None, json_dat
213
216
214
217
return urlread (req , return_json = return_json , return_headers = return_headers )
215
218
216
- # %% ../nbs/03b_net.ipynb 36
219
+ # %% ../nbs/03b_net.ipynb 38
217
220
def do_request (url , post = False , headers = None , ** data ):
218
221
"Call GET or json-encoded POST on `url`, depending on `post`"
219
222
if data :
@@ -223,13 +226,13 @@ def do_request(url, post=False, headers=None, **data):
223
226
data = None
224
227
return urljson (Request (url , headers = headers , data = data or None ))
225
228
226
- # %% ../nbs/03b_net.ipynb 37
229
+ # %% ../nbs/03b_net.ipynb 39
227
230
def _socket_det (port ,host ,dgram ):
228
231
if isinstance (port ,int ): family ,addr = socket .AF_INET ,(host or socket .gethostname (),port )
229
232
else : family ,addr = socket .AF_UNIX ,port
230
233
return family ,addr ,(socket .SOCK_STREAM ,socket .SOCK_DGRAM )[dgram ]
231
234
232
- # %% ../nbs/03b_net.ipynb 38
235
+ # %% ../nbs/03b_net.ipynb 40
233
236
def start_server (port , host = None , dgram = False , reuse_addr = True , n_queue = None ):
234
237
"Create a `socket` server on `port`, with optional `host`, of type `dgram`"
235
238
listen_args = [n_queue ] if n_queue else []
@@ -243,7 +246,7 @@ def start_server(port, host=None, dgram=False, reuse_addr=True, n_queue=None):
243
246
s .listen (* listen_args )
244
247
return s
245
248
246
- # %% ../nbs/03b_net.ipynb 40
249
+ # %% ../nbs/03b_net.ipynb 42
247
250
def start_client (port , host = None , dgram = False ):
248
251
"Create a `socket` client on `port`, with optional `host`, of type `dgram`"
249
252
family ,addr ,typ = _socket_det (port ,host ,dgram )
0 commit comments