Skip to main content

Backend validation package for CountriesDB - server-side validation for country and subdivision codes

Project description

countriesdb-validator

Backend validation package for CountriesDB. Provides server-side validation for country and subdivision codes using ISO 3166-1 and ISO 3166-2 standards.

📖 Full Documentation | 🌐 Website

Important: This package only provides validation methods. Data fetching for frontend widgets must be done through frontend packages (@countriesdb/widget-core, @countriesdb/widget).

Getting Started

⚠️ API Key Required: This package requires a CountriesDB private API key to function. You must create an account at countriesdb.com to obtain your private API key. Test accounts are available with limited functionality.

Installation

pip install countriesdb-validator

Usage

Basic Validation

from validator import CountriesDBValidator

validator = CountriesDBValidator({
    "api_key": "YOUR_API_KEY",
})

# Validate a single country
result = validator.validate_country("US")
print(result)  # {"valid": True} or {"valid": False, "message": "..."}

# Validate a single subdivision
subdivision_result = validator.validate_subdivision("US-CA", "US")
print(subdivision_result)  # {"valid": True} or {"valid": False, "message": "..."}

Multiple Values

# Validate multiple countries
results = validator.validate_countries(["US", "CA", "MX"])
# Returns: [{"code": "US", "valid": True}, {"code": "CA", "valid": True}, ...]

# Validate multiple subdivisions
subdivision_results = validator.validate_subdivisions(
    ["US-CA", "US-NY", "US-TX"],
    "US"
)
# Returns: [{"code": "US-CA", "valid": True}, ...]

Validation Options

# Country validation with follow_upward
result = validator.validate_country("US", follow_upward=True)
# Check if country is referenced in a subdivision

# Subdivision validation with options
result = validator.validate_subdivision(
    "US-CA",
    "US",
    follow_related=True,  # Check if subdivision redirects to another country
    allow_parent=True     # Allow selecting parent subdivisions
)

API Reference

CountriesDBValidator

Main validator class.

Constructor

CountriesDBValidator(config: dict)

Config:

  • api_key (required): Your CountriesDB API key

Methods

validate_country(code, follow_upward=False)

Validate a single country code.

Parameters:

  • code (str): ISO 3166-1 alpha-2 country code
  • follow_upward (bool): Check if country is referenced in a subdivision

Returns: ValidationResult (dict with valid bool and optional message)

validate_countries(codes)

Validate multiple country codes.

Parameters:

  • codes (List[str]): List of ISO 3166-1 alpha-2 country codes

Returns: List[ValidationResult] (each with code, valid, and optional message)

validate_subdivision(code, country, follow_related=False, allow_parent=False)

Validate a single subdivision code.

Parameters:

  • code (str | None): Subdivision code (e.g., 'US-CA') or None/empty string
  • country (str): ISO 3166-1 alpha-2 country code
  • follow_related (bool): Check if subdivision redirects to another country
  • allow_parent (bool): Allow selecting parent subdivisions

Returns: ValidationResult (dict with valid bool and optional message)

validate_subdivisions(codes, country, allow_parent=False)

Validate multiple subdivision codes.

Parameters:

  • codes (List[str | None]): List of subdivision codes or None/empty strings
  • country (str): ISO 3166-1 alpha-2 country code
  • allow_parent (bool): Allow selecting parent subdivisions

Returns: List[ValidationResult] (each with code, valid, and optional message)

Examples

Django Validation

from validator import CountriesDBValidator
from django.core.exceptions import ValidationError

validator = CountriesDBValidator({
    "api_key": settings.COUNTRIESDB_API_KEY,
})

def validate_user_country(country_code: str, subdivision_code: str = None):
    """Validate user's country and subdivision"""
    # Validate country
    result = validator.validate_country(country_code)
    if not result["valid"]:
        raise ValidationError(result["message"])
    
    # Validate subdivision
    if subdivision_code:
        result = validator.validate_subdivision(subdivision_code, country_code)
        if not result["valid"]:
            raise ValidationError(result["message"])

Flask Validation

from validator import CountriesDBValidator
from flask import Flask, request, jsonify

app = Flask(__name__)
validator = CountriesDBValidator({
    "api_key": os.environ.get("COUNTRIESDB_API_KEY"),
})

@app.route("/api/user", methods=["POST"])
def create_user():
    data = request.json
    country = data.get("country")
    subdivision = data.get("subdivision")
    
    # Validate country
    result = validator.validate_country(country)
    if not result["valid"]:
        return jsonify({"error": result["message"]}), 422
    
    # Validate subdivision
    if subdivision:
        result = validator.validate_subdivision(subdivision, country)
        if not result["valid"]:
            return jsonify({"error": result["message"]}), 422
    
    # Proceed with user creation
    # ...
    return jsonify({"success": True}), 201

