Example #1
0
 def __init__(self,
              name=None,
              flags=None,
              short_flag=None,
              long_flag=None,
              *args,
              **kwargs):
     short_flag = True if short_flag is None else short_flag
     long_flag = True if long_flag is None else long_flag
     if flags is None:
         flags = []
     if not isinstance(flags, list):
         flags = [flags]
     if not flags or short_flag or long_flag:
         if short_flag:
             short_name = name
             if short_flag is not True:
                 short_name = short_flag
             if short_name:
                 flags.append(f'-{short_name[0]}')
         if long_flag:
             long_name = name
             if long_flag is not True:
                 long_name = long_flag
             if long_name:
                 flags.append('--{}'.format(StringUtils.dash(long_name)))
                 flags.append('--{}'.format(StringUtils.snake(long_name)))
     super().__init__(name=name, flags=tuple(flags), *args, **kwargs)
Example #2
0
    def __init__(self, name=None, store=None, usage=None, **kwargs):
        """
        # Intialize the Flag Arg

        # Args
        - `name`, the name of the arg
        - `store`, the boolean value that this flag will take on when the arg
          has been specified. when True default is False, when False default is True
        """
        flags = (
            '-{}'.format(StringUtils.dash(name)),
            '-{}'.format(StringUtils.snake(name)),
        )
        if store is None:
            store = True
        if store is True:
            action = 'store_true'
        else:
            action = 'store_false'
        dest = StringUtils.snake(name)
        super().__init__(name=name,
                         dest=dest,
                         action=action,
                         flags=flags,
                         usage=usage)
Example #3
0
    def perform(self, context: Dict = None, **kwargs):
        if context is None:
            context = {}
        ctx = self.get_context()
        ctx.update({
            'app': 'cli',
            'entrypoint': StringUtils.dash(self.usage._package.__name__),
            'action': StringUtils.dash(self.usage._action.__name__),
        })
        ctx.update(context)

        # build a shell command
        # the first item is the command
        # the remaining items are arguments and kwarguments
        command = ctx['entrypoint']
        args = self.build_args([ctx['app'], ctx['action']] + ctx['args'])
        kwargs = self.build_kwargs(ctx['kwargs'])
        command_line = [command]
        command_line.extend(args)
        command_line.extend(kwargs)

        # optionally indent every line but the first
        if self._indent_after_command:
            command_line[1:] = [f'{self.INDENT}{k}' for k in command_line[1:]]
        # set the value of cli display for when rendering the template
        ctx['cli_display'] = self.SPLIT.join(command_line)
        # finally render the template
        return super().perform(context=ctx)
Example #4
0
def resolve_embryo_path(search_path: List[str], name: str) -> str:
    """
    Return the filepath for the embryo with the given name.
    """
    name = name.rstrip('/')
    if inspect.ismodule(name):
        # path to the provided python module
        return name.__path__._path[0]
    elif name[0] == '/':
        # absolute path to embryo dir
        return name
    else:
        for root_path in search_path:
            path = PathUtils.join(root_path, name)
            if PathUtils.exists(path):
                return path

            # try to coerce the name into the expected format
            name_parts = PathUtils.split(name)
            name_parts = [StringUtils.snake(n) for n in name_parts]
            path = PathUtils.join(root_path, *name_parts)
            if PathUtils.exists(path):
                return path

    def is_embryo(path):
        return os.path.isdir(path) and 'embryo.py' in os.listdir(path)

    for root_path in search_path:
        embryo_dirpath = PathUtils.join(root_path, name)
        if is_embryo(embryo_dirpath):
            return embryo_dirpath
        if is_embryo(embryo_dirpath.replace('-', '_')):
            return embryo_dirpath

    raise EmbryoNotFound(name)
Example #5
0
 def on_create():
     singular_name = StringUtils.singular(self.name)
     self.nested.name = singular_name
     self.nested.source = singular_name
     self.np_dtype = self.nested.np_dtype
     on_create_custom = kwargs.pop('on_create', None)
     if on_create_custom:
         on_create_custom()
Example #6
0
    def get_samples_path(cls, sample_type: Text = None):
        """
        # Get Samples Path
        Get the path containing all samples for a particular file type
        """

        return PathUtils.join(
            PathUtils.get_dir_path(__file__), 'sample',
            StringUtils.dash(cls.get_klass().__name__),
            sample_type if sample_type is not None else 'valid')
Example #7
0
 def _build_subparser_kwargs(self, func):
     parser_kwargs = self.decorator.kwargs.get('parser') or {}
     custom_args = self.decorator.kwargs.get('args') or []
     cli_args = self._build_cli_args(func, custom_args)
     name = StringUtils.dash(parser_kwargs.get('name') or self.program_name)
     return dict(parser_kwargs, **{
         'name': name,
         'args': cli_args,
         'perform': self,
     })
Example #8
0
 def _on_bootstrap_aggregate_response_message_types(self):
     """
     Build a lookup table of protobuf response Message types for use when
     routing requests to their downstream actions.
     """
     grpc = self.grpc
     grpc.response_types = {}
     for action in self.actions.values():
         schema_type_name = get_class_name(action.schemas.response)
         message_type_name = get_stripped_schema_name(
             StringUtils.camel(schema_type_name))
         response_message_type = getattr(self.grpc.pb2, message_type_name)
         grpc.response_types[action.name] = response_message_type
Example #9
0
    def _bootstrap_app_actions(self):
        for action in self.app.actions.values():
            action.bootstrap()

        on_parts = []
        pre_parts = []
        post_parts = deque()

        def is_virtual(func):
            return getattr(func, 'is_virtual', None)

        # middleware bootstrapping...
        for idx, mware in enumerate(self.app.middleware):
            mware.bootstrap(app=self.app)

            # everything below is for generating the log message
            # containing the "action execution diagram"
            name = StringUtils.snake(get_class_name(mware))
            if not is_virtual(mware.pre_request):
                pre_parts.append(f"↪ {name}.pre_request(raw_args, raw_kwargs)")

            if not is_virtual(mware.on_request):
                on_parts.append(f"↪ {name}.on_request(args, kwargs)")
            if not is_virtual(mware.post_request):
                if is_virtual(mware.post_bad_request):
                    post_parts.appendleft(f"↪ {name}.post_request(result)")
                else:
                    post_parts.appendleft(
                        f"↪ {name}.post_[bad_]request(result|error)")
            elif not is_virtual(mware.post_bad_request):
                post_parts.appendleft(f"↪ {name}.post_bad_request(error)")

        parts = []
        parts.append('➥ app.on_request(action, *raw_args, **raw_kwargs)')
        parts.extend(pre_parts)
        parts.append('➥ args, kwargs = action.marshal(raw_args, raw_kwargs)')
        parts.extend(on_parts)
        parts.append('➥ raw_result = action(*args, **kwargs)')
        parts.extend(post_parts)
        parts.append('➥ return app.on_response(action, raw_result)')

        diagram = '\n'.join(f'{"  " * (i+1)}{s}' for i, s in enumerate(parts))
        console.debug(message=(f"action execution diagram...\n\n {diagram}\n"))
Example #10
0
 def get_renderer(self, name: Text = None):
     """
     # Get Renderer
     Get a renderer by the provided name.  Name is a mapping available in
     `_renderers`
     """
     renderer = None
     if name is None and self._renderer:
         renderer = self._renderer
     if not self._renderers:
         raise RenderersNotDefinedError()
     if isinstance(name, str):
         # renderer is a string.  let's find a suitable renderer
         renderer = self._renderers.get(StringUtils.dash(name))
         if not renderer:
             raise InvalidUsageRendererError(data={'renderer': name})
     if not renderer:
         raise UnknownUsageRendererError()
     return renderer
Example #11
0
    def _build_func(self, action):
        key = StringUtils.camel(action.name)
        request_type = getattr(self._app.grpc.pb2, f'{key}Request')
        send_request = getattr(self._grpc_stub, action.name)

        def func(**kwargs):
            # prepare and send the request
            request = request_type(**kwargs)
            response = send_request(request)
            # translate the native proto response message to a plain dict
            if action.streams_response:
                data = [
                    self._extract_fields(x, action.schemas.response)
                    for x in response
                ]
            else:
                data = self._extract_fields(response, action.schemas.response)
            return data

        return func
Example #12
0
    def process_message(self, level: Text, message: Text, data: Dict) -> Text:
        when = TimeUtils.utc_now().strftime('%m/%d/%Y %H:%M:%S')
        level = level.upper()[0]

        if data:
            data = self._json.decode(self._json.encode(data))
            if self._style == 'json':
                dumped_data = self._to_json(data)
            elif self._style == 'yaml':
                dumped_data = self._to_yaml(data)
            else:
                raise ValueError(f'unrcognized log style: {self.style}')
        else:
            dumped_data = None

        thread = StringUtils.dash(current_thread().name)

        display_string = (f'{when} ({level}) {self._name}' f' - {message}')
        if dumped_data:
            display_string += f'\n\n{dumped_data}\n'
        return display_string
