pywillow
Async Python client for the Willow plant sensor API.
Installation
pip install pywillow
Usage
import aiohttp
from pywillow import WillowClient
async def main():
async with aiohttp.ClientSession() as session:
client = WillowClient(session, access_token="your-oauth2-token")
# Get the authenticated user's profile
profile = await client.get_profile()
print(profile["username"])
# Get paired sensor devices
devices = await client.get_devices()
for device in devices:
print(device["sensor_id"], device["user_plant"]["name"])
API
WillowClient(session, token, *, base_url=None)
update_token(token)— Update the access token (e.g. after an OAuth2 refresh).get_profile()→WillowProfile— Fetch the authenticated user's profile.get_devices()→list[WillowDevice]— Fetch the user's paired sensor devices.
Models
All models are TypedDict subclasses representing the JSON responses from the Willow API:
WillowProfile—id,username,profile_imageWillowDevice—id,sensor_id,battery_life,version,user_plant,latest_reading,profile_image(optional)WillowUserPlant—id,name,locationWillowReading—timestamp,temperature,humidity,moisture,light
Exceptions
WillowError— Base exception for all Willow API errors.WillowAuthError— Raised on 401/403 responses (authentication failed).WillowApiError— Raised on other HTTP errors. Includes astatusattribute.
Development
# Install with dev dependencies
uv sync
# Run tests
uv run pytest
# Build the package
uv build
License
MIT
Metadata
Release files for pywillow 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pywillow-0.1.2.tar.gz | 71.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pywillow-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 77.1 kB
Release files / pywillow-0.1.2.tar.gz
| Download URL | pywillow-0.1.2.tar.gz |
|---|---|
| Size | 71.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
dab2b3d160f4865bde9d53e3b6331bfd057000428d2c4254f28883649198b9a6
|
|
BLAKE2b-256 checksum How to use checksums |
6b56b98639ef97ce9d96a4d35c27ad865ede94cc20e9d45c0ee191ce86129793
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 28, 2026.
Transparency logRelease files / pywillow-0.1.2-py3-none-any.whl
| Download URL | pywillow-0.1.2-py3-none-any.whl |
|---|---|
| Size | 5.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
cb233f5233dbb4191f92e9a2fc171a594e4f74698d283575d700bad78408b8fc
|
|
BLAKE2b-256 checksum How to use checksums |
c30602e90e7b20834b13c6ac05146a9f4d02b41036cbf0769cee3c26056af1fe
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 28, 2026.
Transparency log