{"id":9432,"library":"acryl-executor","title":"Acryl Executor","description":"Acryl Executor is a Python library used internally by Acryl Agents and the DataHub ecosystem to define and execute modular tasks. It provides core abstractions like `BaseTask` and `Executor` for building extensible task-based workflows. As a sub-package of the larger DataHub project, its releases are often coupled with DataHub's evolution, though its own versioning is independent. The current version is 0.3.10, and it follows an active release cadence driven by DataHub development.","status":"active","version":"0.3.10","language":"en","source_language":"en","source_url":"https://github.com/datahub-project/datahub","tags":["datahub","executor","tasks","agents","workflow","pydantic"],"install":[{"cmd":"pip install acryl-executor","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Used for data validation and settings management within tasks.","package":"pydantic","optional":false}],"imports":[{"note":"The top-level package is `acryl`, not `acryl_executor`, despite the PyPI package name containing a hyphen.","wrong":"from acryl_executor.sdk.tasks.base_task import BaseTask","symbol":"BaseTask","correct":"from acryl.executor.sdk.tasks.base_task import BaseTask"},{"symbol":"TaskResult","correct":"from acryl.executor.sdk.tasks.base_task import TaskResult"},{"note":"The top-level package is `acryl`, not `acryl_executor`, despite the PyPI package name containing a hyphen.","wrong":"from acryl_executor.sdk.executor import Executor","symbol":"Executor","correct":"from acryl.executor.sdk.executor import Executor"}],"quickstart":{"code":"import os\nfrom typing import Dict, Any, NamedTuple\nfrom abc import ABC, abstractmethod\n\nfrom acryl.executor.sdk.tasks.base_task import BaseTask, TaskResult\nfrom acryl.executor.sdk.executor import Executor\n\n\nclass MySimpleTaskResult(NamedTuple):\n    status: str\n    message: str\n\n\nclass MySimpleTask(BaseTask):\n    def execute(self, config: Dict[str, Any]) -> MySimpleTaskResult:\n        name = config.get('name', 'World')\n        # Example of using an environment variable for configuration (e.g., for API keys)\n        secret_key = os.environ.get('MY_SECRET_KEY', 'default_secret')\n        print(f\"Executing MySimpleTask for {name} with secret: {secret_key[:4]}...\")\n        return MySimpleTaskResult(status='SUCCESS', message=f'Hello, {name}!')\n\n# Configure with actual environment variable or a placeholder for quick run\nos.environ['MY_SECRET_KEY'] = os.environ.get('MY_SECRET_KEY', 'some_default_value_for_testing')\n\n# 1. Instantiate the Executor\nexecutor = Executor()\n\n# 2. Define a task instance\nmy_task = MySimpleTask()\n\n# 3. Define task configuration\ntask_config = {\"name\": \"DataHub User\"}\n\n# 4. Execute the task\nprint(\"\\n--- Executing MySimpleTask ---\")\nresult = executor.execute_task(my_task, task_config)\n\nprint(f\"Task Result: {result.status}, Message: {result.message}\")\n\n# Example with different config\ntask_config_2 = {\"name\": \"Acryl Team\"}\nprint(\"\\n--- Executing MySimpleTask with different config ---\")\nresult_2 = executor.execute_task(my_task, task_config_2)\nprint(f\"Task Result: {result_2.status}, Message: {result_2.message}\")\n","lang":"python","description":"This quickstart demonstrates how to define a custom task by inheriting from `BaseTask`, implement its `execute` method, and then run it using the `Executor`. It shows how to pass configuration to the task and retrieve results. The example also illustrates how to safely access environment variables for sensitive data."},"warnings":[{"fix":"Always pin to exact versions (e.g., `acryl-executor==0.3.10`) and review DataHub's main release notes for related changes when upgrading. Be prepared to adapt custom task implementations.","message":"Acryl Executor is primarily an internal library for the DataHub ecosystem. While available on PyPI, its public API (especially pre-1.0 versions like 0.x.x) may evolve rapidly with breaking changes that are not always explicitly documented for `acryl-executor` itself, but rather as part of broader DataHub releases.","severity":"gotcha","affected_versions":"<1.0.0"},{"fix":"Thoroughly test custom tasks against new `acryl-executor` versions before deploying. Consult the DataHub GitHub repository commit history for `acryl-executor` changes if experiencing unexpected behavior after an upgrade.","message":"Given `acryl-executor` is in its 0.x.x series, changes to `BaseTask` method signatures or `TaskResult` structure might occur in minor versions (e.g., `0.3.10` to `0.4.0`) without adhering to strict semantic versioning. This means a minor version bump could introduce breaking changes.","severity":"breaking","affected_versions":"<1.0.0"},{"fix":"For production scenarios requiring async or background execution, integrate `acryl-executor` within a suitable task runner like `datahub-actions` or a custom worker pool. Do not assume `Executor` handles concurrency internally.","message":"The `Executor` provides synchronous task execution by default. For long-running or asynchronous tasks, `acryl-executor` is typically integrated with an external orchestration layer (e.g., DataHub Actions framework), which handles queuing, scheduling, and concurrency. Running `executor.execute_task()` directly will block the calling thread.","severity":"gotcha","affected_versions":"All"}],"env_vars":null,"last_verified":"2026-04-17T00:00:00.000Z","next_check":"2026-07-16T00:00:00.000Z","problems":[{"fix":"Ensure your custom task class includes a definition for `def execute(self, config: Dict[str, Any]) -> TaskResult: ...` with the correct signature and return type.","cause":"A class inheriting from `acryl.executor.sdk.tasks.base_task.BaseTask` must implement the `execute` method as defined in the abstract base class.","error":"TypeError: Can't instantiate abstract class MySimpleTask with abstract method execute"},{"fix":"Run `pip install acryl-executor`. Verify all imports use `from acryl.executor...`.","cause":"The `acryl-executor` library is not installed, or the import path is incorrect (e.g., trying `acryl_executor` instead of `acryl`).","error":"ModuleNotFoundError: No module named 'acryl.executor.sdk'"},{"fix":"Ensure you call `executor.execute_task(my_task_instance, {'key': 'value'})` providing a dictionary for task configuration, even if it's an empty dictionary.","cause":"The `execute_task` method on `Executor` expects two arguments: a `BaseTask` instance and a `config` dictionary.","error":"TypeError: execute_task() missing 1 required positional argument: 'config'"}]}