cocapi

Python Wrapper for SuperCells Clash Of Clan API

View the Project on GitHub tonybenoy/cocapi

CI Status Pypi version

Python version License Ruff

ClashOfClansAPI

A high-performance Python wrapper for SuperCell’s Clash of Clans API with enterprise-grade features including async support, response caching, retry logic, middleware system, and comprehensive metrics.

🎯 Complete API Coverage: All 22 official endpoints implemented
⚑ High Performance: Async support with intelligent caching and rate limiting
πŸ”„ 100% Backward Compatible: Drop-in replacement for existing code
πŸ›‘οΈ Production Ready: Retry logic, middleware pipeline, metrics tracking, and comprehensive error handling
πŸš€ Future-Proof: Custom endpoint support and dynamic Pydantic models

Get Token from https://developer.clashofclans.com/

✨ Key Features

Install

# Standard installation (dict responses)
pip install cocapi

# With optional Pydantic models support
pip install 'cocapi[pydantic]'

Usage Examples

Basic Synchronous Usage (Backward Compatible)

from cocapi import CocApi

token = 'YOUR_API_TOKEN'
timeout = 60  # requests timeout

# Basic initialization (same as before)
api = CocApi(token, timeout)

# With status codes (same as before)
api = CocApi(token, timeout, status_code=True)

Advanced Configuration

from cocapi import CocApi, ApiConfig

# Enterprise-grade configuration
config = ApiConfig(
    # Performance settings
    timeout=30,
    max_retries=5,
    retry_delay=1.5,  # Base delay for exponential backoff
    
    # Caching configuration  
    enable_caching=True,
    cache_ttl=600,  # Cache responses for 10 minutes
    
    # Async rate limiting (async mode only)
    enable_rate_limiting=True,
    requests_per_second=10.0,
    burst_limit=20,
    
    # Advanced features
    enable_metrics=True,
    metrics_window_size=1000,  # Track last 1000 requests
    use_pydantic_models=False  # Enable for type-safe models
)

api = CocApi('YOUR_API_TOKEN', config=config)

# Management methods
cache_stats = api.get_cache_stats()
metrics = api.get_metrics()
api.clear_cache()
api.clear_metrics()

Asynchronous Usage

import asyncio
from cocapi import CocApi, ApiConfig

async def main():
    # Method 1: Automatic async mode with context manager (recommended)
    async with CocApi('YOUR_API_TOKEN') as api:
        clan = await api.clan_tag('#CLAN_TAG')
        player = await api.players('#PLAYER_TAG')
    
    # Method 2: Explicit async mode
    api = CocApi('YOUR_API_TOKEN', async_mode=True)
    async with api:
        clan = await api.clan_tag('#CLAN_TAG')
    
    # Method 3: With custom configuration
    config = ApiConfig(timeout=30, enable_caching=True)
    async with CocApi('YOUR_API_TOKEN', config=config) as api:
        clan = await api.clan_tag('#CLAN_TAG')

# Run async code
asyncio.run(main())

πŸš€ Enterprise Features

πŸ“Š Metrics & Analytics

from cocapi import CocApi, ApiConfig

# Enable metrics tracking
config = ApiConfig(enable_metrics=True, metrics_window_size=1000)
api = CocApi('YOUR_TOKEN', config=config)

# Get comprehensive metrics after API calls
metrics = api.get_metrics()
print(f"Total requests: {metrics['total_requests']}")
print(f"Average response time: {metrics['avg_response_time']:.2f}ms")
print(f"Cache hit rate: {metrics['cache_hit_rate']:.1%}")
print(f"Error rate: {metrics['error_rate']:.1%}")

πŸ”Œ Middleware System

from cocapi import CocApi
from cocapi.middleware import add_user_agent_middleware, add_request_id_middleware

api = CocApi('YOUR_TOKEN')

# Add built-in middleware
api.add_request_middleware(add_user_agent_middleware("MyApp/1.0"))
api.add_request_middleware(add_request_id_middleware())

# Custom middleware
def add_custom_headers(url, headers, params):
    headers['X-Client-Version'] = '3.0.0'
    return url, headers, params

api.add_request_middleware(add_custom_headers)

🎯 Enhanced Caching

