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

Code before:
                )

            for activity_data, entity in zip(activities_data, fetched_entities):
                response_dict: ActivityDataResponseDict = {
                    'id': activity_data['id'],
                    'version': activity_data.get('version'),
                    'payload': entity.to_dict() if entity is not None else None,
                }
                activities.append(response_dict)

        self.render_json(activities)


class AndroidPlatformParametersHandler(
    base.BaseHandler[Dict[str, str], Dict[str, str]]
):
    """Handler that exposes a minimal set of Android platform parameters
    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_min_version_code_for_recommending_app_update': {
                'schema': {'type': 'int'},
                'default_value': None,
            },
            'android_min_supported_version_code': {
                'schema': {'type': 'int'},
                'default_value': None,
            },
            'android_min_supported_api_level': {
                'schema': {'type': 'int'},
                'default_value': None,
            },
        }
    }

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

        Query parameters may override defaults; schema validation enforces
        correct types and returns 400 on parse errors.

Review comment (suggestion):
I don't think I buy this. You can have an "or" type for the default_value and the rest of the schema is consistent anyway for each of the parameters. So please use strict types.

Code after:
                    topic_fetchers.get_multiple_topics_by_ids_and_version(
                        ids_and_versions
                    )
                )

            for activity_data, entity in zip(activities_data, fetched_entities):
                response_dict: ActivityDataResponseDict = {
                    'id': activity_data['id'],
                    'version': activity_data.get('version'),
                    'payload': entity.to_dict() if entity is not None else None,
                }
                activities.append(response_dict)

        self.render_json(activities)


class AndroidPlatformParametersHandler(
    base.BaseHandler[Dict[str, str], Dict[str, str]]
):
    """Handler that returns Android platform parameters for testing."""

    GET_HANDLER_ERROR_RETURN_TYPE = feconf.HANDLER_TYPE_JSON
    URL_PATH_ARGS_SCHEMAS: Dict[str, str] = {}
    HANDLER_ARGS_SCHEMAS = {
        'GET': {
            'android_min_version_code_for_recommending_app_update': {
                'schema': {'type': 'int'},
                'default_value': None,
            },
            'android_min_supported_version_code': {
                'schema': {'type': 'int'},
                'default_value': None,
            },
            'android_min_supported_api_level': {
                'schema': {'type': 'int'},
                'default_value': None,
            },
        }
    }

    @acl_decorators.open_access
    def get(self) -> None:
        """Returns platform parameters as a JSON array of objects.

        This is a temporary implementation that allows query parameters to override
        defaults. Schema validation ensures that invalid parameter values result in
        a 400 error response.

        Each list item has:
            - name (str): the parameter name.
            - value (int): the resolved parameter value.