def get_command_def_rst(command_def): """return rst entry for a function or attribute described by the command def""" one_line = command_def.doc.one_line if command_def.maturity: one_line = get_maturity_rst(command_def.maturity) + "\n" + one_line extended = command_def.doc.extended display_name = command_def.rst_info.display_name if hasattr(command_def, "rst_info") else command_def.name if command_def.is_property: args_text = "" directive = "attribute" else: args_text = "(%s)" % command_def.get_function_args_text() directive = "function" rst = """ .. {directive}:: {name}{args_text} {one_line} """.format(directive=directive, name=display_name, args_text=args_text, one_line=indent(one_line), extended=indent(extended)) if command_def.parameters: rst += indent(_get_parameters_rst(command_def)) if command_def.return_info: rst += indent(_get_returns_rst(command_def.return_info)) rst += indent(extended) return rst
def write_py_rst_collections_file(root_path, collection_name, subfolders, files): # go through subfolders and find the index.rst and add to toc jazz # go through files and list global methods (leave making nice "summary table" as another exercise) title = upper_first(collection_name) title_emphasis = "=" * len(title) # Frame <frame-/index.rst> toctree = indent("\n".join(["%s <%s/index.rst>" % (entity_type_to_class_name(subfolder.replace('-',':')), subfolder) for subfolder in subfolders])) names =[f[:-4] for f in files if f[-4:] == ".rst" and f != "index.rst"] globs = "\n\n".join([":doc:`%s<%s>`" % (name, name) for name in names]) hidden_toctree = indent("\n".join(names)) content = """ {title} {title_emphasis} **Classes** .. toctree:: {toctree} .. toctree:: :hidden: {hidden_toctree} ------- **Global Methods** {globs} """.format(title=title, title_emphasis=title_emphasis, toctree=toctree, hidden_toctree=hidden_toctree, globs=globs) file_path = os.path.join(root_path, "index.rst") write_text_to_file(file_path, content)
def get_class_rst(cls): """ Gets rst text to describe a class Only lists members in summary tables with hyperlinks to other rst docs, with the exception of __init__ which is described in class rst text, below the summary tables. """ sorted_members = get_member_rst_list(cls) # sort defs for both summary table and attribute tables toctree = indent("\n".join([m.rst_name for m in sorted_members])) starter = """ .. toctree:: :hidden: {toctree} .. class:: {name} {rst_doc}""".format(toctree=toctree, name=get_type_name(cls), rst_doc=indent(cls.__doc__)) lines = [starter] lines.append(indent(get_attribute_summary_table(sorted_members), 4)) lines.append(indent(get_method_summary_table(sorted_members), 4)) installation = get_installation(cls) init_commands = [c for c in installation.commands if c.is_constructor] if init_commands: lines.append("\n.. _%s:\n" % get_cls_init_rst_label(cls)) # add rst label for internal reference lines.append(get_command_def_rst(init_commands[0])) return "\n".join(lines)
def get_command_def_rst(command_def): """return rst entry for a function or attribute described by the command def""" one_line = command_def.doc.one_line if command_def.maturity: one_line = get_maturity_rst(command_def.maturity) + "\n" + one_line extended = command_def.doc.extended display_name = command_def.rst_info.display_name if hasattr(command_def, "rst_info") else command_def.name if command_def.is_property: args_text = "" directive = "attribute" else: args_text = "(%s)" % command_def.get_function_args_text() directive = "function" rst = """ .. {directive}:: {name}{args_text} {one_line} """.format(directive=directive, name=display_name, args_text=args_text, one_line=indent(one_line)) if command_def.parameters: rst += indent(_get_parameters_rst(command_def)) if command_def.return_info: rst += indent(_get_returns_rst(command_def.return_info)) rst += indent(extended) if command_def.doc.examples: rst += indent(_get_examples_rst(command_def.doc.examples)) return rst
def get_repr(self, graph): graph_info = self._get_graph_info(graph) graph_name = '"%s"' % graph_info.name if graph_info.name is not None else '<unnamed>' r = ['%s %s' % (graph.__class__.__name__, graph_name), 'status = %s (last_read_date = %s)' % (graph_info.status, graph_info.last_read_date.isoformat())] if hasattr(graph, 'vertices'): r.extend(['vertices = ', indent(repr(graph.vertices) or "(None)", 2)]) if hasattr(graph, 'edges'): r.extend(['edges = ', indent(repr(graph.edges) or "(None)", 2)]) return "\n".join(r)
def get_repr(self, graph): graph_info = self._get_graph_info(graph) graph_name = '"%s"' % graph_info.name if graph_info.name is not None else "<unnamed>" r = [ "%s %s" % (graph.__class__.__name__, graph_name), "status = %s (last_read_date = %s)" % (graph_info.status, graph_info.last_read_date.isoformat()), ] if hasattr(graph, "vertices"): r.extend(["vertices = ", indent(repr(graph.vertices) or "(None)", 2)]) if hasattr(graph, "edges"): r.extend(["edges = ", indent(repr(graph.edges) or "(None)", 2)]) return "\n".join(r)
def _get_parameters_rst(command_def): return """ :Parameters: %s """ % indent("\n".join([ _get_parameter_rst(p) for p in command_def.parameters if not p.use_self ]))
def _get_returns_rest_rst(return_info): return """ ``{data_type}`` {description} """.format(data_type=get_type_name(return_info.data_type), description=indent(return_info.doc, 8)) if return_info\ else "<Missing Return Information>"
def get_doc_stub_modules_text(class_to_member_text_dict, import_return_types): """creates spa text for two different modules, returning the content in a tuple""" # The first module contains dependencies for the entity classes that are 'hard-coded' in the python API, # like Frame, Graph... They need things like _DocStubsFrame, or GraphMl to be defined first. # The second module contains entity classes that are created by meta-programming, like LdaModel, *Model, # which may depend on the 'hard-coded' python API. The second modules also contains any global methods, # like get_frame_names, which depend on objects like Frame being already defined. module1_lines = [get_file_header_text()] module2_lines = [] module2_all = [] # holds the names which should be in module2's __all__ for import * classes = sorted([(k, v) for k, v in class_to_member_text_dict.items()], key=lambda kvp: kvp[0].__name__) for cls, members_info in classes: logger.info("Processing %s for doc stubs", cls) names, text = zip(*members_info) installation = get_installation(cls, None) if installation: class_name, baseclass_name = installation.install_path.get_class_and_baseclass_names() if class_name not in exclude_classes_list: if class_name != cls.__name__: raise RuntimeError( "Internal Error: class name mismatch generating docstubs (%s != %s)" % (class_name, cls.__name__) ) if installation.host_class_was_created and installation.install_path.is_entity: lines = module2_lines module2_all.append(class_name) else: if not installation.host_class_was_created: class_name = get_doc_stub_class_name(class_name) lines = module1_lines lines.append( get_doc_stubs_class_text( class_name, "object", # no inheritance for docstubs, just define all explicitly "Auto-generated to contain doc stubs for static program analysis", indent("\n\n".join(text)), ) ) elif cls.__name__ == "trustedanalytics": module2_lines.extend(list(text)) module2_all.extend(list(names)) module2_lines.insert(0, '\n__all__ = ["%s"]' % '", "'.join(module2_all)) # Need to import any return type to enable SPA, like for get_frame, we need Frame for t in import_return_types: if test_import(t): module2_lines.insert(0, "from trustedanalytics import %s" % t) module2_lines.insert(0, get_file_header_text()) # remove doc_stub from namespace module1_lines.append(get_file_footer_text()) module2_lines.append("\ndel doc_stub") return "\n".join(module1_lines), "\n".join(module2_lines)
def get_doc_stub_modules_text(class_to_member_text_dict, import_return_types): """creates spa text for two different modules, returning the content in a tuple""" # The first module contains dependencies for the entity classes that are 'hard-coded' in the python API, # like Frame, Graph... They need things like _DocStubsFrame, or GraphMl to be defined first. # The second module contains entity classes that are created by meta-programming, like LdaModel, *Model, # which may depend on the 'hard-coded' python API. The second modules also contains any global methods, # like get_frame_names, which depend on objects like Frame being already defined. module1_lines = [get_file_header_text()] module2_lines = [] module2_all = [ ] # holds the names which should be in module2's __all__ for import * classes = sorted([(k, v) for k, v in class_to_member_text_dict.items()], key=lambda kvp: kvp[0].__name__) for cls, members_info in classes: logger.info("Processing %s for doc stubs", cls) names, text = zip(*members_info) installation = get_installation(cls, None) if installation: class_name, baseclass_name = installation.install_path.get_class_and_baseclass_names( ) if class_name not in exclude_classes_list: if class_name != cls.__name__: raise RuntimeError( "Internal Error: class name mismatch generating docstubs (%s != %s)" % (class_name, cls.__name__)) if installation.host_class_was_created and installation.install_path.is_entity: lines = module2_lines module2_all.append(class_name) else: if not installation.host_class_was_created: class_name = get_doc_stub_class_name(class_name) lines = module1_lines lines.append( get_doc_stubs_class_text( class_name, "object", # no inheritance for docstubs, just define all explicitly "Auto-generated to contain doc stubs for static program analysis", indent("\n\n".join(text)))) elif cls.__name__ == "trustedanalytics": module2_lines.extend(list(text)) module2_all.extend(list(names)) module2_lines.insert(0, '\n__all__ = ["%s"]' % '", "'.join(module2_all)) # Need to import any return type to enable SPA, like for get_frame, we need Frame for t in import_return_types: if test_import(t): module2_lines.insert(0, "from trustedanalytics import %s" % t) module2_lines.insert(0, get_file_header_text()) # remove doc_stub from namespace module1_lines.append(get_file_footer_text()) module2_lines.append("\ndel doc_stub") return '\n'.join(module1_lines), '\n'.join(module2_lines)
def get_parameter_text(p): description = indent(p.doc)[4:] # indents, but grabs the first line's space back if p.optional: description = "(default=%s) " % (p.default if p.default is not None else "None") + description return ":param {name}: {description}\n:type {name}: {data_type}".format(name=p.name, description=description, data_type=get_type_name(p.data_type))
def _get_args_warning(command_def): if command_def.name in _commands_with_udf_arg: return indent(""" **Note** - An argument for this command requires a Python User-Defined Function (UDF). This function must be especially prepared (wrapped/serialized) in order for it to run in the engine. **If this argument is needed for your call (i.e. it may be optional), then this particular command usage is NOT practically available as a REST API.** Today, the trustedanalytics Python client does the special function preparation and calls this API. """) return ''
def get_parameter_text(p): description = indent( p.doc)[4:] # indents, but grabs the first line's space back if p.optional: description = "(default=%s) " % (p.default if p.default is not None else "None") + description return ":param {name}: {description}\n:type {name}: {data_type}".format( name=p.name, description=description, data_type=get_type_name(p.data_type))
def _get_returns_rst(return_info): return """ :Returns: : {data_type} .. {description} """.format(data_type=get_type_name(return_info.data_type), description=indent(return_info.doc, 8))
def _get_parameter_rst(p): data_type = get_type_name(p.data_type) if p.optional: data_type += " (default=%s)" % (p.default if p.default is not None else "None") return """ **{name}** : {data_type} .. {description} """.format(name=p.name, data_type=data_type, description=indent(p.doc))
def get_doc_stubs_class_text(class_name, baseclass_name, doc, members_text, decoration="@doc_stub"): """ Produces code text for a loadable class definition """ return ''' {decoration} class {name}({baseclass}): """ {doc} """ {members} '''.format(decoration=decoration, name=class_name, baseclass=baseclass_name, doc=indent(doc), members=members_text)
def _get_argument_rest_rst(p): data_type = get_type_name(p.data_type) doc = p.doc or '<Missing Description>' if p.optional: data_type += " (default=%s)" % (p.default if p.default is not None else "None") return """ **{name}** : {data_type} .. {description} """.format(name=p.name, data_type=data_type, description=indent(doc))
def get_spa_docstring(command_def, override_rtype=None): """return text for a docstring needed for SPA, uses classic rst format""" try: doc_str = str(command_def.doc) except: print "Problem with command_def.doc for command %s" % command_def.full_name raise params = command_def.parameters if params: params_text = "\n".join([get_parameter_text(p) for p in params if not p.use_self]) doc_str += ("\n\n" + params_text) if command_def.return_info: doc_str += ("\n\n" + get_returns_text(command_def.return_info, override_rtype)) doc_str = re.sub(r':term:`(.+)`', r'\1', doc_str) # clear out some sphinx markup (could cover more....) return indent(doc_str)
def get_spa_docstring(command_def, override_rtype=None): """return text for a docstring needed for SPA, uses classic rst format""" try: doc_str = str(command_def.doc) except: print "Problem with command_def.doc for command %s" % command_def.full_name raise params = command_def.parameters if params: params_text = "\n".join( [get_parameter_text(p) for p in params if not p.use_self]) doc_str += ("\n\n" + params_text) if command_def.return_info: doc_str += ("\n\n" + get_returns_text(command_def.return_info, override_rtype)) doc_str = re.sub( r':term:`(.+)`', r'\1', doc_str) # clear out some sphinx markup (could cover more....) return indent(doc_str)
def _get_parameters_rst(command_def): return """ :Parameters: %s """ % indent("\n".join([_get_parameter_rst(p) for p in command_def.parameters if not p.use_self]))
def get_returns_text(return_info, override_rtype): description = indent(return_info.doc)[4:] # indents, but grabs the first line's space back return ":returns: {description}\n:rtype: {data_type}".format(description=description, data_type=get_type_name(override_rtype or return_info.data_type))
def get_command_def_rest_rst(command_def): """return rest entry for a function or attribute described by the command def""" one_line = command_def.doc.one_line if command_def.maturity: one_line = get_maturity_rst(command_def.maturity) + "\n" + one_line extended = command_def.doc.extended arguments = indent("\n".join([_get_argument_rest_rst(p) for p in command_def.parameters])) title = ':doc:`Commands <index>` %s' % command_def.full_name title_emphasis = "-" * len(title) return_info = _get_returns_rest_rst(command_def.return_info) command_rest_template = """ {title_emphasis} {title} {title_emphasis} {one_line} POST /v1/commands/ ================== GET /v1/commands/:id ==================== Request ------- **Route** :: POST /v1/commands/ **Body** {args_warning} :name: {full_name} :arguments: {arguments} | **Headers** :: Authorization: test_api_key_1 Content-type: application/json | **Description** {extended} | Response -------- **Status** :: 200 OK **Body** Returns information about the command. See the Response Body for Get Command here below. It is the same. GET /v1/commands/:id ==================== Request ------- **Route** :: GET /v1/commands/18 **Body** (None) **Headers** :: Authorization: test_api_key_1 Content-type: application/json | Response -------- **Status** :: 200 OK **Body** {return_info} """.format(title=title, title_emphasis=title_emphasis, one_line=one_line, full_name=command_def.full_name, args_warning=_get_args_warning(command_def), arguments=arguments, extended=extended, return_info=return_info) return command_rest_template
def _get_manual_hidden_toctree(): return indent("\n".join([ABOUT_COMMAND_NAMES]))
def _get_auto_hidden_toctree(command_defs): return indent("\n".join(sorted([get_command_rest_rst_file_name(c)[:-4] for c in command_defs])))
def get_returns_text(return_info, override_rtype): description = indent( return_info.doc)[4:] # indents, but grabs the first line's space back return ":returns: {description}\n:rtype: {data_type}".format( description=description, data_type=get_type_name(override_rtype or return_info.data_type))