Skip to content

honeyhive.config.models.http_client

HTTP client configuration models for HoneyHive SDK.

This module provides Pydantic models for HTTP client configuration including connection pooling, timeouts, retry behavior, proxy settings, and SSL configuration.

HTTPClientConfig

Bases: BaseHoneyHiveConfig

HTTP client configuration settings.

This class extends BaseHoneyHiveConfig with HTTP-specific settings for connection pooling, timeouts, retry behavior, proxy settings, and SSL configuration. Supports both HH_ and standard HTTP_ environment variables.

Example

config = HTTPClientConfig( ... timeout=30.0, ... max_connections=50, ... http_proxy="http://proxy.company.com:8080" ... )

Or load from environment variables:

export HH_TIMEOUT=30.0

export HH_MAX_CONNECTIONS=50

config = HTTPClientConfig()

Source code in src/honeyhive/config/models/http_client.py
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
class HTTPClientConfig(BaseHoneyHiveConfig):
    """HTTP client configuration settings.

    This class extends BaseHoneyHiveConfig with HTTP-specific settings
    for connection pooling, timeouts, retry behavior, proxy settings,
    and SSL configuration. Supports both HH_* and standard HTTP_*
    environment variables.

    Example:
        >>> config = HTTPClientConfig(
        ...     timeout=30.0,
        ...     max_connections=50,
        ...     http_proxy="http://proxy.company.com:8080"
        ... )
        >>> # Or load from environment variables:
        >>> # export HH_TIMEOUT=30.0
        >>> # export HH_MAX_CONNECTIONS=50
        >>> config = HTTPClientConfig()
    """

    # Connection settings
    timeout: float = Field(  # type: ignore[call-overload,pydantic-alias]
        default=30.0,
        description="Request timeout in seconds",
        validation_alias=AliasChoices("HH_TIMEOUT", "timeout"),
        examples=[30.0, 60.0, 120.0],
    )

    max_connections: int = Field(  # type: ignore[call-overload,pydantic-alias]
        default=10,
        description="Maximum connections in pool",
        validation_alias=AliasChoices("HH_MAX_CONNECTIONS", "max_connections"),
        examples=[10, 50, 100],
    )

    max_keepalive_connections: int = Field(  # type: ignore[call-overload,pydantic-alias]  # pylint: disable=line-too-long
        default=20,
        description="Maximum keepalive connections",
        validation_alias=AliasChoices(
            "HH_MAX_KEEPALIVE_CONNECTIONS", "max_keepalive_connections"
        ),
        examples=[20, 50, 100],
    )

    keepalive_expiry: float = Field(  # type: ignore[call-overload,pydantic-alias]
        default=30.0,
        description="Keepalive expiry time in seconds",
        validation_alias=AliasChoices("HH_KEEPALIVE_EXPIRY", "keepalive_expiry"),
        examples=[30.0, 60.0, 300.0],
    )

    pool_timeout: float = Field(  # type: ignore[call-overload,pydantic-alias]
        default=10.0,
        description="Pool timeout in seconds",
        validation_alias=AliasChoices("HH_POOL_TIMEOUT", "pool_timeout"),
        examples=[10.0, 30.0, 60.0],
    )

    # Rate limiting
    rate_limit_calls: int = Field(  # type: ignore[call-overload,pydantic-alias]
        default=100,
        description="Maximum calls per time window",
        validation_alias=AliasChoices("HH_RATE_LIMIT_CALLS", "rate_limit_calls"),
        examples=[100, 200, 500],
    )

    rate_limit_window: float = Field(  # type: ignore[call-overload,pydantic-alias]
        default=60.0,
        description="Rate limit time window in seconds",
        validation_alias=AliasChoices("HH_RATE_LIMIT_WINDOW", "rate_limit_window"),
        examples=[60.0, 300.0, 3600.0],
    )

    max_retries: int = Field(  # type: ignore[call-overload,pydantic-alias]
        3,
        description="Maximum retry attempts",
        validation_alias=AliasChoices("HH_MAX_RETRIES", "max_retries"),
        examples=[3, 5, 10],
    )

    # Proxy settings
    http_proxy: Optional[str] = Field(  # type: ignore[call-overload,pydantic-alias]
        None,
        description="HTTP proxy URL",
        validation_alias=AliasChoices("HH_HTTP_PROXY", "http_proxy"),
        examples=["http://proxy.company.com:8080"],
    )

    https_proxy: Optional[str] = Field(  # type: ignore[call-overload,pydantic-alias]
        None,
        description="HTTPS proxy URL",
        validation_alias=AliasChoices("HH_HTTPS_PROXY", "https_proxy"),
        examples=["https://proxy.company.com:8080"],
    )

    no_proxy: Optional[str] = Field(  # type: ignore[call-overload,pydantic-alias]
        None,
        description="Comma-separated list of hosts to bypass proxy",
        validation_alias=AliasChoices("HH_NO_PROXY", "no_proxy"),
        examples=["localhost,127.0.0.1,.local"],
    )

    # SSL and redirects
    verify_ssl: bool = Field(  # type: ignore[call-overload,pydantic-alias]
        True,
        description="Verify SSL certificates",
        validation_alias=AliasChoices("HH_VERIFY_SSL", "verify_ssl"),
    )

    follow_redirects: bool = Field(  # type: ignore[call-overload,pydantic-alias]
        True,
        description="Follow HTTP redirects",
        validation_alias=AliasChoices("HH_FOLLOW_REDIRECTS", "follow_redirects"),
    )

    model_config = SettingsConfigDict(
        validate_assignment=True,
        extra="forbid",
        case_sensitive=False,
    )

    def __init__(self, **data: Any) -> None:
        """Initialize HTTP client config with environment variable fallbacks.

        Supports both HH_* and standard HTTP_* environment variables
        for maximum compatibility with existing infrastructure.
        """
        # Load from environment variables with fallbacks to standard env vars
        env_data = {
            "timeout": _get_env_float("HH_TIMEOUT", 30.0),
            "max_connections": _get_env_int(
                "HH_MAX_CONNECTIONS", _get_env_int("HTTP_MAX_CONNECTIONS", 10)
            ),
            "max_keepalive_connections": _get_env_int(
                "HH_MAX_KEEPALIVE_CONNECTIONS",
                _get_env_int("HTTP_MAX_KEEPALIVE_CONNECTIONS", 20),
            ),
            "keepalive_expiry": _get_env_float(
                "HH_KEEPALIVE_EXPIRY", _get_env_float("HTTP_KEEPALIVE_EXPIRY", 30.0)
            ),
            "pool_timeout": _get_env_float(
                "HH_POOL_TIMEOUT", _get_env_float("HTTP_POOL_TIMEOUT", 10.0)
            ),
            "rate_limit_calls": _get_env_int(
                "HH_RATE_LIMIT_CALLS", _get_env_int("HTTP_RATE_LIMIT_CALLS", 100)
            ),
            "rate_limit_window": _get_env_float(
                "HH_RATE_LIMIT_WINDOW", _get_env_float("HTTP_RATE_LIMIT_WINDOW", 60.0)
            ),
            "max_retries": _get_env_int("HH_MAX_RETRIES", 3),
            # Proxy settings with fallbacks
            "http_proxy": (
                os.getenv("HH_HTTP_PROXY")
                or os.getenv("HTTP_PROXY")
                or os.getenv("http_proxy")
            ),
            "https_proxy": (
                os.getenv("HH_HTTPS_PROXY")
                or os.getenv("HTTPS_PROXY")
                or os.getenv("https_proxy")
            ),
            "no_proxy": (
                os.getenv("HH_NO_PROXY")
                or os.getenv("NO_PROXY")
                or os.getenv("no_proxy")
            ),
            # SSL and redirects
            "verify_ssl": _get_env_bool(
                "HH_VERIFY_SSL", _get_env_bool("VERIFY_SSL", True)
            ),
            "follow_redirects": _get_env_bool(
                "HH_FOLLOW_REDIRECTS", _get_env_bool("FOLLOW_REDIRECTS", True)
            ),
        }

        # Merge environment data with provided data (provided data takes precedence)
        merged_data = {**env_data, **data}
        super().__init__(**merged_data)

    @field_validator(
        "timeout",
        "keepalive_expiry",
        "pool_timeout",
        "rate_limit_window",
        mode="before",
    )
    @classmethod
    def validate_positive_float(cls, v: Any) -> float:
        """Validate that float values are positive with graceful degradation."""
        # Handle type conversion gracefully
        try:
            if v is None:
                return 30.0  # Default for None
            v = float(v)
        except (ValueError, TypeError):
            logger = logging.getLogger(__name__)
            logger.warning(
                "Invalid float type: expected float, got %s. Using default 30.0.",
                type(v).__name__,
                extra={
                    "honeyhive_data": {"invalid_value": v, "type": type(v).__name__}
                },
            )
            return 30.0  # Safe default

        if v <= 0:
            logger = logging.getLogger(__name__)
            logger.warning(
                "Invalid timeout value: must be positive, got %s. Using default 30.0.",
                v,
                extra={"honeyhive_data": {"invalid_timeout": v}},
            )
            return 30.0  # Safe default
        return v  # type: ignore[no-any-return]

    @field_validator(
        "max_connections",
        "max_keepalive_connections",
        "rate_limit_calls",
        "max_retries",
        mode="before",
    )
    @classmethod
    def validate_positive_int(cls, v: Any) -> int:
        """Validate that integer values are positive with graceful degradation."""
        # Handle type conversion gracefully
        try:
            if v is None:
                return 100  # Default for None
            v = int(v)
        except (ValueError, TypeError):
            logger = logging.getLogger(__name__)
            logger.warning(
                "Invalid int type: expected int, got %s. Using default 100.",
                type(v).__name__,
                extra={
                    "honeyhive_data": {"invalid_value": v, "type": type(v).__name__}
                },
            )
            return 100  # Safe default

        if v <= 0:
            logger = logging.getLogger(__name__)
            logger.warning(
                (
                    "Invalid connection value: must be positive, got %s. "
                    "Using default 100."
                ),
                v,
                extra={"honeyhive_data": {"invalid_value": v}},
            )
            return 100  # Safe default
        return v  # type: ignore[no-any-return]

    @field_validator("http_proxy", "https_proxy", mode="before")
    @classmethod
    def validate_proxy_url(cls, v: Optional[str]) -> Optional[str]:
        """Validate proxy URL format with graceful degradation."""

        return _safe_validate_url(v, "proxy_url", allow_none=True, default=None)

