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, TimeoutConfig

# Create custom timeout configuration
timeouts = TimeoutConfig(
    ble_connect=20.0,      # 20 seconds for BLE connection
    ble_disconnect=10.0,   # 10 seconds for disconnection
    http_request=15.0,     # 15 seconds for HTTP requests
    command_response=10.0, # 10 seconds for command responses
    cohn_ready=60.0        # 60 seconds to wait for COHN
)

client = GoProClient(identifier="1234", timeout_config=timeouts)

Persistent COHN Configuration

from gopro_sdk import GoProClient, CohnConfigManager

async def use_saved_config():
    """Use saved COHN configuration."""
    client = GoProClient(identifier="1234")
    config_mgr = CohnConfigManager()

    # Try to load saved config
    saved_config = config_mgr.load_config("1234")

    await client.open_ble()

    if saved_config:
        # Use saved configuration
        print("Using saved COHN configuration")
        await client.apply_cohn_config(saved_config)
    else:
        # First time setup
        print("Configuring COHN for the first time")
        config = await client.configure_cohn(
            ssid="your-wifi",
            password="password"
        )
        # Save for future use
        config_mgr.save_config("1234", config)

    await client.wait_cohn_ready()

Managing Multiple Camera Configs

from gopro_sdk import CohnConfigManager

def manage_camera_configs():
    """Manage configurations for multiple cameras."""
    config_mgr = CohnConfigManager()

    # List all saved configurations
    configs = config_mgr.list_configs()
    print(f"Found {len(configs)} saved configurations")

    for identifier in configs:
        config = config_mgr.load_config(identifier)
        print(f"Camera {identifier}: {config.ssid}")

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

Custom Cache Directory

from gopro_sdk import CohnConfigManager
from pathlib import Path

# Use custom directory for config storage
custom_dir = Path.home() / ".gopro_configs"
config_mgr = CohnConfigManager(cache_dir=custom_dir)