Skip to content

Configuration

TimeoutConfig

gopro_sdk.config.TimeoutConfig dataclass

TimeoutConfig(
    ble_write_timeout: float = 10.0,
    ble_read_timeout: float = 10.0,
    ble_discovery_timeout: float = 5.0,
    ble_response_timeout: float = 5.0,
    ble_connect_timeout: float = 20.0,
    ble_service_discovery_timeout: float = 30.0,
    http_request_timeout: float = 30.0,
    http_download_timeout: float = 300.0,
    http_keep_alive_timeout: float = 8.0,
    http_initial_check_timeout: float = 2.0,
    wifi_scan_timeout: float = 15.0,
    wifi_scan_internal_timeout: float = 10.0,
    wifi_connect_configured_timeout: float = 15.0,
    wifi_provision_timeout: float = 60.0,
    cohn_provision_timeout: float = 60.0,
    cohn_wait_provisioned_timeout: float = 45.0,
    cohn_status_poll_interval: float = 1.0,
    connection_retry_interval: float = 2.0,
    max_reconnect_attempts: int = 3,
    camera_ready_timeout: float = 10.0,
    camera_ready_poll_interval: float = 0.5,
    http_keepalive_max_retries: int = 12,
    http_keepalive_retry_interval: float = 1.5,
    http_keepalive_timeout_threshold: int = 4,
    http_keepalive_fatal_threshold: int = 6,
    ip_wait_max_attempts: int = 5,
    ip_wait_interval: float = 3.0,
    preview_state_settle_delay: float = 0.2,
)

Timeout configuration.

Reference design document question 13, all timeout values are configurable.

CohnConfigManager

gopro_sdk.config.CohnConfigManager

CohnConfigManager(db_path: Path | None = None)

COHN configuration persistence manager.

Uses Repository pattern to encapsulate TinyDB operations. Database file is stored in user data directory.

Supports context manager protocol for automatic resource cleanup

with CohnConfigManager() as manager: manager.save(serial, credentials)

Initialize configuration manager.

Parameters:

Name Type Description Default
db_path Path | None

Database file path, defaults to cohn_credentials.json in current directory

None
Source code in src/gopro_sdk/config.py
def __init__(self, db_path: Path | None = None) -> None:
    """Initialize configuration manager.

    Args:
        db_path: Database file path, defaults to cohn_credentials.json in current directory
    """
    if db_path is None:
        db_path = Path("cohn_credentials.json")

    self._db_path = db_path
    self._db = TinyDB(str(db_path))
    self._table = self._db.table("credentials")
    logger.info(f"COHN configuration database initialized: {db_path}")

Functions

__enter__

__enter__() -> CohnConfigManager

Enter context manager.

Source code in src/gopro_sdk/config.py
def __enter__(self) -> CohnConfigManager:
    """Enter context manager."""
    return self

__exit__

__exit__(exc_type, exc_val, exc_tb) -> None

Exit context manager and close database.

Source code in src/gopro_sdk/config.py
def __exit__(self, exc_type, exc_val, exc_tb) -> None:
    """Exit context manager and close database."""
    self.close()

__del__

__del__() -> None

Cleanup: ensure database is closed when object is destroyed.

Source code in src/gopro_sdk/config.py
def __del__(self) -> None:
    """Cleanup: ensure database is closed when object is destroyed."""
    with contextlib.suppress(Exception):
        if hasattr(self, "_db") and self._db is not None:
            self._db.close()

save

save(serial: str, credentials: CohnCredentials) -> None

Save or update camera COHN credentials.

Parameters:

Name Type Description Default
serial str

Camera serial number (last 4 digits)

required
credentials CohnCredentials

COHN credentials

required
Source code in src/gopro_sdk/config.py
def save(self, serial: str, credentials: CohnCredentials) -> None:
    """Save or update camera COHN credentials.

    Args:
        serial: Camera serial number (last 4 digits)
        credentials: COHN credentials
    """
    query = Query()
    data = {"serial": serial, **credentials.to_dict()}

    # Update or insert
    if self._table.search(query.serial == serial):
        self._table.update(data, query.serial == serial)
        logger.info(f"Updated COHN credentials for camera {serial}")
    else:
        self._table.insert(data)
        logger.info(f"Saved COHN credentials for camera {serial}")

load

load(serial: str) -> CohnCredentials | None

Load camera COHN credentials.

Parameters:

Name Type Description Default
serial str

Camera serial number (last 4 digits)

required

Returns:

Type Description
CohnCredentials | None

COHN credentials, or None if not found

Source code in src/gopro_sdk/config.py
def load(self, serial: str) -> CohnCredentials | None:
    """Load camera COHN credentials.

    Args:
        serial: Camera serial number (last 4 digits)

    Returns:
        COHN credentials, or None if not found
    """
    query = Query()
    result = self._table.search(query.serial == serial)

    if not result:
        logger.debug(f"COHN credentials not found for camera {serial}")
        return None

    data = result[0]
    credentials = CohnCredentials.from_dict({
        "ip_address": data["ip_address"],
        "username": data["username"],
        "password": data["password"],
        "certificate": data["certificate"],
    })
    logger.debug(f"Loaded COHN credentials for camera {serial}: {credentials.ip_address}")
    return credentials

delete

delete(serial: str) -> bool

Delete camera COHN credentials.

Parameters:

Name Type Description Default
serial str

Camera serial number (last 4 digits)

required

Returns:

Type Description
bool

Whether deletion was successful

Source code in src/gopro_sdk/config.py
def delete(self, serial: str) -> bool:
    """Delete camera COHN credentials.

    Args:
        serial: Camera serial number (last 4 digits)

    Returns:
        Whether deletion was successful
    """
    query = Query()
    removed = self._table.remove(query.serial == serial)
    if removed:
        logger.info(f"Deleted COHN credentials for camera {serial}")
        return True
    else:
        logger.debug(f"COHN credentials for camera {serial} do not exist")
        return False

list_all

list_all() -> dict[str, CohnCredentials]

List all saved COHN credentials.

Returns:

Type Description
dict[str, CohnCredentials]

Mapping from serial number to credentials

Source code in src/gopro_sdk/config.py
def list_all(self) -> dict[str, CohnCredentials]:
    """List all saved COHN credentials.

    Returns:
        Mapping from serial number to credentials
    """
    all_records = self._table.all()
    result = {}

    for record in all_records:
        serial = record["serial"]
        credentials = CohnCredentials.from_dict({
            "ip_address": record["ip_address"],
            "username": record["username"],
            "password": record["password"],
            "certificate": record["certificate"],
        })
        result[serial] = credentials

    logger.debug(f"Listed all COHN credentials, total: {len(result)}")
    return result

close

close() -> None

Close database connection.

Source code in src/gopro_sdk/config.py
def close(self) -> None:
    """Close database connection."""
    if hasattr(self, "_db") and self._db is not None:
        self._db.close()
        self._db = None
        logger.debug("COHN configuration database closed")

CohnCredentials

gopro_sdk.config.CohnCredentials dataclass

CohnCredentials(
    ip_address: str,
    username: str,
    password: str,
    certificate: str,
)

COHN credentials information.

Attributes:

Name Type Description
ip_address str

IP address assigned by camera

username str

HTTP authentication username

password str

HTTP authentication password

certificate str

SSL certificate in PEM format (string)

Functions

to_dict

to_dict() -> dict[str, str]

Convert to dictionary.

Source code in src/gopro_sdk/config.py
def to_dict(self) -> dict[str, str]:
    """Convert to dictionary."""
    return {
        "ip_address": self.ip_address,
        "username": self.username,
        "password": self.password,
        "certificate": self.certificate,
    }

from_dict classmethod

from_dict(data: dict[str, str]) -> CohnCredentials

Create from dictionary.

Source code in src/gopro_sdk/config.py
@classmethod
def from_dict(cls, data: dict[str, str]) -> CohnCredentials:
    """Create from dictionary."""
    return cls(
        ip_address=data["ip_address"],
        username=data["username"],
        password=data["password"],
        certificate=data["certificate"],
    )

Usage Examples

Custom Timeouts

from gopro_sdk import GoProClient
from gopro_sdk.config import TimeoutConfig

# Create custom timeout configuration
timeouts = TimeoutConfig(
    ble_connect_timeout=30.0,         # 30 seconds for BLE connection
    ble_response_timeout=10.0,        # 10 seconds for BLE response
    http_request_timeout=60.0,        # 60 seconds for HTTP requests
    wifi_provision_timeout=120.0,     # 120 seconds for WiFi setup
    cohn_provision_timeout=90.0,      # 90 seconds for COHN setup
)

async with GoProClient("1234", timeout_config=timeouts) as client:
    await client.start_recording()

Persistent COHN Configuration

The SDK automatically manages COHN credential persistence via CohnConfigManager. When using online mode, credentials are saved on first connection and reused on subsequent connections.

from gopro_sdk import GoProClient, CohnConfigManager

async def use_persistent_config():
    """COHN credentials are automatically persisted."""
    # First connection: credentials are fetched and saved
    async with GoProClient(
        "1234",
        offline_mode=False,
        wifi_ssid="your-wifi",
        wifi_password="password",
    ) as client:
        status = await client.get_camera_state()
        print(f"Camera state: {status}")

    # Subsequent connections: saved credentials are reused automatically
    async with GoProClient(
        "1234",
        offline_mode=False,
    ) as client:
        print("Connected using saved COHN credentials!")

Managing Multiple Camera Configs

from gopro_sdk import CohnConfigManager, CohnCredentials

def manage_camera_configs():
    """Manage configurations for multiple cameras."""
    with CohnConfigManager() as config_mgr:
        # List all saved configurations
        all_creds = config_mgr.list_all()
        print(f"Found {len(all_creds)} saved configurations")

        for serial, creds in all_creds.items():
            print(f"Camera {serial}: IP {creds.ip_address}")

        # Load specific camera credentials
        creds = config_mgr.load("1234")
        if creds:
            print(f"Camera 1234: {creds.ip_address}")

        # Delete old configuration
        config_mgr.delete("old_camera_id")

Custom Database Path

from gopro_sdk import CohnConfigManager
from pathlib import Path

# Use custom path for credential storage
custom_path = Path.home() / ".gopro" / "cohn_credentials.json"
config_mgr = CohnConfigManager(db_path=custom_path)