Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: add top-level intro and module-level intros #1320

Merged
merged 32 commits into from
Sep 20, 2024
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
30fb6ae
docs: text for 'main page'
dimaqq Sep 3, 2024
cf841cc
reasonable text for ops.testing
dimaqq Sep 10, 2024
28323a2
cook up ops.testing intro
dimaqq Sep 10, 2024
46f9953
top-level intro
dimaqq Sep 10, 2024
9da9d4c
wip: ops module content
dimaqq Sep 10, 2024
3f82a91
headline for ops.main entry point
dimaqq Sep 11, 2024
f79799b
finish ops module summary
dimaqq Sep 17, 2024
91fd2da
fix LifecycleEvent spelling in the change log
dimaqq Sep 17, 2024
1a791ad
Document container.restart() behaviour, https://warthogs.atlassian.ne…
dimaqq Sep 17, 2024
7bc3c31
fix testing doc indent
dimaqq Sep 17, 2024
21de841
clean up after review with Dora
dimaqq Sep 17, 2024
c45ff85
clean up after review with Dora
dimaqq Sep 17, 2024
2872570
move ops.Container summary to ops/__init__.py; write ops.pebble summary
dimaqq Sep 17, 2024
67be6e0
use OPT1
dimaqq Sep 18, 2024
6a6aa1b
capitalisation
dimaqq Sep 18, 2024
d9f6298
use inset to see more
dimaqq Sep 18, 2024
8785714
the
dimaqq Sep 18, 2024
9f42aaa
review comments
dimaqq Sep 18, 2024
4b1c18c
add a note on LifecycleEvent
dimaqq Sep 18, 2024
4c51d74
better lifecycle note
dimaqq Sep 19, 2024
56c433b
and
dimaqq Sep 19, 2024
25f924e
drop marketing speak
dimaqq Sep 19, 2024
f4b779e
add self.model
dimaqq Sep 19, 2024
0ed3633
what ops.pebble is
dimaqq Sep 19, 2024
b824fa9
link to external pebble docs
dimaqq Sep 19, 2024
97a0eab
changes from live review
dimaqq Sep 19, 2024
a5f6df1
ops.testing changes from live review
dimaqq Sep 19, 2024
b66f3d2
added poorly named
dimaqq Sep 19, 2024
1fec637
deemphacise charm libs
dimaqq Sep 19, 2024
027322e
rewrite paragraph `why ops?`
dimaqq Sep 19, 2024
2134e11
pebble client and testing harness one-liners
dimaqq Sep 19, 2024
a82830a
review comments
dimaqq Sep 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@

## Features

