Open Pulse unified CLI and analysis toolkit.
Project description
Open Pulse
Unified CLI, dashboard, and infrastructure repository for graph-analysis
workflows. The Python package lives in src/open_pulse/; deployment assets
live under infra/; container builds live under tools/images/.
Key Structure
src/open_pulse/commands/— CLI command groups (deploy,quest,services,gui,health)src/open_pulse/pipeline/— quest pipeline config, runner, and steps (crawler,neo4j_upload,metadata_extractor,sparql_upload)src/open_pulse/services/— shared service clients (Neo4j, SPARQL store, GME extractor) + endpoint probessrc/open_pulse/utils/grimoire/— grimoire helpers (SPARQL config gen, cron watcher, applier client)src/open_pulse/gui/grimoire_streamlit.py— Streamlit UI for Grimoire configsrc/open_pulse/gui/hub/— Open Pulse Hub: FastAPI dashboard / control plane (single shared password, light + dark theme, marquee, file-based persistence in SQLite + DuckDB)infra/open-pulse-stack/— the Open Pulse stack: main compose, CLI overlay, and the GrimoireLab compose all live here (docker-compose.yml,docker-compose.cli.yml,docker-compose.grimoirelab.yml, plus the GrimoireLab supporting assets undergrimoirelab/)infra/services/— single-service deployment references (neo4j,oxigraph,sparql-proxy,portainer)tools/images/Dockerfile-open-pulse— single image used for the CLI, the cli-orchestrator container, and the hubconfig/quest.example.yml— canonical quest config exampledata/— bind-mounted runtime state (gitignored, namespaced per service)
Quick Start
uv sync --group dev --group test
uv run open-pulse --help
uv run pytest -q
Docker stack
One image (open-pulse) plays two roles via compose overrides — the
open-pulse-cli orchestrator container sits idle awaiting docker exec,
the open-pulse-hub container runs the FastAPI dashboard.
Configuration: where env lives
Two distinct files, two distinct purposes:
<repo>/infra/.env— the deployment env. Owns image refs, ports, resource limits, storage paths, and all container-side credentials and per-service knobs. When you bring the stack up frominfra/, compose reads ONLY this file; every service pulls it in viaenv_file:. It is auto-seeded frominfra/.env.examplethe first timeop deploy upruns.<repo>/.env— the tool/client env. Consumed by the open-pulse Python CLI / hub only when running on the host against EXTERNAL infrastructure (i.e. someone else's deployed services). Compose never loads it. It's a manual copy from.env.example.
Both are gitignored. The split honours the principle: when launching from
infra/, all env lives in infra/; otherwise <repo>/.env is just for
the open-pulse tool acting as a client.
Bring up the stack
# Build locally (or pull from ghcr.io/sdsc-ordes/open-pulse:latest)
docker build -f tools/images/Dockerfile-open-pulse -t open-pulse:local .
# First run seeds .env and infra/.env from their templates; edit them and
# re-run.
./scripts/op deploy up --profile crawler --profile extractor --profile sparql --profile hub
# Or a host-side compose invocation (note both --env-file flags):
docker compose -f infra/open-pulse-stack/docker-compose.yml \
-f infra/open-pulse-stack/docker-compose.cli.yml \
--env-file infra/.env \
--profile hub up -d
Open http://localhost:9090, log in with openpulse / $HUB_AUTH (the
username is free-form; only the password is checked).
The hub talks to the host docker daemon via the bind-mounted socket and
shells open-pulse deploy ... into the cli orchestrator container, so all
stack management goes through the same code path whether triggered from the
browser or from ./scripts/op deploy ... on the host.
./scripts/op is a small wrapper that runs docker exec against the cli
container with MSYS_NO_PATHCONV=1 (so git-bash on Windows doesn't mangle
leading-slash arguments).
Profiles
| Profile | What comes up |
|---|---|
default |
Neo4j |
crawler |
Open Pulse Crawler API |
extractor |
GME metadata extractor + Selenium |
sparql |
Oxigraph + sparql-proxy |
hub |
Open Pulse Hub dashboard (port 9090) |
grimoirelab |
GrimoireLab DB & worker (within main compose) |
orchestration |
Portainer |
The full GrimoireLab stack (Mordred + Sortinghat + OpenSearch + nginx +
projects-applier sidecar) lives alongside the main stack at
infra/open-pulse-stack/docker-compose.grimoirelab.yml. Bring it up
alongside the main stack with --with-grimoire:
./scripts/op deploy up --profile hub --with-grimoire
Quest Config
Service endpoints are defined only under quest.services. Step-level
endpoint fields are no longer supported. The SPARQL upload step is
technology-agnostic (replaces the old tentris_upload):
quest:
name: "my-quest-run"
retry:
max_attempts: 3
backoff_seconds: 5
logging:
level: INFO
file: logs/quest.log
services:
crawler:
endpoint: "http://crawler:8000"
api_token_env: CRAWLER_API_TOKEN
neo4j:
endpoint: "bolt://neo4j:7687"
auth_env: NEO4J_AUTH
metadata_extractor:
endpoint: "http://git-metadata-extractor:1234"
sparql_store:
endpoint: "http://sparql-proxy:7878"
auth_env: SPARQL_AUTH
steps:
crawler:
seeds: ["sdsc-ordes"]
max_rounds: 2
neo4j_upload: { enabled: true }
metadata_extractor:
enabled: true
max_repos: 8
sparql_upload:
enabled: true
Service Layer
open_pulse.services:
- typed service config defaults
Neo4jService.upload()— batched UNWIND MERGE into Neo4jSparqlStoreService.upload()— JSON-LD → N-Triples → Graph Store HTTP Protocol (technology-agnostic; works with Oxigraph, Tentris, …)MetadataExtractorService— v1 (gimie) + v2 (rule-based) clients- shared endpoint probe utilities for
open-pulse health - run-scoped
ServiceContainerused by quest pipeline runs
Open Pulse Hub
Single-page control plane at http://localhost:9090 when --profile hub is
up. Pages:
- Overview — live stat cards, service tiles, quick links
- Stack — bring profiles up / down via the deploy CLI over the socket
- Services — start / stop / restart, tail logs
- Pipeline — discover quest YAMLs and run them
- Projects — query SPARQL → preview → POST to the projects.json applier
- Databases — DuckDB · SPARQL · Cypher consoles, saved queries in SQLite
- Logs — per-container tail with auto-refresh
Top marquee polls aggregated stats every 10s. Light + dark theme toggle in
the sidebar (light mirrors the existing projects-ui's design tokens). State
persists in data/hub/app.db (SQLite) and data/hub/scratch.duckdb.
Set HUB_AUTH (any string) in .env to gate the dashboard.
Health Command Defaults
open-pulse health sources defaults from shared service config:
- Neo4j HTTP:
http://localhost:7474 - Neo4j Bolt:
bolt://localhost:7687 - SPARQL store:
http://localhost:7878 - GME extractor:
http://localhost:1234 - GrimoireLab DB:
localhost:5432
Grimoire Commands
open-pulse services grimoire prepare-config— generateprojects.jsonfrom SPARQLopen-pulse services grimoire apply— query SPARQL → POST to applier (writesprojects.json, restarts mordred)open-pulse services grimoire install-watcher— cron-based config watcheropen-pulse gui grimoire— Streamlit UIopen-pulse gui hub serve— FastAPI Hub dashboard
Docs
- Docusaurus source:
docs-site/ - Docs index:
docs-site/docs/index.md - Legacy static landing:
docs/ - Container build / hub usage:
tools/images/README.md - Compose model:
infra/open-pulse-stack/README.md
Project Links
- Pending follow-ups:
dev/plans/follow-ups.md - Changelog:
CHANGELOG.md - Contributing:
CONTRIBUTING.md - Security:
SECURITY.md
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 Distributions
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 open_pulse_science-1.0.0-py3-none-any.whl.
File metadata
- Download URL: open_pulse_science-1.0.0-py3-none-any.whl
- Upload date:
- Size: 158.8 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 |
5189f2bb32b0626c2e66c18e023a4b6274c24c3e9ec7def95dd8f3e4fb6a472b
|
|
| MD5 |
a64bbd33c6ae9b4125b55af492ead590
|
|
| BLAKE2b-256 |
96864d276ea9e79e1175ae59b3d11b8ffab72b0f060657e863e1605e54f10ae2
|
Provenance
The following attestation bundles were made for open_pulse_science-1.0.0-py3-none-any.whl:
Publisher:
release.yml on sdsc-ordes/open-pulse
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
open_pulse_science-1.0.0-py3-none-any.whl -
Subject digest:
5189f2bb32b0626c2e66c18e023a4b6274c24c3e9ec7def95dd8f3e4fb6a472b - Sigstore transparency entry: 1524887265
- Sigstore integration time:
-
Permalink:
sdsc-ordes/open-pulse@86b26d7aea63d3535676c68af8b7308444c5b447 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/sdsc-ordes
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@86b26d7aea63d3535676c68af8b7308444c5b447 -
Trigger Event:
push
-
Statement type: