This commit is contained in:
commit
7c129cc81b
11 changed files with 1486 additions and 0 deletions
48
.forgejo/workflows/build.yaml
Normal file
48
.forgejo/workflows/build.yaml
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
verbose:
|
||||||
|
description: "Verbose"
|
||||||
|
required: false
|
||||||
|
default: false
|
||||||
|
type: boolean
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: container
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Install the latest version of uv
|
||||||
|
uses: astral-sh/setup-uv@v4
|
||||||
|
with:
|
||||||
|
version: "0.7.6"
|
||||||
|
|
||||||
|
- name: Install
|
||||||
|
run: uv sync
|
||||||
|
|
||||||
|
- name: Get version
|
||||||
|
run: echo "VERSION=$(.venv/bin/dunamai from any --style semver)" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Version
|
||||||
|
run: echo $VERSION
|
||||||
|
|
||||||
|
- name: Get distance from tag
|
||||||
|
run: echo "DISTANCE=$(.venv/bin/dunamai from any --format '{distance}')" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Distance
|
||||||
|
run: echo $DISTANCE
|
||||||
|
|
||||||
|
- name: Build wheel
|
||||||
|
if: env.DISTANCE == '0'
|
||||||
|
run: uv build --wheel
|
||||||
|
|
||||||
|
- name: Publish Python package (home)
|
||||||
|
if: env.DISTANCE == '0'
|
||||||
|
env:
|
||||||
|
LOCAL_PYPI_TOKEN: ${{ secrets.LOCAL_PYPI_TOKEN }}
|
||||||
|
run: uv publish --publish-url https://code.philo.ydns.eu/api/packages/K-Net/pypi --token $LOCAL_PYPI_TOKEN
|
||||||
|
continue-on-error: true
|
12
.gitignore
vendored
Normal file
12
.gitignore
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# Python-generated files
|
||||||
|
__pycache__/
|
||||||
|
*.py[oc]
|
||||||
|
build/
|
||||||
|
dist/
|
||||||
|
wheels/
|
||||||
|
*.egg-info
|
||||||
|
|
||||||
|
# Virtual environments
|
||||||
|
.venv
|
||||||
|
|
||||||
|
.env
|
1
.python-version
Normal file
1
.python-version
Normal file
|
@ -0,0 +1 @@
|
||||||
|
3.13
|
15
README.md
Normal file
15
README.md
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# Template for Knoc plugins
|
||||||
|
|
||||||
|
## Entry points
|
||||||
|
|
||||||
|
It has 4 standard entry points, defined in `pyproject.toml`:
|
||||||
|
|
||||||
|
* CLI
|
||||||
|
* workflow
|
||||||
|
* api
|
||||||
|
* settings
|
||||||
|
|
||||||
|
## CI
|
||||||
|
|
||||||
|
It has a Forgejo CI build action, defined in `.forgejo/actions/build.yaml`.
|
||||||
|
|
41
pyproject.toml
Normal file
41
pyproject.toml
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
[project]
|
||||||
|
name = "knoc-plugin-template"
|
||||||
|
dynamic = ["version"]
|
||||||
|
description = "Data intetrity plugin for Knoc"
|
||||||
|
readme = "README.md"
|
||||||
|
requires-python = ">=3.13"
|
||||||
|
dependencies = ["knoc>=0.1.22"]
|
||||||
|
|
||||||
|
[[tool.uv.index]]
|
||||||
|
url = "https://code.philo.ydns.eu/api/packages/philorg/pypi/simple/"
|
||||||
|
|
||||||
|
[[tool.uv.index]]
|
||||||
|
url = "https://code.philo.ydns.eu/api/packages/K-Net/pypi/simple/"
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["hatchling", "uv-dynamic-versioning"]
|
||||||
|
build-backend = "hatchling.build"
|
||||||
|
|
||||||
|
[dependency-groups]
|
||||||
|
dev = ["dunamai>=1.24.1", "ipdb>=0.13.13"]
|
||||||
|
|
||||||
|
[tool.hatch.build.targets.wheel]
|
||||||
|
packages = ["src/knoc_plugin_template"]
|
||||||
|
|
||||||
|
[tool.hatch.version]
|
||||||
|
source = "uv-dynamic-versioning"
|
||||||
|
|
||||||
|
[tool.uv-dynamic-versioning]
|
||||||
|
style = "semver"
|
||||||
|
|
||||||
|
[project.entry-points."knoc.settings"]
|
||||||
|
plugin_template = "knoc_plugin_template.settings:PluginTemplateSettings"
|
||||||
|
|
||||||
|
[project.entry-points."knoc.api"]
|
||||||
|
plugin_template = "knoc_plugin_template.api:app"
|
||||||
|
|
||||||
|
[project.entry-points."knoc.cli"]
|
||||||
|
plugin_template = "knoc_plugin_template.cli:app"
|
||||||
|
|
||||||
|
[project.entry-points."knoc.workflow"]
|
||||||
|
plugin_template = "knoc_plugin_template.workflows:do_nothing_wf"
|
10
src/knoc_plugin_template/__init__.py
Normal file
10
src/knoc_plugin_template/__init__.py
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import importlib.metadata
|
||||||
|
|
||||||
|
try:
|
||||||
|
from dunamai import Version, Style
|
||||||
|
|
||||||
|
__version__ = Version.from_git().serialize(style=Style.SemVer, dirty=True)
|
||||||
|
except ImportError:
|
||||||
|
# __name__ can be used if the package name is the same
|
||||||
|
# as the directory. Otherwise, specify it explicitely.
|
||||||
|
__version__ = importlib.metadata.version(__name__)
|
39
src/knoc_plugin_template/api.py
Normal file
39
src/knoc_plugin_template/api.py
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
from typing import Annotated
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from fastapi import (
|
||||||
|
FastAPI,
|
||||||
|
Depends,
|
||||||
|
HTTPException,
|
||||||
|
status,
|
||||||
|
)
|
||||||
|
from fastapi.responses import FileResponse, HTMLResponse
|
||||||
|
from pydantic import BaseModel
|
||||||
|
from sqlalchemy.sql.base import ExecutableOption
|
||||||
|
from sqlalchemy.exc import NoResultFound
|
||||||
|
from sqlmodel import select
|
||||||
|
from sqlmodel.ext.asyncio.session import AsyncSession
|
||||||
|
from hatchet_sdk.runnables.types import EmptyModel
|
||||||
|
|
||||||
|
from knoc.settings import settings
|
||||||
|
from knoc.workflows import all_wfs
|
||||||
|
from knoc.workflows.utils import ImportReport
|
||||||
|
from knoc.db import engine, aio_sql_to_df, get_session
|
||||||
|
|
||||||
|
from knoc_plugin_template.workflows import SimpleOutput, do_nothing_wf
|
||||||
|
|
||||||
|
logger = logging.getLogger("knoc-plugin-template.api")
|
||||||
|
|
||||||
|
|
||||||
|
app = FastAPI()
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/")
|
||||||
|
async def template_api_home() -> HTMLResponse:
|
||||||
|
return HTMLResponse("<p>Plugin template home</p>")
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/run_wf")
|
||||||
|
async def template_api_execute_wf() -> dict[str, SimpleOutput]:
|
||||||
|
result = await do_nothing_wf.aio_run(EmptyModel())
|
||||||
|
return result
|
24
src/knoc_plugin_template/cli.py
Normal file
24
src/knoc_plugin_template/cli.py
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
from hatchet_sdk.runnables.types import EmptyModel
|
||||||
|
import typer
|
||||||
|
from knoc.settings import settings
|
||||||
|
|
||||||
|
from knoc_plugin_template.workflows import do_nothing_wf, SimpleOutput
|
||||||
|
|
||||||
|
app = typer.Typer(no_args_is_help=True)
|
||||||
|
|
||||||
|
|
||||||
|
@app.command()
|
||||||
|
def do_nothing():
|
||||||
|
"""A CLI command that does very litle"""
|
||||||
|
typer.echo("Just a template of a CLI command.")
|
||||||
|
typer.echo(
|
||||||
|
f"The plugin has a setting, which is: {settings.plugin_template.setting}."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@app.command()
|
||||||
|
def run_wf():
|
||||||
|
"""A CLI command that runs a workflow"""
|
||||||
|
typer.echo("Just a template of a CLI command that runs a workflow.")
|
||||||
|
typer.echo("Requesting the workflow to tun...")
|
||||||
|
typer.echo(do_nothing_wf.run(EmptyModel()))
|
5
src/knoc_plugin_template/settings.py
Normal file
5
src/knoc_plugin_template/settings.py
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
|
||||||
|
class PluginTemplateSettings(BaseModel):
|
||||||
|
setting: str | None = None
|
24
src/knoc_plugin_template/workflows.py
Normal file
24
src/knoc_plugin_template/workflows.py
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
from datetime import datetime
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
from hatchet_sdk import Context, EmptyModel
|
||||||
|
|
||||||
|
from knoc_plugin_template import __version__
|
||||||
|
from knoc.settings import settings
|
||||||
|
from knoc.hatchet_client import hatchet
|
||||||
|
|
||||||
|
|
||||||
|
class SimpleOutput(BaseModel):
|
||||||
|
message: str
|
||||||
|
|
||||||
|
|
||||||
|
do_nothing_wf = hatchet.workflow(
|
||||||
|
name="Do-nothing-wf",
|
||||||
|
version=__version__,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@do_nothing_wf.task()
|
||||||
|
async def do_nothing(input: EmptyModel, ctx: Context) -> SimpleOutput:
|
||||||
|
ctx.log("Just a workflow template")
|
||||||
|
return SimpleOutput(message=f"Foo v{__version__} at {datetime.now()}")
|
Loading…
Add table
Add a link
Reference in a new issue