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_provideris defined ing4f/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 usestype()to subclassOpenaiTemplate. - Generated classes inherit standard OpenAI-compatible request handling from
g4f/Provider/template/OpenaiTemplate.pywhile binding to custom base URLs. - Integration with
ClientFactory.create_clientandcreate_async_clientenables 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →