From 68c06e2ef8e177727f35a8653e6022b647372edd Mon Sep 17 00:00:00 2001 From: lufire Date: Mon, 12 Jan 2026 14:20:36 +0000 Subject: [PATCH] chore: accept new Cruft update --- .cruft.json | 5 +-- .vscode/settings.json | 2 +- pyproject.toml | 27 ++++++++++++++-- requirements_docs.txt | 4 --- .../actions/__init__.py | 3 ++ .../actions/simple_action/__init__.py | 30 +++++++++++++++++ .../actions/simple_action/activities.py | 8 +++++ .../actions/simple_action/models.py | 15 +++++++++ .../actions/simple_action/workflows.py | 24 ++++++++++++++ tests/actions/test_action.py | 32 +++++++++++++++++++ 10 files changed, 140 insertions(+), 10 deletions(-) delete mode 100644 requirements_docs.txt create mode 100644 src/nomad_plugin_parser_example/actions/__init__.py create mode 100644 src/nomad_plugin_parser_example/actions/simple_action/__init__.py create mode 100644 src/nomad_plugin_parser_example/actions/simple_action/activities.py create mode 100644 src/nomad_plugin_parser_example/actions/simple_action/models.py create mode 100644 src/nomad_plugin_parser_example/actions/simple_action/workflows.py create mode 100644 tests/actions/test_action.py diff --git a/.cruft.json b/.cruft.json index 36a8136..a0836d5 100644 --- a/.cruft.json +++ b/.cruft.json @@ -1,6 +1,6 @@ { "template": "https://github.com/FAIRmat-NFDI/cookiecutter-nomad-plugin", - "commit": "d306850507a46af96b5ab71129582655ce534c86", + "commit": "7bfd556fe5c57f6ad5666fe65eed2cf3672f5719", "checkout": null, "context": { "cookiecutter": { @@ -17,11 +17,12 @@ "include_parser": true, "include_app": false, "include_example_uploads": true, + "include_action": true, "_copy_without_render": [ "*.html" ], "_template": "https://github.com/FAIRmat-NFDI/cookiecutter-nomad-plugin", - "_commit": "d306850507a46af96b5ab71129582655ce534c86" + "_commit": "7bfd556fe5c57f6ad5666fe65eed2cf3672f5719" } }, "directory": null diff --git a/.vscode/settings.json b/.vscode/settings.json index 0c8648f..4f6a41e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,6 @@ { "editor.rulers": [ - 90 + 88 ], "editor.renderWhitespace": "all", "editor.tabSize": 4, diff --git a/pyproject.toml b/pyproject.toml index 05659a3..00437f4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,16 +25,31 @@ maintainers = [ ] license = { file = "LICENSE" } dependencies = [ - "nomad-lab>=1.3.0", - "python-magic-bin; sys_platform == 'win32'", + "nomad-lab>=1.4.0", + "pydantic", + "temporalio", ] [project.urls] Repository = "https://github.com/ZBT-Tools/nomad_plugin_parser_example" [project.optional-dependencies] -dev = ["ruff", "pytest", "structlog"] +dev = [ + "ruff", + "pytest", + "structlog", + "mkdocs", + "mkdocs-material==8.1.1", + "pymdown-extensions", + "mkdocs-click", + "pytest-asyncio", +] +[tool.uv] +extra-index-url = [ + "https://gitlab.mpcdf.mpg.de/api/v4/projects/2187/packages/pypi/simple", +] + [tool.ruff] # Exclude a variety of commonly ignored directories. exclude = [ @@ -82,6 +97,8 @@ select = [ ignore = [ "F403", # 'from module import *' used; unable to detect undefined names + "PLC0415", # `import` should be at the top-level of a file + "E501", # line too long ] fixable = ["ALL"] @@ -89,6 +106,9 @@ fixable = ["ALL"] # Allow unused variables when underscore-prefixed. dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" +[tool.ruff.lint.per-file-ignores] +"__init__.py" = ["PLC0415"] # import-outside-top-level + # this is entirely optional, you can remove this if you wish to [tool.ruff.format] # use single quotes for strings. @@ -115,6 +135,7 @@ schema_package_entry_point = "nomad_plugin_parser_example.schema_packages:schema example_upload_entry_point = "nomad_plugin_parser_example.example_uploads:example_upload_entry_point" +action_entry_point = "nomad_plugin_parser_example.actions:simple_action_entry_point" [tool.cruft] # Avoid updating workflow files, this leads to permissions issues skip = [".github/*"] diff --git a/requirements_docs.txt b/requirements_docs.txt deleted file mode 100644 index bacf1ed..0000000 --- a/requirements_docs.txt +++ /dev/null @@ -1,4 +0,0 @@ -mkdocs -mkdocs-material==8.1.1 -pymdown-extensions -mkdocs-click diff --git a/src/nomad_plugin_parser_example/actions/__init__.py b/src/nomad_plugin_parser_example/actions/__init__.py new file mode 100644 index 0000000..b262ee7 --- /dev/null +++ b/src/nomad_plugin_parser_example/actions/__init__.py @@ -0,0 +1,3 @@ +from nomad_plugin_parser_example.actions.simple_action import simple_action_entry_point + +__all__ = ['simple_action_entry_point'] diff --git a/src/nomad_plugin_parser_example/actions/simple_action/__init__.py b/src/nomad_plugin_parser_example/actions/simple_action/__init__.py new file mode 100644 index 0000000..1afe24c --- /dev/null +++ b/src/nomad_plugin_parser_example/actions/simple_action/__init__.py @@ -0,0 +1,30 @@ +from nomad.actions import TaskQueue +from pydantic import Field +from temporalio import workflow + +with workflow.unsafe.imports_passed_through(): + from nomad.config.models.plugins import ActionEntryPoint + + +class SimpleActionEntryPoint(ActionEntryPoint): + task_queue: str = Field( + default=TaskQueue.CPU, description='Determines the task queue for this action' + ) + + def load(self): + from nomad.actions import Action + + from nomad_plugin_parser_example.actions.simple_action.activities import greet + from nomad_plugin_parser_example.actions.simple_action.workflows import SimpleWorkflow + + return Action( + task_queue=self.task_queue, + workflow=SimpleWorkflow, + activities=[greet], + ) + + +simple_action_entry_point = SimpleActionEntryPoint( + name='SimpleAction', + description='A simple action that returns a greeting.', +) diff --git a/src/nomad_plugin_parser_example/actions/simple_action/activities.py b/src/nomad_plugin_parser_example/actions/simple_action/activities.py new file mode 100644 index 0000000..a9053ab --- /dev/null +++ b/src/nomad_plugin_parser_example/actions/simple_action/activities.py @@ -0,0 +1,8 @@ +from temporalio import activity + +from nomad_plugin_parser_example.actions.simple_action.models import SimpleWorkflowInput + + +@activity.defn +async def greet(data: SimpleWorkflowInput) -> str: + return f'hello {data.name} - created by user {data.user_id} for upload {data.upload_id}' diff --git a/src/nomad_plugin_parser_example/actions/simple_action/models.py b/src/nomad_plugin_parser_example/actions/simple_action/models.py new file mode 100644 index 0000000..fa5dea4 --- /dev/null +++ b/src/nomad_plugin_parser_example/actions/simple_action/models.py @@ -0,0 +1,15 @@ +from pydantic import BaseModel, Field + + +class SimpleWorkflowInput(BaseModel): + """Input model for the simple workflow""" + + upload_id: str = Field( + ..., + description='Unique identifier for the upload associated with the workflow.', + ) + user_id: str = Field( + ..., description='Unique identifier for the user who initiated the workflow.' + ) + + name: str = Field(..., description='The name to greet.') diff --git a/src/nomad_plugin_parser_example/actions/simple_action/workflows.py b/src/nomad_plugin_parser_example/actions/simple_action/workflows.py new file mode 100644 index 0000000..578ed56 --- /dev/null +++ b/src/nomad_plugin_parser_example/actions/simple_action/workflows.py @@ -0,0 +1,24 @@ +from datetime import timedelta + +from temporalio import workflow +from temporalio.common import RetryPolicy + +with workflow.unsafe.imports_passed_through(): + from nomad_plugin_parser_example.actions.simple_action.activities import greet + from nomad_plugin_parser_example.actions.simple_action.models import SimpleWorkflowInput + + +@workflow.defn +class SimpleWorkflow: + @workflow.run + async def run(self, data: SimpleWorkflowInput) -> str: + retry_policy = RetryPolicy( + maximum_attempts=3, + ) + result = await workflow.execute_activity( + greet, + data, + start_to_close_timeout=timedelta(seconds=60), + retry_policy=retry_policy, + ) + return result diff --git a/tests/actions/test_action.py b/tests/actions/test_action.py new file mode 100644 index 0000000..8168098 --- /dev/null +++ b/tests/actions/test_action.py @@ -0,0 +1,32 @@ +import pytest +from temporalio.testing import WorkflowEnvironment +from temporalio.worker import Worker + +from nomad_plugin_parser_example.actions.simple_action.activities import greet +from nomad_plugin_parser_example.actions.simple_action.models import SimpleWorkflowInput +from nomad_plugin_parser_example.actions.simple_action.workflows import SimpleWorkflow + + +@pytest.mark.asyncio +async def test_simple_workflow(): + task_queue = 'test-simple-workflow' + async with await WorkflowEnvironment.start_local() as env: + async with Worker( + env.client, + task_queue=task_queue, + workflows=[SimpleWorkflow], + activities=[greet], + ): + result = await env.client.execute_workflow( + SimpleWorkflow.run, + SimpleWorkflowInput( + upload_id='upload_id', + user_id='user_id', + name='World', + ), + id='test-workflow', + task_queue=task_queue, + ) + assert ( + result == 'hello World - created by user user_id for upload upload_id' + )