Introduction

The cookie-cutter-kodexa-event-model is a project template that helps you quickly set up a new Kodexa event model with the right structure and dependencies. Event models in Kodexa allow you to handle and respond to specific events that occur within the Kodexa platform, providing a way to build custom event-driven functionality.

This documentation will guide you through:

  • Installing the prerequisites
  • Creating a new project from the template
  • Understanding the project structure
  • Setting up your development environment in VS Code
  • Example usage scenarios

Prerequisites

Before using this cookiecutter template, ensure you have the following installed:

  1. Python 3.11+: The template is designed to work with Python 3.11 or higher
  2. Cookiecutter: The templating tool that will create your project
  3. Git: For version control
  4. Visual Studio Code: For development (recommended)
  5. Poetry: For dependency management
  6. Kodexa CLI: For deploying models to Kodexa platform

Installing Required Tools

You can install the required tools using pip:

# Install cookiecutter
pip install cookiecutter

# Install poetry
pip install poetry

# Install Kodexa CLI
pip install kodexa-cli

Creating a New Project

Once you have the prerequisites installed, you can create a new project from the template by running:

cookiecutter https://github.com/kodexa-labs/cookie-cutter-kodexa-event-model.git

You’ll be prompted to provide several configuration values defined in the cookiecutter.json file:

project_name [My Kodexa Event Model]: Document Change Handler
project_slug [document-change-handler]: 
pkg_name [document_change_handler]: 
project_short_description [Skeleton project created by Cookiecutter Kodexa Event Model]: A model that responds to document change events
full_name [Kodexa Support]: Jane Smith
email [support@kodexa.com]: jane.smith@example.com
github_username [kodexa-ai]: janesmith
version [0.1.0]: 
org_slug [my-org]: janes-org

These values will be used to customize your project. Here’s what each prompt means:

  • project_name: The human-readable name of your project
  • project_slug: The slug for your model (automatically derived from project_name)
  • pkg_name: The Python package name (automatically derived from project_name)
  • project_short_description: A short description of what your model does
  • full_name: Your name or your organization’s name
  • email: Contact email for the project
  • github_username: Your GitHub username or organization
  • version: The initial version of your model
  • org_slug: The Kodexa organization slug where your model will be hosted

Project Structure

After running the cookiecutter command, a new directory with your project_slug name will be created with the following structure:

document-change-handler/               # Root directory (project_slug)
├── document_change_handler/           # Python package (pkg_name)
│   ├── __init__.py                    # Package initialization
│   └── model.py                       # Main model implementation with event handler
├── .editorconfig                      # Editor configuration
├── .gitignore                         # Git ignore file
├── makefile                           # Makefile with common tasks
├── model.yml                          # Kodexa model deployment configuration
├── pyproject.toml                     # Poetry project configuration
└── README.md                          # Project readme

Key Files

model.py

This is the main file where you’ll implement your event handler. It comes with a basic implementation of the handle_event function that receives events from the Kodexa platform:

def handle_event(event: BaseEvent):
    logger.info(f"Handle event called with event: {event.type}")

You’ll need to modify this function to handle specific event types and implement your business logic.

model.yml

This file defines how your model will be deployed to the Kodexa platform, including:

slug: {{cookiecutter.project_slug}}
orgSlug: {{cookiecutter.org_slug}}
version: 1.0.0
type: store
storeType: MODEL
publicAccess: true
name: {{cookiecutter.project_name}}
description: {{cookiecutter.project_short_description}}
metadata:
  trainable: false
  inferable: false
  eventAware: true
  type: model
  provider: {{ cookiecutter.github_username }}
  providerUrl: https://github.com/{{ cookiecutter.github_username }}/{{ cookiecutter.project_slug }}
  modelRuntimeRef: kodexa/base-model-runtime
  modelRuntimeParameters:
    module: {{ cookiecutter.pkg_name }}
  contents:
    - {{ cookiecutter.pkg_name }}/*.py

Note the eventAware: true property, which indicates that this model can handle events.

pyproject.toml

This file contains your project’s metadata and dependencies managed by Poetry, including:

  • Project information
  • Python version requirements
  • Dependencies (including Kodexa)
  • Development tools configuration (black, isort, flake8, mypy)

makefile

The makefile includes several useful commands:

  • make format: Format code using isort and black
  • make lint: Lint code using flake8 and mypy
  • make test: Run formatting and linting
  • make clean: Clean up build artifacts
  • make deploy: Deploy the model to Kodexa platform
  • make undeploy: Undeploy the model from Kodexa platform

Setting Up in Visual Studio Code

To set up your new project in Visual Studio Code:

  1. Open VS Code
  2. Choose “File > Open Folder” and select your newly created project directory
  3. Open a terminal in VS Code (Terminal > New Terminal)
  4. Install dependencies using Poetry:
    poetry install
    
  5. Activate the Poetry virtual environment:
    poetry shell
    

For the best development experience, install these VS Code extensions:

  1. Python: The official Python extension
  2. Pylance: Enhanced language support for Python
  3. YAML: For editing YAML files like model.yml
  4. Docker: For containerization if needed
  5. Markdown All in One: For editing documentation

Understanding Event Models

In Kodexa, event models are used to handle specific events that occur within the platform. Events can be related to documents, users, projects, and more. Event models allow you to build custom logic that responds to these events.

Common Event Types

While you’ll need to refer to the Kodexa documentation for a complete list of available events, here are some common event types:

  • Content Events: The structure, labels, or metadata of a document has changed
  • Document Family Events: The metadata of a document family has changed
  • Scheduled Events: A scheduled event has been triggered

The Event Handler

The main entry point for your event model is the handle_event function in model.py. This function receives a BaseEvent object that contains information about the event, including:

  • event.type: The type of event

There are several types of events that you can handle, including:

  • ContentEvent: A document has been created, updated, or deleted (this means the content of the document has changed)
  • DocumentFamilyEvent: A document family has been created, updated, or deleted
  • TaskEvent: A task has been created, updated, or deleted
  • DataObjectEvent: A data object has been created, updated, or deleted
  • AssistantEvent: An assistant has been created, updated, or deleted
  • ChannelEvent: A channel has been created, updated, or deleted
  • WorkspaceEvent: A workspace has been created, updated, or deleted
  • DataFormEvent: A data form has been created, updated, or deleted
  • OrchestrationEvent: An orchestration has been created, updated, or deleted
  • ScheduledEvent: A scheduled event has been triggered

Your task is to implement the logic that should run when specific events are received.

Implementing Your Event Handler

Here’s how to implement an event handler for document changes:

from kodexa import ContentEvent, KodexaClient

import logging
import requests
from kodexa.model.objects import BaseEvent, DocumentFamily

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

def handle_event(event: BaseEvent):
    """
    Handle events from the Kodexa platform.
    
    Args:
        event: The event to handle
    """
    logger.info(f"Received event: {event.type}")
    
    # Check if this is a event event
    if isinstance(event, ContentEvent):
        logger.info(f"Received content object: {event.content_object}")
        logger.info(f"Received document family: {event.document_family}")


Deploying Your Event Model

When your event model is ready, you can deploy it to the Kodexa platform:

make deploy

This will use the Kodexa CLI to deploy your model according to the configuration in model.yml.

Example: Building a Document Notification System

Let’s implement a more complete example of an event model that sends notifications when documents are processed:

from kodexa import ContentEvent, KodexaClient

import logging
import requests
from kodexa.model.objects import BaseEvent, DocumentFamily

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# Webhook URL for notifications (e.g., Slack, MS Teams)
WEBHOOK_URL = "https://hooks.slack.com/services/TXXXXXXXX/BXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX"

def handle_event(event: BaseEvent):
    """
    Handle events from the Kodexa platform.
    
    Args:
        event: The event to handle
    """
    logger.info(f"Received event: {event.type}")

    # Check if this is a document processing event
    if isinstance(event, ContentEvent):
        handle_document_processed(event)

def handle_document_processed(event: ContentEvent):
    """
    Handle document processed events
    
    Args:
        event: The document processed event
    """
    # Get event data
    document_family: DocumentFamily = event.document_family
    labels = event.document_family.labels

    logger.info(f"Document processed: {document_family.id} with status {document_family.document_status}")

    # Send notification
    send_notification(f"Document '{document_family.path}' was updated in store '{document_family.store_ref}' with status '{document_family.document_status}'.")

def send_notification(message):
    """
    Send a notification to the webhook
    
    Args:
        message: The message to send
    """
    payload = {"text": message}
    try:
        response = requests.post(WEBHOOK_URL, json=payload)
        response.raise_for_status()
        logger.info("Notification sent successfully")
    except Exception as e:
        logger.error(f"Failed to send notification: {e}")

Troubleshooting

Common Issues

”Module not found” errors

If you encounter module import errors, make sure:

  • Your Poetry environment is activated (poetry shell)
  • The package is installed in development mode (poetry install)
  • Your import statements use the correct package name

Deployment failures

If your model fails to deploy:

  • Check if your Kodexa CLI is configured correctly
  • Verify that the org_slug in model.yml is correct
  • Look for syntax errors in your Python code

Event handler not triggered

If your event handler isn’t being triggered:

  • Check if your model is subscribed to the correct event type
  • Verify that the event source is generating events
  • Check the logs in the Kodexa platform for error messages