| 1234567891011121314151617181920212223242526272829303132333435363738394041 |
- import urllib.parse
- import urllib.request
- from urllib.error import URLError, HTTPError
- import os
- import re
- import tempfile
- from contextlib import contextmanager
- URL_REGEX = re.compile(r'http://|https://|ftp://|file://|file:\\')
- def is_url(filename):
- """Return True if string is an http or ftp path."""
- return isinstance(filename, str) and URL_REGEX.match(filename) is not None
- @contextmanager
- def file_or_url_context(resource_name):
- """Yield name of file from the given resource (i.e. file or url)."""
- if is_url(resource_name):
- url_components = urllib.parse.urlparse(resource_name)
- _, ext = os.path.splitext(url_components.path)
- try:
- with tempfile.NamedTemporaryFile(delete=False, suffix=ext) as f:
- with urllib.request.urlopen(resource_name) as u:
- f.write(u.read())
- # f must be closed before yielding
- yield f.name
- except (URLError, HTTPError):
- # could not open URL
- os.remove(f.name)
- raise
- except (FileNotFoundError, FileExistsError, PermissionError, BaseException):
- # could not create temporary file
- raise
- else:
- os.remove(f.name)
- else:
- yield resource_name
|