tallyfy


Nametallyfy JSON
Version 1.0.5 PyPI version JSON
download
home_pagehttps://github.com/tallyfy/tallyfy-sdk
SummaryA comprehensive Python SDK for interacting with the Tallyfy API
upload_time2025-08-05 22:35:22
maintainerNone
docs_urlNone
authorTallyfy
requires_python>=3.7
licenseMIT
keywords tallyfy api sdk workflow automation task management
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # 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](#installation)
- [Quick Start](#quick-start)
- [Architecture](#architecture)
- [Core Features](#core-features)
- [API Reference](#api-reference)
- [Data Models](#data-models)
- [Error Handling](#error-handling)
- [Examples](#examples)
- [Advanced Usage](#advanced-usage)
- [Contributing](#contributing)

## Installation

```bash
pip install tallyfy
```

**Dependencies:**
- `requests` - HTTP client library
- `typing` - Type hints support (Python 3.5+)

## Quick Start

```python
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

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

### User Management

```python
# 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

```python
# 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

```python
# 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

```python
# 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:

```python
# 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:

```python
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

```python
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

```python
# 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

```python
# 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

```python
# 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

```python
# 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

```python
# 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

```python
# 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.5
**Last Updated:** 2025

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/tallyfy/tallyfy-sdk",
    "name": "tallyfy",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": "Tallyfy <support@tallyfy.com>",
    "keywords": "tallyfy, api, sdk, workflow, automation, task, management",
    "author": "Tallyfy",
    "author_email": "Tallyfy <support@tallyfy.com>",
    "download_url": "https://files.pythonhosted.org/packages/73/d2/65af3109472ece7eccb3bb4ce76070b082b58b6156359925733a7c499019/tallyfy-1.0.5.tar.gz",
    "platform": null,
    "description": "# Tallyfy SDK\n\nA 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.\n\n## Table of Contents\n\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Architecture](#architecture)\n- [Core Features](#core-features)\n- [API Reference](#api-reference)\n- [Data Models](#data-models)\n- [Error Handling](#error-handling)\n- [Examples](#examples)\n- [Advanced Usage](#advanced-usage)\n- [Contributing](#contributing)\n\n## Installation\n\n```bash\npip install tallyfy\n```\n\n**Dependencies:**\n- `requests` - HTTP client library\n- `typing` - Type hints support (Python 3.5+)\n\n## Quick Start\n\n```python\nfrom tallyfy import TallyfySDK\n\n# Initialize the SDK\nsdk = TallyfySDK(\n    api_key=\"your_api_key_here\"\n)\n\n# Get organization users\nusers = sdk.users.get_organization_users(org_id=\"your_org_id\")\n\n# Get current user's tasks\nmy_tasks = sdk.tasks.get_my_tasks(org_id=\"your_org_id\")\n\n# Search for templates\ntemplates = sdk.search(org_id=\"your_org_id\", search_query=\"onboarding\", search_type=\"blueprint\")\n\n# Get a specific template\ntemplate = sdk.templates.get_template(org_id=\"your_org_id\", template_name=\"Employee Onboarding\")\n```\n\n## Architecture\n\nThe Tallyfy SDK follows a modular architecture with specialized management classes and comprehensive data models:\n\n### Core Components\n\n- **`TallyfySDK`** - Main SDK class that orchestrates all operations with backward compatibility methods\n- **`BaseSDK`** - Base class with HTTP request handling, retry logic, and connection pooling\n- **Management Modules:**\n  - `UserManager` - User and guest operations with modular retrieval and invitation components\n  - `TaskManager` - Task and process operations with search and creation capabilities\n  - `TemplateManager` - Template/checklist operations with automation analysis and health assessment\n  - `FormFieldManager` - Form field operations with AI-powered suggestions and dropdown management\n- **Error Handling:**\n  - `TallyfyError` - Custom exception handling with status codes and response data\n\n### File Structure\n\n```\ntallyfy/\n\u251c\u2500\u2500 __init__.py                        # SDK exports and version\n\u251c\u2500\u2500 core.py                            # BaseSDK and TallyfySDK classes\n\u251c\u2500\u2500 models.py                          # Data models and types\n\u251c\u2500\u2500 user_management/                   # User and guest management (modular)\n\u2502   \u251c\u2500\u2500 __init__.py                    # UserManager with unified interface\n\u2502   \u251c\u2500\u2500 base.py                        # Common validation and error handling\n\u2502   \u251c\u2500\u2500 retrieval.py                   # User and guest retrieval operations\n\u2502   \u2514\u2500\u2500 invitation.py                  # User invitation operations\n\u251c\u2500\u2500 task_management/                   # Task and process management (modular)\n\u2502   \u251c\u2500\u2500 __init__.py                    # TaskManager with unified interface\n\u2502   \u251c\u2500\u2500 base.py                        # Common task operations base\n\u2502   \u251c\u2500\u2500 retrieval.py                   # Task and process retrieval\n\u2502   \u251c\u2500\u2500 search.py                      # Search functionality\n\u2502   \u2514\u2500\u2500 creation.py                    # Task creation operations\n\u251c\u2500\u2500 template_management/               # Template management (modular)\n\u2502   \u251c\u2500\u2500 __init__.py                    # TemplateManager with unified interface\n\u2502   \u251c\u2500\u2500 base.py                        # Common template operations\n\u2502   \u251c\u2500\u2500 basic_operations.py            # Template retrieval and CRUD operations\n\u2502   \u251c\u2500\u2500 automation.py                  # Automation rule management\n\u2502   \u251c\u2500\u2500 analysis.py                    # Template analysis and health checks\n\u2502   \u2514\u2500\u2500 health_assessment.py           # Template health assessment functionality\n\u251c\u2500\u2500 form_fields_management/            # Form field management (modular)\n\u2502   \u251c\u2500\u2500 __init__.py                    # FormFieldManager with unified interface\n\u2502   \u251c\u2500\u2500 base.py                        # Common form field operations\n\u2502   \u251c\u2500\u2500 crud_operations.py             # CRUD operations for form fields\n\u2502   \u251c\u2500\u2500 options_management.py          # Dropdown options management\n\u2502   \u2514\u2500\u2500 suggestions.py                 # AI-powered field suggestions\n\u2514\u2500\u2500 README.md                          # This documentation\n```\n\n## Core Features\n\n### \ud83d\udd10 Authentication & Security\n- Bearer token authentication with session management\n- Configurable request timeouts and connection pooling\n- Automatic retry logic for transient failures (5xx errors)\n- No retry for client errors (4xx) to prevent API abuse\n- Comprehensive error handling with detailed error information\n\n### \ud83d\udc65 User Management\n- **Modular architecture** with specialized retrieval and invitation components\n- Get organization members with full profile data (country, timezone, job details)\n- Get minimal user lists for performance-critical operations\n- Manage guests and external users with guest-specific features\n- **Enhanced search capabilities** - Find users by email or name with fuzzy matching\n- **Batch invitation support** - Invite multiple users with default roles and messages\n- **Advanced invitation features** - Custom messages, role validation, and resend functionality\n- Support for user groups and permissions with flexible query parameters\n- **Convenience methods** - Get all members (users + guests) in a single call\n\n### \u2705 Task Management  \n- Get tasks for specific users or processes with filtering\n- Create standalone tasks with rich assignment options\n- Search processes by name with fuzzy matching\n- Advanced filtering for organization runs (status, owners, tags, etc.)\n- Universal search across processes, templates, and tasks\n\n### \ud83d\udccb Template Management\n- Get templates with full metadata and step details\n- Search templates by name with exact and fuzzy matching\n- Update template properties and metadata\n- Duplicate templates with permission copying options\n- **Automation management** - Create, update, and analyze conditional rules\n- **Step dependency analysis** - Understand step visibility conditions\n- **AI-powered deadline suggestions** for individual steps\n- **Template health assessment** - Comprehensive analysis of template quality\n- **Automation consolidation** - Optimize and merge redundant rules\n- Add assignees and edit step descriptions\n- Kickoff field management for template launch forms\n\n### \ud83d\udcdd Form Field Management\n- Add form fields to template steps with comprehensive validation\n- Support for text, dropdown, date, file upload, WYSIWYG editor fields\n- Update field properties, validation rules, and positioning\n- Move fields between steps with automatic reordering\n- **AI-powered field suggestions** based on step analysis\n- Manage dropdown options with bulk updates\n- **Smart field recommendations** with confidence scoring\n- Field dependency management and conditional logic\n\n### \ud83d\udd0d Search & Discovery\n- Universal search across processes, templates, and tasks\n- Exact and fuzzy matching with relevance scoring\n- Pagination support with configurable page sizes\n- Rich search results with metadata and context\n- Process and template name-based search with suggestions\n\n## API Reference\n\n### SDK Initialization\n\n```python\nTallyfySDK(\n    api_key: str,\n    timeout: int = 30,\n    max_retries: int = 3,\n    retry_delay: float = 1.0\n)\n```\n\n### User Management\n\n```python\n# Get all organization users with optional group data\nusers = sdk.users.get_organization_users(org_id, with_groups=False)\n\n# Get minimal user list for performance\nusers_list = sdk.users.get_organization_users_list(org_id)\n\n# Get organization guests with optional statistics\nguests = sdk.users.get_organization_guests(org_id, with_stats=False)\n\n# Get current user info\ncurrent_user = sdk.users.get_current_user_info(org_id)\n\n# Enhanced search capabilities\nuser = sdk.users.get_user_by_email(org_id, \"john@company.com\")\nguest = sdk.users.get_guest_by_email(org_id, \"contractor@company.com\")\n\n# Search members by name (fuzzy matching)\nsearch_results = sdk.users.search_members_by_name(org_id, \"John Smith\", include_guests=True)\nmatching_users = search_results['users']\nmatching_guests = search_results['guests']\n\n# Get all members in one call\nall_members = sdk.users.get_all_organization_members(\n    org_id, include_guests=True, with_groups=True, with_stats=True\n)\n\n# Invite single user to organization\nuser = sdk.users.invite_user_to_organization(\n    org_id, email=\"new.hire@company.com\", \n    first_name=\"John\", last_name=\"Doe\",\n    role=\"standard\", \n    message=\"Welcome! Please complete your onboarding process.\"\n)\n\n# Batch invite multiple users\ninvitations = [\n    {\n        \"email\": \"user1@company.com\",\n        \"first_name\": \"Jane\",\n        \"last_name\": \"Smith\",\n        \"role\": \"standard\"\n    },\n    {\n        \"email\": \"user2@company.com\", \n        \"first_name\": \"Bob\",\n        \"last_name\": \"Johnson\",\n        \"message\": \"Welcome to the engineering team!\"\n    }\n]\nresults = sdk.users.invite_multiple_users(\n    org_id, invitations, \n    default_role=\"light\",\n    default_message=\"Welcome to our organization!\"\n)\n\n# Resend invitation\nsuccess = sdk.users.resend_invitation(\n    org_id, email=\"pending@company.com\",\n    message=\"Reminder: Please accept your invitation to join our organization.\"\n)\n\n# Generate custom invitation message\nmessage = sdk.users.get_invitation_template_message(\n    org_name=\"ACME Corp\",\n    custom_text=\"We're excited to have you join our innovative team!\"\n)\n\n# Validate invitation data before sending\ninvitation_data = {\n    \"email\": \"new@company.com\",\n    \"first_name\": \"Alice\",\n    \"last_name\": \"Wilson\",\n    \"role\": \"admin\"\n}\nvalidated_data = sdk.users.validate_invitation_data(invitation_data)\n\n# Access modular components directly (advanced usage)\n# Retrieval operations\nusers_with_groups = sdk.users.retrieval.get_organization_users(org_id, with_groups=True)\n\n# Invitation operations  \nbatch_results = sdk.users.invitation.invite_multiple_users(org_id, invitations)\n```\n\n### Task Management\n\n```python\n# Get current user's tasks\nmy_tasks = sdk.tasks.get_my_tasks(org_id)\n\n# Get specific user's tasks\nuser_tasks = sdk.tasks.get_user_tasks(org_id, user_id)\n\n# Get tasks for a process\nprocess_tasks = sdk.tasks.get_tasks_for_process(org_id, process_id=None, process_name=\"My Process\")\n\n# Get organization processes with filtering\nruns = sdk.tasks.get_organization_runs(\n    org_id, \n    status=\"active\",\n    owners=\"123,456\", \n    checklist_id=\"template_id\"\n)\n\n# Create standalone task\ntask = sdk.tasks.create_task(\n    org_id, title=\"Review Document\", \n    deadline=\"2024-12-31T23:59:59Z\",\n    description=\"Please review the attached document\"\n)\n\n# Search processes, templates, or tasks\nresults = sdk.tasks.search(org_id, \"onboarding\", search_type=\"process\")\n\n# Search for specific entity types\ntemplates = sdk.tasks.search(org_id, \"employee onboarding\", search_type=\"blueprint\")\ntasks = sdk.tasks.search(org_id, \"review\", search_type=\"task\")\n```\n\n### Template Management\n\n```python\n# Get template by ID or name\ntemplate = sdk.templates.get_template(org_id, template_id=None, template_name=\"Onboarding\")\n\n# Get template with full step details\ntemplate_data = sdk.templates.get_template_with_steps(org_id, template_id)\n\n# Update template metadata\nupdated = sdk.templates.update_template_metadata(\n    org_id, template_id,\n    title=\"New Title\",\n    summary=\"Updated summary\",\n    guidance=\"New guidance text\"\n)\n\n# Get template steps\nsteps = sdk.templates.get_template_steps(org_id, template_id)\n\n# Analyze step dependencies  \ndependencies = sdk.templates.get_step_dependencies(org_id, template_id, step_id)\n\n# Get deadline suggestions\ndeadline_suggestion = sdk.templates.suggest_step_deadline(org_id, template_id, step_id)\n\n# Advanced template operations\nduplicated = sdk.templates.duplicate_template(org_id, template_id, \"New Template Name\", copy_permissions=True)\n\n# Automation management\nautomation_data = {\n    \"automated_alias\": \"Auto-assign reviewer\",\n    \"conditions\": [{\"field_id\": \"department\", \"operator\": \"equals\", \"value\": \"Engineering\"}],\n    \"actions\": [{\"type\": \"assign_step\", \"step_id\": \"review_step\", \"assignee_type\": \"user\", \"assignee_id\": \"123\"}]\n}\nautomation = sdk.templates.create_automation_rule(org_id, template_id, automation_data)\n\n# Analyze automation conflicts and redundancies\nanalysis = sdk.templates.analyze_template_automations(org_id, template_id)\n\n# Get consolidation suggestions\nsuggestions = sdk.templates.suggest_automation_consolidation(org_id, template_id)\n\n# Assess overall template health\nhealth_report = sdk.templates.assess_template_health(org_id, template_id)\n\n# Template metadata management\nupdated = sdk.templates.update_template_metadata(\n    org_id, template_id,\n    title=\"Updated Template Title\",\n    guidance=\"New guidance text\",\n    is_featured=True\n)\n\n# Add assignees to step\nassignees = {\"users\": [123, 456], \"groups\": [\"managers\"], \"guests\": [\"contractor@company.com\"]}\nsdk.templates.add_assignees_to_step(org_id, template_id, step_id, assignees)\n\n# Edit step description\nsdk.templates.edit_description_on_step(org_id, template_id, step_id, \"Updated step description with detailed instructions\")\n\n# Add new step to template\nstep_data = {\n    \"title\": \"Quality Review\",\n    \"description\": \"Perform final quality check\",\n    \"position\": 5,\n    \"assignees\": {\"users\": [789]}\n}\nnew_step = sdk.templates.add_step_to_template(org_id, template_id, step_data)\n```\n\n### Form Field Management\n\n```python\n# Add form field to step\nfield_data = {\n    \"field_type\": \"text\",\n    \"label\": \"Customer Name\", \n    \"required\": True,\n    \"position\": 1\n}\nfield = sdk.form_fields.add_form_field_to_step(org_id, template_id, step_id, field_data)\n\n# Update form field\nupdated_field = sdk.form_fields.update_form_field(\n    org_id, template_id, step_id, field_id,\n    label=\"Updated Label\",\n    required=False\n)\n\n# Move field between steps\nsuccess = sdk.form_fields.move_form_field(\n    org_id, template_id, from_step, field_id, to_step, position=2\n)\n\n# Delete form field\nsuccess = sdk.form_fields.delete_form_field(org_id, template_id, step_id, field_id)\n\n# Get dropdown options\noptions = sdk.form_fields.get_dropdown_options(org_id, template_id, step_id, field_id)\n\n# Update dropdown options\nsuccess = sdk.form_fields.update_dropdown_options(\n    org_id, template_id, step_id, field_id, \n    [\"Option 1\", \"Option 2\", \"Option 3\"]\n)\n\n# Get AI-powered field suggestions\nsuggestions = sdk.form_fields.suggest_form_fields_for_step(org_id, template_id, step_id)\n```\n\n## Data Models\n\nThe SDK provides comprehensive dataclasses for type safety and easy data access:\n\n### Core Models\n\n- **`User`** - Organization member with full profile data (country, timezone, job details)\n- **`Guest`** - External user with limited access and guest-specific details\n- **`GuestDetails`** - Extended guest information and statistics\n- **`Task`** - Individual work item with owners, deadlines, and process linkage\n- **`Run`** - Process instance (workflow execution) with progress tracking\n- **`Template`** - Complete template/checklist definition with automation rules\n- **`Step`** - Individual step within a template with conditions and assignments\n\n### Assignment and Ownership Models\n\n- **`TaskOwners`** - Task assignment information supporting users, guests, and groups\n- **`RunProgress`** - Process completion tracking with step-level progress\n- **`Country`** - Geographic data for user profiles\n- **`Folder`** - Organizational folder structure for templates and processes\n\n### Template and Automation Models\n\n- **`Tag`** - Industry and topic classification tags\n- **`PrerunField`** - Form fields for template kickoff with validation rules\n- **`AutomationCondition`** - Conditional logic for workflow automation\n- **`AutomationAction`** - Actions triggered by automation rules\n- **`AutomatedAction`** - Complete automation rule with conditions and actions\n- **`AutomationDeadline`** - Deadline configuration for automated actions\n- **`AutomationAssignees`** - Assignee configuration for automated actions\n\n### Step and Form Models\n\n- **`Capture`** - Form fields within steps with validation and positioning\n- **`StepStartDate`** - Start date configuration for steps\n- **`StepDeadline`** - Deadline configuration for individual steps\n- **`StepBpToLaunch`** - Sub-process launch configuration\n\n### Search and Utility Models\n\n- **`SearchResult`** - Unified search results for templates, processes, and tasks\n- **`TallyfyError`** - Custom exception with status codes and response data\n\n### Model Features\n\n- **Automatic parsing** from API responses via `from_dict()` class methods\n- **Type safety** with comprehensive type hints\n- **Nested object support** for complex data structures\n- **Default value handling** for optional fields\n\nExample model usage:\n\n```python\n# Models automatically parse API responses\nusers = sdk.users.get_organization_users(org_id)\nfor user in users:\n    print(f\"{user.full_name} ({user.email})\")\n    if user.country:\n        print(f\"Country: {user.country.name}\")\n\n# Access nested data safely\ntemplate = sdk.templates.get_template(org_id, template_name=\"Onboarding\")\nif template.automated_actions:\n    for automation in template.automated_actions:\n        print(f\"Automation: {automation.automated_alias}\")\n        for condition in automation.conditions:\n            print(f\"  Condition: {condition.statement}\")\n```\n\n## Error Handling\n\nThe SDK provides comprehensive error handling through the `TallyfyError` class:\n\n```python\nfrom tallyfy import TallyfyError\n\ntry:\n    users = sdk.users.get_organization_users(\"invalid_org_id\")\nexcept TallyfyError as e:\n    print(f\"API Error: {e}\")\n    print(f\"Status Code: {e.status_code}\")\n    print(f\"Response Data: {e.response_data}\")\nexcept ValueError as e:\n    print(f\"Validation Error: {e}\")\n```\n\n### Error Types\n\n- **`TallyfyError`** - API-specific errors with status codes and response data\n- **`ValueError`** - Input validation errors for required parameters\n- **`RequestException`** - Network and connection errors (automatically retried)\n\n### Retry Logic\n\nThe SDK automatically retries failed requests with configurable settings:\n\n- **Server errors (5xx)** - Automatically retried up to `max_retries` times\n- **Client errors (4xx)** - Not retried (indicates user/input error)\n- **Network errors** - Retried with exponential backoff\n- **Timeout errors** - Retried with configurable delay\n\n## Examples\n\n### Complete User Onboarding Workflow\n\n```python\nfrom tallyfy import TallyfySDK, TaskOwners\n\nsdk = TallyfySDK(api_key=\"your_api_key\")\norg_id = \"your_org_id\"\n\n# 1. Invite new user\nnew_user = sdk.users.invite_user_to_organization(\n    org_id, \n    email=\"new.hire@company.com\",\n    first_name=\"John\", \n    last_name=\"Doe\",\n    role=\"standard\",\n    message=\"Welcome to the team! Please complete your onboarding.\"\n)\n\n# 2. Create onboarding task\nif new_user:\n    owners = TaskOwners(users=[new_user.id])\n    onboarding_task = sdk.tasks.create_task(\n        org_id,\n        title=\"Complete Employee Onboarding\",\n        deadline=\"2025-12-31 17:00:00\",\n        description=\"Please complete all onboarding steps including HR paperwork and IT setup.\",\n        owners=owners\n    )\n    print(f\"Created onboarding task: {onboarding_task.id}\")\n```\n\n### Template Analysis and Enhancement\n\n```python\n# Get template with full details\ntemplate_data = sdk.templates.get_template_with_steps(org_id, template_name=\"Project Kickoff\")\n\nif template_data:\n    template = template_data['template']\n    print(f\"Template: {template.title}\")\n    print(f\"Steps: {template_data['step_count']}\")\n    print(f\"Automations: {template_data['automation_count']}\")\n    \n    # Analyze each step for improvements\n    for step_data in template_data['steps']:\n        step_id = step_data['id']\n        \n        # Get dependency analysis\n        dependencies = sdk.templates.get_step_dependencies(org_id, template.id, step_id)\n        if dependencies['has_conditional_visibility']:\n            print(f\"Step '{step_data['title']}' has conditional logic\")\n        \n        # Get deadline suggestions\n        deadline_suggestion = sdk.templates.suggest_step_deadline(org_id, template.id, step_id)\n        print(f\"Suggested deadline: {deadline_suggestion['suggested_deadline']}\")\n        \n        # Get form field suggestions\n        field_suggestions = sdk.form_fields.suggest_form_fields_for_step(org_id, template.id, step_id)\n        for suggestion in field_suggestions[:2]:  # Top 2 suggestions\n            if suggestion['confidence'] > 0.7:\n                print(f\"High-confidence field suggestion: {suggestion['field_config']['label']}\")\n```\n\n### Advanced Process Management\n\n```python\n# Get all active processes with comprehensive filtering\nactive_runs = sdk.tasks.get_organization_runs(\n    org_id,\n    status=\"active\",\n    with_data=\"checklist,tasks,assets,tags\",\n    form_fields_values=True,\n    starred=True\n)\n\n# Group by template\ntemplate_usage = {}\nfor run in active_runs:\n    template_id = run.checklist_id\n    if template_id not in template_usage:\n        template_usage[template_id] = {\n            'template_name': run.checklist_title,\n            'active_count': 0,\n            'runs': []\n        }\n    template_usage[template_id]['active_count'] += 1\n    template_usage[template_id]['runs'].append(run)\n\n# Show most used templates\nsorted_templates = sorted(template_usage.items(), key=lambda x: x[1]['active_count'], reverse=True)\nfor template_id, data in sorted_templates[:5]:\n    print(f\"{data['template_name']}: {data['active_count']} active processes\")\n```\n\n## Advanced Usage\n\n### Custom Request Configuration\n\n```python\n# SDK with custom configuration\nsdk = TallyfySDK(\n    api_key=\"your_api_key\",\n    base_url=\"https://api.tallyfy.com\",\n    timeout=60,  # 60 second timeout\n    max_retries=5,  # Retry up to 5 times\n    retry_delay=2.0  # 2 second delay between retries\n)\n```\n\n### Accessing Raw API Responses\n\n```python\n# For advanced users who need raw API data\ntemplate_data = sdk.templates.get_template_with_steps(org_id, template_id)\nraw_api_response = template_data['raw_data']\n\n# Access nested API data not exposed in models\ncustom_fields = raw_api_response.get('custom_metadata', {})\n```\n\n### Batch Operations\n\n```python\n# Efficiently process multiple operations\norg_users = sdk.users.get_organization_users(org_id)\nuser_tasks = {}\n\nfor user in org_users[:10]:  # Process first 10 users\n    try:\n        tasks = sdk.tasks.get_user_tasks(org_id, user.id)\n        user_tasks[user.id] = tasks\n        print(f\"{user.full_name}: {len(tasks)} tasks\")\n    except TallyfyError as e:\n        print(f\"Failed to get tasks for {user.full_name}: {e}\")\n```\n\n### Form Field Automation\n\n```python\n# Automatically enhance templates with smart form fields\ndef enhance_template_with_smart_fields(org_id, template_id):\n    steps = sdk.templates.get_template_steps(org_id, template_id)\n    \n    for step in steps:\n        # Get AI suggestions for each step\n        suggestions = sdk.form_fields.suggest_form_fields_for_step(org_id, template_id, step.id)\n        \n        # Implement high-confidence suggestions\n        for suggestion in suggestions:\n            if suggestion['confidence'] > 0.8 and suggestion['priority'] == 'high':\n                field_data = suggestion['field_config']\n                try:\n                    new_field = sdk.form_fields.add_form_field_to_step(\n                        org_id, template_id, step.id, field_data\n                    )\n                    print(f\"Added field '{field_data['label']}' to step '{step.title}'\")\n                except TallyfyError as e:\n                    print(f\"Failed to add field: {e}\")\n\n# Use the enhancement function\nenhance_template_with_smart_fields(org_id, \"your_template_id\")\n```\n\n## Contributing\n\n### Code Style\n\n- Follow PEP 8 style guidelines\n- Use type hints for all functions and methods\n- Add comprehensive docstrings for public APIs\n- Include error handling for all external API calls\n\n### Adding New Features\n\n1. Add methods to appropriate management class\n2. Create or update data models in `models.py`\n3. Add comprehensive docstrings and type hints\n4. Include error handling and logging\n5. Update this README with usage examples\n\n\n## Support\n\nFor bugs, feature requests, or questions:\n\n1. Check existing issues in the project repository\n2. Contact us at: support@tallyfy.com\n---\n\n**Version:** 1.0.5\n**Last Updated:** 2025\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "A comprehensive Python SDK for interacting with the Tallyfy API",
    "version": "1.0.5",
    "project_urls": {
        "Bug Tracker": "https://github.com/tallyfy/tallyfy-sdk/issues",
        "Changelog": "https://github.com/tallyfy/tallyfy-sdk/blob/main/CHANGELOG.md",
        "Documentation": "https://tallyfy.com/products/",
        "Homepage": "https://github.com/tallyfy/tallyfy-sdk",
        "Repository": "https://github.com/tallyfy/tallyfy-sdk"
    },
    "split_keywords": [
        "tallyfy",
        " api",
        " sdk",
        " workflow",
        " automation",
        " task",
        " management"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "c399e6d90feb4cbd7ef597a76090cf37794dcee83202c04a0155c1af8c66f0a7",
                "md5": "a00b3c0473725fe3389d7dfebb587bbb",
                "sha256": "c42aa08d5ab758514185d8dae3c73098368a724945bdea2230ccfbf5f746d523"
            },
            "downloads": -1,
            "filename": "tallyfy-1.0.5-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "a00b3c0473725fe3389d7dfebb587bbb",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 69990,
            "upload_time": "2025-08-05T22:35:20",
            "upload_time_iso_8601": "2025-08-05T22:35:20.672133Z",
            "url": "https://files.pythonhosted.org/packages/c3/99/e6d90feb4cbd7ef597a76090cf37794dcee83202c04a0155c1af8c66f0a7/tallyfy-1.0.5-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "73d265af3109472ece7eccb3bb4ce76070b082b58b6156359925733a7c499019",
                "md5": "2460e4c3c92181bbdc5d8b86f1878eae",
                "sha256": "828386a3c546e8338aa0d30cd6c5a07b39bb0c69ae181483fdd5fc4baf447dc7"
            },
            "downloads": -1,
            "filename": "tallyfy-1.0.5.tar.gz",
            "has_sig": false,
            "md5_digest": "2460e4c3c92181bbdc5d8b86f1878eae",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 68208,
            "upload_time": "2025-08-05T22:35:22",
            "upload_time_iso_8601": "2025-08-05T22:35:22.769798Z",
            "url": "https://files.pythonhosted.org/packages/73/d2/65af3109472ece7eccb3bb4ce76070b082b58b6156359925733a7c499019/tallyfy-1.0.5.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-05 22:35:22",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "tallyfy",
    "github_project": "tallyfy-sdk",
    "github_not_found": true,
    "lcname": "tallyfy"
}
        
Elapsed time: 1.50997s