shenas is an open-source personal analytics platform. Source plugins bring data in, transforms shape it, dashboards make it visible. Every piece is a plugin you can write, share, and improve.
shenas connects to the services people already use -- Garmin, Strava, Spotify, Lunch Money, Google Calendar -- and syncs the data into a local encrypted database. Transforms normalize it into canonical metrics. Dashboards visualize it. The LLM coach asks questions of it.
Everything is a plugin. If there's a data source you care about, you can write a connector in an afternoon. If there's a way to visualize it, you can build a dashboard in a weekend.
Connect a new API or local file to shenas. dlt handles the pipeline; you define the tables.
Write one in 30 minutes →A source plugin is a Python package that defines tables as dataclasses and extracts data from an API. dlt handles incremental loading, schema migration, and encryption. You focus on the API.
mkdir -p plugins/sources/myapi/shenas_sources/myapi
cd plugins/sources/myapi
# pyproject.toml
cat > pyproject.toml <<'EOF'
[project]
name = "shenas-source-myapi"
dependencies = ["dlt[duckdb]>=1.24.0", "shenas-source-core"]
[project.entry-points."shenas.sources"]
myapi = "shenas_sources.myapi.source:MyApiSource"
EOF from shenas_sources.core.table import EventTable, Field
from typing import Annotated, Any, Iterator
class Activities(EventTable):
class _Meta:
name = "activities"
display_name = "Activities"
pk = ("id",)
id: Annotated[str, Field(db_type="VARCHAR")] = ""
name: Annotated[str, Field(db_type="VARCHAR")] = ""
duration_s: Annotated[int, Field(db_type="INTEGER", unit="s")] = 0
time_at: Annotated[str, Field(db_type="TIMESTAMP")] = ""
@classmethod
def extract(cls, client: Any, **ctx) -> Iterator[dict]:
yield from client.get_activities() from shenas_sources.core.source import Source
class MyApiSource(Source):
name = "myapi"
display_name = "My API"
primary_table = "activities"
def build_client(self):
return MyApiClient(self.get_config_value("api_key"))
def resources(self, client):
from .tables import TABLES
return [t.to_resource(client) for t in TABLES] uv sync # installs your plugin as a workspace member
shenasctl source myapi sync Your data is now in a local encrypted DuckDB, queryable from dashboards and the LLM coach.
Sources are the most common, but shenas has six plugin kinds. Each follows the same pattern: a Python package with an entry point.