hof-engine 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- hof_engine-0.1.0/.dockerignore +7 -0
- hof_engine-0.1.0/.github/workflows/ci.yml +65 -0
- hof_engine-0.1.0/.github/workflows/publish-testpypi.yml +41 -0
- hof_engine-0.1.0/.github/workflows/publish.yml +51 -0
- hof_engine-0.1.0/.gitignore +49 -0
- hof_engine-0.1.0/.hof/components-manifest.json +12 -0
- hof_engine-0.1.0/AGENTS.md +66 -0
- hof_engine-0.1.0/Dockerfile +52 -0
- hof_engine-0.1.0/PKG-INFO +200 -0
- hof_engine-0.1.0/README.md +150 -0
- hof_engine-0.1.0/docker-compose.yml +114 -0
- hof_engine-0.1.0/docs/guide/getting-started.md +155 -0
- hof_engine-0.1.0/docs/reference/cli.md +164 -0
- hof_engine-0.1.0/docs/reference/config.md +109 -0
- hof_engine-0.1.0/docs/reference/cron.md +64 -0
- hof_engine-0.1.0/docs/reference/flows.md +253 -0
- hof_engine-0.1.0/docs/reference/functions.md +154 -0
- hof_engine-0.1.0/docs/reference/llm.md +173 -0
- hof_engine-0.1.0/docs/reference/tables.md +165 -0
- hof_engine-0.1.0/docs/reference/ui.md +201 -0
- hof_engine-0.1.0/hatch_build.py +33 -0
- hof_engine-0.1.0/hof/__init__.py +35 -0
- hof_engine-0.1.0/hof/api/__init__.py +1 -0
- hof_engine-0.1.0/hof/api/auth.py +228 -0
- hof_engine-0.1.0/hof/api/routes/__init__.py +1 -0
- hof_engine-0.1.0/hof/api/routes/admin.py +89 -0
- hof_engine-0.1.0/hof/api/routes/flows.py +100 -0
- hof_engine-0.1.0/hof/api/routes/functions.py +98 -0
- hof_engine-0.1.0/hof/api/routes/tables.py +151 -0
- hof_engine-0.1.0/hof/api/routes/ws.py +77 -0
- hof_engine-0.1.0/hof/api/server.py +280 -0
- hof_engine-0.1.0/hof/app.py +180 -0
- hof_engine-0.1.0/hof/cli/__init__.py +1 -0
- hof_engine-0.1.0/hof/cli/api_client.py +86 -0
- hof_engine-0.1.0/hof/cli/commands/__init__.py +27 -0
- hof_engine-0.1.0/hof/cli/commands/add.py +456 -0
- hof_engine-0.1.0/hof/cli/commands/build.py +31 -0
- hof_engine-0.1.0/hof/cli/commands/cron_cmd.py +87 -0
- hof_engine-0.1.0/hof/cli/commands/db.py +119 -0
- hof_engine-0.1.0/hof/cli/commands/dev.py +287 -0
- hof_engine-0.1.0/hof/cli/commands/flow.py +171 -0
- hof_engine-0.1.0/hof/cli/commands/fn.py +136 -0
- hof_engine-0.1.0/hof/cli/commands/new.py +383 -0
- hof_engine-0.1.0/hof/cli/commands/table.py +140 -0
- hof_engine-0.1.0/hof/cli/main.py +44 -0
- hof_engine-0.1.0/hof/config.py +191 -0
- hof_engine-0.1.0/hof/core/__init__.py +1 -0
- hof_engine-0.1.0/hof/core/discovery.py +56 -0
- hof_engine-0.1.0/hof/core/registry.py +102 -0
- hof_engine-0.1.0/hof/core/types.py +45 -0
- hof_engine-0.1.0/hof/cron/__init__.py +1 -0
- hof_engine-0.1.0/hof/cron/scheduler.py +103 -0
- hof_engine-0.1.0/hof/db/__init__.py +1 -0
- hof_engine-0.1.0/hof/db/engine.py +148 -0
- hof_engine-0.1.0/hof/db/migrations.py +154 -0
- hof_engine-0.1.0/hof/db/schemas.py +114 -0
- hof_engine-0.1.0/hof/db/table.py +359 -0
- hof_engine-0.1.0/hof/errors.py +47 -0
- hof_engine-0.1.0/hof/files/__init__.py +1 -0
- hof_engine-0.1.0/hof/files/processors.py +59 -0
- hof_engine-0.1.0/hof/files/storage.py +50 -0
- hof_engine-0.1.0/hof/flows/__init__.py +1 -0
- hof_engine-0.1.0/hof/flows/executor.py +418 -0
- hof_engine-0.1.0/hof/flows/flow.py +211 -0
- hof_engine-0.1.0/hof/flows/human.py +60 -0
- hof_engine-0.1.0/hof/flows/models.py +61 -0
- hof_engine-0.1.0/hof/flows/node.py +140 -0
- hof_engine-0.1.0/hof/flows/state.py +297 -0
- hof_engine-0.1.0/hof/functions.py +166 -0
- hof_engine-0.1.0/hof/llm/__init__.py +6 -0
- hof_engine-0.1.0/hof/llm/decorators.py +57 -0
- hof_engine-0.1.0/hof/llm/provider.py +67 -0
- hof_engine-0.1.0/hof/logging_config.py +120 -0
- hof_engine-0.1.0/hof/scaffold.py +12 -0
- hof_engine-0.1.0/hof/tasks/__init__.py +1 -0
- hof_engine-0.1.0/hof/tasks/celery_app.py +137 -0
- hof_engine-0.1.0/hof/tasks/worker.py +48 -0
- hof_engine-0.1.0/hof/ui/__init__.py +1 -0
- hof_engine-0.1.0/hof/ui/admin/.gitignore +2 -0
- hof_engine-0.1.0/hof/ui/admin/index.html +12 -0
- hof_engine-0.1.0/hof/ui/admin/package-lock.json +2108 -0
- hof_engine-0.1.0/hof/ui/admin/package.json +24 -0
- hof_engine-0.1.0/hof/ui/admin/src/App.tsx +156 -0
- hof_engine-0.1.0/hof/ui/admin/src/api.ts +162 -0
- hof_engine-0.1.0/hof/ui/admin/src/components/FlowGraph.tsx +116 -0
- hof_engine-0.1.0/hof/ui/admin/src/components/Sidebar.tsx +53 -0
- hof_engine-0.1.0/hof/ui/admin/src/components/UserComponent.tsx +74 -0
- hof_engine-0.1.0/hof/ui/admin/src/main.tsx +13 -0
- hof_engine-0.1.0/hof/ui/admin/src/pages/Dashboard.tsx +95 -0
- hof_engine-0.1.0/hof/ui/admin/src/pages/FlowList.tsx +54 -0
- hof_engine-0.1.0/hof/ui/admin/src/pages/FlowViewer.tsx +131 -0
- hof_engine-0.1.0/hof/ui/admin/src/pages/FunctionList.tsx +61 -0
- hof_engine-0.1.0/hof/ui/admin/src/pages/PendingActions.tsx +154 -0
- hof_engine-0.1.0/hof/ui/admin/src/pages/TableBrowser.tsx +102 -0
- hof_engine-0.1.0/hof/ui/admin/src/pages/TaskList.tsx +91 -0
- hof_engine-0.1.0/hof/ui/admin/src/styles.css +367 -0
- hof_engine-0.1.0/hof/ui/admin/tsconfig.json +17 -0
- hof_engine-0.1.0/hof/ui/admin/vite.config.ts +17 -0
- hof_engine-0.1.0/hof/ui/vite.py +461 -0
- hof_engine-0.1.0/hof-react/package-lock.json +1503 -0
- hof_engine-0.1.0/hof-react/package.json +33 -0
- hof_engine-0.1.0/hof-react/src/hooks/useHofFlow.ts +64 -0
- hof_engine-0.1.0/hof-react/src/hooks/useHofFunction.ts +47 -0
- hof_engine-0.1.0/hof-react/src/hooks/useHofNode.ts +72 -0
- hof_engine-0.1.0/hof-react/src/hooks/useHofTable.ts +103 -0
- hof_engine-0.1.0/hof-react/src/index.ts +4 -0
- hof_engine-0.1.0/hof-react/tsconfig.json +16 -0
- hof_engine-0.1.0/pyproject.toml +102 -0
- hof_engine-0.1.0/tests/__init__.py +0 -0
- hof_engine-0.1.0/tests/conftest.py +147 -0
- hof_engine-0.1.0/tests/test_api.py +267 -0
- hof_engine-0.1.0/tests/test_cli_add.py +261 -0
- hof_engine-0.1.0/tests/test_cli_flow.py +177 -0
- hof_engine-0.1.0/tests/test_cli_fn.py +132 -0
- hof_engine-0.1.0/tests/test_core_discovery.py +87 -0
- hof_engine-0.1.0/tests/test_core_registry.py +154 -0
- hof_engine-0.1.0/tests/test_core_types.py +78 -0
- hof_engine-0.1.0/tests/test_cron.py +178 -0
- hof_engine-0.1.0/tests/test_db_engine.py +109 -0
- hof_engine-0.1.0/tests/test_db_table.py +276 -0
- hof_engine-0.1.0/tests/test_flows_executor.py +305 -0
- hof_engine-0.1.0/tests/test_flows_flow.py +190 -0
- hof_engine-0.1.0/tests/test_flows_node.py +230 -0
- hof_engine-0.1.0/tests/test_flows_state.py +144 -0
- hof_engine-0.1.0/tests/test_functions.py +192 -0
- hof_engine-0.1.0/tests/test_llm.py +79 -0
- hof_engine-0.1.0/tests/test_scaffold.py +91 -0
- hof_engine-0.1.0/tests/test_vite.py +360 -0
- hof_engine-0.1.0/uv.lock +2414 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: ["main", "master"]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: ["main", "master"]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
lint:
|
|
11
|
+
name: Lint & Format
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
|
|
16
|
+
- name: Set up Python
|
|
17
|
+
uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: "3.11"
|
|
20
|
+
|
|
21
|
+
- name: Install ruff
|
|
22
|
+
run: pip install ruff
|
|
23
|
+
|
|
24
|
+
- name: Run ruff (lint)
|
|
25
|
+
run: ruff check hof/ tests/
|
|
26
|
+
|
|
27
|
+
- name: Run ruff (format check)
|
|
28
|
+
run: ruff format --check hof/ tests/
|
|
29
|
+
|
|
30
|
+
test:
|
|
31
|
+
name: Tests (Python ${{ matrix.python-version }})
|
|
32
|
+
runs-on: ubuntu-latest
|
|
33
|
+
strategy:
|
|
34
|
+
fail-fast: false
|
|
35
|
+
matrix:
|
|
36
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
37
|
+
|
|
38
|
+
steps:
|
|
39
|
+
- uses: actions/checkout@v4
|
|
40
|
+
|
|
41
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
42
|
+
uses: actions/setup-python@v5
|
|
43
|
+
with:
|
|
44
|
+
python-version: ${{ matrix.python-version }}
|
|
45
|
+
|
|
46
|
+
- name: Install dependencies
|
|
47
|
+
run: |
|
|
48
|
+
pip install --upgrade pip
|
|
49
|
+
pip install -e ".[dev]"
|
|
50
|
+
|
|
51
|
+
- name: Run tests with coverage
|
|
52
|
+
run: |
|
|
53
|
+
pytest tests/ \
|
|
54
|
+
-m "not integration" \
|
|
55
|
+
--cov=hof \
|
|
56
|
+
--cov-report=term-missing \
|
|
57
|
+
--cov-report=xml \
|
|
58
|
+
-v
|
|
59
|
+
|
|
60
|
+
- name: Upload coverage report
|
|
61
|
+
if: matrix.python-version == '3.11'
|
|
62
|
+
uses: actions/upload-artifact@v4
|
|
63
|
+
with:
|
|
64
|
+
name: coverage-report
|
|
65
|
+
path: coverage.xml
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
name: Publish to TestPyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
|
|
6
|
+
jobs:
|
|
7
|
+
publish:
|
|
8
|
+
name: Build & Publish (TestPyPI)
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
environment:
|
|
11
|
+
name: testpypi
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
id-token: write
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Set up Python
|
|
20
|
+
uses: actions/setup-python@v5
|
|
21
|
+
with:
|
|
22
|
+
python-version: "3.11"
|
|
23
|
+
|
|
24
|
+
- name: Set up Node.js
|
|
25
|
+
uses: actions/setup-node@v4
|
|
26
|
+
with:
|
|
27
|
+
node-version: "20"
|
|
28
|
+
|
|
29
|
+
- name: Install hatch
|
|
30
|
+
run: pip install hatch twine
|
|
31
|
+
|
|
32
|
+
- name: Build package (compiles admin UI via hatch_build.py)
|
|
33
|
+
run: hatch build
|
|
34
|
+
|
|
35
|
+
- name: Check distribution metadata
|
|
36
|
+
run: twine check dist/*
|
|
37
|
+
|
|
38
|
+
- name: Publish to TestPyPI
|
|
39
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
40
|
+
with:
|
|
41
|
+
repository-url: https://test.pypi.org/legacy/
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
push:
|
|
7
|
+
tags:
|
|
8
|
+
- "v*"
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
publish:
|
|
13
|
+
name: Build & Publish
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
environment:
|
|
16
|
+
name: pypi
|
|
17
|
+
permissions:
|
|
18
|
+
contents: read
|
|
19
|
+
id-token: write
|
|
20
|
+
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v4
|
|
23
|
+
|
|
24
|
+
- name: Set up Python
|
|
25
|
+
uses: actions/setup-python@v5
|
|
26
|
+
with:
|
|
27
|
+
python-version: "3.11"
|
|
28
|
+
|
|
29
|
+
- name: Set up Node.js
|
|
30
|
+
uses: actions/setup-node@v4
|
|
31
|
+
with:
|
|
32
|
+
node-version: "20"
|
|
33
|
+
|
|
34
|
+
- name: Install hatch
|
|
35
|
+
run: pip install hatch twine
|
|
36
|
+
|
|
37
|
+
- name: Set version from release tag
|
|
38
|
+
if: github.event_name == 'release' || startsWith(github.ref, 'refs/tags/')
|
|
39
|
+
run: |
|
|
40
|
+
VERSION="${GITHUB_REF_NAME#v}"
|
|
41
|
+
echo "Publishing version: $VERSION"
|
|
42
|
+
sed -i "s/^version = .*/version = \"$VERSION\"/" pyproject.toml
|
|
43
|
+
|
|
44
|
+
- name: Build package (compiles admin UI via hatch_build.py)
|
|
45
|
+
run: hatch build
|
|
46
|
+
|
|
47
|
+
- name: Check distribution metadata
|
|
48
|
+
run: twine check dist/*
|
|
49
|
+
|
|
50
|
+
- name: Publish to PyPI
|
|
51
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.pyo
|
|
5
|
+
*.egg-info/
|
|
6
|
+
*.egg
|
|
7
|
+
dist/
|
|
8
|
+
build/
|
|
9
|
+
*.whl
|
|
10
|
+
.mypy_cache/
|
|
11
|
+
.pytest_cache/
|
|
12
|
+
.ruff_cache/
|
|
13
|
+
htmlcov/
|
|
14
|
+
.coverage
|
|
15
|
+
|
|
16
|
+
# Virtual environments
|
|
17
|
+
.venv/
|
|
18
|
+
venv/
|
|
19
|
+
env/
|
|
20
|
+
|
|
21
|
+
# Environment variables / secrets
|
|
22
|
+
.env
|
|
23
|
+
.env.*
|
|
24
|
+
|
|
25
|
+
# IDE
|
|
26
|
+
.vscode/
|
|
27
|
+
.idea/
|
|
28
|
+
*.swp
|
|
29
|
+
*.swo
|
|
30
|
+
.cursor/
|
|
31
|
+
|
|
32
|
+
# Node
|
|
33
|
+
node_modules/
|
|
34
|
+
hof/ui/admin/dist/
|
|
35
|
+
hof-react/dist/
|
|
36
|
+
|
|
37
|
+
# Hof generated (per-project)
|
|
38
|
+
migrations/
|
|
39
|
+
_hof_entry.tsx
|
|
40
|
+
ui/index.html
|
|
41
|
+
ui/package.json
|
|
42
|
+
ui/vite.config.ts
|
|
43
|
+
ui/tsconfig.json
|
|
44
|
+
ui/node_modules/
|
|
45
|
+
ui/dist/
|
|
46
|
+
|
|
47
|
+
# OS
|
|
48
|
+
.DS_Store
|
|
49
|
+
Thumbs.db
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema_version": 1,
|
|
3
|
+
"updated_at": "2026-03-10T17:14:40Z",
|
|
4
|
+
"artifacts": [
|
|
5
|
+
{
|
|
6
|
+
"engine_version": "0.1.0",
|
|
7
|
+
"artifact_url": "https://github.com/jhoetter/hof-engine/releases/download/components-0.1/hof-components.tar.gz",
|
|
8
|
+
"sha256": "1af4bf05df285815a6ca35af3a9a4eba0473325c451e9265547e51996994c24f",
|
|
9
|
+
"published_at": "2026-03-10T17:14:40Z"
|
|
10
|
+
}
|
|
11
|
+
]
|
|
12
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# AGENTS.md — hof-engine
|
|
2
|
+
|
|
3
|
+
## What this repo is
|
|
4
|
+
|
|
5
|
+
hof-engine is the **core framework** for building full-stack Python + React applications. It is distributed as a pip package (`pip install hof-engine`) and provides:
|
|
6
|
+
|
|
7
|
+
- **Tables** — database schemas as Python classes with auto-generated CRUD APIs
|
|
8
|
+
- **Functions** — backend operations exposed as API endpoints and CLI commands
|
|
9
|
+
- **Flows** — workflow DAGs with parallel execution, LLM nodes, and human-in-the-loop
|
|
10
|
+
- **Cron** — scheduled tasks via Celery Beat
|
|
11
|
+
- **Admin UI** — React dashboard (flow viewer, table browser, pending actions)
|
|
12
|
+
- **CLI** — `hof` command for dev server, migrations, scaffolding, module management
|
|
13
|
+
- **LLM integration** — `@prompt()` decorator with structured outputs via llm-markdown
|
|
14
|
+
- **React hooks** — `@hof-engine/react` npm package (`hof-react/` directory)
|
|
15
|
+
|
|
16
|
+
## What does NOT belong here
|
|
17
|
+
|
|
18
|
+
- **Customer-specific business logic** — belongs in the customer repo
|
|
19
|
+
- **Reusable modules** (tables, flows, functions, UI for specific use cases like lead enrichment, billing) — belongs in **hof-components**
|
|
20
|
+
- **Deployment, server provisioning, DNS, infrastructure** — belongs in **hof-os**
|
|
21
|
+
- **Design tokens, brand colors, Tailwind themes** — belongs in **design-system-\<customer\>** repos (managed by hof-os)
|
|
22
|
+
- **Application examples** — belong in **hof-components** (as modules or in `docs/examples/`)
|
|
23
|
+
|
|
24
|
+
## Ecosystem
|
|
25
|
+
|
|
26
|
+
This repo is part of the bithof platform (hof-os, hof-engine, hof-components, design-system-\<customer\>, customer-\<name\>). For the full ecosystem map, repo boundaries, and ownership rules, see:
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
~/repos/hof-os/docs/ecosystem.md
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Repo Structure
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
hof-engine/
|
|
36
|
+
├── hof/ # Main Python package (this ships in the pip wheel)
|
|
37
|
+
│ ├── api/ # FastAPI server, routes, auth
|
|
38
|
+
│ ├── cli/ # CLI commands (dev, db, flow, fn, table, cron, new, add)
|
|
39
|
+
│ ├── core/ # Registry, discovery
|
|
40
|
+
│ ├── db/ # SQLAlchemy engine, migrations
|
|
41
|
+
│ ├── flows/ # Flow execution engine
|
|
42
|
+
│ ├── llm/ # LLM decorators and integration
|
|
43
|
+
│ └── ui/
|
|
44
|
+
│ ├── admin/ # Admin React UI (pre-built to dist/ for pip wheel)
|
|
45
|
+
│ └── vite.py # ViteManager for user React components
|
|
46
|
+
├── hof-react/ # @hof-engine/react npm package (hooks for customer UIs)
|
|
47
|
+
├── docs/ # Framework reference documentation
|
|
48
|
+
│ ├── guide/ # Getting started
|
|
49
|
+
│ └── reference/ # Tables, functions, flows, UI, CLI, config, LLM
|
|
50
|
+
├── tests/ # pytest test suite
|
|
51
|
+
├── hatch_build.py # Hatch hook: compiles admin UI before wheel build
|
|
52
|
+
├── pyproject.toml # Package config, dependencies, build settings
|
|
53
|
+
└── .github/workflows/ # CI + PyPI publish
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Rules for AI agents
|
|
57
|
+
|
|
58
|
+
1. **Framework only.** Every change here should benefit ALL customer projects, not just one. If it's specific to a use case, it belongs in hof-components.
|
|
59
|
+
|
|
60
|
+
2. **The pip wheel must be self-contained.** The admin UI ships as pre-built static assets (`hof/ui/admin/dist/`). Never add runtime dependencies on Node.js, hof-components, or hof-os.
|
|
61
|
+
|
|
62
|
+
3. **The `hof add` CLI fetches from hof-components.** If you're adding a new module, add it to hof-components, not here. The `hof/cli/commands/add.py` command handles the copy.
|
|
63
|
+
|
|
64
|
+
4. **`hof-react/` is a separate npm package.** It has its own `package.json`, `tsconfig.json`, and build step (`tsup`). Changes to React hooks go here, not in `hof/ui/admin/`.
|
|
65
|
+
|
|
66
|
+
5. **Docs in this repo are framework reference only.** Application examples and tutorials belong in hof-components (`docs/examples/`).
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Multi-stage Dockerfile for hof-engine applications
|
|
2
|
+
# Stage 1: Python dependencies
|
|
3
|
+
FROM python:3.11-slim AS python-deps
|
|
4
|
+
|
|
5
|
+
WORKDIR /app
|
|
6
|
+
|
|
7
|
+
# Install system dependencies required by psycopg2 and other packages
|
|
8
|
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
9
|
+
build-essential \
|
|
10
|
+
libpq-dev \
|
|
11
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
12
|
+
|
|
13
|
+
COPY pyproject.toml ./
|
|
14
|
+
RUN pip install --upgrade pip && pip install -e ".[dev]"
|
|
15
|
+
|
|
16
|
+
# Stage 2: Node.js for building the admin UI and user UI
|
|
17
|
+
FROM node:20-slim AS node-builder
|
|
18
|
+
|
|
19
|
+
WORKDIR /app/hof/ui/admin
|
|
20
|
+
COPY hof/ui/admin/package*.json ./
|
|
21
|
+
RUN npm ci --silent
|
|
22
|
+
|
|
23
|
+
COPY hof/ui/admin/ ./
|
|
24
|
+
RUN npm run build
|
|
25
|
+
|
|
26
|
+
# Stage 3: Final runtime image
|
|
27
|
+
FROM python:3.11-slim AS runtime
|
|
28
|
+
|
|
29
|
+
WORKDIR /app
|
|
30
|
+
|
|
31
|
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
32
|
+
libpq5 \
|
|
33
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
34
|
+
|
|
35
|
+
# Copy installed Python packages from deps stage
|
|
36
|
+
COPY --from=python-deps /usr/local/lib/python3.11 /usr/local/lib/python3.11
|
|
37
|
+
COPY --from=python-deps /usr/local/bin /usr/local/bin
|
|
38
|
+
|
|
39
|
+
# Copy application source
|
|
40
|
+
COPY hof/ ./hof/
|
|
41
|
+
COPY pyproject.toml ./
|
|
42
|
+
|
|
43
|
+
# Copy built admin UI
|
|
44
|
+
COPY --from=node-builder /app/hof/ui/admin/dist ./hof/ui/admin/dist
|
|
45
|
+
|
|
46
|
+
# Create a non-root user
|
|
47
|
+
RUN useradd --create-home --shell /bin/bash hof
|
|
48
|
+
USER hof
|
|
49
|
+
|
|
50
|
+
EXPOSE 8001
|
|
51
|
+
|
|
52
|
+
CMD ["uvicorn", "hof.api.server:create_app", "--factory", "--host", "0.0.0.0", "--port", "8001"]
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: hof-engine
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Full-stack Python + React framework for building applications with workflows, tables, UIs, and LLM integration.
|
|
5
|
+
Project-URL: Homepage, https://github.com/jhoetter/hof-engine
|
|
6
|
+
Project-URL: Documentation, https://github.com/jhoetter/hof-engine/tree/main/docs
|
|
7
|
+
Project-URL: Repository, https://github.com/jhoetter/hof-engine
|
|
8
|
+
Author: Johannes Hoetter
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
Keywords: framework,full-stack,llm,react,workflow
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Framework :: FastAPI
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Requires-Dist: alembic>=1.14.0
|
|
22
|
+
Requires-Dist: asyncpg>=0.30.0
|
|
23
|
+
Requires-Dist: celery[redis]>=5.4.0
|
|
24
|
+
Requires-Dist: fastapi>=0.115.0
|
|
25
|
+
Requires-Dist: httpx>=0.27.0
|
|
26
|
+
Requires-Dist: llm-markdown[openai]>=0.3.0
|
|
27
|
+
Requires-Dist: passlib[bcrypt]>=1.7.4
|
|
28
|
+
Requires-Dist: psycopg2-binary>=2.9.0
|
|
29
|
+
Requires-Dist: pydantic-settings>=2.0.0
|
|
30
|
+
Requires-Dist: pydantic>=2.0.0
|
|
31
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
32
|
+
Requires-Dist: python-jose[cryptography]>=3.3.0
|
|
33
|
+
Requires-Dist: python-multipart>=0.0.9
|
|
34
|
+
Requires-Dist: redis>=5.0.0
|
|
35
|
+
Requires-Dist: rich>=13.0.0
|
|
36
|
+
Requires-Dist: sqlalchemy[asyncio]>=2.0.0
|
|
37
|
+
Requires-Dist: typer>=0.15.0
|
|
38
|
+
Requires-Dist: uvicorn[standard]>=0.32.0
|
|
39
|
+
Requires-Dist: websockets>=14.0
|
|
40
|
+
Provides-Extra: dev
|
|
41
|
+
Requires-Dist: mypy>=1.13.0; extra == 'dev'
|
|
42
|
+
Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
|
|
43
|
+
Requires-Dist: pytest-cov>=6.0.0; extra == 'dev'
|
|
44
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
45
|
+
Requires-Dist: ruff>=0.8.0; extra == 'dev'
|
|
46
|
+
Provides-Extra: docs
|
|
47
|
+
Requires-Dist: mkdocs-material>=9.5.0; extra == 'docs'
|
|
48
|
+
Requires-Dist: mkdocstrings[python]>=0.27.0; extra == 'docs'
|
|
49
|
+
Description-Content-Type: text/markdown
|
|
50
|
+
|
|
51
|
+
# hof-engine
|
|
52
|
+
|
|
53
|
+
Full-stack Python + React framework for building applications with workflows, database tables, UIs, and LLM integration -- all defined as code.
|
|
54
|
+
|
|
55
|
+
## Features
|
|
56
|
+
|
|
57
|
+
- **Tables**: Define database schemas as Python classes with auto-generated CRUD APIs
|
|
58
|
+
- **Functions**: Backend operations exposed as API endpoints and CLI commands
|
|
59
|
+
- **Flows**: Workflow DAGs with parallel execution, LLM nodes, and human-in-the-loop
|
|
60
|
+
- **UIs**: Native React components with hot reload via Vite
|
|
61
|
+
- **Cron Jobs**: Scheduled tasks with Celery Beat
|
|
62
|
+
- **CLI**: Full CLI access to all features
|
|
63
|
+
- **Admin Dashboard**: Visual flow viewer, table browser, execution history, and logs
|
|
64
|
+
- **LLM Integration**: First-class support via llm-markdown with structured outputs
|
|
65
|
+
|
|
66
|
+
## Quick Start
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
pip install hof-engine
|
|
70
|
+
hof new project my-app
|
|
71
|
+
cd my-app
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Define a table:
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
# tables/task.py
|
|
78
|
+
from hof import Table, Column, types
|
|
79
|
+
|
|
80
|
+
class Task(Table):
|
|
81
|
+
title = Column(types.String, required=True)
|
|
82
|
+
done = Column(types.Boolean, default=False)
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Define a function:
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
# functions/greet.py
|
|
89
|
+
from hof import function
|
|
90
|
+
|
|
91
|
+
@function
|
|
92
|
+
def greet(name: str) -> dict:
|
|
93
|
+
return {"message": f"Hello, {name}!"}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Define a flow:
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
# flows/onboarding.py
|
|
100
|
+
from hof import Flow
|
|
101
|
+
|
|
102
|
+
onboarding = Flow("onboarding")
|
|
103
|
+
|
|
104
|
+
@onboarding.node
|
|
105
|
+
def create_task(user_name: str) -> dict:
|
|
106
|
+
return {"task": f"Welcome {user_name}"}
|
|
107
|
+
|
|
108
|
+
@onboarding.node(depends_on=[create_task])
|
|
109
|
+
def notify(task: str) -> dict:
|
|
110
|
+
return {"notified": True}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Run:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
hof db migrate
|
|
117
|
+
hof dev
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Requirements
|
|
121
|
+
|
|
122
|
+
- Python 3.11+
|
|
123
|
+
- Node.js 18+ (for React UI)
|
|
124
|
+
- PostgreSQL
|
|
125
|
+
- Redis
|
|
126
|
+
|
|
127
|
+
## Documentation
|
|
128
|
+
|
|
129
|
+
See the [docs/](docs/) directory:
|
|
130
|
+
|
|
131
|
+
- [Getting Started](docs/guide/getting-started.md)
|
|
132
|
+
- [Tables Reference](docs/reference/tables.md)
|
|
133
|
+
- [Functions Reference](docs/reference/functions.md)
|
|
134
|
+
- [Flows Reference](docs/reference/flows.md)
|
|
135
|
+
- [UI Reference](docs/reference/ui.md)
|
|
136
|
+
- [LLM Reference](docs/reference/llm.md)
|
|
137
|
+
- [CLI Reference](docs/reference/cli.md)
|
|
138
|
+
- [Configuration](docs/reference/config.md)
|
|
139
|
+
|
|
140
|
+
## Ecosystem
|
|
141
|
+
|
|
142
|
+
hof-engine is part of the bithof platform:
|
|
143
|
+
|
|
144
|
+
| Repo | Role |
|
|
145
|
+
|---|---|
|
|
146
|
+
| **hof-engine** (this repo) | Core framework (pip package) |
|
|
147
|
+
| [hof-components](https://github.com/jhoetter/hof-components) | Reusable modules and templates, copied via `hof add` |
|
|
148
|
+
| [hof-os](https://github.com/jhoetter/hof-os) | Agency operations: deployment, provisioning, billing, design system generation |
|
|
149
|
+
| **design-system-\<customer\>** | Per-customer design tokens + Tailwind theme (git submodule in project repos) |
|
|
150
|
+
| [customer-acme-test](https://github.com/jhoetter/customer-acme-test) | Example customer project |
|
|
151
|
+
|
|
152
|
+
For application examples, see [hof-components/docs/examples/](https://github.com/jhoetter/hof-components/tree/main/docs/examples).
|
|
153
|
+
|
|
154
|
+
## License
|
|
155
|
+
|
|
156
|
+
MIT
|
|
157
|
+
|
|
158
|
+
## Releasing to PyPI
|
|
159
|
+
|
|
160
|
+
This repository is configured for Trusted Publishing via GitHub Actions:
|
|
161
|
+
|
|
162
|
+
- `.github/workflows/publish.yml` for PyPI
|
|
163
|
+
- `.github/workflows/publish-testpypi.yml` for TestPyPI
|
|
164
|
+
|
|
165
|
+
- The repository can stay private.
|
|
166
|
+
- No `PYPI_TOKEN` secret is required.
|
|
167
|
+
- Publishing to PyPI happens when a GitHub Release is published (or manually via workflow dispatch).
|
|
168
|
+
- Publishing to TestPyPI is manual via workflow dispatch.
|
|
169
|
+
|
|
170
|
+
One-time setup in your PyPI account:
|
|
171
|
+
|
|
172
|
+
1. Go to [PyPI Trusted Publishers](https://pypi.org/manage/account/publishing/).
|
|
173
|
+
2. Add a publisher with:
|
|
174
|
+
- PyPI project name: `hof-engine`
|
|
175
|
+
- Owner/repo: your GitHub repo for this project
|
|
176
|
+
- Workflow: `publish.yml` (filename only)
|
|
177
|
+
- Environment: `pypi`
|
|
178
|
+
3. In GitHub, create an environment named `pypi` (recommended to require manual approval).
|
|
179
|
+
|
|
180
|
+
Optional setup for TestPyPI:
|
|
181
|
+
|
|
182
|
+
1. Go to [TestPyPI Trusted Publishers](https://test.pypi.org/manage/account/publishing/).
|
|
183
|
+
2. Add a publisher with:
|
|
184
|
+
- TestPyPI project name: `hof-engine`
|
|
185
|
+
- Owner/repo: your GitHub repo for this project
|
|
186
|
+
- Workflow: `publish-testpypi.yml` (filename only)
|
|
187
|
+
- Environment: `testpypi`
|
|
188
|
+
3. In GitHub, create an environment named `testpypi`.
|
|
189
|
+
|
|
190
|
+
Release flow:
|
|
191
|
+
|
|
192
|
+
1. Bump/update code as needed and push to default branch.
|
|
193
|
+
2. Create and push a git tag like `v0.1.1` (`git tag v0.1.1 && git push origin v0.1.1`).
|
|
194
|
+
3. The workflow builds and uploads the package to PyPI under your account/project ownership.
|
|
195
|
+
4. Optional: also publish a GitHub Release for changelog/visibility.
|
|
196
|
+
|
|
197
|
+
Manual publish options:
|
|
198
|
+
|
|
199
|
+
- Publish to PyPI now (no release): run the `Publish to PyPI` workflow via GitHub Actions `Run workflow`.
|
|
200
|
+
- Publish to TestPyPI: run the `Publish to TestPyPI` workflow via GitHub Actions `Run workflow`.
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# hof-engine
|
|
2
|
+
|
|
3
|
+
Full-stack Python + React framework for building applications with workflows, database tables, UIs, and LLM integration -- all defined as code.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Tables**: Define database schemas as Python classes with auto-generated CRUD APIs
|
|
8
|
+
- **Functions**: Backend operations exposed as API endpoints and CLI commands
|
|
9
|
+
- **Flows**: Workflow DAGs with parallel execution, LLM nodes, and human-in-the-loop
|
|
10
|
+
- **UIs**: Native React components with hot reload via Vite
|
|
11
|
+
- **Cron Jobs**: Scheduled tasks with Celery Beat
|
|
12
|
+
- **CLI**: Full CLI access to all features
|
|
13
|
+
- **Admin Dashboard**: Visual flow viewer, table browser, execution history, and logs
|
|
14
|
+
- **LLM Integration**: First-class support via llm-markdown with structured outputs
|
|
15
|
+
|
|
16
|
+
## Quick Start
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pip install hof-engine
|
|
20
|
+
hof new project my-app
|
|
21
|
+
cd my-app
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Define a table:
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
# tables/task.py
|
|
28
|
+
from hof import Table, Column, types
|
|
29
|
+
|
|
30
|
+
class Task(Table):
|
|
31
|
+
title = Column(types.String, required=True)
|
|
32
|
+
done = Column(types.Boolean, default=False)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Define a function:
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
# functions/greet.py
|
|
39
|
+
from hof import function
|
|
40
|
+
|
|
41
|
+
@function
|
|
42
|
+
def greet(name: str) -> dict:
|
|
43
|
+
return {"message": f"Hello, {name}!"}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Define a flow:
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
# flows/onboarding.py
|
|
50
|
+
from hof import Flow
|
|
51
|
+
|
|
52
|
+
onboarding = Flow("onboarding")
|
|
53
|
+
|
|
54
|
+
@onboarding.node
|
|
55
|
+
def create_task(user_name: str) -> dict:
|
|
56
|
+
return {"task": f"Welcome {user_name}"}
|
|
57
|
+
|
|
58
|
+
@onboarding.node(depends_on=[create_task])
|
|
59
|
+
def notify(task: str) -> dict:
|
|
60
|
+
return {"notified": True}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Run:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
hof db migrate
|
|
67
|
+
hof dev
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Requirements
|
|
71
|
+
|
|
72
|
+
- Python 3.11+
|
|
73
|
+
- Node.js 18+ (for React UI)
|
|
74
|
+
- PostgreSQL
|
|
75
|
+
- Redis
|
|
76
|
+
|
|
77
|
+
## Documentation
|
|
78
|
+
|
|
79
|
+
See the [docs/](docs/) directory:
|
|
80
|
+
|
|
81
|
+
- [Getting Started](docs/guide/getting-started.md)
|
|
82
|
+
- [Tables Reference](docs/reference/tables.md)
|
|
83
|
+
- [Functions Reference](docs/reference/functions.md)
|
|
84
|
+
- [Flows Reference](docs/reference/flows.md)
|
|
85
|
+
- [UI Reference](docs/reference/ui.md)
|
|
86
|
+
- [LLM Reference](docs/reference/llm.md)
|
|
87
|
+
- [CLI Reference](docs/reference/cli.md)
|
|
88
|
+
- [Configuration](docs/reference/config.md)
|
|
89
|
+
|
|
90
|
+
## Ecosystem
|
|
91
|
+
|
|
92
|
+
hof-engine is part of the bithof platform:
|
|
93
|
+
|
|
94
|
+
| Repo | Role |
|
|
95
|
+
|---|---|
|
|
96
|
+
| **hof-engine** (this repo) | Core framework (pip package) |
|
|
97
|
+
| [hof-components](https://github.com/jhoetter/hof-components) | Reusable modules and templates, copied via `hof add` |
|
|
98
|
+
| [hof-os](https://github.com/jhoetter/hof-os) | Agency operations: deployment, provisioning, billing, design system generation |
|
|
99
|
+
| **design-system-\<customer\>** | Per-customer design tokens + Tailwind theme (git submodule in project repos) |
|
|
100
|
+
| [customer-acme-test](https://github.com/jhoetter/customer-acme-test) | Example customer project |
|
|
101
|
+
|
|
102
|
+
For application examples, see [hof-components/docs/examples/](https://github.com/jhoetter/hof-components/tree/main/docs/examples).
|
|
103
|
+
|
|
104
|
+
## License
|
|
105
|
+
|
|
106
|
+
MIT
|
|
107
|
+
|
|
108
|
+
## Releasing to PyPI
|
|
109
|
+
|
|
110
|
+
This repository is configured for Trusted Publishing via GitHub Actions:
|
|
111
|
+
|
|
112
|
+
- `.github/workflows/publish.yml` for PyPI
|
|
113
|
+
- `.github/workflows/publish-testpypi.yml` for TestPyPI
|
|
114
|
+
|
|
115
|
+
- The repository can stay private.
|
|
116
|
+
- No `PYPI_TOKEN` secret is required.
|
|
117
|
+
- Publishing to PyPI happens when a GitHub Release is published (or manually via workflow dispatch).
|
|
118
|
+
- Publishing to TestPyPI is manual via workflow dispatch.
|
|
119
|
+
|
|
120
|
+
One-time setup in your PyPI account:
|
|
121
|
+
|
|
122
|
+
1. Go to [PyPI Trusted Publishers](https://pypi.org/manage/account/publishing/).
|
|
123
|
+
2. Add a publisher with:
|
|
124
|
+
- PyPI project name: `hof-engine`
|
|
125
|
+
- Owner/repo: your GitHub repo for this project
|
|
126
|
+
- Workflow: `publish.yml` (filename only)
|
|
127
|
+
- Environment: `pypi`
|
|
128
|
+
3. In GitHub, create an environment named `pypi` (recommended to require manual approval).
|
|
129
|
+
|
|
130
|
+
Optional setup for TestPyPI:
|
|
131
|
+
|
|
132
|
+
1. Go to [TestPyPI Trusted Publishers](https://test.pypi.org/manage/account/publishing/).
|
|
133
|
+
2. Add a publisher with:
|
|
134
|
+
- TestPyPI project name: `hof-engine`
|
|
135
|
+
- Owner/repo: your GitHub repo for this project
|
|
136
|
+
- Workflow: `publish-testpypi.yml` (filename only)
|
|
137
|
+
- Environment: `testpypi`
|
|
138
|
+
3. In GitHub, create an environment named `testpypi`.
|
|
139
|
+
|
|
140
|
+
Release flow:
|
|
141
|
+
|
|
142
|
+
1. Bump/update code as needed and push to default branch.
|
|
143
|
+
2. Create and push a git tag like `v0.1.1` (`git tag v0.1.1 && git push origin v0.1.1`).
|
|
144
|
+
3. The workflow builds and uploads the package to PyPI under your account/project ownership.
|
|
145
|
+
4. Optional: also publish a GitHub Release for changelog/visibility.
|
|
146
|
+
|
|
147
|
+
Manual publish options:
|
|
148
|
+
|
|
149
|
+
- Publish to PyPI now (no release): run the `Publish to PyPI` workflow via GitHub Actions `Run workflow`.
|
|
150
|
+
- Publish to TestPyPI: run the `Publish to TestPyPI` workflow via GitHub Actions `Run workflow`.
|