Skip to content

Commit

Permalink
Add 0.10 docs (#700)
Browse files Browse the repository at this point in the history
* Rename ophyd_async.{epics,tango}.sim -> demo

* Fix typo in import linter

* Rewrite sim and epics.demo devices to do the same

* Fix SignalDatatypeT docs

* Localise usage of T to each module

* Add docstrings without breaking type checking

* Add some more docs

* Tidy ADAravis and write how-to areaDetector

* Localise use of T in tests

* Fix tests

* Try to shorten tutorials

* Patch out more plotting

* Fix tests on windows

* Add another article

* More docstrings

* Switch to autodoc2 and write a lot more docstrings

* Fix tests

* Add back in pyepics for dev deps

* More tweaks

* Apply suggestions from code review

Co-authored-by: Jakub Wlodek <[email protected]>

* Tweak

* Added devices, signals and backends article

* Fix links

* Add diagram

* Update docs/how-to/interact-with-signals.md

Co-authored-by: Eva Lott <[email protected]>

* Review comments

---------

Co-authored-by: Eva <[email protected]>
Co-authored-by: Eva Lott <[email protected]>
Co-authored-by: Jakub Wlodek <[email protected]>
  • Loading branch information
4 people authored Feb 11, 2025
1 parent a69d4e2 commit 663ad9d
Show file tree
Hide file tree
Showing 178 changed files with 3,610 additions and 2,938 deletions.
3 changes: 2 additions & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"editor.codeActionsOnSave": {
"source.organizeImports": "explicit"
},
"remote.autoForwardPorts": false,
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff"
}
Expand All @@ -38,7 +39,7 @@
},
"features": {
// add in eternal history and other bash features
"ghcr.io/diamondlightsource/devcontainer-features/bash-config:1.0.0": {}
"ghcr.io/diamondlightsource/devcontainer-features/bash-config:1": {}
},
// Create the config folder for the bash-config feature
"initializeCommand": "mkdir -p ${localEnv:HOME}/.config/bash-config",
Expand Down
2 changes: 1 addition & 1 deletion .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Contribute to the project
# How to contribute to the project

