{"record":{"id":"507cc7bf2d515118","repo":"xtekky/gpt4free","slug":"cls-name-does-not-implement-get-quota-method","errorCode":null,"errorMessage":"{cls.__name__} does not implement get_quota method","messagePattern":"(.+?) does not implement get_quota method","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"warning","filePath":"g4f/providers/base_provider.py","lineNumber":310,"sourceCode":"            str: The created result as a string.\n        \"\"\"\n        raise NotImplementedError()\n\n\nclass AsyncGeneratorProvider(AbstractProvider):\n    \"\"\"\n    Provides asynchronous generator functionality for streaming results.\n    \"\"\"\n\n    supports_stream = True\n    use_stream_timeout = True\n    quota_url = None\n\n    @classmethod\n    async def get_quota(cls, api_key: Optional[str] = None, **kwargs) -> dict:\n        \"\"\"Get the quota information for the API key.\"\"\"\n        if cls.quota_url is None:\n            raise NotImplementedError(\n                f\"{cls.__name__} does not implement get_quota method\"\n            )\n        if not api_key and cls.needs_auth:\n            raise MissingAuthError(\"API key is required.\")\n        headers = {\"authorization\": f\"Bearer {api_key}\"} if api_key else {}\n        async with ClientSession() as session:\n            async with session.get(cls.quota_url, headers=headers) as response:\n                await raise_for_status(response)\n                return await response.json()\n\n    @staticmethod\n    @abstractmethod\n    async def create_async_generator(\n        model: str, messages: Messages, **kwargs\n    ) -> AsyncResult:\n        \"\"\"\n        Abstract method for creating an asynchronous generator.\n","sourceCodeStart":292,"sourceCodeEnd":328,"githubUrl":"https://github.com/xtekky/gpt4free/blob/973504e1770928ed5fb82f43da528f441ad9ddc3/g4f/providers/base_provider.py#L292-L328","documentation":"Raised by AsyncGeneratorProvider.get_quota when the class attribute quota_url is None — the default on the base class. The generic implementation can only fetch quota from a documented endpoint; providers that never define quota_url cannot support it, so the base method refuses rather than guessing.","triggerScenarios":"await SomeProvider.get_quota(api_key=...) where SomeProvider (or the base AsyncGeneratorProvider) leaves quota_url unset (None).","commonSituations":"Quota-checking UIs iterating over all installed providers and calling get_quota indiscriminately; custom PA providers that forgot to define quota_url; free/scraping providers that have no quota endpoint at all.","solutions":["Skip providers without an endpoint first: if Provider.quota_url is None: continue","If the upstream service has a real quota API, set quota_url on your subclass and get_quota will fetch it","Catch NotImplementedError around the call as a fallback guard"],"exampleFix":"# before\nquota = await provider.get_quota(api_key)\n\n# after\nif provider.quota_url is None:\n    quota = None\nelse:\n    quota = await provider.get_quota(api_key)","handlingStrategy":"type-guard","validationCode":"if provider.quota_url is None:\n    return None  # provider cannot report quota; skip the call\nreturn await provider.get_quota(api_key)","typeGuard":"def supports_quota(provider: type) -> bool:\n    return getattr(provider, \"quota_url\", None) is not None","tryCatchPattern":"try:\n    quota = await provider.get_quota(api_key=key)\nexcept NotImplementedError:\n    quota = None  # treat as 'quota unknown' rather than an error","preventionTips":["Filter provider lists by quota_url before calling get_quota","Treat NotImplementedError here as an expected 'unsupported' signal, not a bug"],"tags":["provider","quota","not-implemented"],"backgroundTag":null,"analyzedSha":"973504e1770928ed5fb82f43da528f441ad9ddc3","analyzedAt":"2026-08-14T23:45:32.408Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}