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 all 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
30 changes: 30 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,45 @@
ops library API reference
=========================

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

See more: `Charm SDK documentation <https://juju.is/docs/sdk>`_

The library provides:

- :ref:`ops_main_entry_point`, used to initialise and run your charm;
- :ref:`ops_module`, the API to respond to Juju events and manage the application;
- :ref:`ops_pebble_module`, the Pebble client, a low-level API for Kubernetes containers;
- :ref:`ops_testing_module`, the framework for unit testing charms in a simulated environment;

You can structure your charm however you like, but with the `ops` library, you
get a framework that promotes consistency and readability by following best
practices. It also helps you organise your code better by separating different
aspects of the charm, such as managing the application’s state, handling
integrations with other services, and making the charm easier to test.

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 +51,16 @@ legacy main module
:noindex:


.. _ops_pebble_module:

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

.. automodule:: ops.pebble


.. _ops_testing_module:

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

Expand Down
47 changes: 29 additions & 18 deletions ops/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,42 @@
# 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 code freatures to your charm, including:
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`, the base class for charms and :class:`~ops.Object`,
the base class for charm libraries.
- :class:`~ops.framework.EventBase` class and individual event types, like
the :class:`~ops.ActionEvent` class.
- :class:`~ops.Framework` class, accessible as ``self.framework`` in a charm,
the main interface for the charm to `ops` library infrastructure, including:

Charms written with ops support Kubernetes using Juju's "sidecar charm"
pattern, as well as charms that deploy to Linux-based machines and containers.
- :attr:`~ops.Framework.on` shorthand property used to
: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

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.model.Model` class that represents the Juju model, accessible as
``self.model`` in a charm, including:

dimaqq marked this conversation as resolved.
Show resolved Hide resolved
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.
- :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
(integrations) defined in the charm, allowing interaction with other applications.

To learn more about Juju, visit https://juju.is/docs/olm.
- :class:`~ops.Container` class to control Kubernetes workloads, including:

.. _available on PyPI: https://pypi.org/project/ops/
- :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 a container, respectively.
- :meth:`~ops.Container.exec` method to run arbitrary commands inside the
container.

- :class:`~ops.StatusBase` class and individual status types, like the
: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/framework.py
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,11 @@ def __getattr__(self, name: str) -> BoundEvent:


class LifecycleEvent(EventBase):
"""Events tied to the lifecycle of the Framework object."""
"""Events tied to the lifecycle of the Framework object.

Note: Here, "lifecycle" was poorly named and has nothing to do with the
dimaqq marked this conversation as resolved.
Show resolved Hide resolved
Juju [application] lifecycle.
"""
dimaqq marked this conversation as resolved.
Show resolved Hide resolved

def defer(self) -> NoReturn:
"""Lifecycle events are not deferrable like other events.
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
19 changes: 17 additions & 2 deletions ops/pebble.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,21 @@
# See the License for the specific language governing permissions and
# limitations under the License.

"""Client for the Pebble API (HTTP over Unix socket).
"""Client for the Pebble API.

For a command-line interface for local testing, see test/pebble_cli.py.
This module provides a way to interact with Pebble, including:

- :class:`~ops.pebble.Client`; communicates directly with the Pebble API.
- :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``.

See more: `Pebble documentation <https://canonical-pebble.readthedocs-hosted.com/>`_
"""

from __future__ import annotations
Expand Down Expand Up @@ -2187,6 +2199,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
22 changes: 20 additions & 2 deletions ops/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,26 @@
# 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.

"""Infrastructure to build unit tests for charms using the ops library."""
"""Framework for unit testing charms in a simulated Juju environment.

The module includes:
dimaqq marked this conversation as resolved.
Show resolved Hide resolved

- :class:`ops.testing.Harness`, a class to set up the simulated environment,
that provides:

- :meth:`~ops.testing.Harness.add_relation` method, to declare a relation
(integration) with another app.
- :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 `Charm SDK | Testing <https://juju.is/docs/sdk/testing>`_.
"""

import dataclasses
import datetime
Expand Down
Loading