Metadata-Version: 2.4
Name: kita
Version: 1.2.3
Summary: Official Python SDK for Kita Document Processing API
Author-email: Kita Team <support@usekita.com>
Maintainer-email: Kita Team <support@usekita.com>
License: MIT
Project-URL: Homepage, https://usekita.com
Project-URL: Documentation, https://docs.usekita.com
Project-URL: Repository, https://github.com/usekita/kita-python-sdk
Project-URL: Issues, https://github.com/usekita/kita-python-sdk/issues
Project-URL: Changelog, https://github.com/usekita/kita-python-sdk/blob/main/CHANGELOG.md
Keywords: kita,document-processing,ocr,bank-statement,payslip,pdf,api,sdk
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Office/Business :: Financial
Classifier: Topic :: Scientific/Engineering :: Image Recognition
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Requires-Dist: requests>=2.25.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
Requires-Dist: black>=22.0.0; extra == "dev"
Requires-Dist: ruff>=0.1.0; extra == "dev"
Requires-Dist: mypy>=1.0.0; extra == "dev"
Requires-Dist: types-requests>=2.28.0; extra == "dev"
Dynamic: requires-python

# Kita Python SDK

The official Python SDK for the Kita Document Processing API.

## Installation

```bash
pip install kita
```

## Quick Start

```python
from kita import KitaClient

client = KitaClient(api_key="kita_prod_...")

# Process a document
result = client.process("statement.pdf", "bank_statement")
print(result.metadata)
print(result.transactions)
result.save_json("output.json")
```

## Configuration

### API Key

Get your API key from the Kita dashboard.

```python
# Pass directly
client = KitaClient(api_key="kita_prod_...")

# Or set environment variable: export KITA_API_KEY=kita_prod_...
client = KitaClient()
```

### Base URL

The SDK defaults to production (`https://portal.usekita.com`). Override for local development:

```python
client = KitaClient(api_key="...", base_url="http://localhost:8080")
# Or: export KITA_API_URL=http://localhost:8080
```

## Document Types

| Type | Description |
|------|-------------|
| `bank_statement` | Bank account statements |
| `payslip` | Salary/pay stubs |
| `bill` | Utility bills |
| `credit_report` | Credit reports (CIBI, etc.) |
| `bir_2303` | BIR Form 2303 |
| `bir_2307` | BIR Form 2307 |
| `secretarys_certificate` | Secretary's Certificate |

Type names are case-insensitive — `"bank_statement"`, `"BANK_STATEMENT"`, and `"Bank Statement"` all work.

---

## Methods

### `process(file_path, document_type)` — Process a document

```python
result = client.process(
    "statement.pdf",
    "bank_statement",
    wait=True,            # Wait for completion (default: True)
    poll_interval=2,      # Seconds between status checks
    timeout=600,          # Max wait time
    password=None,        # PDF password if encrypted
    show_progress=True    # Show spinner
)
```

Returns a `DocumentResult`.

### `process_url(file_url, document_type)` — Process from URL

```python
result = client.process_url(
    "https://example.com/statement.pdf",
    "bank_statement",
    filename="statement.pdf"  # Optional filename override
)
```

### `get_result(document_id)` — Get full result by ID

Retrieve the complete processed result for an already-processed document.

```python
result = client.get_result(12345)
print(result.metadata)
result.save_json("output.json")
```

### `get_summary(document_id)` — Bank statement summary

Returns a flat dict of 48 summary metrics (no transactions). Only works for `bank_statement` and `passbook` documents.

```python
# As JSON dict
summary = client.get_summary(result.document_id)
print(summary['total_inflow'])
print(summary['average_daily_balance'])
print(summary['number_of_transactions'])

# As CSV string
csv_data = client.get_summary(result.document_id, format='csv')
with open('summary.csv', 'w') as f:
    f.write(csv_data)
```