* `StopEvent`, `RemoveEvent`, and all `LifeCycleEvent`s are no longer deferrable, and will raise a `RuntimeError` if `defer()` is called on the event object (#1122)
* `StopEvent`, `RemoveEvent`, and all `LifecycleEvent`s are no longer deferrable, and will raise a `RuntimeError` if `defer()` is called on the event object (#1122)
* Add `ActionEvent.id`, exposing the JUJU_ACTION_UUID environment variable (#1124)
* Add support for creating `pebble.Plan` objects by passing in a `pebble.PlanDict`, the
ability to compare two `Plan` objects with `==`, and the ability to create an empty Plan with `Plan()` (#1134)
Expand Down
32 changes: 32 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,47 @@
ops library API reference
=========================

The `ops` library is a Python framework for writing and testing Juju charms.

For more about the Charm SDK, see https://juju.is/docs/sdk.
dimaqq marked this conversation as resolved.
Show resolved Hide resolved

The library provides:

- :ref:`ops_main_entry_point` used to initialise and run your charm.
dimaqq marked this conversation as resolved.
Show resolved Hide resolved
- :ref:`ops_module`, the API to respond to Juju events and manage the application.
- :ref:`ops_pebble_module` low-level API for Pebble in Kubernetes containers.
dimaqq marked this conversation as resolved.
Show resolved Hide resolved
- :ref:`ops_testing_module`, the framework for unit testing charms in a simulated environment.

You can write a charm in any way you want, but with the `ops` library you get a
framework that helps you write consistent readable charms following the latest
dimaqq marked this conversation as resolved.
Show resolved Hide resolved
best practices, reuse code via charm libs, and separate typical charm concerns
dimaqq marked this conversation as resolved.
Show resolved Hide resolved
--- application state management from integration management or lifecycle
management from testability.
dimaqq marked this conversation as resolved.
Show resolved Hide resolved

Whether you are a machine or a Kubernetes charm author, `ops` is the recommended way to go.

dimaqq marked this conversation as resolved.
Show resolved Hide resolved

.. toctree::
:maxdepth: 2
:caption: Contents:


.. _ops_module:

ops module
==========

.. automodule:: ops
:exclude-members: main


.. _ops_main_entry_point:

ops.main entry point
====================
dimaqq marked this conversation as resolved.
Show resolved Hide resolved

The main entry point to initialise and run your charm.

.. autofunction:: ops.main


Expand All @@ -25,12 +53,16 @@ legacy main module
:noindex:


.. _ops_pebble_module:

ops.pebble module
=================

.. automodule:: ops.pebble


.. _ops_testing_module:

ops.testing module
==================

Expand Down
55 changes: 37 additions & 18 deletions ops/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,50 @@
# See the License for the specific language governing permissions and
# limitations under the License.

"""The ops library: a Python framework for writing Juju charms.
"""The API to respond to Juju events and manage the application.
tonyandrewmeyer marked this conversation as resolved.
Show resolved Hide resolved

The ops library is a Python framework (`available on PyPI`_) for developing
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you drop the link to PyPI because you feel like that's where people expect to get most Python packages, so there's no point? Or because you think it doesn't belong in reference docs? Some other reason? I'm not sure I'm totally onboard, so reasoning would help convince me.

and testing Juju charms in a consistent way, using standard Python constructs
to allow for clean, maintainable, and reusable code.
This module provides:
dimaqq marked this conversation as resolved.
Show resolved Hide resolved

A charm is an operator -- business logic encapsulated in a reusable software
package that automates every aspect of an application's life.
- :class:`~ops.CharmBase` and :class:`~ops.Object` to register the charm or
dimaqq marked this conversation as resolved.
Show resolved Hide resolved
a charm lib, respectively, with the framework.
- [OPT1] :class:`~ops.framework.EventBase` class and individual event types, like
:class:`~ops.ActionEvent` class.
- [OPT2] :class:`~ops.framework.EventBase` and its subclasses:

Charms written with ops support Kubernetes using Juju's "sidecar charm"
pattern, as well as charms that deploy to Linux-based machines and containers.
- :class:`~ops.HookEvent` class for Juju events, like the
:class:`~ops.StartEvent` class.
- :class:`~ops.LifecycleEvent` class for synthetic events, like the
:class:`~ops.CollectStatusEvent` class.
dimaqq marked this conversation as resolved.
Show resolved Hide resolved

Charms should do one thing and do it well. Each charm drives a single
dimaqq marked this conversation as resolved.
Show resolved Hide resolved
application and can be integrated with other charms to deliver a complex
system. A charm handles creating the application in addition to scaling,
configuration, optimisation, networking, service mesh, observability, and other
day-2 operations specific to the application.
- :class:`~ops.Framework` class, accessible as ``self.framework`` in a charm,
the main interface for the charm to `ops` library infrastructure, including:

The ops library is part of the Charm SDK (the other part being Charmcraft).
Full developer documentation for the Charm SDK is available at
https://juju.is/docs/sdk.
- :meth:`~ops.Framework.on` shorthand property used to
dimaqq marked this conversation as resolved.
Show resolved Hide resolved
:meth:`~ops.Framework.observe` and react to Juju events.
- :attr:`~ops.Framework.model` attribute to get hold of the Model instance.
dimaqq marked this conversation as resolved.
Show resolved Hide resolved

To learn more about Juju, visit https://juju.is/docs/olm.
- :class:`~ops.model.Model` class that represents the Juju Model, including:

dimaqq marked this conversation as resolved.
Show resolved Hide resolved
.. _available on PyPI: https://pypi.org/project/ops/
- :attr:`~ops.Model.app` attribute, representing the application associated
with the charm.
- :attr:`~ops.Model.unit` attribute, representing the unit of the application
the charm is running on.
- :attr:`~ops.Model.relations` attribute, which provides access to relations
defined in the charm, allowing interaction with other applications.
- :meth:`~ops.Model.get_secret` method, to access Juju :class:`~ops.Secret`
objects.

- :class:`~ops.Container` class to control Kubernetes workloads, including:

- :meth:`~ops.Container.add_layer` and :meth:`~ops.Container.replan` methods
to update Pebble configuration.
- :meth:`~ops.Container.pull` and :meth:`~ops.Container.push` methods to copy
data to and from container, respectively.
dimaqq marked this conversation as resolved.
Show resolved Hide resolved
- :meth:`~ops.Container.exec` method to run arbitrary commands inside the
container.

- :class:`~ops.StatusBase` class and individual status types, like
:class:`~ops.ActiveStatus` class.
dimaqq marked this conversation as resolved.
Show resolved Hide resolved
"""

# The "from .X import Y" imports below don't explicitly tell Pyright (or MyPy)
Expand Down
6 changes: 5 additions & 1 deletion ops/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -2304,7 +2304,11 @@ def start(self, *service_names: str):
self._pebble.start_services(service_names)

def restart(self, *service_names: str):
"""Restart the given service(s) by name."""
"""Restart the given service(s) by name.

Listed running services will be stopped and restarted, and listed stopped
services will be started.
"""
if not service_names:
raise TypeError('restart expected at least 1 argument, got 0')

Expand Down
15 changes: 14 additions & 1 deletion ops/pebble.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,17 @@
# See the License for the specific language governing permissions and
# limitations under the License.

"""Client for the Pebble API (HTTP over Unix socket).
"""Low-level Pebble API.
dimaqq marked this conversation as resolved.
Show resolved Hide resolved

This module provides:
dimaqq marked this conversation as resolved.
Show resolved Hide resolved
dimaqq marked this conversation as resolved.
Show resolved Hide resolved

- :class:`~ops.pebble.Client` class to communicate directly Pebble.
dimaqq marked this conversation as resolved.
Show resolved Hide resolved
- :class:`~ops.pebble.Layer` class to define Pebble configuration layers,
including:

- :class:`~ops.pebble.Check` class to represent Pebble checks.
- :class:`~ops.pebble.LogTarget` class to represent Pebble log targets.
- :class:`~ops.pebble.Service` class to represent Pebble service descriptions.

For a command-line interface for local testing, see test/pebble_cli.py.
"""
Expand Down Expand Up @@ -2187,6 +2197,9 @@ def restart_services(
) -> ChangeID:
"""Restart services by name and wait (poll) for them to be started.

Listed running services will be stopped and restarted, and listed stopped
services will be started.

Args:
services: Non-empty list of services to restart.
timeout: Seconds before restart change is considered timed out (float). If
Expand Down
19 changes: 18 additions & 1 deletion ops/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,25 @@
# 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.
"""Framework for unit testing charms in a simulated environment.
dimaqq marked this conversation as resolved.
Show resolved Hide resolved

"""Infrastructure to build unit tests for charms using the ops library."""
The module provides:

- :class:`ops.testing.Harness`, a class to set up the environment for charms, and its:
dimaqq marked this conversation as resolved.
Show resolved Hide resolved

- :meth:`~ops.testing.Harness.begin_with_initial_hooks` convenience method for declarative
test setup.
- individual :meth:`~ops.testing.Harness.begin` and :meth:`~ops.testing.Harness.cleanup`
methods to start and end the testing lifecycle.
- :meth:`~ops.testing.Harness.evaluate_status` method, which aggregates the
status of the charm after test interactions.
- :attr:`~ops.testing.Harness.model` attribute, which exposes e.g. the
:attr:`~ops.Model.unit` attribute for detailed assertions on the unit's state.

.. note::
Unit testing is only one aspect of a comprehensive testing strategy. For more
on testing charms, see `Testing Strategies <https://juju.is/docs/sdk/testing>`_.
dimaqq marked this conversation as resolved.
Show resolved Hide resolved
"""

import dataclasses
import datetime
Expand Down
Loading