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/
- 🔄 Sync & Async Support: Same API works for both sync and async
- 🚀 Custom Endpoints: Future-proof with any new SuperCell endpoints
- 💾 Intelligent Caching: Response caching with configurable TTL and statistics
- 🔁 Smart Retry Logic: Exponential backoff with configurable retry policies
- ⚡ Rate Limiting: Built-in protection against API rate limits (async mode)
- 🛡️ Comprehensive Error Handling: Detailed error messages and types
- 📊 Metrics & Analytics: Request performance tracking and insights
- 🔌 Middleware System: Pluggable request/response processing pipeline
- 🎯 Type Safety: Complete type hints and optional Pydantic models
- 🌐 Base URL Configuration: Support for proxies and testing environments
- 🔄 100% Backward Compatible: Drop-in replacement for existing code
# Standard installation (dict responses)
pip install cocapi
# With optional Pydantic models support
pip install 'cocapi[pydantic]'
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)
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()
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())
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%}")
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)
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()
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())
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
- Type Safety: Catch errors at development time
- IDE Support: Full autocompletion and type hints
- Data Validation: Automatic validation of API responses
- Clean Interface: Object-oriented access to data
- Documentation: Self-documenting code with model schemas
- Optional: Zero impact if not used (lazy imports)
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')
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()
- ⚡ Intelligent Caching: Up to 100% faster for repeated requests
- 🚀 Async Operations: Handle dozens of concurrent requests efficiently
- 🔁 Smart Retry Logic: Exponential backoff with configurable policies
- 📈 Monitoring: Track error rates, response times, and cache performance
# 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
])
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)
Major enterprise features while maintaining 100% backward compatibility:
- 📊 Enterprise Metrics: Comprehensive API performance monitoring
- 🔌 Middleware System: Pluggable request/response processing
- ⚡ Enhanced Async: Rate limiting and improved concurrency
- 🚀 Custom Endpoints: Future-proof support for new SuperCell endpoints
- 🎯 Type Safety: Enhanced type hints and Pydantic model integration
- 🌐 Base URL Config: Support for staging environments and proxies
pip install --upgrade cocapi
# Or with Pydantic support:
pip install --upgrade 'cocapi[pydantic]'
v2.2.x: Pydantic models, enhanced type safety, async + Pydantic support
v2.1.x: Unified async support, intelligent caching, retry logic, enhanced configuration
All methods work identically in both sync and async modes - just use await
when in async context!
api.clan_tag(tag) #example tag "#9UOVJJ9J"
Click to view output
{
"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": {}
}
api.clan_members(tag)
returns membersList information from api.clan_tag(tag) under "items" in dict
api.clan_war_log(tag)
Click to view output
{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': {}}
}
api.clan_current_war(tag)
Click to view output
{
"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"
}
api.clan_leaguegroup(tag)
Click to view output
{
"tag": "string",
"state": "string",
"season": "string",
"clans": [
{
"tag": "string",
"clanLevel": 0,
"name": "string",
"members": [
{
"tag": "string",
"townHallLevel": 0,
"name": "string"
}
],
"badgeUrls": {}
}
],
"rounds": [
{
"warTags": [
"string"
]
}
]
}
api.clan_capitalraidseasons(tag)
Retrieve clan's capital raid seasons information
Click to view output
{"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': {}}
}
api.warleague(war_tag)
Click to view output
{
"tag": "string",
"state": "string",
"season": "string",
"clans": [
{
"tag": "string",
"clanLevel": 0,
"name": "string",
"members": [
{
"tag": "string",
"townHallLevel": 0,
"name": "string"
}
],
"badgeUrls": {}
}
],
"rounds": [
{
"warTags": [
"string"
]
}
]
}
api.players(player_tag) #for example "#900PUCPV"
Click to view output
{
"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
}
api.location()
Click to view output
{"items":
[
{
"localizedName": "string",
"id": 0,
"name": "string",
"isCountry": true,
"countryCode": "string"
}
],
"paging": {'cursors': {}}
}
api.location_id(location_tag) #for example "32000047"
returns the above information for a single location
api.location_id_clan_rank(location_tag)
Top 200 clans in a given location
Click to view output
{"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': {}}
}
api.clan_leaguegroup(location_tag)
Top 200 players in a given location
Click to view output
{"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': {}}
}
api.location_clan_versus(location_tag)
Top 200 versus clans in a given location
Click to view output
{"items":
[
{
"clanPoints": 0,
"clanVersusPoints": 0
}
],
"paging": {'cursors': {}}
}
api.location_player_versus(location_tag)
Top 200 versus players in a given location
Click to view output
{"items":
[
{
"clan": {
"tag": "string",
"name": "string",
"badgeUrls": {}
},
"versusBattleWins": 0,
"tag": "string",
"name": "string",
"expLevel": 0,
"rank": 0,
"previousRank": 0,
"versusTrophies": 0
}
],
"paging": {'cursors': {}}
}
api.league()
Click to view output
{"items":
[
{
"name": {},
"id": 0,
"iconUrls": {}
}
],
"paging": {'cursors': {}}
}
api.league_id(league_tag)
Click to view output
{
"name": {},
"id": 0,
"iconUrls": {}
}
api.league_season(league_tag)
Information is available only for Legend League
Click to view output
{"items":
[
{
"id": "string"
}
],
"paging": {'cursors': {}}
}
api.league_season_id(league_tag, season_tag)
Information is available only for Legend League
Click to view output
{"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': {}}
}
api.capitalleagues()
Click to view output
{"items":
[
{
"name": {},
"id": 0,
"iconUrls": {}
}
],
"paging": {'cursors': {}}
}
api.capitalleagues_id(league_id)
Click to view output
{
"name": {},
"id": 0,
"iconUrls": {}
}
api.builderbaseleagues()
Click to view output
{"items":
[
{
"name": {},
"id": 0,
"iconUrls": {}
}
],
"paging": {'cursors': {}}
}
api.builderbaseleagues_id(league_id)
Click to view output
{
"name": {},
"id": 0,
"iconUrls": {}
}
api.warleagues()
Click to view output
{"items":
[
{
"name": {},
"id": 0,
"iconUrls": {}
}
],
"paging": {'cursors': {}}
}
api.warleagues_id(league_id)
Click to view output
{
"name": {},
"id": 0,
"iconUrls": {}
}
api.goldpass_seasons_current()
Get information about the current gold pass season
Click to view output
{
"startTime": "string",
"endTime": "string"
}
api.labels_clans()
Click to view output
{"items":
[
{
"name": {},
"id": 0,
"iconUrls": {}
}
],
"paging": {'cursors': {}}
}
api.labels_players()
Click to view output
{"items":
[
{
"name": {},
"id": 0,
"iconUrls": {}
}
],
"paging": {'cursors': {}}
}
Note versions below 2.0.0 are not supported anymore
*DISCLAIMER: cocapi is not affiliated with SuperCell©.