def find_api_page(obj, version=None, openinbrowser=True, timeout=None): """ Determines the URL of the API page for the specified object, and optionally open that page in a web browser. .. note:: You must be connected to the internet for this to function even if ``openinbrowser`` is `False`, unless you provide a local version of the documentation to ``version`` (e.g., ``file:///path/to/docs``). Parameters ---------- obj The object to open the docs for or its fully-qualified name (as a str). version : str The doc version - either a version number like '0.1', 'dev' for the development/latest docs, or a URL to point to a specific location that should be the *base* of the documentation. Defaults to latest if you are on aren't on a release, otherwise, the version you are on. openinbrowser : bool If `True`, the `webbrowser` package will be used to open the doc page in a new web browser window. timeout : number, optional The number of seconds to wait before timing-out the query to the astropy documentation. If not given, the default python stdlib timeout will be used. Returns ------- url : str The loaded URL Raises ------ ValueError If the documentation can't be found """ import webbrowser import urllib.request from zlib import decompress if (not isinstance(obj, str) and hasattr(obj, '__module__') and hasattr(obj, '__name__')): obj = obj.__module__ + '.' + obj.__name__ elif inspect.ismodule(obj): obj = obj.__name__ if version is None: from astropy import version if version.release: version = 'v' + version.version else: version = 'dev' if '://' in version: if version.endswith('index.html'): baseurl = version[:-10] elif version.endswith('/'): baseurl = version else: baseurl = version + '/' elif version == 'dev' or version == 'latest': baseurl = 'http://devdocs.astropy.org/' else: baseurl = f'http://docs.astropy.org/en/{version}/' if timeout is None: uf = urllib.request.urlopen(baseurl + 'objects.inv') else: uf = urllib.request.urlopen(baseurl + 'objects.inv', timeout=timeout) try: oiread = uf.read() # need to first read/remove the first four lines, which have info before # the compressed section with the actual object inventory idx = -1 headerlines = [] for _ in range(4): oldidx = idx idx = oiread.index(b'\n', oldidx + 1) headerlines.append(oiread[(oldidx + 1):idx].decode('utf-8')) # intersphinx version line, project name, and project version ivers, proj, vers, compr = headerlines if 'The remainder of this file is compressed using zlib' not in compr: raise ValueError('The file downloaded from {} does not seem to be' 'the usual Sphinx objects.inv format. Maybe it ' 'has changed?'.format(baseurl + 'objects.inv')) compressed = oiread[(idx + 1):] finally: uf.close() decompressed = decompress(compressed).decode('utf-8') resurl = None for l in decompressed.strip().splitlines(): ls = l.split() name = ls[0] loc = ls[3] if loc.endswith('$'): loc = loc[:-1] + name if name == obj: resurl = baseurl + loc break if resurl is None: raise ValueError(f'Could not find the docs for the object {obj}') elif openinbrowser: webbrowser.open(resurl) return resurl
def find_api_page(obj, version=None, openinbrowser=True, timeout=None): """ Determines the URL of the API page for the specified object, and optionally open that page in a web browser. .. note:: You must be connected to the internet for this to function even if ``openinbrowser`` is `False`, unless you provide a local version of the documentation to ``version`` (e.g., ``file:///path/to/docs``). Parameters ---------- obj The object to open the docs for or its fully-qualified name (as a str). version : str The doc version - either a version number like '0.1', 'dev' for the development/latest docs, or a URL to point to a specific location that should be the *base* of the documentation. Defaults to latest if you are on aren't on a release, otherwise, the version you are on. openinbrowser : bool If `True`, the `webbrowser` package will be used to open the doc page in a new web browser window. timeout : number, optional The number of seconds to wait before timing-out the query to the astropy documentation. If not given, the default python stdlib timeout will be used. Returns ------- url : str The loaded URL Raises ------ ValueError If the documentation can't be found """ import webbrowser import urllib.request from zlib import decompress if (not isinstance(obj, str) and hasattr(obj, '__module__') and hasattr(obj, '__name__')): obj = obj.__module__ + '.' + obj.__name__ elif inspect.ismodule(obj): obj = obj.__name__ if version is None: from astropy import version if version.release: version = 'v' + version.version else: version = 'dev' if '://' in version: if version.endswith('index.html'): baseurl = version[:-10] elif version.endswith('/'): baseurl = version else: baseurl = version + '/' elif version == 'dev' or version == 'latest': baseurl = 'http://devdocs.astropy.org/' else: baseurl = 'http://docs.astropy.org/en/{vers}/'.format(vers=version) if timeout is None: uf = urllib.request.urlopen(baseurl + 'objects.inv') else: uf = urllib.request.urlopen(baseurl + 'objects.inv', timeout=timeout) try: oiread = uf.read() # need to first read/remove the first four lines, which have info before # the compressed section with the actual object inventory idx = -1 headerlines = [] for _ in range(4): oldidx = idx idx = oiread.index(b'\n', oldidx + 1) headerlines.append(oiread[(oldidx+1):idx].decode('utf-8')) # intersphinx version line, project name, and project version ivers, proj, vers, compr = headerlines if 'The remainder of this file is compressed using zlib' not in compr: raise ValueError('The file downloaded from {0} does not seem to be' 'the usual Sphinx objects.inv format. Maybe it ' 'has changed?'.format(baseurl + 'objects.inv')) compressed = oiread[(idx+1):] finally: uf.close() decompressed = decompress(compressed).decode('utf-8') resurl = None for l in decompressed.strip().splitlines(): ls = l.split() name = ls[0] loc = ls[3] if loc.endswith('$'): loc = loc[:-1] + name if name == obj: resurl = baseurl + loc break if resurl is None: raise ValueError('Could not find the docs for the object {obj}'.format(obj=obj)) elif openinbrowser: webbrowser.open(resurl) return resurl