Untitled

mail@pastecode.io avatar
unknown
python
3 years ago
2.3 kB
6
Indexable
Never
import json
import random
from typing import Callable, Optional, TYPE_CHECKING, Type, cast

from faker import Faker
from pydantic import BaseModel


fake = Faker()


class FakerField:
    if TYPE_CHECKING:
        factory: Callable

    @classmethod
    def set_factory(cls, factory) -> Type["FakerField"]:
        # here you need to return a copy (subclass) as otherwise
        # you would overwrite the factory each time you use it
        # cause note it's a class not an instance!
        new_cls = type("FakerField", (cls,), {})
        new_cls = cast(Type["FakerField"], new_cls)
        new_cls.factory = factory
        return new_cls

    @classmethod
    def __get_validators__(cls):
        yield cls.validate

    @classmethod
    def validate(cls, v):
        if not hasattr(cls, "factory") or not cls.factory:
            raise AttributeError("FakerField has to have factory function set")
        return cls.factory()


def state_helper():
    return random.choice(["AL", "IL", "MA", "OR"])


class State(BaseModel):
    id: FakerField.set_factory(factory=lambda: random.choice(range(50)))
    name: FakerField.set_factory(factory=state_helper)


class Hometown(BaseModel):
    id: FakerField.set_factory(factory=lambda: random.choice(range(1000)))
    name: FakerField.set_factory(factory=fake.city)
    state: Optional[State]


class User(BaseModel):
    name: FakerField.set_factory(factory=fake.name)
    hometown: Optional[Hometown]



# # all fields should be overwritten
# assert output["name"] != json.loads(json_data)["name"]
# assert output["hometown"]["name"] != json.loads(json_data)["hometown"]["name"]
# assert output["hometown"]["id"] != json.loads(json_data)["hometown"]["id"]
# assert (
#     output["hometown"]["state"]["id"]
#     != json.loads(json_data)["hometown"]["state"]["id"]
# )
# assert (
#     output["hometown"]["state"]["name"]
#     != json.loads(json_data)["hometown"]["state"]["name"]
# )
# print(output)






# class Data(dict):
#     def __init__(self ):
#         self = dict() 
#     def add(self, key, value): 
#         self[key] = value
#     def __repr__(self):
#         return "{}({!r})".format(self.__class__.__name__, self.__dict__)