Skip to content

Commit

Permalink
Start adding REST API docs
Browse files Browse the repository at this point in the history
  • Loading branch information
abkfenris committed May 12, 2023
1 parent 81ecbbc commit a84e193
Show file tree
Hide file tree
Showing 18 changed files with 281 additions and 34 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,5 @@ dmypy.json

# Pyre type checker
.pyre/
docs/source/api/generated
docs/source/api/openapi.json
3 changes: 3 additions & 0 deletions .readthedocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ build:
os: ubuntu-22.04
tools:
python: "3.11"
jobs:
pre_build:
- python docs/source/api/generate_openapi.py

# Optionally set the version of Python and requirements required to build your docs
python:
Expand Down
1 change: 1 addition & 0 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ autodoc_pydantic
myst-nb
sphinx-design
sphinx_github_changelog
sphinxcontrib-openapi
138 changes: 138 additions & 0 deletions docs/source/api/contributing.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
========================
Contributing to Xpublish
========================

Contributions are highly welcomed and appreciated. Every little help counts,
so do not hesitate!

.. contents:: Contribution links
:depth: 2

.. _submitfeedback:

Feature requests and feedback
-----------------------------

Do you like Xpublish? Share some love on Twitter or in your blog posts!

We'd also like to hear about your propositions and suggestions. Feel free to
`submit them as issues <https://github.com/xpublish-community/xpublish>`_ and:

* Explain in detail how they should work.
* Keep the scope as narrow as possible. This will make it easier to implement.

.. _reportbugs:

Report bugs
-----------

Report bugs for Xpublish in the `issue tracker <https://github.com/xpublish-community/xpublish>`_.

If you are reporting a bug, please include:

* Your operating system name and version.
* Any details about your local setup that might be helpful in troubleshooting,
specifically the Python interpreter version, installed libraries, and Xpublish
version.
* Detailed steps to reproduce the bug.

If you can write a demonstration test that currently fails but should pass
(xfail), that is a very useful commit to make as well, even if you cannot
fix the bug itself.

.. _fixbugs:

Fix bugs
--------

Look through the `GitHub issues for bugs <https://github.com/xpublish-community/xpublish/labels/type:%20bug>`_.

Talk to developers to find out how you can fix specific bugs.

Write documentation
-------------------

xpublish could always use more documentation. What exactly is needed?

* More complementary documentation. Have you perhaps found something unclear?
* Docstrings. There can never be too many of them.
* Blog posts, articles and such -- they're all very appreciated.

You can also edit documentation files directly in the GitHub web interface,
without using a local copy. This can be convenient for small fixes.

To build the documentation locally, you first need to have a local development environment setup
by following the the steps in `Preparing Pull Requests <#pull-requests>`__ through the **Install
dependencies into a new conda environment** step.

You can then build the documentation with the following commands::

$ conda activate xpublish-dev
$ cd docs
$ pip install -r requirements.txt
$ make html

The built documentation should be available in the ``docs/_build/`` folder.

.. _`pull requests`:
.. _pull-requests:

Preparing Pull Requests
-----------------------

#. Fork the
`xpublish GitHub repository <https://github.com/xpublish-community/xpublish>`__. It's
fine to use ``xpublish`` as your fork repository name because it will live
under your user.

#. Clone your fork locally using `git <https://git-scm.com/>`_ and create a branch::

$ git clone git@github.com:YOUR_GITHUB_USERNAME/xpublish.git
$ cd xpublish

# now, to fix a bug or add feature create your own branch off "main":

$ git checkout -b your-bugfix-feature-branch-name main

#. Install `pre-commit <https://pre-commit.com>`_ and its hook on the Xpublish repo::

$ pip install --user pre-commit
$ pre-commit install

Afterwards ``pre-commit`` will run whenever you commit.

https://pre-commit.com/ is a framework for managing and maintaining multi-language pre-commit hooks
to ensure code-style and code formatting is consistent.

#. Install dependencies into a new conda environment::

$ conda create -n xpublish-dev
$ conda activate xpublish-dev
$ pip install -r dev-requirements.txt
$ pip install --no-deps -e .

#. Run all the tests

Now running tests is as simple as issuing this command::

$ conda activate xpublish-dev
$ pytest

This command will run tests via the "pytest" tool.

#. You can now edit your local working copy and run the tests again as necessary. Please follow PEP-8 for naming.

When committing, ``pre-commit`` will re-format the files if necessary.

#. Commit and push once your tests pass and you are happy with your change(s)::

$ git commit -a -m "<commit message>"
$ git push -u

#. Finally, submit a pull request through the GitHub website using this data::

head-fork: YOUR_GITHUB_USERNAME/xpublish
compare: your-branch-name

base-fork: xpublish-community/xpublish
base: main
6 changes: 6 additions & 0 deletions docs/source/api/endpoints.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# API Endpoints

```{eval-rst}
.. openapi:: ./openapi.json
:group:
```
14 changes: 14 additions & 0 deletions docs/source/api/generate_openapi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import json
from pathlib import Path

import xpublish

rest = xpublish.Rest({})
app = rest.app
openapi_spec = app.openapi()

script_path = Path(__file__)
spec_path = script_path.parent / 'openapi.json'

with spec_path.open('w') as f:
json.dump(openapi_spec, f)
61 changes: 61 additions & 0 deletions docs/source/api/included_plugins.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Included Plugins