Summary fields: `document_id`, `account_holder_name`, `account_number`, `financial_institution`, `statement_start_date`, `statement_end_date`, `total_inflow`, `total_outflow`, `net_cash_flow`, `opening_balance`, `closing_balance`, `average_daily_balance`, `monthly_inflow_average`, `monthly_outflow_average`, `gambling_transaction_count`, `bounced_transaction_count`, `loan_transaction_count`, `income_transaction_count`, `cash_buffer_days`, `sum_of_debits`, `sum_of_credits`, `sum_eod_balances`, `lowest_eod_balance`, `average_eod_balance`, `highest_eod_balance`, `number_of_transactions`, `total_annualized_credits`, `total_annualized_debits`, `credits_per_month`, `debits_per_month`, `income_detection`, `transactions_per_week`, plus category spend percentages (`percent_atm`, `percent_food`, `percent_gambling`, `percent_loan`, etc.)

### `custom_export(document_id, output_path, export_type)` — Excel export

```python
# Org-configured custom Excel export
client.custom_export(result.document_id, "report.xlsx")

# Credit report — multi-sheet Excel export
result = client.process("report.pdf", "credit_report")
client.custom_export(result.document_id, "credit.xlsx", export_type="credit_report")
```

### `batch_process(folder_path, document_type)` — Batch from folder

```python
batch = client.batch_process(
    "/path/to/statements",
    "bank_statement",
    extensions=['.pdf', '.png', '.jpg'],  # Default: ['.pdf', '.png', '.jpg', '.jpeg']
    recursive=False,                       # Search subdirectories
    max_workers=5                          # Parallel upload threads
)

results = batch.results()  # {filepath: DocumentResult}

for filepath, result in results.items():
    print(f"{filepath}: {result.status}")
    result.save_json(f"{filepath}_output.json")
```

### `batch_process_urls(documents)` — Batch from URLs

```python
results = client.batch_process_urls([
    {"file_url": "https://example.com/stmt1.pdf", "document_type": "bank_statement"},
    {"file_url": "https://example.com/stmt2.pdf", "document_type": "bank_statement"},
])
for doc in results['documents']:
    if doc['status'] == 'completed':
        print(doc['result']['metadata'])
```

### `list_documents(limit, offset, status, document_type)` — List documents

```python
docs = client.list_documents(limit=50, status='completed', document_type='bank_statement')
for doc in docs['documents']:
    print(f"{doc['id']}: {doc.get('document_type')}")
```

---

## DocumentResult

All processing methods return a `DocumentResult` object:

```python
result.status           # 'completed', 'failed', etc.
result.document_id      # Document ID (for exports, get_summary, etc.)
result.document_type    # 'bank_statement', 'payslip', etc.
result.metadata         # Dict of document metadata
result.transactions     # List of transactions (bank statements)
result.raw              # Full response dict

result.to_dict()        # Convert to dictionary
result.to_json()        # Formatted JSON string
result.save_json(path)  # Save to JSON file
result['key']           # Dict-like access
result.get('key', default)
```

---

## Response Formats by Document Type

### Bank Statement

```python
result = client.process("statement.pdf", "bank_statement")
```

```json
{
  "status": "completed",
  "document_type": "bank_statement",
  "document_id": "123",
  "filename": "statement.pdf",
  "processing_time_seconds": 12.5,

  "metadata": {
    "account_holder_name": "Juan Dela Cruz",
    "account_number": "1234567890",
    "financial_institution": "BDO",
    "statement_start_date": "01-01-2024",
    "statement_end_date": "01-31-2024",
    "country": "Philippines",
    "currency": "PHP",
    "opening_balance": 50000.00,
    "closing_balance": 62000.00
  },

  "transactions": [
    {
      "date": "01-02-2024",
      "description": "SALARY CREDIT",
      "credit": 30000.00,
      "debit": null,
      "balance": 80000.00,
      "category": "income",
      "subcategory": "salary",
      "transaction_type": "credit"
    }
  ],

  "metrics": {
    "total_inflow": 45000.00,
    "total_outflow": 33000.00,
    "net_cash_flow": 12000.00,
    "opening_balance": 50000.00,
    "closing_balance": 62000.00,
    "average_balance": 58000.00,
    "total_transactions": 25,
    "by_category": {
      "income": { "count": 2, "credit_sum": 35000, "debit_sum": 0 },
      "food": { "count": 8, "credit_sum": 0, "debit_sum": 5000 }
    },
    "by_month": { ... },
    "extended_metrics": { ... }
  },

  "fraud_detection": {
    "risk_level": "low",
    "authenticity_score": 92,
    "is_standardized": true,
    "total_rows": 25,
    "tamper_count": 0,
    "summary_count": 1,
    "summary": { ... },
    "category_scores": { ... },
    "integrity_checks": [ ... ],
    "signals": [
      {
        "severity": "info",
        "category": "document_integrity",
        "message": "Document appears authentic",
        "details": { ... }
      }
    ]
  }
}
```

