build/gen_py_api_docs.py (91 lines of code) (raw):
# Copyright (c) 2020 The Neuropod Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import inspect
import re
class Function(object):
"""
Represents a function
"""
def __init__(self, name, shortdoc="", params=[]):
super(Function, self).__init__()
self.name = name
self.shortdoc = shortdoc
self.params = params
class Parameter(object):
"""
Represents a parameter to a function
"""
def __init__(self, name):
super(Parameter, self).__init__()
self.name = name
self.docs_arr = []
self.has_default = False
self.default = None
def add_doc_line(self, line):
"""
Add a line of documentation
"""
self.docs_arr.append(line)
def get_clean_doc(self):
"""
Get a clean version of the documentation for this parameter
"""
# Strips common leading whitespace
return inspect.cleandoc("\n".join(self.docs_arr))
def set_default(self, value):
"""
Set the default value for this parameter
"""
self.has_default = True
self.default = value
def parse_docstring(f):
"""
Parse the docstring of `f` and return a list of parameters
"""
doc = inspect.cleandoc(f.__doc__)
lines = doc.splitlines()
params = []
currentparam = None
shortdoc = ""
def flush_param_if_necessary():
if currentparam:
params.append(currentparam)
# Loop through all the lines of the docstring
for i, line in enumerate(lines):
match = re.match(r':param\s+(\w+):\s+(.*)', line)
if match:
# This is a new param
flush_param_if_necessary()
currentparam = Parameter(name=match.group(1))
currentparam.add_doc_line(match.group(2))
elif i == 0:
# If this is the first line and it's not a new parameter,
# this is the shortdoc
shortdoc = line
elif currentparam is not None:
# This is part of the documentation of the current parameter
currentparam.add_doc_line(line)
# Make sure we get the final parameter
flush_param_if_necessary()
# Check for default values
params_required = []
params_defaults = []
for param in params:
if param.name in f.neuropod_default_args:
param.set_default(f.neuropod_default_args[param.name])
params_defaults.append(param)
else:
params_required.append(param)
return Function(name=f.__name__, shortdoc=shortdoc, params=params_required + params_defaults)
def write_doc(filename, f):
"""
Write the documentation for a Function `f` to `filename`
"""
with open(filename, "w") as docfile:
# Write the title and shortdoc
docfile.write("## " + f.name + "\n")
docfile.write(f.shortdoc + "\n")
# Write out the signature
docfile.write("```\n")
docfile.write(f.name + "(\n")
for param in f.params:
if param.has_default:
docfile.write(" " + param.name + " = " + str(param.default) + ",\n")
else:
docfile.write(" " + param.name + ",\n")
docfile.write(")\n")
docfile.write("```\n")
# Write out the list of params with their docs
docfile.write("### Params:\n")
for param in f.params:
docfile.write("#### " + param.name + "\n")
if param.has_default:
docfile.write("*default: `" + str(param.default) + "`*\n\n")
docfile.write(param.get_clean_doc() + "\n\n")
def write_doc_for_packager(packager, filename):
"""
Writes the documentation for a packager to a file
"""
f = parse_docstring(packager)
write_doc(filename, f)
if __name__ == '__main__':
import argparse
import os
from neuropod.packagers import create_tensorflow_neuropod, \
create_pytorch_neuropod, \
create_keras_neuropod, \
create_torchscript_neuropod
parser = argparse.ArgumentParser(description='Generate markdown documentation for the Neuropod packagers')
parser.add_argument('out_dir', help='The output directory to write the docs to')
args = parser.parse_args()
packager_mapping = {
"tensorflow.md": create_tensorflow_neuropod,
"pytorch.md": create_pytorch_neuropod,
"keras.md": create_keras_neuropod,
"torchscript.md": create_torchscript_neuropod,
}
for filename, packager in packager_mapping.items():
write_doc_for_packager(packager, os.path.join(args.out_dir, filename))