# Worker

This module provides the `Worker` class, a convenience wrapper around the underlying Temporal worker (`temporalio.worker.Worker`). Its primary role is to host and execute your workflow and activity code, listening for tasks on a specific Temporal task queue.

## Purpose and Role

In the Temporal architecture, Workflows and Activities are just definitions. A **Worker Process** is needed to actually execute that code when the Temporal service assigns it tasks. The `application_sdk.worker.Worker` class simplifies the setup and running of this worker process within the context of the Application SDK.

It connects to Temporal (via a `WorkflowClient`), registers the specific workflow definitions and activity implementations it's responsible for, and then starts polling its assigned task queue for work.

## Initialization

You create an instance of the `Worker` class, providing the necessary components:

```python
from application_sdk.worker import Worker
from application_sdk.clients.workflow import WorkflowClient # Typically TemporalWorkflowClient
from application_sdk.workflows import WorkflowInterface # Your workflow class(es) inherit from this
from application_sdk.activities import ActivitiesInterface # Your activities class(es) inherit from this

# Assume:
# - workflow_client: An initialized and connected TemporalWorkflowClient instance
# - MyWorkflow: Your workflow class inheriting from WorkflowInterface
# - MyActivities: Your activities class inheriting from ActivitiesInterface
# - my_activities_instance: An instance of MyActivities(...)

worker = Worker(
    workflow_client=workflow_client,
    workflow_classes=[MyWorkflow],
    workflow_activities=MyWorkflow.get_activities(my_activities_instance),
    # Optional parameters below
    # passthrough_modules=["my_custom_module"],
    # max_concurrent_activities=10
)
```

**Parameters:**

*   **`workflow_client` (WorkflowClient):** *Required.* An instance of `TemporalWorkflowClient` (obtained via `get_workflow_client` and already connected using `await workflow_client.load()`). The worker uses this client to communicate with the Temporal cluster and uses the client's configured `application_name` to determine which `task_queue` to listen on.
*   **`workflow_classes` (Sequence[ClassType]):** *Required.* A list containing the workflow **class definitions** (subclasses of `WorkflowInterface`) that this worker process is capable of executing. Example: `[MyMetadataWorkflow, MyReportingWorkflow]`.
*   **`workflow_activities` (Sequence[CallableType]):** *Required.* A list of the specific **callable activity methods** that this worker process should execute.
    *   **Crucial Link:** This list is typically generated by calling the static `get_activities()` method of a *workflow class*, passing in an *instance* of the corresponding *activities class*. This links the abstract workflow definition to the concrete activity implementations. Example: `MyMetadataWorkflow.get_activities(my_metadata_activities_instance)`.
*   **`passthrough_modules` (List[str], optional):** A list of module names that should be accessible within the Temporal sandbox environment where workflows run. Defaults include `"application_sdk"`, `"pandas"`, `"os"`, `"app"`. Add other modules if your workflow code directly imports them.
*   **`max_concurrent_activities` (int, optional):** Limits the number of activities this worker will execute concurrently. Defaults to `None` (no limit imposed by this SDK, though Temporal may have server-side limits).

## Starting the Worker

Once initialized, you start the worker using the `start` method:

```python
await worker.start(daemon=True)
# or
# await worker.start(daemon=False)
```

**Parameters:**

*   **`daemon` (bool):**
    *   `True` (Default): Starts the worker in a separate background daemon thread. The `await worker.start()` call returns immediately, allowing your main application (like a FastAPI server) to continue running. This is the typical mode when running alongside a web application.
    *   `False`: Starts the worker in the current thread. The `await worker.start()` call will block indefinitely until the worker is interrupted (e.g., by Ctrl+C). This is useful for standalone worker processes or debugging.

## Configuration and Extensibility

The `Worker` class itself is generally not subclassed. Its configuration and the behavior it exhibits are determined entirely by the parameters passed during initialization:

*   **Which workflows/activities run:** Defined by `workflow_classes` and `workflow_activities`.
*   **Which task queue is polled:** Determined by the `application_name` configured in the `workflow_client`.
*   **Concurrency:** Controlled by `max_concurrent_activities`.

## Example Context (Simplified Application Setup)

```python
import asyncio
# Absolute imports
from application_sdk.worker import Worker
from application_sdk.clients.utils import get_workflow_client
# Assuming definitions exist in my_connector package
from my_connector.workflows import MyConnectorWorkflow
from my_connector.activities import MyConnectorActivities
from my_connector.clients import MyConnectorSQLClient
from my_connector.handlers import MyConnectorHandler

async def main():
    # 1. Initialize and connect the Workflow Client
    # Task queue will be 'my-connector-task-queue'
    workflow_client = get_workflow_client(application_name="my-connector-task-queue")
    await workflow_client.load()

    # 2. Instantiate Activities (which might need client/handler classes)
    # The specific arguments depend on your Activities.__init__
    activities_instance = MyConnectorActivities(
        sql_client_class=MyConnectorSQLClient,
        handler_class=MyConnectorHandler
        # transformer_class=... (if applicable)
    )

    # 3. Instantiate the Worker
    worker = Worker(
        workflow_client=workflow_client,
        # Tell the worker which workflow definitions it knows
        workflow_classes=[MyConnectorWorkflow],
        # Tell the worker which activity methods to run, linking the workflow
        # definition to the specific activity implementations via get_activities
        workflow_activities=MyConnectorWorkflow.get_activities(activities_instance),
        max_concurrent_activities=5 # Example limit
    )

    # 4. Start the Worker (e.g., in the background)
    # This will start listening on 'my-connector-task-queue'
    await worker.start(daemon=True)

    print("Worker started in background. Main application can continue...")
    # Keep the main process alive if needed (e.g., if not running a web server)
    await asyncio.sleep(3600) # Keep alive for an hour in this example

if __name__ == "__main__":
    asyncio.run(main())
```

## Summary

The `application_sdk.worker.Worker` class is the runtime host for executing workflows and activities defined using the SDK. It's configured with the specific workflow definitions and activity implementations it should run, connects to Temporal via a `WorkflowClient`, and listens on a designated task queue. It's typically started in daemon mode when integrated into a larger application.