### Payslip

```python
result = client.process("payslip.pdf", "payslip")
```

```json
{
  "status": "completed",
  "document_type": "payslip",
  "document_id": "456",
  "filename": "payslip.pdf",

  "metadata": {
    "payout_date": "01-15-2024",
    "period_start": "01-01-2024",
    "period_end": "01-15-2024",
    "country": "Philippines"
  },

  "employment_info": {
    "employer_name": "Acme Corp",
    "employee_name": "Juan Dela Cruz",
    "employee_id": "EMP-001",
    "department": "Engineering",
    "tax_status": "Single",
    "employment_type": "Regular",
    "statutory_ids": {
      "tin": "123-456-789",
      "sss": "12-3456789-0",
      "philhealth": "12-123456789-1",
      "pagibig": "1234-5678-9012"
    }
  },

  "financial_breakdown": {
    "earnings": {
      "taxable": [
        { "label": "Basic Pay", "amount": 25000 },
        { "label": "Overtime", "amount": 3000 }
      ],
      "non_taxable": [
        { "label": "Rice Allowance", "amount": 2000 }
      ],
      "total_taxable": 28000,
      "total_non_taxable": 2000,
      "total_gross": 30000
    },
    "deductions": {
      "statutory": [
        { "label": "SSS", "amount": 900 },
        { "label": "PhilHealth", "amount": 450 },
        { "label": "Pag-IBIG", "amount": 100 },
        { "label": "Withholding Tax", "amount": 2500 }
      ],
      "loans_and_obligations": [
        { "label": "SSS Loan", "amount": 1000, "type": "SSS_LOAN" }
      ],
      "total_statutory_deductions": 3950,
      "total_loan_deductions": 1000,
      "total_deductions": 4950
    },
    "net_pay": 25050
  },

  "year_to_date": {
    "ytd_taxable_income": 28000,
    "ytd_tax_withheld": 2500,
    "ytd_non_tax_income": 2000,
    "ytd_effective_tax_rate": 0.089
  },

  "underwriting_signals": {
    "income_quality": {
      "basic_to_gross_ratio": 0.83,
      "variable_income_to_gross_ratio": 0.10,
      "non_taxable_to_gross_ratio": 0.07,
      "is_allowance_heavy": false,
      "is_variable_pay_heavy": false,
      "pay_frequency": "SEMI_MONTHLY"
    },
    "statutory_compliance": {
      "tin_present": true,
      "sss_present": true,
      "philhealth_present": true,
      "pagibig_present": true,
      "missing_statutory_flag": false
    },
    "government_debt_signals": {
      "has_sss_loan": true,
      "has_pagibig_loan": false,
      "government_loan_count": 1,
      "total_government_loan_deductions": 1000,
      "gov_loan_to_net_ratio": 0.04,
      "multiple_gov_loans_flag": false
    },
    "debt_burden": {
      "total_deductions": 4950,
      "deductions_to_gross_ratio": 0.165,
      "high_deduction_pressure_flag": false
    },
    "overall_risk_flags": {
      "is_overleveraged": false,
      "low_net_income_flag": false,
      "potential_income_inflation_flag": false
    }
  },

  "payslip_fields": { ... },
  "payslip_signals": { ... },
  "fraud_detection": { ... }
}
```

### Bill (Utility)

```python
result = client.process("bill.pdf", "bill")
```