timeout class-attribute instance-attribute

timeout: float = Field(
    default=30.0,
    description="Request timeout in seconds",
    validation_alias=AliasChoices("HH_TIMEOUT", "timeout"),
    examples=[30.0, 60.0, 120.0],
)

max_connections class-attribute instance-attribute

max_connections: int = Field(
    default=10,
    description="Maximum connections in pool",
    validation_alias=AliasChoices(
        "HH_MAX_CONNECTIONS", "max_connections"
    ),
    examples=[10, 50, 100],
)

max_keepalive_connections class-attribute instance-attribute

max_keepalive_connections: int = Field(
    default=20,
    description="Maximum keepalive connections",
    validation_alias=AliasChoices(
        "HH_MAX_KEEPALIVE_CONNECTIONS",
        "max_keepalive_connections",
    ),
    examples=[20, 50, 100],
)

keepalive_expiry class-attribute instance-attribute

keepalive_expiry: float = Field(
    default=30.0,
    description="Keepalive expiry time in seconds",
    validation_alias=AliasChoices(
        "HH_KEEPALIVE_EXPIRY", "keepalive_expiry"
    ),
    examples=[30.0, 60.0, 300.0],
)

pool_timeout class-attribute instance-attribute

pool_timeout: float = Field(
    default=10.0,
    description="Pool timeout in seconds",
    validation_alias=AliasChoices(
        "HH_POOL_TIMEOUT", "pool_timeout"
    ),
    examples=[10.0, 30.0, 60.0],
)

