Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
### Added

- A HTTPAdapter with wider parameters has been setup to better address scanning multiple files at the same time.
7 changes: 7 additions & 0 deletions ggshield/core/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from pygitguardian import GGClient, GGClientCallbacks
from pygitguardian.models import APITokensResponse, Detail, TokenScope
from requests import Session
from requests.adapters import HTTPAdapter

from . import ui
from .config import Config
Expand Down Expand Up @@ -101,6 +102,12 @@ def create_session(allow_self_signed: bool = False) -> Session:
)
urllib3.disable_warnings()
session.verify = False
# Mount HTTPAdapter with larger pool sizes for better concurrency
adapter = HTTPAdapter(
pool_maxsize=100, # default 10
)
session.mount("http://", adapter)
session.mount("https://", adapter)
return session


Expand Down
58 changes: 57 additions & 1 deletion tests/unit/core/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@
from pygitguardian import GGClient
from pygitguardian.models import APITokensResponse, Detail, TokenScope

from ggshield.core.client import check_client_api_key, create_client_from_config
from ggshield.core.client import (
check_client_api_key,
create_client_from_config,
create_session,
)
from ggshield.core.config import Config
from ggshield.core.errors import (
APIKeyCheckError,
Expand Down Expand Up @@ -239,3 +243,55 @@ def test_retrieve_client_unknown_custom_dashboard_url(isolated_fs: FakeFilesyste
config = Config()
config.cmdline_instance_name = "https://example.com"
create_client_from_config(config)


def test_create_session_mounts_http_adapter():
"""
GIVEN create_session is called
WHEN the session is created
THEN HTTPAdapter is mounted for both http:// and https://
"""
session = create_session()

# Verify adapters are mounted
assert "http://" in session.adapters
assert "https://" in session.adapters

from requests.adapters import HTTPAdapter

assert isinstance(session.get_adapter("http://example.com"), HTTPAdapter)
assert isinstance(session.get_adapter("https://example.com"), HTTPAdapter)


def test_create_session_pool_configuration():
"""
GIVEN create_session is called
WHEN the session is created
THEN the HTTPAdapter has the correct pool configuration
"""
session = create_session()

adapter = session.get_adapter("https://example.com")

# Verify pool configuration by checking the init parameters
assert getattr(adapter, "_pool_maxsize", None) == 100


@pytest.mark.parametrize("allow_self_signed", [True, False])
def test_create_session_with_self_signed_option(allow_self_signed: bool):
"""
GIVEN create_session is called with allow_self_signed parameter
WHEN the session is created
THEN HTTPAdapter is mounted regardless of allow_self_signed value
AND verify is set correctly
"""
session = create_session(allow_self_signed=allow_self_signed)

# Verify adapters are mounted
assert "https://" in session.adapters

# Verify SSL verification setting
if allow_self_signed:
assert session.verify is False
else:
assert session.verify is True
Loading