A Python client for Habitify: manage habits, logs, completions, skips, and progress from code.
Project description
habitipie
A typed Python client for Habitify API v2.
habitipie gives you a clean, typed way to bring Habitify into Python scripts,
automation, dashboards, and internal tools.
Instead of stitching together raw HTTP calls, you get a resource-oriented client, predictable models, and an API surface that feels natural in Python from the first call.
If this project saves you time, consider starring the repository. It makes the project easier to discover and helps prioritize future work.
Highlights
- Resource-style API:
HabitipyClient(...).habits.list()andHabitipyClient(...).areas.list() - Typed request and response models powered by Pydantic
- Native
httpxtransport with optional client injection - Explicit pagination objects for list endpoints
- Mapped API errors for common HTTP failure cases
Why habitipie?
- Build scripts and services around your Habitify data without hand-rolling API clients
- Keep request and response handling strongly typed instead of passing unstructured payloads
- Start simple with the built-in client or plug into an existing
httpx.Client - Stay close to the Habitify API while keeping the calling code pleasant to read
Installation
habitipie supports Python 3.10 through 3.13.
pip install habitipie
Rename Notice
The PyPI distribution was renamed from habitipy to habitipie because the
old distribution name was already taken.
This is an intentional breaking change:
- install with
pip install habitipie - import with
from habitipie import HabitipyClient
Set your Habitify API key:
export HABITIFY_API_KEY="your-api-key"
Quick Start
import os
from habitipie import HabitipyClient
with HabitipyClient(api_key=os.environ["HABITIFY_API_KEY"]) as client:
habits = client.habits.list(limit=10)
for habit in habits.data:
print(habit.name)
areas = client.areas.list()
for area in areas:
print(area.name)
Resource API
Create a client and work through the habits and areas resources:
from habitipie import HabitipyClient
with HabitipyClient(api_key="YOUR_API_KEY") as client:
page = client.habits.list(limit=25)
for habit in page.data:
print(habit.name)
areas = client.areas.list()
print(len(areas))
journal_entries = client.habits.journal()
print(journal_entries[0].status)
stats = client.habits.statistics("habit-id")
print(stats.total_logs)
If you already manage your own httpx.Client, you can inject it. HabitipyClient
adds the X-API-Key header and default Habitify base URL when they are missing:
import httpx
from habitipie import HabitipyClient
with httpx.Client() as http_client:
client = HabitipyClient(api_key="YOUR_API_KEY", client=http_client)
page = client.habits.list(limit=25)
When you inject your own httpx.Client, HabitipyClient.close() does not close it for you.
Typed Results
List endpoints keep pagination metadata. For example, client.habits.list() returns a
HabitListPage with .data and .pagination.
Single-resource and non-paginated endpoints are unwrapped for convenience:
client.habits.get(...) -> Habitclient.habits.journal(...) -> list[HabitJournalEntry]client.habits.list_notes(...) -> list[HabitNote]client.habits.statistics(...) -> HabitStatisticsclient.areas.list() -> list[Area]
Write calls accept dedicated request models:
from habitipie import HabitLogRequest, HabitNoteCreateRequest, UnitSymbol
with HabitipyClient(api_key="YOUR_API_KEY") as client:
client.habits.create_log(
"habit-id",
HabitLogRequest(unit_symbol=UnitSymbol.KM, value=5),
)
note = client.habits.create_note(
"habit-id",
HabitNoteCreateRequest(content="Solid run today"),
)
print(note.id)
Error Handling
HTTP status errors are mapped onto typed exceptions:
AuthenticationErrorfor401NotFoundErrorfor404RateLimitErrorfor429ServerErrorfor5xxApiErrorfor other non-success responses
Malformed JSON or unexpected top-level payloads raise ResponseDecodeError and
UnexpectedResponseShapeError.
Development
Use Poetry for local development:
poetry install --extras dev
poetry run pre-commit install
Run the full local quality pass before finishing Python changes:
poetry run isort habitipie tests
poetry run black habitipie tests
poetry run ruff check habitipie tests
poetry run mypy habitipie
Or use the dedicated tox environment:
poetry run tox run -e quality
Pre-commit is configured for the same quality stack:
poetry run pre-commit run --all-files
Run a focused test slice:
poetry run pytest tests/test_habits.py
Generate coverage locally:
poetry run pytest --cov=habitipie --cov-report=term-missing
Run the declared Python support matrix with tox:
poetry run tox run -e py310,py311,py312,py313
CI
GitHub Actions runs the same quality and test commands on pull requests and on pushes to main:
poetry run tox run -e qualitypoetry run tox run -e py310,py311,py312,py313poetry run pytest --cov=habitipie --cov-report=xml
Coverage reports are uploaded to Codecov from the Coverage job. The workflow uses
OIDC and also passes CODECOV_TOKEN, so repositories that require the token can use
the same workflow without further changes.
Release
Pushing a version tag triggers the Release GitHub Actions workflow, which runs
quality checks, the test matrix, builds the distributions, and publishes them to PyPI.
Before tagging a release:
- update
versioninpyproject.toml - make sure the
pypiGitHub environment and PyPI trusted publishing are configured
Create and push a release tag whose name matches v<version>:
git tag v0.1.0
git push origin v0.1.0
The workflow verifies that the tag matches pyproject.toml before publishing.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file habitipie-0.1.0.tar.gz.
File metadata
- Download URL: habitipie-0.1.0.tar.gz
- Upload date:
- Size: 16.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0d3119def9475d3de2a4bbec0ecc144db7de329a198ebfc019f2c11ed9f16de1
|
|
| MD5 |
9e9169004c860b6122f86495fb180148
|
|
| BLAKE2b-256 |
6e032668be5038d6a29a8c2484db0bf196808a0f229f03d5363ed0ca638dc89a
|
Provenance
The following attestation bundles were made for habitipie-0.1.0.tar.gz:
Publisher:
release.yml on ReiRev/habitipie
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
habitipie-0.1.0.tar.gz -
Subject digest:
0d3119def9475d3de2a4bbec0ecc144db7de329a198ebfc019f2c11ed9f16de1 - Sigstore transparency entry: 1429066367
- Sigstore integration time:
-
Permalink:
ReiRev/habitipie@a8b9b15602e73312c7a6ce56ae2dcdaefcfffcd3 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/ReiRev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@a8b9b15602e73312c7a6ce56ae2dcdaefcfffcd3 -
Trigger Event:
push
-
Statement type:
File details
Details for the file habitipie-0.1.0-py3-none-any.whl.
File metadata
- Download URL: habitipie-0.1.0-py3-none-any.whl
- Upload date:
- Size: 17.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
104b3e8b29a00c506ffe1ab19cf5a0a6a7f895f8e90f640e0679292f97e7addd
|
|
| MD5 |
316c43d37fe9c635976b54f2fa66fb1b
|
|
| BLAKE2b-256 |
60fc3603483323b6fffe77c5e9ae2162cdfc275ac7fb0cdc35f37de4ba7665cd
|
Provenance
The following attestation bundles were made for habitipie-0.1.0-py3-none-any.whl:
Publisher:
release.yml on ReiRev/habitipie
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
habitipie-0.1.0-py3-none-any.whl -
Subject digest:
104b3e8b29a00c506ffe1ab19cf5a0a6a7f895f8e90f640e0679292f97e7addd - Sigstore transparency entry: 1429066390
- Sigstore integration time:
-
Permalink:
ReiRev/habitipie@a8b9b15602e73312c7a6ce56ae2dcdaefcfffcd3 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/ReiRev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@a8b9b15602e73312c7a6ce56ae2dcdaefcfffcd3 -
Trigger Event:
push
-
Statement type: