Skip to main content

A comprehensive Python SDK for interacting with the Tallyfy API

Project description

Tallyfy SDK

A comprehensive Python SDK for interacting with the Tallyfy API. This SDK provides a clean, modular interface for managing users, tasks, templates, and form fields in your Tallyfy organization.

Table of Contents

Installation

pip install tallyfy

Dependencies:

  • requests - HTTP client library
  • typing - Type hints support (Python 3.5+)

Quick Start

from tallyfy import TallyfySDK

# Initialize the SDK
sdk = TallyfySDK(
    api_key="your_api_key_here"
)

# Get organization users
users = sdk.users.get_organization_users(org_id="your_org_id")

# Get current user's tasks
my_tasks = sdk.tasks.get_my_tasks(org_id="your_org_id")

# Search for templates
templates = sdk.search(org_id="your_org_id", search_query="onboarding", search_type="blueprint")

# Get a specific template
template = sdk.templates.get_template(org_id="your_org_id", template_name="Employee Onboarding")

Architecture

The Tallyfy SDK follows a modular architecture with specialized management classes and comprehensive data models:

Core Components

  • TallyfySDK - Main SDK class that orchestrates all operations with backward compatibility methods
  • BaseSDK - Base class with HTTP request handling, retry logic, and connection pooling
  • Management Modules:
    • UserManager - User and guest operations with modular retrieval and invitation components
    • TaskManager - Task and process operations with search and creation capabilities
    • TemplateManager - Template/checklist operations with automation analysis and health assessment
    • FormFieldManager - Form field operations with AI-powered suggestions and dropdown management
  • Error Handling:
    • TallyfyError - Custom exception handling with status codes and response data

File Structure

tallyfy/
├── __init__.py                        # SDK exports and version
├── core.py                            # BaseSDK and TallyfySDK classes
├── models.py                          # Data models and types
├── user_management/                   # User and guest management (modular)
│   ├── __init__.py                    # UserManager with unified interface
│   ├── base.py                        # Common validation and error handling
│   ├── retrieval.py                   # User and guest retrieval operations
│   └── invitation.py                  # User invitation operations
├── task_management/                   # Task and process management (modular)
│   ├── __init__.py                    # TaskManager with unified interface
│   ├── base.py                        # Common task operations base
│   ├── retrieval.py                   # Task and process retrieval
│   ├── search.py                      # Search functionality
│   └── creation.py                    # Task creation operations
├── template_management/               # Template management (modular)
│   ├── __init__.py                    # TemplateManager with unified interface
│   ├── base.py                        # Common template operations
│   ├── basic_operations.py            # Template retrieval and CRUD operations
│   ├── automation.py                  # Automation rule management
│   ├── analysis.py                    # Template analysis and health checks
│   └── health_assessment.py           # Template health assessment functionality
├── form_fields_management/            # Form field management (modular)
│   ├── __init__.py                    # FormFieldManager with unified interface
│   ├── base.py                        # Common form field operations
│   ├── crud_operations.py             # CRUD operations for form fields
│   ├── options_management.py          # Dropdown options management
│   └── suggestions.py                 # AI-powered field suggestions
└── README.md                          # This documentation

Core Features

🔐 Authentication & Security

  • Bearer token authentication with session management
  • Configurable request timeouts and connection pooling
  • Automatic retry logic for transient failures (5xx errors)
  • No retry for client errors (4xx) to prevent API abuse
  • Comprehensive error handling with detailed error information

👥 User Management

  • Modular architecture with specialized retrieval and invitation components
  • Get organization members with full profile data (country, timezone, job details)
  • Get minimal user lists for performance-critical operations
  • Manage guests and external users with guest-specific features
  • Enhanced search capabilities - Find users by email or name with fuzzy matching
  • Batch invitation support - Invite multiple users with default roles and messages
  • Advanced invitation features - Custom messages, role validation, and resend functionality
  • Support for user groups and permissions with flexible query parameters
  • Convenience methods - Get all members (users + guests) in a single call

✅ Task Management

  • Get tasks for specific users or processes with filtering
  • Create standalone tasks with rich assignment options
  • Search processes by name with fuzzy matching
  • Advanced filtering for organization runs (status, owners, tags, etc.)
  • Universal search across processes, templates, and tasks

📋 Template Management

  • Get templates with full metadata and step details
  • Search templates by name with exact and fuzzy matching
  • Update template properties and metadata
  • Duplicate templates with permission copying options
  • Automation management - Create, update, and analyze conditional rules
  • Step dependency analysis - Understand step visibility conditions
  • AI-powered deadline suggestions for individual steps
  • Template health assessment - Comprehensive analysis of template quality
  • Automation consolidation - Optimize and merge redundant rules
  • Add assignees and edit step descriptions
  • Kickoff field management for template launch forms

📝 Form Field Management

  • Add form fields to template steps with comprehensive validation
  • Support for text, dropdown, date, file upload, WYSIWYG editor fields
  • Update field properties, validation rules, and positioning
  • Move fields between steps with automatic reordering
  • AI-powered field suggestions based on step analysis
  • Manage dropdown options with bulk updates
  • Smart field recommendations with confidence scoring
  • Field dependency management and conditional logic

🔍 Search & Discovery

  • Universal search across processes, templates, and tasks
  • Exact and fuzzy matching with relevance scoring
  • Pagination support with configurable page sizes
  • Rich search results with metadata and context
  • Process and template name-based search with suggestions

API Reference

SDK Initialization

TallyfySDK(
    api_key: str,
    timeout: int = 30,
    max_retries: int = 3,
    retry_delay: float = 1.0
)

User Management

# Get all organization users with optional group data
users = sdk.users.get_organization_users(org_id, with_groups=False)

# Get minimal user list for performance
users_list = sdk.users.get_organization_users_list(org_id)

# Get organization guests with optional statistics
guests = sdk.users.get_organization_guests(org_id, with_stats=False)

# Get current user info
current_user = sdk.users.get_current_user_info(org_id)

# Enhanced search capabilities
user = sdk.users.get_user_by_email(org_id, "john@company.com")
guest = sdk.users.get_guest_by_email(org_id, "contractor@company.com")

# Search members by name (fuzzy matching)
search_results = sdk.users.search_members_by_name(org_id, "John Smith", include_guests=True)
matching_users = search_results['users']
matching_guests = search_results['guests']

# Get all members in one call
all_members = sdk.users.get_all_organization_members(
    org_id, include_guests=True, with_groups=True, with_stats=True
)

# Invite single user to organization
user = sdk.users.invite_user_to_organization(
    org_id, email="new.hire@company.com", 
    first_name="John", last_name="Doe",
    role="standard", 
    message="Welcome! Please complete your onboarding process."
)

# Batch invite multiple users
invitations = [
    {
        "email": "user1@company.com",
        "first_name": "Jane",
        "last_name": "Smith",
        "role": "standard"
    },
    {
        "email": "user2@company.com", 
        "first_name": "Bob",
        "last_name": "Johnson",
        "message": "Welcome to the engineering team!"
    }
]
results = sdk.users.invite_multiple_users(
    org_id, invitations, 
    default_role="light",
    default_message="Welcome to our organization!"
)

# Resend invitation
success = sdk.users.resend_invitation(
    org_id, email="pending@company.com",
    message="Reminder: Please accept your invitation to join our organization."
)

# Generate custom invitation message
message = sdk.users.get_invitation_template_message(
    org_name="ACME Corp",
    custom_text="We're excited to have you join our innovative team!"
)

# Validate invitation data before sending
invitation_data = {
    "email": "new@company.com",
    "first_name": "Alice",
    "last_name": "Wilson",
    "role": "admin"
}
validated_data = sdk.users.validate_invitation_data(invitation_data)

# Access modular components directly (advanced usage)
# Retrieval operations
users_with_groups = sdk.users.retrieval.get_organization_users(org_id, with_groups=True)

# Invitation operations  
batch_results = sdk.users.invitation.invite_multiple_users(org_id, invitations)

Task Management

# Get current user's tasks
my_tasks = sdk.tasks.get_my_tasks(org_id)

# Get specific user's tasks
user_tasks = sdk.tasks.get_user_tasks(org_id, user_id)

# Get tasks for a process
process_tasks = sdk.tasks.get_tasks_for_process(org_id, process_id=None, process_name="My Process")

# Get organization processes with filtering
runs = sdk.tasks.get_organization_runs(
    org_id, 
    status="active",
    owners="123,456", 
    checklist_id="template_id"
)

# Create standalone task
task = sdk.tasks.create_task(
    org_id, title="Review Document", 
    deadline="2024-12-31T23:59:59Z",
    description="Please review the attached document"
)

# Search processes, templates, or tasks
results = sdk.tasks.search(org_id, "onboarding", search_type="process")

# Search for specific entity types
templates = sdk.tasks.search(org_id, "employee onboarding", search_type="blueprint")
tasks = sdk.tasks.search(org_id, "review", search_type="task")

Template Management

# Get template by ID or name
template = sdk.templates.get_template(org_id, template_id=None, template_name="Onboarding")

# Get template with full step details
template_data = sdk.templates.get_template_with_steps(org_id, template_id)

# Update template metadata
updated = sdk.templates.update_template_metadata(
    org_id, template_id,
    title="New Title",
    summary="Updated summary",
    guidance="New guidance text"
)

# Get template steps
steps = sdk.templates.get_template_steps(org_id, template_id)

# Analyze step dependencies  
dependencies = sdk.templates.get_step_dependencies(org_id, template_id, step_id)

# Get deadline suggestions
deadline_suggestion = sdk.templates.suggest_step_deadline(org_id, template_id, step_id)

# Advanced template operations
duplicated = sdk.templates.duplicate_template(org_id, template_id, "New Template Name", copy_permissions=True)

# Automation management
automation_data = {
    "automated_alias": "Auto-assign reviewer",
    "conditions": [{"field_id": "department", "operator": "equals", "value": "Engineering"}],
    "actions": [{"type": "assign_step", "step_id": "review_step", "assignee_type": "user", "assignee_id": "123"}]
}
automation = sdk.templates.create_automation_rule(org_id, template_id, automation_data)

# Analyze automation conflicts and redundancies
analysis = sdk.templates.analyze_template_automations(org_id, template_id)

# Get consolidation suggestions
suggestions = sdk.templates.suggest_automation_consolidation(org_id, template_id)

# Assess overall template health
health_report = sdk.templates.assess_template_health(org_id, template_id)

# Template metadata management
updated = sdk.templates.update_template_metadata(
    org_id, template_id,
    title="Updated Template Title",
    guidance="New guidance text",
    is_featured=True
)

# Add assignees to step
assignees = {"users": [123, 456], "groups": ["managers"], "guests": ["contractor@company.com"]}
sdk.templates.add_assignees_to_step(org_id, template_id, step_id, assignees)

# Edit step description
sdk.templates.edit_description_on_step(org_id, template_id, step_id, "Updated step description with detailed instructions")

# Add new step to template
step_data = {
    "title": "Quality Review",
    "description": "Perform final quality check",
    "position": 5,
    "assignees": {"users": [789]}
}
new_step = sdk.templates.add_step_to_template(org_id, template_id, step_data)

Form Field Management

# Add form field to step
field_data = {
    "field_type": "text",
    "label": "Customer Name", 
    "required": True,
    "position": 1
}
field = sdk.form_fields.add_form_field_to_step(org_id, template_id, step_id, field_data)

# Update form field
updated_field = sdk.form_fields.update_form_field(
    org_id, template_id, step_id, field_id,
    label="Updated Label",
    required=False
)

# Move field between steps
success = sdk.form_fields.move_form_field(
    org_id, template_id, from_step, field_id, to_step, position=2
)

# Delete form field
success = sdk.form_fields.delete_form_field(org_id, template_id, step_id, field_id)

# Get dropdown options
options = sdk.form_fields.get_dropdown_options(org_id, template_id, step_id, field_id)

# Update dropdown options
success = sdk.form_fields.update_dropdown_options(
    org_id, template_id, step_id, field_id, 
    ["Option 1", "Option 2", "Option 3"]
)

# Get AI-powered field suggestions
suggestions = sdk.form_fields.suggest_form_fields_for_step(org_id, template_id, step_id)

Data Models

The SDK provides comprehensive dataclasses for type safety and easy data access:

Core Models

  • User - Organization member with full profile data (country, timezone, job details)
  • Guest - External user with limited access and guest-specific details
  • GuestDetails - Extended guest information and statistics
  • Task - Individual work item with owners, deadlines, and process linkage
  • Run - Process instance (workflow execution) with progress tracking
  • Template - Complete template/checklist definition with automation rules
  • Step - Individual step within a template with conditions and assignments

Assignment and Ownership Models

  • TaskOwners - Task assignment information supporting users, guests, and groups
  • RunProgress - Process completion tracking with step-level progress
  • Country - Geographic data for user profiles
  • Folder - Organizational folder structure for templates and processes

Template and Automation Models

  • Tag - Industry and topic classification tags
  • PrerunField - Form fields for template kickoff with validation rules
  • AutomationCondition - Conditional logic for workflow automation
  • AutomationAction - Actions triggered by automation rules
  • AutomatedAction - Complete automation rule with conditions and actions
  • AutomationDeadline - Deadline configuration for automated actions
  • AutomationAssignees - Assignee configuration for automated actions

Step and Form Models

  • Capture - Form fields within steps with validation and positioning
  • StepStartDate - Start date configuration for steps
  • StepDeadline - Deadline configuration for individual steps
  • StepBpToLaunch - Sub-process launch configuration

Search and Utility Models

  • SearchResult - Unified search results for templates, processes, and tasks
  • TallyfyError - Custom exception with status codes and response data

Model Features

  • Automatic parsing from API responses via from_dict() class methods
  • Type safety with comprehensive type hints
  • Nested object support for complex data structures
  • Default value handling for optional fields

Example model usage:

# Models automatically parse API responses
users = sdk.users.get_organization_users(org_id)
for user in users:
    print(f"{user.full_name} ({user.email})")
    if user.country:
        print(f"Country: {user.country.name}")

# Access nested data safely
template = sdk.templates.get_template(org_id, template_name="Onboarding")
if template.automated_actions:
    for automation in template.automated_actions:
        print(f"Automation: {automation.automated_alias}")
        for condition in automation.conditions:
            print(f"  Condition: {condition.statement}")

Error Handling

The SDK provides comprehensive error handling through the TallyfyError class:

from tallyfy import TallyfyError

try:
    users = sdk.users.get_organization_users("invalid_org_id")
except TallyfyError as e:
    print(f"API Error: {e}")
    print(f"Status Code: {e.status_code}")
    print(f"Response Data: {e.response_data}")
except ValueError as e:
    print(f"Validation Error: {e}")

Error Types

  • TallyfyError - API-specific errors with status codes and response data
  • ValueError - Input validation errors for required parameters
  • RequestException - Network and connection errors (automatically retried)

Retry Logic

The SDK automatically retries failed requests with configurable settings:

  • Server errors (5xx) - Automatically retried up to max_retries times
  • Client errors (4xx) - Not retried (indicates user/input error)
  • Network errors - Retried with exponential backoff
  • Timeout errors - Retried with configurable delay

Examples

Complete User Onboarding Workflow

from tallyfy import TallyfySDK, TaskOwners

sdk = TallyfySDK(api_key="your_api_key")
org_id = "your_org_id"

# 1. Invite new user
new_user = sdk.users.invite_user_to_organization(
    org_id, 
    email="new.hire@company.com",
    first_name="John", 
    last_name="Doe",
    role="standard",
    message="Welcome to the team! Please complete your onboarding."
)

# 2. Create onboarding task
if new_user:
    owners = TaskOwners(users=[new_user.id])
    onboarding_task = sdk.tasks.create_task(
        org_id,
        title="Complete Employee Onboarding",
        deadline="2025-12-31 17:00:00",
        description="Please complete all onboarding steps including HR paperwork and IT setup.",
        owners=owners
    )
    print(f"Created onboarding task: {onboarding_task.id}")

Template Analysis and Enhancement

# Get template with full details
template_data = sdk.templates.get_template_with_steps(org_id, template_name="Project Kickoff")

if template_data:
    template = template_data['template']
    print(f"Template: {template.title}")
    print(f"Steps: {template_data['step_count']}")
    print(f"Automations: {template_data['automation_count']}")
    
    # Analyze each step for improvements
    for step_data in template_data['steps']:
        step_id = step_data['id']
        
        # Get dependency analysis
        dependencies = sdk.templates.get_step_dependencies(org_id, template.id, step_id)
        if dependencies['has_conditional_visibility']:
            print(f"Step '{step_data['title']}' has conditional logic")
        
        # Get deadline suggestions
        deadline_suggestion = sdk.templates.suggest_step_deadline(org_id, template.id, step_id)
        print(f"Suggested deadline: {deadline_suggestion['suggested_deadline']}")
        
        # Get form field suggestions
        field_suggestions = sdk.form_fields.suggest_form_fields_for_step(org_id, template.id, step_id)
        for suggestion in field_suggestions[:2]:  # Top 2 suggestions
            if suggestion['confidence'] > 0.7:
                print(f"High-confidence field suggestion: {suggestion['field_config']['label']}")

Advanced Process Management

# Get all active processes with comprehensive filtering
active_runs = sdk.tasks.get_organization_runs(
    org_id,
    status="active",
    with_data="checklist,tasks,assets,tags",
    form_fields_values=True,
    starred=True
)

# Group by template
template_usage = {}
for run in active_runs:
    template_id = run.checklist_id
    if template_id not in template_usage:
        template_usage[template_id] = {
            'template_name': run.checklist_title,
            'active_count': 0,
            'runs': []
        }
    template_usage[template_id]['active_count'] += 1
    template_usage[template_id]['runs'].append(run)

# Show most used templates
sorted_templates = sorted(template_usage.items(), key=lambda x: x[1]['active_count'], reverse=True)
for template_id, data in sorted_templates[:5]:
    print(f"{data['template_name']}: {data['active_count']} active processes")

Advanced Usage

Custom Request Configuration

# SDK with custom configuration
sdk = TallyfySDK(
    api_key="your_api_key",
    base_url="https://api.tallyfy.com",
    timeout=60,  # 60 second timeout
    max_retries=5,  # Retry up to 5 times
    retry_delay=2.0  # 2 second delay between retries
)

Accessing Raw API Responses

# For advanced users who need raw API data
template_data = sdk.templates.get_template_with_steps(org_id, template_id)
raw_api_response = template_data['raw_data']

# Access nested API data not exposed in models
custom_fields = raw_api_response.get('custom_metadata', {})

Batch Operations

# Efficiently process multiple operations
org_users = sdk.users.get_organization_users(org_id)
user_tasks = {}

for user in org_users[:10]:  # Process first 10 users
    try:
        tasks = sdk.tasks.get_user_tasks(org_id, user.id)
        user_tasks[user.id] = tasks
        print(f"{user.full_name}: {len(tasks)} tasks")
    except TallyfyError as e:
        print(f"Failed to get tasks for {user.full_name}: {e}")

Form Field Automation

# Automatically enhance templates with smart form fields
def enhance_template_with_smart_fields(org_id, template_id):
    steps = sdk.templates.get_template_steps(org_id, template_id)
    
    for step in steps:
        # Get AI suggestions for each step
        suggestions = sdk.form_fields.suggest_form_fields_for_step(org_id, template_id, step.id)
        
        # Implement high-confidence suggestions
        for suggestion in suggestions:
            if suggestion['confidence'] > 0.8 and suggestion['priority'] == 'high':
                field_data = suggestion['field_config']
                try:
                    new_field = sdk.form_fields.add_form_field_to_step(
                        org_id, template_id, step.id, field_data
                    )
                    print(f"Added field '{field_data['label']}' to step '{step.title}'")
                except TallyfyError as e:
                    print(f"Failed to add field: {e}")

# Use the enhancement function
enhance_template_with_smart_fields(org_id, "your_template_id")

Contributing

Code Style

  • Follow PEP 8 style guidelines
  • Use type hints for all functions and methods
  • Add comprehensive docstrings for public APIs
  • Include error handling for all external API calls

Adding New Features

  1. Add methods to appropriate management class
  2. Create or update data models in models.py
  3. Add comprehensive docstrings and type hints
  4. Include error handling and logging
  5. Update this README with usage examples

Support

For bugs, feature requests, or questions:

  1. Check existing issues in the project repository
  2. Contact us at: support@tallyfy.com

Version: 1.0.7 Last Updated: 2025

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tallyfy-1.0.7.tar.gz (70.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tallyfy-1.0.7-py3-none-any.whl (71.7 kB view details)

Uploaded Python 3

File details

Details for the file tallyfy-1.0.7.tar.gz.

File metadata

  • Download URL: tallyfy-1.0.7.tar.gz
  • Upload date:
  • Size: 70.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.6

File hashes

Hashes for tallyfy-1.0.7.tar.gz
Algorithm Hash digest
SHA256 95b449f2127ab341667b108f174d78701464fe8483889cac9cf6f14859a8dce8
MD5 f9866781941c3e4dab58b4540efd107d
BLAKE2b-256 9354e0fe5389357470a601a622bd9deb561a10c42d48e19087eef85b6e17f744

See more details on using hashes here.

File details

Details for the file tallyfy-1.0.7-py3-none-any.whl.

File metadata

  • Download URL: tallyfy-1.0.7-py3-none-any.whl
  • Upload date:
  • Size: 71.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.6

File hashes

Hashes for tallyfy-1.0.7-py3-none-any.whl
Algorithm Hash digest
SHA256 8fa6a8ac05d779e697dea3f6b8c99186fa88c97d421d6f712c773fa098390128
MD5 3dd2a2f45dbc071cb6c1984298666baf
BLAKE2b-256 c1d798e205c9a94367d5a03e3a657696bd78894375ad977ae103b20c4ffa5822

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page