Create one HTML reference page for a module, function, class similar to R
I'm looking for a way to ease my way into new modules by making extensive use of help ().
The problem I'm currently running into is that the output is very useful, but difficult to scroll in an interactive interpreter. I'm looking for a way to learn python modules in a way that is similar to how R handles documentation (when using R PRoject).
R outputs one HTML file that allows you to loop through parameters, functions; I am using python 2.7 on Windows.
I found pydoc that outputs exactly what I'm looking for in the console, but I'm not entirely sure how I'm going to move away from the "webserver" documenting all my installed packages for maintenance only and opening one html page as soon as I type help (x), outputting what it would normally output to the interpreter.
Any help is greatly appreciated.
source to share
Thanks for answers. My final solution is a combination of your two methods:
- I imported TemporaryDirectory () as above;
- Then I call pydoc.writedoc (x) to generate the html file in temp. folder;
- I used another snippet to suppress printing "wrote x.html" from pydoc;
- I used webbrowser.open_new (url) to open a new page in my default browser.
The help call (os) now creates a temporary HTML file (in pydoc) and opens it in my standard browser; that was exactly what I needed.
from __future__ import print_function
import pydoc
import os
import sys
import time
import webbrowser
import warnings as _warnings
import os as _os
from tempfile import mkdtemp
from contextlib import contextmanager
@contextmanager
def suppress_stdout():
""" Suppresses output of all functions called as follows:
with suppress_stdout():
functioncall()
source: http://thesmithfam.org/blog/2012/10/25/temporarily-suppress-console-output-in-python/
"""
with open(os.devnull, "w") as devnull:
old_stdout = sys.stdout
sys.stdout = devnull
try:
yield
finally:
sys.stdout = old_stdout
class TemporaryDirectory(object):
"""Create and return a temporary directory. This has the same
behavior as mkdtemp but can be used as a context manager. For
example:
with TemporaryDirectory() as tmpdir:
...
Upon exiting the context, the directory and everything contained
in it are removed.
"""
def __init__(self, suffix="", prefix="tmp", dir=None):
self._closed = False
self.name = None # Handle mkdtemp raising an exception
self.name = mkdtemp(suffix, prefix, dir)
def __repr__(self):
return "<{} {!r}>".format(self.__class__.__name__, self.name)
def __enter__(self):
return self.name
def cleanup(self, _warn=False):
if self.name and not self._closed:
try:
self._rmtree(self.name)
except (TypeError, AttributeError) as ex:
# Issue #10188: Emit a warning on stderr
# if the directory could not be cleaned
# up due to missing globals
if "None" not in str(ex):
raise
print("ERROR: {!r} while cleaning up {!r}".format(ex, self,),
file=_sys.stderr)
return
self._closed = True
if _warn:
self._warn("Implicitly cleaning up {!r}".format(self),
ResourceWarning)
def __exit__(self, exc, value, tb):
self.cleanup()
def __del__(self):
# Issue a ResourceWarning if implicit cleanup needed
self.cleanup(_warn=True)
# XXX (ncoghlan): The following code attempts to make
# this class tolerant of the module nulling out process
# that happens during CPython interpreter shutdown
# Alas, it doesn't actually manage it. See issue #10188
_listdir = staticmethod(_os.listdir)
_path_join = staticmethod(_os.path.join)
_isdir = staticmethod(_os.path.isdir)
_islink = staticmethod(_os.path.islink)
_remove = staticmethod(_os.remove)
_rmdir = staticmethod(_os.rmdir)
_warn = _warnings.warn
def _rmtree(self, path):
# Essentially a stripped down version of shutil.rmtree. We can't
# use globals because they may be None'ed out at shutdown.
for name in self._listdir(path):
fullname = self._path_join(path, name)
try:
isdir = self._isdir(fullname) and not self._islink(fullname)
except OSError:
isdir = False
if isdir:
self._rmtree(fullname)
else:
try:
self._remove(fullname)
except OSError:
pass
try:
self._rmdir(path)
except OSError:
pass
def help(thing):
""" Create and show HTML page of module documentation,
It should accept anything that the regular help() accepts.
"""
# Create temporary directory to store documentation in
with TemporaryDirectory() as temp_folder:
orignal_cwd = os.getcwd()
# Change working directory to temporary folder
os.chdir(temp_folder)
# Create HTML page of doc
object, name = pydoc.resolve(thing)
pydoc.writedoc(thing)
with suppress_stdout():
filepath = os.path.join(temp_folder, name + ".html")
# Reset working directory
os.chdir(orignal_cwd)
# Open default program to view HTML files
webbrowser.open_new(filepath)
# Sleep for 2 seconds so browser can open before deleting file
time.sleep(2)
if __name__ == "__main__":
help(os)
source to share
I wrote a short function that takes a string containing the name of the module, which creates an html file using pydoc and shows it in your default browser.
It hasn't configured a web server, it just downloads the file to the web browser.
import subprocess
import os
import tempfile
import sys
import time
def show_help(module):
""" Create and show HTML page of module documentation
Pass module as a string
"""
# Create temporary directory to store documentation in
with tempfile.TemporaryDirectory() as temp_folder:
orignal_cwd = os.getcwd()
# Change working directory to temporary folder
os.chdir(temp_folder)
# Create HTML page of doc
subprocess.call(["pydoc", "-w", module], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
filepath = os.path.join(temp_folder, module + ".html")
# Reset working directory
os.chdir(orignal_cwd)
# Open default program to view HTML files
if sys.platform.startswith('darwin'):
subprocess.call(('open', filepath), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
elif os.name == 'nt':
os.startfile(filepath)
elif os.name == 'posix':
subprocess.call(('xdg-open', filepath), stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
# Sleep for 2 seconds so browser can open before deleting file
time.sleep(2)
I tested it with python3.4 on linux where it works fine, but I haven't tested it with Windows.
You can import it as a module in the interpreter and then just use it show_help("module name")
to view the documentation, where "module name" is the name of the module as a string. Eg show_help("os")
.
source to share
You can use pydoc.render_doc
to create a file html
.
import pydoc
str_help = pydoc.render_doc(str)
with open("str_doc.html", "w") as doc_file:
doc_file.write(str_help)
Then you can open this file in a web browser :
import webbrowser
webbrowser.open("file:///path/to/your/doc_file.html")
source to share