rate_limit_calls class-attribute instance-attribute

rate_limit_calls: int = Field(
    default=100,
    description="Maximum calls per time window",
    validation_alias=AliasChoices(
        "HH_RATE_LIMIT_CALLS", "rate_limit_calls"
    ),
    examples=[100, 200, 500],
)

rate_limit_window class-attribute instance-attribute

rate_limit_window: float = Field(
    default=60.0,
    description="Rate limit time window in seconds",
    validation_alias=AliasChoices(
        "HH_RATE_LIMIT_WINDOW", "rate_limit_window"
    ),
    examples=[60.0, 300.0, 3600.0],
)

max_retries class-attribute instance-attribute

max_retries: int = Field(
    3,
    description="Maximum retry attempts",
    validation_alias=AliasChoices(
        "HH_MAX_RETRIES", "max_retries"
    ),
    examples=[3, 5, 10],
)

http_proxy class-attribute instance-attribute

http_proxy: Optional[str] = Field(
    None,
    description="HTTP proxy URL",
    validation_alias=AliasChoices(
        "HH_HTTP_PROXY", "http_proxy"
    ),
    examples=["http://proxy.company.com:8080"],
)

https_proxy class-attribute instance-attribute

https_proxy: Optional[str] = Field(
    None,
    description="HTTPS proxy URL",
    validation_alias=AliasChoices(
        "HH_HTTPS_PROXY", "https_proxy"
    ),
    examples=["https://proxy.company.com:8080"],
)

