Ouranos is the companion server for Gaia, the plant environment automation client. It aggregates sensor data from one or more Gaia instances, archives it, exposes a REST + WebSocket API, and serves as the backend for the web UI and Telegram bot.
Part of the gaia-ouranos ecosystem.
Aggregator
- Receives sensor data, actuator states, and hardware info from Gaia instances in real time via AMQP (RabbitMQ) or Redis
- Archives data from recent tables to long-term storage on a configurable schedule
- Fetches weather forecasts and sunrise/sunset times from external APIs
- Hosts a dedicated file server for camera image uploads from Gaia
Web API (FastAPI + Socket.IO)
- Ecosystem and hardware management — create, configure, and control Gaia ecosystems and their hardware remotely
- Sensor data — current readings and historic queries per ecosystem or sensor
- Actuator control — send commands and retrieve status and history
- Warnings — surface and manage sensor alarms
- Services — weather forecasts, calendar, wiki
- System monitor — CPU, RAM, and disk usage
- Authentication — JWT-based with role-based access control (admin, operator, user)
- OpenAPI docs at
/api/docs
Plugin SDK
- Extend Ouranos with custom
Functionalitysubclasses that hook into the async lifecycle (initialize → startup → shutdown) - Plugins can expose FastAPI routes, CLI commands, and background services
- Plugins run in-process or as independent subprocesses via the multiprocess spawn API
- Python 3.12+
uv— used for dependency management and running the app- A message broker: RabbitMQ or Redis (optional — in-memory for single-instance)
- systemd (optional — for running as a service)
Copy the install script from the scripts/ directory and run it in the
directory where you want to install Ouranos:
bash install.shThe script clones the repository, sets up a uv-managed virtual environment,
installs all dependencies, and optionally configures a systemd service.
After installation, initialise the database:
source ~/.profile
ouranos fill-db --no-check-revision
alembic stamp headIf installed as a systemd service:
sudo systemctl start ouranos.service
sudo systemctl enable ouranos.service # start on bootUsing the CLI directly:
ouranos start
ouranos stop
ouranos restart
ouranos statusBy default, Ouranos runs the web server, aggregator, and all installed plugins
in a single process. Individual components can be run separately by passing the
appropriate flags — see ouranos --help for details.
To expose both the frontend and the API behind a single port (for
tunneling), an example nginx reverse-proxy config is available under
deploy/nginx/ouranos.conf. It is adapted to the current installation path by
scripts/utils/gen_nginx.sh when running install.sh/update.sh. The rendered
config is located at <OURANOS_DIR>/scripts/ouranos.conf.
Plugins are Python packages exposing an ouranos.plugins entry point. They are
cloned next to the core, in <OURANOS_DIR>/lib/, and declared in the master
pyproject.toml. That file is generated once, at installation, and then belongs
to the installation: the update script never overwrites it.
A plugin installation script must at least clone the plugin, then declare it:
git clone https://github.com/vaamb/ouranos-frontend.git "${OURANOS_DIR}/lib/ouranos-frontend"
source "${OURANOS_DIR}/scripts/utils/pyproject_helpers.sh"
add_dependency ouranos-frontend
cd "${OURANOS_DIR}" && uv syncadd_dependency <name> [extras] [source] adds the package to dependencies and
its [tool.uv.sources] entry, both above their anchor comment. It is idempotent
and returns 1 with a message on stderr if the pyproject cannot be edited:
add_dependency ouranos-frontend # a plugin cloned in `lib/`
add_dependency ouranos-core postgresql # add an extra to a package
add_dependency ouranos-frontend "" '{ git = "https://github.com/vaamb/ouranos-frontend.git", tag = "0.2.0" }'
add_dependency humanize "" none # straight from PyPI, no source entryTo disable a plugin, comment out its line in dependencies and run uv sync
again; uncomment it to bring it back. The clone stays in lib/ and therefore
stays part of the uv workspace, so a plugin whose dependencies cannot be
resolved has to be moved out of lib/ rather than just commented out.
Ouranos is configured via a config.py file placed in $OURANOS_DIR. It must
define a DEFAULT_CONFIG variable pointing to a class that subclasses
BaseConfig (and any plugin configs, e.g. FrontendConfig, ChatbotConfig):
from ouranos.core.config.base import BaseConfig
from ouranos_frontend.config import Config as FrontendConfig
class Config(FrontendConfig, BaseConfig):
DEVELOPMENT = True
GAIA_COMMUNICATION_URL = "amqp://localhost"
HOME_COORDINATES = (59.51, 17.38)
OPEN_WEATHER_MAP_API_KEY = "your_key_here"
DEFAULT_CONFIG = ConfigAll settings can also be provided via environment variables. Key settings:
| Setting | Env variable | Description |
|---|---|---|
SECRET_KEY |
OURANOS_SECRET_KEY |
JWT signing key |
GAIA_COMMUNICATION_URL |
GAIA_COMMUNICATION_URL |
Broker URL for Gaia (amqp:// or redis://) |
DISPATCHER_URL |
OURANOS_DISPATCHER_URL |
Internal dispatcher (memory:// or amqp://) |
SIO_MANAGER_URL |
OURANOS_SIO_MANAGER_URL |
Socket.IO manager (memory://, redis://, or amqp://) |
API_HOST / API_PORT |
OURANOS_API_HOST / OURANOS_API_PORT |
Web server bind address (default: 127.0.0.1:5000) |
FRONTEND_URL |
OURANOS_FRONTEND_URL |
Allowed frontend origin (CORS) |
DB_DIR |
OURANOS_DB_DIR |
Directory for SQLite databases |
HOME_COORDINATES |
HOME_COORDINATES |
(lat, lon) used for sunrise/sunset and weather |
OPEN_WEATHER_MAP_API_KEY |
OPEN_WEATHER_MAP_API_KEY |
API key for weather forecasts |
PLUGINS_OMITTED |
OURANOS_PLUGINS_OMITTED |
Comma-separated list of plugins to skip |
MAIL_USERNAME |
OURANOS_MAIL_ADDRESS |
SMTP address for email notifications |
Clone the repository and install dependencies with test extras:
git clone https://github.com/vaamb/ouranos-core.git
cd ouranos-core
uv sync --group testRun the test suite:
uv run pytest tests/ -vLint:
uv sync --group qc
uv run ruff check .- Python 3.12+ · FastAPI · Uvicorn · asyncio
- SQLAlchemy 2.0 (async) · Alembic · aiomysql (MariaDB/MySQL in production) · aiosqlite (tests)
- python-socketio · aio-pika · APScheduler
- PyJWT · argon2-cffi
- numpy · OpenCV (camera image processing)
- event-dispatcher · gaia-validators · sqlalchemy-wrapper
- uv · ruff · pytest · pytest-asyncio · coverage
- GitHub Actions CI: lint + tests across Python 3.12 / 3.13 / 3.14
Active. Running in production at home since 2020. The core data flow is stable; APIs may still change. Requires at least one running Gaia instance for the aggregator to receive data, but the web server and services run independently.