```json
{
  "status": "completed",
  "document_type": "bill",
  "document_id": "789",
  "filename": "bill.pdf",

  "metadata": {
    "account_holder_name": "Juan Dela Cruz",
    "service_address": "123 Main St, Makati"
  },

  "bill_fields": {
    "provider": "Meralco",
    "account_number": "1234567890",
    "billing_period_start": "12-01-2023",
    "billing_period_end": "12-31-2023",
    "due_date": "01-15-2024",
    "total_amount_due": 3500.00,
    "previous_balance": 0,
    "current_charges": 3500.00,
    "account_holder_name": "Juan Dela Cruz",
    "service_address": "123 Main St, Makati",
    "payment_status": "unpaid"
  },

  "signals": [
    {
      "signal_id": "address_match",
      "label": "Address Verification",
      "value": true,
      "status": "pass",
      "message": "Service address matches applicant address",
      "details": { ... }
    }
  ],

  "signal_summary": {
    "overall_score": 85,
    "total_signals": 6,
    "passed": 5,
    "warnings": 1,
    "failed": 0,
    "risk_level": "low"
  },

  "warnings": [],
  "fraud_detection": { ... }
}
```

### Credit Report

```python
result = client.process("credit_report.pdf", "credit_report")
```

```json
{
  "status": "completed",
  "document_type": "credit_report",
  "document_id": "321",
  "filename": "credit_report.pdf",

  "metadata": {
    "subject_name": "Dela Cruz, Juan",
    "bureau_score": 650,
    "source_bureau": "CIBI",
    "report_date": "2024-01-15"
  },

  "credit_report_data": {
    "report_metadata": {
      "source_bureau": "CIBI",
      "report_type": "Individual",
      "request_date": "2024-01-15",
      "transaction_number": "TX-123456",
      "purpose": "Loan Application",
      "result": "Match",
      "page_count": 8,
      "bureau_score_value": 650,
      "bureau_score_band": "Fair"
    },

    "subject_person": {
      "last_name": "Dela Cruz",
      "first_name": "Juan",
      "middle_name": "Santos",
      "gender": "Male",
      "nationality": "Filipino",
      "date_of_birth": "1990-05-15",
      "civil_status": "Single"
    },

    "accounts": [
      {
        "product_type": "Installment",
        "product_category": "Housing Loan",
        "party_role": "main_applicant",
        "contract_phase": "active",
        "provider_name": "BDO",
        "is_bank": true,
        "contract_start_date": "2022-01-01",
        "financed_amount": 2000000,
        "outstanding_balance": 1800000,
        "monthly_payment": 15000,
        "overdue_payments_amount": 0,
        "last_payment_status": "OK",
        "worst_payment_status": "OK",
        "payment_history": [
          {
            "contract_phase": "active",
            "reference_date": "2024-01-01",
            "outstanding_balance": "1800000",
            "payment_status": "OK",
            "overdue_amount": "0"
          }
        ]
      }
    ],

    "summary_tables": {
      "summary_24m": [ ... ],
      "overall_summary": [ ... ],
      "active_accounts_summary": [ ... ]
    },

    "kyc_data": {
      "addresses": [ ... ],
      "contacts": [ ... ],
      "identity_documents": [ ... ],
      "relatives": [ ... ],
      "sole_traders": [ ... ],
      "employment": [ ... ]
    }
  }
}
```

### Generic Documents (BIR 2303, BIR 2307, Secretary's Certificate)

```python
result = client.process("bir.pdf", "bir_2303")
```

```json
{
  "status": "completed",
  "document_type": "bir_2303",
  "document_id": "654",
  "filename": "bir.pdf",
  "metadata": { ... },
  "extracted_data": { ... },
  "fraud_detection": { ... }
}
```

---

## Error Handling

```python
from kita import (
    KitaClient,
    KitaError,
    KitaAPIError,
    KitaAuthenticationError,
    KitaRateLimitError
)

try:
    result = client.process("doc.pdf", "bank_statement")
except KitaAuthenticationError:
    print("Invalid API key")
except KitaRateLimitError as e:
    print(f"Rate limited. Retry after {e.retry_after}s")
except KitaAPIError as e:
    print(f"API Error {e.status_code}: {e.message}")
except KitaError as e:
    print(f"SDK Error: {e}")
```

## Environment Variables

| Variable | Description | Default |
|----------|-------------|---------|
| `KITA_API_KEY` | API key | (required) |
| `KITA_API_URL` | API base URL | `https://portal.usekita.com` |

## License

MIT License
