Repository: oppia/oppia
File: core/controllers/android.py (Python)

Code before:
    base.BaseHandler[Dict[str, str], Dict[str, str]]
):
    """Handler that exposes a minimal set of Android feature flags
    for the Android client used in E2E tests.

    Supports optional GET query-parameter overrides. Invalid values will
    result in HTTP 400 responses thanks to schema validation.
    """

    GET_HANDLER_ERROR_RETURN_TYPE = feconf.HANDLER_TYPE_JSON
    URL_PATH_ARGS_SCHEMAS: Dict[str, str] = {}
    # Here we use object because the nested schema dictionaries contain mixed
    # value types (ints, bools, and nested dicts). No narrower type annotation
    # can represent all possible values without breaking mypy compatibility.
    HANDLER_ARGS_SCHEMAS: Dict[str, Dict[str, object]] = {
        'GET': {
            'android_enable_fast_language_switching_in_lesson': {
                'schema': {'type': 'bool'},
                'default_value': None,
            },
        }
    }

    @acl_decorators.open_access
    def get(self) -> None:
        """Returns feature flags as a list of {name, enabled} objects.

        Query parameters may override defaults; schema validation enforces
        correct types and returns 400 on parse errors.
        """
        assert self.normalized_request is not None

        defaults = {
            'android_enable_fast_language_switching_in_lesson': False,
        }

        result = []
        for name, default_enabled in defaults.items():
            override = self.normalized_request.get(name)
            enabled = override if override is not None else default_enabled
            result.append({'name': name, 'enabled': enabled})

        self.render_json(result)


Review comment (suggestion):
Define the return value more precisely. State its keys and values, their types, and what they indicate.

Code after:

class AndroidFeatureFlagsHandler(
    base.BaseHandler[Dict[str, str], Dict[str, str]]
):
    """Handler that returns Android feature flags for testing."""

    GET_HANDLER_ERROR_RETURN_TYPE = feconf.HANDLER_TYPE_JSON
    URL_PATH_ARGS_SCHEMAS: Dict[str, str] = {}
    HANDLER_ARGS_SCHEMAS = {
        'GET': {
            'android_enable_fast_language_switching_in_lesson': {
                'schema': {'type': 'bool'},
                'default_value': None,
            },
        }
    }

    @acl_decorators.open_access
    def get(self) -> None:
        """Returns Android feature flags as a JSON list of objects.

        Each item in the returned list has the structure:
            {
                'name': str,       # The name of the feature flag.
                'enabled': bool    # Whether the flag is enabled.
            }

        Query parameters may override the default values. Schema validation
        ensures that each override is a valid boolean; invalid values result in
        a 400 error.
        """
        assert self.normalized_request is not None

        defaults = {
            'android_enable_fast_language_switching_in_lesson': False,
        }

        result = []
        for name, default_enabled in defaults.items():
            override = self.normalized_request.get(name)
            enabled = override if override is not None else default_enabled
            result.append({'name': name, 'enabled': enabled})

        self.render_json(result)