Xpublish includes a set of built in plugins with associated endpoints.

```{eval-rst}
.. currentmodule:: xpublish
```

## Dataset Info

```{eval-rst}
.. autosummary::
:toctree: generated/
plugins.included.dataset_info.DatasetInfoPlugin
.. openapi:: ./openapi.json
:include:
/datasets/{dataset_id}/keys
/datasets/{dataset_id}/dict
/datasets/{dataset_id}/info
```

## Module Version

```{eval-rst}
.. autosummary::
:toctree: generated/
plugins.included.module_version.ModuleVersionPlugin
.. openapi:: ./openapi.json
:include:
/versions
```

## Plugin Info

```{eval-rst}
.. autosummary::
:toctree: generated/
plugins.included.plugin_info.PluginInfoPlugin
.. openapi:: ./openapi.json
:include:
/plugins
```

## Zarr

```{eval-rst}
.. autosummary::
:toctree: generated/
plugins.included.zarr.ZarrPlugin
.. openapi:: ./openapi.json
:include:
/datasets/{dataset_id}/zarr/*
```
31 changes: 9 additions & 22 deletions docs/source/api.md → docs/source/api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@

# API reference

```{toctree}
---
hidden:
---
endpoints
included_plugins
plugins
```

## Top-level Rest class

The {class}`~xpublish.Rest` class can be used for publishing a
Expand Down Expand Up @@ -136,25 +145,3 @@ passed in to the `Plugin.app_router` or `Plugin.dataset_router` method.
get_plugins
get_plugin_manager
```

## Plugins

Plugins are inherit from the {class}`~xpublish.Plugin` class, and implement various hooks.

```{eval-rst}
.. currentmodule:: xpublish
```

```{eval-rst}
.. autosummary::
:toctree: generated/
Plugin
hookimpl
hookspec
Dependencies
plugins.hooks.PluginSpec
plugins.manage.find_default_plugins
plugins.manage.load_default_plugins
plugins.manage.configure_plugins
```
25 changes: 25 additions & 0 deletions docs/source/api/plugins.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
```{eval-rst}
.. currentmodule:: xpublish
```

# Plugins

Plugins are inherit from the {class}`~xpublish.Plugin` class, and implement various hooks.

```{eval-rst}
.. currentmodule:: xpublish
```

```{eval-rst}
.. autosummary::
:toctree: generated/
Plugin
hookimpl
hookspec
Dependencies
plugins.hooks.PluginSpec
plugins.manage.find_default_plugins
plugins.manage.load_default_plugins
plugins.manage.configure_plugins
```
1 change: 1 addition & 0 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
'sphinx_design',
'myst_parser',
'sphinx_github_changelog',
'sphinxcontrib.openapi',
]

myst_enable_extensions = []
Expand Down
4 changes: 2 additions & 2 deletions docs/source/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ with useful background information and explanation.
```
```{grid-item-card} API Reference
:link: api
:link: api/index
:link-type: doc
The reference guide contains a detailed description of the Xpublish API/
Expand Down Expand Up @@ -109,7 +109,7 @@ maxdepth: 2
---
getting-started/index
user-guide/index
api
api/index
ecosystem/index
Contributing <contributing>
changelog
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,4 @@ known-third-party = [

[tool.ruff.flake8-bugbear]
# Allow fastapi.Depends and other dependency injection style function arguments
extend-immutable-calls = ["fastapi.Depends", "fastapi.Query"]
extend-immutable-calls = ["fastapi.Depends", "fastapi.Query", "fastapi.Path"]
2 changes: 1 addition & 1 deletion xpublish/plugins/included/dataset_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class DatasetInfoPlugin(Plugin):
name = 'dataset_info'

dataset_router_prefix: str = ''
dataset_router_tags: Sequence[str] = []
dataset_router_tags: Sequence[str] = ['dataset_info']

@hookimpl
def dataset_router(self, deps: Dependencies):
Expand Down
5 changes: 4 additions & 1 deletion xpublish/plugins/included/module_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,20 @@


class ModuleVersionPlugin(Plugin):
"""Share the currently loaded versions of key libraries"""

name = 'module_version'

app_router_prefix: str = ''
app_router_tags: List[str] = []
app_router_tags: List[str] = ['module_version']

@hookimpl
def app_router(self):
router = APIRouter(prefix=self.app_router_prefix, tags=self.app_router_tags)

@router.get('/versions')
def get_versions():
"""Currently loaded versions of key libraries"""
versions = dict(get_sys_info() + netcdf_and_hdf5_versions())
modules = [
'xarray',
Expand Down
5 changes: 4 additions & 1 deletion xpublish/plugins/included/plugin_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ class PluginInfo(BaseModel):


class PluginInfoPlugin(Plugin):
"""Expose plugin source and version"""

name = 'plugin_info'

app_router_prefix: str = ''
app_router_tags: Sequence[str] = []
app_router_tags: Sequence[str] = ['plugin_info']

@hookimpl
def app_router(self, deps: Dependencies):
Expand All @@ -29,6 +31,7 @@ def app_router(self, deps: Dependencies):
def get_plugins(
plugins: Dict[str, Plugin] = Depends(deps.plugins)
) -> Dict[str, PluginInfo]:
"""Return the source and version of the currently loaded plugins"""
plugin_info = {}

for name, plugin in plugins.items():
Expand Down
Loading

0 comments on commit a84e193

Please sign in to comment.