Example #13
0
    def on_bind(
        self,
        resource_type,
        root: Text = None,
        ftype: BaseFile = None,
        store_primitives=None,
        prefetch: bool = None,
        yaml_loader_class: Text = None,
    ):
        """
        Ensure the data dir exists for this Resource type.
        """
        if isinstance(ftype, str):
            self.ftype = import_object(ftype)

        if store_primitives is not None:
            self.store_primitives = store_primitives

        if prefetch is not None:
            self.do_prefetch = prefetch

        if yaml_loader_class is not None:
            if self.ftype.lower() == 'yaml':
                self.yaml_loader_class = getattr(
                    yaml, yaml_loader_class, None
                )
            else:
                self.yaml_loader_class = None

        self.paths.root = root or self.root
        self.paths.records = os.path.join(
            self.paths.root, StringUtils.snake(resource_type.__name__)
        )

        os.makedirs(self.paths.records, exist_ok=True)

        # bootstrap, bind, and backfill the in-memory cache
        if self.do_prefetch:
            self.bust_cache(self.do_prefetch)
Example #14
0
 def on_bootstrap(self):
     self._msg_name_prefix = StringUtils.camel(self.name)
     self.schemas.request = self._build_request_schema()
     self.schemas.response = self._build_response_schema()
Example #15
0
    def infer(
        cls,
        target: Dict,
        name: Text = None,
        predicate: Callable = None,
        depth: int = 0,
    ) -> Type['Schema']:
        """
        Return a new Schema class that mirrors the structure of the input target
        object, as best as possible.
        """
        acc = {}
        depth -= 1

        if not name:
            faker = Faker()
            name = f'{faker.color_name()}Schema'

        if predicate is None:
            predicate = lambda k, v: not k.startswith('_')

        py_type_2_field_type = {
            str: fields.String,
            int: fields.Int,
            float: fields.Float,
            bool: fields.Bool,
            bytes: fields.Bytes,
            UUID: fields.Uuid,
            datetime: fields.DateTime,
            date: fields.DateTime,
        }

        def build_nested_field(seq):
            contained_py_types = {type(x) for x in seq}
            if len(contained_py_types) == 1:
                sub_target = list(seq)[0]
                py_type = list(contained_py_types)[0]
                if py_type in py_type_2_field_type:
                    field_type = py_type_2_field_type[py_type]
                    return field_type(example=sub_target)
                elif py_type in (list, tuple, set):
                    nested = build_nested_field(sub_target)
                    return fields.List(nested)
                elif py_type is dict:
                    return cls.infer(target=sub_target,
                                     predicate=predicate,
                                     depth=(depth - 1))()
            return fields.Field()

        for k, v in target.items():
            if not predicate(k, v):
                continue

            if isinstance(v, dict):
                if depth != 0:
                    sub_schema_type = cls.infer(
                        target=v,
                        name=StringUtils.camel(f'{k}Schema'),
                        predicate=predicate,
                        depth=(depth - 1))
                    acc[k] = fields.Nested(sub_schema_type,
                                           name=k,
                                           source=k,
                                           example=v)
                else:
                    acc[k] = fields.Dict(name=k, source=k, example=v)

            else:
                scalar_field_type = py_type_2_field_type.get(type(v))
                if scalar_field_type:
                    if scalar_field_type is fields.String:
                        # TODO resolve String to more specific field type if possible
                        acc[k] = scalar_field_type(name=k, source=k, example=v)
                    else:
                        acc[k] = scalar_field_type(name=k, source=k, example=v)
                elif isinstance(v, (list, set, tuple)):
                    nested = build_nested_field(v)
                    nested.name = k
                    nested.source = k
                    if isinstance(nested, Schema):
                        type(nested).__name__ = StringUtils.camel(
                            f'{StringUtils.singular(k)}Schema', lower=False)
                    acc[k] = fields.List(nested=nested,
                                         name=k,
                                         source=k,
                                         example=v)
                else:
                    acc[k] = fields.Field(name=k, source=k, example=v)

        return type(name, (cls, ), acc)
Example #16
0
 def derive_table_name(resource_type: Type['Resource']) -> Text:
     return StringUtils.snake(get_class_name(resource_type))