from cocapi import CocApi, ApiConfig

config = ApiConfig(enable_caching=True, cache_ttl=900)  # 15 minutes
api = CocApi('YOUR_TOKEN', config=config)

# Requests are cached automatically
clan1 = api.clan_tag('#CLAN_TAG')  # Cache miss
clan2 = api.clan_tag('#CLAN_TAG')  # Cache hit

# Cache statistics and management
stats = api.get_cache_stats()
api.clear_cache()

⚑ Async Rate Limiting

from cocapi import CocApi, ApiConfig
import asyncio

async def high_throughput_example():
    config = ApiConfig(
        enable_rate_limiting=True,
        requests_per_second=10.0,
        burst_limit=20
    )
    
    async with CocApi('YOUR_TOKEN', config=config) as api:
        # Concurrent requests with automatic rate limiting
        clan_tags = ['#CLAN1', '#CLAN2', '#CLAN3']
        tasks = [api.clan_tag(tag) for tag in clan_tags]
        results = await asyncio.gather(*tasks)

asyncio.run(high_throughput_example())

Pydantic Models (Optional)

For enhanced type safety and structured data validation, cocapi supports optional Pydantic models:

from cocapi import CocApi, ApiConfig, Clan, Player

# Enable Pydantic models
config = ApiConfig(use_pydantic_models=True)
api = CocApi('YOUR_API_TOKEN', config=config)

# Get structured clan data
clan = api.clan_tag('#2PP')  # Returns Clan model instead of dict
print(clan.name)             # Type-safe attribute access
print(clan.clan_level)       # IDE autocompletion support
print(clan.members)          # Validated data structure

# Get structured player data  
player = api.players('#PLAYER_TAG')  # Returns Player model
print(player.town_hall_level)        # Type-safe attributes
print(player.trophies)
print(player.clan.name if player.clan else "No clan")

# Works with async too
async def get_data():
    config = ApiConfig(use_pydantic_models=True)
    async with CocApi('YOUR_TOKEN', config=config) as api:
        clan = await api.clan_tag('#TAG')  # Returns Clan model
        return clan.name

# Available models: Clan, Player, ClanMember, League, Achievement, etc.
# Import them: from cocapi import Clan, Player, ClanMember

Benefits of Pydantic Models

Custom Endpoints πŸš€

Use any new SuperCell endpoints immediately without waiting for library updates:

from cocapi import CocApi

api = CocApi('YOUR_API_TOKEN')

# Call new endpoints directly
result = api.custom_endpoint('/new-endpoint')
result = api.custom_endpoint('/clans/search', {'name': 'my clan', 'limit': 10})

# With dynamic Pydantic models
result = api.custom_endpoint('/new-endpoint', use_dynamic_model=True)
print(result.some_field)  # Type-safe access

# Async support
async with CocApi('YOUR_TOKEN') as api:
    result = await api.custom_endpoint('/new-endpoint')

Base URL Configuration 🌐

Modify base URL for testing, proxying, or adapting to API changes:

from cocapi import CocApi, ApiConfig

api = CocApi('YOUR_TOKEN')

# Change base URL (requires force=True for safety)
api.set_base_url("https://api-staging.example.com/v1", force=True)

# Or set during initialization
config = ApiConfig(base_url="https://my-proxy.com/clash/v1")
api = CocApi('YOUR_TOKEN', config=config)

# Reset to official endpoint
api.reset_base_url()

πŸ“ˆ Performance Benefits

Key Improvements

Example Setup

# High-performance configuration
config = ApiConfig(
    enable_caching=True,
    enable_metrics=True,
    max_retries=3
)

api = CocApi('token', config=config)

# Async mode with concurrency
async with CocApi('token', config=config) as api:
    clans = await asyncio.gather(*[
        api.clan_tag(tag) for tag in clan_tags
    ])

Migration Guide

πŸ”„ Upgrading to v3.0.0 - Zero Breaking Changes!

cocapi 3.0.0 maintains 100% backward compatibility. Your existing code continues to work unchanged:

# All existing patterns still work
from cocapi import CocApi

api = CocApi('YOUR_TOKEN')  # βœ… Works
api = CocApi('YOUR_TOKEN', 60, True)  # βœ… Works
clan = api.clan_tag('#CLAN_TAG')  # βœ… Works

# To use new features, just add configuration:
config = ApiConfig(enable_caching=True, cache_ttl=300)
api = CocApi('YOUR_TOKEN', config=config)

πŸš€ What’s New in v3.0.0

Major enterprise features while maintaining 100% backward compatibility:

Installation

pip install --upgrade cocapi
# Or with Pydantic support:
pip install --upgrade 'cocapi[pydantic]'

Previous Releases

v2.2.x: Pydantic models, enhanced type safety, async + Pydantic support
v2.1.x: Unified async support, intelligent caching, retry logic, enhanced configuration

Full API Reference

All methods work identically in both sync and async modes - just use await when in async context!


Clans

Information about a Clan

api.clan_tag(tag) #example tag "#9UOVJJ9J"
Click to view output ```text { "warLeague": { "name": {}, "id": 0 }, "memberList": [ { "league": { "name": {}, "id": 0, "iconUrls": {} }, "tag": "string", "name": "string", "role": "string", "expLevel": 0, "clanRank": 0, "previousClanRank": 0, "donations": 0, "donationsReceived": 0, "trophies": 0, "versusTrophies": 0 } ], "isWarLogPublic": true, "tag": "string", "warFrequency": "string", "clanLevel": 0, "warWinStreak": 0, "warWins": 0, "warTies": 0, "warLosses": 0, "clanPoints": 0, "clanVersusPoints": 0, "requiredTrophies": 0, "name": "string", "location": { "localizedName": "string", "id": 0, "name": "string", "isCountry": true, "countryCode": "string" }, "type": "string", "members": 0, "labels": [ { "name": {}, "id": 0, "iconUrls": {} } ], "description": "string", "badgeUrls": {} } ```

Members Only

api.clan_members(tag)

returns membersList information from api.clan_tag(tag) under β€œitems” in dict

War Log Information

api.clan_war_log(tag)
Click to view output ```text {items: [ { "clan": { "destructionPercentage": {}, "tag": "string", "name": "string", "badgeUrls": {}, "clanLevel": 0, "attacks": 0, "stars": 0, "expEarned": 0, "members": [ { "tag": "string", "name": "string", "mapPosition": 0, "townhallLevel": 0, "opponentAttacks": 0, "bestOpponentAttack": { "order": 0, "attackerTag": "string", "defenderTag": "string", "stars": 0, "destructionPercentage": 0 }, "attacks": [ { "order": 0, "attackerTag": "string", "defenderTag": "string", "stars": 0, "destructionPercentage": 0 } ] } ] }, "teamSize": 0, "opponent": { "destructionPercentage": {}, "tag": "string", "name": "string", "badgeUrls": {}, "clanLevel": 0, "attacks": 0, "stars": 0, "expEarned": 0, "members": [ { "tag": "string", "name": "string", "mapPosition": 0, "townhallLevel": 0, "opponentAttacks": 0, "bestOpponentAttack": { "order": 0, "attackerTag": "string", "defenderTag": "string", "stars": 0, "destructionPercentage": 0 }, "attacks": [ { "order": 0, "attackerTag": "string", "defenderTag": "string", "stars": 0, "destructionPercentage": 0 } ] } ] }, "endTime": "string", "result": "string" } ], "paging": {'cursors': {}} } ```

Current War Information

api.clan_current_war(tag)
Click to view output ```text { "clan": { "destructionPercentage": {}, "tag": "string", "name": "string", "badgeUrls": {}, "clanLevel": 0, "attacks": 0, "stars": 0, "expEarned": 0, "members": [ { "tag": "string", "name": "string", "mapPosition": 0, "townhallLevel": 0, "opponentAttacks": 0, "bestOpponentAttack": { "order": 0, "attackerTag": "string", "defenderTag": "string", "stars": 0, "destructionPercentage": 0 }, "attacks": [ { "order": 0, "attackerTag": "string", "defenderTag": "string", "stars": 0, "destructionPercentage": 0 } ] } ] }, "teamSize": 0, "opponent": { "destructionPercentage": {}, "tag": "string", "name": "string", "badgeUrls": {}, "clanLevel": 0, "attacks": 0, "stars": 0, "expEarned": 0, "members": [ { "tag": "string", "name": "string", "mapPosition": 0, "townhallLevel": 0, "opponentAttacks": 0, "bestOpponentAttack": { "order": 0, "attackerTag": "string", "defenderTag": "string", "stars": 0, "destructionPercentage": 0 }, "attacks": [ { "order": 0, "attackerTag": "string", "defenderTag": "string", "stars": 0, "destructionPercentage": 0 } ] } ] }, "startTime": "string", "state": "string", "endTime": "string", "preparationStartTime": "string" } ```

