def load()

in client/securedrop_client/config.py [0:0]


    def load(cls) -> "Config":
        """For each attribute, look it up from either QubesDB or the environment."""
        config = {}

        with try_qubesdb() as db:
            for field in fields(cls):
                lookup = cls.mapping[field.name]
                if db:
                    logger.debug(f"Reading {lookup} from QubesDB")
                    value = db.read(f"/vm-config/{lookup}")
                    if not value or len(value) == 0:
                        if field.default == MISSING:
                            raise KeyError(f"Could not read {lookup} from QubesDB")
                        # Normalize for parity with the case where os.environ.get() is None
                        value = None
                else:
                    logger.debug(f"Reading {lookup} from environment")
                    value = os.environ.get(lookup)
                    if not value or len(value) == 0:
                        # Same normalization used for QubesDB
                        value = None

                if value is None and field.default != MISSING:
                    logger.debug(f"Using default value for {lookup}")
                    value = field.default

                # Cast to int if needed (might raise if value is invalid)
                # TODO: in theory we could `field.type(value)` but that doesn't
                # handle union types
                if field.type is int:
                    value = int(value)
                config[field.name] = value

        return cls(**config)