diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 26c23f9..5172e0a 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -33,4 +33,5 @@ jobs: tes - name: Build docs - run: mkdocs build + run: mkdocs build && mkdocs gh-deploy --force + diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..767c555 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,32 @@ +# .readthedocs.yaml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the OS, Python version and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.12" + # You can also specify other tool versions: + # nodejs: "19" + # rust: "1.64" + # golang: "1.19" + +# Build documentation in the "docs/" directory with Sphinx +sphinx: + configuration: docs/conf.py + +# Optionally build your docs in additional formats such as PDF and ePub +formats: + - pdf + - epub + +# Optional but recommended, declare the Python requirements required +# to build your documentation +# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html +python: + install: + - requirements: docs/requirements.txt diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..35844d9 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,177 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = _build + +# User-friendly check for sphinx-build +ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) +$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from https://www.sphinx-doc.org/) +endif + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " xml to make Docutils-native XML files" + @echo " pseudoxml to make pseudoxml-XML files for display purposes" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Snakemake.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Snakemake.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/Snakemake" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Snakemake" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +latexpdfja: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through platex and dvipdfmx..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." + +xml: + $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml + @echo + @echo "Build finished. The XML files are in $(BUILDDIR)/xml." + +pseudoxml: + $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml + @echo + @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/docs/_static/custom.css b/docs/_static/custom.css new file mode 100644 index 0000000..ef0d3c7 --- /dev/null +++ b/docs/_static/custom.css @@ -0,0 +1,91 @@ +.image-reference img { + display: inline; + background: none !important; +} + +.image-reference { + border-bottom: none !important; +} + +:root { + --color-links: #047857; + --color-brand: #047857; +} + +#content { + overflow-x: auto; +} + +.sticky.top-16 { + overflow: unset; + } + +/* Light theme styles (default) */ +body.dark-theme { + background-color: black !important; +} + +/* Dark theme styles */ +body.light-theme { + background-color: blue !important; +} + +pre.light-theme .kn { color: #2838b0 !important } /* Keyword.Namespace */ +pre.light-theme .kp { color: #2838b0 !important } /* Keyword.Pseudo */ +pre.light-theme .kr { color: #2838b0 !important } /* Keyword.Reserved */ +pre.light-theme .kt { color: #2838b0; font-style: italic !important } /* Keyword.Type */ +pre.light-theme .m { color: #444444 !important } /* Literal.Number */ +pre.light-theme .s { color: #b83838 !important } /* Literal.String */ +pre.light-theme .na { color: #388038 !important } /* Name.Attribute */ +pre.light-theme .nb { color: #388038 !important } /* Name.Builtin */ +pre.light-theme .nc { color: #287088 !important } /* Name.Class */ +pre.light-theme .no { color: #b85820 !important } /* Name.Constant */ +pre.light-theme .nd { color: #287088 !important } /* Name.Decorator */ +pre.light-theme .ni { color: #709030 !important } /* Name.Entity */ +pre.light-theme .ne { color: #908828 !important } /* Name.Exception */ +pre.light-theme .nf { color: #785840 !important } /* Name.Function */ +pre.light-theme .nl { color: #289870 !important } /* Name.Label */ +pre.light-theme .nn { color: #289870 !important } /* Name.Namespace */ +pre.light-theme .nt { color: #2838b0 !important } /* Name.Tag */ +pre.light-theme .nv { color: #b04040 !important } /* Name.Variable */ +pre.light-theme .ow { color: #a848a8 !important } /* Operator.Word */ +pre.light-theme .pm { color: #888888 !important } /* Punctuation.Marker */ +pre.light-theme .w { color: #a89028 !important } /* Text.Whitespace */ +pre.light-theme .mb { color: #444444 !important } /* Literal.Number.Bin */ +pre.light-theme .mf { color: #444444 !important } /* Literal.Number.Float */ +pre.light-theme .mh { color: #444444 !important } /* Literal.Number.Hex */ +pre.light-theme .mi { color: #444444 !important } /* Literal.Number.Integer */ +pre.light-theme .mo { color: #444444 !important } /* Literal.Number.Oct */ +pre.light-theme .sa { color: #444444 !important } /* Literal.String.Affix */ +pre.light-theme .sb { color: #b83838 !important } /* Literal.String.Backtick */ +pre.light-theme .sc { color: #a848a8 !important } /* Literal.String.Char */ +pre.light-theme .dl { color: #b85820 !important } /* Literal.String.Delimiter */ +pre.light-theme .sd { color: #b85820; font-style: italic !important } /* Literal.String.Doc */ +pre.light-theme .s2 { color: #b83838 !important } /* Literal.String.Double */ +pre.light-theme .se { color: #709030 !important } /* Literal.String.Escape */ +pre.light-theme .sh { color: #b83838 !important } /* Literal.String.Heredoc */ +pre.light-theme .si { color: #b83838; text-decoration: underline !important } /* Literal.String.Interpol */ +pre.light-theme .sx { color: #a848a8 !important } /* Literal.String.Other */ +pre.light-theme .sr { color: #a848a8 !important } /* Literal.String.Regex */ +pre.light-theme .s1 { color: #b83838 !important } /* Literal.String.Single */ +pre.light-theme .ss { color: #b83838 !important } /* Literal.String.Symbol */ +pre.light-theme .bp { color: #388038; font-style: italic !important } /* Name.Builtin.Pseudo */ +pre.light-theme .fm { color: #b85820 !important } /* Name.Function.Magic */ +pre.light-theme .vc { color: #b04040 !important } /* Name.Variable.Class */ +pre.light-theme .vg { color: #908828 !important } /* Name.Variable.Global */ +pre.light-theme .vi { color: #b04040 !important } /* Name.Variable.Instance */ +pre.light-theme .vm { color: #b85820 !important } /* Name.Variable.Magic */ +pre.light-theme .il { color: #444444 !important } /* Literal.Number.Integer.Long */ +pre.light-theme .n { color: #444444 !important } /* Misc */ +pre.light-theme .o { color: #444 !important } /* Misc */ +pre.light-theme .p { color: #444 !important } /* Misc */ +pre.light-theme .k { color: #a848a8 !important } /* Misc */ +pre.light-theme .kc { color: #2838b0 !important } /* Misc */ +pre.light-theme .go { color: #546E7A !important } /* Misc */ +pre.light-theme .go { color: #546E7A !important } /* Misc */ +pre.light-theme .c1 { color: #546E7A !important } /* Misc */ +pre.light-theme .copy { background: #BBB !important } /* Misc */ + + +.c1 { color: #EEFFFF !important } /* Misc */ +.go { color: #EEFFFF !important } /* Misc */ diff --git a/docs/_static/custom.js b/docs/_static/custom.js new file mode 100644 index 0000000..295b9b5 --- /dev/null +++ b/docs/_static/custom.js @@ -0,0 +1,28 @@ +// Select the button using its class, assuming it's the only one with this class +const nav = document.querySelector(".flex.items-center.space-x-1"); +console.log(nav); + +const themeToggleButton = nav.childNodes[3]; +console.log(themeToggleButton); + +mode = localStorage.getItem('darkMode'); +setTheme(mode); + +// Add an event listener to the button +themeToggleButton.addEventListener('click', function() { + mode = mode === 'light' ? 'dark' : 'light' + setTheme(mode); +}); + +function setTheme(mode) { + var pres = document.body.getElementsByTagName("pre"); + for (let pre of pres) { + if (mode === 'dark') { + pre.classList.add('dark-theme'); + pre.classList.remove('light-theme'); + } else { + pre.classList.add('light-theme'); + pre.classList.remove('dark-theme'); + } + } +} diff --git a/docs/_static/logo-ga4gh-dark.png b/docs/_static/logo-ga4gh-dark.png new file mode 100644 index 0000000..a18b470 Binary files /dev/null and b/docs/_static/logo-ga4gh-dark.png differ diff --git a/docs/_static/logo-ga4gh-light.png b/docs/_static/logo-ga4gh-light.png new file mode 100644 index 0000000..6e42686 Binary files /dev/null and b/docs/_static/logo-ga4gh-light.png differ diff --git a/docs/_static/logo-snake.svg b/docs/_static/logo-snake.svg new file mode 100644 index 0000000..de13355 --- /dev/null +++ b/docs/_static/logo-snake.svg @@ -0,0 +1,109 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/_static/sphinx-argparse.css b/docs/_static/sphinx-argparse.css new file mode 100644 index 0000000..70ce1ab --- /dev/null +++ b/docs/_static/sphinx-argparse.css @@ -0,0 +1,6 @@ +.wy-table-responsive table td { + white-space: normal !important; +} +.wy-table-responsive { + overflow: visible !important; +} diff --git a/docs/_templates/page.html b/docs/_templates/page.html new file mode 100644 index 0000000..453f385 --- /dev/null +++ b/docs/_templates/page.html @@ -0,0 +1,10 @@ +{% extends "!page.html" %} + +{{ super() }} + +{% block extrahead %} + +{% endblock %} diff --git a/docs/api/tes.rst b/docs/api/tes.rst new file mode 100644 index 0000000..77c2a26 --- /dev/null +++ b/docs/api/tes.rst @@ -0,0 +1,34 @@ +py-tes +=========== + +.. toctree:: + :caption: API Docs + :name: api_docs + :hidden: + :maxdepth: 1 + + api_docs/tes + +tes.client module +----------------- + +.. automodule:: tes.client + :members: + :undoc-members: + :show-inheritance: + +tes.models module +----------------- + +.. automodule:: tes.models + :members: + :undoc-members: + :show-inheritance: + +tes.utils module +---------------- + +.. automodule:: tes.utils + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..3c5d55b --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,373 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Snakemake documentation build configuration file, created by +# sphinx-quickstart on Sat Feb 1 16:01:02 2014. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys +import os +from sphinxawesome_theme.postprocess import Icons + + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +sys.path.insert(0, os.path.abspath("../")) + +import tes + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.mathjax", + "sphinx.ext.viewcode", + "sphinx.ext.napoleon", + "sphinxarg.ext", + "sphinx.ext.autosectionlabel", + "myst_parser", + "sphinxawesome_theme.highlighting", +] + +html_css_files = ["custom.css"] +html_js_files = ["custom.js"] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# The suffix of source filenames. +source_suffix = [".rst", ".md"] + +# The encoding of source files. +# source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = "index" + +# General information about the project. +project = "py-tes" + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = tes.__version__ + +if os.environ.get("READTHEDOCS") == "True": + # Because Read The Docs modifies conf.py, versioneer gives a "dirty" + # version like "5.10.0+0.g28674b1.dirty" that is cleaned here. + version = version.partition("+0.g")[0] + +# The full version, including alpha/beta/rc tags. +release = version + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +# today = '' +# Else, today_fmt is used as the format for a strftime call. +# today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ["_build", "apidocs"] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +# default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +# add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +# add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +# show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = "material" +pygments_dark_style = "material" + +# A list of ignored prefixes for module index sorting. +# modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +# keep_warnings = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = "sphinxawesome_theme" +html_theme_options = { + "show_breadcrumbs": True, + "logo_light": "logo-ga4gh-light.png", + "logo_dark": "logo-ga4gh-dark.png", + "main_nav_links": { + "About": "index", + "API": "api/tes", + "GitHub": "https://github.com/ohsu-comp-bio/py-tes", + }, + "awesome_external_links": True, + "awesome_headerlinks": True, + "show_prev_next": False, + "extra_header_link_icons": { + "repository on GitHub": { + "link": "https://github.com/ohsu-comp-bio/py-tes", + "icon": ( + '' + '' + ), + }, + }, +} +html_permalinks_icon = Icons.permalinks_icon +# html_theme_options = { +# "show_nav_level": 2, +# "header_links_before_dropdown": 0, +# "external_links": [ +# { +# "text": "Snakemake plugin catalog", +# "alt": "Snakemake plugin catalog", +# "href": "https://snakemake.github.io/snakemake-plugin-catalog", +# }, +# { +# "text": "Snakemake workflow catalog", +# "alt": "Snakemake workflow catalog", +# "href": "https://snakemake.github.io/snakemake-workflow-catalog", +# }, +# { +# "text": "Snakemake wrappers", +# "alt": "Snakemake wrappers", +# "href": "https://snakemake-wrappers.readthedocs.io", +# }, +# ], +# } +# html_theme_options = { +# "primary_color": "emerald", +# "secondary_color": "emerald", +# "dark_logo": "logo-snake.svg", +# "light_logo": "logo-snake.svg", +# "navigation_style": "plain", +# "sidebar_links": [ +# { +# "text": "Snakemake plugin catalog", +# "alt": "Snakemake plugin catalog", +# "href": "https://snakemake.github.io/snakemake-plugin-catalog", +# }, +# { +# "text": "Snakemake workflow catalog", +# "alt": "Snakemake workflow catalog", +# "href": "https://snakemake.github.io/snakemake-workflow-catalog", +# }, +# { +# "text": "Snakemake wrappers", +# "alt": "Snakemake wrappers", +# "href": "https://snakemake-wrappers.readthedocs.io", +# }, +# ], +# } + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +# html_theme_path = sphinx_bootstrap_theme.get_html_theme_path() + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +# html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +# html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +# html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +# html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ["_static"] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +# html_extra_path = ["_static/css"] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +# html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +# html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +# html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +# html_additional_pages = {"index": "index.html"} + +# If false, no module index is generated. +# html_domain_indices = True + +# If false, no index is generated. +# html_use_index = True + +# If true, the index is split into individual pages for each letter. +# html_split_index = False + +# If true, links to the reST sources are added to the pages. +# html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +# html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +# html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +# html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +# html_file_suffix = None + +# Output file base name for HTML help builder. +# htmlhelp_basename = "Snakemakedoc" + + +# -- Options for LaTeX output --------------------------------------------- + +# latex_elements = { +# # The paper size ('letterpaper' or 'a4paper'). +# #'papersize': 'letterpaper', +# # The font size ('10pt', '11pt' or '12pt'). +# #'pointsize': '10pt', +# # Additional stuff for the LaTeX preamble. +# #'preamble': '', +# } + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +# latex_documents = [ +# ("index", "Snakemake.tex", "Snakemake Documentation", "Johannes Koester", "manual"), +# ] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +# latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +# latex_use_parts = False + +# If true, show page references after internal links. +# latex_show_pagerefs = False + +# If true, show URL addresses after external links. +# latex_show_urls = False + +# Documents to append as an appendix to all manuals. +# latex_appendices = [] + +# If false, no module index is generated. +# latex_domain_indices = True + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +# man_pages = [("index", "snakemake", "Snakemake Documentation", ["Johannes Koester"], 1)] + +# If true, show URL addresses after external links. +# man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +# texinfo_documents = [ +# ( +# "index", +# "Snakemake", +# "Snakemake Documentation", +# "Johannes Koester", +# "Snakemake", +# "One line description of project.", +# "Miscellaneous", +# ), +# ] + +# Documents to append as an appendix to all manuals. +# texinfo_appendices = [] + +# If false, no module index is generated. +# texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +# texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +# texinfo_no_detailmenu = False + + +def setup(app): + app.add_css_file("sphinx-argparse.css") diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..71abaa6 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,210 @@ +.. automodule:: tes + +.. _manual-main: + +====== +py-tes +====== + +.. image:: https://img.shields.io/github/actions/workflow/status/ohsu-comp-bio/py-tes/tests.yml?logo=github + :alt: GitHub Actions Test Status + :target: https://github.com/ohsu-comp-bio/py-tes/actions +.. image:: https://coveralls.io/repos/github/ohsu-comp-bio/py-tes/badge.svg?branch=master + :target: https://coveralls.io/github/ohsu-comp-bio/py-tes?branch=master +.. image:: https://img.shields.io/badge/License-MIT-yellow.svg + :target: https://opensource.org/licenses/MIT + +*py-tes* is a library for interacting with servers implementing the +`GA4GH Task Execution +Schema `__. + +Install +~~~~~~~ + +Available on `PyPI `__. + +:: + + pip install py-tes + +Example +~~~~~~~ + +.. code:: python + + import tes + + # define task + task = tes.Task( + executors=[ + tes.Executor( + image="alpine", + command=["echo", "hello"] + ) + ] + ) + + # create client + cli = tes.HTTPClient("https://funnel.example.com", timeout=5) + + # access endpoints + service_info = cli.get_service_info() + task_id = cli.create_task(task) + task_info = cli.get_task(task_id, view="BASIC") + cli.cancel_task(task_id) + tasks_list = cli.list_tasks(view="MINIMAL") # default view + +How to… +~~~~~~~ + + Makes use of the objects above… + +…export a model to a dictionary +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code:: python + + task_dict = task.as_dict(drop_empty=False) + +``task_dict`` contents: + +.. code:: console + + {'id': None, 'state': None, 'name': None, 'description': None, 'inputs': None, 'outputs': None, 'resources': None, 'executors': [{'image': 'alpine', 'command': ['echo', 'hello'], 'workdir': None, 'stdin': None, 'stdout': None, 'stderr': None, 'env': None}], 'volumes': None, 'tags': None, 'logs': None, 'creation_time': None} + +…export a model to JSON +^^^^^^^^^^^^^^^^^^^^^^^ + +.. code:: python + + task_json = task.as_json() # also accepts `drop_empty` arg + +``task_json`` contents: + +.. code:: console + + {"executors": [{"image": "alpine", "command": ["echo", "hello"]}]} + +…pretty print a model +^^^^^^^^^^^^^^^^^^^^^ + +.. code:: python + + print(task.as_json(indent=3)) # keyword args are passed to `json.dumps()` + +Output: + +.. code:: json + + { + "executors": [ + { + "image": "alpine", + "command": [ + "echo", + "hello" + ] + } + ] + } + +…access a specific task from the task list +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code:: python + + specific_task = tasks_list.tasks[5] + +``specific_task`` contents: + +.. code:: console + + Task(id='393K43', state='COMPLETE', name=None, description=None, inputs=None, outputs=None, resources=None, executors=None, volumes=None, tags=None, logs=None, creation_time=None) + +…iterate over task list items +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code:: python + + for t in tasks_list[:3]: + print(t.as_json(indent=3)) + +Output: + +.. code:: console + + { + "id": "task_A2GFS4", + "state": "RUNNING" + } + { + "id": "task_O8G1PZ", + "state": "CANCELED" + } + { + "id": "task_W246I6", + "state": "COMPLETE" + } + +…instantiate a model from a JSON representation +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code:: python + + task_from_json = tes.client.unmarshal(task_json, tes.Task) + +``task_from_json`` contents: + +.. code:: console + + Task(id=None, state=None, name=None, description=None, inputs=None, outputs=None, resources=None, executors=[Executor(image='alpine', command=['echo', 'hello'], workdir=None, stdin=None, stdout=None, stderr=None, env=None)], volumes=None, tags=None, logs=None, creation_time=None) + +Which is equivalent to ``task``: + +.. code:: python + + print(task_from_json == task) + +Output: + +.. code:: console + + True + +.. _main-support: + +Support +~~~~~~~ + +* For releases, see :ref:`Changelog `. +* Check :ref:`frequently asked questions (FAQ) `. +* For **bugs and feature requests**, please use the `issue tracker `_. +* For **contributions**, visit py-tes on `Github `_ + +.. _main-resources: + +Resources +~~~~~~~~~ + +`cwl-tes `_ + cwl-tes submits your tasks to a TES server. Task submission is parallelized when possible. + +`Funnel `_ + Funnel is a toolkit for distributed task execution with a simple API. + +`ga4gh-tes `_ + C# implementation of the GA4GH TES API; provides distributed batch task execution on Microsoft Azure + +`Nextflow `_ + Nextflow enables scalable and reproducible scientific workflows using software containers. It allows the adaptation of pipelines written in the most common scripting languages. + +`Snakemake `_ + The Snakemape workflow management system is a tool to create reproducible and scalable data analyses + +.. toctree:: + :caption: API + :name: api + :hidden: + :maxdepth: 1 + + api/tes diff --git a/docs/requirements.txt b/docs/requirements.txt index 1833352..4f5db2a 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,5 +1,14 @@ -lazydocs>=0.4.8 -mkdocs>=1.4.2 -mkdocs-awesome-pages-plugin>=2.8.0 -mkdocs-material>=9.0.12 -pydocstyle>=6.3.0 +sphinx >=3 +sphinxcontrib-napoleon +sphinx-argparse +docutils +myst-parser +configargparse +appdirs +immutables +sphinxawesome-theme +snakemake-interface-common +snakemake-interface-executor-plugins +snakemake-interface-storage-plugins +attrs +python-dateutil diff --git a/requirements.txt b/requirements.txt index 907fd76..a83eeec 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,5 @@ -attrs>=22.2.0 -python-dateutil>=2.8.2 -requests>=2.28.2 +attrs>=17.4.0 +future>=0.16.0 +python-dateutil>=2.6.1 +requests>=2.18.2 +sphinx_rtd_theme \ No newline at end of file