Add tutorial doctest module and enable top level await (#919)

Add a tutorial module with examples that can be tested with `doctest`.

In order to simplify the examples they can be run with doctest allowing
top level await statements by adding a fixture to patch the builtins
that xdoctest uses to test code.

---------

Co-authored-by: Teemu R. <tpr@iki.fi>
This commit is contained in:
Steven B
2024-05-16 17:13:44 +01:00
committed by GitHub
parent a2e8d2c4e8
commit 3490a1ef84
17 changed files with 228 additions and 42 deletions

View File

@@ -10,9 +10,10 @@
# 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.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
import os
import sys
sys.path.insert(0, os.path.abspath("..")) # Will find modules in the docs parent
# -- Project information -----------------------------------------------------

View File

@@ -22,13 +22,13 @@ Use :func:`~kasa.Discover.discover` to perform udp-based broadcast discovery on
This will return you a list of device instances based on the discovery replies.
If the device's host is already known, you can use to construct a device instance with
:meth:`~kasa.SmartDevice.connect()`.
:meth:`~kasa.Device.connect()`.
The :meth:`~kasa.SmartDevice.connect()` also enables support for connecting to new
The :meth:`~kasa.Device.connect()` also enables support for connecting to new
KASA SMART protocol and TAPO devices directly using the parameter :class:`~kasa.DeviceConfig`.
Simply serialize the :attr:`~kasa.SmartDevice.config` property via :meth:`~kasa.DeviceConfig.to_dict()`
Simply serialize the :attr:`~kasa.Device.config` property via :meth:`~kasa.DeviceConfig.to_dict()`
and then deserialize it later with :func:`~kasa.DeviceConfig.from_dict()`
and then pass it into :meth:`~kasa.SmartDevice.connect()`.
and then pass it into :meth:`~kasa.Device.connect()`.
.. _update_cycle:
@@ -36,7 +36,7 @@ and then pass it into :meth:`~kasa.SmartDevice.connect()`.
Update Cycle
************
When :meth:`~kasa.SmartDevice.update()` is called,
When :meth:`~kasa.Device.update()` is called,
the library constructs a query to send to the device based on :ref:`supported modules <modules>`.
Internally, each module defines :meth:`~kasa.modules.Module.query()` to describe what they want query during the update.
@@ -45,7 +45,7 @@ All properties defined both in the device class and in the module classes follow
While the properties are designed to provide a nice API to use for common use cases,
you may sometimes want to access the raw, cached data as returned by the device.
This can be done using the :attr:`~kasa.SmartDevice.internal_state` property.
This can be done using the :attr:`~kasa.Device.internal_state` property.
.. _modules:
@@ -53,15 +53,15 @@ This can be done using the :attr:`~kasa.SmartDevice.internal_state` property.
Modules
*******
The functionality provided by all :class:`~kasa.SmartDevice` instances is (mostly) done inside separate modules.
The functionality provided by all :class:`~kasa.Device` instances is (mostly) done inside separate modules.
While the individual device-type specific classes provide an easy access for the most import features,
you can also access individual modules through :attr:`kasa.SmartDevice.modules`.
You can get the list of supported modules for a given device instance using :attr:`~kasa.SmartDevice.supported_modules`.
You can get the list of supported modules for a given device instance using :attr:`~kasa.Device.supported_modules`.
.. note::
If you only need some module-specific information,
you can call the wanted method on the module to avoid using :meth:`~kasa.SmartDevice.update`.
you can call the wanted method on the module to avoid using :meth:`~kasa.Device.update`.
Protocols and Transports
************************
@@ -112,10 +112,22 @@ The base exception for all library errors is :class:`KasaException <kasa.excepti
- If the device fails to respond within a timeout the library raises a :class:`TimeoutError <kasa.exceptions.TimeoutError>`.
- All other failures will raise the base :class:`KasaException <kasa.exceptions.KasaException>` class.
API documentation for modules
*****************************
API documentation for modules and features
******************************************
.. automodule:: kasa.modules
.. autoclass:: kasa.Module
:noindex:
:members:
:inherited-members:
:undoc-members:
.. automodule:: kasa.interfaces
:noindex:
:members:
:inherited-members:
:undoc-members:
.. autoclass:: kasa.Feature
:noindex:
:members:
:inherited-members:

View File

@@ -6,12 +6,12 @@ Common API
.. contents:: Contents
:local:
SmartDevice class
*****************
Device class
************
The basic functionalities of all supported devices are accessible using the common :class:`SmartDevice` base class.
The basic functionalities of all supported devices are accessible using the common :class:`Device` base class.
The property accesses use the data obtained before by awaiting :func:`SmartDevice.update()`.
The property accesses use the data obtained before by awaiting :func:`Device.update()`.
The values are cached until the next update call. In practice this means that property accesses do no I/O and are dependent, while I/O producing methods need to be awaited.
See :ref:`library_design` for more detailed information.
@@ -20,7 +20,7 @@ See :ref:`library_design` for more detailed information.
This means that you need to use the same event loop for subsequent requests.
The library gives a warning ("Detected protocol reuse between different event loop") to hint if you are accessing the device incorrectly.
Methods changing the state of the device do not invalidate the cache (i.e., there is no implicit :func:`SmartDevice.update()` call made by the library).
Methods changing the state of the device do not invalidate the cache (i.e., there is no implicit :func:`Device.update()` call made by the library).
You can assume that the operation has succeeded if no exception is raised.
These methods will return the device response, which can be useful for some use cases.
@@ -103,10 +103,10 @@ Currently there are three known types of encryption for TP-Link devices and two
Devices with automatic firmware updates enabled may update to newer versions of the encryption without separate notice,
so discovery can be helpful to determine the correct config.
To connect directly pass a :class:`DeviceConfig` object to :meth:`SmartDevice.connect()`.
To connect directly pass a :class:`DeviceConfig` object to :meth:`Device.connect()`.
A :class:`DeviceConfig` can be constucted manually if you know the :attr:`DeviceConfig.connection_type` values for the device or
alternatively the config can be retrieved from :attr:`SmartDevice.config` post discovery and then re-used.
alternatively the config can be retrieved from :attr:`Device.config` post discovery and then re-used.
Energy Consumption and Usage Statistics
***************************************
@@ -141,7 +141,7 @@ You can access this information using through the usage module (:class:`kasa.mod
API documentation
*****************
.. autoclass:: SmartDevice
.. autoclass:: Device
:members:
:undoc-members:

View File

@@ -13,7 +13,7 @@ Discovery works by sending broadcast UDP packets to two known TP-link discovery
Port 9999 is used for legacy devices that do not use strong encryption and 20002 is for newer devices that use different
levels of encryption.
If a device uses port 20002 for discovery you will obtain some basic information from the device via discovery, but you
will need to await :func:`SmartDevice.update() <kasa.SmartDevice.update()>` to get full device information.
will need to await :func:`Device.update() <kasa.SmartDevice.update()>` to get full device information.
Credentials will most likely be required for port 20002 devices although if the device has never been connected to the tplink
cloud it may work without credentials.

View File

@@ -7,8 +7,9 @@
Home <self>
cli
tutorial
discover
smartdevice
device
design
contribute
smartbulb

View File

@@ -67,13 +67,13 @@ API documentation
:members:
:undoc-members:
.. autoclass:: kasa.smartbulb.BehaviorMode
.. autoclass:: kasa.iot.iotbulb.BehaviorMode
:members:
.. autoclass:: kasa.TurnOnBehaviors
.. autoclass:: kasa.iot.iotbulb.TurnOnBehaviors
:members:
.. autoclass:: kasa.TurnOnBehavior
.. autoclass:: kasa.iot.iotbulb.TurnOnBehavior
:undoc-members:
:members:

8
docs/source/tutorial.md Normal file
View File

@@ -0,0 +1,8 @@
# Tutorial
```{eval-rst}
.. automodule:: tutorial
:members:
:inherited-members:
:undoc-members:
```