2024-06-05 21:18:37 +02:00
|
|
|
# Copyright 2022 Collate
|
2025-04-03 10:39:47 +05:30
|
|
|
# Licensed under the Collate Community License, Version 1.0 (the "License");
|
2024-06-05 21:18:37 +02:00
|
|
|
# you may not use this file except in compliance with the License.
|
|
|
|
# You may obtain a copy of the License at
|
2025-04-03 10:39:47 +05:30
|
|
|
# https://github.com/open-metadata/OpenMetadata/blob/main/ingestion/LICENSE
|
2024-06-05 21:18:37 +02:00
|
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
# See the License for the specific language governing permissions and
|
|
|
|
# limitations under the License.
|
|
|
|
"""Test pydantic v2 models serialize data as pydantic v1"""
|
2024-06-07 04:36:17 +02:00
|
|
|
from datetime import datetime
|
2024-06-05 21:18:37 +02:00
|
|
|
|
|
|
|
from pydantic import AnyUrl
|
|
|
|
from pydantic.v1 import BaseModel as BaseModelV1
|
|
|
|
|
|
|
|
from metadata.generated.schema.type.basic import DateTime
|
|
|
|
from metadata.ingestion.models.custom_pydantic import BaseModel
|
|
|
|
|
|
|
|
|
|
|
|
def test_simple_dump():
|
|
|
|
"""
|
|
|
|
Compare V1 and custom V2 serialization,
|
|
|
|
due to https://github.com/pydantic/pydantic/issues/8825#issuecomment-1946206415
|
|
|
|
"""
|
|
|
|
|
|
|
|
class ModelV1(BaseModelV1):
|
|
|
|
a: str
|
|
|
|
b: int
|
|
|
|
date: datetime
|
|
|
|
|
|
|
|
class ModelV2(BaseModel):
|
|
|
|
a: str
|
|
|
|
b: int
|
|
|
|
date: datetime
|
|
|
|
|
|
|
|
data = {"a": "магазин", "b": 1, "date": datetime.now()}
|
|
|
|
|
|
|
|
model_v1 = ModelV1(**data)
|
|
|
|
model_v2 = ModelV2(**data)
|
|
|
|
|
|
|
|
json_v1 = model_v1.json()
|
|
|
|
json_v2 = model_v2.model_dump_json()
|
|
|
|
|
|
|
|
assert json_v1 == json_v2
|
|
|
|
|
|
|
|
|
|
|
|
def test_nested_dump():
|
|
|
|
"""Same as above, but with nested items."""
|
|
|
|
|
|
|
|
class NestedV1(BaseModelV1):
|
|
|
|
a: str
|
|
|
|
b: int
|
|
|
|
|
|
|
|
class ModelV1(BaseModelV1):
|
|
|
|
a: str
|
|
|
|
nested: NestedV1
|
|
|
|
|
|
|
|
class NestedV2(BaseModel):
|
|
|
|
a: str
|
|
|
|
b: int
|
|
|
|
|
|
|
|
class ModelV2(BaseModel):
|
|
|
|
a: str
|
|
|
|
nested: NestedV2
|
|
|
|
|
|
|
|
data = {"a": "магазин", "nested": {"a": "магазин", "b": 1}}
|
|
|
|
|
|
|
|
model_v1 = ModelV1(**data)
|
|
|
|
model_v2 = ModelV2(**data)
|
|
|
|
|
|
|
|
json_v1 = model_v1.json()
|
|
|
|
json_v2 = model_v2.model_dump_json()
|
|
|
|
|
|
|
|
assert json_v1 == json_v2
|
|
|
|
|
|
|
|
|
|
|
|
def test_tz_aware_date():
|
|
|
|
"""Validate how we can create "aware" datetime objects"""
|
|
|
|
|
2024-06-07 04:36:17 +02:00
|
|
|
DateTime(datetime.now())
|
2024-06-05 21:18:37 +02:00
|
|
|
|
|
|
|
|
|
|
|
def test_any_url():
|
|
|
|
"""It always ends with /"""
|
|
|
|
assert str(AnyUrl("https://example.com")) == "https://example.com/"
|
|
|
|
assert str(AnyUrl("https://example.com/")) == "https://example.com/"
|
|
|
|
|
|
|
|
|
|
|
|
def test_get_secret_string():
|
|
|
|
"""We can get the right secret from our custom CustomSecretStr"""
|
|
|
|
from metadata.ingestion.models.custom_pydantic import CustomSecretStr
|
|
|
|
|
|
|
|
class MyModel(BaseModel):
|
|
|
|
secret: CustomSecretStr
|
|
|
|
no_secret: str
|
|
|
|
|
|
|
|
model = MyModel(secret="password", no_secret="hello")
|
|
|
|
|
|
|
|
assert model.secret.get_secret_value() == "password"
|
|
|
|
|
|
|
|
# key is shown when serialized
|
|
|
|
assert model.model_dump()["secret"] == "password"
|