FastAPI Validation

from validator import CountriesDBValidator
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel

app = FastAPI()
validator = CountriesDBValidator({
    "api_key": os.environ.get("COUNTRIESDB_API_KEY"),
})

class UserData(BaseModel):
    country: str
    subdivision: str | None = None

@app.post("/api/user")
async def create_user(user_data: UserData):
    # Validate country
    result = validator.validate_country(user_data.country)
    if not result["valid"]:
        raise HTTPException(status_code=422, detail=result["message"])
    
    # Validate subdivision
    if user_data.subdivision:
        result = validator.validate_subdivision(
            user_data.subdivision,
            user_data.country
        )
        if not result["valid"]:
            raise HTTPException(status_code=422, detail=result["message"])
    
    # Proceed with user creation
    return {"success": True}

Error Handling

Single-Value Methods

Single-value methods (validate_country, validate_subdivision) return validation results with valid: False for invalid input. They only raise exceptions on network errors:

try:
    result = validator.validate_country("US")
    if not result["valid"]:
        print(f"Validation failed: {result['message']}")
except ValueError as e:
    print(f"Network error: {e}")

Multi-Value Methods

Multi-value methods (validate_countries, validate_subdivisions) return per-item results. Invalid codes are included in the results list with valid: False. They only raise exceptions on network errors or invalid input types:

try:
    results = validator.validate_countries(["US", "BAD", "CA"])
    # Results: [
    #   {"code": "US", "valid": True},
    #   {"code": "BAD", "valid": False, "message": "Invalid country code."},
    #   {"code": "CA", "valid": True}
    # ]
    
    for result in results:
        if not result["valid"]:
            print(f"Code {result['code']} failed: {result['message']}")
except ValueError as e:
    print(f"Network error: {e}")

Note:

  • Empty arrays return empty results lists (not an error)
  • Basic type checks are performed client-side (e.g., ensuring lists are lists, country is a string)
  • Format validation (e.g., 2-character country codes) is handled by the backend and included in results with appropriate error messages
  • Invalid format codes or invalid country codes are returned in the results list with valid: False rather than raising exceptions

Full backend examples

Clone-and-run projects that use this package (and the other SDKs) are available in the CountriesDB examples repository:

  • javascript/backend-fetch – native fetch
  • javascript/backend-axios – axios wrapper
  • javascript/backend-validator@countriesdb/validator package
  • javascript/backend-nextjs – Next.js App Router API routes
  • php/backend-laravel – PHP/Laravel validation rules
  • php/backend-guzzle – vanilla PHP + Guzzle
  • python/backend-requests – Python requests library
  • java/backend-httpclient and backend-spring – Java examples
  • csharp/backend-httpclient – C# .NET examples
  • go/backend-http – Go examples
  • ruby/backend-faraday – Ruby examples
  • bash/backend-curl – Bash cURL examples

Each folder includes a README with setup instructions so you can test the flows end-to-end.

Requirements

  • Python 3.8+
  • requests library

Additional Resources

License

PROPRIETARY

Copyright (c) NAYEE LLC. All rights reserved.

This software is the proprietary property of NAYEE LLC. For licensing inquiries, please contact NAYEE LLC.

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

countriesdb_validator-1.0.1.tar.gz (6.9 kB view details)

Uploaded Source

Built Distribution

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

countriesdb_validator-1.0.1-py3-none-any.whl (7.7 kB view details)

Uploaded Python 3

File details

Details for the file countriesdb_validator-1.0.1.tar.gz.

File metadata

  • Download URL: countriesdb_validator-1.0.1.tar.gz
  • Upload date:
  • Size: 6.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for countriesdb_validator-1.0.1.tar.gz
Algorithm Hash digest
SHA256 a5568f8bb220dad32aeb83f7a71168fb77d065f6056ce7a882b2eed979ad03be
MD5 1250a60d2e53bb9cd63ea097788553c0
BLAKE2b-256 0238db21b65ed809b70ca0462dca8317759038beb01c895684e3a51c0b4c299b

See more details on using hashes here.

File details

Details for the file countriesdb_validator-1.0.1-py3-none-any.whl.

File metadata

File hashes

Hashes for countriesdb_validator-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 501b8249fe1dfc49adc5b3e50aaff438afd7061b957f5e978bb5ee9ecb13fc1f
MD5 6da47481893a703ec00cbf27ec9c7a43
BLAKE2b-256 0e6483583878b9de94f9f3c1e8524e1e5e162e70beec9db5ed4771b02c72610d

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