no_proxy class-attribute instance-attribute

no_proxy: Optional[str] = Field(
    None,
    description="Comma-separated list of hosts to bypass proxy",
    validation_alias=AliasChoices(
        "HH_NO_PROXY", "no_proxy"
    ),
    examples=["localhost,127.0.0.1,.local"],
)

verify_ssl class-attribute instance-attribute

verify_ssl: bool = Field(
    True,
    description="Verify SSL certificates",
    validation_alias=AliasChoices(
        "HH_VERIFY_SSL", "verify_ssl"
    ),
)

follow_redirects class-attribute instance-attribute

follow_redirects: bool = Field(
    True,
    description="Follow HTTP redirects",
    validation_alias=AliasChoices(
        "HH_FOLLOW_REDIRECTS", "follow_redirects"
    ),
)

validate_positive_float classmethod

validate_positive_float(v: Any) -> float

Validate that float values are positive with graceful degradation.

Source code in src/honeyhive/config/models/http_client.py
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
@field_validator(
    "timeout",
    "keepalive_expiry",
    "pool_timeout",
    "rate_limit_window",
    mode="before",
)
@classmethod
def validate_positive_float(cls, v: Any) -> float:
    """Validate that float values are positive with graceful degradation."""
    # Handle type conversion gracefully
    try:
        if v is None:
            return 30.0  # Default for None
        v = float(v)
    except (ValueError, TypeError):
        logger = logging.getLogger(__name__)
        logger.warning(
            "Invalid float type: expected float, got %s. Using default 30.0.",
            type(v).__name__,
            extra={
                "honeyhive_data": {"invalid_value": v, "type": type(v).__name__}
            },
        )
        return 30.0  # Safe default

    if v <= 0:
        logger = logging.getLogger(__name__)
        logger.warning(
            "Invalid timeout value: must be positive, got %s. Using default 30.0.",
            v,
            extra={"honeyhive_data": {"invalid_timeout": v}},
        )
        return 30.0  # Safe default
    return v  # type: ignore[no-any-return]

validate_positive_int classmethod

validate_positive_int(v: Any) -> int

Validate that integer values are positive with graceful degradation.

Source code in src/honeyhive/config/models/http_client.py
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
@field_validator(
    "max_connections",
    "max_keepalive_connections",
    "rate_limit_calls",
    "max_retries",
    mode="before",
)
@classmethod
def validate_positive_int(cls, v: Any) -> int:
    """Validate that integer values are positive with graceful degradation."""
    # Handle type conversion gracefully
    try:
        if v is None:
            return 100  # Default for None
        v = int(v)
    except (ValueError, TypeError):
        logger = logging.getLogger(__name__)
        logger.warning(
            "Invalid int type: expected int, got %s. Using default 100.",
            type(v).__name__,
            extra={
                "honeyhive_data": {"invalid_value": v, "type": type(v).__name__}
            },
        )
        return 100  # Safe default

    if v <= 0:
        logger = logging.getLogger(__name__)
        logger.warning(
            (
                "Invalid connection value: must be positive, got %s. "
                "Using default 100."
            ),
            v,
            extra={"honeyhive_data": {"invalid_value": v}},
        )
        return 100  # Safe default
    return v  # type: ignore[no-any-return]

validate_proxy_url classmethod

validate_proxy_url(v: Optional[str]) -> Optional[str]

Validate proxy URL format with graceful degradation.

Source code in src/honeyhive/config/models/http_client.py
303
304
305
306
307
308
@field_validator("http_proxy", "https_proxy", mode="before")
@classmethod
def validate_proxy_url(cls, v: Optional[str]) -> Optional[str]:
    """Validate proxy URL format with graceful degradation."""

    return _safe_validate_url(v, "proxy_url", allow_none=True, default=None)