Source code for clash_royale.client

from __future__ import annotations

import httpx

from .auth import CRAuth
from .exceptions import ClashRoyaleHTTPError
from .resources import (
    Cards,
    Clans,
    GlobalTournaments,
    Leaderboards,
    Locations,
    Players,
    Tournaments,
)

CURRENT_VERSION = "v1"
BASE_URL = f"https://api.clashroyale.com/{CURRENT_VERSION}"


[docs] class Client(httpx.Client): """ A client to retrieve data from the Clash Royale API. Create a client instance with the given options. >>> import clash_royale >>> client = clash_royale.Client(api_key="your_api_key_here") This client provides several methods to retrieve the content most kinds of Clash Royale objects, based on their json structure. If your server does not have a static IP address, you can use a proxy server by setting the `proxy` parameter. >>> client = clash_royale.Client( api_key="your_api_key_here", proxy="https://my.proxy.com", ) For more detail about proxy usage, check the usage section of the documentation. :param api_key: The Clash Royale API key. :param proxy: Proxy URL (default: None). :param timeout: Request timeout in seconds (default: 10.0). :param base_url: Base URL for the API (default: https://api.clashroyale.com/v1). """ players: Players clans: Clans cards: Cards tournaments: Tournaments leaderboards: Leaderboards locations: Locations global_tournaments: GlobalTournaments _auth: CRAuth
[docs] def __init__( self, api_key: str, proxy: str | None = None, timeout: float = 10.0, base_url: str = BASE_URL, ): self._auth = CRAuth(api_key) if proxy: # Ensure proxy URL has the version suffix if not proxy.endswith(CURRENT_VERSION): base_url = proxy.rstrip("/") + "/" + CURRENT_VERSION else: base_url = proxy super().__init__( base_url=base_url, auth=self._auth, timeout=timeout, ) self.players = Players(self) self.clans = Clans(self) self.cards = Cards(self) self.tournaments = Tournaments(self) self.leaderboards = Leaderboards(self) self.locations = Locations(self) self.global_tournaments = GlobalTournaments(self)
def _request( self, method: str, endpoint: str, params: dict[str, str | int] | None = None, ) -> dict: """Make an HTTP request to the API. :param method: HTTP method (GET, POST, etc.). :param endpoint: API endpoint (e.g., /players/{tag}). :param params: Query parameters. :returns: The JSON response as a dictionary. :raises ClashRoyaleNotFoundError: If resource is not found (404). :raises ClashRoyaleUnauthorizedError: If API key is invalid (403). :raises ClashRoyaleRateLimitError: If rate limit is exceeded (429). :raises ClashRoyaleBadRequestError: If request is malformed (400). :raises ClashRoyaleServerError: If server error occurs (5xx). :raises ClashRoyaleHTTPError: For other API errors. """ # Convert snake_case parameter names to camelCase for API compatibility if params: params = self._convert_params_to_camel_case(params) try: response = super().request(method, endpoint, params=params) response.raise_for_status() return response.json() except httpx.HTTPStatusError as exc: raise ClashRoyaleHTTPError.from_http_error(exc) from exc def _convert_params_to_camel_case( self, params: dict[str, str | int] ) -> dict[str, str | int]: """Convert snake_case parameter keys to camelCase for API. :param params: Dictionary with snake_case keys. :returns: Dictionary with camelCase keys. """ converted = {} for key, value in params.items(): # Convert snake_case to camelCase if "_" in key: parts = key.split("_") camel_key = parts[0] + "".join(word.capitalize() for word in parts[1:]) converted[camel_key] = value else: converted[key] = value return converted