Clan League Group Information

api.clan_leaguegroup(tag)
Click to view output ```text { "tag": "string", "state": "string", "season": "string", "clans": [ { "tag": "string", "clanLevel": 0, "name": "string", "members": [ { "tag": "string", "townHallLevel": 0, "name": "string" } ], "badgeUrls": {} } ], "rounds": [ { "warTags": [ "string" ] } ] } ```

Clan Capital Raid Seasons

api.clan_capitalraidseasons(tag)

Retrieve clan’s capital raid seasons information

Click to view output ```text {"items": [ { "state": "string", "startTime": "string", "endTime": "string", "capitalTotalLoot": 0, "raidsCompleted": 0, "totalAttacks": 0, "enemyDistrictsDestroyed": 0, "offensiveReward": 0, "defensiveReward": 0, "members": [ { "tag": "string", "name": "string", "attacks": 0, "attackLimit": 0, "bonusAttackLimit": 0, "capitalResourcesLooted": 0 } ] } ], "paging": {'cursors': {}} } ```

Warleague Information

api.warleague(war_tag)
Click to view output ```text { "tag": "string", "state": "string", "season": "string", "clans": [ { "tag": "string", "clanLevel": 0, "name": "string", "members": [ { "tag": "string", "townHallLevel": 0, "name": "string" } ], "badgeUrls": {} } ], "rounds": [ { "warTags": [ "string" ] } ] } ```

Player

Player information

api.players(player_tag) #for example "#900PUCPV"
Click to view output ```text { "clan": { "tag": "string", "clanLevel": 0, "name": "string", "badgeUrls": {} }, "league": { "name": {}, "id": 0, "iconUrls": {} }, "townHallWeaponLevel": 0, "versusBattleWins": 0, "legendStatistics": { "previousSeason": { "trophies": 0, "id": "string", "rank": 0 }, "previousVersusSeason": { "trophies": 0, "id": "string", "rank": 0 }, "bestVersusSeason": { "trophies": 0, "id": "string", "rank": 0 }, "legendTrophies": 0, "currentSeason": { "trophies": 0, "id": "string", "rank": 0 }, "bestSeason": { "trophies": 0, "id": "string", "rank": 0 } }, "troops": [ { "level": 0, "name": {}, "maxLevel": 0, "village": "string" } ], "heroes": [ { "level": 0, "name": {}, "maxLevel": 0, "village": "string" } ], "spells": [ { "level": 0, "name": {}, "maxLevel": 0, "village": "string" } ], "role": "string", "attackWins": 0, "defenseWins": 0, "townHallLevel": 0, "labels": [ { "name": {}, "id": 0, "iconUrls": {} } ], "tag": "string", "name": "string", "expLevel": 0, "trophies": 0, "bestTrophies": 0, "donations": 0, "donationsReceived": 0, "builderHallLevel": 0, "versusTrophies": 0, "bestVersusTrophies": 0, "warStars": 0, "achievements": [ { "stars": 0, "value": 0, "name": {}, "target": 0, "info": {}, "completionInfo": {}, "village": "string" } ], "versusBattleWinCount": 0 } ```

Locations

All Locations Information

api.location()
Click to view output ```text {"items": [ { "localizedName": "string", "id": 0, "name": "string", "isCountry": true, "countryCode": "string" } ], "paging": {'cursors': {}} } ```

Information for a Single Location

api.location_id(location_tag) #for example "32000047"

returns the above information for a single location

Top Clans in a Location

api.location_id_clan_rank(location_tag)

Top 200 clans in a given location

Click to view output ```text {"items": [ { "clanLevel": 0, "clanPoints": 0, "location": { "localizedName": "string", "id": 0, "name": "string", "isCountry": true, "countryCode": "string" }, "members": 0, "tag": "string", "name": "string", "rank": 0, "previousRank": 0, "badgeUrls": {} } ], "paging": {'cursors': {}} } ```

Top Players in a Location

api.clan_leaguegroup(location_tag)

Top 200 players in a given location

Click to view output ```text {"items": [ { "clan": { "tag": "string", "name": "string", "badgeUrls": {} }, "league": { "name": {}, "id": 0, "iconUrls": {} }, "attackWins": 0, "defenseWins": 0, "tag": "string", "name": "string", "expLevel": 0, "rank": 0, "previousRank": 0, "trophies": 0 } ], "paging": {'cursors': {}} } ```

Top Versus Clans in a Location

api.location_clan_versus(location_tag)

Top 200 versus clans in a given location

Click to view output ```text {"items": [ { "clanPoints": 0, "clanVersusPoints": 0 } ], "paging": {'cursors': {}} } ```

Top Versus Players in a Location

api.location_player_versus(location_tag)

Top 200 versus players in a given location

Click to view output ```text {"items": [ { "clan": { "tag": "string", "name": "string", "badgeUrls": {} }, "versusBattleWins": 0, "tag": "string", "name": "string", "expLevel": 0, "rank": 0, "previousRank": 0, "versusTrophies": 0 } ], "paging": {'cursors': {}} } ```

Leagues

List leagues

api.league()
Click to view output ```text {"items": [ { "name": {}, "id": 0, "iconUrls": {} } ], "paging": {'cursors': {}} } ```

League Information

api.league_id(league_tag)
Click to view output ```text { "name": {}, "id": 0, "iconUrls": {} } ```

List Season Leagues

api.league_season(league_tag)

Information is available only for Legend League

Click to view output ```text {"items": [ { "id": "string" } ], "paging": {'cursors': {}} } ```

League Season Ranking

api.league_season_id(league_tag, season_tag)

Information is available only for Legend League

Click to view output ```text {"items": [ { "clan": { "tag": "string", "name": "string", "badgeUrls": {} }, "league": { "name": {}, "id": 0, "iconUrls": {} }, "attackWins": 0, "defenseWins": 0, "tag": "string", "name": "string", "expLevel": 0, "rank": 0, "previousRank": 0, "trophies": 0 } ], "paging": {'cursors': {}} } ```

List Capital Leagues

api.capitalleagues()
Click to view output ```text {"items": [ { "name": {}, "id": 0, "iconUrls": {} } ], "paging": {'cursors': {}} } ```

Capital League Information

api.capitalleagues_id(league_id)
Click to view output ```text { "name": {}, "id": 0, "iconUrls": {} } ```

List Builder Base Leagues

api.builderbaseleagues()
Click to view output ```text {"items": [ { "name": {}, "id": 0, "iconUrls": {} } ], "paging": {'cursors': {}} } ```

Builder Base League Information

api.builderbaseleagues_id(league_id)
Click to view output ```text { "name": {}, "id": 0, "iconUrls": {} } ```

List War Leagues

api.warleagues()
Click to view output ```text {"items": [ { "name": {}, "id": 0, "iconUrls": {} } ], "paging": {'cursors': {}} } ```

War League Information

api.warleagues_id(league_id)
Click to view output ```text { "name": {}, "id": 0, "iconUrls": {} } ```

Gold Pass

Current Gold Pass Season

api.goldpass_seasons_current()

Get information about the current gold pass season

Click to view output ```text { "startTime": "string", "endTime": "string" } ```

Labels

List Clan Labels

api.labels_clans()
Click to view output ```text {"items": [ { "name": {}, "id": 0, "iconUrls": {} } ], "paging": {'cursors': {}} } ```

List Player Labels

api.labels_players()
Click to view output ```text {"items": [ { "name": {}, "id": 0, "iconUrls": {} } ], "paging": {'cursors': {}} } ```

Credits

Note versions below 2.0.0 are not supported anymore

*DISCLAIMER: cocapi is not affiliated with SuperCellΒ©.