Skip to main content
Glama
pydantic

mcp-run-python

Official
by pydantic
test_google.py7.65 kB
"""Tests for Google JSON schema transformer. The GoogleJsonSchemaTransformer transforms JSON schemas for compatibility with Gemini API: - Converts `const` to `enum` with inferred `type` field - Removes unsupported fields like $schema, title, discriminator, examples - Handles format fields by moving them to description """ from __future__ import annotations as _annotations from typing import Literal from inline_snapshot import snapshot from pydantic import BaseModel from pydantic_ai.profiles.google import GoogleJsonSchemaTransformer, google_model_profile # ============================================================================= # Transformer Tests - const to enum conversion with type inference # ============================================================================= def test_const_string_infers_type(): """When converting const to enum, type should be inferred for string values.""" schema = {'const': 'hello'} transformer = GoogleJsonSchemaTransformer(schema) transformed = transformer.walk() assert transformed == snapshot({'enum': ['hello'], 'type': 'string'}) def test_const_integer_infers_type(): """When converting const to enum, type should be inferred for integer values.""" schema = {'const': 42} transformer = GoogleJsonSchemaTransformer(schema) transformed = transformer.walk() assert transformed == snapshot({'enum': [42], 'type': 'integer'}) def test_const_float_infers_type(): """When converting const to enum, type should be inferred for float values.""" schema = {'const': 3.14} transformer = GoogleJsonSchemaTransformer(schema) transformed = transformer.walk() assert transformed == snapshot({'enum': [3.14], 'type': 'number'}) def test_const_boolean_infers_type(): """When converting const to enum, type should be inferred for boolean values.""" schema = {'const': True} transformer = GoogleJsonSchemaTransformer(schema) transformed = transformer.walk() assert transformed == snapshot({'enum': [True], 'type': 'boolean'}) def test_const_false_boolean_infers_type(): """When converting const to enum, type should be inferred for False boolean.""" schema = {'const': False} transformer = GoogleJsonSchemaTransformer(schema) transformed = transformer.walk() assert transformed == snapshot({'enum': [False], 'type': 'boolean'}) def test_const_preserves_existing_type(): """When const has an existing type field, it should be preserved.""" schema = {'const': 'hello', 'type': 'string'} transformer = GoogleJsonSchemaTransformer(schema) transformed = transformer.walk() assert transformed == snapshot({'enum': ['hello'], 'type': 'string'}) def test_const_array_does_not_infer_type(): """When const is an array, type cannot be inferred and should not be added.""" schema = {'const': [1, 2, 3]} transformer = GoogleJsonSchemaTransformer(schema) transformed = transformer.walk() assert transformed == snapshot({'enum': [[1, 2, 3]]}) def test_const_in_nested_object(): """const should be properly converted in nested object properties.""" class TaggedModel(BaseModel): tag: Literal['hello'] value: str schema = TaggedModel.model_json_schema() transformer = GoogleJsonSchemaTransformer(schema) transformed = transformer.walk() # The tag property should have both enum and type assert transformed['properties']['tag'] == snapshot({'enum': ['hello'], 'type': 'string'}) # ============================================================================= # Transformer Tests - field removal # ============================================================================= def test_removes_schema_field(): """$schema field should be removed.""" schema = {'$schema': 'http://json-schema.org/draft-07/schema#', 'type': 'string'} transformer = GoogleJsonSchemaTransformer(schema) transformed = transformer.walk() assert '$schema' not in transformed assert transformed == snapshot({'type': 'string'}) def test_removes_title_field(): """title field should be removed.""" schema = {'title': 'MyString', 'type': 'string'} transformer = GoogleJsonSchemaTransformer(schema) transformed = transformer.walk() assert 'title' not in transformed assert transformed == snapshot({'type': 'string'}) def test_removes_discriminator_field(): """discriminator field should be removed.""" schema = {'discriminator': {'propertyName': 'type'}, 'type': 'object'} transformer = GoogleJsonSchemaTransformer(schema) transformed = transformer.walk() assert 'discriminator' not in transformed assert transformed == snapshot({'type': 'object'}) def test_removes_examples_field(): """examples field should be removed.""" schema = {'examples': ['foo', 'bar'], 'type': 'string'} transformer = GoogleJsonSchemaTransformer(schema) transformed = transformer.walk() assert 'examples' not in transformed assert transformed == snapshot({'type': 'string'}) def test_removes_exclusive_min_max(): """exclusiveMinimum and exclusiveMaximum should be removed.""" schema = {'type': 'integer', 'exclusiveMinimum': 0, 'exclusiveMaximum': 100} transformer = GoogleJsonSchemaTransformer(schema) transformed = transformer.walk() assert 'exclusiveMinimum' not in transformed assert 'exclusiveMaximum' not in transformed assert transformed == snapshot({'type': 'integer'}) # ============================================================================= # Transformer Tests - format handling # ============================================================================= def test_format_moved_to_description(): """format should be moved to description for string types.""" schema = {'type': 'string', 'format': 'date-time'} transformer = GoogleJsonSchemaTransformer(schema) transformed = transformer.walk() assert 'format' not in transformed assert transformed == snapshot({'type': 'string', 'description': 'Format: date-time'}) def test_format_appended_to_existing_description(): """format should be appended to existing description.""" schema = {'type': 'string', 'format': 'email', 'description': 'User email address'} transformer = GoogleJsonSchemaTransformer(schema) transformed = transformer.walk() assert 'format' not in transformed assert transformed == snapshot({'type': 'string', 'description': 'User email address (format: email)'}) # ============================================================================= # Model Profile Tests # ============================================================================= def test_model_profile_gemini_2(): """Gemini 2.x models should have proper profile settings.""" profile = google_model_profile('gemini-2.0-flash') assert profile is not None assert profile.json_schema_transformer == GoogleJsonSchemaTransformer assert profile.supports_json_schema_output is True def test_model_profile_gemini_3(): """Gemini 3.x models should support native output with builtin tools.""" profile = google_model_profile('gemini-3.0-pro') assert profile is not None assert profile.google_supports_native_output_with_builtin_tools is True # type: ignore def test_model_profile_image_model(): """Image models should have limited capabilities.""" profile = google_model_profile('gemini-2.0-flash-image') assert profile is not None assert profile.supports_image_output is True assert profile.supports_json_schema_output is False assert profile.supports_tools is False

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/pydantic/pydantic-ai'

If you have feedback or need assistance with the MCP directory API, please join our Discord server