-
Notifications
You must be signed in to change notification settings - Fork 80
Open
Description
Cartopy fails to download shapefiles with a long exception from JupyterLite.
Workaround is to predownload the data files with python -m cartopy.feature.download cultural, (or physical, ...) distribute the files in the deployment and run import cartopy; cartopy.config['data_dir'] = '/path/to/cartopy/'data before plotting.
In the browser console I get:
xpython.js:9 Mixed Content: The page at 'https:// ... /jupyterlite-obspy/extensions/@jupyterlite/xeus-extension/static/78.27c4816….js?v=27c4816…' was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint 'ws://naturalearth.s3.amazonaws.com:443/'. This request has been blocked; this endpoint must be available over WS
Not sure what the reason for this is and why ws:// is involved here. The file url seems to be https: https://naturalearth.s3.amazonaws.com/110m_physical/ne_110m_ocean.zip . Trace is in the details below.
Details
Matplotlib is building the font cache; this may take a moment.
/lib/python3.13/site-packages/cartopy/io/__init__.py:241: DownloadWarning: Downloading: https://naturalearth.s3.amazonaws.com/110m_physical/ne_110m_ocean.zip
warnings.warn(f'Downloading: {url}', DownloadWarning)
<Figure size 640x480 with 1 Axes>
---------------------------------------------------------------------------
OSError Traceback (most recent call last)
File /lib/python3.13/urllib/request.py:1319, in AbstractHTTPHandler.do_open(self, http_class, req, **http_conn_args)
1318 try:
-> 1319 h.request(req.get_method(), req.selector, req.data, headers,
1320 encode_chunked=req.has_header('Transfer-encoding'))
1321 except OSError as err: # timeout error
File /lib/python3.13/http/client.py:1336, in HTTPConnection.request(self, method, url, body, headers, encode_chunked)
1335 """Send a complete request to the server."""
-> 1336 self._send_request(method, url, body, headers, encode_chunked)
File /lib/python3.13/http/client.py:1382, in HTTPConnection._send_request(self, method, url, body, headers, encode_chunked)
1381 body = _encode(body, 'body')
-> 1382 self.endheaders(body, encode_chunked=encode_chunked)
File /lib/python3.13/http/client.py:1331, in HTTPConnection.endheaders(self, message_body, encode_chunked)
1330 raise CannotSendHeader()
-> 1331 self._send_output(message_body, encode_chunked=encode_chunked)
File /lib/python3.13/http/client.py:1091, in HTTPConnection._send_output(self, message_body, encode_chunked)
1090 del self._buffer[:]
-> 1091 self.send(msg)
1093 if message_body is not None:
1094
1095 # create a consistent interface to message_body
File /lib/python3.13/http/client.py:1035, in HTTPConnection.send(self, data)
1034 if self.auto_open:
-> 1035 self.connect()
1036 else:
File /lib/python3.13/http/client.py:1470, in HTTPSConnection.connect(self)
1468 "Connect to a host on a given (SSL) port."
-> 1470 super().connect()
1472 if self._tunnel_host:
File /lib/python3.13/http/client.py:1001, in HTTPConnection.connect(self)
1000 sys.audit("http.client.connect", self, self.host, self.port)
-> 1001 self.sock = self._create_connection(
1002 (self.host,self.port), self.timeout, self.source_address)
1003 # Might fail in OSs that don't implement TCP_NODELAY
File /lib/python3.13/socket.py:864, in create_connection(address, timeout, source_address, all_errors)
863 if not all_errors:
--> 864 raise exceptions[0]
865 raise ExceptionGroup("create_connection failed", exceptions)
File /lib/python3.13/socket.py:849, in create_connection(address, timeout, source_address, all_errors)
848 sock.bind(source_address)
--> 849 sock.connect(sa)
850 # Break explicitly a reference cycle
OSError: [Errno 23] Host is unreachable
During handling of the above exception, another exception occurred:
URLError Traceback (most recent call last)
File /lib/python3.13/site-packages/IPython/core/formatters.py:402, in BaseFormatter.__call__(self, obj)
400 pass
401 else:
--> 402 return printer(obj)
403 # Finally look for special method names
404 method = get_real_method(obj, self.print_method)
File /lib/python3.13/site-packages/IPython/core/pylabtools.py:170, in print_figure(fig, fmt, bbox_inches, base64, **kwargs)
167 from matplotlib.backend_bases import FigureCanvasBase
168 FigureCanvasBase(fig)
--> 170 fig.canvas.print_figure(bytes_io, **kw)
171 data = bytes_io.getvalue()
172 if fmt == 'svg':
File /lib/python3.13/site-packages/matplotlib/backend_bases.py:2157, in FigureCanvasBase.print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
2154 # we do this instead of `self.figure.draw_without_rendering`
2155 # so that we can inject the orientation
2156 with getattr(renderer, "_draw_disabled", nullcontext)():
-> 2157 self.figure.draw(renderer)
2158 if bbox_inches:
2159 if bbox_inches == "tight":
File /lib/python3.13/site-packages/matplotlib/artist.py:94, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
92 @wraps(draw)
93 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 94 result = draw(artist, renderer, *args, **kwargs)
95 if renderer._rasterizing:
96 renderer.stop_rasterizing()
File /lib/python3.13/site-packages/matplotlib/artist.py:71, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
68 if artist.get_agg_filter() is not None:
69 renderer.start_filter()
---> 71 return draw(artist, renderer)
72 finally:
73 if artist.get_agg_filter() is not None:
File /lib/python3.13/site-packages/matplotlib/figure.py:3257, in Figure.draw(self, renderer)
3254 # ValueError can occur when resizing a window.
3256 self.patch.draw(renderer)
-> 3257 mimage._draw_list_compositing_images(
3258 renderer, self, artists, self.suppressComposite)
3260 renderer.close_group('figure')
3261 finally:
File /lib/python3.13/site-packages/matplotlib/image.py:134, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
132 if not_composite or not has_images:
133 for a in artists:
--> 134 a.draw(renderer)
135 else:
136 # Composite any adjacent images together
137 image_group = []
File /lib/python3.13/site-packages/matplotlib/artist.py:71, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
68 if artist.get_agg_filter() is not None:
69 renderer.start_filter()
---> 71 return draw(artist, renderer)
72 finally:
73 if artist.get_agg_filter() is not None:
File /lib/python3.13/site-packages/cartopy/mpl/geoaxes.py:525, in GeoAxes.draw(self, renderer, **kwargs)
520 self.imshow(img, extent=extent, origin=origin,
521 transform=factory.crs, *factory_args[1:],
522 **factory_kwargs)
523 self._done_img_factory = True
--> 525 return super().draw(renderer=renderer, **kwargs)
File /lib/python3.13/site-packages/matplotlib/artist.py:71, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
68 if artist.get_agg_filter() is not None:
69 renderer.start_filter()
---> 71 return draw(artist, renderer)
72 finally:
73 if artist.get_agg_filter() is not None:
File /lib/python3.13/site-packages/matplotlib/axes/_base.py:3226, in _AxesBase.draw(self, renderer)
3223 if artists_rasterized:
3224 _draw_rasterized(self.get_figure(root=True), artists_rasterized, renderer)
-> 3226 mimage._draw_list_compositing_images(
3227 renderer, self, artists, self.get_figure(root=True).suppressComposite)
3229 renderer.close_group('axes')
3230 self.stale = False
File /lib/python3.13/site-packages/matplotlib/image.py:134, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
132 if not_composite or not has_images:
133 for a in artists:
--> 134 a.draw(renderer)
135 else:
136 # Composite any adjacent images together
137 image_group = []
File /lib/python3.13/site-packages/matplotlib/artist.py:71, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
68 if artist.get_agg_filter() is not None:
69 renderer.start_filter()
---> 71 return draw(artist, renderer)
72 finally:
73 if artist.get_agg_filter() is not None:
File /lib/python3.13/site-packages/cartopy/mpl/feature_artist.py:185, in FeatureArtist.draw(self, renderer)
180 geoms = self._feature.geometries()
181 else:
182 # For efficiency on local maps with high resolution features (e.g
183 # from Natural Earth), only create paths for geometries that are
184 # in view.
--> 185 geoms = self._feature.intersecting_geometries(extent)
187 stylised_paths = {}
188 # Make an empty placeholder style dictionary for when styler is not
189 # used. Freeze it so that we can use it as a dict key. We will need
190 # to unfreeze all style dicts with dict(frozen) before passing to mpl.
File /lib/python3.13/site-packages/cartopy/feature/__init__.py:309, in NaturalEarthFeature.intersecting_geometries(self, extent)
302 """
303 Returns an iterator of shapely geometries that intersect with
304 the given extent.
305 The extent is assumed to be in the CRS of the feature.
306 If extent is None, the method returns all geometries for this dataset.
307 """
308 self.scaler.scale_from_extent(extent)
--> 309 return super().intersecting_geometries(extent)
File /lib/python3.13/site-packages/cartopy/feature/__init__.py:112, in Feature.intersecting_geometries(self, extent)
109 if extent is not None and not np.isnan(extent[0]):
110 extent_geom = sgeom.box(extent[0], extent[2],
111 extent[1], extent[3])
--> 112 return (geom for geom in self.geometries() if
113 geom is not None and extent_geom.intersects(geom))
114 else:
115 return self.geometries()
File /lib/python3.13/site-packages/cartopy/feature/__init__.py:291, in NaturalEarthFeature.geometries(self)
289 key = (self.name, self.category, self.scale)
290 if key not in _NATURAL_EARTH_GEOM_CACHE:
--> 291 path = shapereader.natural_earth(resolution=self.scale,
292 category=self.category,
293 name=self.name)
294 geometries = tuple(shapereader.Reader(path).geometries())
295 _NATURAL_EARTH_GEOM_CACHE[key] = geometries
File /lib/python3.13/site-packages/cartopy/io/shapereader.py:306, in natural_earth(resolution, category, name)
302 ne_downloader = Downloader.from_config(('shapefiles', 'natural_earth',
303 resolution, category, name))
304 format_dict = {'config': config, 'category': category,
305 'name': name, 'resolution': resolution}
--> 306 return ne_downloader.path(format_dict)
File /lib/python3.13/site-packages/cartopy/io/__init__.py:203, in Downloader.path(self, format_dict)
200 result_path = target_path
201 else:
202 # we need to download the file
--> 203 result_path = self.acquire_resource(target_path, format_dict)
205 return result_path
File /lib/python3.13/site-packages/cartopy/io/shapereader.py:359, in NEShpDownloader.acquire_resource(self, target_path, format_dict)
355 target_dir.mkdir(parents=True, exist_ok=True)
357 url = self.url(format_dict)
--> 359 shapefile_online = self._urlopen(url)
361 zfh = ZipFile(io.BytesIO(shapefile_online.read()), 'r')
363 for member_path in self.zip_file_contents(format_dict):
File /lib/python3.13/site-packages/cartopy/io/__init__.py:242, in Downloader._urlopen(self, url)
235 """
236 Returns a file handle to the given HTTP resource URL.
237
238 Caller should close the file handle when finished with it.
239
240 """
241 warnings.warn(f'Downloading: {url}', DownloadWarning)
--> 242 return urlopen(url)
File /lib/python3.13/urllib/request.py:189, in urlopen(url, data, timeout, context)
187 else:
188 opener = _opener
--> 189 return opener.open(url, data, timeout)
File /lib/python3.13/urllib/request.py:489, in OpenerDirector.open(self, fullurl, data, timeout)
486 req = meth(req)
488 sys.audit('urllib.Request', req.full_url, req.data, req.headers, req.get_method())
--> 489 response = self._open(req, data)
491 # post-process response
492 meth_name = protocol+"_response"
File /lib/python3.13/urllib/request.py:506, in OpenerDirector._open(self, req, data)
503 return result
505 protocol = req.type
--> 506 result = self._call_chain(self.handle_open, protocol, protocol +
507 '_open', req)
508 if result:
509 return result
File /lib/python3.13/urllib/request.py:466, in OpenerDirector._call_chain(self, chain, kind, meth_name, *args)
464 for handler in handlers:
465 func = getattr(handler, meth_name)
--> 466 result = func(*args)
467 if result is not None:
468 return result
File /lib/python3.13/urllib/request.py:1367, in HTTPSHandler.https_open(self, req)
1366 def https_open(self, req):
-> 1367 return self.do_open(http.client.HTTPSConnection, req,
1368 context=self._context)
File /lib/python3.13/urllib/request.py:1322, in AbstractHTTPHandler.do_open(self, http_class, req, **http_conn_args)
1319 h.request(req.get_method(), req.selector, req.data, headers,
1320 encode_chunked=req.has_header('Transfer-encoding'))
1321 except OSError as err: # timeout error
-> 1322 raise URLError(err)
1323 r = h.getresponse()
1324 except:
URLError: <urlopen error [Errno 23] Host is unreachable>
Metadata
Metadata
Assignees
Labels
No labels