Skip to main content

Thai VAT tax ID lookup with 10/13-digit support (RD VATINFO)

Project description

phasi-kit

Thai VAT tax ID lookup client for the Revenue Department (RD) VATINFO service.

Overview

  • NEW: Smart unified API - Auto-detects 10/13 digits, handles single/multi results intelligently
  • NEW: Full async support - High-performance async client with connection pooling
  • Auto-routing - Automatically validates and routes 10 or 13-digit tax IDs
  • Parse TIS-620 HTML into structured TaxInfo objects
  • Robust requests with retries, backoff, and rate limiting
  • Detailed logging via loguru for debugging

Requirements

  • Python 3.10+

Installation

  • Using pip (editable): pip install -e .
  • Using uv (fast installer):
    • Create/activate a virtualenv
    • Install editable: uv pip install -e .
    • With test extras: uv pip install -e ".[test]"

Quickstart

New Unified API (Recommended)

from phasi_kit import lookup, lookup_async

# Smart sync lookup - auto-detects 10/13 digits
result = lookup("0107555000023")  # Works with spaces/dashes too: "0107-555-000023"

# Intelligently handles single or multiple results
if result.is_single:
    print(result.company_name)  # Direct access for single result
else:
    for info in result:  # Iterate through multiple branches
        print(f"Branch {info.branch_no}: {info.company_name}")

# Or simply use .first for the most common case
print(result.first.company_name)

# Async version for high performance
import asyncio

async def check_tax():
    result = await lookup_async("3031571440")  # Auto-detects 10-digit
    return result.first.company_name

company = asyncio.run(check_tax())

Legacy API (Still Supported)

from phasi_kit import get_tax_info, get_tax_infos

# First matching result
info = get_tax_info("0107555000023")
print(info.company_name, info.address, info.status)

# All rows (multiple branches)
rows = get_tax_infos("0107555000023")
for r in rows:
    print(r.branch_no, r.company_name)

API

New Unified API

  • lookup(tax_id: str, branch_no: str | None = None) -> TaxInfoResult

    • Smart sync lookup with auto-detection of 10/13 digits
    • Returns TaxInfoResult wrapper that handles single/multi results intelligently
    • Automatically cleans input (removes spaces, dashes)
  • lookup_async(tax_id: str, branch_no: str | None = None) -> TaxInfoResult

    • Async version with same smart features
    • Uses connection pooling for high performance
  • TaxInfoResult - Smart wrapper with:

    • .is_single - Check if single result
    • .first - Get first result (works for any case)
    • .all - Get all results as list
    • .count - Number of results
    • Direct iteration: for info in result:
    • Branch helpers: .get_branch("0"), .hq, .branches

Clients

  • VATInfoClient - Enhanced sync client with:

    • Auto-routing for 10/13 digit tax IDs
    • Connection pooling (max_connections, max_keepalive_connections)
    • Automatic retries with exponential backoff
    • Rate limiting support
  • AsyncVATInfoClient - Full async client with:

    • All features of sync client
    • Async/await support
    • Request coalescing for concurrent identical requests
    • Context manager support: async with AsyncVATInfoClient() as client:

Legacy API (Backward Compatible)

  • get_tax_info() - Returns single TaxInfo
  • get_tax_infos() - Returns list[TaxInfo]
  • Original VATInfoClient methods still available

Examples

Smart Result Handling

from phasi_kit import lookup

# Auto-detects format and cleans input
result = lookup("0107-555-000023")  # Works with dashes
result = lookup("0107 555 000023")  # Works with spaces
result = lookup("0107555000023")    # Works with clean input

# Smart accessors
print(result.company_name)  # Direct attribute access (proxies to first)
print(result.first.address)  # Explicitly get first result
print(result.count)          # Number of results

# Branch operations
if result.has_branch("1"):
    branch1 = result.get_branch("1")
    print(branch1.company_name)

hq = result.hq  # Get headquarters (branch "0")
print(f"Branches: {result.branches}")  # List all branch numbers

Async High Performance

import asyncio
from phasi_kit import AsyncVATInfoClient

async def check_multiple():
    async with AsyncVATInfoClient(
        max_connections=20,  # Connection pooling
        enable_coalescing=True,  # Dedupe concurrent identical requests
    ) as client:
        # These run concurrently
        results = await asyncio.gather(
            client.lookup_smart("0107555000023"),
            client.lookup_smart("3031571440"),
            client.lookup_smart("0105547127301"),
        )
        return [r.first.company_name for r in results]

companies = asyncio.run(check_multiple())

Validation with Auto-Routing

from phasi_kit import validate_and_route_tax_id

# Validate and get routing info
validation = validate_and_route_tax_id("0107-555-000023")
if validation.is_valid:
    print(f"Type: {validation.tax_id_type}")  # "13"
    print(f"Cleaned: {validation.cleaned_id}")  # "0107555000023"
else:
    print(f"Error: {validation.error_message}")

Logging

  • This package uses loguru. Configure sinks/levels in your app:
from loguru import logger
logger.remove()
logger.add(sys.stderr, level="INFO")

Messages include request attempts, backoff decisions, not-found cases, and parsing fallbacks.

Features

Auto-Routing

  • Automatically detects 10 vs 13 digit tax IDs
  • Cleans input (removes spaces, dashes, dots)
  • Detailed validation with specific error messages
  • Caches validation results for performance

Performance

  • Connection pooling for reusing HTTP connections
  • Async support for concurrent lookups
  • Request coalescing (deduplicates concurrent identical requests)
  • Optional response caching with TTL

Robust Error Handling

  • TaxValidationError: Invalid tax ID format or checksum
  • TaxNotFoundError: Valid ID but no record found
  • TaxLookupError: Network/HTTP failures
  • Automatic retries with exponential backoff
  • Detailed loguru debugging throughout

Environment

  • PHASI_VATINFO_URL: Override the default RD endpoint if needed.

Notes

  • Auto-detection works with any format: "0107555000023", "0107-555-000023", "0107 555 000023"
  • The smart API eliminates the need to know beforehand if a tax ID has multiple branches
  • RD HTML is TIS-620 encoded; decoding is handled automatically
  • Branch numbers: 0 = HQ, 1-99998 = branch offices
  • All async operations use connection pooling for optimal performance

Development

  • Run tests: pytest -q

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

phasi_kit-0.2.0.tar.gz (95.2 kB view details)

Uploaded Source

Built Distribution

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

phasi_kit-0.2.0-py3-none-any.whl (27.1 kB view details)

Uploaded Python 3

File details

Details for the file phasi_kit-0.2.0.tar.gz.

File metadata

  • Download URL: phasi_kit-0.2.0.tar.gz
  • Upload date:
  • Size: 95.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for phasi_kit-0.2.0.tar.gz
Algorithm Hash digest
SHA256 b87e4bf40879508bca18dfa76d6cd8b13d73af8a418550d6b657733033b1cbf1
MD5 2dfb7126cbf96d04c86d8b130878cf6e
BLAKE2b-256 979a5266a3dc248959670b076978cc1c38d0b95b33d10ebc14bd21a03e274447

See more details on using hashes here.

File details

Details for the file phasi_kit-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: phasi_kit-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 27.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for phasi_kit-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9a23afd4b1212c78c3bf36678c4ecef5a95c07cd3912913a33584606b8c8b84a
MD5 c342f458345c607f2d777f5803ad6afd
BLAKE2b-256 18453f584f0e24f4d32963ac2eed929ab4cbc127be3de99c7f7855580dc2baa6

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