Contributions and issues are most welcome! All issues and pull requests are
handled through [GitHub](https://github.com/bluesky/ophyd-async/issues). Also, please check for any existing issues before
Expand Down
17 changes: 10 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,19 @@ Asynchronous Bluesky hardware abstraction code, compatible with control systems
| Documentation | <https://bluesky.github.io/ophyd-async> |
| Releases | <https://github.com/bluesky/ophyd-async/releases> |

Ophyd-async is a Python library for asynchronously interfacing with hardware, intended to
be used as an abstraction layer that enables experiment orchestration and data acquisition code to operate above the specifics of particular devices and control
systems.
Ophyd-async is a Python library for asynchronously interfacing with hardware, intended to be used as an abstraction layer that enables experiment orchestration and data acquisition code to operate above the specifics of particular devices and control systems.

Both ophyd and ophyd-async are typically used with the [Bluesky Run Engine][] for experiment orchestration and data acquisition.
Both ophyd sync and ophyd-async are typically used with the [Bluesky Run Engine][] for experiment orchestration and data acquisition.

While [EPICS][] is the most common control system layer that ophyd-async can interface with, support for other control systems like [Tango][] will be supported in the future. The focus of ophyd-async is:
The main differences from ophyd sync are:

* Asynchronous signal access, opening the possibility for hardware-triggered scanning (also known as fly-scanning)
* Simpler instantiation of devices (groupings of signals) with less reliance upon complex class hierarchies
- Asynchronous Signal access, simplifying the parallel control of multiple Signals
- Support for [EPICS][] PVA and [Tango][] as well as the traditional EPICS CA
- Better library support for splitting the logic from the hardware interface to avoid complex class heirarchies

It was written with the aim of implementing flyscanning in a generic and extensible way with highly customizable devices like PandABox and the Delta Tau PMAC products. Using async code makes it possible to do the "put 3 PVs in parallel, then get from another PV" logic that is common in flyscanning without the performance and complexity overhead of multiple threads.

Devices from both ophyd sync and ophyd-async can be used in the same RunEngine and even in the same scan. This allows a per-device migration where devices are reimplemented in ophyd-async one by one.

[Bluesky Run Engine]: http://blueskyproject.io/bluesky
[EPICS]: http://www.aps.anl.gov/epics/
Expand Down
16 changes: 0 additions & 16 deletions docs/_api.rst

This file was deleted.

5 changes: 5 additions & 0 deletions docs/_static/custom.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/* allow a wider screen so we can fit 88 chars of source code on it */
.bd-page-width {
max-width: 100rem;
/* default is 88rem */
}
42 changes: 0 additions & 42 deletions docs/_templates/custom-module-template.rst

This file was deleted.

190 changes: 112 additions & 78 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,44 @@
https://www.sphinx-doc.org/en/master/usage/configuration.html
"""

import os
import sys
from pathlib import Path
from subprocess import check_output

import requests
from sphinx import addnodes, application, environment
from sphinx.ext import intersphinx

import ophyd_async

# -- General configuration ------------------------------------------------
sys.path.insert(0, os.path.abspath("../../src"))

# A custom handler for TypeVars and Unions
def missing_reference_handler(
app: application.Sphinx,
env: environment.BuildEnvironment,
node: addnodes.pending_xref,
contnode,
):
target = node["reftarget"]
if "." in target and node["reftype"] == "class":
# Try again as `obj` so we pick up Unions, TypeVars and other things
if target.startswith("ophyd_async"):
# Pick it up from our domain
domain = env.domains[node["refdomain"]]
refdoc = node.get("refdoc")
return domain.resolve_xref(
env, refdoc, app.builder, "obj", target, node, contnode
)
else:
# pass it to intersphinx with the right type
node["reftype"] = "obj"
return intersphinx.missing_reference(app, env, node, contnode)


def setup(app: application.Sphinx):
app.connect("missing-reference", missing_reference_handler)


# General information about the project.
project = "ophyd-async"
copyright = "2014, Brookhaven National Lab"
Expand All @@ -35,76 +62,110 @@
extensions = [
# for diagrams
"sphinxcontrib.mermaid",
# Used for BaseModel autodoc
"sphinxcontrib.autodoc_pydantic",
# Use this for generating API docs
"sphinx.ext.autodoc",
# Not sure if this is still used?
"sphinx.ext.doctest",
# and making summary tables at the top of API docs
"sphinx.ext.autosummary",
# This can parse google style docstrings
"sphinx.ext.napoleon",
"autodoc2",
# For linking to external sphinx documentation
"sphinx.ext.intersphinx",
# Add links to source code in API docs
"sphinx.ext.viewcode",
# Adds the inheritance-diagram generation directive
"sphinx.ext.inheritance_diagram",
# Add a copy button to each code block
"sphinx_copybutton",
# For the card element
"sphinx_design",
"sphinx.ext.mathjax",
# To make .nojekyll
"sphinx.ext.githubpages",
# To make the {ipython} directive
"IPython.sphinxext.ipython_directive",
# To syntax highlight "ipython" language code blocks
"IPython.sphinxext.ipython_console_highlighting",
# To embed matplotlib plots generated from code
"matplotlib.sphinxext.plot_directive",
# To parse markdown
"myst_parser",
"numpydoc",
]

# So we can use the ::: syntax
myst_enable_extensions = ["colon_fence"]
# Which package to load and document
autodoc2_packages = ["../src/ophyd_async"]

# Put them in docs/_api which is git ignored
autodoc2_output_dir = "_api"

# Modules that should have an all...
autodoc2_module_all_regexes = [
r"ophyd_async\.core",
r"ophyd_async\.sim",
r"ophyd_async\.epics\.[^\.]*",
r"ophyd_async\.tango\.[^\.]*",
r"ophyd_async\.fastcs\.[^\.]*",
r"ophyd_async\.plan_stubs",
r"ophyd_async\.testing",
]

# ... so should have their private modules ignored
autodoc2_skip_module_regexes = [
x + r"\._.*" for x in autodoc2_module_all_regexes + ["ophyd_async"]
]

# parse using napoleon numpy docstrings
autodoc2_docstring_parser_regexes = [(".*", "ophyd_async._docs_parser")]
# Render with shortened names
autodoc2_render_plugin = "ophyd_async._docs_parser.ShortenedNamesRenderer"

napoleon_google_docstring = False
napoleon_numpy_docstring = True
# Don't document private things
autodoc2_hidden_objects = {"private", "inherited", "dunder"}

# We don't have any docstring for __init__, so by separating
# them here we don't get the "Initilize" text that would otherwise be added
autodoc2_class_docstring = "both"

# For some reason annotations are not expanded, this will do here
autodoc2_replace_annotations = [
("~PvSuffix.rbv", "ophyd_async.epics.core.PvSuffix.rbv")
]

# So we can use the ::: syntax and the :param thing: syntax
myst_enable_extensions = ["colon_fence", "fieldlist"]

# If true, Sphinx will warn about all references where the target cannot
# be found.
# nitpicky = True
nitpicky = True

# A list of (type, target) tuples (by default empty) that should be ignored when
# generating warnings in "nitpicky mode". Note that type should include the
# domain name if present. Example entries would be ('py:func', 'int') or
# ('envvar', 'LD_LIBRARY_PATH').
nitpick_ignore = [
# builtins
("py:class", "NoneType"),
("py:class", "'str'"),
("py:class", "'float'"),
("py:class", "'int'"),
("py:class", "'bool'"),
("py:class", "'object'"),
("py:class", "'id'"),
# typing
("py:class", "typing_extensions.Literal"),
obj_ignore = [
"ophyd_async.core._detector.DetectorControllerT",
"ophyd_async.core._detector.DetectorWriterT",
"ophyd_async.core._device.DeviceT",
"ophyd_async.core._device_filler.SignalBackendT",
"ophyd_async.core._device_filler.DeviceConnectorT",
"ophyd_async.core._protocol.C",
"ophyd_async.core._signal_backend.SignalDatatypeV",
"ophyd_async.core._status.AsyncStatusBase",
"ophyd_async.core._utils.P",
"ophyd_async.core._utils.T",
"ophyd_async.core._utils.V",
"ophyd_async.epics.adcore._core_logic.ADBaseIOT",
"ophyd_async.epics.adcore._core_logic.ADBaseControllerT",
"ophyd_async.epics.adcore._core_writer.NDFileIOT",
"ophyd_async.epics.adcore._core_writer.ADWriterT",
"ophyd_async.tango.core._base_device.T",
"ophyd_async.tango.core._tango_transport.R",
"ophyd_async.tango.core._tango_transport.TangoProxy",
"ophyd_async.testing._utils.T",
"0.1",
"1.0",
]
nitpick_ignore = []
for var in obj_ignore:
nitpick_ignore.append(("py:class", var))
nitpick_ignore.append(("py:obj", var))
# Ignore classes in modules with no intersphinx
nitpick_ignore_regex = [
(r"py:.*", r"pydantic\..*"),
(r"py:.*", r"tango\..*"),
]

# Order the members by the order they appear in the source code
autodoc_member_order = "bysource"

# Don't inherit docstrings from baseclasses
autodoc_inherit_docstrings = False

# Add some more modules to the top level autosummary
ophyd_async.__all__ += ["sim", "epics", "tango", "fastcs", "plan_stubs"]

# Document only what is in __all__
autosummary_ignore_module_all = False

# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]

# Output graphviz directive produced images in a scalable format
graphviz_output_format = "svg"
Expand All @@ -127,7 +188,6 @@
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = "sphinx"


# Example configuration for intersphinx: refer to the Python standard library.
# This means you can link things like `str` and `asyncio` to the relevant
# docs in the python documentation.
Expand All @@ -137,20 +197,12 @@
"numpy": ("https://numpy.org/devdocs/", None),
"databroker": ("https://blueskyproject.io/databroker/", None),
"event-model": ("https://blueskyproject.io/event-model/main", None),
"pytest": ("https://docs.pytest.org/en/stable/", None),
}

# A dictionary of graphviz graph attributes for inheritance diagrams.
inheritance_graph_attrs = {"rankdir": "TB"}

# Common links that should be available on every page
rst_epilog = """
.. _NSLS: https://www.bnl.gov/nsls2
.. _black: https://github.com/psf/black
.. _ruff: https://beta.ruff.rs/docs/
.. _mypy: http://mypy-lang.org/
.. _pre-commit: https://pre-commit.com/
"""

# Ignore localhost links for periodic check that links in docs are valid
linkcheck_ignore = [r"http://localhost:\d+/"]

Expand Down Expand Up @@ -230,27 +282,9 @@
html_logo = "images/ophyd-async-logo.svg"
html_favicon = "images/ophyd-favicon.svg"

# If False and a module has the __all__ attribute set, autosummary documents
# every member listed in __all__ and no others. Default is True
autosummary_ignore_module_all = False

# Turn on sphinx.ext.autosummary
autosummary_generate = True

# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]

# Look for signatures in the first line of the docstring (used for C functions)
autodoc_docstring_signature = True

# numpydoc config
numpydoc_show_class_members = False

# Don't show config summary as it's not relevant
autodoc_pydantic_model_show_config_summary = False

# Show the fields in source order
autodoc_pydantic_model_summary_list_order = "bysource"
# Custom CSS
html_static_path = ["_static"]
html_css_files = ["custom.css"]

# Where to put Ipython savefigs
ipython_savefig_dir = "../build/savefig"
Loading

0 comments on commit 663ad9d

Please sign in to comment.