Example #17
0
class String(Field):
    np_dtype = '<U1'

    generator = Field.Generator(callbacks={
        '_id':
        lambda f, **kwargs: UuidString.next_id(),
        'id':
        lambda f, **kwargs: str(f.faker.random_number(digits=16)),
        'public_id':
        lambda f, **kwargs: UuidString.next_id(),
        'first_name':
        lambda f, **kwargs: f.faker.first_name(),
        'last_name':
        lambda f, **kwargs: f.faker.last_name(),
        'full_name':
        lambda f, **kwargs: f.faker.name(),
        'name':
        lambda f, **kwargs: f.faker.catch_phrase().title(),
        'description':
        lambda f, **kwargs: f.faker.paragraph(nb_sentences=10),
        'descr':
        lambda f, **kwargs: f.faker.paragraph(nb_sentences=10),
        'summary':
        lambda f, **kwargs: f.faker.paragraph(nb_sentences=6),
        'comment':
        lambda f, **kwargs: f.faker.paragraph(nb_sentences=4),
        'city':
        lambda f, **kwargs: f.faker.city(),
        'address':
        lambda f, **kwargs: f.faker.address(),
        'phone':
        lambda f, **kwargs: f.faker.phone_number(),
        'phone_number':
        lambda f, **kwargs: f.faker.phone_number(),
        'mobile':
        lambda f, **kwargs: f.faker.phone_number(),
        'zip':
        lambda f, **kwargs: f.faker.zipcode(),
        'zip_code':
        lambda f, **kwargs: f.faker.zipcode(),
        'zipcode':
        lambda f, **kwargs: f.faker.zipcode(),
        'postal_code':
        lambda f, **kwargs: f.faker.zipcode(),
        'postalcode':
        lambda f, **kwargs: f.faker.zipcode(),
        'year':
        lambda f, **kwargs: f.faker.year(),
        'user_name':
        lambda f, **kwargs: f.faker.user_name(),
        'username':
        lambda f, **kwargs: f.faker.user_name(),
        'nick':
        lambda f, **kwargs: f.faker.user_name(),
        'handle':
        lambda f, **kwargs: f.faker.user_name(),
        'screen_name':
        lambda f, **kwargs: f.faker.user_name(),
        'screenname':
        lambda f, **kwargs: f.faker.user_name(),
        'state_code':
        lambda f, **kwargs: f.faker.state_abbr(),
        'state':
        lambda f, **kwargs: f.faker.state(),
        'country_code':
        lambda f, **kwargs: f.faker.country_code(),
        'country':
        lambda f, **kwargs: f.faker.country(),
        'card_number':
        lambda f, **kwargs: f.faker.credit_card_number(),
        'credit_card_number':
        lambda f, **kwargs: f.faker.credit_card_number(),
        'security_code':
        lambda f, **kwargs: f.faker.credit_card_security_code(),
        'credit_card_security_code':
        lambda f, **kwargs: f.faker.credit_card_security_code(),
        'label':
        lambda f, **kwargs: StringUtils.snake(f.faker.color_name()).lower(),
        'color':
        lambda f, **kwargs: StringUtils.snake(f.faker.color_name()).lower(),
        'currency_code':
        lambda f, **kwargs: f.faker.currency_code(),
        'currency_name':
        lambda f, **kwargs: f.faker.currency_name(),
        'ein':
        lambda f, **kwargs: f.faker.ein(),
        'filename':
        lambda f, **kwargs: f.faker.ein(),
        'file_name':
        lambda f, **kwargs: f.faker.ein(),
        'fname':
        lambda f, **kwargs: f.faker.ein(),
        'filepath':
        lambda f, **kwargs: f.faker.file_path(),
        'file_path':
        lambda f, **kwargs: f.faker.file_path(),
        'fpath':
        lambda f, **kwargs: f.faker.file_path(),
        'file_extension':
        lambda f, **kwargs: f.faker.file_extension(),
        'extension':
        lambda f, **kwargs: f.faker.file_extension(),
        'ext':
        lambda f, **kwargs: f.faker.file_extension(),
        'image_url':
        lambda f, **kwargs: f.faker.image_url(),
        'url':
        lambda f, **kwargs: f.faker.url(),
        'host':
        lambda f, **kwargs: f.faker.hostname(),
        'hostname':
        lambda f, **kwargs: f.faker.hostname(),
        'host_name':
        lambda f, **kwargs: f.faker.hostname(),
        'port':
        lambda f, **kwargs: str(random.randrange(1001, 10000)),
        'ssn':
        lambda f, **kwargs: f.faker.ssn(),
        'ip_addr':
        lambda f, **kwargs: f.faker.ipv4(),
        'ip_address':
        lambda f, **kwargs: f.faker.ipv4(),
        'ip':
        lambda f, **kwargs: f.faker.ipv4(),
        'ipv4':
        lambda f, **kwargs: f.faker.ipv4(),
        'ipv6':
        lambda f, **kwargs: f.faker.ipv6(),
        'langauge_code':
        lambda f, **kwargs: f.faker.langauge_code(),
        'license_plate':
        lambda f, **kwargs: f.faker.license_plate(),
        'locale':
        lambda f, **kwargs: f.faker.locale(),
        'mac_addr':
        lambda f, **kwargs: f.faker.mac_address(),
        'mac_address':
        lambda f, **kwargs: f.faker.mac_address(),
        'md5':
        lambda f, **kwargs: str(f.faker.md5()),
        'mime':
        lambda f, **kwargs: f.faker.mime_type(),
        'mime_type':
        lambda f, **kwargs: f.faker.mime_type(),
        'mimetype':
        lambda f, **kwargs: f.faker.mime_type(),
        'month':
        lambda f, **kwargs: f.faker.month(),
        'isbn':
        lambda f, **kwargs: f.faker.isbn(),
        'slug':
        lambda f, **kwargs: f.faker.slug(),
        'street':
        lambda f, **kwargs: f.faker.street_name(),
        'street_name':
        lambda f, **kwargs: f.faker.street_name(),
        'suffix':
        lambda f, **kwargs: f.faker.suffix(),
        'timezone':
        lambda f, **kwargs: f.faker.timezone(),
        'time_zone':
        lambda f, **kwargs: f.faker.timezone(),
        'tz':
        lambda f, **kwargs: f.faker.timezone(),
        'user_agent':
        lambda f, **kwargs: f.faker.user_agent(),
        'useragent':
        lambda f, **kwargs: f.faker.user_agent(),
        'ua':
        lambda f, **kwargs: f.faker.user_agent(),
        'text':
        lambda f, **kwargs: f.faker.text(),
        'event':
        lambda f, **kwargs: f.faker.word(),
        'event_name':
        lambda f, **kwargs: f.faker.word(),
        'email':
        lambda f, **kwargs: f.faker.email(),
        'email_addr':
        lambda f, **kwargs: f.faker.email(),
        'email_address':
        lambda f, **kwargs: f.faker.email(),
        'message':
        lambda f, **kwargs: f.faker.text(max_nb_chars=140),
        'keyword':
        lambda f, **kwargs: f.faker.word().lower(),
        'tag':
        lambda f, **kwargs: f.faker.word().lower(),
        'headline':
        lambda f, **kwargs: f.faker.catch_phrase().title(),
        'amount':
        lambda f, **kwargs: str(random.randrange(0, 51)),
        'count':
        lambda f, **kwargs: str(random.randrange(0, 51)),
        'angle':
        lambda f, **kwargs: str(random.randrange(-360, 361)),
        'password':
        lambda f, **kwargs: f.faker.password(),
    }, )

    def process(self, value):
        if isinstance(value, str):
            return (value, None)
        elif value is not None:
            return (str(value), None)
        else:
            return (value, UNRECOGNIZED_VALUE)

    def on_generate(self, **kwargs):
        return self.faker.text(max_nb_chars=64)

    def on_generate_range(self, bounds: 'Bounds', **kwargs):
        def vec(text, n):
            padding = n - len(text)
            vec = [ord(c) for c in text]
            if padding:
                vec += [ord('a')] * padding
            return vec

        def midpoint(s1, s2):
            n = max(len(s1), len(s2))
            v1 = vec(s1, n)
            v2 = vec(s2, n)
            return ''.join(
                chr(c) for c in (abs(i1 + i2) // 2 for i1, i2 in zip(v1, v2)))

        def increment(text, incr):
            return text[:-1] + chr(ord(text[-1]) + incr)

        lower = None
        upper = None

        if bounds.lower:
            lower = bounds.lower[:]
            if not bounds.lower_inclusive:
                lower = increment(lower, 1)

        if bounds.upper:
            upper = bounds.upper[:]
            if not bounds.upper_inclusive:
                upper = increment(upper, -1)

        if lower is not None and upper is not None:
            return midpoint(lower, upper)
        elif lower is not None:
            return lower

        assert upper is not None
        return upper
Example #18
0
 def on_bind(self, resource_type: Type['Resource'], **kwargs):
     self.type_name = StringUtils.snake(resource_type.__name__).lower()
     self.records = HashSet(self.redis, self.type_name)
     self.revs = HashSet(self.redis, f'{self.type_name}_revisions')
     self.indexes = self._bind_indexes()