How ClientFactory.create_custom_provider Works in gpt4free: Dynamic Provider Generation

ClientFactory.create_custom_provider is a factory function that dynamically generates a new OpenAI-compatible provider class at runtime by subclassing OpenaiTemplate and injecting your custom endpoint configuration.

In the xtekky/gpt4free repository, this method enables seamless integration with self-hosted or third-party APIs without requiring manual provider module creation. By calling create_custom_provider, developers can instantiate client connections to any OpenAI-compatible endpoint using a programmatically generated provider class that inherits standard request handling logic from the base template.

Step-by-Step Implementation Details

The factory method is implemented in g4f/client/__init__.py (lines 22–67) and executes a four-stage process to construct viable provider classes on demand.

Deriving the Class Name from the Base URL

If no explicit name is provided, the function automatically generates one by parsing the supplied base_url. It extracts the network location, sanitizes periods into underscores, converts to title case, and removes separators:

from urllib.parse import urlparse
parsed = urlparse(base_url)
name = parsed.netloc.replace(".", "_").title().replace("_", "")

When URL parsing yields no usable hostname, the function falls back to the string "CustomProvider" to ensure valid Python class naming.

Configuring Class Attributes

The method assembles a dictionary of class attributes that define the provider's behavior. This configuration includes the API endpoint, authentication credentials, operational status, and model specifications:

class_attrs = {
    "url": base_url,
    "base_url": base_url.rstrip("/"),
    "api_key": api_key,
    "working": working,
    "default_model": default_model,
    "models": models or [],
    **kwargs,
}

The **kwargs spread operator allows passing additional custom configuration parameters directly into the class namespace.

Dynamic Class Generation with type()

Using Python’s built-in type constructor, the factory creates a new subclass of OpenaiTemplate (defined in g4f/Provider/template/OpenaiTemplate.py). This metaclass approach avoids manual class declaration:

CustomProvider = type(name, (OpenaiTemplate,), class_attrs)

The generated class inherits all standard OpenAI-compatible request and response handling methods from OpenaiTemplate while overriding endpoint-specific attributes with the custom configuration.

Registration and Return

After instantiation, the function logs the creation event and returns the new class object:

print(f"Created custom provider class '{name}' with base URL '{base_url}'")
return CustomProvider

The returned class functions identically to built-in providers and integrates directly with Client and AsyncClient instantiation workflows.

Practical Usage Examples

Creating a Custom Provider Manually

For explicit control over the generated class, import create_custom_provider directly and configure your endpoint parameters:

from g4f.client import create_custom_provider

# Generate a provider for a self-hosted LLM API

MyProvider = create_custom_provider(
    base_url="https://my.api.server/v1",
    api_key="my-secret-key",
    default_model="gpt-4o-mini",
    models=["gpt-4o-mini", "gpt-4-turbo"],
)

# Use with the standard Client interface

from g4f.client import Client
client = Client(provider=MyProvider)

response = client.chat_completion(
    messages=[{"role": "user", "content": "Hello, world!"}]
)
print(response)

Using ClientFactory for Automatic Generation

When using ClientFactory.create_client or create_async_client with a base_url parameter but no explicit provider, the factory internally calls create_custom_provider to bridge the configuration:

from g4f.client import ClientFactory

# Automatic provider generation and client instantiation

client = ClientFactory.create_client(
    base_url="https://my.api.server/v1",
    api_key="my-secret-key",
)

# The client operates using the dynamically generated provider

print(client.models)
response = client.chat_completion(messages=[{"role": "user", "content": "Test"}])

The custom:ID Shortcut Syntax

For registered custom endpoints, the factory accepts a custom:ID string format that resolves to a specific URL before triggering provider generation:


# Resolves to https://g4f.space/custom/abc123 internally

client = ClientFactory.create_client(
    provider="custom:abc123",
    api_key="my-secret-key",
)

The factory extracts the identifier, resolves the complete endpoint URL, invokes create_custom_provider, and returns a configured client instance ready for API communication.

Summary

  • create_custom_provider is defined in g4f/client/__init__.py (lines 22–67) and serves as the core factory for runtime provider generation.
  • The method derives class names from URL hostnames or defaults to "CustomProvider", configures endpoint attributes, and uses type() to subclass OpenaiTemplate.
  • Generated classes inherit standard OpenAI-compatible request handling from g4f/Provider/template/OpenaiTemplate.py while binding to custom base URLs.
  • Integration with ClientFactory.create_client and create_async_client enables zero-configuration usage patterns for custom endpoints.

Frequently Asked Questions

What base class does create_custom_provider use?

The factory generates subclasses of OpenaiTemplate, which is defined in g4f/Provider/template/OpenaiTemplate.py. This base class provides the standard create_completion and create_async methods that handle OpenAI-compatible request formatting, streaming, and response parsing, allowing generated providers to function immediately without additional method implementation.

Can I use create_custom_provider with AsyncClient?

Yes. When using ClientFactory.create_async_client() with a base_url parameter, the factory internally invokes create_custom_provider to generate the provider class, then instantiates an AsyncClient with that provider. The generated class supports both synchronous and asynchronous operations through the inherited OpenaiTemplate interface.

How does the provider name generation handle invalid URLs?

If urlparse(base_url) returns an empty netloc or the string manipulation yields an empty result, the factory defaults to using "CustomProvider" as the class name. This ensures that even with malformed or unusual URL schemes, the type() constructor receives a valid Python identifier for class creation.

Where is the custom provider logic defined in the source code?

The primary implementation resides in g4f/client/__init__.py between lines 22 and 67. The base provider template that supplies inherited functionality is located in g4f/Provider/template/OpenaiTemplate.py (starting at line 18). Client instantiation logic that orchestrates these components appears later in g4f/client/__init__.py around lines 54–89.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →