PK!R~fistro/__init__.py__version__ = '0.1.0' PK!Lczzfistro/config.pyfrom datetime import datetime, date from typing import FrozenSet INT_LENGTH = 9 STR_LENGTH = 9 MIN_YEAR = 0 MAX_YEAR = 2200 MIN_MONTH = 1 MAX_MONTH = 12 MIN_DAY = 1 MAX_DAY = 31 MIN_HOUR = 0 MAX_HOUR = 23 MIN_MINUTE = 0 MAX_MINUTE = 59 MIN_SECOND = 1 MAX_SECOND = 59 def supported_types() -> FrozenSet: return frozenset([int, str, datetime, date]) PK!Lk..fistro/exceptions.pyclass NotSupportedType(Exception): pass PK!+;RRfistro/factory.pyimport builtins from inspect import signature from typing import Type, Callable, List from fistro.config import supported_types from fistro.exceptions import NotSupportedType from fistro.generators import default_generators def builtin_types() -> List: return [ getattr(builtins, d) for d in dir(builtins) if isinstance(getattr(builtins, d), type) ] class Factory: def __init__(self, generators: List[Callable] = default_generators()): for generator in generators: type_name = signature(generator).return_annotation.__name__ setattr(self, f'{type_name}_generator', generator) def factory(self, typename: Type) -> Callable: if typename in supported_types(): try: return getattr(self, f'{typename.__name__}_generator') except AttributeError: # this is to protect against the case of some type generator is not provided return getattr(DefaultFactory(), f'{typename.__name__}_generator') raise NotSupportedType(f'Type {typename} is not supported') class DefaultFactory: def __init__(self): for generator in default_generators(): type_name = signature(generator).return_annotation.__name__ setattr(self, f'{type_name}_generator', generator) PK!D~  fistro/fistro.pyimport json from dataclasses import make_dataclass, field, asdict from typing import Type, Optional, List, Callable from fistro.factory import Factory def generate( a_class: Type, generators: Optional[List[Callable]] = None, as_dict: bool = False, as_json: bool = False, ) -> Type: annotations = a_class.__annotations__ defaults = [] for field_name in annotations.keys(): try: defaults.append(getattr(a_class, field_name)) except AttributeError: defaults.append(None) rich_annotations = [ ( name, typename, field( default_factory=Factory().factory(typename) if not generators else Factory(generators).factory(typename) ) if not defaults[i] else field(default=defaults[i]), ) for i, (name, typename) in enumerate(annotations.items()) ] dataclass = make_dataclass(a_class.__name__, rich_annotations) if as_dict: return asdict( dataclass() ) # to make asdict parameter must be an instance of dataclass if as_json: return json.dumps(asdict(dataclass())) return dataclass PK!n fistro/generators.pyimport string from datetime import datetime, date from random import randint, sample, choices from typing import Dict, Optional, Callable, List from fistro.config import ( MIN_YEAR, MAX_YEAR, MIN_MONTH, MAX_MONTH, MIN_DAY, MAX_DAY, MIN_HOUR, MAX_HOUR, MIN_MINUTE, MAX_MINUTE, MIN_SECOND, MAX_SECOND, STR_LENGTH, INT_LENGTH, ) # Name is not important, the important thing is the return type # if this one is repeated generator will be override def int_generator(length: int = INT_LENGTH) -> int: return randint(0, 9 * 10 ** length) def str_generator(population: str = string.printable, length: int = STR_LENGTH) -> str: return ''.join(choices(population, k=length)) def datetime_generator(rand_date: Optional[Dict[str, int]] = {}) -> datetime: min_year = rand_date.get('min_year', MIN_YEAR) max_year = rand_date.get('max_year', MAX_YEAR) min_month = rand_date.get('min_month', MIN_MONTH) max_month = rand_date.get('max_month', MAX_MONTH) min_day = rand_date.get('min_day', MIN_DAY) max_day = rand_date.get('max_day', MAX_DAY) min_hour = rand_date.get('min_hour', MIN_HOUR) max_hour = rand_date.get('max_hour', MAX_HOUR) min_minute = rand_date.get('min_minute', MIN_MINUTE) max_minute = rand_date.get('max_minute', MAX_MINUTE) min_second = rand_date.get('min_second', MIN_SECOND) max_second = rand_date.get('max_second', MAX_SECOND) year = randint(min_year, max_year) month = randint(min_month, max_month) day = randint(min_day, max_day) hour = randint(min_hour, max_hour) minute = randint(min_minute, max_minute) second = randint(min_second, max_second) the_date = datetime( year=year, month=month, day=day, hour=hour, minute=minute, second=second ) return datetime.strptime(str(the_date), '%Y-%m-%d %H:%M:%S') def date_generator(rand_date: Optional[Dict[str, int]] = None) -> date: if not rand_date: rand_date = {} min_year = rand_date.get('min_year', MIN_YEAR) max_year = rand_date.get('max_year', MAX_YEAR) min_month = rand_date.get('min_month', MIN_MONTH) max_month = rand_date.get('max_month', MAX_MONTH) min_day = rand_date.get('min_day', MIN_DAY) max_day = rand_date.get('max_day', MAX_DAY) year = randint(min_year, max_year) month = randint(min_month, max_month) day = randint(min_day, max_day) the_date = date(year=year, month=month, day=day) return datetime.strptime(str(the_date), '%Y-%m-%d').date() def default_generators() -> List[Callable]: return [int_generator, str_generator, datetime_generator, date_generator] PK!HlŃTTfistro-0.1.0.dist-info/WHEEL A н#J@Z|Jmqvh&#hڭw!Ѭ"J˫( } %PK!Hxfistro-0.1.0.dist-info/METADATA0 {=,(̢FDD mޡƻc7 NglJhVs&1z  z;q :N (K3( K#ԠN[(+(=4k9VYMCCP2a)'CUpt2`dQ{u}PK!H0 fistro-0.1.0.dist-info/RECORDuK0(neN]}M˪(%mh^s\cI~1nig ?$yB{E{$UYP¤8<%W^2lۛv9oucr!Veb%^Z-'A#iq Dm8m+_ˍ}/}uq<,z@W(ko@,z Zt)^ DAɃ^%(N˜߫^{